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