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 * 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_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"
37 #include "utils/typcache.h"
39 /* Hook for plugins to get control in get_attavgwidth() */
40 get_attavgwidth_hook_type get_attavgwidth_hook = NULL;
43 /* ---------- AMOP CACHES ---------- */
48 * Return t iff operator 'opno' is in operator family 'opfamily'.
50 * This function only considers search operators, not ordering operators.
53 op_in_opfamily(Oid opno, Oid opfamily)
55 return SearchSysCacheExists3(AMOPOPID,
56 ObjectIdGetDatum(opno),
57 CharGetDatum(AMOP_SEARCH),
58 ObjectIdGetDatum(opfamily));
62 * get_op_opfamily_strategy
64 * Get the operator's strategy number within the specified opfamily,
65 * or 0 if it's not a member of the opfamily.
67 * This function only considers search operators, not ordering operators.
70 get_op_opfamily_strategy(Oid opno, Oid opfamily)
73 Form_pg_amop amop_tup;
76 tp = SearchSysCache3(AMOPOPID,
77 ObjectIdGetDatum(opno),
78 CharGetDatum(AMOP_SEARCH),
79 ObjectIdGetDatum(opfamily));
80 if (!HeapTupleIsValid(tp))
82 amop_tup = (Form_pg_amop) GETSTRUCT(tp);
83 result = amop_tup->amopstrategy;
89 * get_op_opfamily_sortfamily
91 * If the operator is an ordering operator within the specified opfamily,
92 * return its amopsortfamily OID; else return InvalidOid.
95 get_op_opfamily_sortfamily(Oid opno, Oid opfamily)
98 Form_pg_amop amop_tup;
101 tp = SearchSysCache3(AMOPOPID,
102 ObjectIdGetDatum(opno),
103 CharGetDatum(AMOP_ORDER),
104 ObjectIdGetDatum(opfamily));
105 if (!HeapTupleIsValid(tp))
107 amop_tup = (Form_pg_amop) GETSTRUCT(tp);
108 result = amop_tup->amopsortfamily;
114 * get_op_opfamily_properties
116 * Get the operator's strategy number and declared input data types
117 * within the specified opfamily.
119 * Caller should already have verified that opno is a member of opfamily,
120 * therefore we raise an error if the tuple is not found.
123 get_op_opfamily_properties(Oid opno, Oid opfamily, bool ordering_op,
129 Form_pg_amop amop_tup;
131 tp = SearchSysCache3(AMOPOPID,
132 ObjectIdGetDatum(opno),
133 CharGetDatum(ordering_op ? AMOP_ORDER : AMOP_SEARCH),
134 ObjectIdGetDatum(opfamily));
135 if (!HeapTupleIsValid(tp))
136 elog(ERROR, "operator %u is not a member of opfamily %u",
138 amop_tup = (Form_pg_amop) GETSTRUCT(tp);
139 *strategy = amop_tup->amopstrategy;
140 *lefttype = amop_tup->amoplefttype;
141 *righttype = amop_tup->amoprighttype;
146 * get_opfamily_member
147 * Get the OID of the operator that implements the specified strategy
148 * with the specified datatypes for the specified opfamily.
150 * Returns InvalidOid if there is no pg_amop entry for the given keys.
153 get_opfamily_member(Oid opfamily, Oid lefttype, Oid righttype,
157 Form_pg_amop amop_tup;
160 tp = SearchSysCache4(AMOPSTRATEGY,
161 ObjectIdGetDatum(opfamily),
162 ObjectIdGetDatum(lefttype),
163 ObjectIdGetDatum(righttype),
164 Int16GetDatum(strategy));
165 if (!HeapTupleIsValid(tp))
167 amop_tup = (Form_pg_amop) GETSTRUCT(tp);
168 result = amop_tup->amopopr;
174 * get_ordering_op_properties
175 * Given the OID of an ordering operator (a btree "<" or ">" operator),
176 * determine its opfamily, its declared input datatype, and its
177 * strategy number (BTLessStrategyNumber or BTGreaterStrategyNumber).
179 * Returns TRUE if successful, FALSE if no matching pg_amop entry exists.
180 * (This indicates that the operator is not a valid ordering operator.)
182 * Note: the operator could be registered in multiple families, for example
183 * if someone were to build a "reverse sort" opfamily. This would result in
184 * uncertainty as to whether "ORDER BY USING op" would default to NULLS FIRST
185 * or NULLS LAST, as well as inefficient planning due to failure to match up
186 * pathkeys that should be the same. So we want a determinate result here.
187 * Because of the way the syscache search works, we'll use the interpretation
188 * associated with the opfamily with smallest OID, which is probably
189 * determinate enough. Since there is no longer any particularly good reason
190 * to build reverse-sort opfamilies, it doesn't seem worth expending any
191 * additional effort on ensuring consistency.
194 get_ordering_op_properties(Oid opno,
195 Oid *opfamily, Oid *opcintype, int16 *strategy)
201 /* ensure outputs are initialized on failure */
202 *opfamily = InvalidOid;
203 *opcintype = InvalidOid;
207 * Search pg_amop to see if the target operator is registered as the "<"
208 * or ">" operator of any btree opfamily.
210 catlist = SearchSysCacheList1(AMOPOPID, ObjectIdGetDatum(opno));
212 for (i = 0; i < catlist->n_members; i++)
214 HeapTuple tuple = &catlist->members[i]->tuple;
215 Form_pg_amop aform = (Form_pg_amop) GETSTRUCT(tuple);
218 if (aform->amopmethod != BTREE_AM_OID)
221 if (aform->amopstrategy == BTLessStrategyNumber ||
222 aform->amopstrategy == BTGreaterStrategyNumber)
224 /* Found it ... should have consistent input types */
225 if (aform->amoplefttype == aform->amoprighttype)
227 /* Found a suitable opfamily, return info */
228 *opfamily = aform->amopfamily;
229 *opcintype = aform->amoplefttype;
230 *strategy = aform->amopstrategy;
237 ReleaseSysCacheList(catlist);
243 * get_compare_function_for_ordering_op
244 * Get the OID of the datatype-specific btree comparison function
245 * associated with an ordering operator (a "<" or ">" operator).
247 * *cmpfunc receives the comparison function OID.
248 * *reverse is set FALSE if the operator is "<", TRUE if it's ">"
249 * (indicating the comparison result must be negated before use).
251 * Returns TRUE if successful, FALSE if no btree function can be found.
252 * (This indicates that the operator is not a valid ordering operator.)
255 get_compare_function_for_ordering_op(Oid opno, Oid *cmpfunc, bool *reverse)
261 /* Find the operator in pg_amop */
262 if (get_ordering_op_properties(opno,
263 &opfamily, &opcintype, &strategy))
265 /* Found a suitable opfamily, get matching support function */
266 *cmpfunc = get_opfamily_proc(opfamily,
271 if (!OidIsValid(*cmpfunc)) /* should not happen */
272 elog(ERROR, "missing support function %d(%u,%u) in opfamily %u",
273 BTORDER_PROC, opcintype, opcintype, opfamily);
274 *reverse = (strategy == BTGreaterStrategyNumber);
278 /* ensure outputs are set on failure */
279 *cmpfunc = InvalidOid;
286 * get_equality_op_for_ordering_op
287 * Get the OID of the datatype-specific btree equality operator
288 * associated with an ordering operator (a "<" or ">" operator).
290 * If "reverse" isn't NULL, also set *reverse to FALSE if the operator is "<",
293 * Returns InvalidOid if no matching equality operator can be found.
294 * (This indicates that the operator is not a valid ordering operator.)
297 get_equality_op_for_ordering_op(Oid opno, bool *reverse)
299 Oid result = InvalidOid;
304 /* Find the operator in pg_amop */
305 if (get_ordering_op_properties(opno,
306 &opfamily, &opcintype, &strategy))
308 /* Found a suitable opfamily, get matching equality operator */
309 result = get_opfamily_member(opfamily,
312 BTEqualStrategyNumber);
314 *reverse = (strategy == BTGreaterStrategyNumber);
321 * get_ordering_op_for_equality_op
322 * Get the OID of a datatype-specific btree ordering operator
323 * associated with an equality operator. (If there are multiple
324 * possibilities, assume any one will do.)
326 * This function is used when we have to sort data before unique-ifying,
327 * and don't much care which sorting op is used as long as it's compatible
328 * with the intended equality operator. Since we need a sorting operator,
329 * it should be single-data-type even if the given operator is cross-type.
330 * The caller specifies whether to find an op for the LHS or RHS data type.
332 * Returns InvalidOid if no matching ordering operator can be found.
335 get_ordering_op_for_equality_op(Oid opno, bool use_lhs_type)
337 Oid result = InvalidOid;
342 * Search pg_amop to see if the target operator is registered as the "="
343 * operator of any btree opfamily.
345 catlist = SearchSysCacheList1(AMOPOPID, ObjectIdGetDatum(opno));
347 for (i = 0; i < catlist->n_members; i++)
349 HeapTuple tuple = &catlist->members[i]->tuple;
350 Form_pg_amop aform = (Form_pg_amop) GETSTRUCT(tuple);
353 if (aform->amopmethod != BTREE_AM_OID)
356 if (aform->amopstrategy == BTEqualStrategyNumber)
358 /* Found a suitable opfamily, get matching ordering operator */
361 typid = use_lhs_type ? aform->amoplefttype : aform->amoprighttype;
362 result = get_opfamily_member(aform->amopfamily,
364 BTLessStrategyNumber);
365 if (OidIsValid(result))
367 /* failure probably shouldn't happen, but keep looking if so */
371 ReleaseSysCacheList(catlist);
377 * get_mergejoin_opfamilies
378 * Given a putatively mergejoinable operator, return a list of the OIDs
379 * of the btree opfamilies in which it represents equality.
381 * It is possible (though at present unusual) for an operator to be equality
382 * in more than one opfamily, hence the result is a list. This also lets us
383 * return NIL if the operator is not found in any opfamilies.
385 * The planner currently uses simple equal() tests to compare the lists
386 * returned by this function, which makes the list order relevant, though
387 * strictly speaking it should not be. Because of the way syscache list
388 * searches are handled, in normal operation the result will be sorted by OID
389 * so everything works fine. If running with system index usage disabled,
390 * the result ordering is unspecified and hence the planner might fail to
391 * recognize optimization opportunities ... but that's hardly a scenario in
392 * which performance is good anyway, so there's no point in expending code
393 * or cycles here to guarantee the ordering in that case.
396 get_mergejoin_opfamilies(Oid opno)
403 * Search pg_amop to see if the target operator is registered as the "="
404 * operator of any btree opfamily.
406 catlist = SearchSysCacheList1(AMOPOPID, ObjectIdGetDatum(opno));
408 for (i = 0; i < catlist->n_members; i++)
410 HeapTuple tuple = &catlist->members[i]->tuple;
411 Form_pg_amop aform = (Form_pg_amop) GETSTRUCT(tuple);
413 /* must be btree equality */
414 if (aform->amopmethod == BTREE_AM_OID &&
415 aform->amopstrategy == BTEqualStrategyNumber)
416 result = lappend_oid(result, aform->amopfamily);
419 ReleaseSysCacheList(catlist);
425 * get_compatible_hash_operators
426 * Get the OID(s) of hash equality operator(s) compatible with the given
427 * operator, but operating on its LHS and/or RHS datatype.
429 * An operator for the LHS type is sought and returned into *lhs_opno if
430 * lhs_opno isn't NULL. Similarly, an operator for the RHS type is sought
431 * and returned into *rhs_opno if rhs_opno isn't NULL.
433 * If the given operator is not cross-type, the results should be the same
434 * operator, but in cross-type situations they will be different.
436 * Returns true if able to find the requested operator(s), false if not.
437 * (This indicates that the operator should not have been marked oprcanhash.)
440 get_compatible_hash_operators(Oid opno,
441 Oid *lhs_opno, Oid *rhs_opno)
447 /* Ensure output args are initialized on failure */
449 *lhs_opno = InvalidOid;
451 *rhs_opno = InvalidOid;
454 * Search pg_amop to see if the target operator is registered as the "="
455 * operator of any hash opfamily. If the operator is registered in
456 * multiple opfamilies, assume we can use any one.
458 catlist = SearchSysCacheList1(AMOPOPID, ObjectIdGetDatum(opno));
460 for (i = 0; i < catlist->n_members; i++)
462 HeapTuple tuple = &catlist->members[i]->tuple;
463 Form_pg_amop aform = (Form_pg_amop) GETSTRUCT(tuple);
465 if (aform->amopmethod == HASH_AM_OID &&
466 aform->amopstrategy == HTEqualStrategyNumber)
468 /* No extra lookup needed if given operator is single-type */
469 if (aform->amoplefttype == aform->amoprighttype)
480 * Get the matching single-type operator(s). Failure probably
481 * shouldn't happen --- it implies a bogus opfamily --- but
482 * continue looking if so.
486 *lhs_opno = get_opfamily_member(aform->amopfamily,
489 HTEqualStrategyNumber);
490 if (!OidIsValid(*lhs_opno))
492 /* Matching LHS found, done if caller doesn't want RHS */
501 *rhs_opno = get_opfamily_member(aform->amopfamily,
502 aform->amoprighttype,
503 aform->amoprighttype,
504 HTEqualStrategyNumber);
505 if (!OidIsValid(*rhs_opno))
507 /* Forget any LHS operator from this opfamily */
509 *lhs_opno = InvalidOid;
512 /* Matching RHS found, so done */
519 ReleaseSysCacheList(catlist);
525 * get_op_hash_functions
526 * Get the OID(s) of hash support function(s) compatible with the given
527 * operator, operating on its LHS and/or RHS datatype as required.
529 * A function for the LHS type is sought and returned into *lhs_procno if
530 * lhs_procno isn't NULL. Similarly, a function for the RHS type is sought
531 * and returned into *rhs_procno if rhs_procno isn't NULL.
533 * If the given operator is not cross-type, the results should be the same
534 * function, but in cross-type situations they will be different.
536 * Returns true if able to find the requested function(s), false if not.
537 * (This indicates that the operator should not have been marked oprcanhash.)
540 get_op_hash_functions(Oid opno,
541 RegProcedure *lhs_procno, RegProcedure *rhs_procno)
547 /* Ensure output args are initialized on failure */
549 *lhs_procno = InvalidOid;
551 *rhs_procno = InvalidOid;
554 * Search pg_amop to see if the target operator is registered as the "="
555 * operator of any hash opfamily. If the operator is registered in
556 * multiple opfamilies, assume we can use any one.
558 catlist = SearchSysCacheList1(AMOPOPID, ObjectIdGetDatum(opno));
560 for (i = 0; i < catlist->n_members; i++)
562 HeapTuple tuple = &catlist->members[i]->tuple;
563 Form_pg_amop aform = (Form_pg_amop) GETSTRUCT(tuple);
565 if (aform->amopmethod == HASH_AM_OID &&
566 aform->amopstrategy == HTEqualStrategyNumber)
569 * Get the matching support function(s). Failure probably
570 * shouldn't happen --- it implies a bogus opfamily --- but
571 * continue looking if so.
575 *lhs_procno = get_opfamily_proc(aform->amopfamily,
579 if (!OidIsValid(*lhs_procno))
581 /* Matching LHS found, done if caller doesn't want RHS */
587 /* Only one lookup needed if given operator is single-type */
588 if (aform->amoplefttype == aform->amoprighttype)
590 *rhs_procno = *lhs_procno;
597 *rhs_procno = get_opfamily_proc(aform->amopfamily,
598 aform->amoprighttype,
599 aform->amoprighttype,
601 if (!OidIsValid(*rhs_procno))
603 /* Forget any LHS function from this opfamily */
605 *lhs_procno = InvalidOid;
608 /* Matching RHS found, so done */
615 ReleaseSysCacheList(catlist);
621 * get_op_btree_interpretation
622 * Given an operator's OID, find out which btree opfamilies it belongs to,
623 * and what strategy number it has within each one. The results are
624 * returned as an OID list and a parallel integer list.
626 * In addition to the normal btree operators, we consider a <> operator to be
627 * a "member" of an opfamily if its negator is an equality operator of the
628 * opfamily. ROWCOMPARE_NE is returned as the strategy number for this case.
631 get_op_btree_interpretation(Oid opno, List **opfamilies, List **opstrats)
641 * Find all the pg_amop entries containing the operator.
643 catlist = SearchSysCacheList1(AMOPOPID, ObjectIdGetDatum(opno));
646 * If we can't find any opfamily containing the op, perhaps it is a <>
647 * operator. See if it has a negator that is in an opfamily.
650 if (catlist->n_members == 0)
652 Oid op_negator = get_negator(opno);
654 if (OidIsValid(op_negator))
657 ReleaseSysCacheList(catlist);
658 catlist = SearchSysCacheList1(AMOPOPID,
659 ObjectIdGetDatum(op_negator));
663 /* Now search the opfamilies */
664 for (i = 0; i < catlist->n_members; i++)
666 HeapTuple op_tuple = &catlist->members[i]->tuple;
667 Form_pg_amop op_form = (Form_pg_amop) GETSTRUCT(op_tuple);
669 StrategyNumber op_strategy;
672 if (op_form->amopmethod != BTREE_AM_OID)
675 /* Get the operator's btree strategy number */
676 opfamily_id = op_form->amopfamily;
677 op_strategy = (StrategyNumber) op_form->amopstrategy;
678 Assert(op_strategy >= 1 && op_strategy <= 5);
682 /* Only consider negators that are = */
683 if (op_strategy != BTEqualStrategyNumber)
685 op_strategy = ROWCOMPARE_NE;
688 *opfamilies = lappend_oid(*opfamilies, opfamily_id);
689 *opstrats = lappend_int(*opstrats, op_strategy);
692 ReleaseSysCacheList(catlist);
696 * equality_ops_are_compatible
697 * Return TRUE if the two given equality operators have compatible
700 * This is trivially true if they are the same operator. Otherwise,
701 * we look to see if they can be found in the same btree or hash opfamily.
702 * Either finding allows us to assume that they have compatible notions
703 * of equality. (The reason we need to do these pushups is that one might
704 * be a cross-type operator; for instance int24eq vs int4eq.)
707 equality_ops_are_compatible(Oid opno1, Oid opno2)
713 /* Easy if they're the same operator */
718 * We search through all the pg_amop entries for opno1.
720 catlist = SearchSysCacheList1(AMOPOPID, ObjectIdGetDatum(opno1));
723 for (i = 0; i < catlist->n_members; i++)
725 HeapTuple op_tuple = &catlist->members[i]->tuple;
726 Form_pg_amop op_form = (Form_pg_amop) GETSTRUCT(op_tuple);
728 /* must be btree or hash */
729 if (op_form->amopmethod == BTREE_AM_OID ||
730 op_form->amopmethod == HASH_AM_OID)
732 if (op_in_opfamily(opno2, op_form->amopfamily))
740 ReleaseSysCacheList(catlist);
746 /* ---------- AMPROC CACHES ---------- */
750 * Get the OID of the specified support function
751 * for the specified opfamily and datatypes.
753 * Returns InvalidOid if there is no pg_amproc entry for the given keys.
756 get_opfamily_proc(Oid opfamily, Oid lefttype, Oid righttype, int16 procnum)
759 Form_pg_amproc amproc_tup;
762 tp = SearchSysCache4(AMPROCNUM,
763 ObjectIdGetDatum(opfamily),
764 ObjectIdGetDatum(lefttype),
765 ObjectIdGetDatum(righttype),
766 Int16GetDatum(procnum));
767 if (!HeapTupleIsValid(tp))
769 amproc_tup = (Form_pg_amproc) GETSTRUCT(tp);
770 result = amproc_tup->amproc;
776 /* ---------- ATTRIBUTE CACHES ---------- */
780 * Given the relation id and the attribute number,
781 * return the "attname" field from the attribute relation.
783 * Note: returns a palloc'd copy of the string, or NULL if no such attribute.
786 get_attname(Oid relid, AttrNumber attnum)
790 tp = SearchSysCache2(ATTNUM,
791 ObjectIdGetDatum(relid),
792 Int16GetDatum(attnum));
793 if (HeapTupleIsValid(tp))
795 Form_pg_attribute att_tup = (Form_pg_attribute) GETSTRUCT(tp);
798 result = pstrdup(NameStr(att_tup->attname));
807 * get_relid_attribute_name
809 * Same as above routine get_attname(), except that error
810 * is handled by elog() instead of returning NULL.
813 get_relid_attribute_name(Oid relid, AttrNumber attnum)
817 attname = get_attname(relid, attnum);
819 elog(ERROR, "cache lookup failed for attribute %d of relation %u",
827 * Given the relation id and the attribute name,
828 * return the "attnum" field from the attribute relation.
830 * Returns InvalidAttrNumber if the attr doesn't exist (or is dropped).
833 get_attnum(Oid relid, const char *attname)
837 tp = SearchSysCacheAttName(relid, attname);
838 if (HeapTupleIsValid(tp))
840 Form_pg_attribute att_tup = (Form_pg_attribute) GETSTRUCT(tp);
843 result = att_tup->attnum;
848 return InvalidAttrNumber;
854 * Given the relation OID and the attribute number with the relation,
855 * return the attribute type OID.
858 get_atttype(Oid relid, AttrNumber attnum)
862 tp = SearchSysCache2(ATTNUM,
863 ObjectIdGetDatum(relid),
864 Int16GetDatum(attnum));
865 if (HeapTupleIsValid(tp))
867 Form_pg_attribute att_tup = (Form_pg_attribute) GETSTRUCT(tp);
870 result = att_tup->atttypid;
881 * Given the relation id and the attribute number,
882 * return the "atttypmod" field from the attribute relation.
885 get_atttypmod(Oid relid, AttrNumber attnum)
889 tp = SearchSysCache2(ATTNUM,
890 ObjectIdGetDatum(relid),
891 Int16GetDatum(attnum));
892 if (HeapTupleIsValid(tp))
894 Form_pg_attribute att_tup = (Form_pg_attribute) GETSTRUCT(tp);
897 result = att_tup->atttypmod;
908 * A two-fer: given the relation id and the attribute number,
909 * fetch both type OID and atttypmod in a single cache lookup.
911 * Unlike the otherwise-similar get_atttype/get_atttypmod, this routine
912 * raises an error if it can't obtain the information.
915 get_atttypetypmod(Oid relid, AttrNumber attnum,
916 Oid *typid, int32 *typmod)
919 Form_pg_attribute att_tup;
921 tp = SearchSysCache2(ATTNUM,
922 ObjectIdGetDatum(relid),
923 Int16GetDatum(attnum));
924 if (!HeapTupleIsValid(tp))
925 elog(ERROR, "cache lookup failed for attribute %d of relation %u",
927 att_tup = (Form_pg_attribute) GETSTRUCT(tp);
929 *typid = att_tup->atttypid;
930 *typmod = att_tup->atttypmod;
934 /* ---------- CONSTRAINT CACHE ---------- */
937 * get_constraint_name
938 * Returns the name of a given pg_constraint entry.
940 * Returns a palloc'd copy of the string, or NULL if no such constraint.
942 * NOTE: since constraint name is not unique, be wary of code that uses this
943 * for anything except preparing error messages.
946 get_constraint_name(Oid conoid)
950 tp = SearchSysCache1(CONSTROID, ObjectIdGetDatum(conoid));
951 if (HeapTupleIsValid(tp))
953 Form_pg_constraint contup = (Form_pg_constraint) GETSTRUCT(tp);
956 result = pstrdup(NameStr(contup->conname));
964 /* ---------- OPCLASS CACHE ---------- */
969 * Returns the OID of the operator family the opclass belongs to.
972 get_opclass_family(Oid opclass)
975 Form_pg_opclass cla_tup;
978 tp = SearchSysCache1(CLAOID, ObjectIdGetDatum(opclass));
979 if (!HeapTupleIsValid(tp))
980 elog(ERROR, "cache lookup failed for opclass %u", opclass);
981 cla_tup = (Form_pg_opclass) GETSTRUCT(tp);
983 result = cla_tup->opcfamily;
989 * get_opclass_input_type
991 * Returns the OID of the datatype the opclass indexes.
994 get_opclass_input_type(Oid opclass)
997 Form_pg_opclass cla_tup;
1000 tp = SearchSysCache1(CLAOID, ObjectIdGetDatum(opclass));
1001 if (!HeapTupleIsValid(tp))
1002 elog(ERROR, "cache lookup failed for opclass %u", opclass);
1003 cla_tup = (Form_pg_opclass) GETSTRUCT(tp);
1005 result = cla_tup->opcintype;
1006 ReleaseSysCache(tp);
1010 /* ---------- OPERATOR CACHE ---------- */
1015 * Returns the regproc id of the routine used to implement an
1016 * operator given the operator oid.
1019 get_opcode(Oid opno)
1023 tp = SearchSysCache1(OPEROID, ObjectIdGetDatum(opno));
1024 if (HeapTupleIsValid(tp))
1026 Form_pg_operator optup = (Form_pg_operator) GETSTRUCT(tp);
1027 RegProcedure result;
1029 result = optup->oprcode;
1030 ReleaseSysCache(tp);
1034 return (RegProcedure) InvalidOid;
1039 * returns the name of the operator with the given opno
1041 * Note: returns a palloc'd copy of the string, or NULL if no such operator.
1044 get_opname(Oid opno)
1048 tp = SearchSysCache1(OPEROID, ObjectIdGetDatum(opno));
1049 if (HeapTupleIsValid(tp))
1051 Form_pg_operator optup = (Form_pg_operator) GETSTRUCT(tp);
1054 result = pstrdup(NameStr(optup->oprname));
1055 ReleaseSysCache(tp);
1065 * Returns the left and right input datatypes for an operator
1066 * (InvalidOid if not relevant).
1069 op_input_types(Oid opno, Oid *lefttype, Oid *righttype)
1072 Form_pg_operator optup;
1074 tp = SearchSysCache1(OPEROID, ObjectIdGetDatum(opno));
1075 if (!HeapTupleIsValid(tp)) /* shouldn't happen */
1076 elog(ERROR, "cache lookup failed for operator %u", opno);
1077 optup = (Form_pg_operator) GETSTRUCT(tp);
1078 *lefttype = optup->oprleft;
1079 *righttype = optup->oprright;
1080 ReleaseSysCache(tp);
1086 * Returns true if the operator is potentially mergejoinable. (The planner
1087 * will fail to find any mergejoin plans unless there are suitable btree
1088 * opfamily entries for this operator and associated sortops. The pg_operator
1089 * flag is just a hint to tell the planner whether to bother looking.)
1091 * In some cases (currently only array_eq), mergejoinability depends on the
1092 * specific input data type the operator is invoked for, so that must be
1093 * passed as well. We currently assume that only one input's type is needed
1094 * to check this --- by convention, pass the left input's data type.
1097 op_mergejoinable(Oid opno, Oid inputtype)
1100 bool result = false;
1102 if (opno == ARRAY_EQ_OP)
1105 * For array_eq, can sort if element type has a default btree opclass.
1106 * We could use GetDefaultOpClass, but that's fairly expensive and not
1107 * cached, so let's use the typcache instead.
1109 Oid elem_type = get_base_element_type(inputtype);
1111 if (OidIsValid(elem_type))
1113 TypeCacheEntry *typentry;
1115 typentry = lookup_type_cache(elem_type, TYPECACHE_BTREE_OPFAMILY);
1116 if (OidIsValid(typentry->btree_opf))
1122 /* For all other operators, rely on pg_operator.oprcanmerge */
1123 tp = SearchSysCache1(OPEROID, ObjectIdGetDatum(opno));
1124 if (HeapTupleIsValid(tp))
1126 Form_pg_operator optup = (Form_pg_operator) GETSTRUCT(tp);
1128 result = optup->oprcanmerge;
1129 ReleaseSysCache(tp);
1138 * Returns true if the operator is hashjoinable. (There must be a suitable
1139 * hash opfamily entry for this operator if it is so marked.)
1141 * In some cases (currently only array_eq), hashjoinability depends on the
1142 * specific input data type the operator is invoked for, so that must be
1143 * passed as well. We currently assume that only one input's type is needed
1144 * to check this --- by convention, pass the left input's data type.
1147 op_hashjoinable(Oid opno, Oid inputtype)
1150 bool result = false;
1152 if (opno == ARRAY_EQ_OP)
1154 /* For array_eq, can hash if element type has a default hash opclass */
1155 Oid elem_type = get_base_element_type(inputtype);
1157 if (OidIsValid(elem_type))
1159 TypeCacheEntry *typentry;
1161 typentry = lookup_type_cache(elem_type, TYPECACHE_HASH_OPFAMILY);
1162 if (OidIsValid(typentry->hash_opf))
1168 /* For all other operators, rely on pg_operator.oprcanhash */
1169 tp = SearchSysCache1(OPEROID, ObjectIdGetDatum(opno));
1170 if (HeapTupleIsValid(tp))
1172 Form_pg_operator optup = (Form_pg_operator) GETSTRUCT(tp);
1174 result = optup->oprcanhash;
1175 ReleaseSysCache(tp);
1184 * Get the proisstrict flag for the operator's underlying function.
1189 RegProcedure funcid = get_opcode(opno);
1191 if (funcid == (RegProcedure) InvalidOid)
1192 elog(ERROR, "operator %u does not exist", opno);
1194 return func_strict((Oid) funcid);
1200 * Get the provolatile flag for the operator's underlying function.
1203 op_volatile(Oid opno)
1205 RegProcedure funcid = get_opcode(opno);
1207 if (funcid == (RegProcedure) InvalidOid)
1208 elog(ERROR, "operator %u does not exist", opno);
1210 return func_volatile((Oid) funcid);
1216 * Returns the corresponding commutator of an operator.
1219 get_commutator(Oid opno)
1223 tp = SearchSysCache1(OPEROID, ObjectIdGetDatum(opno));
1224 if (HeapTupleIsValid(tp))
1226 Form_pg_operator optup = (Form_pg_operator) GETSTRUCT(tp);
1229 result = optup->oprcom;
1230 ReleaseSysCache(tp);
1240 * Returns the corresponding negator of an operator.
1243 get_negator(Oid opno)
1247 tp = SearchSysCache1(OPEROID, ObjectIdGetDatum(opno));
1248 if (HeapTupleIsValid(tp))
1250 Form_pg_operator optup = (Form_pg_operator) GETSTRUCT(tp);
1253 result = optup->oprnegate;
1254 ReleaseSysCache(tp);
1264 * Returns procedure id for computing selectivity of an operator.
1267 get_oprrest(Oid opno)
1271 tp = SearchSysCache1(OPEROID, ObjectIdGetDatum(opno));
1272 if (HeapTupleIsValid(tp))
1274 Form_pg_operator optup = (Form_pg_operator) GETSTRUCT(tp);
1275 RegProcedure result;
1277 result = optup->oprrest;
1278 ReleaseSysCache(tp);
1282 return (RegProcedure) InvalidOid;
1288 * Returns procedure id for computing selectivity of a join.
1291 get_oprjoin(Oid opno)
1295 tp = SearchSysCache1(OPEROID, ObjectIdGetDatum(opno));
1296 if (HeapTupleIsValid(tp))
1298 Form_pg_operator optup = (Form_pg_operator) GETSTRUCT(tp);
1299 RegProcedure result;
1301 result = optup->oprjoin;
1302 ReleaseSysCache(tp);
1306 return (RegProcedure) InvalidOid;
1309 /* ---------- FUNCTION CACHE ---------- */
1313 * returns the name of the function with the given funcid
1315 * Note: returns a palloc'd copy of the string, or NULL if no such function.
1318 get_func_name(Oid funcid)
1322 tp = SearchSysCache1(PROCOID, ObjectIdGetDatum(funcid));
1323 if (HeapTupleIsValid(tp))
1325 Form_pg_proc functup = (Form_pg_proc) GETSTRUCT(tp);
1328 result = pstrdup(NameStr(functup->proname));
1329 ReleaseSysCache(tp);
1337 * get_func_namespace
1339 * Returns the pg_namespace OID associated with a given function.
1342 get_func_namespace(Oid funcid)
1346 tp = SearchSysCache1(PROCOID, ObjectIdGetDatum(funcid));
1347 if (HeapTupleIsValid(tp))
1349 Form_pg_proc functup = (Form_pg_proc) GETSTRUCT(tp);
1352 result = functup->pronamespace;
1353 ReleaseSysCache(tp);
1362 * Given procedure id, return the function's result type.
1365 get_func_rettype(Oid funcid)
1370 tp = SearchSysCache1(PROCOID, ObjectIdGetDatum(funcid));
1371 if (!HeapTupleIsValid(tp))
1372 elog(ERROR, "cache lookup failed for function %u", funcid);
1374 result = ((Form_pg_proc) GETSTRUCT(tp))->prorettype;
1375 ReleaseSysCache(tp);
1381 * Given procedure id, return the number of arguments.
1384 get_func_nargs(Oid funcid)
1389 tp = SearchSysCache1(PROCOID, ObjectIdGetDatum(funcid));
1390 if (!HeapTupleIsValid(tp))
1391 elog(ERROR, "cache lookup failed for function %u", funcid);
1393 result = ((Form_pg_proc) GETSTRUCT(tp))->pronargs;
1394 ReleaseSysCache(tp);
1399 * get_func_signature
1400 * Given procedure id, return the function's argument and result types.
1401 * (The return value is the result type.)
1403 * The arguments are returned as a palloc'd array.
1406 get_func_signature(Oid funcid, Oid **argtypes, int *nargs)
1409 Form_pg_proc procstruct;
1412 tp = SearchSysCache1(PROCOID, ObjectIdGetDatum(funcid));
1413 if (!HeapTupleIsValid(tp))
1414 elog(ERROR, "cache lookup failed for function %u", funcid);
1416 procstruct = (Form_pg_proc) GETSTRUCT(tp);
1418 result = procstruct->prorettype;
1419 *nargs = (int) procstruct->pronargs;
1420 Assert(*nargs == procstruct->proargtypes.dim1);
1421 *argtypes = (Oid *) palloc(*nargs * sizeof(Oid));
1422 memcpy(*argtypes, procstruct->proargtypes.values, *nargs * sizeof(Oid));
1424 ReleaseSysCache(tp);
1430 * Given procedure id, return the function's proretset flag.
1433 get_func_retset(Oid funcid)
1438 tp = SearchSysCache1(PROCOID, ObjectIdGetDatum(funcid));
1439 if (!HeapTupleIsValid(tp))
1440 elog(ERROR, "cache lookup failed for function %u", funcid);
1442 result = ((Form_pg_proc) GETSTRUCT(tp))->proretset;
1443 ReleaseSysCache(tp);
1449 * Given procedure id, return the function's proisstrict flag.
1452 func_strict(Oid funcid)
1457 tp = SearchSysCache1(PROCOID, ObjectIdGetDatum(funcid));
1458 if (!HeapTupleIsValid(tp))
1459 elog(ERROR, "cache lookup failed for function %u", funcid);
1461 result = ((Form_pg_proc) GETSTRUCT(tp))->proisstrict;
1462 ReleaseSysCache(tp);
1468 * Given procedure id, return the function's provolatile flag.
1471 func_volatile(Oid funcid)
1476 tp = SearchSysCache1(PROCOID, ObjectIdGetDatum(funcid));
1477 if (!HeapTupleIsValid(tp))
1478 elog(ERROR, "cache lookup failed for function %u", funcid);
1480 result = ((Form_pg_proc) GETSTRUCT(tp))->provolatile;
1481 ReleaseSysCache(tp);
1487 * Given procedure id, return the function's procost field.
1490 get_func_cost(Oid funcid)
1495 tp = SearchSysCache1(PROCOID, ObjectIdGetDatum(funcid));
1496 if (!HeapTupleIsValid(tp))
1497 elog(ERROR, "cache lookup failed for function %u", funcid);
1499 result = ((Form_pg_proc) GETSTRUCT(tp))->procost;
1500 ReleaseSysCache(tp);
1506 * Given procedure id, return the function's prorows field.
1509 get_func_rows(Oid funcid)
1514 tp = SearchSysCache1(PROCOID, ObjectIdGetDatum(funcid));
1515 if (!HeapTupleIsValid(tp))
1516 elog(ERROR, "cache lookup failed for function %u", funcid);
1518 result = ((Form_pg_proc) GETSTRUCT(tp))->prorows;
1519 ReleaseSysCache(tp);
1523 /* ---------- RELATION CACHE ---------- */
1527 * Given name and namespace of a relation, look up the OID.
1529 * Returns InvalidOid if there is no such relation.
1532 get_relname_relid(const char *relname, Oid relnamespace)
1534 return GetSysCacheOid2(RELNAMENSP,
1535 PointerGetDatum(relname),
1536 ObjectIdGetDatum(relnamespace));
1543 * Returns the number of attributes for a given relation.
1546 get_relnatts(Oid relid)
1550 tp = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
1551 if (HeapTupleIsValid(tp))
1553 Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
1556 result = reltup->relnatts;
1557 ReleaseSysCache(tp);
1561 return InvalidAttrNumber;
1567 * Returns the name of a given relation.
1569 * Returns a palloc'd copy of the string, or NULL if no such relation.
1571 * NOTE: since relation name is not unique, be wary of code that uses this
1572 * for anything except preparing error messages.
1575 get_rel_name(Oid relid)
1579 tp = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
1580 if (HeapTupleIsValid(tp))
1582 Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
1585 result = pstrdup(NameStr(reltup->relname));
1586 ReleaseSysCache(tp);
1596 * Returns the pg_namespace OID associated with a given relation.
1599 get_rel_namespace(Oid relid)
1603 tp = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
1604 if (HeapTupleIsValid(tp))
1606 Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
1609 result = reltup->relnamespace;
1610 ReleaseSysCache(tp);
1620 * Returns the pg_type OID associated with a given relation.
1622 * Note: not all pg_class entries have associated pg_type OIDs; so be
1623 * careful to check for InvalidOid result.
1626 get_rel_type_id(Oid relid)
1630 tp = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
1631 if (HeapTupleIsValid(tp))
1633 Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
1636 result = reltup->reltype;
1637 ReleaseSysCache(tp);
1647 * Returns the relkind associated with a given relation.
1650 get_rel_relkind(Oid relid)
1654 tp = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
1655 if (HeapTupleIsValid(tp))
1657 Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
1660 result = reltup->relkind;
1661 ReleaseSysCache(tp);
1669 * get_rel_tablespace
1671 * Returns the pg_tablespace OID associated with a given relation.
1673 * Note: InvalidOid might mean either that we couldn't find the relation,
1674 * or that it is in the database's default tablespace.
1677 get_rel_tablespace(Oid relid)
1681 tp = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
1682 if (HeapTupleIsValid(tp))
1684 Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
1687 result = reltup->reltablespace;
1688 ReleaseSysCache(tp);
1696 /* ---------- TYPE CACHE ---------- */
1701 * Given the type OID, determine whether the type is defined
1702 * (if not, it's only a shell).
1705 get_typisdefined(Oid typid)
1709 tp = SearchSysCache1(TYPEOID, ObjectIdGetDatum(typid));
1710 if (HeapTupleIsValid(tp))
1712 Form_pg_type typtup = (Form_pg_type) GETSTRUCT(tp);
1715 result = typtup->typisdefined;
1716 ReleaseSysCache(tp);
1726 * Given the type OID, return the length of the type.
1729 get_typlen(Oid typid)
1733 tp = SearchSysCache1(TYPEOID, ObjectIdGetDatum(typid));
1734 if (HeapTupleIsValid(tp))
1736 Form_pg_type typtup = (Form_pg_type) GETSTRUCT(tp);
1739 result = typtup->typlen;
1740 ReleaseSysCache(tp);
1750 * Given the type OID, determine whether the type is returned by value or
1751 * not. Returns true if by value, false if by reference.
1754 get_typbyval(Oid typid)
1758 tp = SearchSysCache1(TYPEOID, ObjectIdGetDatum(typid));
1759 if (HeapTupleIsValid(tp))
1761 Form_pg_type typtup = (Form_pg_type) GETSTRUCT(tp);
1764 result = typtup->typbyval;
1765 ReleaseSysCache(tp);
1775 * A two-fer: given the type OID, return both typlen and typbyval.
1777 * Since both pieces of info are needed to know how to copy a Datum,
1778 * many places need both. Might as well get them with one cache lookup
1779 * instead of two. Also, this routine raises an error instead of
1780 * returning a bogus value when given a bad type OID.
1783 get_typlenbyval(Oid typid, int16 *typlen, bool *typbyval)
1786 Form_pg_type typtup;
1788 tp = SearchSysCache1(TYPEOID, ObjectIdGetDatum(typid));
1789 if (!HeapTupleIsValid(tp))
1790 elog(ERROR, "cache lookup failed for type %u", typid);
1791 typtup = (Form_pg_type) GETSTRUCT(tp);
1792 *typlen = typtup->typlen;
1793 *typbyval = typtup->typbyval;
1794 ReleaseSysCache(tp);
1798 * get_typlenbyvalalign
1800 * A three-fer: given the type OID, return typlen, typbyval, typalign.
1803 get_typlenbyvalalign(Oid typid, int16 *typlen, bool *typbyval,
1807 Form_pg_type typtup;
1809 tp = SearchSysCache1(TYPEOID, ObjectIdGetDatum(typid));
1810 if (!HeapTupleIsValid(tp))
1811 elog(ERROR, "cache lookup failed for type %u", typid);
1812 typtup = (Form_pg_type) GETSTRUCT(tp);
1813 *typlen = typtup->typlen;
1814 *typbyval = typtup->typbyval;
1815 *typalign = typtup->typalign;
1816 ReleaseSysCache(tp);
1821 * Given a pg_type row, select the type OID to pass to I/O functions
1823 * Formerly, all I/O functions were passed pg_type.typelem as their second
1824 * parameter, but we now have a more complex rule about what to pass.
1825 * This knowledge is intended to be centralized here --- direct references
1826 * to typelem elsewhere in the code are wrong, if they are associated with
1827 * I/O calls and not with actual subscripting operations! (But see
1828 * bootstrap.c's boot_get_type_io_data() if you need to change this.)
1830 * As of PostgreSQL 8.1, output functions receive only the value itself
1831 * and not any auxiliary parameters, so the name of this routine is now
1832 * a bit of a misnomer ... it should be getTypeInputParam.
1835 getTypeIOParam(HeapTuple typeTuple)
1837 Form_pg_type typeStruct = (Form_pg_type) GETSTRUCT(typeTuple);
1840 * Array types get their typelem as parameter; everybody else gets their
1841 * own type OID as parameter. (As of 8.2, domains must get their own OID
1842 * even if their base type is an array.)
1844 if (typeStruct->typtype == TYPTYPE_BASE && OidIsValid(typeStruct->typelem))
1845 return typeStruct->typelem;
1847 return HeapTupleGetOid(typeTuple);
1853 * A six-fer: given the type OID, return typlen, typbyval, typalign,
1854 * typdelim, typioparam, and IO function OID. The IO function
1855 * returned is controlled by IOFuncSelector
1858 get_type_io_data(Oid typid,
1859 IOFuncSelector which_func,
1867 HeapTuple typeTuple;
1868 Form_pg_type typeStruct;
1871 * In bootstrap mode, pass it off to bootstrap.c. This hack allows us to
1872 * use array_in and array_out during bootstrap.
1874 if (IsBootstrapProcessingMode())
1879 boot_get_type_io_data(typid,
1896 elog(ERROR, "binary I/O not supported during bootstrap");
1902 typeTuple = SearchSysCache1(TYPEOID, ObjectIdGetDatum(typid));
1903 if (!HeapTupleIsValid(typeTuple))
1904 elog(ERROR, "cache lookup failed for type %u", typid);
1905 typeStruct = (Form_pg_type) GETSTRUCT(typeTuple);
1907 *typlen = typeStruct->typlen;
1908 *typbyval = typeStruct->typbyval;
1909 *typalign = typeStruct->typalign;
1910 *typdelim = typeStruct->typdelim;
1911 *typioparam = getTypeIOParam(typeTuple);
1915 *func = typeStruct->typinput;
1918 *func = typeStruct->typoutput;
1920 case IOFunc_receive:
1921 *func = typeStruct->typreceive;
1924 *func = typeStruct->typsend;
1927 ReleaseSysCache(typeTuple);
1932 get_typalign(Oid typid)
1936 tp = SearchSysCache1(TYPEOID, ObjectIdGetDatum(typid));
1937 if (HeapTupleIsValid(tp))
1939 Form_pg_type typtup = (Form_pg_type) GETSTRUCT(tp);
1942 result = typtup->typalign;
1943 ReleaseSysCache(tp);
1952 get_typstorage(Oid typid)
1956 tp = SearchSysCache1(TYPEOID, ObjectIdGetDatum(typid));
1957 if (HeapTupleIsValid(tp))
1959 Form_pg_type typtup = (Form_pg_type) GETSTRUCT(tp);
1962 result = typtup->typstorage;
1963 ReleaseSysCache(tp);
1972 * Given a type OID, return the type's default value, if any.
1974 * The result is a palloc'd expression node tree, or NULL if there
1975 * is no defined default for the datatype.
1977 * NB: caller should be prepared to coerce result to correct datatype;
1978 * the returned expression tree might produce something of the wrong type.
1981 get_typdefault(Oid typid)
1983 HeapTuple typeTuple;
1989 typeTuple = SearchSysCache1(TYPEOID, ObjectIdGetDatum(typid));
1990 if (!HeapTupleIsValid(typeTuple))
1991 elog(ERROR, "cache lookup failed for type %u", typid);
1992 type = (Form_pg_type) GETSTRUCT(typeTuple);
1995 * typdefault and typdefaultbin are potentially null, so don't try to
1996 * access 'em as struct fields. Must do it the hard way with
1999 datum = SysCacheGetAttr(TYPEOID,
2001 Anum_pg_type_typdefaultbin,
2006 /* We have an expression default */
2007 expr = stringToNode(TextDatumGetCString(datum));
2011 /* Perhaps we have a plain literal default */
2012 datum = SysCacheGetAttr(TYPEOID,
2014 Anum_pg_type_typdefault,
2019 char *strDefaultVal;
2021 /* Convert text datum to C string */
2022 strDefaultVal = TextDatumGetCString(datum);
2023 /* Convert C string to a value of the given type */
2024 datum = OidInputFunctionCall(type->typinput, strDefaultVal,
2025 getTypeIOParam(typeTuple), -1);
2026 /* Build a Const node containing the value */
2027 expr = (Node *) makeConst(typid,
2033 pfree(strDefaultVal);
2042 ReleaseSysCache(typeTuple);
2049 * If the given type is a domain, return its base type;
2050 * otherwise return the type's own OID.
2053 getBaseType(Oid typid)
2057 return getBaseTypeAndTypmod(typid, &typmod);
2061 * getBaseTypeAndTypmod
2062 * If the given type is a domain, return its base type and typmod;
2063 * otherwise return the type's own OID, and leave *typmod unchanged.
2065 * Note that the "applied typmod" should be -1 for every domain level
2066 * above the bottommost; therefore, if the passed-in typid is indeed
2067 * a domain, *typmod should be -1.
2070 getBaseTypeAndTypmod(Oid typid, int32 *typmod)
2073 * We loop to find the bottom base type in a stack of domains.
2078 Form_pg_type typTup;
2080 tup = SearchSysCache1(TYPEOID, ObjectIdGetDatum(typid));
2081 if (!HeapTupleIsValid(tup))
2082 elog(ERROR, "cache lookup failed for type %u", typid);
2083 typTup = (Form_pg_type) GETSTRUCT(tup);
2084 if (typTup->typtype != TYPTYPE_DOMAIN)
2086 /* Not a domain, so done */
2087 ReleaseSysCache(tup);
2091 Assert(*typmod == -1);
2092 typid = typTup->typbasetype;
2093 *typmod = typTup->typtypmod;
2095 ReleaseSysCache(tup);
2104 * Given a type OID and a typmod value (pass -1 if typmod is unknown),
2105 * estimate the average width of values of the type. This is used by
2106 * the planner, which doesn't require absolutely correct results;
2107 * it's OK (and expected) to guess if we don't know for sure.
2110 get_typavgwidth(Oid typid, int32 typmod)
2112 int typlen = get_typlen(typid);
2116 * Easy if it's a fixed-width type
2122 * type_maximum_size knows the encoding of typmod for some datatypes;
2123 * don't duplicate that knowledge here.
2125 maxwidth = type_maximum_size(typid, typmod);
2129 * For BPCHAR, the max width is also the only width. Otherwise we
2130 * need to guess about the typical data width given the max. A sliding
2131 * scale for percentage of max width seems reasonable.
2133 if (typid == BPCHAROID)
2136 return maxwidth; /* assume full width */
2137 if (maxwidth < 1000)
2138 return 32 + (maxwidth - 32) / 2; /* assume 50% */
2141 * Beyond 1000, assume we're looking at something like
2142 * "varchar(10000)" where the limit isn't actually reached often, and
2143 * use a fixed estimate.
2145 return 32 + (1000 - 32) / 2;
2149 * Ooops, we have no idea ... wild guess time.
2157 * Given the type OID, find if it is a basic type, a complex type, etc.
2158 * It returns the null char if the cache lookup fails...
2161 get_typtype(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->typtype;
2172 ReleaseSysCache(tp);
2182 * Convenience function to determine whether a type OID represents
2183 * a "rowtype" type --- either RECORD or a named composite type.
2186 type_is_rowtype(Oid typid)
2188 return (typid == RECORDOID || get_typtype(typid) == TYPTYPE_COMPOSITE);
2193 * Returns true if the given type is an enum type.
2196 type_is_enum(Oid typid)
2198 return (get_typtype(typid) == TYPTYPE_ENUM);
2202 * get_type_category_preferred
2204 * Given the type OID, fetch its category and preferred-type status.
2205 * Throws error on failure.
2208 get_type_category_preferred(Oid typid, char *typcategory, bool *typispreferred)
2211 Form_pg_type typtup;
2213 tp = SearchSysCache1(TYPEOID, ObjectIdGetDatum(typid));
2214 if (!HeapTupleIsValid(tp))
2215 elog(ERROR, "cache lookup failed for type %u", typid);
2216 typtup = (Form_pg_type) GETSTRUCT(tp);
2217 *typcategory = typtup->typcategory;
2218 *typispreferred = typtup->typispreferred;
2219 ReleaseSysCache(tp);
2225 * Given the type OID, get the typrelid (InvalidOid if not a complex
2229 get_typ_typrelid(Oid typid)
2233 tp = SearchSysCache1(TYPEOID, ObjectIdGetDatum(typid));
2234 if (HeapTupleIsValid(tp))
2236 Form_pg_type typtup = (Form_pg_type) GETSTRUCT(tp);
2239 result = typtup->typrelid;
2240 ReleaseSysCache(tp);
2250 * Given the type OID, get the typelem (InvalidOid if not an array type).
2252 * NB: this only considers varlena arrays to be true arrays; InvalidOid is
2253 * returned if the input is a fixed-length array type.
2256 get_element_type(Oid typid)
2260 tp = SearchSysCache1(TYPEOID, ObjectIdGetDatum(typid));
2261 if (HeapTupleIsValid(tp))
2263 Form_pg_type typtup = (Form_pg_type) GETSTRUCT(tp);
2266 if (typtup->typlen == -1)
2267 result = typtup->typelem;
2269 result = InvalidOid;
2270 ReleaseSysCache(tp);
2280 * Given the type OID, get the corresponding "true" array type.
2281 * Returns InvalidOid if no array type can be found.
2284 get_array_type(Oid typid)
2287 Oid result = InvalidOid;
2289 tp = SearchSysCache1(TYPEOID, ObjectIdGetDatum(typid));
2290 if (HeapTupleIsValid(tp))
2292 result = ((Form_pg_type) GETSTRUCT(tp))->typarray;
2293 ReleaseSysCache(tp);
2299 * get_base_element_type
2300 * Given the type OID, get the typelem, looking "through" any domain
2301 * to its underlying array type.
2303 * This is equivalent to get_element_type(getBaseType(typid)), but avoids
2304 * an extra cache lookup. Note that it fails to provide any information
2305 * about the typmod of the array.
2308 get_base_element_type(Oid typid)
2311 * We loop to find the bottom base type in a stack of domains.
2316 Form_pg_type typTup;
2318 tup = SearchSysCache1(TYPEOID, ObjectIdGetDatum(typid));
2319 if (!HeapTupleIsValid(tup))
2321 typTup = (Form_pg_type) GETSTRUCT(tup);
2322 if (typTup->typtype != TYPTYPE_DOMAIN)
2324 /* Not a domain, so stop descending */
2327 /* This test must match get_element_type */
2328 if (typTup->typlen == -1)
2329 result = typTup->typelem;
2331 result = InvalidOid;
2332 ReleaseSysCache(tup);
2336 typid = typTup->typbasetype;
2337 ReleaseSysCache(tup);
2340 /* Like get_element_type, silently return InvalidOid for bogus input */
2347 * Get info needed for converting values of a type to internal form
2350 getTypeInputInfo(Oid type, Oid *typInput, Oid *typIOParam)
2352 HeapTuple typeTuple;
2355 typeTuple = SearchSysCache1(TYPEOID, ObjectIdGetDatum(type));
2356 if (!HeapTupleIsValid(typeTuple))
2357 elog(ERROR, "cache lookup failed for type %u", type);
2358 pt = (Form_pg_type) GETSTRUCT(typeTuple);
2360 if (!pt->typisdefined)
2362 (errcode(ERRCODE_UNDEFINED_OBJECT),
2363 errmsg("type %s is only a shell",
2364 format_type_be(type))));
2365 if (!OidIsValid(pt->typinput))
2367 (errcode(ERRCODE_UNDEFINED_FUNCTION),
2368 errmsg("no input function available for type %s",
2369 format_type_be(type))));
2371 *typInput = pt->typinput;
2372 *typIOParam = getTypeIOParam(typeTuple);
2374 ReleaseSysCache(typeTuple);
2380 * Get info needed for printing values of a type
2383 getTypeOutputInfo(Oid type, Oid *typOutput, bool *typIsVarlena)
2385 HeapTuple typeTuple;
2388 typeTuple = SearchSysCache1(TYPEOID, ObjectIdGetDatum(type));
2389 if (!HeapTupleIsValid(typeTuple))
2390 elog(ERROR, "cache lookup failed for type %u", type);
2391 pt = (Form_pg_type) GETSTRUCT(typeTuple);
2393 if (!pt->typisdefined)
2395 (errcode(ERRCODE_UNDEFINED_OBJECT),
2396 errmsg("type %s is only a shell",
2397 format_type_be(type))));
2398 if (!OidIsValid(pt->typoutput))
2400 (errcode(ERRCODE_UNDEFINED_FUNCTION),
2401 errmsg("no output function available for type %s",
2402 format_type_be(type))));
2404 *typOutput = pt->typoutput;
2405 *typIsVarlena = (!pt->typbyval) && (pt->typlen == -1);
2407 ReleaseSysCache(typeTuple);
2411 * getTypeBinaryInputInfo
2413 * Get info needed for binary input of values of a type
2416 getTypeBinaryInputInfo(Oid type, Oid *typReceive, Oid *typIOParam)
2418 HeapTuple typeTuple;
2421 typeTuple = SearchSysCache1(TYPEOID, ObjectIdGetDatum(type));
2422 if (!HeapTupleIsValid(typeTuple))
2423 elog(ERROR, "cache lookup failed for type %u", type);
2424 pt = (Form_pg_type) GETSTRUCT(typeTuple);
2426 if (!pt->typisdefined)
2428 (errcode(ERRCODE_UNDEFINED_OBJECT),
2429 errmsg("type %s is only a shell",
2430 format_type_be(type))));
2431 if (!OidIsValid(pt->typreceive))
2433 (errcode(ERRCODE_UNDEFINED_FUNCTION),
2434 errmsg("no binary input function available for type %s",
2435 format_type_be(type))));
2437 *typReceive = pt->typreceive;
2438 *typIOParam = getTypeIOParam(typeTuple);
2440 ReleaseSysCache(typeTuple);
2444 * getTypeBinaryOutputInfo
2446 * Get info needed for binary output of values of a type
2449 getTypeBinaryOutputInfo(Oid type, Oid *typSend, bool *typIsVarlena)
2451 HeapTuple typeTuple;
2454 typeTuple = SearchSysCache1(TYPEOID, ObjectIdGetDatum(type));
2455 if (!HeapTupleIsValid(typeTuple))
2456 elog(ERROR, "cache lookup failed for type %u", type);
2457 pt = (Form_pg_type) GETSTRUCT(typeTuple);
2459 if (!pt->typisdefined)
2461 (errcode(ERRCODE_UNDEFINED_OBJECT),
2462 errmsg("type %s is only a shell",
2463 format_type_be(type))));
2464 if (!OidIsValid(pt->typsend))
2466 (errcode(ERRCODE_UNDEFINED_FUNCTION),
2467 errmsg("no binary output function available for type %s",
2468 format_type_be(type))));
2470 *typSend = pt->typsend;
2471 *typIsVarlena = (!pt->typbyval) && (pt->typlen == -1);
2473 ReleaseSysCache(typeTuple);
2479 * Given the type OID, return the type's typmodin procedure, if any.
2482 get_typmodin(Oid typid)
2486 tp = SearchSysCache1(TYPEOID, ObjectIdGetDatum(typid));
2487 if (HeapTupleIsValid(tp))
2489 Form_pg_type typtup = (Form_pg_type) GETSTRUCT(tp);
2492 result = typtup->typmodin;
2493 ReleaseSysCache(tp);
2504 * Given the type OID, return the type's typmodout procedure, if any.
2507 get_typmodout(Oid typid)
2511 tp = SearchSysCache1(TYPEOID, ObjectIdGetDatum(typid));
2512 if (HeapTupleIsValid(tp))
2514 Form_pg_type typtup = (Form_pg_type) GETSTRUCT(tp);
2517 result = typtup->typmodout;
2518 ReleaseSysCache(tp);
2524 #endif /* NOT_USED */
2527 /* ---------- STATISTICS CACHE ---------- */
2532 * Given the table and attribute number of a column, get the average
2533 * width of entries in the column. Return zero if no data available.
2535 * Currently this is only consulted for individual tables, not for inheritance
2536 * trees, so we don't need an "inh" parameter.
2538 * Calling a hook at this point looks somewhat strange, but is required
2539 * because the optimizer calls this function without any other way for
2540 * plug-ins to control the result.
2543 get_attavgwidth(Oid relid, AttrNumber attnum)
2548 if (get_attavgwidth_hook)
2550 stawidth = (*get_attavgwidth_hook) (relid, attnum);
2554 tp = SearchSysCache3(STATRELATTINH,
2555 ObjectIdGetDatum(relid),
2556 Int16GetDatum(attnum),
2557 BoolGetDatum(false));
2558 if (HeapTupleIsValid(tp))
2560 stawidth = ((Form_pg_statistic) GETSTRUCT(tp))->stawidth;
2561 ReleaseSysCache(tp);
2571 * Extract the contents of a "slot" of a pg_statistic tuple.
2572 * Returns TRUE if requested slot type was found, else FALSE.
2574 * Unlike other routines in this file, this takes a pointer to an
2575 * already-looked-up tuple in the pg_statistic cache. We do this since
2576 * most callers will want to extract more than one value from the cache
2577 * entry, and we don't want to repeat the cache lookup unnecessarily.
2578 * Also, this API allows this routine to be used with statistics tuples
2579 * that have been provided by a stats hook and didn't really come from
2582 * statstuple: pg_statistics tuple to be examined.
2583 * atttype: type OID of attribute (can be InvalidOid if values == NULL).
2584 * atttypmod: typmod of attribute (can be 0 if values == NULL).
2585 * reqkind: STAKIND code for desired statistics slot kind.
2586 * reqop: STAOP value wanted, or InvalidOid if don't care.
2587 * actualop: if not NULL, *actualop receives the actual STAOP value.
2588 * values, nvalues: if not NULL, the slot's stavalues are extracted.
2589 * numbers, nnumbers: if not NULL, the slot's stanumbers are extracted.
2591 * If assigned, values and numbers are set to point to palloc'd arrays.
2592 * If the attribute type is pass-by-reference, the values referenced by
2593 * the values array are themselves palloc'd. The palloc'd stuff can be
2594 * freed by calling free_attstatsslot.
2596 * Note: at present, atttype/atttypmod aren't actually used here at all.
2597 * But the caller must have the correct (or at least binary-compatible)
2598 * type ID to pass to free_attstatsslot later.
2601 get_attstatsslot(HeapTuple statstuple,
2602 Oid atttype, int32 atttypmod,
2603 int reqkind, Oid reqop,
2605 Datum **values, int *nvalues,
2606 float4 **numbers, int *nnumbers)
2608 Form_pg_statistic stats = (Form_pg_statistic) GETSTRUCT(statstuple);
2613 ArrayType *statarray;
2616 HeapTuple typeTuple;
2617 Form_pg_type typeForm;
2619 for (i = 0; i < STATISTIC_NUM_SLOTS; i++)
2621 if ((&stats->stakind1)[i] == reqkind &&
2622 (reqop == InvalidOid || (&stats->staop1)[i] == reqop))
2625 if (i >= STATISTIC_NUM_SLOTS)
2626 return false; /* not there */
2629 *actualop = (&stats->staop1)[i];
2633 val = SysCacheGetAttr(STATRELATTINH, statstuple,
2634 Anum_pg_statistic_stavalues1 + i,
2637 elog(ERROR, "stavalues is null");
2638 statarray = DatumGetArrayTypeP(val);
2641 * Need to get info about the array element type. We look at the
2642 * actual element type embedded in the array, which might be only
2643 * binary-compatible with the passed-in atttype. The info we
2644 * extract here should be the same either way, but deconstruct_array
2645 * is picky about having an exact type OID match.
2647 arrayelemtype = ARR_ELEMTYPE(statarray);
2648 typeTuple = SearchSysCache1(TYPEOID, ObjectIdGetDatum(arrayelemtype));
2649 if (!HeapTupleIsValid(typeTuple))
2650 elog(ERROR, "cache lookup failed for type %u", arrayelemtype);
2651 typeForm = (Form_pg_type) GETSTRUCT(typeTuple);
2653 /* Deconstruct array into Datum elements; NULLs not expected */
2654 deconstruct_array(statarray,
2659 values, NULL, nvalues);
2662 * If the element type is pass-by-reference, we now have a bunch of
2663 * Datums that are pointers into the syscache value. Copy them to
2664 * avoid problems if syscache decides to drop the entry.
2666 if (!typeForm->typbyval)
2668 for (j = 0; j < *nvalues; j++)
2670 (*values)[j] = datumCopy((*values)[j],
2676 ReleaseSysCache(typeTuple);
2679 * Free statarray if it's a detoasted copy.
2681 if ((Pointer) statarray != DatumGetPointer(val))
2687 val = SysCacheGetAttr(STATRELATTINH, statstuple,
2688 Anum_pg_statistic_stanumbers1 + i,
2691 elog(ERROR, "stanumbers is null");
2692 statarray = DatumGetArrayTypeP(val);
2695 * We expect the array to be a 1-D float4 array; verify that. We don't
2696 * need to use deconstruct_array() since the array data is just going
2697 * to look like a C array of float4 values.
2699 narrayelem = ARR_DIMS(statarray)[0];
2700 if (ARR_NDIM(statarray) != 1 || narrayelem <= 0 ||
2701 ARR_HASNULL(statarray) ||
2702 ARR_ELEMTYPE(statarray) != FLOAT4OID)
2703 elog(ERROR, "stanumbers is not a 1-D float4 array");
2704 *numbers = (float4 *) palloc(narrayelem * sizeof(float4));
2705 memcpy(*numbers, ARR_DATA_PTR(statarray), narrayelem * sizeof(float4));
2706 *nnumbers = narrayelem;
2709 * Free statarray if it's a detoasted copy.
2711 if ((Pointer) statarray != DatumGetPointer(val))
2720 * Free data allocated by get_attstatsslot
2722 * atttype need be valid only if values != NULL.
2725 free_attstatsslot(Oid atttype,
2726 Datum *values, int nvalues,
2727 float4 *numbers, int nnumbers)
2731 if (!get_typbyval(atttype))
2735 for (i = 0; i < nvalues; i++)
2736 pfree(DatumGetPointer(values[i]));
2744 /* ---------- PG_NAMESPACE CACHE ---------- */
2747 * get_namespace_name
2748 * Returns the name of a given namespace
2750 * Returns a palloc'd copy of the string, or NULL if no such namespace.
2753 get_namespace_name(Oid nspid)
2757 tp = SearchSysCache1(NAMESPACEOID, ObjectIdGetDatum(nspid));
2758 if (HeapTupleIsValid(tp))
2760 Form_pg_namespace nsptup = (Form_pg_namespace) GETSTRUCT(tp);
2763 result = pstrdup(NameStr(nsptup->nspname));
2764 ReleaseSysCache(tp);