diff options
Diffstat (limited to 'src/backend/utils/cache/lsyscache.c')
-rw-r--r-- | src/backend/utils/cache/lsyscache.c | 484 |
1 files changed, 484 insertions, 0 deletions
diff --git a/src/backend/utils/cache/lsyscache.c b/src/backend/utils/cache/lsyscache.c new file mode 100644 index 00000000000..b7fc5e26201 --- /dev/null +++ b/src/backend/utils/cache/lsyscache.c @@ -0,0 +1,484 @@ +/*------------------------------------------------------------------------- + * + * lsyscache.c-- + * Routines to access information within system caches + * + * Copyright (c) 1994, Regents of the University of California + * + * + * IDENTIFICATION + * $Header: /cvsroot/pgsql/src/backend/utils/cache/lsyscache.c,v 1.1.1.1 1996/07/09 06:22:06 scrappy Exp $ + * + * NOTES + * Eventually, the index information should go through here, too. + * + * Most of these routines call SearchSysCacheStruct() and thus simply + * (1) allocate some space for the return struct and (2) call it. + * + *------------------------------------------------------------------------- + */ +#include <string.h> +#include "postgres.h" + +#include "nodes/pg_list.h" +#include "utils/syscache.h" +#include "utils/lsyscache.h" +#include "access/tupmacs.h" +#include "utils/rel.h" +#include "utils/palloc.h" +#include "utils/elog.h" +#include "access/attnum.h" +#include "access/heapam.h" + +#include "catalog/pg_amop.h" +#include "catalog/pg_type.h" + +/* ---------- AMOP CACHES ---------- */ + +/* + * op_class - + * + * Return t iff operator 'opno' is in operator class 'opclass'. + * + */ +bool +op_class(Oid opno, int32 opclass, Oid amopid) +{ + FormData_pg_amop amoptup; + + if (SearchSysCacheStruct(AMOPOPID, + (char *) &amoptup, + ObjectIdGetDatum(opclass), + ObjectIdGetDatum(opno), + ObjectIdGetDatum(amopid), + 0)) + return(true); + else + return(false); +} + +/* ---------- ATTRIBUTE CACHES ---------- */ + +/* + * get_attname - + * + * Given the relation id and the attribute number, + * return the "attname" field from the attribute relation. + * + */ +char* +get_attname(Oid relid, AttrNumber attnum) +{ + FormData_pg_attribute att_tup; + char *retval; + + if (SearchSysCacheStruct(ATTNUM, + (char*)&att_tup, + ObjectIdGetDatum(relid), + UInt16GetDatum(attnum), + 0,0)) { + retval = pstrdup(att_tup.attname.data); + + return(retval); + } + else + return(NULL); +} + +/* + * get_attnum - + * + * Given the relation id and the attribute name, + * return the "attnum" field from the attribute relation. + * + */ +AttrNumber +get_attnum(Oid relid, char *attname) +{ + FormData_pg_attribute att_tup; + + if (SearchSysCacheStruct(ATTNAME, (char *) &att_tup, + ObjectIdGetDatum(relid), + PointerGetDatum(attname), + 0,0)) + return(att_tup.attnum); + else + return(InvalidAttrNumber); +} + +/* + * get_atttype - + * + * Given the relation OID and the attribute number with the relation, + * return the attribute type OID. + * + */ +Oid +get_atttype(Oid relid, AttrNumber attnum) +{ + AttributeTupleForm att_tup = (AttributeTupleForm)palloc(sizeof(*att_tup)); + + if (SearchSysCacheStruct(ATTNUM, + (char *) att_tup, + ObjectIdGetDatum(relid), + UInt16GetDatum(attnum), + 0,0)) + return(att_tup->atttypid); + else + return((Oid)NULL); +} + +/* This routine uses the attname instead of the attnum because it + * replaces the routine find_atttype, which is called sometimes when + * only the attname, not the attno, is available. + */ +bool +get_attisset(Oid relid, char *attname) +{ + HeapTuple htup; + AttrNumber attno; + AttributeTupleForm att_tup; + + attno = get_attnum(relid, attname); + + htup = SearchSysCacheTuple(ATTNAME, + ObjectIdGetDatum(relid), + PointerGetDatum(attname), + 0,0); + if (!HeapTupleIsValid(htup)) + elog(WARN, "get_attisset: no attribute %.16s in relation %d", + attname, relid); + if (heap_attisnull(htup, attno)) + return(false); + else { + att_tup = (AttributeTupleForm)GETSTRUCT(htup); + return(att_tup->attisset); + } +} + +/* ---------- INDEX CACHE ---------- */ + +/* watch this space... + */ + +/* ---------- OPERATOR CACHE ---------- */ + +/* + * get_opcode - + * + * Returns the regproc id of the routine used to implement an + * operator given the operator uid. + * + */ +RegProcedure +get_opcode(Oid opno) +{ + FormData_pg_operator optup; + + if (SearchSysCacheStruct(OPROID, (char *) &optup, + ObjectIdGetDatum(opno), + 0,0,0)) + return(optup.oprcode); + else + return((RegProcedure)NULL); +} + +/* + * get_opname - + * returns the name of the operator with the given opno + * + * Note: return the struct so that it gets copied. + */ +char* +get_opname(Oid opno) +{ + FormData_pg_operator optup; + + if (SearchSysCacheStruct(OPROID, (char *) &optup, + ObjectIdGetDatum(opno), + 0,0,0)) + return (pstrdup(optup.oprname.data)); + else { + elog(WARN, "can't look up operator %d\n", opno); + return NULL; + } +} + +/* + * op_mergesortable - + * + * Returns the left and right sort operators and types corresponding to a + * mergesortable operator, or nil if the operator is not mergesortable. + * + */ +bool +op_mergesortable(Oid opno, Oid ltype, Oid rtype, Oid *leftOp, Oid *rightOp) +{ + FormData_pg_operator optup; + + if (SearchSysCacheStruct(OPROID, (char *) &optup, + ObjectIdGetDatum(opno), + 0,0,0) && + optup.oprlsortop && + optup.oprrsortop && + optup.oprleft == ltype && + optup.oprright == rtype) { + + *leftOp = ObjectIdGetDatum(optup.oprlsortop); + *rightOp = ObjectIdGetDatum(optup.oprrsortop); + return TRUE; + } else { + return FALSE; + } +} + +/* + * op_hashjoinable-- + * + * Returns the hash operator corresponding to a hashjoinable operator, + * or nil if the operator is not hashjoinable. + * + */ +Oid +op_hashjoinable(Oid opno, Oid ltype, Oid rtype) +{ + FormData_pg_operator optup; + + if (SearchSysCacheStruct(OPROID, (char *) &optup, + ObjectIdGetDatum(opno), + 0,0,0) && + optup.oprcanhash && + optup.oprleft == ltype && + optup.oprright == rtype) + return(opno); + else + return(InvalidOid); +} + +/* + * get_commutator - + * + * Returns the corresponding commutator of an operator. + * + */ +Oid +get_commutator(Oid opno) +{ + FormData_pg_operator optup; + + if (SearchSysCacheStruct(OPROID, (char *) &optup, + ObjectIdGetDatum(opno), + 0,0,0)) + return(optup.oprcom); + else + return((Oid)NULL); +} + +HeapTuple +get_operator_tuple(Oid opno) +{ + HeapTuple optup; + + if ((optup = SearchSysCacheTuple(OPROID, + ObjectIdGetDatum(opno), + 0,0,0))) + return(optup); + else + return((HeapTuple)NULL); +} + +/* + * get_negator - + * + * Returns the corresponding negator of an operator. + * + */ +Oid +get_negator(Oid opno) +{ + FormData_pg_operator optup; + + if (SearchSysCacheStruct(OPROID, (char *) &optup, + ObjectIdGetDatum(opno), + 0,0,0)) + return(optup.oprnegate); + else + return((Oid)NULL); +} + +/* + * get_oprrest - + * + * Returns procedure id for computing selectivity of an operator. + * + */ +RegProcedure +get_oprrest(Oid opno) +{ + FormData_pg_operator optup; + + if (SearchSysCacheStruct(OPROID, (char *) &optup, + ObjectIdGetDatum(opno), + 0,0,0)) + return(optup.oprrest ); + else + return((RegProcedure) NULL); +} + +/* + * get_oprjoin - + * + * Returns procedure id for computing selectivity of a join. + * + */ +RegProcedure +get_oprjoin(Oid opno) +{ + FormData_pg_operator optup; + + if (SearchSysCacheStruct(OPROID, (char *) &optup, + ObjectIdGetDatum(opno), + 0,0,0)) + return(optup.oprjoin); + else + return((RegProcedure)NULL); +} + +/* ---------- RELATION CACHE ---------- */ + +/* + * get_relnatts - + * + * Returns the number of attributes for a given relation. + * + */ +int +get_relnatts(Oid relid) +{ + FormData_pg_class reltup; + + if (SearchSysCacheStruct(RELOID, (char *) &reltup, + ObjectIdGetDatum(relid), + 0,0,0)) + return(reltup.relnatts); + else + return(InvalidAttrNumber); +} + +/* + * get_rel_name - + * + * Returns the name of a given relation. + * + */ +char* +get_rel_name(Oid relid) +{ + FormData_pg_class reltup; + + if ((SearchSysCacheStruct(RELOID, + (char*)&reltup, + ObjectIdGetDatum(relid), + 0,0,0))) { + return (pstrdup(reltup.relname.data)); + } else + return(NULL); +} + +/* ---------- TYPE CACHE ---------- */ + +/* + * get_typlen - + * + * Given the type OID, return the length of the type. + * + */ +int16 +get_typlen(Oid typid) +{ + TypeTupleFormData typtup; + + if (SearchSysCacheStruct(TYPOID, (char *) &typtup, + ObjectIdGetDatum(typid), + 0,0,0)) + return(typtup.typlen); + else + return((int16)NULL); +} + +/* + * get_typbyval - + * + * Given the type OID, determine whether the type is returned by value or + * not. Returns 1 if by value, 0 if by reference. + * + */ +bool +get_typbyval(Oid typid) +{ + TypeTupleFormData typtup; + + if (SearchSysCacheStruct(TYPOID, (char *) &typtup, + ObjectIdGetDatum(typid), + 0,0,0)) + return((bool)typtup.typbyval); + else + return(false); +} + +/* + * get_typbyval - + * + * Given the type OID, determine whether the type is returned by value or + * not. Returns 1 if by value, 0 if by reference. + * + */ +char +get_typalign(Oid typid) +{ + TypeTupleFormData typtup; + + if (SearchSysCacheStruct(TYPOID, (char *) &typtup, + ObjectIdGetDatum(typid), + 0,0,0)) + return(typtup.typalign); + else + return ('i'); +} + +/* + * get_typdefault - + * + * Given the type OID, return the default value of the ADT. + * + */ +struct varlena * +get_typdefault(Oid typid) +{ + struct varlena *typdefault = + (struct varlena *)TypeDefaultRetrieve (typid); + return(typdefault); +} + +/* + * get_typtype - + * + * Given the type OID, find if it is a basic type, a named relation + * or the generic type 'relation'. + * It returns the null char if the cache lookup fails... + * + */ +char +get_typtype(Oid typid) +{ + TypeTupleFormData typtup; + + if (SearchSysCacheStruct(TYPOID, (char *) &typtup, + ObjectIdGetDatum(typid), + 0,0,0)) { + return(typtup.typtype); + } else { + return('\0'); + } +} + |