Newer
Older
/*-------------------------------------------------------------------------
*
* lsyscache.c
* Convenience routines for common queries in the system catalog cache.
* Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
* $PostgreSQL: pgsql/src/backend/utils/cache/lsyscache.c,v 1.135 2006/07/14 14:52:25 momjian Exp $
* Eventually, the index information should go through here, too.
*-------------------------------------------------------------------------
*/
#include "postgres.h"
#include "access/hash.h"
#include "catalog/pg_amop.h"
#include "catalog/pg_amproc.h"
#include "catalog/pg_namespace.h"
#include "catalog/pg_opclass.h"
#include "catalog/pg_proc.h"
#include "catalog/pg_statistic.h"
#include "catalog/pg_type.h"
#include "utils/array.h"
#include "utils/builtins.h"
#include "utils/datum.h"
#include "utils/lsyscache.h"
#include "utils/syscache.h"
/* ---------- AMOP CACHES ---------- */
* op_in_opclass
* Return t iff operator 'opno' is in operator class 'opclass'.
op_in_opclass(Oid opno, Oid opclass)
return SearchSysCacheExists(AMOPOPID,
ObjectIdGetDatum(opno),
ObjectIdGetDatum(opclass),
0, 0);
}
/*
* get_op_opclass_strategy
*
* Get the operator's strategy number within the specified opclass,
* or 0 if it's not a member of the opclass.
*/
int
get_op_opclass_strategy(Oid opno, Oid opclass)
{
HeapTuple tp;
Form_pg_amop amop_tup;
int result;
tp = SearchSysCache(AMOPOPID,
ObjectIdGetDatum(opno),
ObjectIdGetDatum(opclass),
0, 0);
if (!HeapTupleIsValid(tp))
return 0;
amop_tup = (Form_pg_amop) GETSTRUCT(tp);
result = amop_tup->amopstrategy;
ReleaseSysCache(tp);
return result;
}
* get_op_opclass_properties
* Get the operator's strategy number, subtype, and recheck (lossy) flag
* within the specified opclass.
*
* Caller should already have verified that opno is a member of opclass,
* therefore we raise an error if the tuple is not found.
*/
void
get_op_opclass_properties(Oid opno, Oid opclass,
int *strategy, Oid *subtype, bool *recheck)
{
HeapTuple tp;
Form_pg_amop amop_tup;
tp = SearchSysCache(AMOPOPID,
ObjectIdGetDatum(opno),
ObjectIdGetDatum(opclass),
0, 0);
if (!HeapTupleIsValid(tp))
elog(ERROR, "operator %u is not a member of opclass %u",
opno, opclass);
amop_tup = (Form_pg_amop) GETSTRUCT(tp);
*strategy = amop_tup->amopstrategy;
*subtype = amop_tup->amopsubtype;
*recheck = amop_tup->amopreqcheck;
ReleaseSysCache(tp);
/*
* get_opclass_member
* Get the OID of the operator that implements the specified strategy
* with the specified subtype for the specified opclass.
*
* Returns InvalidOid if there is no pg_amop entry for the given keys.
*/
Oid
get_opclass_member(Oid opclass, Oid subtype, int16 strategy)
{
HeapTuple tp;
Form_pg_amop amop_tup;
Oid result;
tp = SearchSysCache(AMOPSTRATEGY,
ObjectIdGetDatum(opclass),
ObjectIdGetDatum(subtype),
Int16GetDatum(strategy),
if (!HeapTupleIsValid(tp))
return InvalidOid;
amop_tup = (Form_pg_amop) GETSTRUCT(tp);
result = amop_tup->amopopr;
ReleaseSysCache(tp);
return result;
}
/*
* get_op_hash_function
* Get the OID of the datatype-specific hash function associated with
* a hashable equality operator.
*
* Returns InvalidOid if no hash function can be found. (This indicates
* that the operator should not have been marked oprcanhash.)
*/
Oid
get_op_hash_function(Oid opno)
{
CatCList *catlist;
int i;
Oid opclass = InvalidOid;
/*
* Search pg_amop to see if the target operator is registered as the "="
* operator of any hash opclass. If the operator is registered in
* multiple opclasses, assume we can use the associated hash function from
* any one.
*/
catlist = SearchSysCacheList(AMOPOPID, 1,
ObjectIdGetDatum(opno),
0, 0, 0);
for (i = 0; i < catlist->n_members; i++)
{
HeapTuple tuple = &catlist->members[i]->tuple;
Form_pg_amop aform = (Form_pg_amop) GETSTRUCT(tuple);
if (aform->amopstrategy == HTEqualStrategyNumber &&
opclass_is_hash(aform->amopclaid))
{
opclass = aform->amopclaid;
break;
}
}
ReleaseSysCacheList(catlist);
if (OidIsValid(opclass))
{
/* Found a suitable opclass, get its default hash support function */
return get_opclass_proc(opclass, InvalidOid, HASHPROC);
}
/* Didn't find a match... */
return InvalidOid;
}
/*
* get_op_btree_interpretation
* Given an operator's OID, find out which btree opclasses it belongs to,
* and what strategy number it has within each one. The results are
* returned as an OID list and a parallel integer list.
*
* In addition to the normal btree operators, we consider a <> operator to be
* a "member" of an opclass if its negator is the opclass' equality operator.
* ROWCOMPARE_NE is returned as the strategy number for this case.
*/
void
get_op_btree_interpretation(Oid opno, List **opclasses, List **opstrats)
{
Oid lefttype,
righttype;
CatCList *catlist;
bool op_negated;
int i;
Loading
Loading full blame...