Age Owner TLA 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 :
6185 teodor 10 CBC 2 : PG_FUNCTION_INFO_V1(ginint4_queryextract);
11 :
12 : Datum
6031 bruce 13 26 : ginint4_queryextract(PG_FUNCTION_ARGS)
14 : {
5912 teodor 15 26 : int32 *nentries = (int32 *) PG_GETARG_POINTER(1);
6031 bruce 16 26 : StrategyNumber strategy = PG_GETARG_UINT16(2);
4473 tgl 17 26 : int32 *searchMode = (int32 *) PG_GETARG_POINTER(6);
6031 bruce 18 26 : Datum *res = NULL;
19 :
6185 teodor 20 26 : *nentries = 0;
21 :
6031 bruce 22 26 : if (strategy == BooleanSearchStrategy)
23 : {
4473 tgl 24 12 : QUERYTYPE *query = PG_GETARG_QUERYTYPE_P(0);
6031 bruce 25 12 : ITEM *items = GETQUERY(query);
26 : int i;
27 :
28 : /* empty query must fail */
4473 tgl 29 12 : if (query->size <= 0)
6185 teodor 30 UBC 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 : */
4473 tgl 37 CBC 12 : if (query_has_required_values(query))
38 8 : *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 : */
6031 bruce 45 12 : res = (Datum *) palloc(sizeof(Datum) * query->size);
6185 teodor 46 12 : *nentries = 0;
47 :
6031 bruce 48 62 : for (i = 0; i < query->size; i++)
49 : {
50 50 : if (items[i].type == VAL)
51 : {
52 28 : res[*nentries] = Int32GetDatum(items[i].val);
6185 teodor 53 28 : (*nentries)++;
54 : }
55 : }
56 : }
57 : else
58 : {
6031 bruce 59 14 : ArrayType *query = PG_GETARG_ARRAYTYPE_P(0);
60 :
6185 teodor 61 14 : CHECKARRVALID(query);
6031 bruce 62 14 : *nentries = ARRNELEMS(query);
63 14 : if (*nentries > 0)
64 : {
65 : int32 *arr;
66 : int32 i;
67 :
68 14 : res = (Datum *) palloc(sizeof(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 :
5624 75 14 : switch (strategy)
76 : {
5912 teodor 77 2 : case RTOverlapStrategyNumber:
4473 tgl 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;
5624 bruce 84 2 : break;
4473 tgl 85 2 : case RTSameStrategyNumber:
86 2 : if (*nentries > 0)
87 2 : *searchMode = GIN_SEARCH_MODE_DEFAULT;
88 : else
4473 tgl 89 UBC 0 : *searchMode = GIN_SEARCH_MODE_INCLUDE_EMPTY;
5624 bruce 90 CBC 2 : break;
4473 tgl 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 */
4473 tgl 96 UBC 0 : *searchMode = GIN_SEARCH_MODE_ALL;
4473 tgl 97 CBC 8 : break;
4473 tgl 98 UBC 0 : default:
99 0 : elog(ERROR, "ginint4_queryextract: unknown strategy number: %d",
100 : strategy);
101 : }
102 : }
103 :
6031 bruce 104 CBC 26 : PG_RETURN_POINTER(res);
105 : }
106 :
6185 teodor 107 2 : PG_FUNCTION_INFO_V1(ginint4_consistent);
108 :
109 : Datum
6031 bruce 110 16958 : ginint4_consistent(PG_FUNCTION_ARGS)
111 : {
112 16958 : bool *check = (bool *) PG_GETARG_POINTER(0);
113 16958 : StrategyNumber strategy = PG_GETARG_UINT16(1);
4473 tgl 114 16958 : int32 nkeys = PG_GETARG_INT32(3);
115 :
116 : /* Pointer *extra_data = (Pointer *) PG_GETARG_POINTER(4); */
5128 117 16958 : bool *recheck = (bool *) PG_GETARG_POINTER(5);
2062 peter_e 118 16958 : bool res = false;
119 : int32 i;
120 :
6031 bruce 121 16958 : switch (strategy)
122 : {
123 405 : case RTOverlapStrategyNumber:
124 : /* result is not lossy */
5473 tgl 125 405 : *recheck = false;
126 : /* at least one element in check[] is true, so result = true */
2062 peter_e 127 405 : res = true;
5473 tgl 128 405 : break;
6031 bruce 129 632 : case RTContainedByStrategyNumber:
130 : case RTOldContainedByStrategyNumber:
131 : /* we will need recheck */
5473 tgl 132 632 : *recheck = true;
133 : /* at least one element in check[] is true, so result = true */
2062 peter_e 134 632 : res = true;
6031 bruce 135 632 : break;
136 205 : case RTSameStrategyNumber:
137 : /* we will need recheck */
4473 tgl 138 205 : *recheck = true;
139 : /* Must have all elements in check[] true */
2062 peter_e 140 205 : res = true;
4473 tgl 141 413 : for (i = 0; i < nkeys; i++)
142 : {
143 412 : if (!check[i])
144 : {
2062 peter_e 145 204 : res = false;
4473 tgl 146 204 : break;
147 : }
148 : }
5473 149 205 : break;
6031 bruce 150 815 : case RTContainsStrategyNumber:
151 : case RTOldContainsStrategyNumber:
152 : /* result is not lossy */
4473 tgl 153 815 : *recheck = false;
154 : /* Must have all elements in check[] true */
2062 peter_e 155 815 : res = true;
4473 tgl 156 909 : for (i = 0; i < nkeys; i++)
157 : {
158 864 : if (!check[i])
159 : {
2062 peter_e 160 770 : res = false;
4473 tgl 161 770 : break;
162 : }
163 : }
6185 teodor 164 815 : break;
6031 bruce 165 14901 : case BooleanSearchStrategy:
166 : {
4473 tgl 167 14901 : QUERYTYPE *query = PG_GETARG_QUERYTYPE_P(2);
168 :
169 : /* result is not lossy */
5473 170 14901 : *recheck = false;
4473 171 14901 : res = gin_bool_consistent(query, check);
172 : }
6031 bruce 173 14901 : break;
6031 bruce 174 UBC 0 : default:
5473 tgl 175 0 : elog(ERROR, "ginint4_consistent: unknown strategy number: %d",
176 : strategy);
177 : }
178 :
6031 bruce 179 CBC 16958 : PG_RETURN_BOOL(res);
180 : }
|