1 /*-------------------------------------------------------------------------
4 * Convenience routines for common queries in the system catalog cache.
6 * Portions Copyright (c) 1996-2011, PostgreSQL Global Development Group
7 * Portions Copyright (c) 1994, Regents of the University of California
10 * src/backend/utils/cache/lsyscache.c
13 * Eventually, the index information should go through here, too.
14 *-------------------------------------------------------------------------
18 #include "access/hash.h"
19 #include "access/nbtree.h"
20 #include "bootstrap/bootstrap.h"
21 #include "catalog/pg_amop.h"
22 #include "catalog/pg_amproc.h"
23 #include "catalog/pg_collation.h"
24 #include "catalog/pg_constraint.h"
25 #include "catalog/pg_namespace.h"
26 #include "catalog/pg_opclass.h"
27 #include "catalog/pg_operator.h"
28 #include "catalog/pg_proc.h"
29 #include "catalog/pg_statistic.h"
30 #include "catalog/pg_type.h"
31 #include "miscadmin.h"
32 #include "nodes/makefuncs.h"
33 #include "utils/array.h"
34 #include "utils/builtins.h"
35 #include "utils/datum.h"
36 #include "utils/fmgroids.h"
37 #include "utils/lsyscache.h"
38 #include "utils/syscache.h"
39 #include "utils/typcache.h"
41 /* Hook for plugins to get control in get_attavgwidth() */
42 get_attavgwidth_hook_type get_attavgwidth_hook = NULL;
45 /* ---------- AMOP CACHES ---------- */
50 * Return t iff operator 'opno' is in operator family 'opfamily'.
52 * This function only considers search operators, not ordering operators.
55 op_in_opfamily(Oid opno, Oid opfamily)
57 return SearchSysCacheExists3(AMOPOPID,
58 ObjectIdGetDatum(opno),
59 CharGetDatum(AMOP_SEARCH),
60 ObjectIdGetDatum(opfamily));
64 * get_op_opfamily_strategy
66 * Get the operator's strategy number within the specified opfamily,
67 * or 0 if it's not a member of the opfamily.
69 * This function only considers search operators, not ordering operators.
72 get_op_opfamily_strategy(Oid opno, Oid opfamily)
75 Form_pg_amop amop_tup;
78 tp = SearchSysCache3(AMOPOPID,
79 ObjectIdGetDatum(opno),
80 CharGetDatum(AMOP_SEARCH),
81 ObjectIdGetDatum(opfamily));
82 if (!HeapTupleIsValid(tp))
84 amop_tup = (Form_pg_amop) GETSTRUCT(tp);
85 result = amop_tup->amopstrategy;
91 * get_op_opfamily_sortfamily
93 * If the operator is an ordering operator within the specified opfamily,
94 * return its amopsortfamily OID; else return InvalidOid.
97 get_op_opfamily_sortfamily(Oid opno, Oid opfamily)
100 Form_pg_amop amop_tup;
103 tp = SearchSysCache3(AMOPOPID,
104 ObjectIdGetDatum(opno),
105 CharGetDatum(AMOP_ORDER),
106 ObjectIdGetDatum(opfamily));
107 if (!HeapTupleIsValid(tp))
109 amop_tup = (Form_pg_amop) GETSTRUCT(tp);
110 result = amop_tup->amopsortfamily;
116 * get_op_opfamily_properties
118 * Get the operator's strategy number and declared input data types
119 * within the specified opfamily.
121 * Caller should already have verified that opno is a member of opfamily,
122 * therefore we raise an error if the tuple is not found.
125 get_op_opfamily_properties(Oid opno, Oid opfamily, bool ordering_op,
131 Form_pg_amop amop_tup;
133 tp = SearchSysCache3(AMOPOPID,
134 ObjectIdGetDatum(opno),
135 CharGetDatum(ordering_op ? AMOP_ORDER : AMOP_SEARCH),
136 ObjectIdGetDatum(opfamily));
137 if (!HeapTupleIsValid(tp))
138 elog(ERROR, "operator %u is not a member of opfamily %u",
140 amop_tup = (Form_pg_amop) GETSTRUCT(tp);
141 *strategy = amop_tup->amopstrategy;
142 *lefttype = amop_tup->amoplefttype;
143 *righttype = amop_tup->amoprighttype;
148 * get_opfamily_member
149 * Get the OID of the operator that implements the specified strategy
150 * with the specified datatypes for the specified opfamily.
152 * Returns InvalidOid if there is no pg_amop entry for the given keys.
155 get_opfamily_member(Oid opfamily, Oid lefttype, Oid righttype,
159 Form_pg_amop amop_tup;
162 tp = SearchSysCache4(AMOPSTRATEGY,
163 ObjectIdGetDatum(opfamily),
164 ObjectIdGetDatum(lefttype),
165 ObjectIdGetDatum(righttype),
166 Int16GetDatum(strategy));
167 if (!HeapTupleIsValid(tp))
169 amop_tup = (Form_pg_amop) GETSTRUCT(tp);
170 result = amop_tup->amopopr;
176 * get_ordering_op_properties
177 * Given the OID of an ordering operator (a btree "<" or ">" operator),
178 * determine its opfamily, its declared input datatype, and its
179 * strategy number (BTLessStrategyNumber or BTGreaterStrategyNumber).
181 * Returns TRUE if successful, FALSE if no matching pg_amop entry exists.
182 * (This indicates that the operator is not a valid ordering operator.)
184 * Note: the operator could be registered in multiple families, for example
185 * if someone were to build a "reverse sort" opfamily. This would result in
186 * uncertainty as to whether "ORDER BY USING op" would default to NULLS FIRST
187 * or NULLS LAST, as well as inefficient planning due to failure to match up
188 * pathkeys that should be the same. So we want a determinate result here.
189 * Because of the way the syscache search works, we'll use the interpretation
190 * associated with the opfamily with smallest OID, which is probably
191 * determinate enough. Since there is no longer any particularly good reason
192 * to build reverse-sort opfamilies, it doesn't seem worth expending any
193 * additional effort on ensuring consistency.
196 get_ordering_op_properties(Oid opno,
197 Oid *opfamily, Oid *opcintype, int16 *strategy)
203 /* ensure outputs are initialized on failure */
204 *opfamily = InvalidOid;
205 *opcintype = InvalidOid;
209 * Search pg_amop to see if the target operator is registered as the "<"
210 * or ">" operator of any btree opfamily.
212 catlist = SearchSysCacheList1(AMOPOPID, ObjectIdGetDatum(opno));
214 for (i = 0; i < catlist->n_members; i++)
216 HeapTuple tuple = &catlist->members[i]->tuple;
217 Form_pg_amop aform = (Form_pg_amop) GETSTRUCT(tuple);
220 if (aform->amopmethod != BTREE_AM_OID)
223 if (aform->amopstrategy == BTLessStrategyNumber ||
224 aform->amopstrategy == BTGreaterStrategyNumber)
226 /* Found it ... should have consistent input types */
227 if (aform->amoplefttype == aform->amoprighttype)
229 /* Found a suitable opfamily, return info */
230 *opfamily = aform->amopfamily;
231 *opcintype = aform->amoplefttype;
232 *strategy = aform->amopstrategy;
239 ReleaseSysCacheList(catlist);
245 * get_compare_function_for_ordering_op
246 * Get the OID of the datatype-specific btree comparison function
247 * associated with an ordering operator (a "<" or ">" operator).
249 * *cmpfunc receives the comparison function OID.
250 * *reverse is set FALSE if the operator is "<", TRUE if it's ">"
251 * (indicating the comparison result must be negated before use).
253 * Returns TRUE if successful, FALSE if no btree function can be found.
254 * (This indicates that the operator is not a valid ordering operator.)
257 get_compare_function_for_ordering_op(Oid opno, Oid *cmpfunc, bool *reverse)
263 /* Find the operator in pg_amop */
264 if (get_ordering_op_properties(opno,
265 &opfamily, &opcintype, &strategy))
267 /* Found a suitable opfamily, get matching support function */
268 *cmpfunc = get_opfamily_proc(opfamily,
273 if (!OidIsValid(*cmpfunc)) /* should not happen */
274 elog(ERROR, "missing support function %d(%u,%u) in opfamily %u",
275 BTORDER_PROC, opcintype, opcintype, opfamily);
276 *reverse = (strategy == BTGreaterStrategyNumber);
280 /* ensure outputs are set on failure */
281 *cmpfunc = InvalidOid;
288 * get_equality_op_for_ordering_op
289 * Get the OID of the datatype-specific btree equality operator
290 * associated with an ordering operator (a "<" or ">" operator).
292 * If "reverse" isn't NULL, also set *reverse to FALSE if the operator is "<",
295 * Returns InvalidOid if no matching equality operator can be found.
296 * (This indicates that the operator is not a valid ordering operator.)
299 get_equality_op_for_ordering_op(Oid opno, bool *reverse)
301 Oid result = InvalidOid;
306 /* Find the operator in pg_amop */
307 if (get_ordering_op_properties(opno,
308 &opfamily, &opcintype, &strategy))
310 /* Found a suitable opfamily, get matching equality operator */
311 result = get_opfamily_member(opfamily,
314 BTEqualStrategyNumber);
316 *reverse = (strategy == BTGreaterStrategyNumber);
323 * get_ordering_op_for_equality_op
324 * Get the OID of a datatype-specific btree ordering operator
325 * associated with an equality operator. (If there are multiple
326 * possibilities, assume any one will do.)
328 * This function is used when we have to sort data before unique-ifying,
329 * and don't much care which sorting op is used as long as it's compatible
330 * with the intended equality operator. Since we need a sorting operator,
331 * it should be single-data-type even if the given operator is cross-type.
332 * The caller specifies whether to find an op for the LHS or RHS data type.
334 * Returns InvalidOid if no matching ordering operator can be found.
337 get_ordering_op_for_equality_op(Oid opno, bool use_lhs_type)
339 Oid result = InvalidOid;
344 * Search pg_amop to see if the target operator is registered as the "="
345 * operator of any btree opfamily.
347 catlist = SearchSysCacheList1(AMOPOPID, ObjectIdGetDatum(opno));
349 for (i = 0; i < catlist->n_members; i++)
351 HeapTuple tuple = &catlist->members[i]->tuple;
352 Form_pg_amop aform = (Form_pg_amop) GETSTRUCT(tuple);
355 if (aform->amopmethod != BTREE_AM_OID)
358 if (aform->amopstrategy == BTEqualStrategyNumber)
360 /* Found a suitable opfamily, get matching ordering operator */
363 typid = use_lhs_type ? aform->amoplefttype : aform->amoprighttype;
364 result = get_opfamily_member(aform->amopfamily,
366 BTLessStrategyNumber);
367 if (OidIsValid(result))
369 /* failure probably shouldn't happen, but keep looking if so */
373 ReleaseSysCacheList(catlist);
379 * get_mergejoin_opfamilies
380 * Given a putatively mergejoinable operator, return a list of the OIDs
381 * of the btree opfamilies in which it represents equality.
383 * It is possible (though at present unusual) for an operator to be equality
384 * in more than one opfamily, hence the result is a list. This also lets us
385 * return NIL if the operator is not found in any opfamilies.
387 * The planner currently uses simple equal() tests to compare the lists
388 * returned by this function, which makes the list order relevant, though
389 * strictly speaking it should not be. Because of the way syscache list
390 * searches are handled, in normal operation the result will be sorted by OID
391 * so everything works fine. If running with system index usage disabled,
392 * the result ordering is unspecified and hence the planner might fail to
393 * recognize optimization opportunities ... but that's hardly a scenario in
394 * which performance is good anyway, so there's no point in expending code
395 * or cycles here to guarantee the ordering in that case.
398 get_mergejoin_opfamilies(Oid opno)
405 * Search pg_amop to see if the target operator is registered as the "="
406 * operator of any btree opfamily.
408 catlist = SearchSysCacheList1(AMOPOPID, ObjectIdGetDatum(opno));
410 for (i = 0; i < catlist->n_members; i++)
412 HeapTuple tuple = &catlist->members[i]->tuple;
413 Form_pg_amop aform = (Form_pg_amop) GETSTRUCT(tuple);
415 /* must be btree equality */
416 if (aform->amopmethod == BTREE_AM_OID &&
417 aform->amopstrategy == BTEqualStrategyNumber)
418 result = lappend_oid(result, aform->amopfamily);
421 ReleaseSysCacheList(catlist);
427 * get_compatible_hash_operators
428 * Get the OID(s) of hash equality operator(s) compatible with the given
429 * operator, but operating on its LHS and/or RHS datatype.
431 * An operator for the LHS type is sought and returned into *lhs_opno if
432 * lhs_opno isn't NULL. Similarly, an operator for the RHS type is sought
433 * and returned into *rhs_opno if rhs_opno isn't NULL.
435 * If the given operator is not cross-type, the results should be the same
436 * operator, but in cross-type situations they will be different.
438 * Returns true if able to find the requested operator(s), false if not.
439 * (This indicates that the operator should not have been marked oprcanhash.)
442 get_compatible_hash_operators(Oid opno,
443 Oid *lhs_opno, Oid *rhs_opno)
449 /* Ensure output args are initialized on failure */
451 *lhs_opno = InvalidOid;
453 *rhs_opno = InvalidOid;
456 * Search pg_amop to see if the target operator is registered as the "="
457 * operator of any hash opfamily. If the operator is registered in
458 * multiple opfamilies, assume we can use any one.
460 catlist = SearchSysCacheList1(AMOPOPID, ObjectIdGetDatum(opno));
462 for (i = 0; i < catlist->n_members; i++)
464 HeapTuple tuple = &catlist->members[i]->tuple;
465 Form_pg_amop aform = (Form_pg_amop) GETSTRUCT(tuple);
467 if (aform->amopmethod == HASH_AM_OID &&
468 aform->amopstrategy == HTEqualStrategyNumber)
470 /* No extra lookup needed if given operator is single-type */
471 if (aform->amoplefttype == aform->amoprighttype)
482 * Get the matching single-type operator(s). Failure probably
483 * shouldn't happen --- it implies a bogus opfamily --- but
484 * continue looking if so.
488 *lhs_opno = get_opfamily_member(aform->amopfamily,
491 HTEqualStrategyNumber);
492 if (!OidIsValid(*lhs_opno))
494 /* Matching LHS found, done if caller doesn't want RHS */
503 *rhs_opno = get_opfamily_member(aform->amopfamily,
504 aform->amoprighttype,
505 aform->amoprighttype,
506 HTEqualStrategyNumber);
507 if (!OidIsValid(*rhs_opno))
509 /* Forget any LHS operator from this opfamily */
511 *lhs_opno = InvalidOid;
514 /* Matching RHS found, so done */
521 ReleaseSysCacheList(catlist);
527 * get_op_hash_functions
528 * Get the OID(s) of hash support function(s) compatible with the given
529 * operator, operating on its LHS and/or RHS datatype as required.
531 * A function for the LHS type is sought and returned into *lhs_procno if
532 * lhs_procno isn't NULL. Similarly, a function for the RHS type is sought
533 * and returned into *rhs_procno if rhs_procno isn't NULL.
535 * If the given operator is not cross-type, the results should be the same
536 * function, but in cross-type situations they will be different.
538 * Returns true if able to find the requested function(s), false if not.
539 * (This indicates that the operator should not have been marked oprcanhash.)
542 get_op_hash_functions(Oid opno,
543 RegProcedure *lhs_procno, RegProcedure *rhs_procno)
549 /* Ensure output args are initialized on failure */
551 *lhs_procno = InvalidOid;
553 *rhs_procno = InvalidOid;
556 * Search pg_amop to see if the target operator is registered as the "="
557 * operator of any hash opfamily. If the operator is registered in
558 * multiple opfamilies, assume we can use any one.
560 catlist = SearchSysCacheList1(AMOPOPID, ObjectIdGetDatum(opno));
562 for (i = 0; i < catlist->n_members; i++)
564 HeapTuple tuple = &catlist->members[i]->tuple;
565 Form_pg_amop aform = (Form_pg_amop) GETSTRUCT(tuple);
567 if (aform->amopmethod == HASH_AM_OID &&
568 aform->amopstrategy == HTEqualStrategyNumber)
571 * Get the matching support function(s). Failure probably
572 * shouldn't happen --- it implies a bogus opfamily --- but
573 * continue looking if so.
577 *lhs_procno = get_opfamily_proc(aform->amopfamily,
581 if (!OidIsValid(*lhs_procno))
583 /* Matching LHS found, done if caller doesn't want RHS */
589 /* Only one lookup needed if given operator is single-type */
590 if (aform->amoplefttype == aform->amoprighttype)
592 *rhs_procno = *lhs_procno;
599 *rhs_procno = get_opfamily_proc(aform->amopfamily,
600 aform->amoprighttype,
601 aform->amoprighttype,
603 if (!OidIsValid(*rhs_procno))
605 /* Forget any LHS function from this opfamily */
607 *lhs_procno = InvalidOid;
610 /* Matching RHS found, so done */
617 ReleaseSysCacheList(catlist);
623 * get_op_btree_interpretation
624 * Given an operator's OID, find out which btree opfamilies it belongs to,
625 * and what strategy number it has within each one. The results are
626 * returned as an OID list and a parallel integer list.
628 * In addition to the normal btree operators, we consider a <> operator to be
629 * a "member" of an opfamily if its negator is an equality operator of the
630 * opfamily. ROWCOMPARE_NE is returned as the strategy number for this case.
633 get_op_btree_interpretation(Oid opno, List **opfamilies, List **opstrats)
643 * Find all the pg_amop entries containing the operator.
645 catlist = SearchSysCacheList1(AMOPOPID, ObjectIdGetDatum(opno));
648 * If we can't find any opfamily containing the op, perhaps it is a <>
649 * operator. See if it has a negator that is in an opfamily.
652 if (catlist->n_members == 0)
654 Oid op_negator = get_negator(opno);
656 if (OidIsValid(op_negator))
659 ReleaseSysCacheList(catlist);
660 catlist = SearchSysCacheList1(AMOPOPID,
661 ObjectIdGetDatum(op_negator));
665 /* Now search the opfamilies */
666 for (i = 0; i < catlist->n_members; i++)
668 HeapTuple op_tuple = &catlist->members[i]->tuple;
669 Form_pg_amop op_form = (Form_pg_amop) GETSTRUCT(op_tuple);
671 StrategyNumber op_strategy;
674 if (op_form->amopmethod != BTREE_AM_OID)
677 /* Get the operator's btree strategy number */
678 opfamily_id = op_form->amopfamily;
679 op_strategy = (StrategyNumber) op_form->amopstrategy;
680 Assert(op_strategy >= 1 && op_strategy <= 5);
684 /* Only consider negators that are = */
685 if (op_strategy != BTEqualStrategyNumber)
687 op_strategy = ROWCOMPARE_NE;
690 *opfamilies = lappend_oid(*opfamilies, opfamily_id);
691 *opstrats = lappend_int(*opstrats, op_strategy);
694 ReleaseSysCacheList(catlist);
698 * equality_ops_are_compatible
699 * Return TRUE if the two given equality operators have compatible
702 * This is trivially true if they are the same operator. Otherwise,
703 * we look to see if they can be found in the same btree or hash opfamily.
704 * Either finding allows us to assume that they have compatible notions
705 * of equality. (The reason we need to do these pushups is that one might
706 * be a cross-type operator; for instance int24eq vs int4eq.)
709 equality_ops_are_compatible(Oid opno1, Oid opno2)
715 /* Easy if they're the same operator */
720 * We search through all the pg_amop entries for opno1.
722 catlist = SearchSysCacheList1(AMOPOPID, ObjectIdGetDatum(opno1));
725 for (i = 0; i < catlist->n_members; i++)
727 HeapTuple op_tuple = &catlist->members[i]->tuple;
728 Form_pg_amop op_form = (Form_pg_amop) GETSTRUCT(op_tuple);
730 /* must be btree or hash */
731 if (op_form->amopmethod == BTREE_AM_OID ||
732 op_form->amopmethod == HASH_AM_OID)
734 if (op_in_opfamily(opno2, op_form->amopfamily))
742 ReleaseSysCacheList(catlist);
748 /* ---------- AMPROC CACHES ---------- */
752 * Get the OID of the specified support function
753 * for the specified opfamily and datatypes.
755 * Returns InvalidOid if there is no pg_amproc entry for the given keys.
758 get_opfamily_proc(Oid opfamily, Oid lefttype, Oid righttype, int16 procnum)
761 Form_pg_amproc amproc_tup;
764 tp = SearchSysCache4(AMPROCNUM,
765 ObjectIdGetDatum(opfamily),
766 ObjectIdGetDatum(lefttype),
767 ObjectIdGetDatum(righttype),
768 Int16GetDatum(procnum));
769 if (!HeapTupleIsValid(tp))
771 amproc_tup = (Form_pg_amproc) GETSTRUCT(tp);
772 result = amproc_tup->amproc;
778 /* ---------- ATTRIBUTE CACHES ---------- */
782 * Given the relation id and the attribute number,
783 * return the "attname" field from the attribute relation.
785 * Note: returns a palloc'd copy of the string, or NULL if no such attribute.
788 get_attname(Oid relid, AttrNumber attnum)
792 tp = SearchSysCache2(ATTNUM,
793 ObjectIdGetDatum(relid),
794 Int16GetDatum(attnum));
795 if (HeapTupleIsValid(tp))
797 Form_pg_attribute att_tup = (Form_pg_attribute) GETSTRUCT(tp);
800 result = pstrdup(NameStr(att_tup->attname));
809 * get_relid_attribute_name
811 * Same as above routine get_attname(), except that error
812 * is handled by elog() instead of returning NULL.
815 get_relid_attribute_name(Oid relid, AttrNumber attnum)
819 attname = get_attname(relid, attnum);
821 elog(ERROR, "cache lookup failed for attribute %d of relation %u",
829 * Given the relation id and the attribute name,
830 * return the "attnum" field from the attribute relation.
832 * Returns InvalidAttrNumber if the attr doesn't exist (or is dropped).
835 get_attnum(Oid relid, const char *attname)
839 tp = SearchSysCacheAttName(relid, attname);
840 if (HeapTupleIsValid(tp))
842 Form_pg_attribute att_tup = (Form_pg_attribute) GETSTRUCT(tp);
845 result = att_tup->attnum;
850 return InvalidAttrNumber;
856 * Given the relation OID and the attribute number with the relation,
857 * return the attribute type OID.
860 get_atttype(Oid relid, AttrNumber attnum)
864 tp = SearchSysCache2(ATTNUM,
865 ObjectIdGetDatum(relid),
866 Int16GetDatum(attnum));
867 if (HeapTupleIsValid(tp))
869 Form_pg_attribute att_tup = (Form_pg_attribute) GETSTRUCT(tp);
872 result = att_tup->atttypid;
883 * Given the relation id and the attribute number,
884 * return the "atttypmod" field from the attribute relation.
887 get_atttypmod(Oid relid, AttrNumber attnum)
891 tp = SearchSysCache2(ATTNUM,
892 ObjectIdGetDatum(relid),
893 Int16GetDatum(attnum));
894 if (HeapTupleIsValid(tp))
896 Form_pg_attribute att_tup = (Form_pg_attribute) GETSTRUCT(tp);
899 result = att_tup->atttypmod;
908 * get_atttypetypmodcoll
910 * A three-fer: given the relation id and the attribute number,
911 * fetch atttypid, atttypmod, and attcollation in a single cache lookup.
913 * Unlike the otherwise-similar get_atttype/get_atttypmod, this routine
914 * raises an error if it can't obtain the information.
917 get_atttypetypmodcoll(Oid relid, AttrNumber attnum,
918 Oid *typid, int32 *typmod, Oid *collid)
921 Form_pg_attribute att_tup;
923 tp = SearchSysCache2(ATTNUM,
924 ObjectIdGetDatum(relid),
925 Int16GetDatum(attnum));
926 if (!HeapTupleIsValid(tp))
927 elog(ERROR, "cache lookup failed for attribute %d of relation %u",
929 att_tup = (Form_pg_attribute) GETSTRUCT(tp);
931 *typid = att_tup->atttypid;
932 *typmod = att_tup->atttypmod;
933 *collid = att_tup->attcollation;
937 /* ---------- COLLATION CACHE ---------- */
941 * Returns the name of a given pg_collation entry.
943 * Returns a palloc'd copy of the string, or NULL if no such constraint.
945 * NOTE: since collation name is not unique, be wary of code that uses this
946 * for anything except preparing error messages.
949 get_collation_name(Oid colloid)
953 tp = SearchSysCache1(COLLOID, ObjectIdGetDatum(colloid));
954 if (HeapTupleIsValid(tp))
956 Form_pg_collation colltup = (Form_pg_collation) GETSTRUCT(tp);
959 result = pstrdup(NameStr(colltup->collname));
967 /* ---------- CONSTRAINT CACHE ---------- */
970 * get_constraint_name
971 * Returns the name of a given pg_constraint entry.
973 * Returns a palloc'd copy of the string, or NULL if no such constraint.
975 * NOTE: since constraint name is not unique, be wary of code that uses this
976 * for anything except preparing error messages.
979 get_constraint_name(Oid conoid)
983 tp = SearchSysCache1(CONSTROID, ObjectIdGetDatum(conoid));
984 if (HeapTupleIsValid(tp))
986 Form_pg_constraint contup = (Form_pg_constraint) GETSTRUCT(tp);
989 result = pstrdup(NameStr(contup->conname));
997 /* ---------- OPCLASS CACHE ---------- */
1000 * get_opclass_family
1002 * Returns the OID of the operator family the opclass belongs to.
1005 get_opclass_family(Oid opclass)
1008 Form_pg_opclass cla_tup;
1011 tp = SearchSysCache1(CLAOID, ObjectIdGetDatum(opclass));
1012 if (!HeapTupleIsValid(tp))
1013 elog(ERROR, "cache lookup failed for opclass %u", opclass);
1014 cla_tup = (Form_pg_opclass) GETSTRUCT(tp);
1016 result = cla_tup->opcfamily;
1017 ReleaseSysCache(tp);
1022 * get_opclass_input_type
1024 * Returns the OID of the datatype the opclass indexes.
1027 get_opclass_input_type(Oid opclass)
1030 Form_pg_opclass cla_tup;
1033 tp = SearchSysCache1(CLAOID, ObjectIdGetDatum(opclass));
1034 if (!HeapTupleIsValid(tp))
1035 elog(ERROR, "cache lookup failed for opclass %u", opclass);
1036 cla_tup = (Form_pg_opclass) GETSTRUCT(tp);
1038 result = cla_tup->opcintype;
1039 ReleaseSysCache(tp);
1043 /* ---------- OPERATOR CACHE ---------- */
1048 * Returns the regproc id of the routine used to implement an
1049 * operator given the operator oid.
1052 get_opcode(Oid opno)
1056 tp = SearchSysCache1(OPEROID, ObjectIdGetDatum(opno));
1057 if (HeapTupleIsValid(tp))
1059 Form_pg_operator optup = (Form_pg_operator) GETSTRUCT(tp);
1060 RegProcedure result;
1062 result = optup->oprcode;
1063 ReleaseSysCache(tp);
1067 return (RegProcedure) InvalidOid;
1072 * returns the name of the operator with the given opno
1074 * Note: returns a palloc'd copy of the string, or NULL if no such operator.
1077 get_opname(Oid opno)
1081 tp = SearchSysCache1(OPEROID, ObjectIdGetDatum(opno));
1082 if (HeapTupleIsValid(tp))
1084 Form_pg_operator optup = (Form_pg_operator) GETSTRUCT(tp);
1087 result = pstrdup(NameStr(optup->oprname));
1088 ReleaseSysCache(tp);
1098 * Returns the left and right input datatypes for an operator
1099 * (InvalidOid if not relevant).
1102 op_input_types(Oid opno, Oid *lefttype, Oid *righttype)
1105 Form_pg_operator optup;
1107 tp = SearchSysCache1(OPEROID, ObjectIdGetDatum(opno));
1108 if (!HeapTupleIsValid(tp)) /* shouldn't happen */
1109 elog(ERROR, "cache lookup failed for operator %u", opno);
1110 optup = (Form_pg_operator) GETSTRUCT(tp);
1111 *lefttype = optup->oprleft;
1112 *righttype = optup->oprright;
1113 ReleaseSysCache(tp);
1119 * Returns true if the operator is potentially mergejoinable. (The planner
1120 * will fail to find any mergejoin plans unless there are suitable btree
1121 * opfamily entries for this operator and associated sortops. The pg_operator
1122 * flag is just a hint to tell the planner whether to bother looking.)
1124 * In some cases (currently only array_eq and record_eq), mergejoinability
1125 * depends on the specific input data type the operator is invoked for, so
1126 * that must be passed as well. We currently assume that only one input's type
1127 * is needed to check this --- by convention, pass the left input's data type.
1130 op_mergejoinable(Oid opno, Oid inputtype)
1132 bool result = false;
1134 TypeCacheEntry *typentry;
1137 * For array_eq or record_eq, we can sort if the element or field types
1138 * are all sortable. We could implement all the checks for that here, but
1139 * the typcache already does that and caches the results too, so let's
1140 * rely on the typcache.
1142 if (opno == ARRAY_EQ_OP)
1144 typentry = lookup_type_cache(inputtype, TYPECACHE_CMP_PROC);
1145 if (typentry->cmp_proc == F_BTARRAYCMP)
1148 else if (opno == RECORD_EQ_OP)
1150 typentry = lookup_type_cache(inputtype, TYPECACHE_CMP_PROC);
1151 if (typentry->cmp_proc == F_BTRECORDCMP)
1156 /* For all other operators, rely on pg_operator.oprcanmerge */
1157 tp = SearchSysCache1(OPEROID, ObjectIdGetDatum(opno));
1158 if (HeapTupleIsValid(tp))
1160 Form_pg_operator optup = (Form_pg_operator) GETSTRUCT(tp);
1162 result = optup->oprcanmerge;
1163 ReleaseSysCache(tp);
1172 * Returns true if the operator is hashjoinable. (There must be a suitable
1173 * hash opfamily entry for this operator if it is so marked.)
1175 * In some cases (currently only array_eq), hashjoinability depends on the
1176 * specific input data type the operator is invoked for, so that must be
1177 * passed as well. We currently assume that only one input's type is needed
1178 * to check this --- by convention, pass the left input's data type.
1181 op_hashjoinable(Oid opno, Oid inputtype)
1183 bool result = false;
1185 TypeCacheEntry *typentry;
1187 /* As in op_mergejoinable, let the typcache handle the hard cases */
1188 /* Eventually we'll need a similar case for record_eq ... */
1189 if (opno == ARRAY_EQ_OP)
1191 typentry = lookup_type_cache(inputtype, TYPECACHE_HASH_PROC);
1192 if (typentry->hash_proc == F_HASH_ARRAY)
1197 /* For all other operators, rely on pg_operator.oprcanhash */
1198 tp = SearchSysCache1(OPEROID, ObjectIdGetDatum(opno));
1199 if (HeapTupleIsValid(tp))
1201 Form_pg_operator optup = (Form_pg_operator) GETSTRUCT(tp);
1203 result = optup->oprcanhash;
1204 ReleaseSysCache(tp);
1213 * Get the proisstrict flag for the operator's underlying function.
1218 RegProcedure funcid = get_opcode(opno);
1220 if (funcid == (RegProcedure) InvalidOid)
1221 elog(ERROR, "operator %u does not exist", opno);
1223 return func_strict((Oid) funcid);
1229 * Get the provolatile flag for the operator's underlying function.
1232 op_volatile(Oid opno)
1234 RegProcedure funcid = get_opcode(opno);
1236 if (funcid == (RegProcedure) InvalidOid)
1237 elog(ERROR, "operator %u does not exist", opno);
1239 return func_volatile((Oid) funcid);
1245 * Returns the corresponding commutator of an operator.
1248 get_commutator(Oid opno)
1252 tp = SearchSysCache1(OPEROID, ObjectIdGetDatum(opno));
1253 if (HeapTupleIsValid(tp))
1255 Form_pg_operator optup = (Form_pg_operator) GETSTRUCT(tp);
1258 result = optup->oprcom;
1259 ReleaseSysCache(tp);
1269 * Returns the corresponding negator of an operator.
1272 get_negator(Oid opno)
1276 tp = SearchSysCache1(OPEROID, ObjectIdGetDatum(opno));
1277 if (HeapTupleIsValid(tp))
1279 Form_pg_operator optup = (Form_pg_operator) GETSTRUCT(tp);
1282 result = optup->oprnegate;
1283 ReleaseSysCache(tp);
1293 * Returns procedure id for computing selectivity of an operator.
1296 get_oprrest(Oid opno)
1300 tp = SearchSysCache1(OPEROID, ObjectIdGetDatum(opno));
1301 if (HeapTupleIsValid(tp))
1303 Form_pg_operator optup = (Form_pg_operator) GETSTRUCT(tp);
1304 RegProcedure result;
1306 result = optup->oprrest;
1307 ReleaseSysCache(tp);
1311 return (RegProcedure) InvalidOid;
1317 * Returns procedure id for computing selectivity of a join.
1320 get_oprjoin(Oid opno)
1324 tp = SearchSysCache1(OPEROID, ObjectIdGetDatum(opno));
1325 if (HeapTupleIsValid(tp))
1327 Form_pg_operator optup = (Form_pg_operator) GETSTRUCT(tp);
1328 RegProcedure result;
1330 result = optup->oprjoin;
1331 ReleaseSysCache(tp);
1335 return (RegProcedure) InvalidOid;
1338 /* ---------- FUNCTION CACHE ---------- */
1342 * returns the name of the function with the given funcid
1344 * Note: returns a palloc'd copy of the string, or NULL if no such function.
1347 get_func_name(Oid funcid)
1351 tp = SearchSysCache1(PROCOID, ObjectIdGetDatum(funcid));
1352 if (HeapTupleIsValid(tp))
1354 Form_pg_proc functup = (Form_pg_proc) GETSTRUCT(tp);
1357 result = pstrdup(NameStr(functup->proname));
1358 ReleaseSysCache(tp);
1366 * get_func_namespace
1368 * Returns the pg_namespace OID associated with a given function.
1371 get_func_namespace(Oid funcid)
1375 tp = SearchSysCache1(PROCOID, ObjectIdGetDatum(funcid));
1376 if (HeapTupleIsValid(tp))
1378 Form_pg_proc functup = (Form_pg_proc) GETSTRUCT(tp);
1381 result = functup->pronamespace;
1382 ReleaseSysCache(tp);
1391 * Given procedure id, return the function's result type.
1394 get_func_rettype(Oid funcid)
1399 tp = SearchSysCache1(PROCOID, ObjectIdGetDatum(funcid));
1400 if (!HeapTupleIsValid(tp))
1401 elog(ERROR, "cache lookup failed for function %u", funcid);
1403 result = ((Form_pg_proc) GETSTRUCT(tp))->prorettype;
1404 ReleaseSysCache(tp);
1410 * Given procedure id, return the number of arguments.
1413 get_func_nargs(Oid funcid)
1418 tp = SearchSysCache1(PROCOID, ObjectIdGetDatum(funcid));
1419 if (!HeapTupleIsValid(tp))
1420 elog(ERROR, "cache lookup failed for function %u", funcid);
1422 result = ((Form_pg_proc) GETSTRUCT(tp))->pronargs;
1423 ReleaseSysCache(tp);
1428 * get_func_signature
1429 * Given procedure id, return the function's argument and result types.
1430 * (The return value is the result type.)
1432 * The arguments are returned as a palloc'd array.
1435 get_func_signature(Oid funcid, Oid **argtypes, int *nargs)
1438 Form_pg_proc procstruct;
1441 tp = SearchSysCache1(PROCOID, ObjectIdGetDatum(funcid));
1442 if (!HeapTupleIsValid(tp))
1443 elog(ERROR, "cache lookup failed for function %u", funcid);
1445 procstruct = (Form_pg_proc) GETSTRUCT(tp);
1447 result = procstruct->prorettype;
1448 *nargs = (int) procstruct->pronargs;
1449 Assert(*nargs == procstruct->proargtypes.dim1);
1450 *argtypes = (Oid *) palloc(*nargs * sizeof(Oid));
1451 memcpy(*argtypes, procstruct->proargtypes.values, *nargs * sizeof(Oid));
1453 ReleaseSysCache(tp);
1459 * Given procedure id, return the function's proretset flag.
1462 get_func_retset(Oid funcid)
1467 tp = SearchSysCache1(PROCOID, ObjectIdGetDatum(funcid));
1468 if (!HeapTupleIsValid(tp))
1469 elog(ERROR, "cache lookup failed for function %u", funcid);
1471 result = ((Form_pg_proc) GETSTRUCT(tp))->proretset;
1472 ReleaseSysCache(tp);
1478 * Given procedure id, return the function's proisstrict flag.
1481 func_strict(Oid funcid)
1486 tp = SearchSysCache1(PROCOID, ObjectIdGetDatum(funcid));
1487 if (!HeapTupleIsValid(tp))
1488 elog(ERROR, "cache lookup failed for function %u", funcid);
1490 result = ((Form_pg_proc) GETSTRUCT(tp))->proisstrict;
1491 ReleaseSysCache(tp);
1497 * Given procedure id, return the function's provolatile flag.
1500 func_volatile(Oid funcid)
1505 tp = SearchSysCache1(PROCOID, ObjectIdGetDatum(funcid));
1506 if (!HeapTupleIsValid(tp))
1507 elog(ERROR, "cache lookup failed for function %u", funcid);
1509 result = ((Form_pg_proc) GETSTRUCT(tp))->provolatile;
1510 ReleaseSysCache(tp);
1516 * Given procedure id, return the function's procost field.
1519 get_func_cost(Oid funcid)
1524 tp = SearchSysCache1(PROCOID, ObjectIdGetDatum(funcid));
1525 if (!HeapTupleIsValid(tp))
1526 elog(ERROR, "cache lookup failed for function %u", funcid);
1528 result = ((Form_pg_proc) GETSTRUCT(tp))->procost;
1529 ReleaseSysCache(tp);
1535 * Given procedure id, return the function's prorows field.
1538 get_func_rows(Oid funcid)
1543 tp = SearchSysCache1(PROCOID, ObjectIdGetDatum(funcid));
1544 if (!HeapTupleIsValid(tp))
1545 elog(ERROR, "cache lookup failed for function %u", funcid);
1547 result = ((Form_pg_proc) GETSTRUCT(tp))->prorows;
1548 ReleaseSysCache(tp);
1552 /* ---------- RELATION CACHE ---------- */
1556 * Given name and namespace of a relation, look up the OID.
1558 * Returns InvalidOid if there is no such relation.
1561 get_relname_relid(const char *relname, Oid relnamespace)
1563 return GetSysCacheOid2(RELNAMENSP,
1564 PointerGetDatum(relname),
1565 ObjectIdGetDatum(relnamespace));
1572 * Returns the number of attributes for a given relation.
1575 get_relnatts(Oid relid)
1579 tp = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
1580 if (HeapTupleIsValid(tp))
1582 Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
1585 result = reltup->relnatts;
1586 ReleaseSysCache(tp);
1590 return InvalidAttrNumber;
1596 * Returns the name of a given relation.
1598 * Returns a palloc'd copy of the string, or NULL if no such relation.
1600 * NOTE: since relation name is not unique, be wary of code that uses this
1601 * for anything except preparing error messages.
1604 get_rel_name(Oid relid)
1608 tp = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
1609 if (HeapTupleIsValid(tp))
1611 Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
1614 result = pstrdup(NameStr(reltup->relname));
1615 ReleaseSysCache(tp);
1625 * Returns the pg_namespace OID associated with a given relation.
1628 get_rel_namespace(Oid relid)
1632 tp = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
1633 if (HeapTupleIsValid(tp))
1635 Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
1638 result = reltup->relnamespace;
1639 ReleaseSysCache(tp);
1649 * Returns the pg_type OID associated with a given relation.
1651 * Note: not all pg_class entries have associated pg_type OIDs; so be
1652 * careful to check for InvalidOid result.
1655 get_rel_type_id(Oid relid)
1659 tp = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
1660 if (HeapTupleIsValid(tp))
1662 Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
1665 result = reltup->reltype;
1666 ReleaseSysCache(tp);
1676 * Returns the relkind associated with a given relation.
1679 get_rel_relkind(Oid relid)
1683 tp = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
1684 if (HeapTupleIsValid(tp))
1686 Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
1689 result = reltup->relkind;
1690 ReleaseSysCache(tp);
1698 * get_rel_tablespace
1700 * Returns the pg_tablespace OID associated with a given relation.
1702 * Note: InvalidOid might mean either that we couldn't find the relation,
1703 * or that it is in the database's default tablespace.
1706 get_rel_tablespace(Oid relid)
1710 tp = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
1711 if (HeapTupleIsValid(tp))
1713 Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
1716 result = reltup->reltablespace;
1717 ReleaseSysCache(tp);
1725 /* ---------- TYPE CACHE ---------- */
1730 * Given the type OID, determine whether the type is defined
1731 * (if not, it's only a shell).
1734 get_typisdefined(Oid typid)
1738 tp = SearchSysCache1(TYPEOID, ObjectIdGetDatum(typid));
1739 if (HeapTupleIsValid(tp))
1741 Form_pg_type typtup = (Form_pg_type) GETSTRUCT(tp);
1744 result = typtup->typisdefined;
1745 ReleaseSysCache(tp);
1755 * Given the type OID, return the length of the type.
1758 get_typlen(Oid typid)
1762 tp = SearchSysCache1(TYPEOID, ObjectIdGetDatum(typid));
1763 if (HeapTupleIsValid(tp))
1765 Form_pg_type typtup = (Form_pg_type) GETSTRUCT(tp);
1768 result = typtup->typlen;
1769 ReleaseSysCache(tp);
1779 * Given the type OID, determine whether the type is returned by value or
1780 * not. Returns true if by value, false if by reference.
1783 get_typbyval(Oid typid)
1787 tp = SearchSysCache1(TYPEOID, ObjectIdGetDatum(typid));
1788 if (HeapTupleIsValid(tp))
1790 Form_pg_type typtup = (Form_pg_type) GETSTRUCT(tp);
1793 result = typtup->typbyval;
1794 ReleaseSysCache(tp);
1804 * A two-fer: given the type OID, return both typlen and typbyval.
1806 * Since both pieces of info are needed to know how to copy a Datum,
1807 * many places need both. Might as well get them with one cache lookup
1808 * instead of two. Also, this routine raises an error instead of
1809 * returning a bogus value when given a bad type OID.
1812 get_typlenbyval(Oid typid, int16 *typlen, bool *typbyval)
1815 Form_pg_type typtup;
1817 tp = SearchSysCache1(TYPEOID, ObjectIdGetDatum(typid));
1818 if (!HeapTupleIsValid(tp))
1819 elog(ERROR, "cache lookup failed for type %u", typid);
1820 typtup = (Form_pg_type) GETSTRUCT(tp);
1821 *typlen = typtup->typlen;
1822 *typbyval = typtup->typbyval;
1823 ReleaseSysCache(tp);
1827 * get_typlenbyvalalign
1829 * A three-fer: given the type OID, return typlen, typbyval, typalign.
1832 get_typlenbyvalalign(Oid typid, int16 *typlen, bool *typbyval,
1836 Form_pg_type typtup;
1838 tp = SearchSysCache1(TYPEOID, ObjectIdGetDatum(typid));
1839 if (!HeapTupleIsValid(tp))
1840 elog(ERROR, "cache lookup failed for type %u", typid);
1841 typtup = (Form_pg_type) GETSTRUCT(tp);
1842 *typlen = typtup->typlen;
1843 *typbyval = typtup->typbyval;
1844 *typalign = typtup->typalign;
1845 ReleaseSysCache(tp);
1850 * Given a pg_type row, select the type OID to pass to I/O functions
1852 * Formerly, all I/O functions were passed pg_type.typelem as their second
1853 * parameter, but we now have a more complex rule about what to pass.
1854 * This knowledge is intended to be centralized here --- direct references
1855 * to typelem elsewhere in the code are wrong, if they are associated with
1856 * I/O calls and not with actual subscripting operations! (But see
1857 * bootstrap.c's boot_get_type_io_data() if you need to change this.)
1859 * As of PostgreSQL 8.1, output functions receive only the value itself
1860 * and not any auxiliary parameters, so the name of this routine is now
1861 * a bit of a misnomer ... it should be getTypeInputParam.
1864 getTypeIOParam(HeapTuple typeTuple)
1866 Form_pg_type typeStruct = (Form_pg_type) GETSTRUCT(typeTuple);
1869 * Array types get their typelem as parameter; everybody else gets their
1870 * own type OID as parameter. (As of 8.2, domains must get their own OID
1871 * even if their base type is an array.)
1873 if (typeStruct->typtype == TYPTYPE_BASE && OidIsValid(typeStruct->typelem))
1874 return typeStruct->typelem;
1876 return HeapTupleGetOid(typeTuple);
1882 * A six-fer: given the type OID, return typlen, typbyval, typalign,
1883 * typdelim, typioparam, and IO function OID. The IO function
1884 * returned is controlled by IOFuncSelector
1887 get_type_io_data(Oid typid,
1888 IOFuncSelector which_func,
1896 HeapTuple typeTuple;
1897 Form_pg_type typeStruct;
1900 * In bootstrap mode, pass it off to bootstrap.c. This hack allows us to
1901 * use array_in and array_out during bootstrap.
1903 if (IsBootstrapProcessingMode())
1908 boot_get_type_io_data(typid,
1925 elog(ERROR, "binary I/O not supported during bootstrap");
1931 typeTuple = SearchSysCache1(TYPEOID, ObjectIdGetDatum(typid));
1932 if (!HeapTupleIsValid(typeTuple))
1933 elog(ERROR, "cache lookup failed for type %u", typid);
1934 typeStruct = (Form_pg_type) GETSTRUCT(typeTuple);
1936 *typlen = typeStruct->typlen;
1937 *typbyval = typeStruct->typbyval;
1938 *typalign = typeStruct->typalign;
1939 *typdelim = typeStruct->typdelim;
1940 *typioparam = getTypeIOParam(typeTuple);
1944 *func = typeStruct->typinput;
1947 *func = typeStruct->typoutput;
1949 case IOFunc_receive:
1950 *func = typeStruct->typreceive;
1953 *func = typeStruct->typsend;
1956 ReleaseSysCache(typeTuple);
1961 get_typalign(Oid typid)
1965 tp = SearchSysCache1(TYPEOID, ObjectIdGetDatum(typid));
1966 if (HeapTupleIsValid(tp))
1968 Form_pg_type typtup = (Form_pg_type) GETSTRUCT(tp);
1971 result = typtup->typalign;
1972 ReleaseSysCache(tp);
1981 get_typstorage(Oid typid)
1985 tp = SearchSysCache1(TYPEOID, ObjectIdGetDatum(typid));
1986 if (HeapTupleIsValid(tp))
1988 Form_pg_type typtup = (Form_pg_type) GETSTRUCT(tp);
1991 result = typtup->typstorage;
1992 ReleaseSysCache(tp);
2001 * Given a type OID, return the type's default value, if any.
2003 * The result is a palloc'd expression node tree, or NULL if there
2004 * is no defined default for the datatype.
2006 * NB: caller should be prepared to coerce result to correct datatype;
2007 * the returned expression tree might produce something of the wrong type.
2010 get_typdefault(Oid typid)
2012 HeapTuple typeTuple;
2018 typeTuple = SearchSysCache1(TYPEOID, ObjectIdGetDatum(typid));
2019 if (!HeapTupleIsValid(typeTuple))
2020 elog(ERROR, "cache lookup failed for type %u", typid);
2021 type = (Form_pg_type) GETSTRUCT(typeTuple);
2024 * typdefault and typdefaultbin are potentially null, so don't try to
2025 * access 'em as struct fields. Must do it the hard way with
2028 datum = SysCacheGetAttr(TYPEOID,
2030 Anum_pg_type_typdefaultbin,
2035 /* We have an expression default */
2036 expr = stringToNode(TextDatumGetCString(datum));
2040 /* Perhaps we have a plain literal default */
2041 datum = SysCacheGetAttr(TYPEOID,
2043 Anum_pg_type_typdefault,
2048 char *strDefaultVal;
2050 /* Convert text datum to C string */
2051 strDefaultVal = TextDatumGetCString(datum);
2052 /* Convert C string to a value of the given type */
2053 datum = OidInputFunctionCall(type->typinput, strDefaultVal,
2054 getTypeIOParam(typeTuple), -1);
2055 /* Build a Const node containing the value */
2056 expr = (Node *) makeConst(typid,
2063 pfree(strDefaultVal);
2072 ReleaseSysCache(typeTuple);
2079 * If the given type is a domain, return its base type;
2080 * otherwise return the type's own OID.
2083 getBaseType(Oid typid)
2087 return getBaseTypeAndTypmod(typid, &typmod);
2091 * getBaseTypeAndTypmod
2092 * If the given type is a domain, return its base type and typmod;
2093 * otherwise return the type's own OID, and leave *typmod unchanged.
2095 * Note that the "applied typmod" should be -1 for every domain level
2096 * above the bottommost; therefore, if the passed-in typid is indeed
2097 * a domain, *typmod should be -1.
2100 getBaseTypeAndTypmod(Oid typid, int32 *typmod)
2103 * We loop to find the bottom base type in a stack of domains.
2108 Form_pg_type typTup;
2110 tup = SearchSysCache1(TYPEOID, ObjectIdGetDatum(typid));
2111 if (!HeapTupleIsValid(tup))
2112 elog(ERROR, "cache lookup failed for type %u", typid);
2113 typTup = (Form_pg_type) GETSTRUCT(tup);
2114 if (typTup->typtype != TYPTYPE_DOMAIN)
2116 /* Not a domain, so done */
2117 ReleaseSysCache(tup);
2121 Assert(*typmod == -1);
2122 typid = typTup->typbasetype;
2123 *typmod = typTup->typtypmod;
2125 ReleaseSysCache(tup);
2134 * Given a type OID and a typmod value (pass -1 if typmod is unknown),
2135 * estimate the average width of values of the type. This is used by
2136 * the planner, which doesn't require absolutely correct results;
2137 * it's OK (and expected) to guess if we don't know for sure.
2140 get_typavgwidth(Oid typid, int32 typmod)
2142 int typlen = get_typlen(typid);
2146 * Easy if it's a fixed-width type
2152 * type_maximum_size knows the encoding of typmod for some datatypes;
2153 * don't duplicate that knowledge here.
2155 maxwidth = type_maximum_size(typid, typmod);
2159 * For BPCHAR, the max width is also the only width. Otherwise we
2160 * need to guess about the typical data width given the max. A sliding
2161 * scale for percentage of max width seems reasonable.
2163 if (typid == BPCHAROID)
2166 return maxwidth; /* assume full width */
2167 if (maxwidth < 1000)
2168 return 32 + (maxwidth - 32) / 2; /* assume 50% */
2171 * Beyond 1000, assume we're looking at something like
2172 * "varchar(10000)" where the limit isn't actually reached often, and
2173 * use a fixed estimate.
2175 return 32 + (1000 - 32) / 2;
2179 * Ooops, we have no idea ... wild guess time.
2187 * Given the type OID, find if it is a basic type, a complex type, etc.
2188 * It returns the null char if the cache lookup fails...
2191 get_typtype(Oid typid)
2195 tp = SearchSysCache1(TYPEOID, ObjectIdGetDatum(typid));
2196 if (HeapTupleIsValid(tp))
2198 Form_pg_type typtup = (Form_pg_type) GETSTRUCT(tp);
2201 result = typtup->typtype;
2202 ReleaseSysCache(tp);
2212 * Convenience function to determine whether a type OID represents
2213 * a "rowtype" type --- either RECORD or a named composite type.
2216 type_is_rowtype(Oid typid)
2218 return (typid == RECORDOID || get_typtype(typid) == TYPTYPE_COMPOSITE);
2223 * Returns true if the given type is an enum type.
2226 type_is_enum(Oid typid)
2228 return (get_typtype(typid) == TYPTYPE_ENUM);
2232 * get_type_category_preferred
2234 * Given the type OID, fetch its category and preferred-type status.
2235 * Throws error on failure.
2238 get_type_category_preferred(Oid typid, char *typcategory, bool *typispreferred)
2241 Form_pg_type typtup;
2243 tp = SearchSysCache1(TYPEOID, ObjectIdGetDatum(typid));
2244 if (!HeapTupleIsValid(tp))
2245 elog(ERROR, "cache lookup failed for type %u", typid);
2246 typtup = (Form_pg_type) GETSTRUCT(tp);
2247 *typcategory = typtup->typcategory;
2248 *typispreferred = typtup->typispreferred;
2249 ReleaseSysCache(tp);
2255 * Given the type OID, get the typrelid (InvalidOid if not a complex
2259 get_typ_typrelid(Oid typid)
2263 tp = SearchSysCache1(TYPEOID, ObjectIdGetDatum(typid));
2264 if (HeapTupleIsValid(tp))
2266 Form_pg_type typtup = (Form_pg_type) GETSTRUCT(tp);
2269 result = typtup->typrelid;
2270 ReleaseSysCache(tp);
2280 * Given the type OID, get the typelem (InvalidOid if not an array type).
2282 * NB: this only considers varlena arrays to be true arrays; InvalidOid is
2283 * returned if the input is a fixed-length array type.
2286 get_element_type(Oid typid)
2290 tp = SearchSysCache1(TYPEOID, ObjectIdGetDatum(typid));
2291 if (HeapTupleIsValid(tp))
2293 Form_pg_type typtup = (Form_pg_type) GETSTRUCT(tp);
2296 if (typtup->typlen == -1)
2297 result = typtup->typelem;
2299 result = InvalidOid;
2300 ReleaseSysCache(tp);
2310 * Given the type OID, get the corresponding "true" array type.
2311 * Returns InvalidOid if no array type can be found.
2314 get_array_type(Oid typid)
2317 Oid result = InvalidOid;
2319 tp = SearchSysCache1(TYPEOID, ObjectIdGetDatum(typid));
2320 if (HeapTupleIsValid(tp))
2322 result = ((Form_pg_type) GETSTRUCT(tp))->typarray;
2323 ReleaseSysCache(tp);
2329 * get_base_element_type
2330 * Given the type OID, get the typelem, looking "through" any domain
2331 * to its underlying array type.
2333 * This is equivalent to get_element_type(getBaseType(typid)), but avoids
2334 * an extra cache lookup. Note that it fails to provide any information
2335 * about the typmod of the array.
2338 get_base_element_type(Oid typid)
2341 * We loop to find the bottom base type in a stack of domains.
2346 Form_pg_type typTup;
2348 tup = SearchSysCache1(TYPEOID, ObjectIdGetDatum(typid));
2349 if (!HeapTupleIsValid(tup))
2351 typTup = (Form_pg_type) GETSTRUCT(tup);
2352 if (typTup->typtype != TYPTYPE_DOMAIN)
2354 /* Not a domain, so stop descending */
2357 /* This test must match get_element_type */
2358 if (typTup->typlen == -1)
2359 result = typTup->typelem;
2361 result = InvalidOid;
2362 ReleaseSysCache(tup);
2366 typid = typTup->typbasetype;
2367 ReleaseSysCache(tup);
2370 /* Like get_element_type, silently return InvalidOid for bogus input */
2377 * Get info needed for converting values of a type to internal form
2380 getTypeInputInfo(Oid type, Oid *typInput, Oid *typIOParam)
2382 HeapTuple typeTuple;
2385 typeTuple = SearchSysCache1(TYPEOID, ObjectIdGetDatum(type));
2386 if (!HeapTupleIsValid(typeTuple))
2387 elog(ERROR, "cache lookup failed for type %u", type);
2388 pt = (Form_pg_type) GETSTRUCT(typeTuple);
2390 if (!pt->typisdefined)
2392 (errcode(ERRCODE_UNDEFINED_OBJECT),
2393 errmsg("type %s is only a shell",
2394 format_type_be(type))));
2395 if (!OidIsValid(pt->typinput))
2397 (errcode(ERRCODE_UNDEFINED_FUNCTION),
2398 errmsg("no input function available for type %s",
2399 format_type_be(type))));
2401 *typInput = pt->typinput;
2402 *typIOParam = getTypeIOParam(typeTuple);
2404 ReleaseSysCache(typeTuple);
2410 * Get info needed for printing values of a type
2413 getTypeOutputInfo(Oid type, Oid *typOutput, bool *typIsVarlena)
2415 HeapTuple typeTuple;
2418 typeTuple = SearchSysCache1(TYPEOID, ObjectIdGetDatum(type));
2419 if (!HeapTupleIsValid(typeTuple))
2420 elog(ERROR, "cache lookup failed for type %u", type);
2421 pt = (Form_pg_type) GETSTRUCT(typeTuple);
2423 if (!pt->typisdefined)
2425 (errcode(ERRCODE_UNDEFINED_OBJECT),
2426 errmsg("type %s is only a shell",
2427 format_type_be(type))));
2428 if (!OidIsValid(pt->typoutput))
2430 (errcode(ERRCODE_UNDEFINED_FUNCTION),
2431 errmsg("no output function available for type %s",
2432 format_type_be(type))));
2434 *typOutput = pt->typoutput;
2435 *typIsVarlena = (!pt->typbyval) && (pt->typlen == -1);
2437 ReleaseSysCache(typeTuple);
2441 * getTypeBinaryInputInfo
2443 * Get info needed for binary input of values of a type
2446 getTypeBinaryInputInfo(Oid type, Oid *typReceive, Oid *typIOParam)
2448 HeapTuple typeTuple;
2451 typeTuple = SearchSysCache1(TYPEOID, ObjectIdGetDatum(type));
2452 if (!HeapTupleIsValid(typeTuple))
2453 elog(ERROR, "cache lookup failed for type %u", type);
2454 pt = (Form_pg_type) GETSTRUCT(typeTuple);
2456 if (!pt->typisdefined)
2458 (errcode(ERRCODE_UNDEFINED_OBJECT),
2459 errmsg("type %s is only a shell",
2460 format_type_be(type))));
2461 if (!OidIsValid(pt->typreceive))
2463 (errcode(ERRCODE_UNDEFINED_FUNCTION),
2464 errmsg("no binary input function available for type %s",
2465 format_type_be(type))));
2467 *typReceive = pt->typreceive;
2468 *typIOParam = getTypeIOParam(typeTuple);
2470 ReleaseSysCache(typeTuple);
2474 * getTypeBinaryOutputInfo
2476 * Get info needed for binary output of values of a type
2479 getTypeBinaryOutputInfo(Oid type, Oid *typSend, bool *typIsVarlena)
2481 HeapTuple typeTuple;
2484 typeTuple = SearchSysCache1(TYPEOID, ObjectIdGetDatum(type));
2485 if (!HeapTupleIsValid(typeTuple))
2486 elog(ERROR, "cache lookup failed for type %u", type);
2487 pt = (Form_pg_type) GETSTRUCT(typeTuple);
2489 if (!pt->typisdefined)
2491 (errcode(ERRCODE_UNDEFINED_OBJECT),
2492 errmsg("type %s is only a shell",
2493 format_type_be(type))));
2494 if (!OidIsValid(pt->typsend))
2496 (errcode(ERRCODE_UNDEFINED_FUNCTION),
2497 errmsg("no binary output function available for type %s",
2498 format_type_be(type))));
2500 *typSend = pt->typsend;
2501 *typIsVarlena = (!pt->typbyval) && (pt->typlen == -1);
2503 ReleaseSysCache(typeTuple);
2509 * Given the type OID, return the type's typmodin procedure, if any.
2512 get_typmodin(Oid typid)
2516 tp = SearchSysCache1(TYPEOID, ObjectIdGetDatum(typid));
2517 if (HeapTupleIsValid(tp))
2519 Form_pg_type typtup = (Form_pg_type) GETSTRUCT(tp);
2522 result = typtup->typmodin;
2523 ReleaseSysCache(tp);
2534 * Given the type OID, return the type's typmodout procedure, if any.
2537 get_typmodout(Oid typid)
2541 tp = SearchSysCache1(TYPEOID, ObjectIdGetDatum(typid));
2542 if (HeapTupleIsValid(tp))
2544 Form_pg_type typtup = (Form_pg_type) GETSTRUCT(tp);
2547 result = typtup->typmodout;
2548 ReleaseSysCache(tp);
2554 #endif /* NOT_USED */
2559 * Given the type OID, return the type's typcollation attribute.
2562 get_typcollation(Oid typid)
2566 tp = SearchSysCache1(TYPEOID, ObjectIdGetDatum(typid));
2567 if (HeapTupleIsValid(tp))
2569 Form_pg_type typtup = (Form_pg_type) GETSTRUCT(tp);
2572 result = typtup->typcollation;
2573 ReleaseSysCache(tp);
2582 * type_is_collatable
2584 * Return whether the type cares about collations
2587 type_is_collatable(Oid typid)
2589 return OidIsValid(get_typcollation(typid));
2593 /* ---------- STATISTICS CACHE ---------- */
2598 * Given the table and attribute number of a column, get the average
2599 * width of entries in the column. Return zero if no data available.
2601 * Currently this is only consulted for individual tables, not for inheritance
2602 * trees, so we don't need an "inh" parameter.
2604 * Calling a hook at this point looks somewhat strange, but is required
2605 * because the optimizer calls this function without any other way for
2606 * plug-ins to control the result.
2609 get_attavgwidth(Oid relid, AttrNumber attnum)
2614 if (get_attavgwidth_hook)
2616 stawidth = (*get_attavgwidth_hook) (relid, attnum);
2620 tp = SearchSysCache3(STATRELATTINH,
2621 ObjectIdGetDatum(relid),
2622 Int16GetDatum(attnum),
2623 BoolGetDatum(false));
2624 if (HeapTupleIsValid(tp))
2626 stawidth = ((Form_pg_statistic) GETSTRUCT(tp))->stawidth;
2627 ReleaseSysCache(tp);
2637 * Extract the contents of a "slot" of a pg_statistic tuple.
2638 * Returns TRUE if requested slot type was found, else FALSE.
2640 * Unlike other routines in this file, this takes a pointer to an
2641 * already-looked-up tuple in the pg_statistic cache. We do this since
2642 * most callers will want to extract more than one value from the cache
2643 * entry, and we don't want to repeat the cache lookup unnecessarily.
2644 * Also, this API allows this routine to be used with statistics tuples
2645 * that have been provided by a stats hook and didn't really come from
2648 * statstuple: pg_statistics tuple to be examined.
2649 * atttype: type OID of attribute (can be InvalidOid if values == NULL).
2650 * atttypmod: typmod of attribute (can be 0 if values == NULL).
2651 * reqkind: STAKIND code for desired statistics slot kind.
2652 * reqop: STAOP value wanted, or InvalidOid if don't care.
2653 * actualop: if not NULL, *actualop receives the actual STAOP value.
2654 * values, nvalues: if not NULL, the slot's stavalues are extracted.
2655 * numbers, nnumbers: if not NULL, the slot's stanumbers are extracted.
2657 * If assigned, values and numbers are set to point to palloc'd arrays.
2658 * If the attribute type is pass-by-reference, the values referenced by
2659 * the values array are themselves palloc'd. The palloc'd stuff can be
2660 * freed by calling free_attstatsslot.
2662 * Note: at present, atttype/atttypmod aren't actually used here at all.
2663 * But the caller must have the correct (or at least binary-compatible)
2664 * type ID to pass to free_attstatsslot later.
2667 get_attstatsslot(HeapTuple statstuple,
2668 Oid atttype, int32 atttypmod,
2669 int reqkind, Oid reqop,
2671 Datum **values, int *nvalues,
2672 float4 **numbers, int *nnumbers)
2674 Form_pg_statistic stats = (Form_pg_statistic) GETSTRUCT(statstuple);
2679 ArrayType *statarray;
2682 HeapTuple typeTuple;
2683 Form_pg_type typeForm;
2685 for (i = 0; i < STATISTIC_NUM_SLOTS; i++)
2687 if ((&stats->stakind1)[i] == reqkind &&
2688 (reqop == InvalidOid || (&stats->staop1)[i] == reqop))
2691 if (i >= STATISTIC_NUM_SLOTS)
2692 return false; /* not there */
2695 *actualop = (&stats->staop1)[i];
2699 val = SysCacheGetAttr(STATRELATTINH, statstuple,
2700 Anum_pg_statistic_stavalues1 + i,
2703 elog(ERROR, "stavalues is null");
2704 statarray = DatumGetArrayTypeP(val);
2707 * Need to get info about the array element type. We look at the
2708 * actual element type embedded in the array, which might be only
2709 * binary-compatible with the passed-in atttype. The info we extract
2710 * here should be the same either way, but deconstruct_array is picky
2711 * about having an exact type OID match.
2713 arrayelemtype = ARR_ELEMTYPE(statarray);
2714 typeTuple = SearchSysCache1(TYPEOID, ObjectIdGetDatum(arrayelemtype));
2715 if (!HeapTupleIsValid(typeTuple))
2716 elog(ERROR, "cache lookup failed for type %u", arrayelemtype);
2717 typeForm = (Form_pg_type) GETSTRUCT(typeTuple);
2719 /* Deconstruct array into Datum elements; NULLs not expected */
2720 deconstruct_array(statarray,
2725 values, NULL, nvalues);
2728 * If the element type is pass-by-reference, we now have a bunch of
2729 * Datums that are pointers into the syscache value. Copy them to
2730 * avoid problems if syscache decides to drop the entry.
2732 if (!typeForm->typbyval)
2734 for (j = 0; j < *nvalues; j++)
2736 (*values)[j] = datumCopy((*values)[j],
2742 ReleaseSysCache(typeTuple);
2745 * Free statarray if it's a detoasted copy.
2747 if ((Pointer) statarray != DatumGetPointer(val))
2753 val = SysCacheGetAttr(STATRELATTINH, statstuple,
2754 Anum_pg_statistic_stanumbers1 + i,
2757 elog(ERROR, "stanumbers is null");
2758 statarray = DatumGetArrayTypeP(val);
2761 * We expect the array to be a 1-D float4 array; verify that. We don't
2762 * need to use deconstruct_array() since the array data is just going
2763 * to look like a C array of float4 values.
2765 narrayelem = ARR_DIMS(statarray)[0];
2766 if (ARR_NDIM(statarray) != 1 || narrayelem <= 0 ||
2767 ARR_HASNULL(statarray) ||
2768 ARR_ELEMTYPE(statarray) != FLOAT4OID)
2769 elog(ERROR, "stanumbers is not a 1-D float4 array");
2770 *numbers = (float4 *) palloc(narrayelem * sizeof(float4));
2771 memcpy(*numbers, ARR_DATA_PTR(statarray), narrayelem * sizeof(float4));
2772 *nnumbers = narrayelem;
2775 * Free statarray if it's a detoasted copy.
2777 if ((Pointer) statarray != DatumGetPointer(val))
2786 * Free data allocated by get_attstatsslot
2788 * atttype need be valid only if values != NULL.
2791 free_attstatsslot(Oid atttype,
2792 Datum *values, int nvalues,
2793 float4 *numbers, int nnumbers)
2797 if (!get_typbyval(atttype))
2801 for (i = 0; i < nvalues; i++)
2802 pfree(DatumGetPointer(values[i]));
2810 /* ---------- PG_NAMESPACE CACHE ---------- */
2813 * get_namespace_name
2814 * Returns the name of a given namespace
2816 * Returns a palloc'd copy of the string, or NULL if no such namespace.
2819 get_namespace_name(Oid nspid)
2823 tp = SearchSysCache1(NAMESPACEOID, ObjectIdGetDatum(nspid));
2824 if (HeapTupleIsValid(tp))
2826 Form_pg_namespace nsptup = (Form_pg_namespace) GETSTRUCT(tp);
2829 result = pstrdup(NameStr(nsptup->nspname));
2830 ReleaseSysCache(tp);