1 /*-------------------------------------------------------------------------
4 * Convenience routines for common queries in the system catalog cache.
6 * Portions Copyright (c) 1996-2005, 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.123 2005/04/11 23:06:56 tgl Exp $
13 * Eventually, the index information should go through here, too.
14 *-------------------------------------------------------------------------
17 #include "miscadmin.h"
19 #include "access/hash.h"
20 #include "access/tupmacs.h"
21 #include "catalog/pg_amop.h"
22 #include "catalog/pg_amproc.h"
23 #include "catalog/pg_namespace.h"
24 #include "catalog/pg_opclass.h"
25 #include "catalog/pg_operator.h"
26 #include "catalog/pg_proc.h"
27 #include "catalog/pg_shadow.h"
28 #include "catalog/pg_group.h"
29 #include "catalog/pg_statistic.h"
30 #include "catalog/pg_type.h"
31 #include "nodes/makefuncs.h"
32 #include "utils/array.h"
33 #include "utils/builtins.h"
34 #include "utils/catcache.h"
35 #include "utils/datum.h"
36 #include "utils/lsyscache.h"
37 #include "utils/syscache.h"
40 /* ---------- AMOP CACHES ---------- */
45 * Return t iff operator 'opno' is in operator class 'opclass'.
48 op_in_opclass(Oid opno, Oid opclass)
50 return SearchSysCacheExists(AMOPOPID,
51 ObjectIdGetDatum(opno),
52 ObjectIdGetDatum(opclass),
57 * get_op_opclass_strategy
59 * Get the operator's strategy number within the specified opclass,
60 * or 0 if it's not a member of the opclass.
63 get_op_opclass_strategy(Oid opno, Oid opclass)
66 Form_pg_amop amop_tup;
69 tp = SearchSysCache(AMOPOPID,
70 ObjectIdGetDatum(opno),
71 ObjectIdGetDatum(opclass),
73 if (!HeapTupleIsValid(tp))
75 amop_tup = (Form_pg_amop) GETSTRUCT(tp);
76 result = amop_tup->amopstrategy;
82 * get_op_opclass_properties
84 * Get the operator's strategy number, subtype, and recheck (lossy) flag
85 * within the specified opclass.
87 * Caller should already have verified that opno is a member of opclass,
88 * therefore we raise an error if the tuple is not found.
91 get_op_opclass_properties(Oid opno, Oid opclass,
92 int *strategy, Oid *subtype, bool *recheck)
95 Form_pg_amop amop_tup;
97 tp = SearchSysCache(AMOPOPID,
98 ObjectIdGetDatum(opno),
99 ObjectIdGetDatum(opclass),
101 if (!HeapTupleIsValid(tp))
102 elog(ERROR, "operator %u is not a member of opclass %u",
104 amop_tup = (Form_pg_amop) GETSTRUCT(tp);
105 *strategy = amop_tup->amopstrategy;
106 *subtype = amop_tup->amopsubtype;
107 *recheck = amop_tup->amopreqcheck;
113 * Get the OID of the operator that implements the specified strategy
114 * with the specified subtype for the specified opclass.
116 * Returns InvalidOid if there is no pg_amop entry for the given keys.
119 get_opclass_member(Oid opclass, Oid subtype, int16 strategy)
122 Form_pg_amop amop_tup;
125 tp = SearchSysCache(AMOPSTRATEGY,
126 ObjectIdGetDatum(opclass),
127 ObjectIdGetDatum(subtype),
128 Int16GetDatum(strategy),
130 if (!HeapTupleIsValid(tp))
132 amop_tup = (Form_pg_amop) GETSTRUCT(tp);
133 result = amop_tup->amopopr;
139 * get_op_hash_function
140 * Get the OID of the datatype-specific hash function associated with
141 * a hashable equality operator.
143 * Returns InvalidOid if no hash function can be found. (This indicates
144 * that the operator should not have been marked oprcanhash.)
147 get_op_hash_function(Oid opno)
151 Oid opclass = InvalidOid;
154 * Search pg_amop to see if the target operator is registered as the
155 * "=" operator of any hash opclass. If the operator is registered in
156 * multiple opclasses, assume we can use the associated hash function
159 catlist = SearchSysCacheList(AMOPOPID, 1,
160 ObjectIdGetDatum(opno),
163 for (i = 0; i < catlist->n_members; i++)
165 HeapTuple tuple = &catlist->members[i]->tuple;
166 Form_pg_amop aform = (Form_pg_amop) GETSTRUCT(tuple);
168 if (aform->amopstrategy == HTEqualStrategyNumber &&
169 opclass_is_hash(aform->amopclaid))
171 opclass = aform->amopclaid;
176 ReleaseSysCacheList(catlist);
178 if (OidIsValid(opclass))
180 /* Found a suitable opclass, get its default hash support function */
181 return get_opclass_proc(opclass, InvalidOid, HASHPROC);
184 /* Didn't find a match... */
189 /* ---------- AMPROC CACHES ---------- */
193 * Get the OID of the specified support function
194 * for the specified opclass and subtype.
196 * Returns InvalidOid if there is no pg_amproc entry for the given keys.
199 get_opclass_proc(Oid opclass, Oid subtype, int16 procnum)
202 Form_pg_amproc amproc_tup;
205 tp = SearchSysCache(AMPROCNUM,
206 ObjectIdGetDatum(opclass),
207 ObjectIdGetDatum(subtype),
208 Int16GetDatum(procnum),
210 if (!HeapTupleIsValid(tp))
212 amproc_tup = (Form_pg_amproc) GETSTRUCT(tp);
213 result = amproc_tup->amproc;
219 /* ---------- ATTRIBUTE CACHES ---------- */
223 * Given the relation id and the attribute number,
224 * return the "attname" field from the attribute relation.
226 * Note: returns a palloc'd copy of the string, or NULL if no such attribute.
229 get_attname(Oid relid, AttrNumber attnum)
233 tp = SearchSysCache(ATTNUM,
234 ObjectIdGetDatum(relid),
235 Int16GetDatum(attnum),
237 if (HeapTupleIsValid(tp))
239 Form_pg_attribute att_tup = (Form_pg_attribute) GETSTRUCT(tp);
242 result = pstrdup(NameStr(att_tup->attname));
251 * get_relid_attribute_name
253 * Same as above routine get_attname(), except that error
254 * is handled by elog() instead of returning NULL.
257 get_relid_attribute_name(Oid relid, AttrNumber attnum)
261 attname = get_attname(relid, attnum);
263 elog(ERROR, "cache lookup failed for attribute %d of relation %u",
271 * Given the relation id and the attribute name,
272 * return the "attnum" field from the attribute relation.
274 * Returns InvalidAttrNumber if the attr doesn't exist (or is dropped).
277 get_attnum(Oid relid, const char *attname)
281 tp = SearchSysCacheAttName(relid, attname);
282 if (HeapTupleIsValid(tp))
284 Form_pg_attribute att_tup = (Form_pg_attribute) GETSTRUCT(tp);
287 result = att_tup->attnum;
292 return InvalidAttrNumber;
298 * Given the relation OID and the attribute number with the relation,
299 * return the attribute type OID.
302 get_atttype(Oid relid, AttrNumber attnum)
306 tp = SearchSysCache(ATTNUM,
307 ObjectIdGetDatum(relid),
308 Int16GetDatum(attnum),
310 if (HeapTupleIsValid(tp))
312 Form_pg_attribute att_tup = (Form_pg_attribute) GETSTRUCT(tp);
315 result = att_tup->atttypid;
326 * Given the relation id and the attribute number,
327 * return the "atttypmod" field from the attribute relation.
330 get_atttypmod(Oid relid, AttrNumber attnum)
334 tp = SearchSysCache(ATTNUM,
335 ObjectIdGetDatum(relid),
336 Int16GetDatum(attnum),
338 if (HeapTupleIsValid(tp))
340 Form_pg_attribute att_tup = (Form_pg_attribute) GETSTRUCT(tp);
343 result = att_tup->atttypmod;
354 * A two-fer: given the relation id and the attribute number,
355 * fetch both type OID and atttypmod in a single cache lookup.
357 * Unlike the otherwise-similar get_atttype/get_atttypmod, this routine
358 * raises an error if it can't obtain the information.
361 get_atttypetypmod(Oid relid, AttrNumber attnum,
362 Oid *typid, int32 *typmod)
365 Form_pg_attribute att_tup;
367 tp = SearchSysCache(ATTNUM,
368 ObjectIdGetDatum(relid),
369 Int16GetDatum(attnum),
371 if (!HeapTupleIsValid(tp))
372 elog(ERROR, "cache lookup failed for attribute %d of relation %u",
374 att_tup = (Form_pg_attribute) GETSTRUCT(tp);
376 *typid = att_tup->atttypid;
377 *typmod = att_tup->atttypmod;
381 /* ---------- INDEX CACHE ---------- */
383 /* watch this space...
386 /* ---------- OPCLASS CACHE ---------- */
391 * Returns TRUE iff the specified opclass is associated with the
392 * btree index access method.
395 opclass_is_btree(Oid opclass)
398 Form_pg_opclass cla_tup;
401 tp = SearchSysCache(CLAOID,
402 ObjectIdGetDatum(opclass),
404 if (!HeapTupleIsValid(tp))
405 elog(ERROR, "cache lookup failed for opclass %u", opclass);
406 cla_tup = (Form_pg_opclass) GETSTRUCT(tp);
408 result = (cla_tup->opcamid == BTREE_AM_OID);
416 * Returns TRUE iff the specified opclass is associated with the
417 * hash index access method.
420 opclass_is_hash(Oid opclass)
423 Form_pg_opclass cla_tup;
426 tp = SearchSysCache(CLAOID,
427 ObjectIdGetDatum(opclass),
429 if (!HeapTupleIsValid(tp))
430 elog(ERROR, "cache lookup failed for opclass %u", opclass);
431 cla_tup = (Form_pg_opclass) GETSTRUCT(tp);
433 result = (cla_tup->opcamid == HASH_AM_OID);
438 /* ---------- OPERATOR CACHE ---------- */
443 * Returns the regproc id of the routine used to implement an
444 * operator given the operator oid.
451 tp = SearchSysCache(OPEROID,
452 ObjectIdGetDatum(opno),
454 if (HeapTupleIsValid(tp))
456 Form_pg_operator optup = (Form_pg_operator) GETSTRUCT(tp);
459 result = optup->oprcode;
464 return (RegProcedure) InvalidOid;
469 * returns the name of the operator with the given opno
471 * Note: returns a palloc'd copy of the string, or NULL if no such operator.
478 tp = SearchSysCache(OPEROID,
479 ObjectIdGetDatum(opno),
481 if (HeapTupleIsValid(tp))
483 Form_pg_operator optup = (Form_pg_operator) GETSTRUCT(tp);
486 result = pstrdup(NameStr(optup->oprname));
497 * Returns the left and right input datatypes for an operator
498 * (InvalidOid if not relevant).
501 op_input_types(Oid opno, Oid *lefttype, Oid *righttype)
504 Form_pg_operator optup;
506 tp = SearchSysCache(OPEROID,
507 ObjectIdGetDatum(opno),
509 if (!HeapTupleIsValid(tp)) /* shouldn't happen */
510 elog(ERROR, "cache lookup failed for operator %u", opno);
511 optup = (Form_pg_operator) GETSTRUCT(tp);
512 *lefttype = optup->oprleft;
513 *righttype = optup->oprright;
520 * Returns the left and right sort operators corresponding to a
521 * mergejoinable operator, or false if the operator is not mergejoinable.
524 op_mergejoinable(Oid opno, Oid *leftOp, Oid *rightOp)
529 tp = SearchSysCache(OPEROID,
530 ObjectIdGetDatum(opno),
532 if (HeapTupleIsValid(tp))
534 Form_pg_operator optup = (Form_pg_operator) GETSTRUCT(tp);
536 if (optup->oprlsortop &&
539 *leftOp = optup->oprlsortop;
540 *rightOp = optup->oprrsortop;
549 * op_mergejoin_crossops
551 * Returns the cross-type comparison operators (ltype "<" rtype and
552 * ltype ">" rtype) for an operator previously determined to be
553 * mergejoinable. Optionally, fetches the regproc ids of these
554 * operators, as well as their operator OIDs.
557 op_mergejoin_crossops(Oid opno, Oid *ltop, Oid *gtop,
558 RegProcedure *ltproc, RegProcedure *gtproc)
561 Form_pg_operator optup;
564 * Get the declared comparison operators of the operator.
566 tp = SearchSysCache(OPEROID,
567 ObjectIdGetDatum(opno),
569 if (!HeapTupleIsValid(tp)) /* shouldn't happen */
570 elog(ERROR, "cache lookup failed for operator %u", opno);
571 optup = (Form_pg_operator) GETSTRUCT(tp);
572 *ltop = optup->oprltcmpop;
573 *gtop = optup->oprgtcmpop;
576 /* Check < op provided */
577 if (!OidIsValid(*ltop))
578 elog(ERROR, "mergejoin operator %u has no matching < operator",
581 *ltproc = get_opcode(*ltop);
583 /* Check > op provided */
584 if (!OidIsValid(*gtop))
585 elog(ERROR, "mergejoin operator %u has no matching > operator",
588 *gtproc = get_opcode(*gtop);
594 * Returns true if the operator is hashjoinable.
597 op_hashjoinable(Oid opno)
602 tp = SearchSysCache(OPEROID,
603 ObjectIdGetDatum(opno),
605 if (HeapTupleIsValid(tp))
607 Form_pg_operator optup = (Form_pg_operator) GETSTRUCT(tp);
609 result = optup->oprcanhash;
618 * Get the proisstrict flag for the operator's underlying function.
623 RegProcedure funcid = get_opcode(opno);
625 if (funcid == (RegProcedure) InvalidOid)
626 elog(ERROR, "operator %u does not exist", opno);
628 return func_strict((Oid) funcid);
634 * Get the provolatile flag for the operator's underlying function.
637 op_volatile(Oid opno)
639 RegProcedure funcid = get_opcode(opno);
641 if (funcid == (RegProcedure) InvalidOid)
642 elog(ERROR, "operator %u does not exist", opno);
644 return func_volatile((Oid) funcid);
650 * Returns the corresponding commutator of an operator.
653 get_commutator(Oid opno)
657 tp = SearchSysCache(OPEROID,
658 ObjectIdGetDatum(opno),
660 if (HeapTupleIsValid(tp))
662 Form_pg_operator optup = (Form_pg_operator) GETSTRUCT(tp);
665 result = optup->oprcom;
676 * Returns the corresponding negator of an operator.
679 get_negator(Oid opno)
683 tp = SearchSysCache(OPEROID,
684 ObjectIdGetDatum(opno),
686 if (HeapTupleIsValid(tp))
688 Form_pg_operator optup = (Form_pg_operator) GETSTRUCT(tp);
691 result = optup->oprnegate;
702 * Returns procedure id for computing selectivity of an operator.
705 get_oprrest(Oid opno)
709 tp = SearchSysCache(OPEROID,
710 ObjectIdGetDatum(opno),
712 if (HeapTupleIsValid(tp))
714 Form_pg_operator optup = (Form_pg_operator) GETSTRUCT(tp);
717 result = optup->oprrest;
722 return (RegProcedure) InvalidOid;
728 * Returns procedure id for computing selectivity of a join.
731 get_oprjoin(Oid opno)
735 tp = SearchSysCache(OPEROID,
736 ObjectIdGetDatum(opno),
738 if (HeapTupleIsValid(tp))
740 Form_pg_operator optup = (Form_pg_operator) GETSTRUCT(tp);
743 result = optup->oprjoin;
748 return (RegProcedure) InvalidOid;
751 /* ---------- FUNCTION CACHE ---------- */
755 * returns the name of the function with the given funcid
757 * Note: returns a palloc'd copy of the string, or NULL if no such function.
760 get_func_name(Oid funcid)
764 tp = SearchSysCache(PROCOID,
765 ObjectIdGetDatum(funcid),
767 if (HeapTupleIsValid(tp))
769 Form_pg_proc functup = (Form_pg_proc) GETSTRUCT(tp);
772 result = pstrdup(NameStr(functup->proname));
782 * Given procedure id, return the function's result type.
785 get_func_rettype(Oid funcid)
790 tp = SearchSysCache(PROCOID,
791 ObjectIdGetDatum(funcid),
793 if (!HeapTupleIsValid(tp))
794 elog(ERROR, "cache lookup failed for function %u", funcid);
796 result = ((Form_pg_proc) GETSTRUCT(tp))->prorettype;
803 * Given procedure id, return the number of arguments.
806 get_func_nargs(Oid funcid)
811 tp = SearchSysCache(PROCOID,
812 ObjectIdGetDatum(funcid),
814 if (!HeapTupleIsValid(tp))
815 elog(ERROR, "cache lookup failed for function %u", funcid);
817 result = ((Form_pg_proc) GETSTRUCT(tp))->pronargs;
824 * Given procedure id, return the function's argument and result types.
825 * (The return value is the result type.)
827 * The arguments are returned as a palloc'd array.
830 get_func_signature(Oid funcid, Oid **argtypes, int *nargs)
833 Form_pg_proc procstruct;
836 tp = SearchSysCache(PROCOID,
837 ObjectIdGetDatum(funcid),
839 if (!HeapTupleIsValid(tp))
840 elog(ERROR, "cache lookup failed for function %u", funcid);
842 procstruct = (Form_pg_proc) GETSTRUCT(tp);
844 result = procstruct->prorettype;
845 *nargs = (int) procstruct->pronargs;
846 Assert(*nargs == procstruct->proargtypes.dim1);
847 *argtypes = (Oid *) palloc(*nargs * sizeof(Oid));
848 memcpy(*argtypes, procstruct->proargtypes.values, *nargs * sizeof(Oid));
856 * Given procedure id, return the function's proretset flag.
859 get_func_retset(Oid funcid)
864 tp = SearchSysCache(PROCOID,
865 ObjectIdGetDatum(funcid),
867 if (!HeapTupleIsValid(tp))
868 elog(ERROR, "cache lookup failed for function %u", funcid);
870 result = ((Form_pg_proc) GETSTRUCT(tp))->proretset;
877 * Given procedure id, return the function's proisstrict flag.
880 func_strict(Oid funcid)
885 tp = SearchSysCache(PROCOID,
886 ObjectIdGetDatum(funcid),
888 if (!HeapTupleIsValid(tp))
889 elog(ERROR, "cache lookup failed for function %u", funcid);
891 result = ((Form_pg_proc) GETSTRUCT(tp))->proisstrict;
898 * Given procedure id, return the function's provolatile flag.
901 func_volatile(Oid funcid)
906 tp = SearchSysCache(PROCOID,
907 ObjectIdGetDatum(funcid),
909 if (!HeapTupleIsValid(tp))
910 elog(ERROR, "cache lookup failed for function %u", funcid);
912 result = ((Form_pg_proc) GETSTRUCT(tp))->provolatile;
917 /* ---------- RELATION CACHE ---------- */
921 * Given name and namespace of a relation, look up the OID.
923 * Returns InvalidOid if there is no such relation.
926 get_relname_relid(const char *relname, Oid relnamespace)
928 return GetSysCacheOid(RELNAMENSP,
929 PointerGetDatum(relname),
930 ObjectIdGetDatum(relnamespace),
935 * get_system_catalog_relid
936 * Get the OID of a system catalog identified by name.
939 get_system_catalog_relid(const char *catname)
943 relid = GetSysCacheOid(RELNAMENSP,
944 PointerGetDatum(catname),
945 ObjectIdGetDatum(PG_CATALOG_NAMESPACE),
947 if (!OidIsValid(relid))
948 elog(ERROR, "cache lookup failed for system relation %s", catname);
957 * Returns the number of attributes for a given relation.
960 get_relnatts(Oid relid)
964 tp = SearchSysCache(RELOID,
965 ObjectIdGetDatum(relid),
967 if (HeapTupleIsValid(tp))
969 Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
972 result = reltup->relnatts;
977 return InvalidAttrNumber;
983 * Returns the name of a given relation.
985 * Returns a palloc'd copy of the string, or NULL if no such relation.
987 * NOTE: since relation name is not unique, be wary of code that uses this
988 * for anything except preparing error messages.
991 get_rel_name(Oid relid)
995 tp = SearchSysCache(RELOID,
996 ObjectIdGetDatum(relid),
998 if (HeapTupleIsValid(tp))
1000 Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
1003 result = pstrdup(NameStr(reltup->relname));
1004 ReleaseSysCache(tp);
1014 * Returns the pg_namespace OID associated with a given relation.
1017 get_rel_namespace(Oid relid)
1021 tp = SearchSysCache(RELOID,
1022 ObjectIdGetDatum(relid),
1024 if (HeapTupleIsValid(tp))
1026 Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
1029 result = reltup->relnamespace;
1030 ReleaseSysCache(tp);
1040 * Returns the pg_type OID associated with a given relation.
1042 * Note: not all pg_class entries have associated pg_type OIDs; so be
1043 * careful to check for InvalidOid result.
1046 get_rel_type_id(Oid relid)
1050 tp = SearchSysCache(RELOID,
1051 ObjectIdGetDatum(relid),
1053 if (HeapTupleIsValid(tp))
1055 Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
1058 result = reltup->reltype;
1059 ReleaseSysCache(tp);
1069 * Returns the relkind associated with a given relation.
1072 get_rel_relkind(Oid relid)
1076 tp = SearchSysCache(RELOID,
1077 ObjectIdGetDatum(relid),
1079 if (HeapTupleIsValid(tp))
1081 Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
1084 result = reltup->relkind;
1085 ReleaseSysCache(tp);
1093 /* ---------- TYPE CACHE ---------- */
1098 * Given the type OID, determine whether the type is defined
1099 * (if not, it's only a shell).
1102 get_typisdefined(Oid typid)
1106 tp = SearchSysCache(TYPEOID,
1107 ObjectIdGetDatum(typid),
1109 if (HeapTupleIsValid(tp))
1111 Form_pg_type typtup = (Form_pg_type) GETSTRUCT(tp);
1114 result = typtup->typisdefined;
1115 ReleaseSysCache(tp);
1125 * Given the type OID, return the length of the type.
1128 get_typlen(Oid typid)
1132 tp = SearchSysCache(TYPEOID,
1133 ObjectIdGetDatum(typid),
1135 if (HeapTupleIsValid(tp))
1137 Form_pg_type typtup = (Form_pg_type) GETSTRUCT(tp);
1140 result = typtup->typlen;
1141 ReleaseSysCache(tp);
1151 * Given the type OID, determine whether the type is returned by value or
1152 * not. Returns true if by value, false if by reference.
1155 get_typbyval(Oid typid)
1159 tp = SearchSysCache(TYPEOID,
1160 ObjectIdGetDatum(typid),
1162 if (HeapTupleIsValid(tp))
1164 Form_pg_type typtup = (Form_pg_type) GETSTRUCT(tp);
1167 result = typtup->typbyval;
1168 ReleaseSysCache(tp);
1178 * A two-fer: given the type OID, return both typlen and typbyval.
1180 * Since both pieces of info are needed to know how to copy a Datum,
1181 * many places need both. Might as well get them with one cache lookup
1182 * instead of two. Also, this routine raises an error instead of
1183 * returning a bogus value when given a bad type OID.
1186 get_typlenbyval(Oid typid, int16 *typlen, bool *typbyval)
1189 Form_pg_type typtup;
1191 tp = SearchSysCache(TYPEOID,
1192 ObjectIdGetDatum(typid),
1194 if (!HeapTupleIsValid(tp))
1195 elog(ERROR, "cache lookup failed for type %u", typid);
1196 typtup = (Form_pg_type) GETSTRUCT(tp);
1197 *typlen = typtup->typlen;
1198 *typbyval = typtup->typbyval;
1199 ReleaseSysCache(tp);
1203 * get_typlenbyvalalign
1205 * A three-fer: given the type OID, return typlen, typbyval, typalign.
1208 get_typlenbyvalalign(Oid typid, int16 *typlen, bool *typbyval,
1212 Form_pg_type typtup;
1214 tp = SearchSysCache(TYPEOID,
1215 ObjectIdGetDatum(typid),
1217 if (!HeapTupleIsValid(tp))
1218 elog(ERROR, "cache lookup failed for type %u", typid);
1219 typtup = (Form_pg_type) GETSTRUCT(tp);
1220 *typlen = typtup->typlen;
1221 *typbyval = typtup->typbyval;
1222 *typalign = typtup->typalign;
1223 ReleaseSysCache(tp);
1228 * Given a pg_type row, select the type OID to pass to I/O functions
1230 * Formerly, all I/O functions were passed pg_type.typelem as their second
1231 * parameter, but we now have a more complex rule about what to pass.
1232 * This knowledge is intended to be centralized here --- direct references
1233 * to typelem elsewhere in the code are wrong, if they are associated with
1234 * I/O calls and not with actual subscripting operations! (But see
1235 * bootstrap.c, which can't conveniently use this routine.)
1238 getTypeIOParam(HeapTuple typeTuple)
1240 Form_pg_type typeStruct = (Form_pg_type) GETSTRUCT(typeTuple);
1243 * Composite types get their own OID as parameter; array types get
1244 * their typelem as parameter; everybody else gets zero.
1246 if (typeStruct->typtype == 'c')
1247 return HeapTupleGetOid(typeTuple);
1249 return typeStruct->typelem;
1255 * A six-fer: given the type OID, return typlen, typbyval, typalign,
1256 * typdelim, typioparam, and IO function OID. The IO function
1257 * returned is controlled by IOFuncSelector
1260 get_type_io_data(Oid typid,
1261 IOFuncSelector which_func,
1269 HeapTuple typeTuple;
1270 Form_pg_type typeStruct;
1272 typeTuple = SearchSysCache(TYPEOID,
1273 ObjectIdGetDatum(typid),
1275 if (!HeapTupleIsValid(typeTuple))
1276 elog(ERROR, "cache lookup failed for type %u", typid);
1277 typeStruct = (Form_pg_type) GETSTRUCT(typeTuple);
1279 *typlen = typeStruct->typlen;
1280 *typbyval = typeStruct->typbyval;
1281 *typalign = typeStruct->typalign;
1282 *typdelim = typeStruct->typdelim;
1283 *typioparam = getTypeIOParam(typeTuple);
1287 *func = typeStruct->typinput;
1290 *func = typeStruct->typoutput;
1292 case IOFunc_receive:
1293 *func = typeStruct->typreceive;
1296 *func = typeStruct->typsend;
1299 ReleaseSysCache(typeTuple);
1304 get_typalign(Oid typid)
1308 tp = SearchSysCache(TYPEOID,
1309 ObjectIdGetDatum(typid),
1311 if (HeapTupleIsValid(tp))
1313 Form_pg_type typtup = (Form_pg_type) GETSTRUCT(tp);
1316 result = typtup->typalign;
1317 ReleaseSysCache(tp);
1326 get_typstorage(Oid typid)
1330 tp = SearchSysCache(TYPEOID,
1331 ObjectIdGetDatum(typid),
1333 if (HeapTupleIsValid(tp))
1335 Form_pg_type typtup = (Form_pg_type) GETSTRUCT(tp);
1338 result = typtup->typstorage;
1339 ReleaseSysCache(tp);
1349 * Given the type OID, return the typtypmod field (domain's typmod
1353 get_typtypmod(Oid typid)
1357 tp = SearchSysCache(TYPEOID,
1358 ObjectIdGetDatum(typid),
1360 if (HeapTupleIsValid(tp))
1362 Form_pg_type typtup = (Form_pg_type) GETSTRUCT(tp);
1365 result = typtup->typtypmod;
1366 ReleaseSysCache(tp);
1375 * Given a type OID, return the type's default value, if any.
1377 * The result is a palloc'd expression node tree, or NULL if there
1378 * is no defined default for the datatype.
1380 * NB: caller should be prepared to coerce result to correct datatype;
1381 * the returned expression tree might produce something of the wrong type.
1384 get_typdefault(Oid typid)
1386 HeapTuple typeTuple;
1392 typeTuple = SearchSysCache(TYPEOID,
1393 ObjectIdGetDatum(typid),
1395 if (!HeapTupleIsValid(typeTuple))
1396 elog(ERROR, "cache lookup failed for type %u", typid);
1397 type = (Form_pg_type) GETSTRUCT(typeTuple);
1400 * typdefault and typdefaultbin are potentially null, so don't try to
1401 * access 'em as struct fields. Must do it the hard way with
1404 datum = SysCacheGetAttr(TYPEOID,
1406 Anum_pg_type_typdefaultbin,
1411 /* We have an expression default */
1412 expr = stringToNode(DatumGetCString(DirectFunctionCall1(textout,
1417 /* Perhaps we have a plain literal default */
1418 datum = SysCacheGetAttr(TYPEOID,
1420 Anum_pg_type_typdefault,
1425 char *strDefaultVal;
1427 /* Convert text datum to C string */
1428 strDefaultVal = DatumGetCString(DirectFunctionCall1(textout,
1430 /* Convert C string to a value of the given type */
1431 datum = OidFunctionCall3(type->typinput,
1432 CStringGetDatum(strDefaultVal),
1433 ObjectIdGetDatum(getTypeIOParam(typeTuple)),
1435 /* Build a Const node containing the value */
1436 expr = (Node *) makeConst(typid,
1441 pfree(strDefaultVal);
1450 ReleaseSysCache(typeTuple);
1457 * If the given type is a domain, return its base type;
1458 * otherwise return the type's own OID.
1461 getBaseType(Oid typid)
1464 * We loop to find the bottom base type in a stack of domains.
1469 Form_pg_type typTup;
1471 tup = SearchSysCache(TYPEOID,
1472 ObjectIdGetDatum(typid),
1474 if (!HeapTupleIsValid(tup))
1475 elog(ERROR, "cache lookup failed for type %u", typid);
1476 typTup = (Form_pg_type) GETSTRUCT(tup);
1477 if (typTup->typtype != 'd')
1479 /* Not a domain, so done */
1480 ReleaseSysCache(tup);
1484 typid = typTup->typbasetype;
1485 ReleaseSysCache(tup);
1494 * Given a type OID and a typmod value (pass -1 if typmod is unknown),
1495 * estimate the average width of values of the type. This is used by
1496 * the planner, which doesn't require absolutely correct results;
1497 * it's OK (and expected) to guess if we don't know for sure.
1500 get_typavgwidth(Oid typid, int32 typmod)
1502 int typlen = get_typlen(typid);
1506 * Easy if it's a fixed-width type
1512 * type_maximum_size knows the encoding of typmod for some datatypes;
1513 * don't duplicate that knowledge here.
1515 maxwidth = type_maximum_size(typid, typmod);
1519 * For BPCHAR, the max width is also the only width. Otherwise we
1520 * need to guess about the typical data width given the max. A
1521 * sliding scale for percentage of max width seems reasonable.
1523 if (typid == BPCHAROID)
1526 return maxwidth; /* assume full width */
1527 if (maxwidth < 1000)
1528 return 32 + (maxwidth - 32) / 2; /* assume 50% */
1531 * Beyond 1000, assume we're looking at something like
1532 * "varchar(10000)" where the limit isn't actually reached often,
1533 * and use a fixed estimate.
1535 return 32 + (1000 - 32) / 2;
1539 * Ooops, we have no idea ... wild guess time.
1547 * Given the type OID, find if it is a basic type, a complex type, etc.
1548 * It returns the null char if the cache lookup fails...
1551 get_typtype(Oid typid)
1555 tp = SearchSysCache(TYPEOID,
1556 ObjectIdGetDatum(typid),
1558 if (HeapTupleIsValid(tp))
1560 Form_pg_type typtup = (Form_pg_type) GETSTRUCT(tp);
1563 result = typtup->typtype;
1564 ReleaseSysCache(tp);
1574 * Given the type OID, get the typrelid (InvalidOid if not a complex
1578 get_typ_typrelid(Oid typid)
1582 tp = SearchSysCache(TYPEOID,
1583 ObjectIdGetDatum(typid),
1585 if (HeapTupleIsValid(tp))
1587 Form_pg_type typtup = (Form_pg_type) GETSTRUCT(tp);
1590 result = typtup->typrelid;
1591 ReleaseSysCache(tp);
1601 * Given the type OID, get the typelem (InvalidOid if not an array type).
1603 * NB: this only considers varlena arrays to be true arrays; InvalidOid is
1604 * returned if the input is a fixed-length array type.
1607 get_element_type(Oid typid)
1611 tp = SearchSysCache(TYPEOID,
1612 ObjectIdGetDatum(typid),
1614 if (HeapTupleIsValid(tp))
1616 Form_pg_type typtup = (Form_pg_type) GETSTRUCT(tp);
1619 if (typtup->typlen == -1)
1620 result = typtup->typelem;
1622 result = InvalidOid;
1623 ReleaseSysCache(tp);
1633 * Given the type OID, get the corresponding array type.
1634 * Returns InvalidOid if no array type can be found.
1636 * NB: this only considers varlena arrays to be true arrays.
1639 get_array_type(Oid typid)
1643 tp = SearchSysCache(TYPEOID,
1644 ObjectIdGetDatum(typid),
1646 if (HeapTupleIsValid(tp))
1648 Form_pg_type typtup = (Form_pg_type) GETSTRUCT(tp);
1649 char *array_typename;
1652 array_typename = makeArrayTypeName(NameStr(typtup->typname));
1653 namespaceId = typtup->typnamespace;
1654 ReleaseSysCache(tp);
1656 tp = SearchSysCache(TYPENAMENSP,
1657 PointerGetDatum(array_typename),
1658 ObjectIdGetDatum(namespaceId),
1661 pfree(array_typename);
1663 if (HeapTupleIsValid(tp))
1667 typtup = (Form_pg_type) GETSTRUCT(tp);
1668 if (typtup->typlen == -1 && typtup->typelem == typid)
1669 result = HeapTupleGetOid(tp);
1671 result = InvalidOid;
1672 ReleaseSysCache(tp);
1682 * Get info needed for converting values of a type to internal form
1685 getTypeInputInfo(Oid type, Oid *typInput, Oid *typIOParam)
1687 HeapTuple typeTuple;
1690 typeTuple = SearchSysCache(TYPEOID,
1691 ObjectIdGetDatum(type),
1693 if (!HeapTupleIsValid(typeTuple))
1694 elog(ERROR, "cache lookup failed for type %u", type);
1695 pt = (Form_pg_type) GETSTRUCT(typeTuple);
1697 if (!pt->typisdefined)
1699 (errcode(ERRCODE_UNDEFINED_OBJECT),
1700 errmsg("type %s is only a shell",
1701 format_type_be(type))));
1702 if (!OidIsValid(pt->typinput))
1704 (errcode(ERRCODE_UNDEFINED_FUNCTION),
1705 errmsg("no input function available for type %s",
1706 format_type_be(type))));
1708 *typInput = pt->typinput;
1709 *typIOParam = getTypeIOParam(typeTuple);
1711 ReleaseSysCache(typeTuple);
1717 * Get info needed for printing values of a type
1720 getTypeOutputInfo(Oid type, Oid *typOutput, Oid *typIOParam,
1723 HeapTuple typeTuple;
1726 typeTuple = SearchSysCache(TYPEOID,
1727 ObjectIdGetDatum(type),
1729 if (!HeapTupleIsValid(typeTuple))
1730 elog(ERROR, "cache lookup failed for type %u", type);
1731 pt = (Form_pg_type) GETSTRUCT(typeTuple);
1733 if (!pt->typisdefined)
1735 (errcode(ERRCODE_UNDEFINED_OBJECT),
1736 errmsg("type %s is only a shell",
1737 format_type_be(type))));
1738 if (!OidIsValid(pt->typoutput))
1740 (errcode(ERRCODE_UNDEFINED_FUNCTION),
1741 errmsg("no output function available for type %s",
1742 format_type_be(type))));
1744 *typOutput = pt->typoutput;
1745 *typIOParam = getTypeIOParam(typeTuple);
1746 *typIsVarlena = (!pt->typbyval) && (pt->typlen == -1);
1748 ReleaseSysCache(typeTuple);
1752 * getTypeBinaryInputInfo
1754 * Get info needed for binary input of values of a type
1757 getTypeBinaryInputInfo(Oid type, Oid *typReceive, Oid *typIOParam)
1759 HeapTuple typeTuple;
1762 typeTuple = SearchSysCache(TYPEOID,
1763 ObjectIdGetDatum(type),
1765 if (!HeapTupleIsValid(typeTuple))
1766 elog(ERROR, "cache lookup failed for type %u", type);
1767 pt = (Form_pg_type) GETSTRUCT(typeTuple);
1769 if (!pt->typisdefined)
1771 (errcode(ERRCODE_UNDEFINED_OBJECT),
1772 errmsg("type %s is only a shell",
1773 format_type_be(type))));
1774 if (!OidIsValid(pt->typreceive))
1776 (errcode(ERRCODE_UNDEFINED_FUNCTION),
1777 errmsg("no binary input function available for type %s",
1778 format_type_be(type))));
1780 *typReceive = pt->typreceive;
1781 *typIOParam = getTypeIOParam(typeTuple);
1783 ReleaseSysCache(typeTuple);
1787 * getTypeBinaryOutputInfo
1789 * Get info needed for binary output of values of a type
1792 getTypeBinaryOutputInfo(Oid type, Oid *typSend, Oid *typIOParam,
1795 HeapTuple typeTuple;
1798 typeTuple = SearchSysCache(TYPEOID,
1799 ObjectIdGetDatum(type),
1801 if (!HeapTupleIsValid(typeTuple))
1802 elog(ERROR, "cache lookup failed for type %u", type);
1803 pt = (Form_pg_type) GETSTRUCT(typeTuple);
1805 if (!pt->typisdefined)
1807 (errcode(ERRCODE_UNDEFINED_OBJECT),
1808 errmsg("type %s is only a shell",
1809 format_type_be(type))));
1810 if (!OidIsValid(pt->typsend))
1812 (errcode(ERRCODE_UNDEFINED_FUNCTION),
1813 errmsg("no binary output function available for type %s",
1814 format_type_be(type))));
1816 *typSend = pt->typsend;
1817 *typIOParam = getTypeIOParam(typeTuple);
1818 *typIsVarlena = (!pt->typbyval) && (pt->typlen == -1);
1820 ReleaseSysCache(typeTuple);
1824 /* ---------- STATISTICS CACHE ---------- */
1829 * Given the table and attribute number of a column, get the average
1830 * width of entries in the column. Return zero if no data available.
1833 get_attavgwidth(Oid relid, AttrNumber attnum)
1837 tp = SearchSysCache(STATRELATT,
1838 ObjectIdGetDatum(relid),
1839 Int16GetDatum(attnum),
1841 if (HeapTupleIsValid(tp))
1843 int32 stawidth = ((Form_pg_statistic) GETSTRUCT(tp))->stawidth;
1845 ReleaseSysCache(tp);
1855 * Extract the contents of a "slot" of a pg_statistic tuple.
1856 * Returns TRUE if requested slot type was found, else FALSE.
1858 * Unlike other routines in this file, this takes a pointer to an
1859 * already-looked-up tuple in the pg_statistic cache. We do this since
1860 * most callers will want to extract more than one value from the cache
1861 * entry, and we don't want to repeat the cache lookup unnecessarily.
1863 * statstuple: pg_statistics tuple to be examined.
1864 * atttype: type OID of attribute.
1865 * atttypmod: typmod of attribute.
1866 * reqkind: STAKIND code for desired statistics slot kind.
1867 * reqop: STAOP value wanted, or InvalidOid if don't care.
1868 * values, nvalues: if not NULL, the slot's stavalues are extracted.
1869 * numbers, nnumbers: if not NULL, the slot's stanumbers are extracted.
1871 * If assigned, values and numbers are set to point to palloc'd arrays.
1872 * If the attribute type is pass-by-reference, the values referenced by
1873 * the values array are themselves palloc'd. The palloc'd stuff can be
1874 * freed by calling free_attstatsslot.
1877 get_attstatsslot(HeapTuple statstuple,
1878 Oid atttype, int32 atttypmod,
1879 int reqkind, Oid reqop,
1880 Datum **values, int *nvalues,
1881 float4 **numbers, int *nnumbers)
1883 Form_pg_statistic stats = (Form_pg_statistic) GETSTRUCT(statstuple);
1888 ArrayType *statarray;
1890 HeapTuple typeTuple;
1891 Form_pg_type typeForm;
1893 for (i = 0; i < STATISTIC_NUM_SLOTS; i++)
1895 if ((&stats->stakind1)[i] == reqkind &&
1896 (reqop == InvalidOid || (&stats->staop1)[i] == reqop))
1899 if (i >= STATISTIC_NUM_SLOTS)
1900 return false; /* not there */
1904 val = SysCacheGetAttr(STATRELATT, statstuple,
1905 Anum_pg_statistic_stavalues1 + i,
1908 elog(ERROR, "stavalues is null");
1909 statarray = DatumGetArrayTypeP(val);
1911 /* Need to get info about the array element type */
1912 typeTuple = SearchSysCache(TYPEOID,
1913 ObjectIdGetDatum(atttype),
1915 if (!HeapTupleIsValid(typeTuple))
1916 elog(ERROR, "cache lookup failed for type %u", atttype);
1917 typeForm = (Form_pg_type) GETSTRUCT(typeTuple);
1919 /* Deconstruct array into Datum elements */
1920 deconstruct_array(statarray,
1928 * If the element type is pass-by-reference, we now have a bunch
1929 * of Datums that are pointers into the syscache value. Copy them
1930 * to avoid problems if syscache decides to drop the entry.
1932 if (!typeForm->typbyval)
1934 for (j = 0; j < *nvalues; j++)
1936 (*values)[j] = datumCopy((*values)[j],
1942 ReleaseSysCache(typeTuple);
1945 * Free statarray if it's a detoasted copy.
1947 if ((Pointer) statarray != DatumGetPointer(val))
1953 val = SysCacheGetAttr(STATRELATT, statstuple,
1954 Anum_pg_statistic_stanumbers1 + i,
1957 elog(ERROR, "stanumbers is null");
1958 statarray = DatumGetArrayTypeP(val);
1961 * We expect the array to be a 1-D float4 array; verify that. We
1962 * don't need to use deconstruct_array() since the array data is
1963 * just going to look like a C array of float4 values.
1965 narrayelem = ARR_DIMS(statarray)[0];
1966 if (ARR_NDIM(statarray) != 1 || narrayelem <= 0 ||
1967 ARR_ELEMTYPE(statarray) != FLOAT4OID)
1968 elog(ERROR, "stanumbers is not a 1-D float4 array");
1969 *numbers = (float4 *) palloc(narrayelem * sizeof(float4));
1970 memcpy(*numbers, ARR_DATA_PTR(statarray), narrayelem * sizeof(float4));
1971 *nnumbers = narrayelem;
1974 * Free statarray if it's a detoasted copy.
1976 if ((Pointer) statarray != DatumGetPointer(val))
1984 free_attstatsslot(Oid atttype,
1985 Datum *values, int nvalues,
1986 float4 *numbers, int nnumbers)
1990 if (!get_typbyval(atttype))
1994 for (i = 0; i < nvalues; i++)
1995 pfree(DatumGetPointer(values[i]));
2003 /* ---------- PG_NAMESPACE CACHE ---------- */
2006 * get_namespace_name
2007 * Returns the name of a given namespace
2009 * Returns a palloc'd copy of the string, or NULL if no such namespace.
2012 get_namespace_name(Oid nspid)
2016 tp = SearchSysCache(NAMESPACEOID,
2017 ObjectIdGetDatum(nspid),
2019 if (HeapTupleIsValid(tp))
2021 Form_pg_namespace nsptup = (Form_pg_namespace) GETSTRUCT(tp);
2024 result = pstrdup(NameStr(nsptup->nspname));
2025 ReleaseSysCache(tp);
2032 /* ---------- PG_SHADOW CACHE ---------- */
2037 * Given a user name, look up the user's sysid.
2038 * Raises an error if no such user (rather than returning zero,
2039 * which might possibly be a valid usesysid).
2041 * Note: the type of usesysid is currently int4, but may change to Oid
2042 * someday. It'd be reasonable to return zero on failure if we were
2046 get_usesysid(const char *username)
2051 userTup = SearchSysCache(SHADOWNAME,
2052 PointerGetDatum(username),
2054 if (!HeapTupleIsValid(userTup))
2056 (errcode(ERRCODE_UNDEFINED_OBJECT),
2057 errmsg("user \"%s\" does not exist", username)));
2059 userId = ((Form_pg_shadow) GETSTRUCT(userTup))->usesysid;
2061 ReleaseSysCache(userTup);
2069 * Given a group name, look up the group's sysid.
2070 * Raises an error if no such group (rather than returning zero,
2071 * which might possibly be a valid grosysid).
2075 get_grosysid(char *groname)
2080 groupTup = SearchSysCache(GRONAME,
2081 PointerGetDatum(groname),
2083 if (!HeapTupleIsValid(groupTup))
2085 (errcode(ERRCODE_UNDEFINED_OBJECT),
2086 errmsg("group \"%s\" does not exist", groname)));
2088 groupId = ((Form_pg_group) GETSTRUCT(groupTup))->grosysid;
2090 ReleaseSysCache(groupTup);