PostgreSQL Source Code  git master
_int_gin.c
Go to the documentation of this file.
1 /*
2  * contrib/intarray/_int_gin.c
3  */
4 #include "postgres.h"
5 
6 #include "access/gin.h"
7 #include "access/stratnum.h"
8 
9 #include "_int.h"
10 
12 
13 Datum
15 {
16  int32 *nentries = (int32 *) PG_GETARG_POINTER(1);
17  StrategyNumber strategy = PG_GETARG_UINT16(2);
18  int32 *searchMode = (int32 *) PG_GETARG_POINTER(6);
19  Datum *res = NULL;
20 
21  *nentries = 0;
22 
23  if (strategy == BooleanSearchStrategy)
24  {
25  QUERYTYPE *query = PG_GETARG_QUERYTYPE_P(0);
26  ITEM *items = GETQUERY(query);
27  int i;
28 
29  /* empty query must fail */
30  if (query->size <= 0)
31  PG_RETURN_POINTER(NULL);
32 
33  /*
34  * If the query doesn't have any required primitive values (for
35  * instance, it's something like '! 42'), we have to do a full index
36  * scan.
37  */
38  if (query_has_required_values(query))
39  *searchMode = GIN_SEARCH_MODE_DEFAULT;
40  else
41  *searchMode = GIN_SEARCH_MODE_ALL;
42 
43  /*
44  * Extract all the VAL items as things we want GIN to check for.
45  */
46  res = (Datum *) palloc(sizeof(Datum) * query->size);
47  *nentries = 0;
48 
49  for (i = 0; i < query->size; i++)
50  {
51  if (items[i].type == VAL)
52  {
53  res[*nentries] = Int32GetDatum(items[i].val);
54  (*nentries)++;
55  }
56  }
57  }
58  else
59  {
60  ArrayType *query = PG_GETARG_ARRAYTYPE_P(0);
61 
62  CHECKARRVALID(query);
63  *nentries = ARRNELEMS(query);
64  if (*nentries > 0)
65  {
66  int32 *arr;
67  int32 i;
68 
69  res = (Datum *) palloc(sizeof(Datum) * (*nentries));
70 
71  arr = ARRPTR(query);
72  for (i = 0; i < *nentries; i++)
73  res[i] = Int32GetDatum(arr[i]);
74  }
75 
76  switch (strategy)
77  {
79  *searchMode = GIN_SEARCH_MODE_DEFAULT;
80  break;
83  /* empty set is contained in everything */
84  *searchMode = GIN_SEARCH_MODE_INCLUDE_EMPTY;
85  break;
87  if (*nentries > 0)
88  *searchMode = GIN_SEARCH_MODE_DEFAULT;
89  else
90  *searchMode = GIN_SEARCH_MODE_INCLUDE_EMPTY;
91  break;
94  if (*nentries > 0)
95  *searchMode = GIN_SEARCH_MODE_DEFAULT;
96  else /* everything contains the empty set */
97  *searchMode = GIN_SEARCH_MODE_ALL;
98  break;
99  default:
100  elog(ERROR, "ginint4_queryextract: unknown strategy number: %d",
101  strategy);
102  }
103  }
104 
105  PG_RETURN_POINTER(res);
106 }
107 
109 
110 Datum
112 {
113  bool *check = (bool *) PG_GETARG_POINTER(0);
114  StrategyNumber strategy = PG_GETARG_UINT16(1);
115  int32 nkeys = PG_GETARG_INT32(3);
116 
117  /* Pointer *extra_data = (Pointer *) PG_GETARG_POINTER(4); */
118  bool *recheck = (bool *) PG_GETARG_POINTER(5);
119  bool res = false;
120  int32 i;
121 
122  switch (strategy)
123  {
125  /* result is not lossy */
126  *recheck = false;
127  /* at least one element in check[] is true, so result = true */
128  res = true;
129  break;
132  /* we will need recheck */
133  *recheck = true;
134  /* at least one element in check[] is true, so result = true */
135  res = true;
136  break;
138  /* we will need recheck */
139  *recheck = true;
140  /* Must have all elements in check[] true */
141  res = true;
142  for (i = 0; i < nkeys; i++)
143  {
144  if (!check[i])
145  {
146  res = false;
147  break;
148  }
149  }
150  break;
153  /* result is not lossy */
154  *recheck = false;
155  /* Must have all elements in check[] true */
156  res = true;
157  for (i = 0; i < nkeys; i++)
158  {
159  if (!check[i])
160  {
161  res = false;
162  break;
163  }
164  }
165  break;
167  {
168  QUERYTYPE *query = PG_GETARG_QUERYTYPE_P(2);
169 
170  /* result is not lossy */
171  *recheck = false;
172  res = gin_bool_consistent(query, check);
173  }
174  break;
175  default:
176  elog(ERROR, "ginint4_consistent: unknown strategy number: %d",
177  strategy);
178  }
179 
180  PG_RETURN_BOOL(res);
181 }
#define PG_GETARG_QUERYTYPE_P(n)
Definition: _int.h:155
Definition: _int.h:125
#define PG_RETURN_POINTER(x)
Definition: fmgr.h:321
#define PG_GETARG_INT32(n)
Definition: fmgr.h:234
#define RTOldContainsStrategyNumber
Definition: stratnum.h:56
#define RTOldContainedByStrategyNumber
Definition: stratnum.h:57
#define CHECKARRVALID(x)
Definition: _int.h:18
uint16 StrategyNumber
Definition: stratnum.h:22
#define RTContainedByStrategyNumber
Definition: stratnum.h:51
#define PG_GETARG_POINTER(n)
Definition: fmgr.h:241
#define GETQUERY(x)
Definition: _int.h:142
signed int int32
Definition: c.h:284
bool gin_bool_consistent(QUERYTYPE *query, bool *check)
Definition: _int_bool.c:337
#define PG_GETARG_ARRAYTYPE_P(n)
Definition: array.h:248
#define GIN_SEARCH_MODE_ALL
Definition: gin.h:35
#define GIN_SEARCH_MODE_INCLUDE_EMPTY
Definition: gin.h:34
#define ERROR
Definition: elog.h:43
#define RTSameStrategyNumber
Definition: stratnum.h:49
Datum ginint4_consistent(PG_FUNCTION_ARGS)
Definition: _int_gin.c:111
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:319
uintptr_t Datum
Definition: postgres.h:372
bool query_has_required_values(QUERYTYPE *query)
Definition: _int_bool.c:400
#define GIN_SEARCH_MODE_DEFAULT
Definition: gin.h:33
#define VAL
Definition: _int.h:147
#define BooleanSearchStrategy
Definition: _int.h:119
#define RTContainsStrategyNumber
Definition: stratnum.h:50
#define ARRNELEMS(x)
Definition: cube.c:27
#define PG_GETARG_UINT16(n)
Definition: fmgr.h:237
#define Int32GetDatum(X)
Definition: postgres.h:485
void * palloc(Size size)
Definition: mcxt.c:848
PG_FUNCTION_INFO_V1(ginint4_queryextract)
int i
#define RTOverlapStrategyNumber
Definition: stratnum.h:46
#define PG_FUNCTION_ARGS
Definition: fmgr.h:158
#define ARRPTR(x)
Definition: cube.c:26
#define elog
Definition: elog.h:219
Datum ginint4_queryextract(PG_FUNCTION_ARGS)
Definition: _int_gin.c:14
int32 size
Definition: _int.h:135
long val
Definition: informix.c:689