/* * The inexact GiST distance method for geometric types that store bounding * boxes. * * Compute lossy distance from point to index entries. The result is inexact * because index entries are bounding boxes, not the exact shapes of the * indexed geometric types. We use distance from point to MBR of index entry. * This is a lower bound estimate of distance from point to indexed geometric * type. */ Datum gist_bbox_distance(PG_FUNCTION_ARGS) { GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0); StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2); bool *recheck = (bool *) PG_GETARG_POINTER(4); double distance; StrategyNumber strategyGroup = strategy / GeoStrategyNumberOffset; /* Bounding box distance is always inexact. */ *recheck = true; switch (strategyGroup) { case PointStrategyNumberGroup: distance = computeDistance(false, DatumGetBoxP(entry->key), PG_GETARG_POINT_P(1)); break; default: elog(ERROR, "unknown strategy number: %d", strategy); distance = 0.0; /* keep compiler quiet */ } PG_RETURN_FLOAT8(distance); }
Datum uint28(PG_FUNCTION_ARGS) { uint16 arg = PG_GETARG_UINT16(0); PG_RETURN_UINT64((uint64) arg); }
/* * The GiST Consistent method for circles */ Datum gist_circle_consistent(PG_FUNCTION_ARGS) { GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0); CIRCLE *query = PG_GETARG_CIRCLE_P(1); StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2); /* Oid subtype = PG_GETARG_OID(3); */ bool *recheck = (bool *) PG_GETARG_POINTER(4); BOX bbox; bool result; /* All cases served by this function are inexact */ *recheck = true; if (DatumGetBoxP(entry->key) == NULL || query == NULL) PG_RETURN_BOOL(FALSE); /* * Since the operators require recheck anyway, we can just use * rtree_internal_consistent even at leaf nodes. (This works in part * because the index entries are bounding boxes not circles.) */ bbox.high.x = query->center.x + query->radius; bbox.low.x = query->center.x - query->radius; bbox.high.y = query->center.y + query->radius; bbox.low.y = query->center.y - query->radius; result = rtree_internal_consistent(DatumGetBoxP(entry->key), &bbox, strategy); PG_RETURN_BOOL(result); }
Datum gbt_bpchar_consistent(PG_FUNCTION_ARGS) { GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0); void *query = (void *) DatumGetPointer(PG_DETOAST_DATUM(PG_GETARG_DATUM(1))); StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2); /* Oid subtype = PG_GETARG_OID(3); */ bool *recheck = (bool *) PG_GETARG_POINTER(4); bool retval; GBT_VARKEY *key = (GBT_VARKEY *) DatumGetPointer(entry->key); GBT_VARKEY_R r = gbt_var_key_readable(key); void *trim = (void *) DatumGetPointer(DirectFunctionCall1(rtrim1, PointerGetDatum(query))); /* All cases served by this function are exact */ *recheck = false; if (tinfo.eml == 0) { tinfo.eml = pg_database_encoding_max_length(); } retval = gbt_var_consistent(&r, trim, &strategy, GIST_LEAF(entry), &tinfo); PG_RETURN_BOOL(retval); }
/* * The GiST Consistent method for boxes * * Should return false if for all data items x below entry, * the predicate x op query must be FALSE, where op is the oper * corresponding to strategy in the pg_amop table. */ Datum gist_box_consistent(PG_FUNCTION_ARGS) { GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0); BOX *query = PG_GETARG_BOX_P(1); StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2); /* Oid subtype = PG_GETARG_OID(3); */ bool *recheck = (bool *) PG_GETARG_POINTER(4); /* All cases served by this function are exact */ *recheck = false; if (DatumGetBoxP(entry->key) == NULL || query == NULL) PG_RETURN_BOOL(FALSE); /* * if entry is not leaf, use rtree_internal_consistent, else use * gist_box_leaf_consistent */ if (GIST_LEAF(entry)) PG_RETURN_BOOL(gist_box_leaf_consistent(DatumGetBoxP(entry->key), query, strategy)); else PG_RETURN_BOOL(rtree_internal_consistent(DatumGetBoxP(entry->key), query, strategy)); }
Datum gtsquery_consistent(PG_FUNCTION_ARGS) { GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0); TSQuery query = PG_GETARG_TSQUERY(1); StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2); /* Oid subtype = PG_GETARG_OID(3); */ bool *recheck = (bool *) PG_GETARG_POINTER(4); TSQuerySign key = DatumGetTSQuerySign(entry->key); TSQuerySign sq = makeTSQuerySign(query); bool retval; /* All cases served by this function are inexact */ *recheck = true; switch (strategy) { case RTContainsStrategyNumber: if (GIST_LEAF(entry)) retval = (key & sq) == sq; else retval = (key & sq) != 0; break; case RTContainedByStrategyNumber: if (GIST_LEAF(entry)) retval = (key & sq) == key; else retval = (key & sq) != 0; break; default: retval = FALSE; } PG_RETURN_BOOL(retval); }
/* ** The GiST Consistent method for boxes ** Should return false if for all data items x below entry, ** the predicate x op query == FALSE, where op is the oper ** corresponding to strategy in the pg_amop table. */ Datum g_cube_consistent(PG_FUNCTION_ARGS) { GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0); NDBOX *query = PG_GETARG_NDBOX(1); StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2); /* Oid subtype = PG_GETARG_OID(3); */ bool *recheck = (bool *) PG_GETARG_POINTER(4); bool res; /* All cases served by this function are exact */ *recheck = false; /* * if entry is not leaf, use g_cube_internal_consistent, else use * g_cube_leaf_consistent */ if (GIST_LEAF(entry)) res = g_cube_leaf_consistent(DatumGetNDBOX(entry->key), query, strategy); else res = g_cube_internal_consistent(DatumGetNDBOX(entry->key), query, strategy); PG_FREE_IF_COPY(query, 1); PG_RETURN_BOOL(res); }
Datum gin_extract_hstore_query(PG_FUNCTION_ARGS) { StrategyNumber strategy = PG_GETARG_UINT16(2); if (strategy == HStoreContainsStrategyNumber) { PG_RETURN_DATUM(DirectFunctionCall2( gin_extract_hstore, PG_GETARG_DATUM(0), PG_GETARG_DATUM(1) )); } else if (strategy == HStoreExistsStrategyNumber) { text *item, *q = PG_GETARG_TEXT_P(0); int32 *nentries = (int32 *) PG_GETARG_POINTER(1); Datum *entries = NULL; *nentries = 1; entries = (Datum *) palloc(sizeof(Datum)); item = makeitem(VARDATA(q), VARSIZE(q) - VARHDRSZ); *VARDATA(item) = KEYFLAG; entries[0] = PointerGetDatum(item); PG_RETURN_POINTER(entries); } else elog(ERROR, "Unsupported strategy number: %d", strategy); PG_RETURN_POINTER(NULL); }
Datum gin_triconsistent_jsonb_path(PG_FUNCTION_ARGS) { GinTernaryValue *check = (GinTernaryValue *) PG_GETARG_POINTER(0); StrategyNumber strategy = PG_GETARG_UINT16(1); /* Jsonb *query = PG_GETARG_JSONB_P(2); */ int32 nkeys = PG_GETARG_INT32(3); /* Pointer *extra_data = (Pointer *) PG_GETARG_POINTER(4); */ GinTernaryValue res = GIN_MAYBE; int32 i; if (strategy != JsonbContainsStrategyNumber) elog(ERROR, "unrecognized strategy number: %d", strategy); /* * Note that we never return GIN_TRUE, only GIN_MAYBE or GIN_FALSE; this * corresponds to always forcing recheck in the regular consistent * function, for the reasons listed there. */ for (i = 0; i < nkeys; i++) { if (check[i] == GIN_FALSE) { res = GIN_FALSE; break; } } PG_RETURN_GIN_TERNARY_VALUE(res); }
Datum gtsquery_consistent(PG_FUNCTION_ARGS) { GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0); TSQuerySign *key = (TSQuerySign *) DatumGetPointer(entry->key); TSQuery query = PG_GETARG_TSQUERY(1); StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2); TSQuerySign sq = makeTSQuerySign(query); bool retval; switch (strategy) { case RTContainsStrategyNumber: if (GIST_LEAF(entry)) retval = (*key & sq) == sq; else retval = (*key & sq) != 0; break; case RTContainedByStrategyNumber: if (GIST_LEAF(entry)) retval = (*key & sq) == *key; else retval = (*key & sq) != 0; break; default: retval = FALSE; } PG_RETURN_BOOL(retval); }
/* * The GiST Consistent method for circles */ Datum gist_circle_consistent(PG_FUNCTION_ARGS) { GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0); CIRCLE *query = PG_GETARG_CIRCLE_P(1); StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2); BOX bbox; bool result; if (DatumGetBoxP(entry->key) == NULL || query == NULL) PG_RETURN_BOOL(FALSE); /* * Since the operators are marked lossy anyway, we can just use * rtree_internal_consistent even at leaf nodes. (This works in part * because the index entries are bounding boxes not circles.) */ bbox.high.x = query->center.x + query->radius; bbox.low.x = query->center.x - query->radius; bbox.high.y = query->center.y + query->radius; bbox.low.y = query->center.y - query->radius; result = rtree_internal_consistent(DatumGetBoxP(entry->key), &bbox, strategy); PG_RETURN_BOOL(result); }
Datum gbt_bit_consistent(PG_FUNCTION_ARGS) { GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0); void *query = (void *) DatumGetByteaP(PG_GETARG_DATUM(1)); StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2); /* Oid subtype = PG_GETARG_OID(3); */ bool *recheck = (bool *) PG_GETARG_POINTER(4); bool retval; GBT_VARKEY *key = (GBT_VARKEY *) DatumGetPointer(entry->key); GBT_VARKEY_R r = gbt_var_key_readable(key); /* All cases served by this function are exact */ *recheck = false; if (GIST_LEAF(entry)) retval = gbt_var_consistent(&r, query, strategy, PG_GET_COLLATION(), TRUE, &tinfo); else { bytea *q = gbt_bit_xfrm((bytea *) query); retval = gbt_var_consistent(&r, q, strategy, PG_GET_COLLATION(), FALSE, &tinfo); } PG_RETURN_BOOL(retval); }
Datum gbt_timetz_consistent(PG_FUNCTION_ARGS) { GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0); TimeTzADT *query = PG_GETARG_TIMETZADT_P(1); StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2); /* Oid subtype = PG_GETARG_OID(3); */ bool *recheck = (bool *) PG_GETARG_POINTER(4); timeKEY *kkk = (timeKEY *) DatumGetPointer(entry->key); TimeADT qqq; GBT_NUMKEY_R key; /* All cases served by this function are inexact */ *recheck = true; #ifdef HAVE_INT64_TIMESTAMP qqq = query->time + (query->zone * INT64CONST(1000000)); #else qqq = (query->time + query->zone); #endif key.lower = (GBT_NUMKEY *) &kkk->lower; key.upper = (GBT_NUMKEY *) &kkk->upper; PG_RETURN_BOOL( gbt_num_consistent(&key, (void *) &qqq, &strategy, GIST_LEAF(entry), &tinfo) ); }
/* ** The GiST Consistent method for _intments ** Should return false if for all data items x below entry, ** the predicate x op query == FALSE, where op is the oper ** corresponding to strategy in the pg_amop table. */ Datum g_int_consistent(PG_FUNCTION_ARGS) { GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0); ArrayType *query = (ArrayType *) PG_DETOAST_DATUM_COPY(PG_GETARG_POINTER(1)); StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2); bool retval; if (strategy == BooleanSearchStrategy) { retval =execconsistent((QUERYTYPE *) query, (ArrayType *) DatumGetPointer(entry->key), ISLEAFKEY((ArrayType *) DatumGetPointer(entry->key))); pfree( query ); PG_RETURN_BOOL(retval); } /* sort query for fast search, key is already sorted */ if (ARRISVOID(query)) { pfree( query ); PG_RETURN_BOOL(false); } PREPAREARR(query); switch (strategy) { case RTOverlapStrategyNumber: retval = inner_int_overlap((ArrayType *) DatumGetPointer(entry->key), query); break; case RTSameStrategyNumber: if (GIST_LEAF(entry)) DirectFunctionCall3( g_int_same, entry->key, PointerGetDatum(query), PointerGetDatum(&retval) ); else retval = inner_int_contains((ArrayType *) DatumGetPointer(entry->key), query); break; case RTContainsStrategyNumber: retval = inner_int_contains((ArrayType *) DatumGetPointer(entry->key), query); break; case RTContainedByStrategyNumber: if (GIST_LEAF(entry)) retval = inner_int_contains(query, (ArrayType *) DatumGetPointer(entry->key)); else retval = inner_int_overlap((ArrayType *) DatumGetPointer(entry->key), query); break; default: retval = FALSE; } pfree( query ); PG_RETURN_BOOL(retval); }
Datum uint28mul(PG_FUNCTION_ARGS) { uint16 arg1 = PG_GETARG_UINT16(0); uint64 arg2 = PG_GETARG_UINT64(1); uint64 result; result = arg1 * arg2; /* * Overflow check. We basically check to see if result / arg2 gives arg1 * again. There is one case where this fails: arg2 = 0 (which cannot * overflow). * * Since the division is likely much more expensive than the actual * multiplication, we'd like to skip it where possible. The best bang for * the buck seems to be to check whether both inputs are in the uint32 * range; if so, no overflow is possible. */ if (arg2 != (uint64) ((uint32) arg2) && result / arg2 != arg1) ereport(ERROR, (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), errmsg("bigint out of range"))); PG_RETURN_UINT64(result); }
/* * The GiST Consistent method for polygons */ Datum gist_poly_consistent(PG_FUNCTION_ARGS) { GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0); POLYGON *query = PG_GETARG_POLYGON_P(1); StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2); /* Oid subtype = PG_GETARG_OID(3); */ bool *recheck = (bool *) PG_GETARG_POINTER(4); bool result; /* All cases served by this function are inexact */ *recheck = true; if (DatumGetBoxP(entry->key) == NULL || query == NULL) PG_RETURN_BOOL(FALSE); /* * Since the operators require recheck anyway, we can just use * rtree_internal_consistent even at leaf nodes. (This works in part * because the index entries are bounding boxes not polygons.) */ result = rtree_internal_consistent(DatumGetBoxP(entry->key), &(query->boundbox), strategy); /* Avoid memory leak if supplied poly is toasted */ PG_FREE_IF_COPY(query, 1); PG_RETURN_BOOL(result); }
Datum gin_trgm_consistent(PG_FUNCTION_ARGS) { bool *check = (bool *) PG_GETARG_POINTER(0); StrategyNumber strategy = PG_GETARG_UINT16(1); /* text *query = PG_GETARG_TEXT_P(2); */ int32 nkeys = PG_GETARG_INT32(3); /* Pointer *extra_data = (Pointer *) PG_GETARG_POINTER(4); */ bool *recheck = (bool *) PG_GETARG_POINTER(5); bool res; int32 i, ntrue; /* All cases served by this function are inexact */ *recheck = true; switch (strategy) { case SimilarityStrategyNumber: /* Count the matches */ ntrue = 0; for (i = 0; i < nkeys; i++) { if (check[i]) ntrue++; } #ifdef DIVUNION res = (nkeys == ntrue) ? true : ((((((float4) ntrue) / ((float4) (nkeys - ntrue)))) >= trgm_limit) ? true : false); #else res = (nkeys == 0) ? false : ((((((float4) ntrue) / ((float4) nkeys))) >= trgm_limit) ? true : false); #endif break; case ILikeStrategyNumber: #ifndef IGNORECASE elog(ERROR, "cannot handle ~~* with case-sensitive trigrams"); #endif /* FALL THRU */ case LikeStrategyNumber: /* Check if all extracted trigrams are presented. */ res = true; for (i = 0; i < nkeys; i++) { if (!check[i]) { res = false; break; } } break; default: elog(ERROR, "unrecognized strategy number: %d", strategy); res = false; /* keep compiler quiet */ break; } PG_RETURN_BOOL(res); }
/* * extractQuery support function */ Datum ginqueryarrayextract(PG_FUNCTION_ARGS) { /* Make copy of array input to ensure it doesn't disappear while in use */ ArrayType *array = PG_GETARG_ARRAYTYPE_P_COPY(0); int32 *nkeys = (int32 *) PG_GETARG_POINTER(1); StrategyNumber strategy = PG_GETARG_UINT16(2); /* bool **pmatch = (bool **) PG_GETARG_POINTER(3); */ /* Pointer *extra_data = (Pointer *) PG_GETARG_POINTER(4); */ bool **nullFlags = (bool **) PG_GETARG_POINTER(5); int32 *searchMode = (int32 *) PG_GETARG_POINTER(6); int16 elmlen; bool elmbyval; char elmalign; Datum *elems; bool *nulls; int nelems; get_typlenbyvalalign(ARR_ELEMTYPE(array), &elmlen, &elmbyval, &elmalign); deconstruct_array(array, ARR_ELEMTYPE(array), elmlen, elmbyval, elmalign, &elems, &nulls, &nelems); *nkeys = nelems; *nullFlags = nulls; switch (strategy) { case GinOverlapStrategy: *searchMode = GIN_SEARCH_MODE_DEFAULT; break; case GinContainsStrategy: if (nelems > 0) *searchMode = GIN_SEARCH_MODE_DEFAULT; else /* everything contains the empty set */ *searchMode = GIN_SEARCH_MODE_ALL; break; case GinContainedStrategy: /* empty set is contained in everything */ *searchMode = GIN_SEARCH_MODE_INCLUDE_EMPTY; break; case GinEqualStrategy: if (nelems > 0) *searchMode = GIN_SEARCH_MODE_DEFAULT; else *searchMode = GIN_SEARCH_MODE_INCLUDE_EMPTY; break; default: elog(ERROR, "ginqueryarrayextract: unknown strategy number: %d", strategy); } /* we should not free array, elems[i] points into it */ PG_RETURN_POINTER(elems); }
Datum uint82lt(PG_FUNCTION_ARGS) { uint64 val1 = PG_GETARG_UINT64(0); uint16 val2 = PG_GETARG_UINT16(1); PG_RETURN_BOOL(val1 < val2); }
Datum uint28ge(PG_FUNCTION_ARGS) { uint16 val1 = PG_GETARG_UINT16(0); uint64 val2 = PG_GETARG_UINT64(1); PG_RETURN_BOOL(val1 >= val2); }
Datum geography_gist_consistent(PG_FUNCTION_ARGS) { GISTENTRY *entry = (GISTENTRY*) PG_GETARG_POINTER(0); StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2); bool result; char gidxmem[GIDX_MAX_SIZE]; GIDX *query_gbox_index = (GIDX*)gidxmem; #if POSTGIS_PGSQL_VERSION >= 84 /* PostgreSQL 8.4 and later require the RECHECK flag to be set here, rather than being supplied as part of the operator class definition */ bool *recheck = (bool *) PG_GETARG_POINTER(4); /* We set recheck to false to avoid repeatedly pulling every "possibly matched" geometry out during index scans. For cases when the geometries are large, rechecking can make things twice as slow. */ *recheck = false; #endif POSTGIS_DEBUG(4, "[GIST] 'consistent' function called"); /* Quick sanity check on query argument. */ if ( DatumGetPointer(PG_GETARG_DATUM(1)) == NULL ) { POSTGIS_DEBUG(4, "[GIST] null query pointer (!?!), returning false"); PG_RETURN_BOOL(FALSE); /* NULL query! This is screwy! */ } /* Quick sanity check on entry key. */ if ( DatumGetPointer(entry->key) == NULL ) { POSTGIS_DEBUG(4, "[GIST] null index entry, returning false"); PG_RETURN_BOOL(FALSE); /* NULL entry! */ } /* Null box should never make this far. */ if ( geography_datum_gidx(PG_GETARG_DATUM(1), query_gbox_index) == G_FAILURE ) { POSTGIS_DEBUG(4, "[GIST] null query_gbox_index!"); PG_RETURN_BOOL(FALSE); } /* Treat leaf node tests different from internal nodes */ if (GIST_LEAF(entry)) { result = geography_gist_consistent_leaf( (GIDX*)DatumGetPointer(entry->key), query_gbox_index, strategy); } else { result = geography_gist_consistent_internal( (GIDX*)DatumGetPointer(entry->key), query_gbox_index, strategy); } PG_RETURN_BOOL(result); }
Datum gin_extract_tsquery(PG_FUNCTION_ARGS) { TSQuery query = PG_GETARG_TSQUERY(0); int32 *nentries = (int32 *) PG_GETARG_POINTER(1); StrategyNumber strategy = PG_GETARG_UINT16(2); Datum *entries = NULL; *nentries = 0; if (query->size > 0) { int4 i, j = 0, len; QueryItem *item; item = clean_NOT(GETQUERY(query), &len); if (!item) ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("query requires full scan, which is not supported by GIN indexes"))); item = GETQUERY(query); for (i = 0; i < query->size; i++) if (item[i].type == QI_VAL) (*nentries)++; entries = (Datum *) palloc(sizeof(Datum) * (*nentries)); for (i = 0; i < query->size; i++) if (item[i].type == QI_VAL) { text *txt; QueryOperand *val = &item[i].operand; txt = (text *) palloc(VARHDRSZ + val->length); SET_VARSIZE(txt, VARHDRSZ + val->length); memcpy(VARDATA(txt), GETOPERAND(query) + val->distance, val->length); entries[j++] = PointerGetDatum(txt); if (strategy != TSearchWithClassStrategyNumber && val->weight != 0) ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("@@ operator does not support lexeme weight restrictions in GIN index searches"), errhint("Use the @@@ operator instead."))); } } else *nentries = -1; /* nothing can be found */ PG_FREE_IF_COPY(query, 0); PG_RETURN_POINTER(entries); }
/* ** The GiST Consistent method for _intments ** Should return false if for all data items x below entry, ** the predicate x op query == FALSE, where op is the oper ** corresponding to strategy in the pg_amop table. */ Datum g_int_consistent(PG_FUNCTION_ARGS) { GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0); ArrayType *query = (ArrayType *) PG_GETARG_POINTER(1); StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2); bool retval; if (strategy == BooleanSearchStrategy) PG_RETURN_BOOL(execconsistent((QUERYTYPE *) query, (ArrayType *) DatumGetPointer(entry->key), ISLEAFKEY((ArrayType *) DatumGetPointer(entry->key)))); /* XXX are we sure it's safe to scribble on the query object here? */ /* XXX what about toasted input? */ /* sort query for fast search, key is already sorted */ if (ARRISVOID(query)) PG_RETURN_BOOL(false); PREPAREARR(query); switch (strategy) { case RTOverlapStrategyNumber: retval = inner_int_overlap((ArrayType *) DatumGetPointer(entry->key), query); break; case RTSameStrategyNumber: if (GIST_LEAF(entry)) DirectFunctionCall3( g_int_same, entry->key, PointerGetDatum(query), PointerGetDatum(&retval) ); else retval = inner_int_contains((ArrayType *) DatumGetPointer(entry->key), query); break; case RTContainsStrategyNumber: retval = inner_int_contains((ArrayType *) DatumGetPointer(entry->key), query); break; case RTContainedByStrategyNumber: if (GIST_LEAF(entry)) retval = inner_int_contains(query, (ArrayType *) DatumGetPointer(entry->key)); else retval = inner_int_overlap((ArrayType *) DatumGetPointer(entry->key), query); break; default: retval = FALSE; } PG_RETURN_BOOL(retval); }
Datum uint82pl(PG_FUNCTION_ARGS) { uint64 arg1 = PG_GETARG_UINT64(0); uint16 arg2 = PG_GETARG_UINT16(1); if (arg1 > ULONG_LONG_MAX - arg2) report_out_of_range(); PG_RETURN_UINT64(arg1 + arg2); }
Datum uint82mi(PG_FUNCTION_ARGS) { uint64 arg1 = PG_GETARG_UINT64(0); uint16 arg2 = PG_GETARG_UINT16(1); if (arg2 - arg1) report_out_of_range(); PG_RETURN_UINT64(arg1 - arg2); }
Datum gbt_cidr_consistent(PG_FUNCTION_ARGS) { GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0); double query = convert_network_to_scalar(PG_GETARG_DATUM(1), CIDROID); StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2); PG_RETURN_BOOL( gbt_inet_consistent_internal(entry, &query, &strategy) ); }
Datum uint82div(PG_FUNCTION_ARGS) { uint64 arg1 = PG_GETARG_UINT64(0); uint16 arg2 = PG_GETARG_UINT16(1); if (arg2 == 0) report_division_by_zero(); PG_RETURN_UINT64(arg1 / arg2); }
Datum gin_consistent_jsonb_path(PG_FUNCTION_ARGS) { bool *check = (bool *) PG_GETARG_POINTER(0); StrategyNumber strategy = PG_GETARG_UINT16(1); /* Jsonb *query = PG_GETARG_JSONB_P(2); */ int32 nkeys = PG_GETARG_INT32(3); Pointer *extra_data = (Pointer *) PG_GETARG_POINTER(4); bool *recheck = (bool *) PG_GETARG_POINTER(5); bool res = true; int32 i; if (strategy == JsonbContainsStrategyNumber) { /* * jsonb_path_ops is necessarily lossy, not only because of hash * collisions but also because it doesn't preserve complete * information about the structure of the JSON object. Besides, there * are some special rules around the containment of raw scalars in * arrays that are not handled here. So we must always recheck a * match. However, if not all of the keys are present, the tuple * certainly doesn't match. */ *recheck = true; for (i = 0; i < nkeys; i++) { if (!check[i]) { res = false; break; } } } else if (strategy == JsonbJsonpathPredicateStrategyNumber || strategy == JsonbJsonpathExistsStrategyNumber) { *recheck = true; if (nkeys > 0) { Assert(extra_data && extra_data[0]); res = execute_jsp_gin_node((JsonPathGinNode *) extra_data[0], check, false) != GIN_FALSE; } } else elog(ERROR, "unrecognized strategy number: %d", strategy); PG_RETURN_BOOL(res); }
Datum gin_consistent_hstore(PG_FUNCTION_ARGS) { bool *check = (bool *) PG_GETARG_POINTER(0); StrategyNumber strategy = PG_GETARG_UINT16(1); /* HStore *query = PG_GETARG_HS(2); */ int32 nkeys = PG_GETARG_INT32(3); /* Pointer *extra_data = (Pointer *) PG_GETARG_POINTER(4); */ bool *recheck = (bool *) PG_GETARG_POINTER(5); bool res = true; *recheck = false; if (strategy == HStoreContainsStrategyNumber) { int i; /* * Index lost information about correspondence of keys and values, so * we need recheck (pre-8.4 this is handled at SQL level) */ *recheck = true; for (i = 0; res && i < nkeys; i++) if (check[i] == false) res = false; } else if (strategy == HStoreExistsStrategyNumber) { /* Existence of key is guaranteed */ res = true; } else if (strategy == HStoreExistsAnyStrategyNumber) { /* Existence of key is guaranteed */ res = true; } else if (strategy == HStoreExistsAllStrategyNumber) { int i; for (i = 0; res && i < nkeys; ++i) if (!check[i]) res = false; } else elog(ERROR, "Unsupported strategy number: %d", strategy); PG_RETURN_BOOL(res); }
Datum uint82mul(PG_FUNCTION_ARGS) { uint64 arg1 = PG_GETARG_UINT64(0); uint16 arg2 = PG_GETARG_UINT16(1); uint64 result; result = arg1 * arg2; if (arg2 != 0 && arg1 > UINT_MAX && result / arg2 != arg1) report_out_of_range(); PG_RETURN_UINT64(result); }