PostgreSQL Source Code  git master
hstore_gin.c File Reference
#include "postgres.h"
#include "access/gin.h"
#include "access/stratnum.h"
#include "catalog/pg_type.h"
#include "hstore.h"
Include dependency graph for hstore_gin.c:

Go to the source code of this file.

Macros

#define KEYFLAG   'K'
 
#define VALFLAG   'V'
 
#define NULLFLAG   'N'
 

Functions

 PG_FUNCTION_INFO_V1 (gin_extract_hstore)
 
static textmakeitem (char *str, int len, char flag)
 
Datum gin_extract_hstore (PG_FUNCTION_ARGS)
 
 PG_FUNCTION_INFO_V1 (gin_extract_hstore_query)
 
Datum gin_extract_hstore_query (PG_FUNCTION_ARGS)
 
 PG_FUNCTION_INFO_V1 (gin_consistent_hstore)
 
Datum gin_consistent_hstore (PG_FUNCTION_ARGS)
 

Macro Definition Documentation

◆ KEYFLAG

#define KEYFLAG   'K'

Definition at line 20 of file hstore_gin.c.

Referenced by gin_extract_hstore(), and gin_extract_hstore_query().

◆ NULLFLAG

#define NULLFLAG   'N'

Definition at line 22 of file hstore_gin.c.

Referenced by gin_extract_hstore().

◆ VALFLAG

#define VALFLAG   'V'

Definition at line 21 of file hstore_gin.c.

Referenced by gin_extract_hstore().

Function Documentation

◆ gin_consistent_hstore()

Datum gin_consistent_hstore ( PG_FUNCTION_ARGS  )

Definition at line 153 of file hstore_gin.c.

References elog, ERROR, HStoreContainsStrategyNumber, HStoreExistsAllStrategyNumber, HStoreExistsAnyStrategyNumber, HStoreExistsStrategyNumber, i, PG_GETARG_INT32, PG_GETARG_POINTER, PG_GETARG_UINT16, and PG_RETURN_BOOL.

Referenced by gin_extract_hstore_query().

154 {
155  bool *check = (bool *) PG_GETARG_POINTER(0);
156  StrategyNumber strategy = PG_GETARG_UINT16(1);
157 
158  /* HStore *query = PG_GETARG_HSTORE_P(2); */
159  int32 nkeys = PG_GETARG_INT32(3);
160 
161  /* Pointer *extra_data = (Pointer *) PG_GETARG_POINTER(4); */
162  bool *recheck = (bool *) PG_GETARG_POINTER(5);
163  bool res = true;
164  int32 i;
165 
166  if (strategy == HStoreContainsStrategyNumber)
167  {
168  /*
169  * Index doesn't have information about correspondence of keys and
170  * values, so we need recheck. However, if not all the keys are
171  * present, we can fail at once.
172  */
173  *recheck = true;
174  for (i = 0; i < nkeys; i++)
175  {
176  if (!check[i])
177  {
178  res = false;
179  break;
180  }
181  }
182  }
183  else if (strategy == HStoreExistsStrategyNumber)
184  {
185  /* Existence of key is guaranteed in default search mode */
186  *recheck = false;
187  res = true;
188  }
189  else if (strategy == HStoreExistsAnyStrategyNumber)
190  {
191  /* Existence of key is guaranteed in default search mode */
192  *recheck = false;
193  res = true;
194  }
195  else if (strategy == HStoreExistsAllStrategyNumber)
196  {
197  /* Testing for all the keys being present gives an exact result */
198  *recheck = false;
199  for (i = 0; i < nkeys; i++)
200  {
201  if (!check[i])
202  {
203  res = false;
204  break;
205  }
206  }
207  }
208  else
209  elog(ERROR, "unrecognized strategy number: %d", strategy);
210 
211  PG_RETURN_BOOL(res);
212 }
#define PG_GETARG_INT32(n)
Definition: fmgr.h:234
#define HStoreContainsStrategyNumber
Definition: hstore.h:180
uint16 StrategyNumber
Definition: stratnum.h:22
#define PG_GETARG_POINTER(n)
Definition: fmgr.h:241
signed int int32
Definition: c.h:284
#define ERROR
Definition: elog.h:43
#define HStoreExistsStrategyNumber
Definition: hstore.h:181
#define HStoreExistsAllStrategyNumber
Definition: hstore.h:183
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:319
#define PG_GETARG_UINT16(n)
Definition: fmgr.h:237
#define HStoreExistsAnyStrategyNumber
Definition: hstore.h:182
int i
#define elog
Definition: elog.h:219

◆ gin_extract_hstore()

Datum gin_extract_hstore ( PG_FUNCTION_ARGS  )

Definition at line 44 of file hstore_gin.c.

References ARRPTR, gin_extract_hstore_query(), HS_COUNT, HSTORE_KEY, HSTORE_KEYLEN, HSTORE_VAL, HSTORE_VALISNULL, HSTORE_VALLEN, i, KEYFLAG, makeitem(), NULLFLAG, palloc(), PG_FUNCTION_INFO_V1(), PG_GETARG_HSTORE_P, PG_GETARG_POINTER, PG_RETURN_POINTER, PointerGetDatum, STRPTR, and VALFLAG.

Referenced by gin_extract_hstore_query().

45 {
46  HStore *hs = PG_GETARG_HSTORE_P(0);
47  int32 *nentries = (int32 *) PG_GETARG_POINTER(1);
48  Datum *entries = NULL;
49  HEntry *hsent = ARRPTR(hs);
50  char *ptr = STRPTR(hs);
51  int count = HS_COUNT(hs);
52  int i;
53 
54  *nentries = 2 * count;
55  if (count)
56  entries = (Datum *) palloc(sizeof(Datum) * 2 * count);
57 
58  for (i = 0; i < count; ++i)
59  {
60  text *item;
61 
62  item = makeitem(HSTORE_KEY(hsent, ptr, i),
63  HSTORE_KEYLEN(hsent, i),
64  KEYFLAG);
65  entries[2 * i] = PointerGetDatum(item);
66 
67  if (HSTORE_VALISNULL(hsent, i))
68  item = makeitem(NULL, 0, NULLFLAG);
69  else
70  item = makeitem(HSTORE_VAL(hsent, ptr, i),
71  HSTORE_VALLEN(hsent, i),
72  VALFLAG);
73  entries[2 * i + 1] = PointerGetDatum(item);
74  }
75 
76  PG_RETURN_POINTER(entries);
77 }
#define PG_RETURN_POINTER(x)
Definition: fmgr.h:321
Definition: hstore.h:44
#define PG_GETARG_HSTORE_P(x)
Definition: hstore.h:154
#define PointerGetDatum(X)
Definition: postgres.h:562
#define HSTORE_KEYLEN(arr_, i_)
Definition: hstore.h:81
#define HSTORE_VALLEN(arr_, i_)
Definition: hstore.h:82
#define PG_GETARG_POINTER(n)
Definition: fmgr.h:241
#define KEYFLAG
Definition: hstore_gin.c:20
static text * makeitem(char *str, int len, char flag)
Definition: hstore_gin.c:28
signed int int32
Definition: c.h:284
#define HSTORE_VALISNULL(arr_, i_)
Definition: hstore.h:83
#define HS_COUNT(hsp_)
Definition: hstore.h:61
#define HSTORE_KEY(arr_, str_, i_)
Definition: hstore.h:79
uintptr_t Datum
Definition: postgres.h:372
#define VALFLAG
Definition: hstore_gin.c:21
Definition: hstore.h:18
#define HSTORE_VAL(arr_, str_, i_)
Definition: hstore.h:80
#define NULLFLAG
Definition: hstore_gin.c:22
void * palloc(Size size)
Definition: mcxt.c:848
#define STRPTR(x)
Definition: hstore.h:76
int i
Definition: c.h:487
#define ARRPTR(x)
Definition: cube.c:26

◆ gin_extract_hstore_query()

Datum gin_extract_hstore_query ( PG_FUNCTION_ARGS  )

Definition at line 82 of file hstore_gin.c.

References DatumGetPointer, deconstruct_array(), DirectFunctionCall2, elog, ERROR, gin_consistent_hstore(), gin_extract_hstore(), GIN_SEARCH_MODE_ALL, HStoreContainsStrategyNumber, HStoreExistsAllStrategyNumber, HStoreExistsAnyStrategyNumber, HStoreExistsStrategyNumber, i, KEYFLAG, makeitem(), palloc(), PG_FUNCTION_INFO_V1(), PG_GETARG_ARRAYTYPE_P, PG_GETARG_DATUM, PG_GETARG_POINTER, PG_GETARG_TEXT_PP, PG_GETARG_UINT16, PG_RETURN_POINTER, PointerGetDatum, TEXTOID, VARDATA, VARDATA_ANY, VARHDRSZ, VARSIZE, and VARSIZE_ANY_EXHDR.

Referenced by gin_extract_hstore().

83 {
84  int32 *nentries = (int32 *) PG_GETARG_POINTER(1);
85  StrategyNumber strategy = PG_GETARG_UINT16(2);
86  int32 *searchMode = (int32 *) PG_GETARG_POINTER(6);
87  Datum *entries;
88 
89  if (strategy == HStoreContainsStrategyNumber)
90  {
91  /* Query is an hstore, so just apply gin_extract_hstore... */
92  entries = (Datum *)
94  PG_GETARG_DATUM(0),
95  PointerGetDatum(nentries)));
96  /* ... except that "contains {}" requires a full index scan */
97  if (entries == NULL)
98  *searchMode = GIN_SEARCH_MODE_ALL;
99  }
100  else if (strategy == HStoreExistsStrategyNumber)
101  {
102  text *query = PG_GETARG_TEXT_PP(0);
103  text *item;
104 
105  *nentries = 1;
106  entries = (Datum *) palloc(sizeof(Datum));
107  item = makeitem(VARDATA_ANY(query), VARSIZE_ANY_EXHDR(query), KEYFLAG);
108  entries[0] = PointerGetDatum(item);
109  }
110  else if (strategy == HStoreExistsAnyStrategyNumber ||
111  strategy == HStoreExistsAllStrategyNumber)
112  {
113  ArrayType *query = PG_GETARG_ARRAYTYPE_P(0);
114  Datum *key_datums;
115  bool *key_nulls;
116  int key_count;
117  int i,
118  j;
119  text *item;
120 
121  deconstruct_array(query,
122  TEXTOID, -1, false, 'i',
123  &key_datums, &key_nulls, &key_count);
124 
125  entries = (Datum *) palloc(sizeof(Datum) * key_count);
126 
127  for (i = 0, j = 0; i < key_count; ++i)
128  {
129  /* Nulls in the array are ignored, cf hstoreArrayToPairs */
130  if (key_nulls[i])
131  continue;
132  item = makeitem(VARDATA(key_datums[i]), VARSIZE(key_datums[i]) - VARHDRSZ, KEYFLAG);
133  entries[j++] = PointerGetDatum(item);
134  }
135 
136  *nentries = j;
137  /* ExistsAll with no keys should match everything */
138  if (j == 0 && strategy == HStoreExistsAllStrategyNumber)
139  *searchMode = GIN_SEARCH_MODE_ALL;
140  }
141  else
142  {
143  elog(ERROR, "unrecognized strategy number: %d", strategy);
144  entries = NULL; /* keep compiler quiet */
145  }
146 
147  PG_RETURN_POINTER(entries);
148 }
#define PG_RETURN_POINTER(x)
Definition: fmgr.h:321
#define HStoreContainsStrategyNumber
Definition: hstore.h:180
#define VARDATA_ANY(PTR)
Definition: postgres.h:347
#define VARDATA(PTR)
Definition: postgres.h:303
#define TEXTOID
Definition: pg_type.h:324
#define VARSIZE(PTR)
Definition: postgres.h:304
#define PointerGetDatum(X)
Definition: postgres.h:562
#define PG_GETARG_DATUM(n)
Definition: fmgr.h:233
#define VARHDRSZ
Definition: c.h:493
uint16 StrategyNumber
Definition: stratnum.h:22
#define PG_GETARG_POINTER(n)
Definition: fmgr.h:241
#define KEYFLAG
Definition: hstore_gin.c:20
static text * makeitem(char *str, int len, char flag)
Definition: hstore_gin.c:28
signed int int32
Definition: c.h:284
#define PG_GETARG_TEXT_PP(n)
Definition: fmgr.h:273
#define PG_GETARG_ARRAYTYPE_P(n)
Definition: array.h:248
#define GIN_SEARCH_MODE_ALL
Definition: gin.h:35
#define ERROR
Definition: elog.h:43
#define HStoreExistsStrategyNumber
Definition: hstore.h:181
#define HStoreExistsAllStrategyNumber
Definition: hstore.h:183
Datum gin_extract_hstore(PG_FUNCTION_ARGS)
Definition: hstore_gin.c:44
uintptr_t Datum
Definition: postgres.h:372
#define PG_GETARG_UINT16(n)
Definition: fmgr.h:237
#define DatumGetPointer(X)
Definition: postgres.h:555
void deconstruct_array(ArrayType *array, Oid elmtype, int elmlen, bool elmbyval, char elmalign, Datum **elemsp, bool **nullsp, int *nelemsp)
Definition: arrayfuncs.c:3449
#define VARSIZE_ANY_EXHDR(PTR)
Definition: postgres.h:340
void * palloc(Size size)
Definition: mcxt.c:848
#define HStoreExistsAnyStrategyNumber
Definition: hstore.h:182
int i
Definition: c.h:487
#define elog
Definition: elog.h:219
#define DirectFunctionCall2(func, arg1, arg2)
Definition: fmgr.h:587

◆ makeitem()

static text* makeitem ( char *  str,
int  len,
char  flag 
)
static

Definition at line 28 of file hstore_gin.c.

References flag(), palloc(), SET_VARSIZE, VARDATA, and VARHDRSZ.

Referenced by gin_extract_hstore(), and gin_extract_hstore_query().

29 {
30  text *item;
31 
32  item = (text *) palloc(VARHDRSZ + len + 1);
33  SET_VARSIZE(item, VARHDRSZ + len + 1);
34 
35  *VARDATA(item) = flag;
36 
37  if (str && len > 0)
38  memcpy(VARDATA(item) + 1, str, len);
39 
40  return item;
41 }
#define VARDATA(PTR)
Definition: postgres.h:303
#define VARHDRSZ
Definition: c.h:493
char * flag(int b)
Definition: test-ctype.c:33
void * palloc(Size size)
Definition: mcxt.c:848
Definition: c.h:487
#define SET_VARSIZE(PTR, len)
Definition: postgres.h:328

◆ PG_FUNCTION_INFO_V1() [1/3]

PG_FUNCTION_INFO_V1 ( gin_extract_hstore  )

◆ PG_FUNCTION_INFO_V1() [2/3]

PG_FUNCTION_INFO_V1 ( gin_extract_hstore_query  )

◆ PG_FUNCTION_INFO_V1() [3/3]

PG_FUNCTION_INFO_V1 ( gin_consistent_hstore  )