1
/*-------------------------------------------------------------------------
4
* support functions for GIN's indexing of any array
7
* Portions Copyright (c) 1996-2011, PostgreSQL Global Development Group
8
* Portions Copyright (c) 1994, Regents of the University of California
11
* src/backend/access/gin/ginarrayproc.c
12
*-------------------------------------------------------------------------
16
#include "access/gin.h"
17
#include "access/skey.h"
18
#include "utils/array.h"
19
#include "utils/builtins.h"
20
#include "utils/lsyscache.h"
23
#define GinOverlapStrategy 1
24
#define GinContainsStrategy 2
25
#define GinContainedStrategy 3
26
#define GinEqualStrategy 4
30
* extractValue support function
33
ginarrayextract(PG_FUNCTION_ARGS)
35
/* Make copy of array input to ensure it doesn't disappear while in use */
36
ArrayType *array = PG_GETARG_ARRAYTYPE_P_COPY(0);
37
int32 *nkeys = (int32 *) PG_GETARG_POINTER(1);
38
bool **nullFlags = (bool **) PG_GETARG_POINTER(2);
46
get_typlenbyvalalign(ARR_ELEMTYPE(array),
47
&elmlen, &elmbyval, &elmalign);
49
deconstruct_array(array,
51
elmlen, elmbyval, elmalign,
52
&elems, &nulls, &nelems);
57
/* we should not free array, elems[i] points into it */
58
PG_RETURN_POINTER(elems);
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.
68
ginarrayextract_2args(PG_FUNCTION_ARGS)
70
if (PG_NARGS() < 3) /* should not happen */
71
elog(ERROR, "ginarrayextract requires three arguments");
72
return ginarrayextract(fcinfo);
76
* extractQuery support function
79
ginqueryarrayextract(PG_FUNCTION_ARGS)
81
/* Make copy of array input to ensure it doesn't disappear while in use */
82
ArrayType *array = PG_GETARG_ARRAYTYPE_P_COPY(0);
83
int32 *nkeys = (int32 *) PG_GETARG_POINTER(1);
84
StrategyNumber strategy = PG_GETARG_UINT16(2);
86
/* bool **pmatch = (bool **) PG_GETARG_POINTER(3); */
87
/* Pointer *extra_data = (Pointer *) PG_GETARG_POINTER(4); */
88
bool **nullFlags = (bool **) PG_GETARG_POINTER(5);
89
int32 *searchMode = (int32 *) PG_GETARG_POINTER(6);
97
get_typlenbyvalalign(ARR_ELEMTYPE(array),
98
&elmlen, &elmbyval, &elmalign);
100
deconstruct_array(array,
102
elmlen, elmbyval, elmalign,
103
&elems, &nulls, &nelems);
110
case GinOverlapStrategy:
111
*searchMode = GIN_SEARCH_MODE_DEFAULT;
113
case GinContainsStrategy:
115
*searchMode = GIN_SEARCH_MODE_DEFAULT;
116
else /* everything contains the empty set */
117
*searchMode = GIN_SEARCH_MODE_ALL;
119
case GinContainedStrategy:
120
/* empty set is contained in everything */
121
*searchMode = GIN_SEARCH_MODE_INCLUDE_EMPTY;
123
case GinEqualStrategy:
125
*searchMode = GIN_SEARCH_MODE_DEFAULT;
127
*searchMode = GIN_SEARCH_MODE_INCLUDE_EMPTY;
130
elog(ERROR, "ginqueryarrayextract: unknown strategy number: %d",
134
/* we should not free array, elems[i] points into it */
135
PG_RETURN_POINTER(elems);
139
* consistent support function
142
ginarrayconsistent(PG_FUNCTION_ARGS)
144
bool *check = (bool *) PG_GETARG_POINTER(0);
145
StrategyNumber strategy = PG_GETARG_UINT16(1);
147
/* ArrayType *query = PG_GETARG_ARRAYTYPE_P(2); */
148
int32 nkeys = PG_GETARG_INT32(3);
150
/* Pointer *extra_data = (Pointer *) PG_GETARG_POINTER(4); */
151
bool *recheck = (bool *) PG_GETARG_POINTER(5);
153
/* Datum *queryKeys = (Datum *) PG_GETARG_POINTER(6); */
154
bool *nullFlags = (bool *) PG_GETARG_POINTER(7);
160
case GinOverlapStrategy:
161
/* result is not lossy */
163
/* must have a match for at least one non-null element */
165
for (i = 0; i < nkeys; i++)
167
if (check[i] && !nullFlags[i])
174
case GinContainsStrategy:
175
/* result is not lossy */
177
/* must have all elements in check[] true, and no nulls */
179
for (i = 0; i < nkeys; i++)
181
if (!check[i] || nullFlags[i])
188
case GinContainedStrategy:
189
/* we will need recheck */
191
/* can't do anything else useful here */
194
case GinEqualStrategy:
195
/* we will need recheck */
199
* Must have all elements in check[] true; no discrimination
200
* against nulls here. This is because array_contain_compare and
201
* array_eq handle nulls differently ...
204
for (i = 0; i < nkeys; i++)
214
elog(ERROR, "ginarrayconsistent: unknown strategy number: %d",