1 /*-------------------------------------------------------------------------
4 * Convenience routines for common queries in the system catalog cache.
6 * Portions Copyright (c) 1996-2010, 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.169 2010/04/23 22:23:39 sriggs Exp $
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_constraint.h"
24 #include "catalog/pg_namespace.h"
25 #include "catalog/pg_opclass.h"
26 #include "catalog/pg_operator.h"
27 #include "catalog/pg_proc.h"
28 #include "catalog/pg_statistic.h"
29 #include "catalog/pg_type.h"
30 #include "miscadmin.h"
31 #include "nodes/makefuncs.h"
32 #include "utils/array.h"
33 #include "utils/builtins.h"
34 #include "utils/datum.h"
35 #include "utils/lsyscache.h"
36 #include "utils/syscache.h"
38 /* Hook for plugins to get control in get_attavgwidth() */
39 get_attavgwidth_hook_type get_attavgwidth_hook = NULL;
41 /* Hook for plugins to get control in get_func_cost and get_func_rows */
42 get_func_cost_hook_type get_func_cost_hook = NULL;
43 get_func_rows_hook_type get_func_rows_hook = NULL;
45 /* ---------- AMOP CACHES ---------- */
50 * Return t iff operator 'opno' is in operator family 'opfamily'.
53 op_in_opfamily(Oid opno, Oid opfamily)
55 return SearchSysCacheExists2(AMOPOPID,
56 ObjectIdGetDatum(opno),
57 ObjectIdGetDatum(opfamily));
61 * get_op_opfamily_strategy
63 * Get the operator's strategy number within the specified opfamily,
64 * or 0 if it's not a member of the opfamily.
67 get_op_opfamily_strategy(Oid opno, Oid opfamily)
70 Form_pg_amop amop_tup;
73 tp = SearchSysCache2(AMOPOPID,
74 ObjectIdGetDatum(opno),
75 ObjectIdGetDatum(opfamily));
76 if (!HeapTupleIsValid(tp))
78 amop_tup = (Form_pg_amop) GETSTRUCT(tp);
79 result = amop_tup->amopstrategy;
85 * get_op_opfamily_properties
87 * Get the operator's strategy number and declared input data types
88 * within the specified opfamily.
90 * Caller should already have verified that opno is a member of opfamily,
91 * therefore we raise an error if the tuple is not found.
94 get_op_opfamily_properties(Oid opno, Oid opfamily,
100 Form_pg_amop amop_tup;
102 tp = SearchSysCache2(AMOPOPID,
103 ObjectIdGetDatum(opno),
104 ObjectIdGetDatum(opfamily));
105 if (!HeapTupleIsValid(tp))
106 elog(ERROR, "operator %u is not a member of opfamily %u",
108 amop_tup = (Form_pg_amop) GETSTRUCT(tp);
109 *strategy = amop_tup->amopstrategy;
110 *lefttype = amop_tup->amoplefttype;
111 *righttype = amop_tup->amoprighttype;
116 * get_opfamily_member
117 * Get the OID of the operator that implements the specified strategy
118 * with the specified datatypes for the specified opfamily.
120 * Returns InvalidOid if there is no pg_amop entry for the given keys.
123 get_opfamily_member(Oid opfamily, Oid lefttype, Oid righttype,
127 Form_pg_amop amop_tup;
130 tp = SearchSysCache4(AMOPSTRATEGY,
131 ObjectIdGetDatum(opfamily),
132 ObjectIdGetDatum(lefttype),
133 ObjectIdGetDatum(righttype),
134 Int16GetDatum(strategy));
135 if (!HeapTupleIsValid(tp))
137 amop_tup = (Form_pg_amop) GETSTRUCT(tp);
138 result = amop_tup->amopopr;
144 * get_ordering_op_properties
145 * Given the OID of an ordering operator (a btree "<" or ">" operator),
146 * determine its opfamily, its declared input datatype, and its
147 * strategy number (BTLessStrategyNumber or BTGreaterStrategyNumber).
149 * Returns TRUE if successful, FALSE if no matching pg_amop entry exists.
150 * (This indicates that the operator is not a valid ordering operator.)
152 * Note: the operator could be registered in multiple families, for example
153 * if someone were to build a "reverse sort" opfamily. This would result in
154 * uncertainty as to whether "ORDER BY USING op" would default to NULLS FIRST
155 * or NULLS LAST, as well as inefficient planning due to failure to match up
156 * pathkeys that should be the same. So we want a determinate result here.
157 * Because of the way the syscache search works, we'll use the interpretation
158 * associated with the opfamily with smallest OID, which is probably
159 * determinate enough. Since there is no longer any particularly good reason
160 * to build reverse-sort opfamilies, it doesn't seem worth expending any
161 * additional effort on ensuring consistency.
164 get_ordering_op_properties(Oid opno,
165 Oid *opfamily, Oid *opcintype, int16 *strategy)
171 /* ensure outputs are initialized on failure */
172 *opfamily = InvalidOid;
173 *opcintype = InvalidOid;
177 * Search pg_amop to see if the target operator is registered as the "<"
178 * or ">" operator of any btree opfamily.
180 catlist = SearchSysCacheList1(AMOPOPID, ObjectIdGetDatum(opno));
182 for (i = 0; i < catlist->n_members; i++)
184 HeapTuple tuple = &catlist->members[i]->tuple;
185 Form_pg_amop aform = (Form_pg_amop) GETSTRUCT(tuple);
188 if (aform->amopmethod != BTREE_AM_OID)
191 if (aform->amopstrategy == BTLessStrategyNumber ||
192 aform->amopstrategy == BTGreaterStrategyNumber)
194 /* Found it ... should have consistent input types */
195 if (aform->amoplefttype == aform->amoprighttype)
197 /* Found a suitable opfamily, return info */
198 *opfamily = aform->amopfamily;
199 *opcintype = aform->amoplefttype;
200 *strategy = aform->amopstrategy;
207 ReleaseSysCacheList(catlist);
213 * get_compare_function_for_ordering_op
214 * Get the OID of the datatype-specific btree comparison function
215 * associated with an ordering operator (a "<" or ">" operator).
217 * *cmpfunc receives the comparison function OID.
218 * *reverse is set FALSE if the operator is "<", TRUE if it's ">"
219 * (indicating the comparison result must be negated before use).
221 * Returns TRUE if successful, FALSE if no btree function can be found.
222 * (This indicates that the operator is not a valid ordering operator.)
225 get_compare_function_for_ordering_op(Oid opno, Oid *cmpfunc, bool *reverse)
231 /* Find the operator in pg_amop */
232 if (get_ordering_op_properties(opno,
233 &opfamily, &opcintype, &strategy))
235 /* Found a suitable opfamily, get matching support function */
236 *cmpfunc = get_opfamily_proc(opfamily,
241 if (!OidIsValid(*cmpfunc)) /* should not happen */
242 elog(ERROR, "missing support function %d(%u,%u) in opfamily %u",
243 BTORDER_PROC, opcintype, opcintype, opfamily);
244 *reverse = (strategy == BTGreaterStrategyNumber);
248 /* ensure outputs are set on failure */
249 *cmpfunc = InvalidOid;
256 * get_equality_op_for_ordering_op
257 * Get the OID of the datatype-specific btree equality operator
258 * associated with an ordering operator (a "<" or ">" operator).
260 * If "reverse" isn't NULL, also set *reverse to FALSE if the operator is "<",
263 * Returns InvalidOid if no matching equality operator can be found.
264 * (This indicates that the operator is not a valid ordering operator.)
267 get_equality_op_for_ordering_op(Oid opno, bool *reverse)
269 Oid result = InvalidOid;
274 /* Find the operator in pg_amop */
275 if (get_ordering_op_properties(opno,
276 &opfamily, &opcintype, &strategy))
278 /* Found a suitable opfamily, get matching equality operator */
279 result = get_opfamily_member(opfamily,
282 BTEqualStrategyNumber);
284 *reverse = (strategy == BTGreaterStrategyNumber);
291 * get_ordering_op_for_equality_op
292 * Get the OID of a datatype-specific btree ordering operator
293 * associated with an equality operator. (If there are multiple
294 * possibilities, assume any one will do.)
296 * This function is used when we have to sort data before unique-ifying,
297 * and don't much care which sorting op is used as long as it's compatible
298 * with the intended equality operator. Since we need a sorting operator,
299 * it should be single-data-type even if the given operator is cross-type.
300 * The caller specifies whether to find an op for the LHS or RHS data type.
302 * Returns InvalidOid if no matching ordering operator can be found.
305 get_ordering_op_for_equality_op(Oid opno, bool use_lhs_type)
307 Oid result = InvalidOid;
312 * Search pg_amop to see if the target operator is registered as the "="
313 * operator of any btree opfamily.
315 catlist = SearchSysCacheList1(AMOPOPID, ObjectIdGetDatum(opno));
317 for (i = 0; i < catlist->n_members; i++)
319 HeapTuple tuple = &catlist->members[i]->tuple;
320 Form_pg_amop aform = (Form_pg_amop) GETSTRUCT(tuple);
323 if (aform->amopmethod != BTREE_AM_OID)
326 if (aform->amopstrategy == BTEqualStrategyNumber)
328 /* Found a suitable opfamily, get matching ordering operator */
331 typid = use_lhs_type ? aform->amoplefttype : aform->amoprighttype;
332 result = get_opfamily_member(aform->amopfamily,
334 BTLessStrategyNumber);
335 if (OidIsValid(result))
337 /* failure probably shouldn't happen, but keep looking if so */
341 ReleaseSysCacheList(catlist);
347 * get_mergejoin_opfamilies
348 * Given a putatively mergejoinable operator, return a list of the OIDs
349 * of the btree opfamilies in which it represents equality.
351 * It is possible (though at present unusual) for an operator to be equality
352 * in more than one opfamily, hence the result is a list. This also lets us
353 * return NIL if the operator is not found in any opfamilies.
355 * The planner currently uses simple equal() tests to compare the lists
356 * returned by this function, which makes the list order relevant, though
357 * strictly speaking it should not be. Because of the way syscache list
358 * searches are handled, in normal operation the result will be sorted by OID
359 * so everything works fine. If running with system index usage disabled,
360 * the result ordering is unspecified and hence the planner might fail to
361 * recognize optimization opportunities ... but that's hardly a scenario in
362 * which performance is good anyway, so there's no point in expending code
363 * or cycles here to guarantee the ordering in that case.
366 get_mergejoin_opfamilies(Oid opno)
373 * Search pg_amop to see if the target operator is registered as the "="
374 * operator of any btree opfamily.
376 catlist = SearchSysCacheList1(AMOPOPID, ObjectIdGetDatum(opno));
378 for (i = 0; i < catlist->n_members; i++)
380 HeapTuple tuple = &catlist->members[i]->tuple;
381 Form_pg_amop aform = (Form_pg_amop) GETSTRUCT(tuple);
383 /* must be btree equality */
384 if (aform->amopmethod == BTREE_AM_OID &&
385 aform->amopstrategy == BTEqualStrategyNumber)
386 result = lappend_oid(result, aform->amopfamily);
389 ReleaseSysCacheList(catlist);
395 * get_compatible_hash_operators
396 * Get the OID(s) of hash equality operator(s) compatible with the given
397 * operator, but operating on its LHS and/or RHS datatype.
399 * An operator for the LHS type is sought and returned into *lhs_opno if
400 * lhs_opno isn't NULL. Similarly, an operator for the RHS type is sought
401 * and returned into *rhs_opno if rhs_opno isn't NULL.
403 * If the given operator is not cross-type, the results should be the same
404 * operator, but in cross-type situations they will be different.
406 * Returns true if able to find the requested operator(s), false if not.
407 * (This indicates that the operator should not have been marked oprcanhash.)
410 get_compatible_hash_operators(Oid opno,
411 Oid *lhs_opno, Oid *rhs_opno)
417 /* Ensure output args are initialized on failure */
419 *lhs_opno = InvalidOid;
421 *rhs_opno = InvalidOid;
424 * Search pg_amop to see if the target operator is registered as the "="
425 * operator of any hash opfamily. If the operator is registered in
426 * multiple opfamilies, assume we can use any one.
428 catlist = SearchSysCacheList1(AMOPOPID, ObjectIdGetDatum(opno));
430 for (i = 0; i < catlist->n_members; i++)
432 HeapTuple tuple = &catlist->members[i]->tuple;
433 Form_pg_amop aform = (Form_pg_amop) GETSTRUCT(tuple);
435 if (aform->amopmethod == HASH_AM_OID &&
436 aform->amopstrategy == HTEqualStrategyNumber)
438 /* No extra lookup needed if given operator is single-type */
439 if (aform->amoplefttype == aform->amoprighttype)
450 * Get the matching single-type operator(s). Failure probably
451 * shouldn't happen --- it implies a bogus opfamily --- but
452 * continue looking if so.
456 *lhs_opno = get_opfamily_member(aform->amopfamily,
459 HTEqualStrategyNumber);
460 if (!OidIsValid(*lhs_opno))
462 /* Matching LHS found, done if caller doesn't want RHS */
471 *rhs_opno = get_opfamily_member(aform->amopfamily,
472 aform->amoprighttype,
473 aform->amoprighttype,
474 HTEqualStrategyNumber);
475 if (!OidIsValid(*rhs_opno))
477 /* Forget any LHS operator from this opfamily */
479 *lhs_opno = InvalidOid;
482 /* Matching RHS found, so done */
489 ReleaseSysCacheList(catlist);
495 * get_op_hash_functions
496 * Get the OID(s) of hash support function(s) compatible with the given
497 * operator, operating on its LHS and/or RHS datatype as required.
499 * A function for the LHS type is sought and returned into *lhs_procno if
500 * lhs_procno isn't NULL. Similarly, a function for the RHS type is sought
501 * and returned into *rhs_procno if rhs_procno isn't NULL.
503 * If the given operator is not cross-type, the results should be the same
504 * function, but in cross-type situations they will be different.
506 * Returns true if able to find the requested function(s), false if not.
507 * (This indicates that the operator should not have been marked oprcanhash.)
510 get_op_hash_functions(Oid opno,
511 RegProcedure *lhs_procno, RegProcedure *rhs_procno)
517 /* Ensure output args are initialized on failure */
519 *lhs_procno = InvalidOid;
521 *rhs_procno = InvalidOid;
524 * Search pg_amop to see if the target operator is registered as the "="
525 * operator of any hash opfamily. If the operator is registered in
526 * multiple opfamilies, assume we can use any one.
528 catlist = SearchSysCacheList1(AMOPOPID, ObjectIdGetDatum(opno));
530 for (i = 0; i < catlist->n_members; i++)
532 HeapTuple tuple = &catlist->members[i]->tuple;
533 Form_pg_amop aform = (Form_pg_amop) GETSTRUCT(tuple);
535 if (aform->amopmethod == HASH_AM_OID &&
536 aform->amopstrategy == HTEqualStrategyNumber)
539 * Get the matching support function(s). Failure probably
540 * shouldn't happen --- it implies a bogus opfamily --- but
541 * continue looking if so.
545 *lhs_procno = get_opfamily_proc(aform->amopfamily,
549 if (!OidIsValid(*lhs_procno))
551 /* Matching LHS found, done if caller doesn't want RHS */
557 /* Only one lookup needed if given operator is single-type */
558 if (aform->amoplefttype == aform->amoprighttype)
560 *rhs_procno = *lhs_procno;
567 *rhs_procno = get_opfamily_proc(aform->amopfamily,
568 aform->amoprighttype,
569 aform->amoprighttype,
571 if (!OidIsValid(*rhs_procno))
573 /* Forget any LHS function from this opfamily */
575 *lhs_procno = InvalidOid;
578 /* Matching RHS found, so done */
585 ReleaseSysCacheList(catlist);
591 * get_op_btree_interpretation
592 * Given an operator's OID, find out which btree opfamilies it belongs to,
593 * and what strategy number it has within each one. The results are
594 * returned as an OID list and a parallel integer list.
596 * In addition to the normal btree operators, we consider a <> operator to be
597 * a "member" of an opfamily if its negator is an equality operator of the
598 * opfamily. ROWCOMPARE_NE is returned as the strategy number for this case.
601 get_op_btree_interpretation(Oid opno, List **opfamilies, List **opstrats)
611 * Find all the pg_amop entries containing the operator.
613 catlist = SearchSysCacheList1(AMOPOPID, ObjectIdGetDatum(opno));
616 * If we can't find any opfamily containing the op, perhaps it is a <>
617 * operator. See if it has a negator that is in an opfamily.
620 if (catlist->n_members == 0)
622 Oid op_negator = get_negator(opno);
624 if (OidIsValid(op_negator))
627 ReleaseSysCacheList(catlist);
628 catlist = SearchSysCacheList1(AMOPOPID,
629 ObjectIdGetDatum(op_negator));
633 /* Now search the opfamilies */
634 for (i = 0; i < catlist->n_members; i++)
636 HeapTuple op_tuple = &catlist->members[i]->tuple;
637 Form_pg_amop op_form = (Form_pg_amop) GETSTRUCT(op_tuple);
639 StrategyNumber op_strategy;
642 if (op_form->amopmethod != BTREE_AM_OID)
645 /* Get the operator's btree strategy number */
646 opfamily_id = op_form->amopfamily;
647 op_strategy = (StrategyNumber) op_form->amopstrategy;
648 Assert(op_strategy >= 1 && op_strategy <= 5);
652 /* Only consider negators that are = */
653 if (op_strategy != BTEqualStrategyNumber)
655 op_strategy = ROWCOMPARE_NE;
658 *opfamilies = lappend_oid(*opfamilies, opfamily_id);
659 *opstrats = lappend_int(*opstrats, op_strategy);
662 ReleaseSysCacheList(catlist);
666 * equality_ops_are_compatible
667 * Return TRUE if the two given equality operators have compatible
670 * This is trivially true if they are the same operator. Otherwise,
671 * we look to see if they can be found in the same btree or hash opfamily.
672 * Either finding allows us to assume that they have compatible notions
673 * of equality. (The reason we need to do these pushups is that one might
674 * be a cross-type operator; for instance int24eq vs int4eq.)
677 equality_ops_are_compatible(Oid opno1, Oid opno2)
683 /* Easy if they're the same operator */
688 * We search through all the pg_amop entries for opno1.
690 catlist = SearchSysCacheList1(AMOPOPID, ObjectIdGetDatum(opno1));
693 for (i = 0; i < catlist->n_members; i++)
695 HeapTuple op_tuple = &catlist->members[i]->tuple;
696 Form_pg_amop op_form = (Form_pg_amop) GETSTRUCT(op_tuple);
698 /* must be btree or hash */
699 if (op_form->amopmethod == BTREE_AM_OID ||
700 op_form->amopmethod == HASH_AM_OID)
702 if (op_in_opfamily(opno2, op_form->amopfamily))
710 ReleaseSysCacheList(catlist);
716 /* ---------- AMPROC CACHES ---------- */
720 * Get the OID of the specified support function
721 * for the specified opfamily and datatypes.
723 * Returns InvalidOid if there is no pg_amproc entry for the given keys.
726 get_opfamily_proc(Oid opfamily, Oid lefttype, Oid righttype, int16 procnum)
729 Form_pg_amproc amproc_tup;
732 tp = SearchSysCache4(AMPROCNUM,
733 ObjectIdGetDatum(opfamily),
734 ObjectIdGetDatum(lefttype),
735 ObjectIdGetDatum(righttype),
736 Int16GetDatum(procnum));
737 if (!HeapTupleIsValid(tp))
739 amproc_tup = (Form_pg_amproc) GETSTRUCT(tp);
740 result = amproc_tup->amproc;
746 /* ---------- ATTRIBUTE CACHES ---------- */
750 * Given the relation id and the attribute number,
751 * return the "attname" field from the attribute relation.
753 * Note: returns a palloc'd copy of the string, or NULL if no such attribute.
756 get_attname(Oid relid, AttrNumber attnum)
760 tp = SearchSysCache2(ATTNUM,
761 ObjectIdGetDatum(relid),
762 Int16GetDatum(attnum));
763 if (HeapTupleIsValid(tp))
765 Form_pg_attribute att_tup = (Form_pg_attribute) GETSTRUCT(tp);
768 result = pstrdup(NameStr(att_tup->attname));
777 * get_relid_attribute_name
779 * Same as above routine get_attname(), except that error
780 * is handled by elog() instead of returning NULL.
783 get_relid_attribute_name(Oid relid, AttrNumber attnum)
787 attname = get_attname(relid, attnum);
789 elog(ERROR, "cache lookup failed for attribute %d of relation %u",
797 * Given the relation id and the attribute name,
798 * return the "attnum" field from the attribute relation.
800 * Returns InvalidAttrNumber if the attr doesn't exist (or is dropped).
803 get_attnum(Oid relid, const char *attname)
807 tp = SearchSysCacheAttName(relid, attname);
808 if (HeapTupleIsValid(tp))
810 Form_pg_attribute att_tup = (Form_pg_attribute) GETSTRUCT(tp);
813 result = att_tup->attnum;
818 return InvalidAttrNumber;
824 * Given the relation OID and the attribute number with the relation,
825 * return the attribute type OID.
828 get_atttype(Oid relid, AttrNumber attnum)
832 tp = SearchSysCache2(ATTNUM,
833 ObjectIdGetDatum(relid),
834 Int16GetDatum(attnum));
835 if (HeapTupleIsValid(tp))
837 Form_pg_attribute att_tup = (Form_pg_attribute) GETSTRUCT(tp);
840 result = att_tup->atttypid;
851 * Given the relation id and the attribute number,
852 * return the "atttypmod" field from the attribute relation.
855 get_atttypmod(Oid relid, AttrNumber attnum)
859 tp = SearchSysCache2(ATTNUM,
860 ObjectIdGetDatum(relid),
861 Int16GetDatum(attnum));
862 if (HeapTupleIsValid(tp))
864 Form_pg_attribute att_tup = (Form_pg_attribute) GETSTRUCT(tp);
867 result = att_tup->atttypmod;
878 * A two-fer: given the relation id and the attribute number,
879 * fetch both type OID and atttypmod in a single cache lookup.
881 * Unlike the otherwise-similar get_atttype/get_atttypmod, this routine
882 * raises an error if it can't obtain the information.
885 get_atttypetypmod(Oid relid, AttrNumber attnum,
886 Oid *typid, int32 *typmod)
889 Form_pg_attribute att_tup;
891 tp = SearchSysCache2(ATTNUM,
892 ObjectIdGetDatum(relid),
893 Int16GetDatum(attnum));
894 if (!HeapTupleIsValid(tp))
895 elog(ERROR, "cache lookup failed for attribute %d of relation %u",
897 att_tup = (Form_pg_attribute) GETSTRUCT(tp);
899 *typid = att_tup->atttypid;
900 *typmod = att_tup->atttypmod;
904 /* ---------- CONSTRAINT CACHE ---------- */
907 * get_constraint_name
908 * Returns the name of a given pg_constraint entry.
910 * Returns a palloc'd copy of the string, or NULL if no such constraint.
912 * NOTE: since constraint name is not unique, be wary of code that uses this
913 * for anything except preparing error messages.
916 get_constraint_name(Oid conoid)
920 tp = SearchSysCache1(CONSTROID, ObjectIdGetDatum(conoid));
921 if (HeapTupleIsValid(tp))
923 Form_pg_constraint contup = (Form_pg_constraint) GETSTRUCT(tp);
926 result = pstrdup(NameStr(contup->conname));
934 /* ---------- OPCLASS CACHE ---------- */
939 * Returns the OID of the operator family the opclass belongs to.
942 get_opclass_family(Oid opclass)
945 Form_pg_opclass cla_tup;
948 tp = SearchSysCache1(CLAOID, ObjectIdGetDatum(opclass));
949 if (!HeapTupleIsValid(tp))
950 elog(ERROR, "cache lookup failed for opclass %u", opclass);
951 cla_tup = (Form_pg_opclass) GETSTRUCT(tp);
953 result = cla_tup->opcfamily;
959 * get_opclass_input_type
961 * Returns the OID of the datatype the opclass indexes.
964 get_opclass_input_type(Oid opclass)
967 Form_pg_opclass cla_tup;
970 tp = SearchSysCache1(CLAOID, ObjectIdGetDatum(opclass));
971 if (!HeapTupleIsValid(tp))
972 elog(ERROR, "cache lookup failed for opclass %u", opclass);
973 cla_tup = (Form_pg_opclass) GETSTRUCT(tp);
975 result = cla_tup->opcintype;
980 /* ---------- OPERATOR CACHE ---------- */
985 * Returns the regproc id of the routine used to implement an
986 * operator given the operator oid.
993 tp = SearchSysCache1(OPEROID, ObjectIdGetDatum(opno));
994 if (HeapTupleIsValid(tp))
996 Form_pg_operator optup = (Form_pg_operator) GETSTRUCT(tp);
999 result = optup->oprcode;
1000 ReleaseSysCache(tp);
1004 return (RegProcedure) InvalidOid;
1009 * returns the name of the operator with the given opno
1011 * Note: returns a palloc'd copy of the string, or NULL if no such operator.
1014 get_opname(Oid opno)
1018 tp = SearchSysCache1(OPEROID, ObjectIdGetDatum(opno));
1019 if (HeapTupleIsValid(tp))
1021 Form_pg_operator optup = (Form_pg_operator) GETSTRUCT(tp);
1024 result = pstrdup(NameStr(optup->oprname));
1025 ReleaseSysCache(tp);
1035 * Returns the left and right input datatypes for an operator
1036 * (InvalidOid if not relevant).
1039 op_input_types(Oid opno, Oid *lefttype, Oid *righttype)
1042 Form_pg_operator optup;
1044 tp = SearchSysCache1(OPEROID, ObjectIdGetDatum(opno));
1045 if (!HeapTupleIsValid(tp)) /* shouldn't happen */
1046 elog(ERROR, "cache lookup failed for operator %u", opno);
1047 optup = (Form_pg_operator) GETSTRUCT(tp);
1048 *lefttype = optup->oprleft;
1049 *righttype = optup->oprright;
1050 ReleaseSysCache(tp);
1056 * Returns true if the operator is potentially mergejoinable. (The planner
1057 * will fail to find any mergejoin plans unless there are suitable btree
1058 * opfamily entries for this operator and associated sortops. The pg_operator
1059 * flag is just a hint to tell the planner whether to bother looking.)
1062 op_mergejoinable(Oid opno)
1065 bool result = false;
1067 tp = SearchSysCache1(OPEROID, ObjectIdGetDatum(opno));
1068 if (HeapTupleIsValid(tp))
1070 Form_pg_operator optup = (Form_pg_operator) GETSTRUCT(tp);
1072 result = optup->oprcanmerge;
1073 ReleaseSysCache(tp);
1081 * Returns true if the operator is hashjoinable. (There must be a suitable
1082 * hash opfamily entry for this operator if it is so marked.)
1085 op_hashjoinable(Oid opno)
1088 bool result = false;
1090 tp = SearchSysCache1(OPEROID, ObjectIdGetDatum(opno));
1091 if (HeapTupleIsValid(tp))
1093 Form_pg_operator optup = (Form_pg_operator) GETSTRUCT(tp);
1095 result = optup->oprcanhash;
1096 ReleaseSysCache(tp);
1104 * Get the proisstrict flag for the operator's underlying function.
1109 RegProcedure funcid = get_opcode(opno);
1111 if (funcid == (RegProcedure) InvalidOid)
1112 elog(ERROR, "operator %u does not exist", opno);
1114 return func_strict((Oid) funcid);
1120 * Get the provolatile flag for the operator's underlying function.
1123 op_volatile(Oid opno)
1125 RegProcedure funcid = get_opcode(opno);
1127 if (funcid == (RegProcedure) InvalidOid)
1128 elog(ERROR, "operator %u does not exist", opno);
1130 return func_volatile((Oid) funcid);
1136 * Returns the corresponding commutator of an operator.
1139 get_commutator(Oid opno)
1143 tp = SearchSysCache1(OPEROID, ObjectIdGetDatum(opno));
1144 if (HeapTupleIsValid(tp))
1146 Form_pg_operator optup = (Form_pg_operator) GETSTRUCT(tp);
1149 result = optup->oprcom;
1150 ReleaseSysCache(tp);
1160 * Returns the corresponding negator of an operator.
1163 get_negator(Oid opno)
1167 tp = SearchSysCache1(OPEROID, ObjectIdGetDatum(opno));
1168 if (HeapTupleIsValid(tp))
1170 Form_pg_operator optup = (Form_pg_operator) GETSTRUCT(tp);
1173 result = optup->oprnegate;
1174 ReleaseSysCache(tp);
1184 * Returns procedure id for computing selectivity of an operator.
1187 get_oprrest(Oid opno)
1191 tp = SearchSysCache1(OPEROID, ObjectIdGetDatum(opno));
1192 if (HeapTupleIsValid(tp))
1194 Form_pg_operator optup = (Form_pg_operator) GETSTRUCT(tp);
1195 RegProcedure result;
1197 result = optup->oprrest;
1198 ReleaseSysCache(tp);
1202 return (RegProcedure) InvalidOid;
1208 * Returns procedure id for computing selectivity of a join.
1211 get_oprjoin(Oid opno)
1215 tp = SearchSysCache1(OPEROID, ObjectIdGetDatum(opno));
1216 if (HeapTupleIsValid(tp))
1218 Form_pg_operator optup = (Form_pg_operator) GETSTRUCT(tp);
1219 RegProcedure result;
1221 result = optup->oprjoin;
1222 ReleaseSysCache(tp);
1226 return (RegProcedure) InvalidOid;
1229 /* ---------- FUNCTION CACHE ---------- */
1233 * returns the name of the function with the given funcid
1235 * Note: returns a palloc'd copy of the string, or NULL if no such function.
1238 get_func_name(Oid funcid)
1242 tp = SearchSysCache1(PROCOID, ObjectIdGetDatum(funcid));
1243 if (HeapTupleIsValid(tp))
1245 Form_pg_proc functup = (Form_pg_proc) GETSTRUCT(tp);
1248 result = pstrdup(NameStr(functup->proname));
1249 ReleaseSysCache(tp);
1257 * get_func_namespace
1259 * Returns the pg_namespace OID associated with a given function.
1262 get_func_namespace(Oid funcid)
1266 tp = SearchSysCache1(PROCOID, ObjectIdGetDatum(funcid));
1267 if (HeapTupleIsValid(tp))
1269 Form_pg_proc functup = (Form_pg_proc) GETSTRUCT(tp);
1272 result = functup->pronamespace;
1273 ReleaseSysCache(tp);
1282 * Given procedure id, return the function's result type.
1285 get_func_rettype(Oid funcid)
1290 tp = SearchSysCache1(PROCOID, ObjectIdGetDatum(funcid));
1291 if (!HeapTupleIsValid(tp))
1292 elog(ERROR, "cache lookup failed for function %u", funcid);
1294 result = ((Form_pg_proc) GETSTRUCT(tp))->prorettype;
1295 ReleaseSysCache(tp);
1301 * Given procedure id, return the number of arguments.
1304 get_func_nargs(Oid funcid)
1309 tp = SearchSysCache1(PROCOID, ObjectIdGetDatum(funcid));
1310 if (!HeapTupleIsValid(tp))
1311 elog(ERROR, "cache lookup failed for function %u", funcid);
1313 result = ((Form_pg_proc) GETSTRUCT(tp))->pronargs;
1314 ReleaseSysCache(tp);
1319 * get_func_signature
1320 * Given procedure id, return the function's argument and result types.
1321 * (The return value is the result type.)
1323 * The arguments are returned as a palloc'd array.
1326 get_func_signature(Oid funcid, Oid **argtypes, int *nargs)
1329 Form_pg_proc procstruct;
1332 tp = SearchSysCache1(PROCOID, ObjectIdGetDatum(funcid));
1333 if (!HeapTupleIsValid(tp))
1334 elog(ERROR, "cache lookup failed for function %u", funcid);
1336 procstruct = (Form_pg_proc) GETSTRUCT(tp);
1338 result = procstruct->prorettype;
1339 *nargs = (int) procstruct->pronargs;
1340 Assert(*nargs == procstruct->proargtypes.dim1);
1341 *argtypes = (Oid *) palloc(*nargs * sizeof(Oid));
1342 memcpy(*argtypes, procstruct->proargtypes.values, *nargs * sizeof(Oid));
1344 ReleaseSysCache(tp);
1350 * Given procedure id, return the function's proretset flag.
1353 get_func_retset(Oid funcid)
1358 tp = SearchSysCache1(PROCOID, ObjectIdGetDatum(funcid));
1359 if (!HeapTupleIsValid(tp))
1360 elog(ERROR, "cache lookup failed for function %u", funcid);
1362 result = ((Form_pg_proc) GETSTRUCT(tp))->proretset;
1363 ReleaseSysCache(tp);
1369 * Given procedure id, return the function's proisstrict flag.
1372 func_strict(Oid funcid)
1377 tp = SearchSysCache1(PROCOID, ObjectIdGetDatum(funcid));
1378 if (!HeapTupleIsValid(tp))
1379 elog(ERROR, "cache lookup failed for function %u", funcid);
1381 result = ((Form_pg_proc) GETSTRUCT(tp))->proisstrict;
1382 ReleaseSysCache(tp);
1388 * Given procedure id, return the function's provolatile flag.
1391 func_volatile(Oid funcid)
1396 tp = SearchSysCache1(PROCOID, ObjectIdGetDatum(funcid));
1397 if (!HeapTupleIsValid(tp))
1398 elog(ERROR, "cache lookup failed for function %u", funcid);
1400 result = ((Form_pg_proc) GETSTRUCT(tp))->provolatile;
1401 ReleaseSysCache(tp);
1407 * Given procedure id, return the function's procost field.
1410 get_func_cost(Oid funcid)
1415 if (get_func_cost_hook)
1417 result = (*get_func_cost_hook) (funcid);
1418 if (result > (float4) 0)
1421 tp = SearchSysCache1(PROCOID, ObjectIdGetDatum(funcid));
1422 if (!HeapTupleIsValid(tp))
1423 elog(ERROR, "cache lookup failed for function %u", funcid);
1425 result = ((Form_pg_proc) GETSTRUCT(tp))->procost;
1426 ReleaseSysCache(tp);
1432 * Given procedure id, return the function's prorows field.
1435 get_func_rows(Oid funcid)
1440 if (get_func_rows_hook)
1442 result = (*get_func_rows_hook) (funcid);
1443 if (result > (float4) 0)
1446 tp = SearchSysCache1(PROCOID, ObjectIdGetDatum(funcid));
1447 if (!HeapTupleIsValid(tp))
1448 elog(ERROR, "cache lookup failed for function %u", funcid);
1450 result = ((Form_pg_proc) GETSTRUCT(tp))->prorows;
1451 ReleaseSysCache(tp);
1455 /* ---------- RELATION CACHE ---------- */
1459 * Given name and namespace of a relation, look up the OID.
1461 * Returns InvalidOid if there is no such relation.
1464 get_relname_relid(const char *relname, Oid relnamespace)
1466 return GetSysCacheOid2(RELNAMENSP,
1467 PointerGetDatum(relname),
1468 ObjectIdGetDatum(relnamespace));
1475 * Returns the number of attributes for a given relation.
1478 get_relnatts(Oid relid)
1482 tp = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
1483 if (HeapTupleIsValid(tp))
1485 Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
1488 result = reltup->relnatts;
1489 ReleaseSysCache(tp);
1493 return InvalidAttrNumber;
1499 * Returns the name of a given relation.
1501 * Returns a palloc'd copy of the string, or NULL if no such relation.
1503 * NOTE: since relation name is not unique, be wary of code that uses this
1504 * for anything except preparing error messages.
1507 get_rel_name(Oid relid)
1511 tp = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
1512 if (HeapTupleIsValid(tp))
1514 Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
1517 result = pstrdup(NameStr(reltup->relname));
1518 ReleaseSysCache(tp);
1528 * Returns the pg_namespace OID associated with a given relation.
1531 get_rel_namespace(Oid relid)
1535 tp = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
1536 if (HeapTupleIsValid(tp))
1538 Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
1541 result = reltup->relnamespace;
1542 ReleaseSysCache(tp);
1552 * Returns the pg_type OID associated with a given relation.
1554 * Note: not all pg_class entries have associated pg_type OIDs; so be
1555 * careful to check for InvalidOid result.
1558 get_rel_type_id(Oid relid)
1562 tp = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
1563 if (HeapTupleIsValid(tp))
1565 Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
1568 result = reltup->reltype;
1569 ReleaseSysCache(tp);
1579 * Returns the relkind associated with a given relation.
1582 get_rel_relkind(Oid relid)
1586 tp = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
1587 if (HeapTupleIsValid(tp))
1589 Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
1592 result = reltup->relkind;
1593 ReleaseSysCache(tp);
1601 * get_rel_tablespace
1603 * Returns the pg_tablespace OID associated with a given relation.
1605 * Note: InvalidOid might mean either that we couldn't find the relation,
1606 * or that it is in the database's default tablespace.
1609 get_rel_tablespace(Oid relid)
1613 tp = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
1614 if (HeapTupleIsValid(tp))
1616 Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
1619 result = reltup->reltablespace;
1620 ReleaseSysCache(tp);
1628 /* ---------- TYPE CACHE ---------- */
1633 * Given the type OID, determine whether the type is defined
1634 * (if not, it's only a shell).
1637 get_typisdefined(Oid typid)
1641 tp = SearchSysCache1(TYPEOID, ObjectIdGetDatum(typid));
1642 if (HeapTupleIsValid(tp))
1644 Form_pg_type typtup = (Form_pg_type) GETSTRUCT(tp);
1647 result = typtup->typisdefined;
1648 ReleaseSysCache(tp);
1658 * Given the type OID, return the length of the type.
1661 get_typlen(Oid typid)
1665 tp = SearchSysCache1(TYPEOID, ObjectIdGetDatum(typid));
1666 if (HeapTupleIsValid(tp))
1668 Form_pg_type typtup = (Form_pg_type) GETSTRUCT(tp);
1671 result = typtup->typlen;
1672 ReleaseSysCache(tp);
1682 * Given the type OID, determine whether the type is returned by value or
1683 * not. Returns true if by value, false if by reference.
1686 get_typbyval(Oid typid)
1690 tp = SearchSysCache1(TYPEOID, ObjectIdGetDatum(typid));
1691 if (HeapTupleIsValid(tp))
1693 Form_pg_type typtup = (Form_pg_type) GETSTRUCT(tp);
1696 result = typtup->typbyval;
1697 ReleaseSysCache(tp);
1707 * A two-fer: given the type OID, return both typlen and typbyval.
1709 * Since both pieces of info are needed to know how to copy a Datum,
1710 * many places need both. Might as well get them with one cache lookup
1711 * instead of two. Also, this routine raises an error instead of
1712 * returning a bogus value when given a bad type OID.
1715 get_typlenbyval(Oid typid, int16 *typlen, bool *typbyval)
1718 Form_pg_type typtup;
1720 tp = SearchSysCache1(TYPEOID, ObjectIdGetDatum(typid));
1721 if (!HeapTupleIsValid(tp))
1722 elog(ERROR, "cache lookup failed for type %u", typid);
1723 typtup = (Form_pg_type) GETSTRUCT(tp);
1724 *typlen = typtup->typlen;
1725 *typbyval = typtup->typbyval;
1726 ReleaseSysCache(tp);
1730 * get_typlenbyvalalign
1732 * A three-fer: given the type OID, return typlen, typbyval, typalign.
1735 get_typlenbyvalalign(Oid typid, int16 *typlen, bool *typbyval,
1739 Form_pg_type typtup;
1741 tp = SearchSysCache1(TYPEOID, ObjectIdGetDatum(typid));
1742 if (!HeapTupleIsValid(tp))
1743 elog(ERROR, "cache lookup failed for type %u", typid);
1744 typtup = (Form_pg_type) GETSTRUCT(tp);
1745 *typlen = typtup->typlen;
1746 *typbyval = typtup->typbyval;
1747 *typalign = typtup->typalign;
1748 ReleaseSysCache(tp);
1753 * Given a pg_type row, select the type OID to pass to I/O functions
1755 * Formerly, all I/O functions were passed pg_type.typelem as their second
1756 * parameter, but we now have a more complex rule about what to pass.
1757 * This knowledge is intended to be centralized here --- direct references
1758 * to typelem elsewhere in the code are wrong, if they are associated with
1759 * I/O calls and not with actual subscripting operations! (But see
1760 * bootstrap.c's boot_get_type_io_data() if you need to change this.)
1762 * As of PostgreSQL 8.1, output functions receive only the value itself
1763 * and not any auxiliary parameters, so the name of this routine is now
1764 * a bit of a misnomer ... it should be getTypeInputParam.
1767 getTypeIOParam(HeapTuple typeTuple)
1769 Form_pg_type typeStruct = (Form_pg_type) GETSTRUCT(typeTuple);
1772 * Array types get their typelem as parameter; everybody else gets their
1773 * own type OID as parameter. (As of 8.2, domains must get their own OID
1774 * even if their base type is an array.)
1776 if (typeStruct->typtype == TYPTYPE_BASE && OidIsValid(typeStruct->typelem))
1777 return typeStruct->typelem;
1779 return HeapTupleGetOid(typeTuple);
1785 * A six-fer: given the type OID, return typlen, typbyval, typalign,
1786 * typdelim, typioparam, and IO function OID. The IO function
1787 * returned is controlled by IOFuncSelector
1790 get_type_io_data(Oid typid,
1791 IOFuncSelector which_func,
1799 HeapTuple typeTuple;
1800 Form_pg_type typeStruct;
1803 * In bootstrap mode, pass it off to bootstrap.c. This hack allows us to
1804 * use array_in and array_out during bootstrap.
1806 if (IsBootstrapProcessingMode())
1811 boot_get_type_io_data(typid,
1828 elog(ERROR, "binary I/O not supported during bootstrap");
1834 typeTuple = SearchSysCache1(TYPEOID, ObjectIdGetDatum(typid));
1835 if (!HeapTupleIsValid(typeTuple))
1836 elog(ERROR, "cache lookup failed for type %u", typid);
1837 typeStruct = (Form_pg_type) GETSTRUCT(typeTuple);
1839 *typlen = typeStruct->typlen;
1840 *typbyval = typeStruct->typbyval;
1841 *typalign = typeStruct->typalign;
1842 *typdelim = typeStruct->typdelim;
1843 *typioparam = getTypeIOParam(typeTuple);
1847 *func = typeStruct->typinput;
1850 *func = typeStruct->typoutput;
1852 case IOFunc_receive:
1853 *func = typeStruct->typreceive;
1856 *func = typeStruct->typsend;
1859 ReleaseSysCache(typeTuple);
1864 get_typalign(Oid typid)
1868 tp = SearchSysCache1(TYPEOID, ObjectIdGetDatum(typid));
1869 if (HeapTupleIsValid(tp))
1871 Form_pg_type typtup = (Form_pg_type) GETSTRUCT(tp);
1874 result = typtup->typalign;
1875 ReleaseSysCache(tp);
1884 get_typstorage(Oid typid)
1888 tp = SearchSysCache1(TYPEOID, ObjectIdGetDatum(typid));
1889 if (HeapTupleIsValid(tp))
1891 Form_pg_type typtup = (Form_pg_type) GETSTRUCT(tp);
1894 result = typtup->typstorage;
1895 ReleaseSysCache(tp);
1904 * Given a type OID, return the type's default value, if any.
1906 * The result is a palloc'd expression node tree, or NULL if there
1907 * is no defined default for the datatype.
1909 * NB: caller should be prepared to coerce result to correct datatype;
1910 * the returned expression tree might produce something of the wrong type.
1913 get_typdefault(Oid typid)
1915 HeapTuple typeTuple;
1921 typeTuple = SearchSysCache1(TYPEOID, ObjectIdGetDatum(typid));
1922 if (!HeapTupleIsValid(typeTuple))
1923 elog(ERROR, "cache lookup failed for type %u", typid);
1924 type = (Form_pg_type) GETSTRUCT(typeTuple);
1927 * typdefault and typdefaultbin are potentially null, so don't try to
1928 * access 'em as struct fields. Must do it the hard way with
1931 datum = SysCacheGetAttr(TYPEOID,
1933 Anum_pg_type_typdefaultbin,
1938 /* We have an expression default */
1939 expr = stringToNode(TextDatumGetCString(datum));
1943 /* Perhaps we have a plain literal default */
1944 datum = SysCacheGetAttr(TYPEOID,
1946 Anum_pg_type_typdefault,
1951 char *strDefaultVal;
1953 /* Convert text datum to C string */
1954 strDefaultVal = TextDatumGetCString(datum);
1955 /* Convert C string to a value of the given type */
1956 datum = OidInputFunctionCall(type->typinput, strDefaultVal,
1957 getTypeIOParam(typeTuple), -1);
1958 /* Build a Const node containing the value */
1959 expr = (Node *) makeConst(typid,
1965 pfree(strDefaultVal);
1974 ReleaseSysCache(typeTuple);
1981 * If the given type is a domain, return its base type;
1982 * otherwise return the type's own OID.
1985 getBaseType(Oid typid)
1989 return getBaseTypeAndTypmod(typid, &typmod);
1993 * getBaseTypeAndTypmod
1994 * If the given type is a domain, return its base type and typmod;
1995 * otherwise return the type's own OID, and leave *typmod unchanged.
1997 * Note that the "applied typmod" should be -1 for every domain level
1998 * above the bottommost; therefore, if the passed-in typid is indeed
1999 * a domain, *typmod should be -1.
2002 getBaseTypeAndTypmod(Oid typid, int32 *typmod)
2005 * We loop to find the bottom base type in a stack of domains.
2010 Form_pg_type typTup;
2012 tup = SearchSysCache1(TYPEOID, ObjectIdGetDatum(typid));
2013 if (!HeapTupleIsValid(tup))
2014 elog(ERROR, "cache lookup failed for type %u", typid);
2015 typTup = (Form_pg_type) GETSTRUCT(tup);
2016 if (typTup->typtype != TYPTYPE_DOMAIN)
2018 /* Not a domain, so done */
2019 ReleaseSysCache(tup);
2023 Assert(*typmod == -1);
2024 typid = typTup->typbasetype;
2025 *typmod = typTup->typtypmod;
2027 ReleaseSysCache(tup);
2036 * Given a type OID and a typmod value (pass -1 if typmod is unknown),
2037 * estimate the average width of values of the type. This is used by
2038 * the planner, which doesn't require absolutely correct results;
2039 * it's OK (and expected) to guess if we don't know for sure.
2042 get_typavgwidth(Oid typid, int32 typmod)
2044 int typlen = get_typlen(typid);
2048 * Easy if it's a fixed-width type
2054 * type_maximum_size knows the encoding of typmod for some datatypes;
2055 * don't duplicate that knowledge here.
2057 maxwidth = type_maximum_size(typid, typmod);
2061 * For BPCHAR, the max width is also the only width. Otherwise we
2062 * need to guess about the typical data width given the max. A sliding
2063 * scale for percentage of max width seems reasonable.
2065 if (typid == BPCHAROID)
2068 return maxwidth; /* assume full width */
2069 if (maxwidth < 1000)
2070 return 32 + (maxwidth - 32) / 2; /* assume 50% */
2073 * Beyond 1000, assume we're looking at something like
2074 * "varchar(10000)" where the limit isn't actually reached often, and
2075 * use a fixed estimate.
2077 return 32 + (1000 - 32) / 2;
2081 * Ooops, we have no idea ... wild guess time.
2089 * Given the type OID, find if it is a basic type, a complex type, etc.
2090 * It returns the null char if the cache lookup fails...
2093 get_typtype(Oid typid)
2097 tp = SearchSysCache1(TYPEOID, ObjectIdGetDatum(typid));
2098 if (HeapTupleIsValid(tp))
2100 Form_pg_type typtup = (Form_pg_type) GETSTRUCT(tp);
2103 result = typtup->typtype;
2104 ReleaseSysCache(tp);
2114 * Convenience function to determine whether a type OID represents
2115 * a "rowtype" type --- either RECORD or a named composite type.
2118 type_is_rowtype(Oid typid)
2120 return (typid == RECORDOID || get_typtype(typid) == TYPTYPE_COMPOSITE);
2125 * Returns true if the given type is an enum type.
2128 type_is_enum(Oid typid)
2130 return (get_typtype(typid) == TYPTYPE_ENUM);
2134 * get_type_category_preferred
2136 * Given the type OID, fetch its category and preferred-type status.
2137 * Throws error on failure.
2140 get_type_category_preferred(Oid typid, char *typcategory, bool *typispreferred)
2143 Form_pg_type typtup;
2145 tp = SearchSysCache1(TYPEOID, ObjectIdGetDatum(typid));
2146 if (!HeapTupleIsValid(tp))
2147 elog(ERROR, "cache lookup failed for type %u", typid);
2148 typtup = (Form_pg_type) GETSTRUCT(tp);
2149 *typcategory = typtup->typcategory;
2150 *typispreferred = typtup->typispreferred;
2151 ReleaseSysCache(tp);
2157 * Given the type OID, get the typrelid (InvalidOid if not a complex
2161 get_typ_typrelid(Oid typid)
2165 tp = SearchSysCache1(TYPEOID, ObjectIdGetDatum(typid));
2166 if (HeapTupleIsValid(tp))
2168 Form_pg_type typtup = (Form_pg_type) GETSTRUCT(tp);
2171 result = typtup->typrelid;
2172 ReleaseSysCache(tp);
2182 * Given the type OID, get the typelem (InvalidOid if not an array type).
2184 * NB: this only considers varlena arrays to be true arrays; InvalidOid is
2185 * returned if the input is a fixed-length array type.
2188 get_element_type(Oid typid)
2192 tp = SearchSysCache1(TYPEOID, ObjectIdGetDatum(typid));
2193 if (HeapTupleIsValid(tp))
2195 Form_pg_type typtup = (Form_pg_type) GETSTRUCT(tp);
2198 if (typtup->typlen == -1)
2199 result = typtup->typelem;
2201 result = InvalidOid;
2202 ReleaseSysCache(tp);
2212 * Given the type OID, get the corresponding "true" array type.
2213 * Returns InvalidOid if no array type can be found.
2216 get_array_type(Oid typid)
2219 Oid result = InvalidOid;
2221 tp = SearchSysCache1(TYPEOID, ObjectIdGetDatum(typid));
2222 if (HeapTupleIsValid(tp))
2224 result = ((Form_pg_type) GETSTRUCT(tp))->typarray;
2225 ReleaseSysCache(tp);
2233 * Get info needed for converting values of a type to internal form
2236 getTypeInputInfo(Oid type, Oid *typInput, Oid *typIOParam)
2238 HeapTuple typeTuple;
2241 typeTuple = SearchSysCache1(TYPEOID, ObjectIdGetDatum(type));
2242 if (!HeapTupleIsValid(typeTuple))
2243 elog(ERROR, "cache lookup failed for type %u", type);
2244 pt = (Form_pg_type) GETSTRUCT(typeTuple);
2246 if (!pt->typisdefined)
2248 (errcode(ERRCODE_UNDEFINED_OBJECT),
2249 errmsg("type %s is only a shell",
2250 format_type_be(type))));
2251 if (!OidIsValid(pt->typinput))
2253 (errcode(ERRCODE_UNDEFINED_FUNCTION),
2254 errmsg("no input function available for type %s",
2255 format_type_be(type))));
2257 *typInput = pt->typinput;
2258 *typIOParam = getTypeIOParam(typeTuple);
2260 ReleaseSysCache(typeTuple);
2266 * Get info needed for printing values of a type
2269 getTypeOutputInfo(Oid type, Oid *typOutput, bool *typIsVarlena)
2271 HeapTuple typeTuple;
2274 typeTuple = SearchSysCache1(TYPEOID, ObjectIdGetDatum(type));
2275 if (!HeapTupleIsValid(typeTuple))
2276 elog(ERROR, "cache lookup failed for type %u", type);
2277 pt = (Form_pg_type) GETSTRUCT(typeTuple);
2279 if (!pt->typisdefined)
2281 (errcode(ERRCODE_UNDEFINED_OBJECT),
2282 errmsg("type %s is only a shell",
2283 format_type_be(type))));
2284 if (!OidIsValid(pt->typoutput))
2286 (errcode(ERRCODE_UNDEFINED_FUNCTION),
2287 errmsg("no output function available for type %s",
2288 format_type_be(type))));
2290 *typOutput = pt->typoutput;
2291 *typIsVarlena = (!pt->typbyval) && (pt->typlen == -1);
2293 ReleaseSysCache(typeTuple);
2297 * getTypeBinaryInputInfo
2299 * Get info needed for binary input of values of a type
2302 getTypeBinaryInputInfo(Oid type, Oid *typReceive, Oid *typIOParam)
2304 HeapTuple typeTuple;
2307 typeTuple = SearchSysCache1(TYPEOID, ObjectIdGetDatum(type));
2308 if (!HeapTupleIsValid(typeTuple))
2309 elog(ERROR, "cache lookup failed for type %u", type);
2310 pt = (Form_pg_type) GETSTRUCT(typeTuple);
2312 if (!pt->typisdefined)
2314 (errcode(ERRCODE_UNDEFINED_OBJECT),
2315 errmsg("type %s is only a shell",
2316 format_type_be(type))));
2317 if (!OidIsValid(pt->typreceive))
2319 (errcode(ERRCODE_UNDEFINED_FUNCTION),
2320 errmsg("no binary input function available for type %s",
2321 format_type_be(type))));
2323 *typReceive = pt->typreceive;
2324 *typIOParam = getTypeIOParam(typeTuple);
2326 ReleaseSysCache(typeTuple);
2330 * getTypeBinaryOutputInfo
2332 * Get info needed for binary output of values of a type
2335 getTypeBinaryOutputInfo(Oid type, Oid *typSend, bool *typIsVarlena)
2337 HeapTuple typeTuple;
2340 typeTuple = SearchSysCache1(TYPEOID, ObjectIdGetDatum(type));
2341 if (!HeapTupleIsValid(typeTuple))
2342 elog(ERROR, "cache lookup failed for type %u", type);
2343 pt = (Form_pg_type) GETSTRUCT(typeTuple);
2345 if (!pt->typisdefined)
2347 (errcode(ERRCODE_UNDEFINED_OBJECT),
2348 errmsg("type %s is only a shell",
2349 format_type_be(type))));
2350 if (!OidIsValid(pt->typsend))
2352 (errcode(ERRCODE_UNDEFINED_FUNCTION),
2353 errmsg("no binary output function available for type %s",
2354 format_type_be(type))));
2356 *typSend = pt->typsend;
2357 *typIsVarlena = (!pt->typbyval) && (pt->typlen == -1);
2359 ReleaseSysCache(typeTuple);
2365 * Given the type OID, return the type's typmodin procedure, if any.
2368 get_typmodin(Oid typid)
2372 tp = SearchSysCache1(TYPEOID, ObjectIdGetDatum(typid));
2373 if (HeapTupleIsValid(tp))
2375 Form_pg_type typtup = (Form_pg_type) GETSTRUCT(tp);
2378 result = typtup->typmodin;
2379 ReleaseSysCache(tp);
2390 * Given the type OID, return the type's typmodout procedure, if any.
2393 get_typmodout(Oid typid)
2397 tp = SearchSysCache1(TYPEOID, ObjectIdGetDatum(typid));
2398 if (HeapTupleIsValid(tp))
2400 Form_pg_type typtup = (Form_pg_type) GETSTRUCT(tp);
2403 result = typtup->typmodout;
2404 ReleaseSysCache(tp);
2410 #endif /* NOT_USED */
2413 /* ---------- STATISTICS CACHE ---------- */
2418 * Given the table and attribute number of a column, get the average
2419 * width of entries in the column. Return zero if no data available.
2421 * Currently this is only consulted for individual tables, not for inheritance
2422 * trees, so we don't need an "inh" parameter.
2424 * Calling a hook at this point looks somewhat strange, but is required
2425 * because the optimizer calls this function without any other way for
2426 * plug-ins to control the result.
2429 get_attavgwidth(Oid relid, AttrNumber attnum)
2434 if (get_attavgwidth_hook)
2436 stawidth = (*get_attavgwidth_hook) (relid, attnum);
2440 tp = SearchSysCache3(STATRELATTINH,
2441 ObjectIdGetDatum(relid),
2442 Int16GetDatum(attnum),
2443 BoolGetDatum(false));
2444 if (HeapTupleIsValid(tp))
2446 stawidth = ((Form_pg_statistic) GETSTRUCT(tp))->stawidth;
2447 ReleaseSysCache(tp);
2457 * Extract the contents of a "slot" of a pg_statistic tuple.
2458 * Returns TRUE if requested slot type was found, else FALSE.
2460 * Unlike other routines in this file, this takes a pointer to an
2461 * already-looked-up tuple in the pg_statistic cache. We do this since
2462 * most callers will want to extract more than one value from the cache
2463 * entry, and we don't want to repeat the cache lookup unnecessarily.
2464 * Also, this API allows this routine to be used with statistics tuples
2465 * that have been provided by a stats hook and didn't really come from
2468 * statstuple: pg_statistics tuple to be examined.
2469 * atttype: type OID of attribute (can be InvalidOid if values == NULL).
2470 * atttypmod: typmod of attribute (can be 0 if values == NULL).
2471 * reqkind: STAKIND code for desired statistics slot kind.
2472 * reqop: STAOP value wanted, or InvalidOid if don't care.
2473 * actualop: if not NULL, *actualop receives the actual STAOP value.
2474 * values, nvalues: if not NULL, the slot's stavalues are extracted.
2475 * numbers, nnumbers: if not NULL, the slot's stanumbers are extracted.
2477 * If assigned, values and numbers are set to point to palloc'd arrays.
2478 * If the attribute type is pass-by-reference, the values referenced by
2479 * the values array are themselves palloc'd. The palloc'd stuff can be
2480 * freed by calling free_attstatsslot.
2483 get_attstatsslot(HeapTuple statstuple,
2484 Oid atttype, int32 atttypmod,
2485 int reqkind, Oid reqop,
2487 Datum **values, int *nvalues,
2488 float4 **numbers, int *nnumbers)
2490 Form_pg_statistic stats = (Form_pg_statistic) GETSTRUCT(statstuple);
2495 ArrayType *statarray;
2497 HeapTuple typeTuple;
2498 Form_pg_type typeForm;
2500 for (i = 0; i < STATISTIC_NUM_SLOTS; i++)
2502 if ((&stats->stakind1)[i] == reqkind &&
2503 (reqop == InvalidOid || (&stats->staop1)[i] == reqop))
2506 if (i >= STATISTIC_NUM_SLOTS)
2507 return false; /* not there */
2510 *actualop = (&stats->staop1)[i];
2514 val = SysCacheGetAttr(STATRELATTINH, statstuple,
2515 Anum_pg_statistic_stavalues1 + i,
2518 elog(ERROR, "stavalues is null");
2519 statarray = DatumGetArrayTypeP(val);
2521 /* Need to get info about the array element type */
2522 typeTuple = SearchSysCache1(TYPEOID, ObjectIdGetDatum(atttype));
2523 if (!HeapTupleIsValid(typeTuple))
2524 elog(ERROR, "cache lookup failed for type %u", atttype);
2525 typeForm = (Form_pg_type) GETSTRUCT(typeTuple);
2527 /* Deconstruct array into Datum elements; NULLs not expected */
2528 deconstruct_array(statarray,
2533 values, NULL, nvalues);
2536 * If the element type is pass-by-reference, we now have a bunch of
2537 * Datums that are pointers into the syscache value. Copy them to
2538 * avoid problems if syscache decides to drop the entry.
2540 if (!typeForm->typbyval)
2542 for (j = 0; j < *nvalues; j++)
2544 (*values)[j] = datumCopy((*values)[j],
2550 ReleaseSysCache(typeTuple);
2553 * Free statarray if it's a detoasted copy.
2555 if ((Pointer) statarray != DatumGetPointer(val))
2561 val = SysCacheGetAttr(STATRELATTINH, statstuple,
2562 Anum_pg_statistic_stanumbers1 + i,
2565 elog(ERROR, "stanumbers is null");
2566 statarray = DatumGetArrayTypeP(val);
2569 * We expect the array to be a 1-D float4 array; verify that. We don't
2570 * need to use deconstruct_array() since the array data is just going
2571 * to look like a C array of float4 values.
2573 narrayelem = ARR_DIMS(statarray)[0];
2574 if (ARR_NDIM(statarray) != 1 || narrayelem <= 0 ||
2575 ARR_HASNULL(statarray) ||
2576 ARR_ELEMTYPE(statarray) != FLOAT4OID)
2577 elog(ERROR, "stanumbers is not a 1-D float4 array");
2578 *numbers = (float4 *) palloc(narrayelem * sizeof(float4));
2579 memcpy(*numbers, ARR_DATA_PTR(statarray), narrayelem * sizeof(float4));
2580 *nnumbers = narrayelem;
2583 * Free statarray if it's a detoasted copy.
2585 if ((Pointer) statarray != DatumGetPointer(val))
2594 * Free data allocated by get_attstatsslot
2596 * atttype need be valid only if values != NULL.
2599 free_attstatsslot(Oid atttype,
2600 Datum *values, int nvalues,
2601 float4 *numbers, int nnumbers)
2605 if (!get_typbyval(atttype))
2609 for (i = 0; i < nvalues; i++)
2610 pfree(DatumGetPointer(values[i]));
2618 /* ---------- PG_NAMESPACE CACHE ---------- */
2621 * get_namespace_name
2622 * Returns the name of a given namespace
2624 * Returns a palloc'd copy of the string, or NULL if no such namespace.
2627 get_namespace_name(Oid nspid)
2631 tp = SearchSysCache1(NAMESPACEOID, ObjectIdGetDatum(nspid));
2632 if (HeapTupleIsValid(tp))
2634 Form_pg_namespace nsptup = (Form_pg_namespace) GETSTRUCT(tp);
2637 result = pstrdup(NameStr(nsptup->nspname));
2638 ReleaseSysCache(tp);
2645 /* ---------- PG_AUTHID CACHE ---------- */
2649 * Given a role name, look up the role's OID.
2650 * Returns InvalidOid if no such role.
2653 get_roleid(const char *rolname)
2655 return GetSysCacheOid1(AUTHNAME, PointerGetDatum(rolname));
2659 * get_roleid_checked
2660 * Given a role name, look up the role's OID.
2661 * ereports if no such role.
2664 get_roleid_checked(const char *rolname)
2668 roleid = get_roleid(rolname);
2669 if (!OidIsValid(roleid))
2671 (errcode(ERRCODE_UNDEFINED_OBJECT),
2672 errmsg("role \"%s\" does not exist", rolname)));