summaryrefslogtreecommitdiff
path: root/src/backend/utils/cache/lsyscache.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/utils/cache/lsyscache.c')
-rw-r--r--src/backend/utils/cache/lsyscache.c1389
1 files changed, 0 insertions, 1389 deletions
diff --git a/src/backend/utils/cache/lsyscache.c b/src/backend/utils/cache/lsyscache.c
deleted file mode 100644
index 233910a85c3..00000000000
--- a/src/backend/utils/cache/lsyscache.c
+++ /dev/null
@@ -1,1389 +0,0 @@
-/*-------------------------------------------------------------------------
- *
- * lsyscache.c
- * Convenience routines for common queries in the system catalog cache.
- *
- * Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
- * Portions Copyright (c) 1994, Regents of the University of California
- *
- * IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/utils/cache/lsyscache.c,v 1.74 2002/06/20 20:29:39 momjian Exp $
- *
- * NOTES
- * Eventually, the index information should go through here, too.
- *-------------------------------------------------------------------------
- */
-#include "postgres.h"
-
-#include "access/tupmacs.h"
-#include "catalog/pg_amop.h"
-#include "catalog/pg_namespace.h"
-#include "catalog/pg_opclass.h"
-#include "catalog/pg_operator.h"
-#include "catalog/pg_proc.h"
-#include "catalog/pg_shadow.h"
-#include "catalog/pg_statistic.h"
-#include "catalog/pg_type.h"
-#include "nodes/makefuncs.h"
-#include "utils/array.h"
-#include "utils/builtins.h"
-#include "utils/lsyscache.h"
-#include "utils/syscache.h"
-
-
-/* ---------- AMOP CACHES ---------- */
-
-/*
- * op_in_opclass
- *
- * Return t iff operator 'opno' is in operator class 'opclass'.
- */
-bool
-op_in_opclass(Oid opno, Oid opclass)
-{
- return SearchSysCacheExists(AMOPOPID,
- ObjectIdGetDatum(opclass),
- ObjectIdGetDatum(opno),
- 0, 0);
-}
-
-/*
- * op_requires_recheck
- *
- * Return t if operator 'opno' requires a recheck when used as a
- * member of opclass 'opclass' (ie, this opclass is lossy for this
- * operator).
- *
- * Caller should already have verified that opno is a member of opclass,
- * therefore we raise an error if the tuple is not found.
- */
-bool
-op_requires_recheck(Oid opno, Oid opclass)
-{
- HeapTuple tp;
- Form_pg_amop amop_tup;
- bool result;
-
- tp = SearchSysCache(AMOPOPID,
- ObjectIdGetDatum(opclass),
- ObjectIdGetDatum(opno),
- 0, 0);
- if (!HeapTupleIsValid(tp))
- elog(ERROR, "op_requires_recheck: op %u is not a member of opclass %u",
- opno, opclass);
- amop_tup = (Form_pg_amop) GETSTRUCT(tp);
-
- result = amop_tup->amopreqcheck;
- ReleaseSysCache(tp);
- return result;
-}
-
-/* ---------- ATTRIBUTE CACHES ---------- */
-
-/*
- * get_attname
- *
- * Given the relation id and the attribute number,
- * return the "attname" field from the attribute relation.
- *
- * Note: returns a palloc'd copy of the string, or NULL if no such operator.
- */
-char *
-get_attname(Oid relid, AttrNumber attnum)
-{
- HeapTuple tp;
-
- tp = SearchSysCache(ATTNUM,
- ObjectIdGetDatum(relid),
- Int16GetDatum(attnum),
- 0, 0);
- if (HeapTupleIsValid(tp))
- {
- Form_pg_attribute att_tup = (Form_pg_attribute) GETSTRUCT(tp);
- char *result;
-
- result = pstrdup(NameStr(att_tup->attname));
- ReleaseSysCache(tp);
- return result;
- }
- 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)
-{
- HeapTuple tp;
-
- tp = SearchSysCache(ATTNAME,
- ObjectIdGetDatum(relid),
- PointerGetDatum(attname),
- 0, 0);
- if (HeapTupleIsValid(tp))
- {
- Form_pg_attribute att_tup = (Form_pg_attribute) GETSTRUCT(tp);
- AttrNumber result;
-
- result = att_tup->attnum;
- ReleaseSysCache(tp);
- return result;
- }
- 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)
-{
- HeapTuple tp;
-
- tp = SearchSysCache(ATTNUM,
- ObjectIdGetDatum(relid),
- Int16GetDatum(attnum),
- 0, 0);
- if (HeapTupleIsValid(tp))
- {
- Form_pg_attribute att_tup = (Form_pg_attribute) GETSTRUCT(tp);
- Oid result;
-
- result = att_tup->atttypid;
- ReleaseSysCache(tp);
- return result;
- }
- else
- return InvalidOid;
-}
-
-/* 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 tp;
-
- tp = SearchSysCache(ATTNAME,
- ObjectIdGetDatum(relid),
- PointerGetDatum(attname),
- 0, 0);
- if (HeapTupleIsValid(tp))
- {
- Form_pg_attribute att_tup = (Form_pg_attribute) GETSTRUCT(tp);
- bool result;
-
- result = att_tup->attisset;
- ReleaseSysCache(tp);
- return result;
- }
- else
- return false;
-}
-
-/*
- * get_atttypmod
- *
- * Given the relation id and the attribute number,
- * return the "atttypmod" field from the attribute relation.
- */
-int32
-get_atttypmod(Oid relid, AttrNumber attnum)
-{
- HeapTuple tp;
-
- tp = SearchSysCache(ATTNUM,
- ObjectIdGetDatum(relid),
- Int16GetDatum(attnum),
- 0, 0);
- if (HeapTupleIsValid(tp))
- {
- Form_pg_attribute att_tup = (Form_pg_attribute) GETSTRUCT(tp);
- int32 result;
-
- result = att_tup->atttypmod;
- ReleaseSysCache(tp);
- return result;
- }
- else
- return -1;
-}
-
-/*
- * get_atttypetypmod
- *
- * A two-fer: given the relation id and the attribute number,
- * fetch both type OID and atttypmod in a single cache lookup.
- *
- * Unlike the otherwise-similar get_atttype/get_atttypmod, this routine
- * raises an error if it can't obtain the information.
- */
-void
-get_atttypetypmod(Oid relid, AttrNumber attnum,
- Oid *typid, int32 *typmod)
-{
- HeapTuple tp;
- Form_pg_attribute att_tup;
-
- tp = SearchSysCache(ATTNUM,
- ObjectIdGetDatum(relid),
- Int16GetDatum(attnum),
- 0, 0);
- if (!HeapTupleIsValid(tp))
- elog(ERROR, "cache lookup failed for relation %u attribute %d",
- relid, attnum);
- att_tup = (Form_pg_attribute) GETSTRUCT(tp);
-
- *typid = att_tup->atttypid;
- *typmod = att_tup->atttypmod;
- ReleaseSysCache(tp);
-}
-
-/* ---------- INDEX CACHE ---------- */
-
-/* watch this space...
- */
-
-/* ---------- OPCLASS CACHE ---------- */
-
-/*
- * opclass_is_btree
- *
- * Returns TRUE iff the specified opclass is associated with the
- * btree index access method.
- */
-bool
-opclass_is_btree(Oid opclass)
-{
- HeapTuple tp;
- Form_pg_opclass cla_tup;
- bool result;
-
- tp = SearchSysCache(CLAOID,
- ObjectIdGetDatum(opclass),
- 0, 0, 0);
- if (!HeapTupleIsValid(tp))
- elog(ERROR, "cache lookup failed for opclass %u", opclass);
- cla_tup = (Form_pg_opclass) GETSTRUCT(tp);
-
- result = (cla_tup->opcamid == BTREE_AM_OID);
- ReleaseSysCache(tp);
- return result;
-}
-
-/* ---------- OPERATOR CACHE ---------- */
-
-/*
- * get_opcode
- *
- * Returns the regproc id of the routine used to implement an
- * operator given the operator oid.
- */
-RegProcedure
-get_opcode(Oid opno)
-{
- HeapTuple tp;
-
- tp = SearchSysCache(OPEROID,
- ObjectIdGetDatum(opno),
- 0, 0, 0);
- if (HeapTupleIsValid(tp))
- {
- Form_pg_operator optup = (Form_pg_operator) GETSTRUCT(tp);
- RegProcedure result;
-
- result = optup->oprcode;
- ReleaseSysCache(tp);
- return result;
- }
- else
- return (RegProcedure) InvalidOid;
-}
-
-/*
- * get_opname
- * returns the name of the operator with the given opno
- *
- * Note: returns a palloc'd copy of the string, or NULL if no such operator.
- */
-char *
-get_opname(Oid opno)
-{
- HeapTuple tp;
-
- tp = SearchSysCache(OPEROID,
- ObjectIdGetDatum(opno),
- 0, 0, 0);
- if (HeapTupleIsValid(tp))
- {
- Form_pg_operator optup = (Form_pg_operator) GETSTRUCT(tp);
- char *result;
-
- result = pstrdup(NameStr(optup->oprname));
- ReleaseSysCache(tp);
- return result;
- }
- else
- return NULL;
-}
-
-/*
- * op_mergejoinable
- *
- * Returns the left and right sort operators and types corresponding to a
- * mergejoinable operator, or nil if the operator is not mergejoinable.
- */
-bool
-op_mergejoinable(Oid opno, Oid ltype, Oid rtype, Oid *leftOp, Oid *rightOp)
-{
- HeapTuple tp;
- bool result = false;
-
- tp = SearchSysCache(OPEROID,
- ObjectIdGetDatum(opno),
- 0, 0, 0);
- if (HeapTupleIsValid(tp))
- {
- Form_pg_operator optup = (Form_pg_operator) GETSTRUCT(tp);
-
- if (optup->oprlsortop &&
- optup->oprrsortop &&
- optup->oprleft == ltype &&
- optup->oprright == rtype)
- {
- *leftOp = optup->oprlsortop;
- *rightOp = optup->oprrsortop;
- result = true;
- }
- ReleaseSysCache(tp);
- }
- return result;
-}
-
-/*
- * op_mergejoin_crossops
- *
- * Returns the cross-type comparison operators (ltype "<" rtype and
- * ltype ">" rtype) for an operator previously determined to be
- * mergejoinable. Optionally, fetches the regproc ids of these
- * operators, as well as their operator OIDs.
- */
-void
-op_mergejoin_crossops(Oid opno, Oid *ltop, Oid *gtop,
- RegProcedure *ltproc, RegProcedure *gtproc)
-{
- HeapTuple tp;
- Form_pg_operator optup;
-
- /*
- * Get the declared comparison operators of the operator.
- */
- tp = SearchSysCache(OPEROID,
- ObjectIdGetDatum(opno),
- 0, 0, 0);
- if (!HeapTupleIsValid(tp)) /* shouldn't happen */
- elog(ERROR, "op_mergejoin_crossops: operator %u not found", opno);
- optup = (Form_pg_operator) GETSTRUCT(tp);
- *ltop = optup->oprltcmpop;
- *gtop = optup->oprgtcmpop;
- ReleaseSysCache(tp);
-
- /* Check < op provided */
- if (!OidIsValid(*ltop))
- elog(ERROR, "op_mergejoin_crossops: mergejoin operator %u has no matching < operator",
- opno);
- if (ltproc)
- *ltproc = get_opcode(*ltop);
-
- /* Check > op provided */
- if (!OidIsValid(*gtop))
- elog(ERROR, "op_mergejoin_crossops: mergejoin operator %u has no matching > operator",
- opno);
- if (gtproc)
- *gtproc = get_opcode(*gtop);
-}
-
-/*
- * op_hashjoinable
- *
- * Returns the hash operator corresponding to a hashjoinable operator,
- * or InvalidOid if the operator is not hashjoinable.
- */
-Oid
-op_hashjoinable(Oid opno, Oid ltype, Oid rtype)
-{
- HeapTuple tp;
- Oid result = InvalidOid;
-
- tp = SearchSysCache(OPEROID,
- ObjectIdGetDatum(opno),
- 0, 0, 0);
- if (HeapTupleIsValid(tp))
- {
- Form_pg_operator optup = (Form_pg_operator) GETSTRUCT(tp);
-
- if (optup->oprcanhash &&
- optup->oprleft == ltype &&
- optup->oprright == rtype)
- result = opno;
- ReleaseSysCache(tp);
- }
- return result;
-}
-
-/*
- * op_volatile
- *
- * Get the provolatile flag for the operator's underlying function.
- */
-char
-op_volatile(Oid opno)
-{
- RegProcedure funcid = get_opcode(opno);
-
- if (funcid == (RegProcedure) InvalidOid)
- elog(ERROR, "Operator OID %u does not exist", opno);
-
- return func_volatile((Oid) funcid);
-}
-
-/*
- * get_commutator
- *
- * Returns the corresponding commutator of an operator.
- */
-Oid
-get_commutator(Oid opno)
-{
- HeapTuple tp;
-
- tp = SearchSysCache(OPEROID,
- ObjectIdGetDatum(opno),
- 0, 0, 0);
- if (HeapTupleIsValid(tp))
- {
- Form_pg_operator optup = (Form_pg_operator) GETSTRUCT(tp);
- Oid result;
-
- result = optup->oprcom;
- ReleaseSysCache(tp);
- return result;
- }
- else
- return InvalidOid;
-}
-
-/*
- * get_negator
- *
- * Returns the corresponding negator of an operator.
- */
-Oid
-get_negator(Oid opno)
-{
- HeapTuple tp;
-
- tp = SearchSysCache(OPEROID,
- ObjectIdGetDatum(opno),
- 0, 0, 0);
- if (HeapTupleIsValid(tp))
- {
- Form_pg_operator optup = (Form_pg_operator) GETSTRUCT(tp);
- Oid result;
-
- result = optup->oprnegate;
- ReleaseSysCache(tp);
- return result;
- }
- else
- return InvalidOid;
-}
-
-/*
- * get_oprrest
- *
- * Returns procedure id for computing selectivity of an operator.
- */
-RegProcedure
-get_oprrest(Oid opno)
-{
- HeapTuple tp;
-
- tp = SearchSysCache(OPEROID,
- ObjectIdGetDatum(opno),
- 0, 0, 0);
- if (HeapTupleIsValid(tp))
- {
- Form_pg_operator optup = (Form_pg_operator) GETSTRUCT(tp);
- RegProcedure result;
-
- result = optup->oprrest;
- ReleaseSysCache(tp);
- return result;
- }
- else
- return (RegProcedure) InvalidOid;
-}
-
-/*
- * get_oprjoin
- *
- * Returns procedure id for computing selectivity of a join.
- */
-RegProcedure
-get_oprjoin(Oid opno)
-{
- HeapTuple tp;
-
- tp = SearchSysCache(OPEROID,
- ObjectIdGetDatum(opno),
- 0, 0, 0);
- if (HeapTupleIsValid(tp))
- {
- Form_pg_operator optup = (Form_pg_operator) GETSTRUCT(tp);
- RegProcedure result;
-
- result = optup->oprjoin;
- ReleaseSysCache(tp);
- return result;
- }
- else
- return (RegProcedure) InvalidOid;
-}
-
-/* ---------- FUNCTION CACHE ---------- */
-
-/*
- * get_func_name
- * returns the name of the function with the given funcid
- *
- * Note: returns a palloc'd copy of the string, or NULL if no such function.
- */
-char *
-get_func_name(Oid funcid)
-{
- HeapTuple tp;
-
- tp = SearchSysCache(PROCOID,
- ObjectIdGetDatum(funcid),
- 0, 0, 0);
- if (HeapTupleIsValid(tp))
- {
- Form_pg_proc functup = (Form_pg_proc) GETSTRUCT(tp);
- char *result;
-
- result = pstrdup(NameStr(functup->proname));
- ReleaseSysCache(tp);
- return result;
- }
- else
- return NULL;
-}
-
-/*
- * get_func_rettype
- * Given procedure id, return the function's result type.
- */
-Oid
-get_func_rettype(Oid funcid)
-{
- HeapTuple tp;
- Oid result;
-
- tp = SearchSysCache(PROCOID,
- ObjectIdGetDatum(funcid),
- 0, 0, 0);
- if (!HeapTupleIsValid(tp))
- elog(ERROR, "Function OID %u does not exist", funcid);
-
- result = ((Form_pg_proc) GETSTRUCT(tp))->prorettype;
- ReleaseSysCache(tp);
- return result;
-}
-
-/*
- * get_func_retset
- * Given procedure id, return the function's proretset flag.
- */
-bool
-get_func_retset(Oid funcid)
-{
- HeapTuple tp;
- bool result;
-
- tp = SearchSysCache(PROCOID,
- ObjectIdGetDatum(funcid),
- 0, 0, 0);
- if (!HeapTupleIsValid(tp))
- elog(ERROR, "Function OID %u does not exist", funcid);
-
- result = ((Form_pg_proc) GETSTRUCT(tp))->proretset;
- ReleaseSysCache(tp);
- return result;
-}
-
-/*
- * func_volatile
- * Given procedure id, return the function's provolatile flag.
- */
-char
-func_volatile(Oid funcid)
-{
- HeapTuple tp;
- char result;
-
- tp = SearchSysCache(PROCOID,
- ObjectIdGetDatum(funcid),
- 0, 0, 0);
- if (!HeapTupleIsValid(tp))
- elog(ERROR, "Function OID %u does not exist", funcid);
-
- result = ((Form_pg_proc) GETSTRUCT(tp))->provolatile;
- ReleaseSysCache(tp);
- return result;
-}
-
-/* ---------- RELATION CACHE ---------- */
-
-/*
- * get_relname_relid
- * Given name and namespace of a relation, look up the OID.
- *
- * Returns InvalidOid if there is no such relation.
- */
-Oid
-get_relname_relid(const char *relname, Oid relnamespace)
-{
- return GetSysCacheOid(RELNAMENSP,
- PointerGetDatum(relname),
- ObjectIdGetDatum(relnamespace),
- 0, 0);
-}
-
-#ifdef NOT_USED
-/*
- * get_relnatts
- *
- * Returns the number of attributes for a given relation.
- */
-int
-get_relnatts(Oid relid)
-{
- HeapTuple tp;
-
- tp = SearchSysCache(RELOID,
- ObjectIdGetDatum(relid),
- 0, 0, 0);
- if (HeapTupleIsValid(tp))
- {
- Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
- int result;
-
- result = reltup->relnatts;
- ReleaseSysCache(tp);
- return result;
- }
- else
- return InvalidAttrNumber;
-}
-#endif
-
-/*
- * get_rel_name
- * Returns the name of a given relation.
- *
- * Returns a palloc'd copy of the string, or NULL if no such relation.
- *
- * NOTE: since relation name is not unique, be wary of code that uses this
- * for anything except preparing error messages.
- */
-char *
-get_rel_name(Oid relid)
-{
- HeapTuple tp;
-
- tp = SearchSysCache(RELOID,
- ObjectIdGetDatum(relid),
- 0, 0, 0);
- if (HeapTupleIsValid(tp))
- {
- Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
- char *result;
-
- result = pstrdup(NameStr(reltup->relname));
- ReleaseSysCache(tp);
- return result;
- }
- else
- return NULL;
-}
-
-/*
- * get_rel_namespace
- *
- * Returns the pg_namespace OID associated with a given relation.
- */
-Oid
-get_rel_namespace(Oid relid)
-{
- HeapTuple tp;
-
- tp = SearchSysCache(RELOID,
- ObjectIdGetDatum(relid),
- 0, 0, 0);
- if (HeapTupleIsValid(tp))
- {
- Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
- Oid result;
-
- result = reltup->relnamespace;
- ReleaseSysCache(tp);
- return result;
- }
- else
- return InvalidOid;
-}
-
-/*
- * get_rel_type_id
- *
- * Returns the pg_type OID associated with a given relation.
- *
- * Note: not all pg_class entries have associated pg_type OIDs; so be
- * careful to check for InvalidOid result.
- */
-Oid
-get_rel_type_id(Oid relid)
-{
- HeapTuple tp;
-
- tp = SearchSysCache(RELOID,
- ObjectIdGetDatum(relid),
- 0, 0, 0);
- if (HeapTupleIsValid(tp))
- {
- Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
- Oid result;
-
- result = reltup->reltype;
- ReleaseSysCache(tp);
- return result;
- }
- else
- return InvalidOid;
-}
-
-/* ---------- TYPE CACHE ---------- */
-
-/*
- * get_typisdefined
- *
- * Given the type OID, determine whether the type is defined
- * (if not, it's only a shell).
- */
-bool
-get_typisdefined(Oid typid)
-{
- HeapTuple tp;
-
- tp = SearchSysCache(TYPEOID,
- ObjectIdGetDatum(typid),
- 0, 0, 0);
- if (HeapTupleIsValid(tp))
- {
- Form_pg_type typtup = (Form_pg_type) GETSTRUCT(tp);
- bool result;
-
- result = typtup->typisdefined;
- ReleaseSysCache(tp);
- return result;
- }
- else
- return false;
-}
-
-/*
- * get_typlen
- *
- * Given the type OID, return the length of the type.
- */
-int16
-get_typlen(Oid typid)
-{
- HeapTuple tp;
-
- tp = SearchSysCache(TYPEOID,
- ObjectIdGetDatum(typid),
- 0, 0, 0);
- if (HeapTupleIsValid(tp))
- {
- Form_pg_type typtup = (Form_pg_type) GETSTRUCT(tp);
- int16 result;
-
- result = typtup->typlen;
- ReleaseSysCache(tp);
- return result;
- }
- else
- return 0;
-}
-
-/*
- * get_typbyval
- *
- * Given the type OID, determine whether the type is returned by value or
- * not. Returns true if by value, false if by reference.
- */
-bool
-get_typbyval(Oid typid)
-{
- HeapTuple tp;
-
- tp = SearchSysCache(TYPEOID,
- ObjectIdGetDatum(typid),
- 0, 0, 0);
- if (HeapTupleIsValid(tp))
- {
- Form_pg_type typtup = (Form_pg_type) GETSTRUCT(tp);
- bool result;
-
- result = typtup->typbyval;
- ReleaseSysCache(tp);
- return result;
- }
- else
- return false;
-}
-
-/*
- * get_typlenbyval
- *
- * A two-fer: given the type OID, return both typlen and typbyval.
- *
- * Since both pieces of info are needed to know how to copy a Datum,
- * many places need both. Might as well get them with one cache lookup
- * instead of two. Also, this routine raises an error instead of
- * returning a bogus value when given a bad type OID.
- */
-void
-get_typlenbyval(Oid typid, int16 *typlen, bool *typbyval)
-{
- HeapTuple tp;
- Form_pg_type typtup;
-
- tp = SearchSysCache(TYPEOID,
- ObjectIdGetDatum(typid),
- 0, 0, 0);
- if (!HeapTupleIsValid(tp))
- elog(ERROR, "cache lookup failed for type %u", typid);
- typtup = (Form_pg_type) GETSTRUCT(tp);
- *typlen = typtup->typlen;
- *typbyval = typtup->typbyval;
- ReleaseSysCache(tp);
-}
-
-#ifdef NOT_USED
-char
-get_typalign(Oid typid)
-{
- HeapTuple tp;
-
- tp = SearchSysCache(TYPEOID,
- ObjectIdGetDatum(typid),
- 0, 0, 0);
- if (HeapTupleIsValid(tp))
- {
- Form_pg_type typtup = (Form_pg_type) GETSTRUCT(tp);
- char result;
-
- result = typtup->typalign;
- ReleaseSysCache(tp);
- return result;
- }
- else
- return 'i';
-}
-#endif
-
-char
-get_typstorage(Oid typid)
-{
- HeapTuple tp;
-
- tp = SearchSysCache(TYPEOID,
- ObjectIdGetDatum(typid),
- 0, 0, 0);
- if (HeapTupleIsValid(tp))
- {
- Form_pg_type typtup = (Form_pg_type) GETSTRUCT(tp);
- char result;
-
- result = typtup->typstorage;
- ReleaseSysCache(tp);
- return result;
- }
- else
- return 'p';
-}
-
-/*
- * get_typdefault
- * Given a type OID, return the type's default value, if any.
- *
- * The result is a palloc'd expression node tree, or NULL if there
- * is no defined default for the datatype.
- *
- * NB: caller should be prepared to coerce result to correct datatype;
- * the returned expression tree might produce something of the wrong type.
- */
-Node *
-get_typdefault(Oid typid)
-{
- HeapTuple typeTuple;
- Form_pg_type type;
- Datum datum;
- bool isNull;
- Node *expr;
-
- typeTuple = SearchSysCache(TYPEOID,
- ObjectIdGetDatum(typid),
- 0, 0, 0);
- if (!HeapTupleIsValid(typeTuple))
- elog(ERROR, "get_typdefault: failed to lookup type %u", typid);
- type = (Form_pg_type) GETSTRUCT(typeTuple);
-
- /*
- * typdefault and typdefaultbin are potentially null, so don't try to
- * access 'em as struct fields. Must do it the hard way with
- * SysCacheGetAttr.
- */
- datum = SysCacheGetAttr(TYPEOID,
- typeTuple,
- Anum_pg_type_typdefaultbin,
- &isNull);
-
- if (!isNull)
- {
- /* We have an expression default */
- expr = stringToNode(DatumGetCString(DirectFunctionCall1(textout,
- datum)));
- }
- else
- {
- /* Perhaps we have a plain literal default */
- datum = SysCacheGetAttr(TYPEOID,
- typeTuple,
- Anum_pg_type_typdefault,
- &isNull);
-
- if (!isNull)
- {
- char *strDefaultVal;
-
- /* Convert text datum to C string */
- strDefaultVal = DatumGetCString(DirectFunctionCall1(textout,
- datum));
- /* Convert C string to a value of the given type */
- datum = OidFunctionCall3(type->typinput,
- CStringGetDatum(strDefaultVal),
- ObjectIdGetDatum(type->typelem),
- Int32GetDatum(-1));
- /* Build a Const node containing the value */
- expr = (Node *) makeConst(typid,
- type->typlen,
- datum,
- false,
- type->typbyval,
- false, /* not a set */
- false);
- pfree(strDefaultVal);
- }
- else
- {
- /* No default */
- expr = NULL;
- }
- }
-
- ReleaseSysCache(typeTuple);
-
- return expr;
-}
-
-/*
- * getBaseType
- * If the given type is a domain, return its base type;
- * otherwise return the type's own OID.
- */
-Oid
-getBaseType(Oid typid)
-{
- /*
- * We loop to find the bottom base type in a stack of domains.
- */
- for (;;)
- {
- HeapTuple tup;
- Form_pg_type typTup;
-
- tup = SearchSysCache(TYPEOID,
- ObjectIdGetDatum(typid),
- 0, 0, 0);
- if (!HeapTupleIsValid(tup))
- elog(ERROR, "getBaseType: failed to lookup type %u", typid);
- typTup = (Form_pg_type) GETSTRUCT(tup);
- if (typTup->typtype != 'd')
- {
- /* Not a domain, so done */
- ReleaseSysCache(tup);
- break;
- }
-
- typid = typTup->typbasetype;
- ReleaseSysCache(tup);
- }
-
- return typid;
-}
-
-/*
- * get_typavgwidth
- *
- * Given a type OID and a typmod value (pass -1 if typmod is unknown),
- * estimate the average width of values of the type. This is used by
- * the planner, which doesn't require absolutely correct results;
- * it's OK (and expected) to guess if we don't know for sure.
- */
-int32
-get_typavgwidth(Oid typid, int32 typmod)
-{
- int typlen = get_typlen(typid);
- int32 maxwidth;
-
- /*
- * Easy if it's a fixed-width type
- */
- if (typlen > 0)
- return typlen;
-
- /*
- * type_maximum_size knows the encoding of typmod for some datatypes;
- * don't duplicate that knowledge here.
- */
- maxwidth = type_maximum_size(typid, typmod);
- if (maxwidth > 0)
- {
- /*
- * For BPCHAR, the max width is also the only width. Otherwise we
- * need to guess about the typical data width given the max. A
- * sliding scale for percentage of max width seems reasonable.
- */
- if (typid == BPCHAROID)
- return maxwidth;
- if (maxwidth <= 32)
- return maxwidth; /* assume full width */
- if (maxwidth < 1000)
- return 32 + (maxwidth - 32) / 2; /* assume 50% */
-
- /*
- * Beyond 1000, assume we're looking at something like
- * "varchar(10000)" where the limit isn't actually reached often,
- * and use a fixed estimate.
- */
- return 32 + (1000 - 32) / 2;
- }
-
- /*
- * Ooops, we have no idea ... wild guess time.
- */
- return 32;
-}
-
-/*
- * 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...
- */
-#ifdef NOT_USED
-char
-get_typtype(Oid typid)
-{
- HeapTuple tp;
-
- tp = SearchSysCache(TYPEOID,
- ObjectIdGetDatum(typid),
- 0, 0, 0);
- if (HeapTupleIsValid(tp))
- {
- Form_pg_type typtup = (Form_pg_type) GETSTRUCT(tp);
- char result;
-
- result = typtup->typtype;
- ReleaseSysCache(tp);
- return result;
- }
- else
- return '\0';
-}
-#endif
-
-/* ---------- STATISTICS CACHE ---------- */
-
-/*
- * get_attavgwidth
- *
- * Given the table and attribute number of a column, get the average
- * width of entries in the column. Return zero if no data available.
- */
-int32
-get_attavgwidth(Oid relid, AttrNumber attnum)
-{
- HeapTuple tp;
-
- tp = SearchSysCache(STATRELATT,
- ObjectIdGetDatum(relid),
- Int16GetDatum(attnum),
- 0, 0);
- if (HeapTupleIsValid(tp))
- {
- int32 stawidth = ((Form_pg_statistic) GETSTRUCT(tp))->stawidth;
-
- ReleaseSysCache(tp);
- if (stawidth > 0)
- return stawidth;
- }
- return 0;
-}
-
-/*
- * get_attstatsslot
- *
- * Extract the contents of a "slot" of a pg_statistic tuple.
- * Returns TRUE if requested slot type was found, else FALSE.
- *
- * Unlike other routines in this file, this takes a pointer to an
- * already-looked-up tuple in the pg_statistic cache. We do this since
- * most callers will want to extract more than one value from the cache
- * entry, and we don't want to repeat the cache lookup unnecessarily.
- *
- * statstuple: pg_statistics tuple to be examined.
- * atttype: type OID of attribute.
- * atttypmod: typmod of attribute.
- * reqkind: STAKIND code for desired statistics slot kind.
- * reqop: STAOP value wanted, or InvalidOid if don't care.
- * values, nvalues: if not NULL, the slot's stavalues are extracted.
- * numbers, nnumbers: if not NULL, the slot's stanumbers are extracted.
- *
- * If assigned, values and numbers are set to point to palloc'd arrays.
- * If the attribute type is pass-by-reference, the values referenced by
- * the values array are themselves palloc'd. The palloc'd stuff can be
- * freed by calling free_attstatsslot.
- */
-bool
-get_attstatsslot(HeapTuple statstuple,
- Oid atttype, int32 atttypmod,
- int reqkind, Oid reqop,
- Datum **values, int *nvalues,
- float4 **numbers, int *nnumbers)
-{
- Form_pg_statistic stats = (Form_pg_statistic) GETSTRUCT(statstuple);
- int i,
- j;
- Datum val;
- bool isnull;
- ArrayType *statarray;
- int narrayelem;
- HeapTuple typeTuple;
- FmgrInfo inputproc;
- Oid typelem;
-
- for (i = 0; i < STATISTIC_NUM_SLOTS; i++)
- {
- if ((&stats->stakind1)[i] == reqkind &&
- (reqop == InvalidOid || (&stats->staop1)[i] == reqop))
- break;
- }
- if (i >= STATISTIC_NUM_SLOTS)
- return false; /* not there */
-
- if (values)
- {
- val = SysCacheGetAttr(STATRELATT, statstuple,
- Anum_pg_statistic_stavalues1 + i,
- &isnull);
- if (isnull)
- elog(ERROR, "get_attstatsslot: stavalues is null");
- statarray = DatumGetArrayTypeP(val);
-
- /*
- * Do initial examination of the array. This produces a list of
- * text Datums --- ie, pointers into the text array value.
- */
- deconstruct_array(statarray, false, -1, 'i', values, nvalues);
- narrayelem = *nvalues;
-
- /*
- * We now need to replace each text Datum by its internal
- * equivalent.
- *
- * Get the type input proc and typelem for the column datatype.
- */
- typeTuple = SearchSysCache(TYPEOID,
- ObjectIdGetDatum(atttype),
- 0, 0, 0);
- if (!HeapTupleIsValid(typeTuple))
- elog(ERROR, "get_attstatsslot: Cache lookup failed for type %u",
- atttype);
- fmgr_info(((Form_pg_type) GETSTRUCT(typeTuple))->typinput, &inputproc);
- typelem = ((Form_pg_type) GETSTRUCT(typeTuple))->typelem;
- ReleaseSysCache(typeTuple);
-
- /*
- * Do the conversions. The palloc'd array of Datums is reused in
- * place.
- */
- for (j = 0; j < narrayelem; j++)
- {
- char *strval;
-
- strval = DatumGetCString(DirectFunctionCall1(textout,
- (*values)[j]));
- (*values)[j] = FunctionCall3(&inputproc,
- CStringGetDatum(strval),
- ObjectIdGetDatum(typelem),
- Int32GetDatum(atttypmod));
- pfree(strval);
- }
-
- /*
- * Free statarray if it's a detoasted copy.
- */
- if ((Pointer) statarray != DatumGetPointer(val))
- pfree(statarray);
- }
-
- if (numbers)
- {
- val = SysCacheGetAttr(STATRELATT, statstuple,
- Anum_pg_statistic_stanumbers1 + i,
- &isnull);
- if (isnull)
- elog(ERROR, "get_attstatsslot: stanumbers is null");
- statarray = DatumGetArrayTypeP(val);
-
- /*
- * We expect the array to be a 1-D float4 array; verify that. We
- * don't need to use deconstruct_array() since the array data is
- * just going to look like a C array of float4 values.
- */
- narrayelem = ARR_DIMS(statarray)[0];
- if (ARR_NDIM(statarray) != 1 || narrayelem <= 0 ||
- ARR_SIZE(statarray) != (ARR_OVERHEAD(1) + narrayelem * sizeof(float4)))
- elog(ERROR, "get_attstatsslot: stanumbers is bogus");
- *numbers = (float4 *) palloc(narrayelem * sizeof(float4));
- memcpy(*numbers, ARR_DATA_PTR(statarray), narrayelem * sizeof(float4));
- *nnumbers = narrayelem;
-
- /*
- * Free statarray if it's a detoasted copy.
- */
- if ((Pointer) statarray != DatumGetPointer(val))
- pfree(statarray);
- }
-
- return true;
-}
-
-void
-free_attstatsslot(Oid atttype,
- Datum *values, int nvalues,
- float4 *numbers, int nnumbers)
-{
- if (values)
- {
- if (!get_typbyval(atttype))
- {
- int i;
-
- for (i = 0; i < nvalues; i++)
- pfree(DatumGetPointer(values[i]));
- }
- pfree(values);
- }
- if (numbers)
- pfree(numbers);
-}
-
-/* ---------- PG_NAMESPACE CACHE ---------- */
-
-/*
- * get_namespace_name
- * Returns the name of a given namespace
- *
- * Returns a palloc'd copy of the string, or NULL if no such namespace.
- */
-char *
-get_namespace_name(Oid nspid)
-{
- HeapTuple tp;
-
- tp = SearchSysCache(NAMESPACEOID,
- ObjectIdGetDatum(nspid),
- 0, 0, 0);
- if (HeapTupleIsValid(tp))
- {
- Form_pg_namespace nsptup = (Form_pg_namespace) GETSTRUCT(tp);
- char *result;
-
- result = pstrdup(NameStr(nsptup->nspname));
- ReleaseSysCache(tp);
- return result;
- }
- else
- return NULL;
-}
-
-/* ---------- PG_SHADOW CACHE ---------- */
-
-/*
- * get_usesysid
- *
- * Given a user name, look up the user's sysid.
- * Raises an error if no such user (rather than returning zero,
- * which might possibly be a valid usesysid).
- *
- * Note: the type of usesysid is currently int4, but may change to Oid
- * someday. It'd be reasonable to return zero on failure if we were
- * using Oid ...
- */
-int32
-get_usesysid(const char *username)
-{
- int32 result;
- HeapTuple userTup;
-
- userTup = SearchSysCache(SHADOWNAME,
- PointerGetDatum(username),
- 0, 0, 0);
- if (!HeapTupleIsValid(userTup))
- elog(ERROR, "user \"%s\" does not exist", username);
-
- result = ((Form_pg_shadow) GETSTRUCT(userTup))->usesysid;
-
- ReleaseSysCache(userTup);
-
- return result;
-}