Skip to content
Snippets Groups Projects
lsyscache.c 58.8 KiB
Newer Older
/*-------------------------------------------------------------------------
 *
 *	  Convenience routines for common queries in the system catalog cache.
 * Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
Bruce Momjian's avatar
Bruce Momjian committed
 * Portions Copyright (c) 1994, Regents of the University of California
 *	  $PostgreSQL: pgsql/src/backend/utils/cache/lsyscache.c,v 1.143 2007/01/10 18:06:04 tgl Exp $
 *	  Eventually, the index information should go through here, too.
 *-------------------------------------------------------------------------
 */
#include "postgres.h"

#include "bootstrap/bootstrap.h"
#include "catalog/pg_amproc.h"
#include "catalog/pg_namespace.h"
#include "catalog/pg_operator.h"
#include "catalog/pg_proc.h"
#include "catalog/pg_statistic.h"
#include "catalog/pg_type.h"
Tom Lane's avatar
Tom Lane committed
#include "nodes/makefuncs.h"
#include "utils/array.h"
#include "utils/builtins.h"
Bruce Momjian's avatar
Bruce Momjian committed
#include "utils/lsyscache.h"
#include "utils/syscache.h"
/*				---------- AMOP CACHES ----------						 */
 *		Return t iff operator 'opno' is in operator family 'opfamily'.
op_in_opfamily(Oid opno, Oid opfamily)
	return SearchSysCacheExists(AMOPOPID,
								ObjectIdGetDatum(opno),
 *		Get the operator's strategy number within the specified opfamily,
 *		or 0 if it's not a member of the opfamily.
get_op_opfamily_strategy(Oid opno, Oid opfamily)
{
	HeapTuple	tp;
	Form_pg_amop amop_tup;
	int			result;

	tp = SearchSysCache(AMOPOPID,
						ObjectIdGetDatum(opno),
						0, 0);
	if (!HeapTupleIsValid(tp))
		return 0;
	amop_tup = (Form_pg_amop) GETSTRUCT(tp);
	result = amop_tup->amopstrategy;
	ReleaseSysCache(tp);
	return result;
}

 *		Get the operator's strategy number, input types, and recheck (lossy)
 *		flag within the specified opfamily.
 * Caller should already have verified that opno is a member of opfamily,
 * therefore we raise an error if the tuple is not found.
 */
get_op_opfamily_properties(Oid opno, Oid opfamily,
						   int *strategy,
						   Oid *lefttype,
						   Oid *righttype,
						   bool *recheck)
{
	HeapTuple	tp;
	Form_pg_amop amop_tup;

	tp = SearchSysCache(AMOPOPID,
						ObjectIdGetDatum(opno),
		elog(ERROR, "operator %u is not a member of opfamily %u",
			 opno, opfamily);
	amop_tup = (Form_pg_amop) GETSTRUCT(tp);
	*strategy = amop_tup->amopstrategy;
	*lefttype = amop_tup->amoplefttype;
	*righttype = amop_tup->amoprighttype;
	*recheck = amop_tup->amopreqcheck;
 *		Get the OID of the operator that implements the specified strategy
 *		with the specified datatypes for the specified opfamily.
 *
 * Returns InvalidOid if there is no pg_amop entry for the given keys.
 */
Oid
get_opfamily_member(Oid opfamily, Oid lefttype, Oid righttype,
					int16 strategy)
{
	HeapTuple	tp;
	Form_pg_amop amop_tup;
	Oid			result;

	tp = SearchSysCache(AMOPSTRATEGY,
						ObjectIdGetDatum(opfamily),
						ObjectIdGetDatum(lefttype),
						ObjectIdGetDatum(righttype),
						Int16GetDatum(strategy));
	if (!HeapTupleIsValid(tp))
		return InvalidOid;
	amop_tup = (Form_pg_amop) GETSTRUCT(tp);
	result = amop_tup->amopopr;
	ReleaseSysCache(tp);
	return result;
}

/*
 * get_op_mergejoin_info
 *		Given the OIDs of a (putatively) mergejoinable equality operator
 *		and a sortop defining the sort ordering of the lefthand input of
 *		the merge clause, determine whether this sort ordering is actually
 *		usable for merging.  If so, return the required sort ordering op
 *		for the righthand input, as well as the btree opfamily OID containing
 *		these operators and the operator strategy number of the two sortops
 *		(either BTLessStrategyNumber or BTGreaterStrategyNumber).
 *
 * We can mergejoin if we find the two operators in the same opfamily as
 * equality and either less-than or greater-than respectively.  If there
 * are multiple such opfamilies, assume we can use any one.
 */
#ifdef NOT_YET
/* eventually should look like this */
bool
get_op_mergejoin_info(Oid eq_op, Oid left_sortop,
					  Oid *right_sortop, Oid *opfamily, int *opstrategy)
{
	bool		result = false;
	Oid			lefttype;
	Oid			righttype;
	CatCList   *catlist;
	int			i;

	/* Make sure output args are initialized even on failure */
	*right_sortop = InvalidOid;
	*opfamily = InvalidOid;
	*opstrategy = 0;

	/* Need the righthand input datatype */
	op_input_types(eq_op, &lefttype, &righttype);

	/*
	 * Search through all the pg_amop entries containing the equality operator
	 */
	catlist = SearchSysCacheList(AMOPOPID, 1,
								 ObjectIdGetDatum(eq_op),
								 0, 0, 0);

	for (i = 0; i < catlist->n_members; i++)
	{
		HeapTuple	op_tuple = &catlist->members[i]->tuple;
		Form_pg_amop op_form = (Form_pg_amop) GETSTRUCT(op_tuple);
		Oid			opfamily_id;
		StrategyNumber op_strategy;

		/* must be btree */
		if (op_form->amopmethod != BTREE_AM_OID)
			continue;
		/* must use the operator as equality */
		if (op_form->amopstrategy != BTEqualStrategyNumber)
			continue;

		/* See if sort operator is also in this opfamily with OK semantics */
		opfamily_id = op_form->amopfamily;
		op_strategy = get_op_opfamily_strategy(left_sortop, opfamily_id);
		if (op_strategy == BTLessStrategyNumber ||
			op_strategy == BTGreaterStrategyNumber)
Loading
Loading full blame...