Branch data 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 : : }
|