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