1
/*-------------------------------------------------------------------------
4
* support functions for GIN's indexing of any array
7
* Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
8
* Portions Copyright (c) 1994, Regents of the University of California
12
*-------------------------------------------------------------------------
16
#include "access/gin.h"
17
#include "utils/array.h"
18
#include "utils/lsyscache.h"
21
#define GinOverlapStrategy 1
22
#define GinContainsStrategy 2
23
#define GinContainedStrategy 3
24
#define GinEqualStrategy 4
26
#define ARRAYCHECK(x) do { \
27
if ( ARR_HASNULL(x) ) \
29
(errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED), \
30
errmsg("array must not contain null values"))); \
35
* Function used as extractValue and extractQuery both
38
ginarrayextract(PG_FUNCTION_ARGS)
41
int32 *nentries = (int32 *) PG_GETARG_POINTER(1);
42
Datum *entries = NULL;
48
* we should guarantee that array will not be destroyed during all
51
array = PG_GETARG_ARRAYTYPE_P_COPY(0);
55
get_typlenbyvalalign(ARR_ELEMTYPE(array),
56
&elmlen, &elmbyval, &elmalign);
58
deconstruct_array(array,
60
elmlen, elmbyval, elmalign,
61
&entries, NULL, (int *) nentries);
63
if (*nentries == 0 && PG_NARGS() == 3)
65
switch (PG_GETARG_UINT16(2)) /* StrategyNumber */
67
case GinOverlapStrategy:
68
*nentries = -1; /* nobody can be found */
70
case GinContainsStrategy:
71
case GinContainedStrategy:
72
case GinEqualStrategy:
73
default: /* require fullscan: GIN can't find void
79
/* we should not free array, entries[i] points into it */
80
PG_RETURN_POINTER(entries);
84
ginqueryarrayextract(PG_FUNCTION_ARGS)
86
PG_RETURN_DATUM(DirectFunctionCall3(ginarrayextract,
93
ginarrayconsistent(PG_FUNCTION_ARGS)
95
bool *check = (bool *) PG_GETARG_POINTER(0);
96
StrategyNumber strategy = PG_GETARG_UINT16(1);
97
ArrayType *query = PG_GETARG_ARRAYTYPE_P(2);
98
/* int32 nkeys = PG_GETARG_INT32(3); */
99
/* Pointer *extra_data = (Pointer *) PG_GETARG_POINTER(4); */
100
bool *recheck = (bool *) PG_GETARG_POINTER(5);
105
/* ARRAYCHECK was already done by previous ginarrayextract call */
109
case GinOverlapStrategy:
110
/* result is not lossy */
112
/* at least one element in check[] is true, so result = true */
115
case GinContainedStrategy:
116
/* we will need recheck */
118
/* at least one element in check[] is true, so result = true */
121
case GinContainsStrategy:
122
/* result is not lossy */
124
/* must have all elements in check[] true */
125
nentries = ArrayGetNItems(ARR_NDIM(query), ARR_DIMS(query));
127
for (i = 0; i < nentries; i++)
136
case GinEqualStrategy:
137
/* we will need recheck */
139
/* must have all elements in check[] true */
140
nentries = ArrayGetNItems(ARR_NDIM(query), ARR_DIMS(query));
142
for (i = 0; i < nentries; i++)
152
elog(ERROR, "ginarrayconsistent: unknown strategy number: %d",