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/lsyscache.h"
37 #include "utils/syscache.h"
38 #include "utils/typcache.h"
40 /* Hook for plugins to get control in get_attavgwidth() */
41 get_attavgwidth_hook_type get_attavgwidth_hook = NULL;
44 /* ---------- AMOP CACHES ---------- */
49 * Return t iff operator 'opno' is in operator family 'opfamily'.
51 * This function only considers search operators, not ordering operators.
54 op_in_opfamily(Oid opno, Oid opfamily)
56 return SearchSysCacheExists3(AMOPOPID,
57 ObjectIdGetDatum(opno),
58 CharGetDatum(AMOP_SEARCH),
59 ObjectIdGetDatum(opfamily));
63 * get_op_opfamily_strategy
65 * Get the operator's strategy number within the specified opfamily,
66 * or 0 if it's not a member of the opfamily.
68 * This function only considers search operators, not ordering operators.
71 get_op_opfamily_strategy(Oid opno, Oid opfamily)
74 Form_pg_amop amop_tup;
77 tp = SearchSysCache3(AMOPOPID,
78 ObjectIdGetDatum(opno),
79 CharGetDatum(AMOP_SEARCH),
80 ObjectIdGetDatum(opfamily));
81 if (!HeapTupleIsValid(tp))
83 amop_tup = (Form_pg_amop) GETSTRUCT(tp);
84 result = amop_tup->amopstrategy;
90 * get_op_opfamily_sortfamily
92 * If the operator is an ordering operator within the specified opfamily,
93 * return its amopsortfamily OID; else return InvalidOid.
96 get_op_opfamily_sortfamily(Oid opno, Oid opfamily)
99 Form_pg_amop amop_tup;
102 tp = SearchSysCache3(AMOPOPID,
103 ObjectIdGetDatum(opno),
104 CharGetDatum(AMOP_ORDER),
105 ObjectIdGetDatum(opfamily));
106 if (!HeapTupleIsValid(tp))
108 amop_tup = (Form_pg_amop) GETSTRUCT(tp);
109 result = amop_tup->amopsortfamily;
115 * get_op_opfamily_properties
117 * Get the operator's strategy number and declared input data types
118 * within the specified opfamily.
120 * Caller should already have verified that opno is a member of opfamily,
121 * therefore we raise an error if the tuple is not found.
124 get_op_opfamily_properties(Oid opno, Oid opfamily, bool ordering_op,
130 Form_pg_amop amop_tup;
132 tp = SearchSysCache3(AMOPOPID,
133 ObjectIdGetDatum(opno),
134 CharGetDatum(ordering_op ? AMOP_ORDER : AMOP_SEARCH),
135 ObjectIdGetDatum(opfamily));
136 if (!HeapTupleIsValid(tp))
137 elog(ERROR, "operator %u is not a member of opfamily %u",
139 amop_tup = (Form_pg_amop) GETSTRUCT(tp);
140 *strategy = amop_tup->amopstrategy;
141 *lefttype = amop_tup->amoplefttype;
142 *righttype = amop_tup->amoprighttype;
147 * get_opfamily_member
148 * Get the OID of the operator that implements the specified strategy
149 * with the specified datatypes for the specified opfamily.
151 * Returns InvalidOid if there is no pg_amop entry for the given keys.
154 get_opfamily_member(Oid opfamily, Oid lefttype, Oid righttype,
158 Form_pg_amop amop_tup;
161 tp = SearchSysCache4(AMOPSTRATEGY,
162 ObjectIdGetDatum(opfamily),
163 ObjectIdGetDatum(lefttype),
164 ObjectIdGetDatum(righttype),
165 Int16GetDatum(strategy));
166 if (!HeapTupleIsValid(tp))
168 amop_tup = (Form_pg_amop) GETSTRUCT(tp);
169 result = amop_tup->amopopr;
175 * get_ordering_op_properties
176 * Given the OID of an ordering operator (a btree "<" or ">" operator),
177 * determine its opfamily, its declared input datatype, and its
178 * strategy number (BTLessStrategyNumber or BTGreaterStrategyNumber).
180 * Returns TRUE if successful, FALSE if no matching pg_amop entry exists.
181 * (This indicates that the operator is not a valid ordering operator.)
183 * Note: the operator could be registered in multiple families, for example
184 * if someone were to build a "reverse sort" opfamily. This would result in
185 * uncertainty as to whether "ORDER BY USING op" would default to NULLS FIRST
186 * or NULLS LAST, as well as inefficient planning due to failure to match up
187 * pathkeys that should be the same. So we want a determinate result here.
188 * Because of the way the syscache search works, we'll use the interpretation
189 * associated with the opfamily with smallest OID, which is probably
190 * determinate enough. Since there is no longer any particularly good reason
191 * to build reverse-sort opfamilies, it doesn't seem worth expending any
192 * additional effort on ensuring consistency.
195 get_ordering_op_properties(Oid opno,
196 Oid *opfamily, Oid *opcintype, int16 *strategy)
202 /* ensure outputs are initialized on failure */
203 *opfamily = InvalidOid;
204 *opcintype = InvalidOid;
208 * Search pg_amop to see if the target operator is registered as the "<"
209 * or ">" operator of any btree opfamily.
211 catlist = SearchSysCacheList1(AMOPOPID, ObjectIdGetDatum(opno));
213 for (i = 0; i < catlist->n_members; i++)
215 HeapTuple tuple = &catlist->members[i]->tuple;
216 Form_pg_amop aform = (Form_pg_amop) GETSTRUCT(tuple);
219 if (aform->amopmethod != BTREE_AM_OID)
222 if (aform->amopstrategy == BTLessStrategyNumber ||
223 aform->amopstrategy == BTGreaterStrategyNumber)
225 /* Found it ... should have consistent input types */
226 if (aform->amoplefttype == aform->amoprighttype)
228 /* Found a suitable opfamily, return info */
229 *opfamily = aform->amopfamily;
230 *opcintype = aform->amoplefttype;
231 *strategy = aform->amopstrategy;
238 ReleaseSysCacheList(catlist);
244 * get_compare_function_for_ordering_op
245 * Get the OID of the datatype-specific btree comparison function
246 * associated with an ordering operator (a "<" or ">" operator).
248 * *cmpfunc receives the comparison function OID.
249 * *reverse is set FALSE if the operator is "<", TRUE if it's ">"
250 * (indicating the comparison result must be negated before use).
252 * Returns TRUE if successful, FALSE if no btree function can be found.
253 * (This indicates that the operator is not a valid ordering operator.)
256 get_compare_function_for_ordering_op(Oid opno, Oid *cmpfunc, bool *reverse)
262 /* Find the operator in pg_amop */
263 if (get_ordering_op_properties(opno,
264 &opfamily, &opcintype, &strategy))
266 /* Found a suitable opfamily, get matching support function */
267 *cmpfunc = get_opfamily_proc(opfamily,
272 if (!OidIsValid(*cmpfunc)) /* should not happen */
273 elog(ERROR, "missing support function %d(%u,%u) in opfamily %u",
274 BTORDER_PROC, opcintype, opcintype, opfamily);
275 *reverse = (strategy == BTGreaterStrategyNumber);
279 /* ensure outputs are set on failure */
280 *cmpfunc = InvalidOid;
287 * get_equality_op_for_ordering_op
288 * Get the OID of the datatype-specific btree equality operator
289 * associated with an ordering operator (a "<" or ">" operator).
291 * If "reverse" isn't NULL, also set *reverse to FALSE if the operator is "<",
294 * Returns InvalidOid if no matching equality operator can be found.
295 * (This indicates that the operator is not a valid ordering operator.)
298 get_equality_op_for_ordering_op(Oid opno, bool *reverse)
300 Oid result = InvalidOid;
305 /* Find the operator in pg_amop */
306 if (get_ordering_op_properties(opno,
307 &opfamily, &opcintype, &strategy))
309 /* Found a suitable opfamily, get matching equality operator */
310 result = get_opfamily_member(opfamily,
313 BTEqualStrategyNumber);
315 *reverse = (strategy == BTGreaterStrategyNumber);
322 * get_ordering_op_for_equality_op
323 * Get the OID of a datatype-specific btree ordering operator
324 * associated with an equality operator. (If there are multiple
325 * possibilities, assume any one will do.)
327 * This function is used when we have to sort data before unique-ifying,
328 * and don't much care which sorting op is used as long as it's compatible
329 * with the intended equality operator. Since we need a sorting operator,
330 * it should be single-data-type even if the given operator is cross-type.
331 * The caller specifies whether to find an op for the LHS or RHS data type.
333 * Returns InvalidOid if no matching ordering operator can be found.
336 get_ordering_op_for_equality_op(Oid opno, bool use_lhs_type)
338 Oid result = InvalidOid;
343 * Search pg_amop to see if the target operator is registered as the "="
344 * operator of any btree opfamily.
346 catlist = SearchSysCacheList1(AMOPOPID, ObjectIdGetDatum(opno));
348 for (i = 0; i < catlist->n_members; i++)
350 HeapTuple tuple = &catlist->members[i]->tuple;
351 Form_pg_amop aform = (Form_pg_amop) GETSTRUCT(tuple);
354 if (aform->amopmethod != BTREE_AM_OID)
357 if (aform->amopstrategy == BTEqualStrategyNumber)
359 /* Found a suitable opfamily, get matching ordering operator */
362 typid = use_lhs_type ? aform->amoplefttype : aform->amoprighttype;
363 result = get_opfamily_member(aform->amopfamily,
365 BTLessStrategyNumber);
366 if (OidIsValid(result))
368 /* failure probably shouldn't happen, but keep looking if so */
372 ReleaseSysCacheList(catlist);
378 * get_mergejoin_opfamilies
379 * Given a putatively mergejoinable operator, return a list of the OIDs
380 * of the btree opfamilies in which it represents equality.
382 * It is possible (though at present unusual) for an operator to be equality
383 * in more than one opfamily, hence the result is a list. This also lets us
384 * return NIL if the operator is not found in any opfamilies.
386 * The planner currently uses simple equal() tests to compare the lists
387 * returned by this function, which makes the list order relevant, though
388 * strictly speaking it should not be. Because of the way syscache list
389 * searches are handled, in normal operation the result will be sorted by OID
390 * so everything works fine. If running with system index usage disabled,
391 * the result ordering is unspecified and hence the planner might fail to
392 * recognize optimization opportunities ... but that's hardly a scenario in
393 * which performance is good anyway, so there's no point in expending code
394 * or cycles here to guarantee the ordering in that case.
397 get_mergejoin_opfamilies(Oid opno)
404 * Search pg_amop to see if the target operator is registered as the "="
405 * operator of any btree opfamily.
407 catlist = SearchSysCacheList1(AMOPOPID, ObjectIdGetDatum(opno));
409 for (i = 0; i < catlist->n_members; i++)
411 HeapTuple tuple = &catlist->members[i]->tuple;
412 Form_pg_amop aform = (Form_pg_amop) GETSTRUCT(tuple);
414 /* must be btree equality */
415 if (aform->amopmethod == BTREE_AM_OID &&
416 aform->amopstrategy == BTEqualStrategyNumber)
417 result = lappend_oid(result, aform->amopfamily);
420 ReleaseSysCacheList(catlist);
426 * get_compatible_hash_operators
427 * Get the OID(s) of hash equality operator(s) compatible with the given
428 * operator, but operating on its LHS and/or RHS datatype.
430 * An operator for the LHS type is sought and returned into *lhs_opno if
431 * lhs_opno isn't NULL. Similarly, an operator for the RHS type is sought
432 * and returned into *rhs_opno if rhs_opno isn't NULL.
434 * If the given operator is not cross-type, the results should be the same
435 * operator, but in cross-type situations they will be different.
437 * Returns true if able to find the requested operator(s), false if not.
438 * (This indicates that the operator should not have been marked oprcanhash.)
441 get_compatible_hash_operators(Oid opno,
442 Oid *lhs_opno, Oid *rhs_opno)
448 /* Ensure output args are initialized on failure */
450 *lhs_opno = InvalidOid;
452 *rhs_opno = InvalidOid;
455 * Search pg_amop to see if the target operator is registered as the "="
456 * operator of any hash opfamily. If the operator is registered in
457 * multiple opfamilies, assume we can use any one.
459 catlist = SearchSysCacheList1(AMOPOPID, ObjectIdGetDatum(opno));
461 for (i = 0; i < catlist->n_members; i++)
463 HeapTuple tuple = &catlist->members[i]->tuple;
464 Form_pg_amop aform = (Form_pg_amop) GETSTRUCT(tuple);
466 if (aform->amopmethod == HASH_AM_OID &&
467 aform->amopstrategy == HTEqualStrategyNumber)
469 /* No extra lookup needed if given operator is single-type */
470 if (aform->amoplefttype == aform->amoprighttype)
481 * Get the matching single-type operator(s). Failure probably
482 * shouldn't happen --- it implies a bogus opfamily --- but
483 * continue looking if so.
487 *lhs_opno = get_opfamily_member(aform->amopfamily,
490 HTEqualStrategyNumber);
491 if (!OidIsValid(*lhs_opno))
493 /* Matching LHS found, done if caller doesn't want RHS */
502 *rhs_opno = get_opfamily_member(aform->amopfamily,
503 aform->amoprighttype,
504 aform->amoprighttype,
505 HTEqualStrategyNumber);
506 if (!OidIsValid(*rhs_opno))
508 /* Forget any LHS operator from this opfamily */
510 *lhs_opno = InvalidOid;
513 /* Matching RHS found, so done */
520 ReleaseSysCacheList(catlist);
526 * get_op_hash_functions
527 * Get the OID(s) of hash support function(s) compatible with the given
528 * operator, operating on its LHS and/or RHS datatype as required.
530 * A function for the LHS type is sought and returned into *lhs_procno if
531 * lhs_procno isn't NULL. Similarly, a function for the RHS type is sought
532 * and returned into *rhs_procno if rhs_procno isn't NULL.
534 * If the given operator is not cross-type, the results should be the same
535 * function, but in cross-type situations they will be different.
537 * Returns true if able to find the requested function(s), false if not.
538 * (This indicates that the operator should not have been marked oprcanhash.)
541 get_op_hash_functions(Oid opno,
542 RegProcedure *lhs_procno, RegProcedure *rhs_procno)
548 /* Ensure output args are initialized on failure */
550 *lhs_procno = InvalidOid;
552 *rhs_procno = InvalidOid;
555 * Search pg_amop to see if the target operator is registered as the "="
556 * operator of any hash opfamily. If the operator is registered in
557 * multiple opfamilies, assume we can use any one.
559 catlist = SearchSysCacheList1(AMOPOPID, ObjectIdGetDatum(opno));
561 for (i = 0; i < catlist->n_members; i++)
563 HeapTuple tuple = &catlist->members[i]->tuple;
564 Form_pg_amop aform = (Form_pg_amop) GETSTRUCT(tuple);
566 if (aform->amopmethod == HASH_AM_OID &&
567 aform->amopstrategy == HTEqualStrategyNumber)
570 * Get the matching support function(s). Failure probably
571 * shouldn't happen --- it implies a bogus opfamily --- but
572 * continue looking if so.
576 *lhs_procno = get_opfamily_proc(aform->amopfamily,
580 if (!OidIsValid(*lhs_procno))
582 /* Matching LHS found, done if caller doesn't want RHS */
588 /* Only one lookup needed if given operator is single-type */
589 if (aform->amoplefttype == aform->amoprighttype)
591 *rhs_procno = *lhs_procno;
598 *rhs_procno = get_opfamily_proc(aform->amopfamily,
599 aform->amoprighttype,
600 aform->amoprighttype,
602 if (!OidIsValid(*rhs_procno))
604 /* Forget any LHS function from this opfamily */
606 *lhs_procno = InvalidOid;
609 /* Matching RHS found, so done */
616 ReleaseSysCacheList(catlist);
622 * get_op_btree_interpretation
623 * Given an operator's OID, find out which btree opfamilies it belongs to,
624 * and what strategy number it has within each one. The results are
625 * returned as an OID list and a parallel integer list.
627 * In addition to the normal btree operators, we consider a <> operator to be
628 * a "member" of an opfamily if its negator is an equality operator of the
629 * opfamily. ROWCOMPARE_NE is returned as the strategy number for this case.
632 get_op_btree_interpretation(Oid opno, List **opfamilies, List **opstrats)
642 * Find all the pg_amop entries containing the operator.
644 catlist = SearchSysCacheList1(AMOPOPID, ObjectIdGetDatum(opno));
647 * If we can't find any opfamily containing the op, perhaps it is a <>
648 * operator. See if it has a negator that is in an opfamily.
651 if (catlist->n_members == 0)
653 Oid op_negator = get_negator(opno);
655 if (OidIsValid(op_negator))
658 ReleaseSysCacheList(catlist);
659 catlist = SearchSysCacheList1(AMOPOPID,
660 ObjectIdGetDatum(op_negator));
664 /* Now search the opfamilies */
665 for (i = 0; i < catlist->n_members; i++)
667 HeapTuple op_tuple = &catlist->members[i]->tuple;
668 Form_pg_amop op_form = (Form_pg_amop) GETSTRUCT(op_tuple);
670 StrategyNumber op_strategy;
673 if (op_form->amopmethod != BTREE_AM_OID)
676 /* Get the operator's btree strategy number */
677 opfamily_id = op_form->amopfamily;
678 op_strategy = (StrategyNumber) op_form->amopstrategy;
679 Assert(op_strategy >= 1 && op_strategy <= 5);
683 /* Only consider negators that are = */
684 if (op_strategy != BTEqualStrategyNumber)
686 op_strategy = ROWCOMPARE_NE;
689 *opfamilies = lappend_oid(*opfamilies, opfamily_id);
690 *opstrats = lappend_int(*opstrats, op_strategy);
693 ReleaseSysCacheList(catlist);
697 * equality_ops_are_compatible
698 * Return TRUE if the two given equality operators have compatible
701 * This is trivially true if they are the same operator. Otherwise,
702 * we look to see if they can be found in the same btree or hash opfamily.
703 * Either finding allows us to assume that they have compatible notions
704 * of equality. (The reason we need to do these pushups is that one might
705 * be a cross-type operator; for instance int24eq vs int4eq.)
708 equality_ops_are_compatible(Oid opno1, Oid opno2)
714 /* Easy if they're the same operator */
719 * We search through all the pg_amop entries for opno1.
721 catlist = SearchSysCacheList1(AMOPOPID, ObjectIdGetDatum(opno1));
724 for (i = 0; i < catlist->n_members; i++)
726 HeapTuple op_tuple = &catlist->members[i]->tuple;
727 Form_pg_amop op_form = (Form_pg_amop) GETSTRUCT(op_tuple);
729 /* must be btree or hash */
730 if (op_form->amopmethod == BTREE_AM_OID ||
731 op_form->amopmethod == HASH_AM_OID)
733 if (op_in_opfamily(opno2, op_form->amopfamily))
741 ReleaseSysCacheList(catlist);
747 /* ---------- AMPROC CACHES ---------- */
751 * Get the OID of the specified support function
752 * for the specified opfamily and datatypes.
754 * Returns InvalidOid if there is no pg_amproc entry for the given keys.
757 get_opfamily_proc(Oid opfamily, Oid lefttype, Oid righttype, int16 procnum)
760 Form_pg_amproc amproc_tup;
763 tp = SearchSysCache4(AMPROCNUM,
764 ObjectIdGetDatum(opfamily),
765 ObjectIdGetDatum(lefttype),
766 ObjectIdGetDatum(righttype),
767 Int16GetDatum(procnum));
768 if (!HeapTupleIsValid(tp))
770 amproc_tup = (Form_pg_amproc) GETSTRUCT(tp);
771 result = amproc_tup->amproc;
777 /* ---------- ATTRIBUTE CACHES ---------- */
781 * Given the relation id and the attribute number,
782 * return the "attname" field from the attribute relation.
784 * Note: returns a palloc'd copy of the string, or NULL if no such attribute.
787 get_attname(Oid relid, AttrNumber attnum)
791 tp = SearchSysCache2(ATTNUM,
792 ObjectIdGetDatum(relid),
793 Int16GetDatum(attnum));
794 if (HeapTupleIsValid(tp))
796 Form_pg_attribute att_tup = (Form_pg_attribute) GETSTRUCT(tp);
799 result = pstrdup(NameStr(att_tup->attname));
808 * get_relid_attribute_name
810 * Same as above routine get_attname(), except that error
811 * is handled by elog() instead of returning NULL.
814 get_relid_attribute_name(Oid relid, AttrNumber attnum)
818 attname = get_attname(relid, attnum);
820 elog(ERROR, "cache lookup failed for attribute %d of relation %u",
828 * Given the relation id and the attribute name,
829 * return the "attnum" field from the attribute relation.
831 * Returns InvalidAttrNumber if the attr doesn't exist (or is dropped).
834 get_attnum(Oid relid, const char *attname)
838 tp = SearchSysCacheAttName(relid, attname);
839 if (HeapTupleIsValid(tp))
841 Form_pg_attribute att_tup = (Form_pg_attribute) GETSTRUCT(tp);
844 result = att_tup->attnum;
849 return InvalidAttrNumber;
855 * Given the relation OID and the attribute number with the relation,
856 * return the attribute type OID.
859 get_atttype(Oid relid, AttrNumber attnum)
863 tp = SearchSysCache2(ATTNUM,
864 ObjectIdGetDatum(relid),
865 Int16GetDatum(attnum));
866 if (HeapTupleIsValid(tp))
868 Form_pg_attribute att_tup = (Form_pg_attribute) GETSTRUCT(tp);
871 result = att_tup->atttypid;
882 * Given the relation id and the attribute number,
883 * return the "atttypmod" field from the attribute relation.
886 get_atttypmod(Oid relid, AttrNumber attnum)
890 tp = SearchSysCache2(ATTNUM,
891 ObjectIdGetDatum(relid),
892 Int16GetDatum(attnum));
893 if (HeapTupleIsValid(tp))
895 Form_pg_attribute att_tup = (Form_pg_attribute) GETSTRUCT(tp);
898 result = att_tup->atttypmod;
909 * Given the relation id and the attribute number,
910 * return the "attcollation" field from the attribute relation.
913 get_attcollation(Oid relid, AttrNumber attnum)
917 tp = SearchSysCache2(ATTNUM,
918 ObjectIdGetDatum(relid),
919 Int16GetDatum(attnum));
920 if (HeapTupleIsValid(tp))
922 Form_pg_attribute att_tup = (Form_pg_attribute) GETSTRUCT(tp);
925 result = att_tup->attcollation;
936 * A two-fer: given the relation id and the attribute number,
937 * fetch both type OID and atttypmod in a single cache lookup.
939 * Unlike the otherwise-similar get_atttype/get_atttypmod, this routine
940 * raises an error if it can't obtain the information.
943 get_atttypetypmod(Oid relid, AttrNumber attnum,
944 Oid *typid, int32 *typmod)
947 Form_pg_attribute att_tup;
949 tp = SearchSysCache2(ATTNUM,
950 ObjectIdGetDatum(relid),
951 Int16GetDatum(attnum));
952 if (!HeapTupleIsValid(tp))
953 elog(ERROR, "cache lookup failed for attribute %d of relation %u",
955 att_tup = (Form_pg_attribute) GETSTRUCT(tp);
957 *typid = att_tup->atttypid;
958 *typmod = att_tup->atttypmod;
962 /* ---------- COLLATION CACHE ---------- */
966 * Returns the name of a given pg_collation entry.
968 * Returns a palloc'd copy of the string, or NULL if no such constraint.
970 * NOTE: since collation name is not unique, be wary of code that uses this
971 * for anything except preparing error messages.
974 get_collation_name(Oid colloid)
978 tp = SearchSysCache1(COLLOID, ObjectIdGetDatum(colloid));
979 if (HeapTupleIsValid(tp))
981 Form_pg_collation colltup = (Form_pg_collation) GETSTRUCT(tp);
984 result = pstrdup(NameStr(colltup->collname));
992 /* ---------- CONSTRAINT CACHE ---------- */
995 * get_constraint_name
996 * Returns the name of a given pg_constraint entry.
998 * Returns a palloc'd copy of the string, or NULL if no such constraint.
1000 * NOTE: since constraint name is not unique, be wary of code that uses this
1001 * for anything except preparing error messages.
1004 get_constraint_name(Oid conoid)
1008 tp = SearchSysCache1(CONSTROID, ObjectIdGetDatum(conoid));
1009 if (HeapTupleIsValid(tp))
1011 Form_pg_constraint contup = (Form_pg_constraint) GETSTRUCT(tp);
1014 result = pstrdup(NameStr(contup->conname));
1015 ReleaseSysCache(tp);
1022 /* ---------- OPCLASS CACHE ---------- */
1025 * get_opclass_family
1027 * Returns the OID of the operator family the opclass belongs to.
1030 get_opclass_family(Oid opclass)
1033 Form_pg_opclass cla_tup;
1036 tp = SearchSysCache1(CLAOID, ObjectIdGetDatum(opclass));
1037 if (!HeapTupleIsValid(tp))
1038 elog(ERROR, "cache lookup failed for opclass %u", opclass);
1039 cla_tup = (Form_pg_opclass) GETSTRUCT(tp);
1041 result = cla_tup->opcfamily;
1042 ReleaseSysCache(tp);
1047 * get_opclass_input_type
1049 * Returns the OID of the datatype the opclass indexes.
1052 get_opclass_input_type(Oid opclass)
1055 Form_pg_opclass cla_tup;
1058 tp = SearchSysCache1(CLAOID, ObjectIdGetDatum(opclass));
1059 if (!HeapTupleIsValid(tp))
1060 elog(ERROR, "cache lookup failed for opclass %u", opclass);
1061 cla_tup = (Form_pg_opclass) GETSTRUCT(tp);
1063 result = cla_tup->opcintype;
1064 ReleaseSysCache(tp);
1068 /* ---------- OPERATOR CACHE ---------- */
1073 * Returns the regproc id of the routine used to implement an
1074 * operator given the operator oid.
1077 get_opcode(Oid opno)
1081 tp = SearchSysCache1(OPEROID, ObjectIdGetDatum(opno));
1082 if (HeapTupleIsValid(tp))
1084 Form_pg_operator optup = (Form_pg_operator) GETSTRUCT(tp);
1085 RegProcedure result;
1087 result = optup->oprcode;
1088 ReleaseSysCache(tp);
1092 return (RegProcedure) InvalidOid;
1097 * returns the name of the operator with the given opno
1099 * Note: returns a palloc'd copy of the string, or NULL if no such operator.
1102 get_opname(Oid opno)
1106 tp = SearchSysCache1(OPEROID, ObjectIdGetDatum(opno));
1107 if (HeapTupleIsValid(tp))
1109 Form_pg_operator optup = (Form_pg_operator) GETSTRUCT(tp);
1112 result = pstrdup(NameStr(optup->oprname));
1113 ReleaseSysCache(tp);
1123 * Returns the left and right input datatypes for an operator
1124 * (InvalidOid if not relevant).
1127 op_input_types(Oid opno, Oid *lefttype, Oid *righttype)
1130 Form_pg_operator optup;
1132 tp = SearchSysCache1(OPEROID, ObjectIdGetDatum(opno));
1133 if (!HeapTupleIsValid(tp)) /* shouldn't happen */
1134 elog(ERROR, "cache lookup failed for operator %u", opno);
1135 optup = (Form_pg_operator) GETSTRUCT(tp);
1136 *lefttype = optup->oprleft;
1137 *righttype = optup->oprright;
1138 ReleaseSysCache(tp);
1144 * Returns true if the operator is potentially mergejoinable. (The planner
1145 * will fail to find any mergejoin plans unless there are suitable btree
1146 * opfamily entries for this operator and associated sortops. The pg_operator
1147 * flag is just a hint to tell the planner whether to bother looking.)
1149 * In some cases (currently only array_eq), mergejoinability depends on the
1150 * specific input data type the operator is invoked for, so that must be
1151 * passed as well. We currently assume that only one input's type is needed
1152 * to check this --- by convention, pass the left input's data type.
1155 op_mergejoinable(Oid opno, Oid inputtype)
1158 bool result = false;
1160 if (opno == ARRAY_EQ_OP)
1163 * For array_eq, can sort if element type has a default btree opclass.
1164 * We could use GetDefaultOpClass, but that's fairly expensive and not
1165 * cached, so let's use the typcache instead.
1167 Oid elem_type = get_base_element_type(inputtype);
1169 if (OidIsValid(elem_type))
1171 TypeCacheEntry *typentry;
1173 typentry = lookup_type_cache(elem_type, TYPECACHE_BTREE_OPFAMILY);
1174 if (OidIsValid(typentry->btree_opf))
1180 /* For all other operators, rely on pg_operator.oprcanmerge */
1181 tp = SearchSysCache1(OPEROID, ObjectIdGetDatum(opno));
1182 if (HeapTupleIsValid(tp))
1184 Form_pg_operator optup = (Form_pg_operator) GETSTRUCT(tp);
1186 result = optup->oprcanmerge;
1187 ReleaseSysCache(tp);
1196 * Returns true if the operator is hashjoinable. (There must be a suitable
1197 * hash opfamily entry for this operator if it is so marked.)
1199 * In some cases (currently only array_eq), hashjoinability depends on the
1200 * specific input data type the operator is invoked for, so that must be
1201 * passed as well. We currently assume that only one input's type is needed
1202 * to check this --- by convention, pass the left input's data type.
1205 op_hashjoinable(Oid opno, Oid inputtype)
1208 bool result = false;
1210 if (opno == ARRAY_EQ_OP)
1212 /* For array_eq, can hash if element type has a default hash opclass */
1213 Oid elem_type = get_base_element_type(inputtype);
1215 if (OidIsValid(elem_type))
1217 TypeCacheEntry *typentry;
1219 typentry = lookup_type_cache(elem_type, TYPECACHE_HASH_OPFAMILY);
1220 if (OidIsValid(typentry->hash_opf))
1226 /* For all other operators, rely on pg_operator.oprcanhash */
1227 tp = SearchSysCache1(OPEROID, ObjectIdGetDatum(opno));
1228 if (HeapTupleIsValid(tp))
1230 Form_pg_operator optup = (Form_pg_operator) GETSTRUCT(tp);
1232 result = optup->oprcanhash;
1233 ReleaseSysCache(tp);
1242 * Get the proisstrict flag for the operator's underlying function.
1247 RegProcedure funcid = get_opcode(opno);
1249 if (funcid == (RegProcedure) InvalidOid)
1250 elog(ERROR, "operator %u does not exist", opno);
1252 return func_strict((Oid) funcid);
1258 * Get the provolatile flag for the operator's underlying function.
1261 op_volatile(Oid opno)
1263 RegProcedure funcid = get_opcode(opno);
1265 if (funcid == (RegProcedure) InvalidOid)
1266 elog(ERROR, "operator %u does not exist", opno);
1268 return func_volatile((Oid) funcid);
1274 * Returns the corresponding commutator of an operator.
1277 get_commutator(Oid opno)
1281 tp = SearchSysCache1(OPEROID, ObjectIdGetDatum(opno));
1282 if (HeapTupleIsValid(tp))
1284 Form_pg_operator optup = (Form_pg_operator) GETSTRUCT(tp);
1287 result = optup->oprcom;
1288 ReleaseSysCache(tp);
1298 * Returns the corresponding negator of an operator.
1301 get_negator(Oid opno)
1305 tp = SearchSysCache1(OPEROID, ObjectIdGetDatum(opno));
1306 if (HeapTupleIsValid(tp))
1308 Form_pg_operator optup = (Form_pg_operator) GETSTRUCT(tp);
1311 result = optup->oprnegate;
1312 ReleaseSysCache(tp);
1322 * Returns procedure id for computing selectivity of an operator.
1325 get_oprrest(Oid opno)
1329 tp = SearchSysCache1(OPEROID, ObjectIdGetDatum(opno));
1330 if (HeapTupleIsValid(tp))
1332 Form_pg_operator optup = (Form_pg_operator) GETSTRUCT(tp);
1333 RegProcedure result;
1335 result = optup->oprrest;
1336 ReleaseSysCache(tp);
1340 return (RegProcedure) InvalidOid;
1346 * Returns procedure id for computing selectivity of a join.
1349 get_oprjoin(Oid opno)
1353 tp = SearchSysCache1(OPEROID, ObjectIdGetDatum(opno));
1354 if (HeapTupleIsValid(tp))
1356 Form_pg_operator optup = (Form_pg_operator) GETSTRUCT(tp);
1357 RegProcedure result;
1359 result = optup->oprjoin;
1360 ReleaseSysCache(tp);
1364 return (RegProcedure) InvalidOid;
1367 /* ---------- FUNCTION CACHE ---------- */
1371 * returns the name of the function with the given funcid
1373 * Note: returns a palloc'd copy of the string, or NULL if no such function.
1376 get_func_name(Oid funcid)
1380 tp = SearchSysCache1(PROCOID, ObjectIdGetDatum(funcid));
1381 if (HeapTupleIsValid(tp))
1383 Form_pg_proc functup = (Form_pg_proc) GETSTRUCT(tp);
1386 result = pstrdup(NameStr(functup->proname));
1387 ReleaseSysCache(tp);
1395 * get_func_namespace
1397 * Returns the pg_namespace OID associated with a given function.
1400 get_func_namespace(Oid funcid)
1404 tp = SearchSysCache1(PROCOID, ObjectIdGetDatum(funcid));
1405 if (HeapTupleIsValid(tp))
1407 Form_pg_proc functup = (Form_pg_proc) GETSTRUCT(tp);
1410 result = functup->pronamespace;
1411 ReleaseSysCache(tp);
1420 * Given procedure id, return the function's result type.
1423 get_func_rettype(Oid funcid)
1428 tp = SearchSysCache1(PROCOID, ObjectIdGetDatum(funcid));
1429 if (!HeapTupleIsValid(tp))
1430 elog(ERROR, "cache lookup failed for function %u", funcid);
1432 result = ((Form_pg_proc) GETSTRUCT(tp))->prorettype;
1433 ReleaseSysCache(tp);
1439 * Given procedure id, return the number of arguments.
1442 get_func_nargs(Oid funcid)
1447 tp = SearchSysCache1(PROCOID, ObjectIdGetDatum(funcid));
1448 if (!HeapTupleIsValid(tp))
1449 elog(ERROR, "cache lookup failed for function %u", funcid);
1451 result = ((Form_pg_proc) GETSTRUCT(tp))->pronargs;
1452 ReleaseSysCache(tp);
1457 * get_func_signature
1458 * Given procedure id, return the function's argument and result types.
1459 * (The return value is the result type.)
1461 * The arguments are returned as a palloc'd array.
1464 get_func_signature(Oid funcid, Oid **argtypes, int *nargs)
1467 Form_pg_proc procstruct;
1470 tp = SearchSysCache1(PROCOID, ObjectIdGetDatum(funcid));
1471 if (!HeapTupleIsValid(tp))
1472 elog(ERROR, "cache lookup failed for function %u", funcid);
1474 procstruct = (Form_pg_proc) GETSTRUCT(tp);
1476 result = procstruct->prorettype;
1477 *nargs = (int) procstruct->pronargs;
1478 Assert(*nargs == procstruct->proargtypes.dim1);
1479 *argtypes = (Oid *) palloc(*nargs * sizeof(Oid));
1480 memcpy(*argtypes, procstruct->proargtypes.values, *nargs * sizeof(Oid));
1482 ReleaseSysCache(tp);
1488 * Given procedure id, return the function's proretset flag.
1491 get_func_retset(Oid funcid)
1496 tp = SearchSysCache1(PROCOID, ObjectIdGetDatum(funcid));
1497 if (!HeapTupleIsValid(tp))
1498 elog(ERROR, "cache lookup failed for function %u", funcid);
1500 result = ((Form_pg_proc) GETSTRUCT(tp))->proretset;
1501 ReleaseSysCache(tp);
1507 * Given procedure id, return the function's proisstrict flag.
1510 func_strict(Oid funcid)
1515 tp = SearchSysCache1(PROCOID, ObjectIdGetDatum(funcid));
1516 if (!HeapTupleIsValid(tp))
1517 elog(ERROR, "cache lookup failed for function %u", funcid);
1519 result = ((Form_pg_proc) GETSTRUCT(tp))->proisstrict;
1520 ReleaseSysCache(tp);
1526 * Given procedure id, return the function's provolatile flag.
1529 func_volatile(Oid funcid)
1534 tp = SearchSysCache1(PROCOID, ObjectIdGetDatum(funcid));
1535 if (!HeapTupleIsValid(tp))
1536 elog(ERROR, "cache lookup failed for function %u", funcid);
1538 result = ((Form_pg_proc) GETSTRUCT(tp))->provolatile;
1539 ReleaseSysCache(tp);
1545 * Given procedure id, return the function's procost field.
1548 get_func_cost(Oid funcid)
1553 tp = SearchSysCache1(PROCOID, ObjectIdGetDatum(funcid));
1554 if (!HeapTupleIsValid(tp))
1555 elog(ERROR, "cache lookup failed for function %u", funcid);
1557 result = ((Form_pg_proc) GETSTRUCT(tp))->procost;
1558 ReleaseSysCache(tp);
1564 * Given procedure id, return the function's prorows field.
1567 get_func_rows(Oid funcid)
1572 tp = SearchSysCache1(PROCOID, ObjectIdGetDatum(funcid));
1573 if (!HeapTupleIsValid(tp))
1574 elog(ERROR, "cache lookup failed for function %u", funcid);
1576 result = ((Form_pg_proc) GETSTRUCT(tp))->prorows;
1577 ReleaseSysCache(tp);
1581 /* ---------- RELATION CACHE ---------- */
1585 * Given name and namespace of a relation, look up the OID.
1587 * Returns InvalidOid if there is no such relation.
1590 get_relname_relid(const char *relname, Oid relnamespace)
1592 return GetSysCacheOid2(RELNAMENSP,
1593 PointerGetDatum(relname),
1594 ObjectIdGetDatum(relnamespace));
1601 * Returns the number of attributes for a given relation.
1604 get_relnatts(Oid relid)
1608 tp = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
1609 if (HeapTupleIsValid(tp))
1611 Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
1614 result = reltup->relnatts;
1615 ReleaseSysCache(tp);
1619 return InvalidAttrNumber;
1625 * Returns the name of a given relation.
1627 * Returns a palloc'd copy of the string, or NULL if no such relation.
1629 * NOTE: since relation name is not unique, be wary of code that uses this
1630 * for anything except preparing error messages.
1633 get_rel_name(Oid relid)
1637 tp = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
1638 if (HeapTupleIsValid(tp))
1640 Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
1643 result = pstrdup(NameStr(reltup->relname));
1644 ReleaseSysCache(tp);
1654 * Returns the pg_namespace OID associated with a given relation.
1657 get_rel_namespace(Oid relid)
1661 tp = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
1662 if (HeapTupleIsValid(tp))
1664 Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
1667 result = reltup->relnamespace;
1668 ReleaseSysCache(tp);
1678 * Returns the pg_type OID associated with a given relation.
1680 * Note: not all pg_class entries have associated pg_type OIDs; so be
1681 * careful to check for InvalidOid result.
1684 get_rel_type_id(Oid relid)
1688 tp = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
1689 if (HeapTupleIsValid(tp))
1691 Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
1694 result = reltup->reltype;
1695 ReleaseSysCache(tp);
1705 * Returns the relkind associated with a given relation.
1708 get_rel_relkind(Oid relid)
1712 tp = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
1713 if (HeapTupleIsValid(tp))
1715 Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
1718 result = reltup->relkind;
1719 ReleaseSysCache(tp);
1727 * get_rel_tablespace
1729 * Returns the pg_tablespace OID associated with a given relation.
1731 * Note: InvalidOid might mean either that we couldn't find the relation,
1732 * or that it is in the database's default tablespace.
1735 get_rel_tablespace(Oid relid)
1739 tp = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
1740 if (HeapTupleIsValid(tp))
1742 Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
1745 result = reltup->reltablespace;
1746 ReleaseSysCache(tp);
1754 /* ---------- TYPE CACHE ---------- */
1759 * Given the type OID, determine whether the type is defined
1760 * (if not, it's only a shell).
1763 get_typisdefined(Oid typid)
1767 tp = SearchSysCache1(TYPEOID, ObjectIdGetDatum(typid));
1768 if (HeapTupleIsValid(tp))
1770 Form_pg_type typtup = (Form_pg_type) GETSTRUCT(tp);
1773 result = typtup->typisdefined;
1774 ReleaseSysCache(tp);
1784 * Given the type OID, return the length of the type.
1787 get_typlen(Oid typid)
1791 tp = SearchSysCache1(TYPEOID, ObjectIdGetDatum(typid));
1792 if (HeapTupleIsValid(tp))
1794 Form_pg_type typtup = (Form_pg_type) GETSTRUCT(tp);
1797 result = typtup->typlen;
1798 ReleaseSysCache(tp);
1808 * Given the type OID, determine whether the type is returned by value or
1809 * not. Returns true if by value, false if by reference.
1812 get_typbyval(Oid typid)
1816 tp = SearchSysCache1(TYPEOID, ObjectIdGetDatum(typid));
1817 if (HeapTupleIsValid(tp))
1819 Form_pg_type typtup = (Form_pg_type) GETSTRUCT(tp);
1822 result = typtup->typbyval;
1823 ReleaseSysCache(tp);
1833 * A two-fer: given the type OID, return both typlen and typbyval.
1835 * Since both pieces of info are needed to know how to copy a Datum,
1836 * many places need both. Might as well get them with one cache lookup
1837 * instead of two. Also, this routine raises an error instead of
1838 * returning a bogus value when given a bad type OID.
1841 get_typlenbyval(Oid typid, int16 *typlen, bool *typbyval)
1844 Form_pg_type typtup;
1846 tp = SearchSysCache1(TYPEOID, ObjectIdGetDatum(typid));
1847 if (!HeapTupleIsValid(tp))
1848 elog(ERROR, "cache lookup failed for type %u", typid);
1849 typtup = (Form_pg_type) GETSTRUCT(tp);
1850 *typlen = typtup->typlen;
1851 *typbyval = typtup->typbyval;
1852 ReleaseSysCache(tp);
1856 * get_typlenbyvalalign
1858 * A three-fer: given the type OID, return typlen, typbyval, typalign.
1861 get_typlenbyvalalign(Oid typid, int16 *typlen, bool *typbyval,
1865 Form_pg_type typtup;
1867 tp = SearchSysCache1(TYPEOID, ObjectIdGetDatum(typid));
1868 if (!HeapTupleIsValid(tp))
1869 elog(ERROR, "cache lookup failed for type %u", typid);
1870 typtup = (Form_pg_type) GETSTRUCT(tp);
1871 *typlen = typtup->typlen;
1872 *typbyval = typtup->typbyval;
1873 *typalign = typtup->typalign;
1874 ReleaseSysCache(tp);
1879 * Given a pg_type row, select the type OID to pass to I/O functions
1881 * Formerly, all I/O functions were passed pg_type.typelem as their second
1882 * parameter, but we now have a more complex rule about what to pass.
1883 * This knowledge is intended to be centralized here --- direct references
1884 * to typelem elsewhere in the code are wrong, if they are associated with
1885 * I/O calls and not with actual subscripting operations! (But see
1886 * bootstrap.c's boot_get_type_io_data() if you need to change this.)
1888 * As of PostgreSQL 8.1, output functions receive only the value itself
1889 * and not any auxiliary parameters, so the name of this routine is now
1890 * a bit of a misnomer ... it should be getTypeInputParam.
1893 getTypeIOParam(HeapTuple typeTuple)
1895 Form_pg_type typeStruct = (Form_pg_type) GETSTRUCT(typeTuple);
1898 * Array types get their typelem as parameter; everybody else gets their
1899 * own type OID as parameter. (As of 8.2, domains must get their own OID
1900 * even if their base type is an array.)
1902 if (typeStruct->typtype == TYPTYPE_BASE && OidIsValid(typeStruct->typelem))
1903 return typeStruct->typelem;
1905 return HeapTupleGetOid(typeTuple);
1911 * A six-fer: given the type OID, return typlen, typbyval, typalign,
1912 * typdelim, typioparam, and IO function OID. The IO function
1913 * returned is controlled by IOFuncSelector
1916 get_type_io_data(Oid typid,
1917 IOFuncSelector which_func,
1925 HeapTuple typeTuple;
1926 Form_pg_type typeStruct;
1929 * In bootstrap mode, pass it off to bootstrap.c. This hack allows us to
1930 * use array_in and array_out during bootstrap.
1932 if (IsBootstrapProcessingMode())
1937 boot_get_type_io_data(typid,
1954 elog(ERROR, "binary I/O not supported during bootstrap");
1960 typeTuple = SearchSysCache1(TYPEOID, ObjectIdGetDatum(typid));
1961 if (!HeapTupleIsValid(typeTuple))
1962 elog(ERROR, "cache lookup failed for type %u", typid);
1963 typeStruct = (Form_pg_type) GETSTRUCT(typeTuple);
1965 *typlen = typeStruct->typlen;
1966 *typbyval = typeStruct->typbyval;
1967 *typalign = typeStruct->typalign;
1968 *typdelim = typeStruct->typdelim;
1969 *typioparam = getTypeIOParam(typeTuple);
1973 *func = typeStruct->typinput;
1976 *func = typeStruct->typoutput;
1978 case IOFunc_receive:
1979 *func = typeStruct->typreceive;
1982 *func = typeStruct->typsend;
1985 ReleaseSysCache(typeTuple);
1990 get_typalign(Oid typid)
1994 tp = SearchSysCache1(TYPEOID, ObjectIdGetDatum(typid));
1995 if (HeapTupleIsValid(tp))
1997 Form_pg_type typtup = (Form_pg_type) GETSTRUCT(tp);
2000 result = typtup->typalign;
2001 ReleaseSysCache(tp);
2010 get_typstorage(Oid typid)
2014 tp = SearchSysCache1(TYPEOID, ObjectIdGetDatum(typid));
2015 if (HeapTupleIsValid(tp))
2017 Form_pg_type typtup = (Form_pg_type) GETSTRUCT(tp);
2020 result = typtup->typstorage;
2021 ReleaseSysCache(tp);
2030 * Given a type OID, return the type's default value, if any.
2032 * The result is a palloc'd expression node tree, or NULL if there
2033 * is no defined default for the datatype.
2035 * NB: caller should be prepared to coerce result to correct datatype;
2036 * the returned expression tree might produce something of the wrong type.
2039 get_typdefault(Oid typid)
2041 HeapTuple typeTuple;
2047 typeTuple = SearchSysCache1(TYPEOID, ObjectIdGetDatum(typid));
2048 if (!HeapTupleIsValid(typeTuple))
2049 elog(ERROR, "cache lookup failed for type %u", typid);
2050 type = (Form_pg_type) GETSTRUCT(typeTuple);
2053 * typdefault and typdefaultbin are potentially null, so don't try to
2054 * access 'em as struct fields. Must do it the hard way with
2057 datum = SysCacheGetAttr(TYPEOID,
2059 Anum_pg_type_typdefaultbin,
2064 /* We have an expression default */
2065 expr = stringToNode(TextDatumGetCString(datum));
2069 /* Perhaps we have a plain literal default */
2070 datum = SysCacheGetAttr(TYPEOID,
2072 Anum_pg_type_typdefault,
2077 char *strDefaultVal;
2079 /* Convert text datum to C string */
2080 strDefaultVal = TextDatumGetCString(datum);
2081 /* Convert C string to a value of the given type */
2082 datum = OidInputFunctionCall(type->typinput, strDefaultVal,
2083 getTypeIOParam(typeTuple), -1);
2084 /* Build a Const node containing the value */
2085 expr = (Node *) makeConst(typid,
2092 pfree(strDefaultVal);
2101 ReleaseSysCache(typeTuple);
2108 * If the given type is a domain, return its base type;
2109 * otherwise return the type's own OID.
2112 getBaseType(Oid typid)
2116 return getBaseTypeAndTypmod(typid, &typmod);
2120 * getBaseTypeAndTypmod
2121 * If the given type is a domain, return its base type and typmod;
2122 * otherwise return the type's own OID, and leave *typmod unchanged.
2124 * Note that the "applied typmod" should be -1 for every domain level
2125 * above the bottommost; therefore, if the passed-in typid is indeed
2126 * a domain, *typmod should be -1.
2129 getBaseTypeAndTypmod(Oid typid, int32 *typmod)
2132 * We loop to find the bottom base type in a stack of domains.
2137 Form_pg_type typTup;
2139 tup = SearchSysCache1(TYPEOID, ObjectIdGetDatum(typid));
2140 if (!HeapTupleIsValid(tup))
2141 elog(ERROR, "cache lookup failed for type %u", typid);
2142 typTup = (Form_pg_type) GETSTRUCT(tup);
2143 if (typTup->typtype != TYPTYPE_DOMAIN)
2145 /* Not a domain, so done */
2146 ReleaseSysCache(tup);
2150 Assert(*typmod == -1);
2151 typid = typTup->typbasetype;
2152 *typmod = typTup->typtypmod;
2154 ReleaseSysCache(tup);
2163 * Given a type OID and a typmod value (pass -1 if typmod is unknown),
2164 * estimate the average width of values of the type. This is used by
2165 * the planner, which doesn't require absolutely correct results;
2166 * it's OK (and expected) to guess if we don't know for sure.
2169 get_typavgwidth(Oid typid, int32 typmod)
2171 int typlen = get_typlen(typid);
2175 * Easy if it's a fixed-width type
2181 * type_maximum_size knows the encoding of typmod for some datatypes;
2182 * don't duplicate that knowledge here.
2184 maxwidth = type_maximum_size(typid, typmod);
2188 * For BPCHAR, the max width is also the only width. Otherwise we
2189 * need to guess about the typical data width given the max. A sliding
2190 * scale for percentage of max width seems reasonable.
2192 if (typid == BPCHAROID)
2195 return maxwidth; /* assume full width */
2196 if (maxwidth < 1000)
2197 return 32 + (maxwidth - 32) / 2; /* assume 50% */
2200 * Beyond 1000, assume we're looking at something like
2201 * "varchar(10000)" where the limit isn't actually reached often, and
2202 * use a fixed estimate.
2204 return 32 + (1000 - 32) / 2;
2208 * Ooops, we have no idea ... wild guess time.
2216 * Given the type OID, find if it is a basic type, a complex type, etc.
2217 * It returns the null char if the cache lookup fails...
2220 get_typtype(Oid typid)
2224 tp = SearchSysCache1(TYPEOID, ObjectIdGetDatum(typid));
2225 if (HeapTupleIsValid(tp))
2227 Form_pg_type typtup = (Form_pg_type) GETSTRUCT(tp);
2230 result = typtup->typtype;
2231 ReleaseSysCache(tp);
2241 * Convenience function to determine whether a type OID represents
2242 * a "rowtype" type --- either RECORD or a named composite type.
2245 type_is_rowtype(Oid typid)
2247 return (typid == RECORDOID || get_typtype(typid) == TYPTYPE_COMPOSITE);
2252 * Returns true if the given type is an enum type.
2255 type_is_enum(Oid typid)
2257 return (get_typtype(typid) == TYPTYPE_ENUM);
2261 * get_type_category_preferred
2263 * Given the type OID, fetch its category and preferred-type status.
2264 * Throws error on failure.
2267 get_type_category_preferred(Oid typid, char *typcategory, bool *typispreferred)
2270 Form_pg_type typtup;
2272 tp = SearchSysCache1(TYPEOID, ObjectIdGetDatum(typid));
2273 if (!HeapTupleIsValid(tp))
2274 elog(ERROR, "cache lookup failed for type %u", typid);
2275 typtup = (Form_pg_type) GETSTRUCT(tp);
2276 *typcategory = typtup->typcategory;
2277 *typispreferred = typtup->typispreferred;
2278 ReleaseSysCache(tp);
2284 * Given the type OID, get the typrelid (InvalidOid if not a complex
2288 get_typ_typrelid(Oid typid)
2292 tp = SearchSysCache1(TYPEOID, ObjectIdGetDatum(typid));
2293 if (HeapTupleIsValid(tp))
2295 Form_pg_type typtup = (Form_pg_type) GETSTRUCT(tp);
2298 result = typtup->typrelid;
2299 ReleaseSysCache(tp);
2309 * Given the type OID, get the typelem (InvalidOid if not an array type).
2311 * NB: this only considers varlena arrays to be true arrays; InvalidOid is
2312 * returned if the input is a fixed-length array type.
2315 get_element_type(Oid typid)
2319 tp = SearchSysCache1(TYPEOID, ObjectIdGetDatum(typid));
2320 if (HeapTupleIsValid(tp))
2322 Form_pg_type typtup = (Form_pg_type) GETSTRUCT(tp);
2325 if (typtup->typlen == -1)
2326 result = typtup->typelem;
2328 result = InvalidOid;
2329 ReleaseSysCache(tp);
2339 * Given the type OID, get the corresponding "true" array type.
2340 * Returns InvalidOid if no array type can be found.
2343 get_array_type(Oid typid)
2346 Oid result = InvalidOid;
2348 tp = SearchSysCache1(TYPEOID, ObjectIdGetDatum(typid));
2349 if (HeapTupleIsValid(tp))
2351 result = ((Form_pg_type) GETSTRUCT(tp))->typarray;
2352 ReleaseSysCache(tp);
2358 * get_base_element_type
2359 * Given the type OID, get the typelem, looking "through" any domain
2360 * to its underlying array type.
2362 * This is equivalent to get_element_type(getBaseType(typid)), but avoids
2363 * an extra cache lookup. Note that it fails to provide any information
2364 * about the typmod of the array.
2367 get_base_element_type(Oid typid)
2370 * We loop to find the bottom base type in a stack of domains.
2375 Form_pg_type typTup;
2377 tup = SearchSysCache1(TYPEOID, ObjectIdGetDatum(typid));
2378 if (!HeapTupleIsValid(tup))
2380 typTup = (Form_pg_type) GETSTRUCT(tup);
2381 if (typTup->typtype != TYPTYPE_DOMAIN)
2383 /* Not a domain, so stop descending */
2386 /* This test must match get_element_type */
2387 if (typTup->typlen == -1)
2388 result = typTup->typelem;
2390 result = InvalidOid;
2391 ReleaseSysCache(tup);
2395 typid = typTup->typbasetype;
2396 ReleaseSysCache(tup);
2399 /* Like get_element_type, silently return InvalidOid for bogus input */
2406 * Get info needed for converting values of a type to internal form
2409 getTypeInputInfo(Oid type, Oid *typInput, Oid *typIOParam)
2411 HeapTuple typeTuple;
2414 typeTuple = SearchSysCache1(TYPEOID, ObjectIdGetDatum(type));
2415 if (!HeapTupleIsValid(typeTuple))
2416 elog(ERROR, "cache lookup failed for type %u", type);
2417 pt = (Form_pg_type) GETSTRUCT(typeTuple);
2419 if (!pt->typisdefined)
2421 (errcode(ERRCODE_UNDEFINED_OBJECT),
2422 errmsg("type %s is only a shell",
2423 format_type_be(type))));
2424 if (!OidIsValid(pt->typinput))
2426 (errcode(ERRCODE_UNDEFINED_FUNCTION),
2427 errmsg("no input function available for type %s",
2428 format_type_be(type))));
2430 *typInput = pt->typinput;
2431 *typIOParam = getTypeIOParam(typeTuple);
2433 ReleaseSysCache(typeTuple);
2439 * Get info needed for printing values of a type
2442 getTypeOutputInfo(Oid type, Oid *typOutput, bool *typIsVarlena)
2444 HeapTuple typeTuple;
2447 typeTuple = SearchSysCache1(TYPEOID, ObjectIdGetDatum(type));
2448 if (!HeapTupleIsValid(typeTuple))
2449 elog(ERROR, "cache lookup failed for type %u", type);
2450 pt = (Form_pg_type) GETSTRUCT(typeTuple);
2452 if (!pt->typisdefined)
2454 (errcode(ERRCODE_UNDEFINED_OBJECT),
2455 errmsg("type %s is only a shell",
2456 format_type_be(type))));
2457 if (!OidIsValid(pt->typoutput))
2459 (errcode(ERRCODE_UNDEFINED_FUNCTION),
2460 errmsg("no output function available for type %s",
2461 format_type_be(type))));
2463 *typOutput = pt->typoutput;
2464 *typIsVarlena = (!pt->typbyval) && (pt->typlen == -1);
2466 ReleaseSysCache(typeTuple);
2470 * getTypeBinaryInputInfo
2472 * Get info needed for binary input of values of a type
2475 getTypeBinaryInputInfo(Oid type, Oid *typReceive, Oid *typIOParam)
2477 HeapTuple typeTuple;
2480 typeTuple = SearchSysCache1(TYPEOID, ObjectIdGetDatum(type));
2481 if (!HeapTupleIsValid(typeTuple))
2482 elog(ERROR, "cache lookup failed for type %u", type);
2483 pt = (Form_pg_type) GETSTRUCT(typeTuple);
2485 if (!pt->typisdefined)
2487 (errcode(ERRCODE_UNDEFINED_OBJECT),
2488 errmsg("type %s is only a shell",
2489 format_type_be(type))));
2490 if (!OidIsValid(pt->typreceive))
2492 (errcode(ERRCODE_UNDEFINED_FUNCTION),
2493 errmsg("no binary input function available for type %s",
2494 format_type_be(type))));
2496 *typReceive = pt->typreceive;
2497 *typIOParam = getTypeIOParam(typeTuple);
2499 ReleaseSysCache(typeTuple);
2503 * getTypeBinaryOutputInfo
2505 * Get info needed for binary output of values of a type
2508 getTypeBinaryOutputInfo(Oid type, Oid *typSend, bool *typIsVarlena)
2510 HeapTuple typeTuple;
2513 typeTuple = SearchSysCache1(TYPEOID, ObjectIdGetDatum(type));
2514 if (!HeapTupleIsValid(typeTuple))
2515 elog(ERROR, "cache lookup failed for type %u", type);
2516 pt = (Form_pg_type) GETSTRUCT(typeTuple);
2518 if (!pt->typisdefined)
2520 (errcode(ERRCODE_UNDEFINED_OBJECT),
2521 errmsg("type %s is only a shell",
2522 format_type_be(type))));
2523 if (!OidIsValid(pt->typsend))
2525 (errcode(ERRCODE_UNDEFINED_FUNCTION),
2526 errmsg("no binary output function available for type %s",
2527 format_type_be(type))));
2529 *typSend = pt->typsend;
2530 *typIsVarlena = (!pt->typbyval) && (pt->typlen == -1);
2532 ReleaseSysCache(typeTuple);
2538 * Given the type OID, return the type's typmodin procedure, if any.
2541 get_typmodin(Oid typid)
2545 tp = SearchSysCache1(TYPEOID, ObjectIdGetDatum(typid));
2546 if (HeapTupleIsValid(tp))
2548 Form_pg_type typtup = (Form_pg_type) GETSTRUCT(tp);
2551 result = typtup->typmodin;
2552 ReleaseSysCache(tp);
2563 * Given the type OID, return the type's typmodout procedure, if any.
2566 get_typmodout(Oid typid)
2570 tp = SearchSysCache1(TYPEOID, ObjectIdGetDatum(typid));
2571 if (HeapTupleIsValid(tp))
2573 Form_pg_type typtup = (Form_pg_type) GETSTRUCT(tp);
2576 result = typtup->typmodout;
2577 ReleaseSysCache(tp);
2583 #endif /* NOT_USED */
2588 * Given the type OID, return the type's typcollation attribute.
2591 get_typcollation(Oid typid)
2595 tp = SearchSysCache1(TYPEOID, ObjectIdGetDatum(typid));
2596 if (HeapTupleIsValid(tp))
2598 Form_pg_type typtup = (Form_pg_type) GETSTRUCT(tp);
2601 result = typtup->typcollation;
2602 ReleaseSysCache(tp);
2611 * type_is_collatable
2613 * Return whether the type cares about collations
2616 type_is_collatable(Oid typid)
2618 return OidIsValid(get_typcollation(typid));
2622 /* ---------- STATISTICS CACHE ---------- */
2627 * Given the table and attribute number of a column, get the average
2628 * width of entries in the column. Return zero if no data available.
2630 * Currently this is only consulted for individual tables, not for inheritance
2631 * trees, so we don't need an "inh" parameter.
2633 * Calling a hook at this point looks somewhat strange, but is required
2634 * because the optimizer calls this function without any other way for
2635 * plug-ins to control the result.
2638 get_attavgwidth(Oid relid, AttrNumber attnum)
2643 if (get_attavgwidth_hook)
2645 stawidth = (*get_attavgwidth_hook) (relid, attnum);
2649 tp = SearchSysCache3(STATRELATTINH,
2650 ObjectIdGetDatum(relid),
2651 Int16GetDatum(attnum),
2652 BoolGetDatum(false));
2653 if (HeapTupleIsValid(tp))
2655 stawidth = ((Form_pg_statistic) GETSTRUCT(tp))->stawidth;
2656 ReleaseSysCache(tp);
2666 * Extract the contents of a "slot" of a pg_statistic tuple.
2667 * Returns TRUE if requested slot type was found, else FALSE.
2669 * Unlike other routines in this file, this takes a pointer to an
2670 * already-looked-up tuple in the pg_statistic cache. We do this since
2671 * most callers will want to extract more than one value from the cache
2672 * entry, and we don't want to repeat the cache lookup unnecessarily.
2673 * Also, this API allows this routine to be used with statistics tuples
2674 * that have been provided by a stats hook and didn't really come from
2677 * statstuple: pg_statistics tuple to be examined.
2678 * atttype: type OID of attribute (can be InvalidOid if values == NULL).
2679 * atttypmod: typmod of attribute (can be 0 if values == NULL).
2680 * reqkind: STAKIND code for desired statistics slot kind.
2681 * reqop: STAOP value wanted, or InvalidOid if don't care.
2682 * actualop: if not NULL, *actualop receives the actual STAOP value.
2683 * values, nvalues: if not NULL, the slot's stavalues are extracted.
2684 * numbers, nnumbers: if not NULL, the slot's stanumbers are extracted.
2686 * If assigned, values and numbers are set to point to palloc'd arrays.
2687 * If the attribute type is pass-by-reference, the values referenced by
2688 * the values array are themselves palloc'd. The palloc'd stuff can be
2689 * freed by calling free_attstatsslot.
2691 * Note: at present, atttype/atttypmod aren't actually used here at all.
2692 * But the caller must have the correct (or at least binary-compatible)
2693 * type ID to pass to free_attstatsslot later.
2696 get_attstatsslot(HeapTuple statstuple,
2697 Oid atttype, int32 atttypmod,
2698 int reqkind, Oid reqop,
2700 Datum **values, int *nvalues,
2701 float4 **numbers, int *nnumbers)
2703 Form_pg_statistic stats = (Form_pg_statistic) GETSTRUCT(statstuple);
2708 ArrayType *statarray;
2711 HeapTuple typeTuple;
2712 Form_pg_type typeForm;
2714 for (i = 0; i < STATISTIC_NUM_SLOTS; i++)
2716 if ((&stats->stakind1)[i] == reqkind &&
2717 (reqop == InvalidOid || (&stats->staop1)[i] == reqop))
2720 if (i >= STATISTIC_NUM_SLOTS)
2721 return false; /* not there */
2724 *actualop = (&stats->staop1)[i];
2728 val = SysCacheGetAttr(STATRELATTINH, statstuple,
2729 Anum_pg_statistic_stavalues1 + i,
2732 elog(ERROR, "stavalues is null");
2733 statarray = DatumGetArrayTypeP(val);
2736 * Need to get info about the array element type. We look at the
2737 * actual element type embedded in the array, which might be only
2738 * binary-compatible with the passed-in atttype. The info we
2739 * extract here should be the same either way, but deconstruct_array
2740 * is picky about having an exact type OID match.
2742 arrayelemtype = ARR_ELEMTYPE(statarray);
2743 typeTuple = SearchSysCache1(TYPEOID, ObjectIdGetDatum(arrayelemtype));
2744 if (!HeapTupleIsValid(typeTuple))
2745 elog(ERROR, "cache lookup failed for type %u", arrayelemtype);
2746 typeForm = (Form_pg_type) GETSTRUCT(typeTuple);
2748 /* Deconstruct array into Datum elements; NULLs not expected */
2749 deconstruct_array(statarray,
2754 values, NULL, nvalues);
2757 * If the element type is pass-by-reference, we now have a bunch of
2758 * Datums that are pointers into the syscache value. Copy them to
2759 * avoid problems if syscache decides to drop the entry.
2761 if (!typeForm->typbyval)
2763 for (j = 0; j < *nvalues; j++)
2765 (*values)[j] = datumCopy((*values)[j],
2771 ReleaseSysCache(typeTuple);
2774 * Free statarray if it's a detoasted copy.
2776 if ((Pointer) statarray != DatumGetPointer(val))
2782 val = SysCacheGetAttr(STATRELATTINH, statstuple,
2783 Anum_pg_statistic_stanumbers1 + i,
2786 elog(ERROR, "stanumbers is null");
2787 statarray = DatumGetArrayTypeP(val);
2790 * We expect the array to be a 1-D float4 array; verify that. We don't
2791 * need to use deconstruct_array() since the array data is just going
2792 * to look like a C array of float4 values.
2794 narrayelem = ARR_DIMS(statarray)[0];
2795 if (ARR_NDIM(statarray) != 1 || narrayelem <= 0 ||
2796 ARR_HASNULL(statarray) ||
2797 ARR_ELEMTYPE(statarray) != FLOAT4OID)
2798 elog(ERROR, "stanumbers is not a 1-D float4 array");
2799 *numbers = (float4 *) palloc(narrayelem * sizeof(float4));
2800 memcpy(*numbers, ARR_DATA_PTR(statarray), narrayelem * sizeof(float4));
2801 *nnumbers = narrayelem;
2804 * Free statarray if it's a detoasted copy.
2806 if ((Pointer) statarray != DatumGetPointer(val))
2815 * Free data allocated by get_attstatsslot
2817 * atttype need be valid only if values != NULL.
2820 free_attstatsslot(Oid atttype,
2821 Datum *values, int nvalues,
2822 float4 *numbers, int nnumbers)
2826 if (!get_typbyval(atttype))
2830 for (i = 0; i < nvalues; i++)
2831 pfree(DatumGetPointer(values[i]));
2839 /* ---------- PG_NAMESPACE CACHE ---------- */
2842 * get_namespace_name
2843 * Returns the name of a given namespace
2845 * Returns a palloc'd copy of the string, or NULL if no such namespace.
2848 get_namespace_name(Oid nspid)
2852 tp = SearchSysCache1(NAMESPACEOID, ObjectIdGetDatum(nspid));
2853 if (HeapTupleIsValid(tp))
2855 Form_pg_namespace nsptup = (Form_pg_namespace) GETSTRUCT(tp);
2858 result = pstrdup(NameStr(nsptup->nspname));
2859 ReleaseSysCache(tp);