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 : 10 CBC 2 : PG_FUNCTION_INFO_V1(ginint4_queryextract); 11 : 12 : Datum 13 26 : ginint4_queryextract(PG_FUNCTION_ARGS) 14 : { 15 26 : int32 *nentries = (int32 *) PG_GETARG_POINTER(1); 16 26 : StrategyNumber strategy = PG_GETARG_UINT16(2); 17 26 : int32 *searchMode = (int32 *) PG_GETARG_POINTER(6); 18 26 : Datum *res = NULL; 19 : 20 26 : *nentries = 0; 21 : 22 26 : if (strategy == BooleanSearchStrategy) 23 : { 24 12 : QUERYTYPE *query = PG_GETARG_QUERYTYPE_P(0); 25 12 : ITEM *items = GETQUERY(query); 26 : int i; 27 : 28 : /* empty query must fail */ 29 12 : if (query->size <= 0) 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 : */ 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 : */ 45 12 : res = (Datum *) palloc(sizeof(Datum) * query->size); 46 12 : *nentries = 0; 47 : 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); 53 28 : (*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 = (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 : 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 UBC 0 : *searchMode = GIN_SEARCH_MODE_INCLUDE_EMPTY; 90 CBC 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 UBC 0 : *searchMode = GIN_SEARCH_MODE_ALL; 97 CBC 8 : break; 98 UBC 0 : default: 99 0 : elog(ERROR, "ginint4_queryextract: unknown strategy number: %d", 100 : strategy); 101 : } 102 : } 103 : 104 CBC 26 : PG_RETURN_POINTER(res); 105 : } 106 : 107 2 : PG_FUNCTION_INFO_V1(ginint4_consistent); 108 : 109 : Datum 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); 114 16958 : int32 nkeys = PG_GETARG_INT32(3); 115 : 116 : /* Pointer *extra_data = (Pointer *) PG_GETARG_POINTER(4); */ 117 16958 : bool *recheck = (bool *) PG_GETARG_POINTER(5); 118 16958 : bool res = false; 119 : int32 i; 120 : 121 16958 : switch (strategy) 122 : { 123 405 : case RTOverlapStrategyNumber: 124 : /* result is not lossy */ 125 405 : *recheck = false; 126 : /* at least one element in check[] is true, so result = true */ 127 405 : res = true; 128 405 : break; 129 632 : case RTContainedByStrategyNumber: 130 : case RTOldContainedByStrategyNumber: 131 : /* we will need recheck */ 132 632 : *recheck = true; 133 : /* at least one element in check[] is true, so result = true */ 134 632 : res = true; 135 632 : break; 136 205 : case RTSameStrategyNumber: 137 : /* we will need recheck */ 138 205 : *recheck = true; 139 : /* Must have all elements in check[] true */ 140 205 : res = true; 141 413 : for (i = 0; i < nkeys; i++) 142 : { 143 412 : if (!check[i]) 144 : { 145 204 : res = false; 146 204 : break; 147 : } 148 : } 149 205 : break; 150 815 : case RTContainsStrategyNumber: 151 : case RTOldContainsStrategyNumber: 152 : /* result is not lossy */ 153 815 : *recheck = false; 154 : /* Must have all elements in check[] true */ 155 815 : res = true; 156 909 : for (i = 0; i < nkeys; i++) 157 : { 158 864 : if (!check[i]) 159 : { 160 770 : res = false; 161 770 : break; 162 : } 163 : } 164 815 : break; 165 14901 : case BooleanSearchStrategy: 166 : { 167 14901 : QUERYTYPE *query = PG_GETARG_QUERYTYPE_P(2); 168 : 169 : /* result is not lossy */ 170 14901 : *recheck = false; 171 14901 : res = gin_bool_consistent(query, check); 172 : } 173 14901 : break; 174 UBC 0 : default: 175 0 : elog(ERROR, "ginint4_consistent: unknown strategy number: %d", 176 : strategy); 177 : } 178 : 179 CBC 16958 : PG_RETURN_BOOL(res); 180 : }