Пример #1
0
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));
}
Пример #2
0
/* ----------------
 *		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);
}
Пример #3
0
/*
 * 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;
}
Пример #4
0
static Datum call_delete_hstore_text(Datum hstore_0, Datum text_1){
    return OidFunctionCall2(delete_hstore_text_oid, hstore_0, text_1);
}