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