static bool assert_equals_base(FunctionCallInfo fcinfo) { Datum value1 = PG_GETARG_DATUM(0); Datum value2 = PG_GETARG_DATUM(1); Oid *ptr; ptr = (Oid *) fcinfo->flinfo->fn_extra; if (ptr == NULL) { Oid valtype = get_fn_expr_argtype(fcinfo->flinfo, 0); Oid eqopfcid; if (!OidIsValid(valtype)) elog(ERROR, "could not determine data type of input"); eqopfcid = equality_oper_funcid(valtype); if (!OidIsValid(eqopfcid)) ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("unknown equal operand for datatype"))); /* First time calling for current query: allocate storage */ fcinfo->flinfo->fn_extra = MemoryContextAlloc(fcinfo->flinfo->fn_mcxt, sizeof(Oid)); ptr = (Oid *) fcinfo->flinfo->fn_extra; *ptr = eqopfcid; } return DatumGetBool(OidFunctionCall2(*ptr, value1, value2)); }
/* ---------------- * index_rescan - (re)start a scan of an index * * The caller may specify a new set of scankeys (but the number of keys * cannot change). To restart the scan without changing keys, pass NULL * for the key array. * * Note that this is also called when first starting an indexscan; * see RelationGetIndexScan. Keys *must* be passed in that case, * unless scan->numberOfKeys is zero. * ---------------- */ void index_rescan(IndexScanDesc scan, ScanKey key) { RegProcedure procedure; SCAN_CHECKS; GET_SCAN_PROCEDURE(rescan, amrescan); scan->kill_prior_tuple = false; /* for safety */ scan->keys_are_unique = false; /* may be set by index AM */ scan->got_tuple = false; scan->unique_tuple_pos = 0; scan->unique_tuple_mark = 0; OidFunctionCall2(procedure, PointerGetDatum(scan), PointerGetDatum(key)); pgstat_reset_index_scan(&scan->xs_pgstat_info); }
/* * Compare two scankey values using a specified operator. Both values * must be already known non-NULL. * * The test we want to perform is logically "leftarg op rightarg", where * leftarg and rightarg are the sk_argument values in those ScanKeys, and * the comparison operator is the one in the op ScanKey. However, in * cross-data-type situations we may need to look up the correct operator in * the index's opfamily: it is the one having amopstrategy = op->sk_strategy * and amoplefttype/amoprighttype equal to the two argument datatypes. * * If the opfamily doesn't supply a complete set of cross-type operators we * may not be able to make the comparison. If we can make the comparison * we store the operator result in *result and return TRUE. We return FALSE * if the comparison could not be made. * * Note: op always points at the same ScanKey as either leftarg or rightarg. * Since we don't scribble on the scankeys, this aliasing should cause no * trouble. * * Note: this routine needs to be insensitive to any DESC option applied * to the index column. For example, "x < 4" is a tighter constraint than * "x < 5" regardless of which way the index is sorted. We don't worry about * NULLS FIRST/LAST either, since the given values are never nulls. */ static bool _bt_compare_scankey_args(IndexScanDesc scan, ScanKey op, ScanKey leftarg, ScanKey rightarg, bool *result) { Relation rel = scan->indexRelation; Oid lefttype, righttype, optype, opcintype, cmp_op; StrategyNumber strat; /* * The opfamily we need to worry about is identified by the index column. */ Assert(leftarg->sk_attno == rightarg->sk_attno); opcintype = rel->rd_opcintype[leftarg->sk_attno - 1]; /* * Determine the actual datatypes of the ScanKey arguments. We have to * support the convention that sk_subtype == InvalidOid means the opclass * input type; this is a hack to simplify life for ScanKeyInit(). */ lefttype = leftarg->sk_subtype; if (lefttype == InvalidOid) lefttype = opcintype; righttype = rightarg->sk_subtype; if (righttype == InvalidOid) righttype = opcintype; optype = op->sk_subtype; if (optype == InvalidOid) optype = opcintype; /* * If leftarg and rightarg match the types expected for the "op" scankey, * we can use its already-looked-up comparison function. */ if (lefttype == opcintype && righttype == optype) { *result = DatumGetBool(FunctionCall2(&op->sk_func, leftarg->sk_argument, rightarg->sk_argument)); return true; } /* * Otherwise, we need to go to the syscache to find the appropriate * operator. (This cannot result in infinite recursion, since no * indexscan initiated by syscache lookup will use cross-data-type * operators.) * * If the sk_strategy was flipped by _bt_mark_scankey_with_indoption, we * have to un-flip it to get the correct opfamily member. */ strat = op->sk_strategy; if (op->sk_flags & SK_BT_DESC) strat = BTCommuteStrategyNumber(strat); cmp_op = get_opfamily_member(rel->rd_opfamily[leftarg->sk_attno - 1], lefttype, righttype, strat); if (OidIsValid(cmp_op)) { RegProcedure cmp_proc = get_opcode(cmp_op); if (RegProcedureIsValid(cmp_proc)) { *result = DatumGetBool(OidFunctionCall2(cmp_proc, leftarg->sk_argument, rightarg->sk_argument)); return true; } } /* Can't make the comparison */ *result = false; /* suppress compiler warnings */ return false; }
static Datum call_delete_hstore_text(Datum hstore_0, Datum text_1){ return OidFunctionCall2(delete_hstore_text_oid, hstore_0, text_1); }