Line data Source code
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 :
10 2 : PG_FUNCTION_INFO_V1(ginint4_queryextract);
11 :
12 : Datum
13 28 : ginint4_queryextract(PG_FUNCTION_ARGS)
14 : {
15 28 : int32 *nentries = (int32 *) PG_GETARG_POINTER(1);
16 28 : StrategyNumber strategy = PG_GETARG_UINT16(2);
17 28 : int32 *searchMode = (int32 *) PG_GETARG_POINTER(6);
18 28 : Datum *res = NULL;
19 :
20 28 : *nentries = 0;
21 :
22 28 : if (strategy == BooleanSearchStrategy)
23 : {
24 14 : QUERYTYPE *query = PG_GETARG_QUERYTYPE_P(0);
25 14 : ITEM *items = GETQUERY(query);
26 : int i;
27 :
28 : /* empty query must fail */
29 14 : if (query->size <= 0)
30 0 : 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 14 : if (query_has_required_values(query))
38 10 : *searchMode = GIN_SEARCH_MODE_DEFAULT;
39 : else
40 4 : *searchMode = GIN_SEARCH_MODE_ALL;
41 :
42 : /*
43 : * Extract all the VAL items as things we want GIN to check for.
44 : */
45 14 : res = palloc_array(Datum, query->size);
46 14 : *nentries = 0;
47 :
48 76 : for (i = 0; i < query->size; i++)
49 : {
50 62 : if (items[i].type == VAL)
51 : {
52 34 : res[*nentries] = Int32GetDatum(items[i].val);
53 34 : (*nentries)++;
54 : }
55 : }
56 : }
57 : else
58 : {
59 14 : ArrayType *query = PG_GETARG_ARRAYTYPE_P(0);
60 :
61 14 : CHECKARRVALID(query);
62 14 : *nentries = ARRNELEMS(query);
63 14 : if (*nentries > 0)
64 : {
65 : int32 *arr;
66 : int32 i;
67 :
68 14 : res = palloc_array(Datum, *nentries);
69 :
70 14 : arr = ARRPTR(query);
71 46 : for (i = 0; i < *nentries; i++)
72 32 : res[i] = Int32GetDatum(arr[i]);
73 : }
74 :
75 14 : switch (strategy)
76 : {
77 2 : case RTOverlapStrategyNumber:
78 2 : *searchMode = GIN_SEARCH_MODE_DEFAULT;
79 2 : break;
80 2 : case RTContainedByStrategyNumber:
81 : case RTOldContainedByStrategyNumber:
82 : /* empty set is contained in everything */
83 2 : *searchMode = GIN_SEARCH_MODE_INCLUDE_EMPTY;
84 2 : break;
85 2 : case RTSameStrategyNumber:
86 2 : if (*nentries > 0)
87 2 : *searchMode = GIN_SEARCH_MODE_DEFAULT;
88 : else
89 0 : *searchMode = GIN_SEARCH_MODE_INCLUDE_EMPTY;
90 2 : break;
91 8 : case RTContainsStrategyNumber:
92 : case RTOldContainsStrategyNumber:
93 8 : if (*nentries > 0)
94 8 : *searchMode = GIN_SEARCH_MODE_DEFAULT;
95 : else /* everything contains the empty set */
96 0 : *searchMode = GIN_SEARCH_MODE_ALL;
97 8 : break;
98 0 : default:
99 0 : elog(ERROR, "ginint4_queryextract: unknown strategy number: %d",
100 : strategy);
101 : }
102 : }
103 :
104 28 : PG_RETURN_POINTER(res);
105 : }
106 :
107 2 : PG_FUNCTION_INFO_V1(ginint4_consistent);
108 :
109 : Datum
110 16976 : ginint4_consistent(PG_FUNCTION_ARGS)
111 : {
112 16976 : bool *check = (bool *) PG_GETARG_POINTER(0);
113 16976 : StrategyNumber strategy = PG_GETARG_UINT16(1);
114 16976 : int32 nkeys = PG_GETARG_INT32(3);
115 : #ifdef NOT_USED
116 : Pointer *extra_data = (Pointer *) PG_GETARG_POINTER(4);
117 : #endif
118 16976 : bool *recheck = (bool *) PG_GETARG_POINTER(5);
119 16976 : bool res = false;
120 : int32 i;
121 :
122 16976 : switch (strategy)
123 : {
124 405 : case RTOverlapStrategyNumber:
125 : /* result is not lossy */
126 405 : *recheck = false;
127 : /* at least one element in check[] is true, so result = true */
128 405 : res = true;
129 405 : break;
130 632 : case RTContainedByStrategyNumber:
131 : case RTOldContainedByStrategyNumber:
132 : /* we will need recheck */
133 632 : *recheck = true;
134 : /* at least one element in check[] is true, so result = true */
135 632 : res = true;
136 632 : break;
137 205 : case RTSameStrategyNumber:
138 : /* we will need recheck */
139 205 : *recheck = true;
140 : /* Must have all elements in check[] true */
141 205 : res = true;
142 413 : for (i = 0; i < nkeys; i++)
143 : {
144 412 : if (!check[i])
145 : {
146 204 : res = false;
147 204 : break;
148 : }
149 : }
150 205 : break;
151 815 : case RTContainsStrategyNumber:
152 : case RTOldContainsStrategyNumber:
153 : /* result is not lossy */
154 815 : *recheck = false;
155 : /* Must have all elements in check[] true */
156 815 : res = true;
157 909 : for (i = 0; i < nkeys; i++)
158 : {
159 864 : if (!check[i])
160 : {
161 770 : res = false;
162 770 : break;
163 : }
164 : }
165 815 : break;
166 14919 : case BooleanSearchStrategy:
167 : {
168 14919 : QUERYTYPE *query = PG_GETARG_QUERYTYPE_P(2);
169 :
170 : /* result is not lossy */
171 14919 : *recheck = false;
172 14919 : res = gin_bool_consistent(query, check);
173 : }
174 14919 : break;
175 0 : default:
176 0 : elog(ERROR, "ginint4_consistent: unknown strategy number: %d",
177 : strategy);
178 : }
179 :
180 16976 : PG_RETURN_BOOL(res);
181 : }
|