1 /*-------------------------------------------------------------------------
4 * Convenience routines for common queries in the system catalog cache.
6 * Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group
7 * Portions Copyright (c) 1994, Regents of the University of California
10 * $PostgreSQL: pgsql/src/backend/utils/cache/lsyscache.c,v 1.138 2006/10/04 00:30:00 momjian Exp $
13 * Eventually, the index information should go through here, too.
14 *-------------------------------------------------------------------------
18 #include "access/hash.h"
19 #include "bootstrap/bootstrap.h"
20 #include "catalog/pg_amop.h"
21 #include "catalog/pg_amproc.h"
22 #include "catalog/pg_namespace.h"
23 #include "catalog/pg_opclass.h"
24 #include "catalog/pg_operator.h"
25 #include "catalog/pg_proc.h"
26 #include "catalog/pg_statistic.h"
27 #include "catalog/pg_type.h"
28 #include "miscadmin.h"
29 #include "nodes/makefuncs.h"
30 #include "utils/array.h"
31 #include "utils/builtins.h"
32 #include "utils/datum.h"
33 #include "utils/lsyscache.h"
34 #include "utils/syscache.h"
37 /* ---------- AMOP CACHES ---------- */
42 * Return t iff operator 'opno' is in operator class 'opclass'.
45 op_in_opclass(Oid opno, Oid opclass)
47 return SearchSysCacheExists(AMOPOPID,
48 ObjectIdGetDatum(opno),
49 ObjectIdGetDatum(opclass),
54 * get_op_opclass_strategy
56 * Get the operator's strategy number within the specified opclass,
57 * or 0 if it's not a member of the opclass.
60 get_op_opclass_strategy(Oid opno, Oid opclass)
63 Form_pg_amop amop_tup;
66 tp = SearchSysCache(AMOPOPID,
67 ObjectIdGetDatum(opno),
68 ObjectIdGetDatum(opclass),
70 if (!HeapTupleIsValid(tp))
72 amop_tup = (Form_pg_amop) GETSTRUCT(tp);
73 result = amop_tup->amopstrategy;
79 * get_op_opclass_properties
81 * Get the operator's strategy number, subtype, and recheck (lossy) flag
82 * within the specified opclass.
84 * Caller should already have verified that opno is a member of opclass,
85 * therefore we raise an error if the tuple is not found.
88 get_op_opclass_properties(Oid opno, Oid opclass,
89 int *strategy, Oid *subtype, bool *recheck)
92 Form_pg_amop amop_tup;
94 tp = SearchSysCache(AMOPOPID,
95 ObjectIdGetDatum(opno),
96 ObjectIdGetDatum(opclass),
98 if (!HeapTupleIsValid(tp))
99 elog(ERROR, "operator %u is not a member of opclass %u",
101 amop_tup = (Form_pg_amop) GETSTRUCT(tp);
102 *strategy = amop_tup->amopstrategy;
103 *subtype = amop_tup->amopsubtype;
104 *recheck = amop_tup->amopreqcheck;
110 * Get the OID of the operator that implements the specified strategy
111 * with the specified subtype for the specified opclass.
113 * Returns InvalidOid if there is no pg_amop entry for the given keys.
116 get_opclass_member(Oid opclass, Oid subtype, int16 strategy)
119 Form_pg_amop amop_tup;
122 tp = SearchSysCache(AMOPSTRATEGY,
123 ObjectIdGetDatum(opclass),
124 ObjectIdGetDatum(subtype),
125 Int16GetDatum(strategy),
127 if (!HeapTupleIsValid(tp))
129 amop_tup = (Form_pg_amop) GETSTRUCT(tp);
130 result = amop_tup->amopopr;
136 * get_op_hash_function
137 * Get the OID of the datatype-specific hash function associated with
138 * a hashable equality operator.
140 * Returns InvalidOid if no hash function can be found. (This indicates
141 * that the operator should not have been marked oprcanhash.)
144 get_op_hash_function(Oid opno)
148 Oid opclass = InvalidOid;
151 * Search pg_amop to see if the target operator is registered as the "="
152 * operator of any hash opclass. If the operator is registered in
153 * multiple opclasses, assume we can use the associated hash function from
156 catlist = SearchSysCacheList(AMOPOPID, 1,
157 ObjectIdGetDatum(opno),
160 for (i = 0; i < catlist->n_members; i++)
162 HeapTuple tuple = &catlist->members[i]->tuple;
163 Form_pg_amop aform = (Form_pg_amop) GETSTRUCT(tuple);
165 if (aform->amopstrategy == HTEqualStrategyNumber &&
166 opclass_is_hash(aform->amopclaid))
168 opclass = aform->amopclaid;
173 ReleaseSysCacheList(catlist);
175 if (OidIsValid(opclass))
177 /* Found a suitable opclass, get its default hash support function */
178 return get_opclass_proc(opclass, InvalidOid, HASHPROC);
181 /* Didn't find a match... */
186 * get_op_btree_interpretation
187 * Given an operator's OID, find out which btree opclasses it belongs to,
188 * and what strategy number it has within each one. The results are
189 * returned as an OID list and a parallel integer list.
191 * In addition to the normal btree operators, we consider a <> operator to be
192 * a "member" of an opclass if its negator is the opclass' equality operator.
193 * ROWCOMPARE_NE is returned as the strategy number for this case.
196 get_op_btree_interpretation(Oid opno, List **opclasses, List **opstrats)
208 * Get the nominal left-hand input type of the operator; we will ignore
209 * opclasses that don't have that as the expected input datatype. This is
210 * a kluge to avoid being confused by binary-compatible opclasses (such as
211 * text_ops and varchar_ops, which share the same operators).
213 op_input_types(opno, &lefttype, &righttype);
214 Assert(OidIsValid(lefttype));
217 * Find all the pg_amop entries containing the operator.
219 catlist = SearchSysCacheList(AMOPOPID, 1,
220 ObjectIdGetDatum(opno),
224 * If we can't find any opclass containing the op, perhaps it is a <>
225 * operator. See if it has a negator that is in an opclass.
228 if (catlist->n_members == 0)
230 Oid op_negator = get_negator(opno);
232 if (OidIsValid(op_negator))
235 ReleaseSysCacheList(catlist);
236 catlist = SearchSysCacheList(AMOPOPID, 1,
237 ObjectIdGetDatum(op_negator),
242 /* Now search the opclasses */
243 for (i = 0; i < catlist->n_members; i++)
245 HeapTuple op_tuple = &catlist->members[i]->tuple;
246 Form_pg_amop op_form = (Form_pg_amop) GETSTRUCT(op_tuple);
248 StrategyNumber op_strategy;
250 opclass_id = op_form->amopclaid;
253 if (!opclass_is_btree(opclass_id))
256 /* must match operator input type exactly */
257 if (get_opclass_input_type(opclass_id) != lefttype)
260 /* Get the operator's btree strategy number */
261 op_strategy = (StrategyNumber) op_form->amopstrategy;
262 Assert(op_strategy >= 1 && op_strategy <= 5);
266 /* Only consider negators that are = */
267 if (op_strategy != BTEqualStrategyNumber)
269 op_strategy = ROWCOMPARE_NE;
272 *opclasses = lappend_oid(*opclasses, opclass_id);
273 *opstrats = lappend_int(*opstrats, op_strategy);
276 ReleaseSysCacheList(catlist);
280 /* ---------- AMPROC CACHES ---------- */
284 * Get the OID of the specified support function
285 * for the specified opclass and subtype.
287 * Returns InvalidOid if there is no pg_amproc entry for the given keys.
290 get_opclass_proc(Oid opclass, Oid subtype, int16 procnum)
293 Form_pg_amproc amproc_tup;
296 tp = SearchSysCache(AMPROCNUM,
297 ObjectIdGetDatum(opclass),
298 ObjectIdGetDatum(subtype),
299 Int16GetDatum(procnum),
301 if (!HeapTupleIsValid(tp))
303 amproc_tup = (Form_pg_amproc) GETSTRUCT(tp);
304 result = amproc_tup->amproc;
310 /* ---------- ATTRIBUTE CACHES ---------- */
314 * Given the relation id and the attribute number,
315 * return the "attname" field from the attribute relation.
317 * Note: returns a palloc'd copy of the string, or NULL if no such attribute.
320 get_attname(Oid relid, AttrNumber attnum)
324 tp = SearchSysCache(ATTNUM,
325 ObjectIdGetDatum(relid),
326 Int16GetDatum(attnum),
328 if (HeapTupleIsValid(tp))
330 Form_pg_attribute att_tup = (Form_pg_attribute) GETSTRUCT(tp);
333 result = pstrdup(NameStr(att_tup->attname));
342 * get_relid_attribute_name
344 * Same as above routine get_attname(), except that error
345 * is handled by elog() instead of returning NULL.
348 get_relid_attribute_name(Oid relid, AttrNumber attnum)
352 attname = get_attname(relid, attnum);
354 elog(ERROR, "cache lookup failed for attribute %d of relation %u",
362 * Given the relation id and the attribute name,
363 * return the "attnum" field from the attribute relation.
365 * Returns InvalidAttrNumber if the attr doesn't exist (or is dropped).
368 get_attnum(Oid relid, const char *attname)
372 tp = SearchSysCacheAttName(relid, attname);
373 if (HeapTupleIsValid(tp))
375 Form_pg_attribute att_tup = (Form_pg_attribute) GETSTRUCT(tp);
378 result = att_tup->attnum;
383 return InvalidAttrNumber;
389 * Given the relation OID and the attribute number with the relation,
390 * return the attribute type OID.
393 get_atttype(Oid relid, AttrNumber attnum)
397 tp = SearchSysCache(ATTNUM,
398 ObjectIdGetDatum(relid),
399 Int16GetDatum(attnum),
401 if (HeapTupleIsValid(tp))
403 Form_pg_attribute att_tup = (Form_pg_attribute) GETSTRUCT(tp);
406 result = att_tup->atttypid;
417 * Given the relation id and the attribute number,
418 * return the "atttypmod" field from the attribute relation.
421 get_atttypmod(Oid relid, AttrNumber attnum)
425 tp = SearchSysCache(ATTNUM,
426 ObjectIdGetDatum(relid),
427 Int16GetDatum(attnum),
429 if (HeapTupleIsValid(tp))
431 Form_pg_attribute att_tup = (Form_pg_attribute) GETSTRUCT(tp);
434 result = att_tup->atttypmod;
445 * A two-fer: given the relation id and the attribute number,
446 * fetch both type OID and atttypmod in a single cache lookup.
448 * Unlike the otherwise-similar get_atttype/get_atttypmod, this routine
449 * raises an error if it can't obtain the information.
452 get_atttypetypmod(Oid relid, AttrNumber attnum,
453 Oid *typid, int32 *typmod)
456 Form_pg_attribute att_tup;
458 tp = SearchSysCache(ATTNUM,
459 ObjectIdGetDatum(relid),
460 Int16GetDatum(attnum),
462 if (!HeapTupleIsValid(tp))
463 elog(ERROR, "cache lookup failed for attribute %d of relation %u",
465 att_tup = (Form_pg_attribute) GETSTRUCT(tp);
467 *typid = att_tup->atttypid;
468 *typmod = att_tup->atttypmod;
472 /* ---------- INDEX CACHE ---------- */
474 /* watch this space...
477 /* ---------- OPCLASS CACHE ---------- */
482 * Returns TRUE iff the specified opclass is associated with the
483 * btree index access method.
486 opclass_is_btree(Oid opclass)
489 Form_pg_opclass cla_tup;
492 tp = SearchSysCache(CLAOID,
493 ObjectIdGetDatum(opclass),
495 if (!HeapTupleIsValid(tp))
496 elog(ERROR, "cache lookup failed for opclass %u", opclass);
497 cla_tup = (Form_pg_opclass) GETSTRUCT(tp);
499 result = (cla_tup->opcamid == BTREE_AM_OID);
507 * Returns TRUE iff the specified opclass is associated with the
508 * hash index access method.
511 opclass_is_hash(Oid opclass)
514 Form_pg_opclass cla_tup;
517 tp = SearchSysCache(CLAOID,
518 ObjectIdGetDatum(opclass),
520 if (!HeapTupleIsValid(tp))
521 elog(ERROR, "cache lookup failed for opclass %u", opclass);
522 cla_tup = (Form_pg_opclass) GETSTRUCT(tp);
524 result = (cla_tup->opcamid == HASH_AM_OID);
532 * Returns TRUE iff the specified opclass is the default for its
533 * index access method and input data type.
536 opclass_is_default(Oid opclass)
539 Form_pg_opclass cla_tup;
542 tp = SearchSysCache(CLAOID,
543 ObjectIdGetDatum(opclass),
545 if (!HeapTupleIsValid(tp))
546 elog(ERROR, "cache lookup failed for opclass %u", opclass);
547 cla_tup = (Form_pg_opclass) GETSTRUCT(tp);
549 result = cla_tup->opcdefault;
555 * get_opclass_input_type
557 * Returns the OID of the datatype the opclass indexes.
560 get_opclass_input_type(Oid opclass)
563 Form_pg_opclass cla_tup;
566 tp = SearchSysCache(CLAOID,
567 ObjectIdGetDatum(opclass),
569 if (!HeapTupleIsValid(tp))
570 elog(ERROR, "cache lookup failed for opclass %u", opclass);
571 cla_tup = (Form_pg_opclass) GETSTRUCT(tp);
573 result = cla_tup->opcintype;
578 /* ---------- OPERATOR CACHE ---------- */
583 * Returns the regproc id of the routine used to implement an
584 * operator given the operator oid.
591 tp = SearchSysCache(OPEROID,
592 ObjectIdGetDatum(opno),
594 if (HeapTupleIsValid(tp))
596 Form_pg_operator optup = (Form_pg_operator) GETSTRUCT(tp);
599 result = optup->oprcode;
604 return (RegProcedure) InvalidOid;
609 * returns the name of the operator with the given opno
611 * Note: returns a palloc'd copy of the string, or NULL if no such operator.
618 tp = SearchSysCache(OPEROID,
619 ObjectIdGetDatum(opno),
621 if (HeapTupleIsValid(tp))
623 Form_pg_operator optup = (Form_pg_operator) GETSTRUCT(tp);
626 result = pstrdup(NameStr(optup->oprname));
637 * Returns the left and right input datatypes for an operator
638 * (InvalidOid if not relevant).
641 op_input_types(Oid opno, Oid *lefttype, Oid *righttype)
644 Form_pg_operator optup;
646 tp = SearchSysCache(OPEROID,
647 ObjectIdGetDatum(opno),
649 if (!HeapTupleIsValid(tp)) /* shouldn't happen */
650 elog(ERROR, "cache lookup failed for operator %u", opno);
651 optup = (Form_pg_operator) GETSTRUCT(tp);
652 *lefttype = optup->oprleft;
653 *righttype = optup->oprright;
660 * Returns the left and right sort operators corresponding to a
661 * mergejoinable operator, or false if the operator is not mergejoinable.
664 op_mergejoinable(Oid opno, Oid *leftOp, Oid *rightOp)
669 tp = SearchSysCache(OPEROID,
670 ObjectIdGetDatum(opno),
672 if (HeapTupleIsValid(tp))
674 Form_pg_operator optup = (Form_pg_operator) GETSTRUCT(tp);
676 if (optup->oprlsortop &&
679 *leftOp = optup->oprlsortop;
680 *rightOp = optup->oprrsortop;
689 * op_mergejoin_crossops
691 * Returns the cross-type comparison operators (ltype "<" rtype and
692 * ltype ">" rtype) for an operator previously determined to be
693 * mergejoinable. Optionally, fetches the regproc ids of these
694 * operators, as well as their operator OIDs.
697 op_mergejoin_crossops(Oid opno, Oid *ltop, Oid *gtop,
698 RegProcedure *ltproc, RegProcedure *gtproc)
701 Form_pg_operator optup;
704 * Get the declared comparison operators of the operator.
706 tp = SearchSysCache(OPEROID,
707 ObjectIdGetDatum(opno),
709 if (!HeapTupleIsValid(tp)) /* shouldn't happen */
710 elog(ERROR, "cache lookup failed for operator %u", opno);
711 optup = (Form_pg_operator) GETSTRUCT(tp);
712 *ltop = optup->oprltcmpop;
713 *gtop = optup->oprgtcmpop;
716 /* Check < op provided */
717 if (!OidIsValid(*ltop))
718 elog(ERROR, "mergejoin operator %u has no matching < operator",
721 *ltproc = get_opcode(*ltop);
723 /* Check > op provided */
724 if (!OidIsValid(*gtop))
725 elog(ERROR, "mergejoin operator %u has no matching > operator",
728 *gtproc = get_opcode(*gtop);
734 * Returns true if the operator is hashjoinable.
737 op_hashjoinable(Oid opno)
742 tp = SearchSysCache(OPEROID,
743 ObjectIdGetDatum(opno),
745 if (HeapTupleIsValid(tp))
747 Form_pg_operator optup = (Form_pg_operator) GETSTRUCT(tp);
749 result = optup->oprcanhash;
758 * Get the proisstrict flag for the operator's underlying function.
763 RegProcedure funcid = get_opcode(opno);
765 if (funcid == (RegProcedure) InvalidOid)
766 elog(ERROR, "operator %u does not exist", opno);
768 return func_strict((Oid) funcid);
774 * Get the provolatile flag for the operator's underlying function.
777 op_volatile(Oid opno)
779 RegProcedure funcid = get_opcode(opno);
781 if (funcid == (RegProcedure) InvalidOid)
782 elog(ERROR, "operator %u does not exist", opno);
784 return func_volatile((Oid) funcid);
790 * Returns the corresponding commutator of an operator.
793 get_commutator(Oid opno)
797 tp = SearchSysCache(OPEROID,
798 ObjectIdGetDatum(opno),
800 if (HeapTupleIsValid(tp))
802 Form_pg_operator optup = (Form_pg_operator) GETSTRUCT(tp);
805 result = optup->oprcom;
816 * Returns the corresponding negator of an operator.
819 get_negator(Oid opno)
823 tp = SearchSysCache(OPEROID,
824 ObjectIdGetDatum(opno),
826 if (HeapTupleIsValid(tp))
828 Form_pg_operator optup = (Form_pg_operator) GETSTRUCT(tp);
831 result = optup->oprnegate;
842 * Returns procedure id for computing selectivity of an operator.
845 get_oprrest(Oid opno)
849 tp = SearchSysCache(OPEROID,
850 ObjectIdGetDatum(opno),
852 if (HeapTupleIsValid(tp))
854 Form_pg_operator optup = (Form_pg_operator) GETSTRUCT(tp);
857 result = optup->oprrest;
862 return (RegProcedure) InvalidOid;
868 * Returns procedure id for computing selectivity of a join.
871 get_oprjoin(Oid opno)
875 tp = SearchSysCache(OPEROID,
876 ObjectIdGetDatum(opno),
878 if (HeapTupleIsValid(tp))
880 Form_pg_operator optup = (Form_pg_operator) GETSTRUCT(tp);
883 result = optup->oprjoin;
888 return (RegProcedure) InvalidOid;
891 /* ---------- FUNCTION CACHE ---------- */
895 * returns the name of the function with the given funcid
897 * Note: returns a palloc'd copy of the string, or NULL if no such function.
900 get_func_name(Oid funcid)
904 tp = SearchSysCache(PROCOID,
905 ObjectIdGetDatum(funcid),
907 if (HeapTupleIsValid(tp))
909 Form_pg_proc functup = (Form_pg_proc) GETSTRUCT(tp);
912 result = pstrdup(NameStr(functup->proname));
922 * Given procedure id, return the function's result type.
925 get_func_rettype(Oid funcid)
930 tp = SearchSysCache(PROCOID,
931 ObjectIdGetDatum(funcid),
933 if (!HeapTupleIsValid(tp))
934 elog(ERROR, "cache lookup failed for function %u", funcid);
936 result = ((Form_pg_proc) GETSTRUCT(tp))->prorettype;
943 * Given procedure id, return the number of arguments.
946 get_func_nargs(Oid funcid)
951 tp = SearchSysCache(PROCOID,
952 ObjectIdGetDatum(funcid),
954 if (!HeapTupleIsValid(tp))
955 elog(ERROR, "cache lookup failed for function %u", funcid);
957 result = ((Form_pg_proc) GETSTRUCT(tp))->pronargs;
964 * Given procedure id, return the function's argument and result types.
965 * (The return value is the result type.)
967 * The arguments are returned as a palloc'd array.
970 get_func_signature(Oid funcid, Oid **argtypes, int *nargs)
973 Form_pg_proc procstruct;
976 tp = SearchSysCache(PROCOID,
977 ObjectIdGetDatum(funcid),
979 if (!HeapTupleIsValid(tp))
980 elog(ERROR, "cache lookup failed for function %u", funcid);
982 procstruct = (Form_pg_proc) GETSTRUCT(tp);
984 result = procstruct->prorettype;
985 *nargs = (int) procstruct->pronargs;
986 Assert(*nargs == procstruct->proargtypes.dim1);
987 *argtypes = (Oid *) palloc(*nargs * sizeof(Oid));
988 memcpy(*argtypes, procstruct->proargtypes.values, *nargs * sizeof(Oid));
996 * Given procedure id, return the function's proretset flag.
999 get_func_retset(Oid funcid)
1004 tp = SearchSysCache(PROCOID,
1005 ObjectIdGetDatum(funcid),
1007 if (!HeapTupleIsValid(tp))
1008 elog(ERROR, "cache lookup failed for function %u", funcid);
1010 result = ((Form_pg_proc) GETSTRUCT(tp))->proretset;
1011 ReleaseSysCache(tp);
1017 * Given procedure id, return the function's proisstrict flag.
1020 func_strict(Oid funcid)
1025 tp = SearchSysCache(PROCOID,
1026 ObjectIdGetDatum(funcid),
1028 if (!HeapTupleIsValid(tp))
1029 elog(ERROR, "cache lookup failed for function %u", funcid);
1031 result = ((Form_pg_proc) GETSTRUCT(tp))->proisstrict;
1032 ReleaseSysCache(tp);
1038 * Given procedure id, return the function's provolatile flag.
1041 func_volatile(Oid funcid)
1046 tp = SearchSysCache(PROCOID,
1047 ObjectIdGetDatum(funcid),
1049 if (!HeapTupleIsValid(tp))
1050 elog(ERROR, "cache lookup failed for function %u", funcid);
1052 result = ((Form_pg_proc) GETSTRUCT(tp))->provolatile;
1053 ReleaseSysCache(tp);
1057 /* ---------- RELATION CACHE ---------- */
1061 * Given name and namespace of a relation, look up the OID.
1063 * Returns InvalidOid if there is no such relation.
1066 get_relname_relid(const char *relname, Oid relnamespace)
1068 return GetSysCacheOid(RELNAMENSP,
1069 PointerGetDatum(relname),
1070 ObjectIdGetDatum(relnamespace),
1078 * Returns the number of attributes for a given relation.
1081 get_relnatts(Oid relid)
1085 tp = SearchSysCache(RELOID,
1086 ObjectIdGetDatum(relid),
1088 if (HeapTupleIsValid(tp))
1090 Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
1093 result = reltup->relnatts;
1094 ReleaseSysCache(tp);
1098 return InvalidAttrNumber;
1104 * Returns the name of a given relation.
1106 * Returns a palloc'd copy of the string, or NULL if no such relation.
1108 * NOTE: since relation name is not unique, be wary of code that uses this
1109 * for anything except preparing error messages.
1112 get_rel_name(Oid relid)
1116 tp = SearchSysCache(RELOID,
1117 ObjectIdGetDatum(relid),
1119 if (HeapTupleIsValid(tp))
1121 Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
1124 result = pstrdup(NameStr(reltup->relname));
1125 ReleaseSysCache(tp);
1135 * Returns the pg_namespace OID associated with a given relation.
1138 get_rel_namespace(Oid relid)
1142 tp = SearchSysCache(RELOID,
1143 ObjectIdGetDatum(relid),
1145 if (HeapTupleIsValid(tp))
1147 Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
1150 result = reltup->relnamespace;
1151 ReleaseSysCache(tp);
1161 * Returns the pg_type OID associated with a given relation.
1163 * Note: not all pg_class entries have associated pg_type OIDs; so be
1164 * careful to check for InvalidOid result.
1167 get_rel_type_id(Oid relid)
1171 tp = SearchSysCache(RELOID,
1172 ObjectIdGetDatum(relid),
1174 if (HeapTupleIsValid(tp))
1176 Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
1179 result = reltup->reltype;
1180 ReleaseSysCache(tp);
1190 * Returns the relkind associated with a given relation.
1193 get_rel_relkind(Oid relid)
1197 tp = SearchSysCache(RELOID,
1198 ObjectIdGetDatum(relid),
1200 if (HeapTupleIsValid(tp))
1202 Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
1205 result = reltup->relkind;
1206 ReleaseSysCache(tp);
1214 /* ---------- TYPE CACHE ---------- */
1219 * Given the type OID, determine whether the type is defined
1220 * (if not, it's only a shell).
1223 get_typisdefined(Oid typid)
1227 tp = SearchSysCache(TYPEOID,
1228 ObjectIdGetDatum(typid),
1230 if (HeapTupleIsValid(tp))
1232 Form_pg_type typtup = (Form_pg_type) GETSTRUCT(tp);
1235 result = typtup->typisdefined;
1236 ReleaseSysCache(tp);
1246 * Given the type OID, return the length of the type.
1249 get_typlen(Oid typid)
1253 tp = SearchSysCache(TYPEOID,
1254 ObjectIdGetDatum(typid),
1256 if (HeapTupleIsValid(tp))
1258 Form_pg_type typtup = (Form_pg_type) GETSTRUCT(tp);
1261 result = typtup->typlen;
1262 ReleaseSysCache(tp);
1272 * Given the type OID, determine whether the type is returned by value or
1273 * not. Returns true if by value, false if by reference.
1276 get_typbyval(Oid typid)
1280 tp = SearchSysCache(TYPEOID,
1281 ObjectIdGetDatum(typid),
1283 if (HeapTupleIsValid(tp))
1285 Form_pg_type typtup = (Form_pg_type) GETSTRUCT(tp);
1288 result = typtup->typbyval;
1289 ReleaseSysCache(tp);
1299 * A two-fer: given the type OID, return both typlen and typbyval.
1301 * Since both pieces of info are needed to know how to copy a Datum,
1302 * many places need both. Might as well get them with one cache lookup
1303 * instead of two. Also, this routine raises an error instead of
1304 * returning a bogus value when given a bad type OID.
1307 get_typlenbyval(Oid typid, int16 *typlen, bool *typbyval)
1310 Form_pg_type typtup;
1312 tp = SearchSysCache(TYPEOID,
1313 ObjectIdGetDatum(typid),
1315 if (!HeapTupleIsValid(tp))
1316 elog(ERROR, "cache lookup failed for type %u", typid);
1317 typtup = (Form_pg_type) GETSTRUCT(tp);
1318 *typlen = typtup->typlen;
1319 *typbyval = typtup->typbyval;
1320 ReleaseSysCache(tp);
1324 * get_typlenbyvalalign
1326 * A three-fer: given the type OID, return typlen, typbyval, typalign.
1329 get_typlenbyvalalign(Oid typid, int16 *typlen, bool *typbyval,
1333 Form_pg_type typtup;
1335 tp = SearchSysCache(TYPEOID,
1336 ObjectIdGetDatum(typid),
1338 if (!HeapTupleIsValid(tp))
1339 elog(ERROR, "cache lookup failed for type %u", typid);
1340 typtup = (Form_pg_type) GETSTRUCT(tp);
1341 *typlen = typtup->typlen;
1342 *typbyval = typtup->typbyval;
1343 *typalign = typtup->typalign;
1344 ReleaseSysCache(tp);
1349 * Given a pg_type row, select the type OID to pass to I/O functions
1351 * Formerly, all I/O functions were passed pg_type.typelem as their second
1352 * parameter, but we now have a more complex rule about what to pass.
1353 * This knowledge is intended to be centralized here --- direct references
1354 * to typelem elsewhere in the code are wrong, if they are associated with
1355 * I/O calls and not with actual subscripting operations! (But see
1356 * bootstrap.c's boot_get_type_io_data() if you need to change this.)
1358 * As of PostgreSQL 8.1, output functions receive only the value itself
1359 * and not any auxiliary parameters, so the name of this routine is now
1360 * a bit of a misnomer ... it should be getTypeInputParam.
1363 getTypeIOParam(HeapTuple typeTuple)
1365 Form_pg_type typeStruct = (Form_pg_type) GETSTRUCT(typeTuple);
1368 * Array types get their typelem as parameter; everybody else gets their
1369 * own type OID as parameter. (This is a change from 8.0, in which only
1370 * composite types got their own OID as parameter.)
1372 if (OidIsValid(typeStruct->typelem))
1373 return typeStruct->typelem;
1375 return HeapTupleGetOid(typeTuple);
1381 * A six-fer: given the type OID, return typlen, typbyval, typalign,
1382 * typdelim, typioparam, and IO function OID. The IO function
1383 * returned is controlled by IOFuncSelector
1386 get_type_io_data(Oid typid,
1387 IOFuncSelector which_func,
1395 HeapTuple typeTuple;
1396 Form_pg_type typeStruct;
1399 * In bootstrap mode, pass it off to bootstrap.c. This hack allows us to
1400 * use array_in and array_out during bootstrap.
1402 if (IsBootstrapProcessingMode())
1407 boot_get_type_io_data(typid,
1424 elog(ERROR, "binary I/O not supported during bootstrap");
1430 typeTuple = SearchSysCache(TYPEOID,
1431 ObjectIdGetDatum(typid),
1433 if (!HeapTupleIsValid(typeTuple))
1434 elog(ERROR, "cache lookup failed for type %u", typid);
1435 typeStruct = (Form_pg_type) GETSTRUCT(typeTuple);
1437 *typlen = typeStruct->typlen;
1438 *typbyval = typeStruct->typbyval;
1439 *typalign = typeStruct->typalign;
1440 *typdelim = typeStruct->typdelim;
1441 *typioparam = getTypeIOParam(typeTuple);
1445 *func = typeStruct->typinput;
1448 *func = typeStruct->typoutput;
1450 case IOFunc_receive:
1451 *func = typeStruct->typreceive;
1454 *func = typeStruct->typsend;
1457 ReleaseSysCache(typeTuple);
1462 get_typalign(Oid typid)
1466 tp = SearchSysCache(TYPEOID,
1467 ObjectIdGetDatum(typid),
1469 if (HeapTupleIsValid(tp))
1471 Form_pg_type typtup = (Form_pg_type) GETSTRUCT(tp);
1474 result = typtup->typalign;
1475 ReleaseSysCache(tp);
1484 get_typstorage(Oid typid)
1488 tp = SearchSysCache(TYPEOID,
1489 ObjectIdGetDatum(typid),
1491 if (HeapTupleIsValid(tp))
1493 Form_pg_type typtup = (Form_pg_type) GETSTRUCT(tp);
1496 result = typtup->typstorage;
1497 ReleaseSysCache(tp);
1506 * Given a type OID, return the type's default value, if any.
1508 * The result is a palloc'd expression node tree, or NULL if there
1509 * is no defined default for the datatype.
1511 * NB: caller should be prepared to coerce result to correct datatype;
1512 * the returned expression tree might produce something of the wrong type.
1515 get_typdefault(Oid typid)
1517 HeapTuple typeTuple;
1523 typeTuple = SearchSysCache(TYPEOID,
1524 ObjectIdGetDatum(typid),
1526 if (!HeapTupleIsValid(typeTuple))
1527 elog(ERROR, "cache lookup failed for type %u", typid);
1528 type = (Form_pg_type) GETSTRUCT(typeTuple);
1531 * typdefault and typdefaultbin are potentially null, so don't try to
1532 * access 'em as struct fields. Must do it the hard way with
1535 datum = SysCacheGetAttr(TYPEOID,
1537 Anum_pg_type_typdefaultbin,
1542 /* We have an expression default */
1543 expr = stringToNode(DatumGetCString(DirectFunctionCall1(textout,
1548 /* Perhaps we have a plain literal default */
1549 datum = SysCacheGetAttr(TYPEOID,
1551 Anum_pg_type_typdefault,
1556 char *strDefaultVal;
1558 /* Convert text datum to C string */
1559 strDefaultVal = DatumGetCString(DirectFunctionCall1(textout,
1561 /* Convert C string to a value of the given type */
1562 datum = OidInputFunctionCall(type->typinput, strDefaultVal,
1563 getTypeIOParam(typeTuple), -1);
1564 /* Build a Const node containing the value */
1565 expr = (Node *) makeConst(typid,
1570 pfree(strDefaultVal);
1579 ReleaseSysCache(typeTuple);
1586 * If the given type is a domain, return its base type;
1587 * otherwise return the type's own OID.
1590 getBaseType(Oid typid)
1594 return getBaseTypeAndTypmod(typid, &typmod);
1598 * getBaseTypeAndTypmod
1599 * If the given type is a domain, return its base type and typmod;
1600 * otherwise return the type's own OID, and leave *typmod unchanged.
1602 * Note that the "applied typmod" should be -1 for every domain level
1603 * above the bottommost; therefore, if the passed-in typid is indeed
1604 * a domain, *typmod should be -1.
1607 getBaseTypeAndTypmod(Oid typid, int32 *typmod)
1610 * We loop to find the bottom base type in a stack of domains.
1615 Form_pg_type typTup;
1617 tup = SearchSysCache(TYPEOID,
1618 ObjectIdGetDatum(typid),
1620 if (!HeapTupleIsValid(tup))
1621 elog(ERROR, "cache lookup failed for type %u", typid);
1622 typTup = (Form_pg_type) GETSTRUCT(tup);
1623 if (typTup->typtype != 'd')
1625 /* Not a domain, so done */
1626 ReleaseSysCache(tup);
1630 Assert(*typmod == -1);
1631 typid = typTup->typbasetype;
1632 *typmod = typTup->typtypmod;
1634 ReleaseSysCache(tup);
1643 * Given a type OID and a typmod value (pass -1 if typmod is unknown),
1644 * estimate the average width of values of the type. This is used by
1645 * the planner, which doesn't require absolutely correct results;
1646 * it's OK (and expected) to guess if we don't know for sure.
1649 get_typavgwidth(Oid typid, int32 typmod)
1651 int typlen = get_typlen(typid);
1655 * Easy if it's a fixed-width type
1661 * type_maximum_size knows the encoding of typmod for some datatypes;
1662 * don't duplicate that knowledge here.
1664 maxwidth = type_maximum_size(typid, typmod);
1668 * For BPCHAR, the max width is also the only width. Otherwise we
1669 * need to guess about the typical data width given the max. A sliding
1670 * scale for percentage of max width seems reasonable.
1672 if (typid == BPCHAROID)
1675 return maxwidth; /* assume full width */
1676 if (maxwidth < 1000)
1677 return 32 + (maxwidth - 32) / 2; /* assume 50% */
1680 * Beyond 1000, assume we're looking at something like
1681 * "varchar(10000)" where the limit isn't actually reached often, and
1682 * use a fixed estimate.
1684 return 32 + (1000 - 32) / 2;
1688 * Ooops, we have no idea ... wild guess time.
1696 * Given the type OID, find if it is a basic type, a complex type, etc.
1697 * It returns the null char if the cache lookup fails...
1700 get_typtype(Oid typid)
1704 tp = SearchSysCache(TYPEOID,
1705 ObjectIdGetDatum(typid),
1707 if (HeapTupleIsValid(tp))
1709 Form_pg_type typtup = (Form_pg_type) GETSTRUCT(tp);
1712 result = typtup->typtype;
1713 ReleaseSysCache(tp);
1723 * Convenience function to determine whether a type OID represents
1724 * a "rowtype" type --- either RECORD or a named composite type.
1727 type_is_rowtype(Oid typid)
1729 return (typid == RECORDOID || get_typtype(typid) == 'c');
1735 * Given the type OID, get the typrelid (InvalidOid if not a complex
1739 get_typ_typrelid(Oid typid)
1743 tp = SearchSysCache(TYPEOID,
1744 ObjectIdGetDatum(typid),
1746 if (HeapTupleIsValid(tp))
1748 Form_pg_type typtup = (Form_pg_type) GETSTRUCT(tp);
1751 result = typtup->typrelid;
1752 ReleaseSysCache(tp);
1762 * Given the type OID, get the typelem (InvalidOid if not an array type).
1764 * NB: this only considers varlena arrays to be true arrays; InvalidOid is
1765 * returned if the input is a fixed-length array type.
1768 get_element_type(Oid typid)
1772 tp = SearchSysCache(TYPEOID,
1773 ObjectIdGetDatum(typid),
1775 if (HeapTupleIsValid(tp))
1777 Form_pg_type typtup = (Form_pg_type) GETSTRUCT(tp);
1780 if (typtup->typlen == -1)
1781 result = typtup->typelem;
1783 result = InvalidOid;
1784 ReleaseSysCache(tp);
1794 * Given the type OID, get the corresponding array type.
1795 * Returns InvalidOid if no array type can be found.
1797 * NB: this only considers varlena arrays to be true arrays.
1800 get_array_type(Oid typid)
1804 tp = SearchSysCache(TYPEOID,
1805 ObjectIdGetDatum(typid),
1807 if (HeapTupleIsValid(tp))
1809 Form_pg_type typtup = (Form_pg_type) GETSTRUCT(tp);
1810 char *array_typename;
1813 array_typename = makeArrayTypeName(NameStr(typtup->typname));
1814 namespaceId = typtup->typnamespace;
1815 ReleaseSysCache(tp);
1817 tp = SearchSysCache(TYPENAMENSP,
1818 PointerGetDatum(array_typename),
1819 ObjectIdGetDatum(namespaceId),
1822 pfree(array_typename);
1824 if (HeapTupleIsValid(tp))
1828 typtup = (Form_pg_type) GETSTRUCT(tp);
1829 if (typtup->typlen == -1 && typtup->typelem == typid)
1830 result = HeapTupleGetOid(tp);
1832 result = InvalidOid;
1833 ReleaseSysCache(tp);
1843 * Get info needed for converting values of a type to internal form
1846 getTypeInputInfo(Oid type, Oid *typInput, Oid *typIOParam)
1848 HeapTuple typeTuple;
1851 typeTuple = SearchSysCache(TYPEOID,
1852 ObjectIdGetDatum(type),
1854 if (!HeapTupleIsValid(typeTuple))
1855 elog(ERROR, "cache lookup failed for type %u", type);
1856 pt = (Form_pg_type) GETSTRUCT(typeTuple);
1858 if (!pt->typisdefined)
1860 (errcode(ERRCODE_UNDEFINED_OBJECT),
1861 errmsg("type %s is only a shell",
1862 format_type_be(type))));
1863 if (!OidIsValid(pt->typinput))
1865 (errcode(ERRCODE_UNDEFINED_FUNCTION),
1866 errmsg("no input function available for type %s",
1867 format_type_be(type))));
1869 *typInput = pt->typinput;
1870 *typIOParam = getTypeIOParam(typeTuple);
1872 ReleaseSysCache(typeTuple);
1878 * Get info needed for printing values of a type
1881 getTypeOutputInfo(Oid type, Oid *typOutput, bool *typIsVarlena)
1883 HeapTuple typeTuple;
1886 typeTuple = SearchSysCache(TYPEOID,
1887 ObjectIdGetDatum(type),
1889 if (!HeapTupleIsValid(typeTuple))
1890 elog(ERROR, "cache lookup failed for type %u", type);
1891 pt = (Form_pg_type) GETSTRUCT(typeTuple);
1893 if (!pt->typisdefined)
1895 (errcode(ERRCODE_UNDEFINED_OBJECT),
1896 errmsg("type %s is only a shell",
1897 format_type_be(type))));
1898 if (!OidIsValid(pt->typoutput))
1900 (errcode(ERRCODE_UNDEFINED_FUNCTION),
1901 errmsg("no output function available for type %s",
1902 format_type_be(type))));
1904 *typOutput = pt->typoutput;
1905 *typIsVarlena = (!pt->typbyval) && (pt->typlen == -1);
1907 ReleaseSysCache(typeTuple);
1911 * getTypeBinaryInputInfo
1913 * Get info needed for binary input of values of a type
1916 getTypeBinaryInputInfo(Oid type, Oid *typReceive, Oid *typIOParam)
1918 HeapTuple typeTuple;
1921 typeTuple = SearchSysCache(TYPEOID,
1922 ObjectIdGetDatum(type),
1924 if (!HeapTupleIsValid(typeTuple))
1925 elog(ERROR, "cache lookup failed for type %u", type);
1926 pt = (Form_pg_type) GETSTRUCT(typeTuple);
1928 if (!pt->typisdefined)
1930 (errcode(ERRCODE_UNDEFINED_OBJECT),
1931 errmsg("type %s is only a shell",
1932 format_type_be(type))));
1933 if (!OidIsValid(pt->typreceive))
1935 (errcode(ERRCODE_UNDEFINED_FUNCTION),
1936 errmsg("no binary input function available for type %s",
1937 format_type_be(type))));
1939 *typReceive = pt->typreceive;
1940 *typIOParam = getTypeIOParam(typeTuple);
1942 ReleaseSysCache(typeTuple);
1946 * getTypeBinaryOutputInfo
1948 * Get info needed for binary output of values of a type
1951 getTypeBinaryOutputInfo(Oid type, Oid *typSend, bool *typIsVarlena)
1953 HeapTuple typeTuple;
1956 typeTuple = SearchSysCache(TYPEOID,
1957 ObjectIdGetDatum(type),
1959 if (!HeapTupleIsValid(typeTuple))
1960 elog(ERROR, "cache lookup failed for type %u", type);
1961 pt = (Form_pg_type) GETSTRUCT(typeTuple);
1963 if (!pt->typisdefined)
1965 (errcode(ERRCODE_UNDEFINED_OBJECT),
1966 errmsg("type %s is only a shell",
1967 format_type_be(type))));
1968 if (!OidIsValid(pt->typsend))
1970 (errcode(ERRCODE_UNDEFINED_FUNCTION),
1971 errmsg("no binary output function available for type %s",
1972 format_type_be(type))));
1974 *typSend = pt->typsend;
1975 *typIsVarlena = (!pt->typbyval) && (pt->typlen == -1);
1977 ReleaseSysCache(typeTuple);
1981 /* ---------- STATISTICS CACHE ---------- */
1986 * Given the table and attribute number of a column, get the average
1987 * width of entries in the column. Return zero if no data available.
1990 get_attavgwidth(Oid relid, AttrNumber attnum)
1994 tp = SearchSysCache(STATRELATT,
1995 ObjectIdGetDatum(relid),
1996 Int16GetDatum(attnum),
1998 if (HeapTupleIsValid(tp))
2000 int32 stawidth = ((Form_pg_statistic) GETSTRUCT(tp))->stawidth;
2002 ReleaseSysCache(tp);
2012 * Extract the contents of a "slot" of a pg_statistic tuple.
2013 * Returns TRUE if requested slot type was found, else FALSE.
2015 * Unlike other routines in this file, this takes a pointer to an
2016 * already-looked-up tuple in the pg_statistic cache. We do this since
2017 * most callers will want to extract more than one value from the cache
2018 * entry, and we don't want to repeat the cache lookup unnecessarily.
2020 * statstuple: pg_statistics tuple to be examined.
2021 * atttype: type OID of attribute (can be InvalidOid if values == NULL).
2022 * atttypmod: typmod of attribute (can be 0 if values == NULL).
2023 * reqkind: STAKIND code for desired statistics slot kind.
2024 * reqop: STAOP value wanted, or InvalidOid if don't care.
2025 * values, nvalues: if not NULL, the slot's stavalues are extracted.
2026 * numbers, nnumbers: if not NULL, the slot's stanumbers are extracted.
2028 * If assigned, values and numbers are set to point to palloc'd arrays.
2029 * If the attribute type is pass-by-reference, the values referenced by
2030 * the values array are themselves palloc'd. The palloc'd stuff can be
2031 * freed by calling free_attstatsslot.
2034 get_attstatsslot(HeapTuple statstuple,
2035 Oid atttype, int32 atttypmod,
2036 int reqkind, Oid reqop,
2037 Datum **values, int *nvalues,
2038 float4 **numbers, int *nnumbers)
2040 Form_pg_statistic stats = (Form_pg_statistic) GETSTRUCT(statstuple);
2045 ArrayType *statarray;
2047 HeapTuple typeTuple;
2048 Form_pg_type typeForm;
2050 for (i = 0; i < STATISTIC_NUM_SLOTS; i++)
2052 if ((&stats->stakind1)[i] == reqkind &&
2053 (reqop == InvalidOid || (&stats->staop1)[i] == reqop))
2056 if (i >= STATISTIC_NUM_SLOTS)
2057 return false; /* not there */
2061 val = SysCacheGetAttr(STATRELATT, statstuple,
2062 Anum_pg_statistic_stavalues1 + i,
2065 elog(ERROR, "stavalues is null");
2066 statarray = DatumGetArrayTypeP(val);
2068 /* Need to get info about the array element type */
2069 typeTuple = SearchSysCache(TYPEOID,
2070 ObjectIdGetDatum(atttype),
2072 if (!HeapTupleIsValid(typeTuple))
2073 elog(ERROR, "cache lookup failed for type %u", atttype);
2074 typeForm = (Form_pg_type) GETSTRUCT(typeTuple);
2076 /* Deconstruct array into Datum elements; NULLs not expected */
2077 deconstruct_array(statarray,
2082 values, NULL, nvalues);
2085 * If the element type is pass-by-reference, we now have a bunch of
2086 * Datums that are pointers into the syscache value. Copy them to
2087 * avoid problems if syscache decides to drop the entry.
2089 if (!typeForm->typbyval)
2091 for (j = 0; j < *nvalues; j++)
2093 (*values)[j] = datumCopy((*values)[j],
2099 ReleaseSysCache(typeTuple);
2102 * Free statarray if it's a detoasted copy.
2104 if ((Pointer) statarray != DatumGetPointer(val))
2110 val = SysCacheGetAttr(STATRELATT, statstuple,
2111 Anum_pg_statistic_stanumbers1 + i,
2114 elog(ERROR, "stanumbers is null");
2115 statarray = DatumGetArrayTypeP(val);
2118 * We expect the array to be a 1-D float4 array; verify that. We don't
2119 * need to use deconstruct_array() since the array data is just going
2120 * to look like a C array of float4 values.
2122 narrayelem = ARR_DIMS(statarray)[0];
2123 if (ARR_NDIM(statarray) != 1 || narrayelem <= 0 ||
2124 ARR_HASNULL(statarray) ||
2125 ARR_ELEMTYPE(statarray) != FLOAT4OID)
2126 elog(ERROR, "stanumbers is not a 1-D float4 array");
2127 *numbers = (float4 *) palloc(narrayelem * sizeof(float4));
2128 memcpy(*numbers, ARR_DATA_PTR(statarray), narrayelem * sizeof(float4));
2129 *nnumbers = narrayelem;
2132 * Free statarray if it's a detoasted copy.
2134 if ((Pointer) statarray != DatumGetPointer(val))
2143 * Free data allocated by get_attstatsslot
2145 * atttype need be valid only if values != NULL.
2148 free_attstatsslot(Oid atttype,
2149 Datum *values, int nvalues,
2150 float4 *numbers, int nnumbers)
2154 if (!get_typbyval(atttype))
2158 for (i = 0; i < nvalues; i++)
2159 pfree(DatumGetPointer(values[i]));
2167 /* ---------- PG_NAMESPACE CACHE ---------- */
2170 * get_namespace_name
2171 * Returns the name of a given namespace
2173 * Returns a palloc'd copy of the string, or NULL if no such namespace.
2176 get_namespace_name(Oid nspid)
2180 tp = SearchSysCache(NAMESPACEOID,
2181 ObjectIdGetDatum(nspid),
2183 if (HeapTupleIsValid(tp))
2185 Form_pg_namespace nsptup = (Form_pg_namespace) GETSTRUCT(tp);
2188 result = pstrdup(NameStr(nsptup->nspname));
2189 ReleaseSysCache(tp);
2196 /* ---------- PG_AUTHID CACHE ---------- */
2200 * Given a role name, look up the role's OID.
2201 * Returns InvalidOid if no such role.
2204 get_roleid(const char *rolname)
2206 return GetSysCacheOid(AUTHNAME,
2207 PointerGetDatum(rolname),
2212 * get_roleid_checked
2213 * Given a role name, look up the role's OID.
2214 * ereports if no such role.
2217 get_roleid_checked(const char *rolname)
2221 roleid = get_roleid(rolname);
2222 if (!OidIsValid(roleid))
2224 (errcode(ERRCODE_UNDEFINED_OBJECT),
2225 errmsg("role \"%s\" does not exist", rolname)));