PostgreSQL Source Code git master
Loading...
Searching...
No Matches
ginarrayproc.c
Go to the documentation of this file.
1/*-------------------------------------------------------------------------
2 *
3 * ginarrayproc.c
4 * support functions for GIN's indexing of any array
5 *
6 *
7 * Portions Copyright (c) 1996-2026, PostgreSQL Global Development Group
8 * Portions Copyright (c) 1994, Regents of the University of California
9 *
10 * IDENTIFICATION
11 * src/backend/access/gin/ginarrayproc.c
12 *-------------------------------------------------------------------------
13 */
14#include "postgres.h"
15
16#include "access/gin.h"
17#include "access/stratnum.h"
18#include "utils/array.h"
19#include "utils/fmgrprotos.h"
20#include "utils/lsyscache.h"
21
22
23#define GinOverlapStrategy 1
24#define GinContainsStrategy 2
25#define GinContainedStrategy 3
26#define GinEqualStrategy 4
27
28
29/*
30 * extractValue support function
31 */
34{
35 /* Make copy of array input to ensure it doesn't disappear while in use */
37 int32 *nkeys = (int32 *) PG_GETARG_POINTER(1);
38 bool **nullFlags = (bool **) PG_GETARG_POINTER(2);
40 bool elmbyval;
41 char elmalign;
42 Datum *elems;
43 bool *nulls;
44 int nelems;
45
48
50 ARR_ELEMTYPE(array),
52 &elems, &nulls, &nelems);
53
54 *nkeys = nelems;
55 *nullFlags = nulls;
56
57 /* we should not free array, elems[i] points into it */
58 PG_RETURN_POINTER(elems);
59}
60
61/*
62 * Formerly, ginarrayextract had only two arguments. Now it has three,
63 * but we still need a pg_proc entry with two args to support reloading
64 * pre-9.1 contrib/intarray opclass declarations. This compatibility
65 * function should go away eventually.
66 */
69{
70 if (PG_NARGS() < 3) /* should not happen */
71 elog(ERROR, "ginarrayextract requires three arguments");
72 return ginarrayextract(fcinfo);
73}
74
75/*
76 * extractQuery support function
77 */
80{
81 /* Make copy of array input to ensure it doesn't disappear while in use */
83 int32 *nkeys = (int32 *) PG_GETARG_POINTER(1);
84 StrategyNumber strategy = PG_GETARG_UINT16(2);
85#ifdef NOT_USED
86 bool **pmatch = (bool **) PG_GETARG_POINTER(3);
87 Pointer *extra_data = (Pointer *) PG_GETARG_POINTER(4);
88#endif
89 bool **nullFlags = (bool **) PG_GETARG_POINTER(5);
90 int32 *searchMode = (int32 *) PG_GETARG_POINTER(6);
92 bool elmbyval;
93 char elmalign;
94 Datum *elems;
95 bool *nulls;
96 int nelems;
97
100
101 deconstruct_array(array,
102 ARR_ELEMTYPE(array),
104 &elems, &nulls, &nelems);
105
106 *nkeys = nelems;
107 *nullFlags = nulls;
108
109 switch (strategy)
110 {
112 *searchMode = GIN_SEARCH_MODE_DEFAULT;
113 break;
115 if (nelems > 0)
116 *searchMode = GIN_SEARCH_MODE_DEFAULT;
117 else /* everything contains the empty set */
118 *searchMode = GIN_SEARCH_MODE_ALL;
119 break;
121 /* empty set is contained in everything */
122 *searchMode = GIN_SEARCH_MODE_INCLUDE_EMPTY;
123 break;
124 case GinEqualStrategy:
125 if (nelems > 0)
126 *searchMode = GIN_SEARCH_MODE_DEFAULT;
127 else
128 *searchMode = GIN_SEARCH_MODE_INCLUDE_EMPTY;
129 break;
130 default:
131 elog(ERROR, "ginqueryarrayextract: unknown strategy number: %d",
132 strategy);
133 }
134
135 /* we should not free array, elems[i] points into it */
136 PG_RETURN_POINTER(elems);
137}
138
139/*
140 * consistent support function
141 */
142Datum
144{
145 bool *check = (bool *) PG_GETARG_POINTER(0);
146 StrategyNumber strategy = PG_GETARG_UINT16(1);
147#ifdef NOT_USED
149#endif
150 int32 nkeys = PG_GETARG_INT32(3);
151#ifdef NOT_USED
152 Pointer *extra_data = (Pointer *) PG_GETARG_POINTER(4);
153#endif
154 bool *recheck = (bool *) PG_GETARG_POINTER(5);
155#ifdef NOT_USED
157#endif
158 bool *nullFlags = (bool *) PG_GETARG_POINTER(7);
159 bool res;
160 int32 i;
161
162 switch (strategy)
163 {
165 /* result is not lossy */
166 *recheck = false;
167 /* must have a match for at least one non-null element */
168 res = false;
169 for (i = 0; i < nkeys; i++)
170 {
171 if (check[i] && !nullFlags[i])
172 {
173 res = true;
174 break;
175 }
176 }
177 break;
179 /* result is not lossy */
180 *recheck = false;
181 /* must have all elements in check[] true, and no nulls */
182 res = true;
183 for (i = 0; i < nkeys; i++)
184 {
185 if (!check[i] || nullFlags[i])
186 {
187 res = false;
188 break;
189 }
190 }
191 break;
193 /* we will need recheck */
194 *recheck = true;
195 /* can't do anything else useful here */
196 res = true;
197 break;
198 case GinEqualStrategy:
199 /* we will need recheck */
200 *recheck = true;
201
202 /*
203 * Must have all elements in check[] true; no discrimination
204 * against nulls here. This is because array_contain_compare and
205 * array_eq handle nulls differently ...
206 */
207 res = true;
208 for (i = 0; i < nkeys; i++)
209 {
210 if (!check[i])
211 {
212 res = false;
213 break;
214 }
215 }
216 break;
217 default:
218 elog(ERROR, "ginarrayconsistent: unknown strategy number: %d",
219 strategy);
220 res = false;
221 }
222
223 PG_RETURN_BOOL(res);
224}
225
226/*
227 * triconsistent support function
228 */
229Datum
231{
233 StrategyNumber strategy = PG_GETARG_UINT16(1);
234#ifdef NOT_USED
236#endif
237 int32 nkeys = PG_GETARG_INT32(3);
238#ifdef NOT_USED
239 Pointer *extra_data = (Pointer *) PG_GETARG_POINTER(4);
241#endif
242 bool *nullFlags = (bool *) PG_GETARG_POINTER(6);
243 GinTernaryValue res;
244 int32 i;
245
246 switch (strategy)
247 {
249 /* must have a match for at least one non-null element */
250 res = GIN_FALSE;
251 for (i = 0; i < nkeys; i++)
252 {
253 if (!nullFlags[i])
254 {
255 if (check[i] == GIN_TRUE)
256 {
257 res = GIN_TRUE;
258 break;
259 }
260 else if (check[i] == GIN_MAYBE && res == GIN_FALSE)
261 {
262 res = GIN_MAYBE;
263 }
264 }
265 }
266 break;
268 /* must have all elements in check[] true, and no nulls */
269 res = GIN_TRUE;
270 for (i = 0; i < nkeys; i++)
271 {
272 if (check[i] == GIN_FALSE || nullFlags[i])
273 {
274 res = GIN_FALSE;
275 break;
276 }
277 if (check[i] == GIN_MAYBE)
278 {
279 res = GIN_MAYBE;
280 }
281 }
282 break;
284 /* can't do anything else useful here */
285 res = GIN_MAYBE;
286 break;
287 case GinEqualStrategy:
288
289 /*
290 * Must have all elements in check[] true; no discrimination
291 * against nulls here. This is because array_contain_compare and
292 * array_eq handle nulls differently ...
293 */
294 res = GIN_MAYBE;
295 for (i = 0; i < nkeys; i++)
296 {
297 if (check[i] == GIN_FALSE)
298 {
299 res = GIN_FALSE;
300 break;
301 }
302 }
303 break;
304 default:
305 elog(ERROR, "ginarrayconsistent: unknown strategy number: %d",
306 strategy);
307 res = false;
308 }
309
311}
#define PG_GETARG_ARRAYTYPE_P_COPY(n)
Definition array.h:264
#define PG_GETARG_ARRAYTYPE_P(n)
Definition array.h:263
#define ARR_ELEMTYPE(a)
Definition array.h:292
void deconstruct_array(const ArrayType *array, Oid elmtype, int elmlen, bool elmbyval, char elmalign, Datum **elemsp, bool **nullsp, int *nelemsp)
int16_t int16
Definition c.h:541
int32_t int32
Definition c.h:542
void * Pointer
Definition c.h:537
#define ERROR
Definition elog.h:39
#define elog(elevel,...)
Definition elog.h:226
#define PG_GETARG_POINTER(n)
Definition fmgr.h:277
#define PG_NARGS()
Definition fmgr.h:203
#define PG_GETARG_UINT16(n)
Definition fmgr.h:272
#define PG_GETARG_INT32(n)
Definition fmgr.h:269
#define PG_RETURN_POINTER(x)
Definition fmgr.h:363
#define PG_FUNCTION_ARGS
Definition fmgr.h:193
#define PG_RETURN_BOOL(x)
Definition fmgr.h:360
#define PG_RETURN_GIN_TERNARY_VALUE(x)
Definition gin.h:92
#define GIN_SEARCH_MODE_ALL
Definition gin.h:38
#define GIN_FALSE
Definition gin.h:76
#define GIN_SEARCH_MODE_DEFAULT
Definition gin.h:36
char GinTernaryValue
Definition gin.h:71
#define GIN_SEARCH_MODE_INCLUDE_EMPTY
Definition gin.h:37
#define GIN_MAYBE
Definition gin.h:78
#define GIN_TRUE
Definition gin.h:77
Datum ginarraytriconsistent(PG_FUNCTION_ARGS)
Datum ginarrayextract_2args(PG_FUNCTION_ARGS)
#define GinEqualStrategy
Datum ginarrayextract(PG_FUNCTION_ARGS)
Datum ginarrayconsistent(PG_FUNCTION_ARGS)
#define GinOverlapStrategy
#define GinContainedStrategy
#define GinContainsStrategy
Datum ginqueryarrayextract(PG_FUNCTION_ARGS)
int i
Definition isn.c:77
void get_typlenbyvalalign(Oid typid, int16 *typlen, bool *typbyval, char *typalign)
Definition lsyscache.c:2421
uint64_t Datum
Definition postgres.h:70
static int fb(int x)
uint16 StrategyNumber
Definition stratnum.h:22