PostgreSQL Source Code  git master
lsyscache.c
Go to the documentation of this file.
1 /*-------------------------------------------------------------------------
2  *
3  * lsyscache.c
4  * Convenience routines for common queries in the system catalog cache.
5  *
6  * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group
7  * Portions Copyright (c) 1994, Regents of the University of California
8  *
9  * IDENTIFICATION
10  * src/backend/utils/cache/lsyscache.c
11  *
12  * NOTES
13  * Eventually, the index information should go through here, too.
14  *-------------------------------------------------------------------------
15  */
16 #include "postgres.h"
17 
18 #include "access/hash.h"
19 #include "access/htup_details.h"
20 #include "access/nbtree.h"
21 #include "bootstrap/bootstrap.h"
22 #include "catalog/namespace.h"
23 #include "catalog/pg_am.h"
24 #include "catalog/pg_amop.h"
25 #include "catalog/pg_amproc.h"
26 #include "catalog/pg_collation.h"
27 #include "catalog/pg_constraint.h"
28 #include "catalog/pg_language.h"
29 #include "catalog/pg_namespace.h"
30 #include "catalog/pg_opclass.h"
31 #include "catalog/pg_operator.h"
32 #include "catalog/pg_proc.h"
33 #include "catalog/pg_range.h"
34 #include "catalog/pg_statistic.h"
35 #include "catalog/pg_transform.h"
36 #include "catalog/pg_type.h"
37 #include "miscadmin.h"
38 #include "nodes/makefuncs.h"
39 #include "utils/array.h"
40 #include "utils/builtins.h"
41 #include "utils/catcache.h"
42 #include "utils/datum.h"
43 #include "utils/fmgroids.h"
44 #include "utils/lsyscache.h"
45 #include "utils/rel.h"
46 #include "utils/syscache.h"
47 #include "utils/typcache.h"
48 
49 /* Hook for plugins to get control in get_attavgwidth() */
51 
52 
53 /* ---------- AMOP CACHES ---------- */
54 
55 /*
56  * op_in_opfamily
57  *
58  * Return t iff operator 'opno' is in operator family 'opfamily'.
59  *
60  * This function only considers search operators, not ordering operators.
61  */
62 bool
63 op_in_opfamily(Oid opno, Oid opfamily)
64 {
66  ObjectIdGetDatum(opno),
67  CharGetDatum(AMOP_SEARCH),
68  ObjectIdGetDatum(opfamily));
69 }
70 
71 /*
72  * get_op_opfamily_strategy
73  *
74  * Get the operator's strategy number within the specified opfamily,
75  * or 0 if it's not a member of the opfamily.
76  *
77  * This function only considers search operators, not ordering operators.
78  */
79 int
81 {
82  HeapTuple tp;
83  Form_pg_amop amop_tup;
84  int result;
85 
87  ObjectIdGetDatum(opno),
88  CharGetDatum(AMOP_SEARCH),
89  ObjectIdGetDatum(opfamily));
90  if (!HeapTupleIsValid(tp))
91  return 0;
92  amop_tup = (Form_pg_amop) GETSTRUCT(tp);
93  result = amop_tup->amopstrategy;
94  ReleaseSysCache(tp);
95  return result;
96 }
97 
98 /*
99  * get_op_opfamily_sortfamily
100  *
101  * If the operator is an ordering operator within the specified opfamily,
102  * return its amopsortfamily OID; else return InvalidOid.
103  */
104 Oid
106 {
107  HeapTuple tp;
108  Form_pg_amop amop_tup;
109  Oid result;
110 
112  ObjectIdGetDatum(opno),
113  CharGetDatum(AMOP_ORDER),
114  ObjectIdGetDatum(opfamily));
115  if (!HeapTupleIsValid(tp))
116  return InvalidOid;
117  amop_tup = (Form_pg_amop) GETSTRUCT(tp);
118  result = amop_tup->amopsortfamily;
119  ReleaseSysCache(tp);
120  return result;
121 }
122 
123 /*
124  * get_op_opfamily_properties
125  *
126  * Get the operator's strategy number and declared input data types
127  * within the specified opfamily.
128  *
129  * Caller should already have verified that opno is a member of opfamily,
130  * therefore we raise an error if the tuple is not found.
131  */
132 void
133 get_op_opfamily_properties(Oid opno, Oid opfamily, bool ordering_op,
134  int *strategy,
135  Oid *lefttype,
136  Oid *righttype)
137 {
138  HeapTuple tp;
139  Form_pg_amop amop_tup;
140 
142  ObjectIdGetDatum(opno),
143  CharGetDatum(ordering_op ? AMOP_ORDER : AMOP_SEARCH),
144  ObjectIdGetDatum(opfamily));
145  if (!HeapTupleIsValid(tp))
146  elog(ERROR, "operator %u is not a member of opfamily %u",
147  opno, opfamily);
148  amop_tup = (Form_pg_amop) GETSTRUCT(tp);
149  *strategy = amop_tup->amopstrategy;
150  *lefttype = amop_tup->amoplefttype;
151  *righttype = amop_tup->amoprighttype;
152  ReleaseSysCache(tp);
153 }
154 
155 /*
156  * get_opfamily_member
157  * Get the OID of the operator that implements the specified strategy
158  * with the specified datatypes for the specified opfamily.
159  *
160  * Returns InvalidOid if there is no pg_amop entry for the given keys.
161  */
162 Oid
163 get_opfamily_member(Oid opfamily, Oid lefttype, Oid righttype,
164  int16 strategy)
165 {
166  HeapTuple tp;
167  Form_pg_amop amop_tup;
168  Oid result;
169 
171  ObjectIdGetDatum(opfamily),
172  ObjectIdGetDatum(lefttype),
173  ObjectIdGetDatum(righttype),
174  Int16GetDatum(strategy));
175  if (!HeapTupleIsValid(tp))
176  return InvalidOid;
177  amop_tup = (Form_pg_amop) GETSTRUCT(tp);
178  result = amop_tup->amopopr;
179  ReleaseSysCache(tp);
180  return result;
181 }
182 
183 /*
184  * get_ordering_op_properties
185  * Given the OID of an ordering operator (a btree "<" or ">" operator),
186  * determine its opfamily, its declared input datatype, and its
187  * strategy number (BTLessStrategyNumber or BTGreaterStrategyNumber).
188  *
189  * Returns true if successful, false if no matching pg_amop entry exists.
190  * (This indicates that the operator is not a valid ordering operator.)
191  *
192  * Note: the operator could be registered in multiple families, for example
193  * if someone were to build a "reverse sort" opfamily. This would result in
194  * uncertainty as to whether "ORDER BY USING op" would default to NULLS FIRST
195  * or NULLS LAST, as well as inefficient planning due to failure to match up
196  * pathkeys that should be the same. So we want a determinate result here.
197  * Because of the way the syscache search works, we'll use the interpretation
198  * associated with the opfamily with smallest OID, which is probably
199  * determinate enough. Since there is no longer any particularly good reason
200  * to build reverse-sort opfamilies, it doesn't seem worth expending any
201  * additional effort on ensuring consistency.
202  */
203 bool
205  Oid *opfamily, Oid *opcintype, int16 *strategy)
206 {
207  bool result = false;
208  CatCList *catlist;
209  int i;
210 
211  /* ensure outputs are initialized on failure */
212  *opfamily = InvalidOid;
213  *opcintype = InvalidOid;
214  *strategy = 0;
215 
216  /*
217  * Search pg_amop to see if the target operator is registered as the "<"
218  * or ">" operator of any btree opfamily.
219  */
221 
222  for (i = 0; i < catlist->n_members; i++)
223  {
224  HeapTuple tuple = &catlist->members[i]->tuple;
225  Form_pg_amop aform = (Form_pg_amop) GETSTRUCT(tuple);
226 
227  /* must be btree */
228  if (aform->amopmethod != BTREE_AM_OID)
229  continue;
230 
231  if (aform->amopstrategy == BTLessStrategyNumber ||
232  aform->amopstrategy == BTGreaterStrategyNumber)
233  {
234  /* Found it ... should have consistent input types */
235  if (aform->amoplefttype == aform->amoprighttype)
236  {
237  /* Found a suitable opfamily, return info */
238  *opfamily = aform->amopfamily;
239  *opcintype = aform->amoplefttype;
240  *strategy = aform->amopstrategy;
241  result = true;
242  break;
243  }
244  }
245  }
246 
247  ReleaseSysCacheList(catlist);
248 
249  return result;
250 }
251 
252 /*
253  * get_equality_op_for_ordering_op
254  * Get the OID of the datatype-specific btree equality operator
255  * associated with an ordering operator (a "<" or ">" operator).
256  *
257  * If "reverse" isn't NULL, also set *reverse to false if the operator is "<",
258  * true if it's ">"
259  *
260  * Returns InvalidOid if no matching equality operator can be found.
261  * (This indicates that the operator is not a valid ordering operator.)
262  */
263 Oid
265 {
266  Oid result = InvalidOid;
267  Oid opfamily;
268  Oid opcintype;
269  int16 strategy;
270 
271  /* Find the operator in pg_amop */
273  &opfamily, &opcintype, &strategy))
274  {
275  /* Found a suitable opfamily, get matching equality operator */
276  result = get_opfamily_member(opfamily,
277  opcintype,
278  opcintype,
280  if (reverse)
281  *reverse = (strategy == BTGreaterStrategyNumber);
282  }
283 
284  return result;
285 }
286 
287 /*
288  * get_ordering_op_for_equality_op
289  * Get the OID of a datatype-specific btree ordering operator
290  * associated with an equality operator. (If there are multiple
291  * possibilities, assume any one will do.)
292  *
293  * This function is used when we have to sort data before unique-ifying,
294  * and don't much care which sorting op is used as long as it's compatible
295  * with the intended equality operator. Since we need a sorting operator,
296  * it should be single-data-type even if the given operator is cross-type.
297  * The caller specifies whether to find an op for the LHS or RHS data type.
298  *
299  * Returns InvalidOid if no matching ordering operator can be found.
300  */
301 Oid
302 get_ordering_op_for_equality_op(Oid opno, bool use_lhs_type)
303 {
304  Oid result = InvalidOid;
305  CatCList *catlist;
306  int i;
307 
308  /*
309  * Search pg_amop to see if the target operator is registered as the "="
310  * operator of any btree opfamily.
311  */
313 
314  for (i = 0; i < catlist->n_members; i++)
315  {
316  HeapTuple tuple = &catlist->members[i]->tuple;
317  Form_pg_amop aform = (Form_pg_amop) GETSTRUCT(tuple);
318 
319  /* must be btree */
320  if (aform->amopmethod != BTREE_AM_OID)
321  continue;
322 
323  if (aform->amopstrategy == BTEqualStrategyNumber)
324  {
325  /* Found a suitable opfamily, get matching ordering operator */
326  Oid typid;
327 
328  typid = use_lhs_type ? aform->amoplefttype : aform->amoprighttype;
329  result = get_opfamily_member(aform->amopfamily,
330  typid, typid,
332  if (OidIsValid(result))
333  break;
334  /* failure probably shouldn't happen, but keep looking if so */
335  }
336  }
337 
338  ReleaseSysCacheList(catlist);
339 
340  return result;
341 }
342 
343 /*
344  * get_mergejoin_opfamilies
345  * Given a putatively mergejoinable operator, return a list of the OIDs
346  * of the btree opfamilies in which it represents equality.
347  *
348  * It is possible (though at present unusual) for an operator to be equality
349  * in more than one opfamily, hence the result is a list. This also lets us
350  * return NIL if the operator is not found in any opfamilies.
351  *
352  * The planner currently uses simple equal() tests to compare the lists
353  * returned by this function, which makes the list order relevant, though
354  * strictly speaking it should not be. Because of the way syscache list
355  * searches are handled, in normal operation the result will be sorted by OID
356  * so everything works fine. If running with system index usage disabled,
357  * the result ordering is unspecified and hence the planner might fail to
358  * recognize optimization opportunities ... but that's hardly a scenario in
359  * which performance is good anyway, so there's no point in expending code
360  * or cycles here to guarantee the ordering in that case.
361  */
362 List *
364 {
365  List *result = NIL;
366  CatCList *catlist;
367  int i;
368 
369  /*
370  * Search pg_amop to see if the target operator is registered as the "="
371  * operator of any btree opfamily.
372  */
374 
375  for (i = 0; i < catlist->n_members; i++)
376  {
377  HeapTuple tuple = &catlist->members[i]->tuple;
378  Form_pg_amop aform = (Form_pg_amop) GETSTRUCT(tuple);
379 
380  /* must be btree equality */
381  if (aform->amopmethod == BTREE_AM_OID &&
382  aform->amopstrategy == BTEqualStrategyNumber)
383  result = lappend_oid(result, aform->amopfamily);
384  }
385 
386  ReleaseSysCacheList(catlist);
387 
388  return result;
389 }
390 
391 /*
392  * get_compatible_hash_operators
393  * Get the OID(s) of hash equality operator(s) compatible with the given
394  * operator, but operating on its LHS and/or RHS datatype.
395  *
396  * An operator for the LHS type is sought and returned into *lhs_opno if
397  * lhs_opno isn't NULL. Similarly, an operator for the RHS type is sought
398  * and returned into *rhs_opno if rhs_opno isn't NULL.
399  *
400  * If the given operator is not cross-type, the results should be the same
401  * operator, but in cross-type situations they will be different.
402  *
403  * Returns true if able to find the requested operator(s), false if not.
404  * (This indicates that the operator should not have been marked oprcanhash.)
405  */
406 bool
408  Oid *lhs_opno, Oid *rhs_opno)
409 {
410  bool result = false;
411  CatCList *catlist;
412  int i;
413 
414  /* Ensure output args are initialized on failure */
415  if (lhs_opno)
416  *lhs_opno = InvalidOid;
417  if (rhs_opno)
418  *rhs_opno = InvalidOid;
419 
420  /*
421  * Search pg_amop to see if the target operator is registered as the "="
422  * operator of any hash opfamily. If the operator is registered in
423  * multiple opfamilies, assume we can use any one.
424  */
426 
427  for (i = 0; i < catlist->n_members; i++)
428  {
429  HeapTuple tuple = &catlist->members[i]->tuple;
430  Form_pg_amop aform = (Form_pg_amop) GETSTRUCT(tuple);
431 
432  if (aform->amopmethod == HASH_AM_OID &&
433  aform->amopstrategy == HTEqualStrategyNumber)
434  {
435  /* No extra lookup needed if given operator is single-type */
436  if (aform->amoplefttype == aform->amoprighttype)
437  {
438  if (lhs_opno)
439  *lhs_opno = opno;
440  if (rhs_opno)
441  *rhs_opno = opno;
442  result = true;
443  break;
444  }
445 
446  /*
447  * Get the matching single-type operator(s). Failure probably
448  * shouldn't happen --- it implies a bogus opfamily --- but
449  * continue looking if so.
450  */
451  if (lhs_opno)
452  {
453  *lhs_opno = get_opfamily_member(aform->amopfamily,
454  aform->amoplefttype,
455  aform->amoplefttype,
457  if (!OidIsValid(*lhs_opno))
458  continue;
459  /* Matching LHS found, done if caller doesn't want RHS */
460  if (!rhs_opno)
461  {
462  result = true;
463  break;
464  }
465  }
466  if (rhs_opno)
467  {
468  *rhs_opno = get_opfamily_member(aform->amopfamily,
469  aform->amoprighttype,
470  aform->amoprighttype,
472  if (!OidIsValid(*rhs_opno))
473  {
474  /* Forget any LHS operator from this opfamily */
475  if (lhs_opno)
476  *lhs_opno = InvalidOid;
477  continue;
478  }
479  /* Matching RHS found, so done */
480  result = true;
481  break;
482  }
483  }
484  }
485 
486  ReleaseSysCacheList(catlist);
487 
488  return result;
489 }
490 
491 /*
492  * get_op_hash_functions
493  * Get the OID(s) of the standard hash support function(s) compatible with
494  * the given operator, operating on its LHS and/or RHS datatype as required.
495  *
496  * A function for the LHS type is sought and returned into *lhs_procno if
497  * lhs_procno isn't NULL. Similarly, a function for the RHS type is sought
498  * and returned into *rhs_procno if rhs_procno isn't NULL.
499  *
500  * If the given operator is not cross-type, the results should be the same
501  * function, but in cross-type situations they will be different.
502  *
503  * Returns true if able to find the requested function(s), false if not.
504  * (This indicates that the operator should not have been marked oprcanhash.)
505  */
506 bool
508  RegProcedure *lhs_procno, RegProcedure *rhs_procno)
509 {
510  bool result = false;
511  CatCList *catlist;
512  int i;
513 
514  /* Ensure output args are initialized on failure */
515  if (lhs_procno)
516  *lhs_procno = InvalidOid;
517  if (rhs_procno)
518  *rhs_procno = InvalidOid;
519 
520  /*
521  * Search pg_amop to see if the target operator is registered as the "="
522  * operator of any hash opfamily. If the operator is registered in
523  * multiple opfamilies, assume we can use any one.
524  */
526 
527  for (i = 0; i < catlist->n_members; i++)
528  {
529  HeapTuple tuple = &catlist->members[i]->tuple;
530  Form_pg_amop aform = (Form_pg_amop) GETSTRUCT(tuple);
531 
532  if (aform->amopmethod == HASH_AM_OID &&
533  aform->amopstrategy == HTEqualStrategyNumber)
534  {
535  /*
536  * Get the matching support function(s). Failure probably
537  * shouldn't happen --- it implies a bogus opfamily --- but
538  * continue looking if so.
539  */
540  if (lhs_procno)
541  {
542  *lhs_procno = get_opfamily_proc(aform->amopfamily,
543  aform->amoplefttype,
544  aform->amoplefttype,
546  if (!OidIsValid(*lhs_procno))
547  continue;
548  /* Matching LHS found, done if caller doesn't want RHS */
549  if (!rhs_procno)
550  {
551  result = true;
552  break;
553  }
554  /* Only one lookup needed if given operator is single-type */
555  if (aform->amoplefttype == aform->amoprighttype)
556  {
557  *rhs_procno = *lhs_procno;
558  result = true;
559  break;
560  }
561  }
562  if (rhs_procno)
563  {
564  *rhs_procno = get_opfamily_proc(aform->amopfamily,
565  aform->amoprighttype,
566  aform->amoprighttype,
568  if (!OidIsValid(*rhs_procno))
569  {
570  /* Forget any LHS function from this opfamily */
571  if (lhs_procno)
572  *lhs_procno = InvalidOid;
573  continue;
574  }
575  /* Matching RHS found, so done */
576  result = true;
577  break;
578  }
579  }
580  }
581 
582  ReleaseSysCacheList(catlist);
583 
584  return result;
585 }
586 
587 /*
588  * get_op_btree_interpretation
589  * Given an operator's OID, find out which btree opfamilies it belongs to,
590  * and what properties it has within each one. The results are returned
591  * as a palloc'd list of OpBtreeInterpretation structs.
592  *
593  * In addition to the normal btree operators, we consider a <> operator to be
594  * a "member" of an opfamily if its negator is an equality operator of the
595  * opfamily. ROWCOMPARE_NE is returned as the strategy number for this case.
596  */
597 List *
599 {
600  List *result = NIL;
601  OpBtreeInterpretation *thisresult;
602  CatCList *catlist;
603  int i;
604 
605  /*
606  * Find all the pg_amop entries containing the operator.
607  */
609 
610  for (i = 0; i < catlist->n_members; i++)
611  {
612  HeapTuple op_tuple = &catlist->members[i]->tuple;
613  Form_pg_amop op_form = (Form_pg_amop) GETSTRUCT(op_tuple);
614  StrategyNumber op_strategy;
615 
616  /* must be btree */
617  if (op_form->amopmethod != BTREE_AM_OID)
618  continue;
619 
620  /* Get the operator's btree strategy number */
621  op_strategy = (StrategyNumber) op_form->amopstrategy;
622  Assert(op_strategy >= 1 && op_strategy <= 5);
623 
624  thisresult = (OpBtreeInterpretation *)
625  palloc(sizeof(OpBtreeInterpretation));
626  thisresult->opfamily_id = op_form->amopfamily;
627  thisresult->strategy = op_strategy;
628  thisresult->oplefttype = op_form->amoplefttype;
629  thisresult->oprighttype = op_form->amoprighttype;
630  result = lappend(result, thisresult);
631  }
632 
633  ReleaseSysCacheList(catlist);
634 
635  /*
636  * If we didn't find any btree opfamily containing the operator, perhaps
637  * it is a <> operator. See if it has a negator that is in an opfamily.
638  */
639  if (result == NIL)
640  {
641  Oid op_negator = get_negator(opno);
642 
643  if (OidIsValid(op_negator))
644  {
645  catlist = SearchSysCacheList1(AMOPOPID,
646  ObjectIdGetDatum(op_negator));
647 
648  for (i = 0; i < catlist->n_members; i++)
649  {
650  HeapTuple op_tuple = &catlist->members[i]->tuple;
651  Form_pg_amop op_form = (Form_pg_amop) GETSTRUCT(op_tuple);
652  StrategyNumber op_strategy;
653 
654  /* must be btree */
655  if (op_form->amopmethod != BTREE_AM_OID)
656  continue;
657 
658  /* Get the operator's btree strategy number */
659  op_strategy = (StrategyNumber) op_form->amopstrategy;
660  Assert(op_strategy >= 1 && op_strategy <= 5);
661 
662  /* Only consider negators that are = */
663  if (op_strategy != BTEqualStrategyNumber)
664  continue;
665 
666  /* OK, report it with "strategy" ROWCOMPARE_NE */
667  thisresult = (OpBtreeInterpretation *)
668  palloc(sizeof(OpBtreeInterpretation));
669  thisresult->opfamily_id = op_form->amopfamily;
670  thisresult->strategy = ROWCOMPARE_NE;
671  thisresult->oplefttype = op_form->amoplefttype;
672  thisresult->oprighttype = op_form->amoprighttype;
673  result = lappend(result, thisresult);
674  }
675 
676  ReleaseSysCacheList(catlist);
677  }
678  }
679 
680  return result;
681 }
682 
683 /*
684  * equality_ops_are_compatible
685  * Return true if the two given equality operators have compatible
686  * semantics.
687  *
688  * This is trivially true if they are the same operator. Otherwise,
689  * we look to see if they can be found in the same btree or hash opfamily.
690  * Either finding allows us to assume that they have compatible notions
691  * of equality. (The reason we need to do these pushups is that one might
692  * be a cross-type operator; for instance int24eq vs int4eq.)
693  */
694 bool
696 {
697  bool result;
698  CatCList *catlist;
699  int i;
700 
701  /* Easy if they're the same operator */
702  if (opno1 == opno2)
703  return true;
704 
705  /*
706  * We search through all the pg_amop entries for opno1.
707  */
708  catlist = SearchSysCacheList1(AMOPOPID, ObjectIdGetDatum(opno1));
709 
710  result = false;
711  for (i = 0; i < catlist->n_members; i++)
712  {
713  HeapTuple op_tuple = &catlist->members[i]->tuple;
714  Form_pg_amop op_form = (Form_pg_amop) GETSTRUCT(op_tuple);
715 
716  /* must be btree or hash */
717  if (op_form->amopmethod == BTREE_AM_OID ||
718  op_form->amopmethod == HASH_AM_OID)
719  {
720  if (op_in_opfamily(opno2, op_form->amopfamily))
721  {
722  result = true;
723  break;
724  }
725  }
726  }
727 
728  ReleaseSysCacheList(catlist);
729 
730  return result;
731 }
732 
733 
734 /* ---------- AMPROC CACHES ---------- */
735 
736 /*
737  * get_opfamily_proc
738  * Get the OID of the specified support function
739  * for the specified opfamily and datatypes.
740  *
741  * Returns InvalidOid if there is no pg_amproc entry for the given keys.
742  */
743 Oid
744 get_opfamily_proc(Oid opfamily, Oid lefttype, Oid righttype, int16 procnum)
745 {
746  HeapTuple tp;
747  Form_pg_amproc amproc_tup;
748  RegProcedure result;
749 
751  ObjectIdGetDatum(opfamily),
752  ObjectIdGetDatum(lefttype),
753  ObjectIdGetDatum(righttype),
754  Int16GetDatum(procnum));
755  if (!HeapTupleIsValid(tp))
756  return InvalidOid;
757  amproc_tup = (Form_pg_amproc) GETSTRUCT(tp);
758  result = amproc_tup->amproc;
759  ReleaseSysCache(tp);
760  return result;
761 }
762 
763 
764 /* ---------- ATTRIBUTE CACHES ---------- */
765 
766 /*
767  * get_attname
768  * Given the relation id and the attribute number, return the "attname"
769  * field from the attribute relation as a palloc'ed string.
770  *
771  * If no such attribute exists and missing_ok is true, NULL is returned;
772  * otherwise a not-intended-for-user-consumption error is thrown.
773  */
774 char *
775 get_attname(Oid relid, AttrNumber attnum, bool missing_ok)
776 {
777  HeapTuple tp;
778 
779  tp = SearchSysCache2(ATTNUM,
780  ObjectIdGetDatum(relid), Int16GetDatum(attnum));
781  if (HeapTupleIsValid(tp))
782  {
784  char *result;
785 
786  result = pstrdup(NameStr(att_tup->attname));
787  ReleaseSysCache(tp);
788  return result;
789  }
790 
791  if (!missing_ok)
792  elog(ERROR, "cache lookup failed for attribute %d of relation %u",
793  attnum, relid);
794  return NULL;
795 }
796 
797 /*
798  * get_attnum
799  *
800  * Given the relation id and the attribute name,
801  * return the "attnum" field from the attribute relation.
802  *
803  * Returns InvalidAttrNumber if the attr doesn't exist (or is dropped).
804  */
806 get_attnum(Oid relid, const char *attname)
807 {
808  HeapTuple tp;
809 
810  tp = SearchSysCacheAttName(relid, attname);
811  if (HeapTupleIsValid(tp))
812  {
814  AttrNumber result;
815 
816  result = att_tup->attnum;
817  ReleaseSysCache(tp);
818  return result;
819  }
820  else
821  return InvalidAttrNumber;
822 }
823 
824 /*
825  * get_attgenerated
826  *
827  * Given the relation id and the attribute name,
828  * return the "attgenerated" field from the attribute relation.
829  *
830  * Errors if not found.
831  *
832  * Since not generated is represented by '\0', this can also be used as a
833  * Boolean test.
834  */
835 char
837 {
838  HeapTuple tp;
839  Form_pg_attribute att_tup;
840  char result;
841 
842  tp = SearchSysCache2(ATTNUM,
843  ObjectIdGetDatum(relid),
844  Int16GetDatum(attnum));
845  if (!HeapTupleIsValid(tp))
846  elog(ERROR, "cache lookup failed for attribute %d of relation %u",
847  attnum, relid);
848  att_tup = (Form_pg_attribute) GETSTRUCT(tp);
849  result = att_tup->attgenerated;
850  ReleaseSysCache(tp);
851  return result;
852 }
853 
854 /*
855  * get_atttype
856  *
857  * Given the relation OID and the attribute number with the relation,
858  * return the attribute type OID.
859  */
860 Oid
862 {
863  HeapTuple tp;
864 
865  tp = SearchSysCache2(ATTNUM,
866  ObjectIdGetDatum(relid),
867  Int16GetDatum(attnum));
868  if (HeapTupleIsValid(tp))
869  {
871  Oid result;
872 
873  result = att_tup->atttypid;
874  ReleaseSysCache(tp);
875  return result;
876  }
877  else
878  return InvalidOid;
879 }
880 
881 /*
882  * get_atttypetypmodcoll
883  *
884  * A three-fer: given the relation id and the attribute number,
885  * fetch atttypid, atttypmod, and attcollation in a single cache lookup.
886  *
887  * Unlike the otherwise-similar get_atttype, this routine
888  * raises an error if it can't obtain the information.
889  */
890 void
892  Oid *typid, int32 *typmod, Oid *collid)
893 {
894  HeapTuple tp;
895  Form_pg_attribute att_tup;
896 
897  tp = SearchSysCache2(ATTNUM,
898  ObjectIdGetDatum(relid),
899  Int16GetDatum(attnum));
900  if (!HeapTupleIsValid(tp))
901  elog(ERROR, "cache lookup failed for attribute %d of relation %u",
902  attnum, relid);
903  att_tup = (Form_pg_attribute) GETSTRUCT(tp);
904 
905  *typid = att_tup->atttypid;
906  *typmod = att_tup->atttypmod;
907  *collid = att_tup->attcollation;
908  ReleaseSysCache(tp);
909 }
910 
911 /* ---------- COLLATION CACHE ---------- */
912 
913 /*
914  * get_collation_name
915  * Returns the name of a given pg_collation entry.
916  *
917  * Returns a palloc'd copy of the string, or NULL if no such collation.
918  *
919  * NOTE: since collation name is not unique, be wary of code that uses this
920  * for anything except preparing error messages.
921  */
922 char *
924 {
925  HeapTuple tp;
926 
927  tp = SearchSysCache1(COLLOID, ObjectIdGetDatum(colloid));
928  if (HeapTupleIsValid(tp))
929  {
931  char *result;
932 
933  result = pstrdup(NameStr(colltup->collname));
934  ReleaseSysCache(tp);
935  return result;
936  }
937  else
938  return NULL;
939 }
940 
941 bool
943 {
944  HeapTuple tp;
945  Form_pg_collation colltup;
946  bool result;
947 
948  tp = SearchSysCache1(COLLOID, ObjectIdGetDatum(colloid));
949  if (!HeapTupleIsValid(tp))
950  elog(ERROR, "cache lookup failed for collation %u", colloid);
951  colltup = (Form_pg_collation) GETSTRUCT(tp);
952  result = colltup->collisdeterministic;
953  ReleaseSysCache(tp);
954  return result;
955 }
956 
957 /* ---------- CONSTRAINT CACHE ---------- */
958 
959 /*
960  * get_constraint_name
961  * Returns the name of a given pg_constraint entry.
962  *
963  * Returns a palloc'd copy of the string, or NULL if no such constraint.
964  *
965  * NOTE: since constraint name is not unique, be wary of code that uses this
966  * for anything except preparing error messages.
967  */
968 char *
970 {
971  HeapTuple tp;
972 
974  if (HeapTupleIsValid(tp))
975  {
977  char *result;
978 
979  result = pstrdup(NameStr(contup->conname));
980  ReleaseSysCache(tp);
981  return result;
982  }
983  else
984  return NULL;
985 }
986 
987 /* ---------- LANGUAGE CACHE ---------- */
988 
989 char *
990 get_language_name(Oid langoid, bool missing_ok)
991 {
992  HeapTuple tp;
993 
994  tp = SearchSysCache1(LANGOID, ObjectIdGetDatum(langoid));
995  if (HeapTupleIsValid(tp))
996  {
998  char *result;
999 
1000  result = pstrdup(NameStr(lantup->lanname));
1001  ReleaseSysCache(tp);
1002  return result;
1003  }
1004 
1005  if (!missing_ok)
1006  elog(ERROR, "cache lookup failed for language %u",
1007  langoid);
1008  return NULL;
1009 }
1010 
1011 /* ---------- OPCLASS CACHE ---------- */
1012 
1013 /*
1014  * get_opclass_family
1015  *
1016  * Returns the OID of the operator family the opclass belongs to.
1017  */
1018 Oid
1020 {
1021  HeapTuple tp;
1022  Form_pg_opclass cla_tup;
1023  Oid result;
1024 
1025  tp = SearchSysCache1(CLAOID, ObjectIdGetDatum(opclass));
1026  if (!HeapTupleIsValid(tp))
1027  elog(ERROR, "cache lookup failed for opclass %u", opclass);
1028  cla_tup = (Form_pg_opclass) GETSTRUCT(tp);
1029 
1030  result = cla_tup->opcfamily;
1031  ReleaseSysCache(tp);
1032  return result;
1033 }
1034 
1035 /*
1036  * get_opclass_input_type
1037  *
1038  * Returns the OID of the datatype the opclass indexes.
1039  */
1040 Oid
1042 {
1043  HeapTuple tp;
1044  Form_pg_opclass cla_tup;
1045  Oid result;
1046 
1047  tp = SearchSysCache1(CLAOID, ObjectIdGetDatum(opclass));
1048  if (!HeapTupleIsValid(tp))
1049  elog(ERROR, "cache lookup failed for opclass %u", opclass);
1050  cla_tup = (Form_pg_opclass) GETSTRUCT(tp);
1051 
1052  result = cla_tup->opcintype;
1053  ReleaseSysCache(tp);
1054  return result;
1055 }
1056 
1057 /*
1058  * get_opclass_opfamily_and_input_type
1059  *
1060  * Returns the OID of the operator family the opclass belongs to,
1061  * the OID of the datatype the opclass indexes
1062  */
1063 bool
1064 get_opclass_opfamily_and_input_type(Oid opclass, Oid *opfamily, Oid *opcintype)
1065 {
1066  HeapTuple tp;
1067  Form_pg_opclass cla_tup;
1068 
1069  tp = SearchSysCache1(CLAOID, ObjectIdGetDatum(opclass));
1070  if (!HeapTupleIsValid(tp))
1071  return false;
1072 
1073  cla_tup = (Form_pg_opclass) GETSTRUCT(tp);
1074 
1075  *opfamily = cla_tup->opcfamily;
1076  *opcintype = cla_tup->opcintype;
1077 
1078  ReleaseSysCache(tp);
1079 
1080  return true;
1081 }
1082 
1083 /* ---------- OPERATOR CACHE ---------- */
1084 
1085 /*
1086  * get_opcode
1087  *
1088  * Returns the regproc id of the routine used to implement an
1089  * operator given the operator oid.
1090  */
1093 {
1094  HeapTuple tp;
1095 
1097  if (HeapTupleIsValid(tp))
1098  {
1100  RegProcedure result;
1101 
1102  result = optup->oprcode;
1103  ReleaseSysCache(tp);
1104  return result;
1105  }
1106  else
1107  return (RegProcedure) InvalidOid;
1108 }
1109 
1110 /*
1111  * get_opname
1112  * returns the name of the operator with the given opno
1113  *
1114  * Note: returns a palloc'd copy of the string, or NULL if no such operator.
1115  */
1116 char *
1118 {
1119  HeapTuple tp;
1120 
1122  if (HeapTupleIsValid(tp))
1123  {
1125  char *result;
1126 
1127  result = pstrdup(NameStr(optup->oprname));
1128  ReleaseSysCache(tp);
1129  return result;
1130  }
1131  else
1132  return NULL;
1133 }
1134 
1135 /*
1136  * get_op_rettype
1137  * Given operator oid, return the operator's result type.
1138  */
1139 Oid
1141 {
1142  HeapTuple tp;
1143 
1145  if (HeapTupleIsValid(tp))
1146  {
1148  Oid result;
1149 
1150  result = optup->oprresult;
1151  ReleaseSysCache(tp);
1152  return result;
1153  }
1154  else
1155  return InvalidOid;
1156 }
1157 
1158 /*
1159  * op_input_types
1160  *
1161  * Returns the left and right input datatypes for an operator
1162  * (InvalidOid if not relevant).
1163  */
1164 void
1165 op_input_types(Oid opno, Oid *lefttype, Oid *righttype)
1166 {
1167  HeapTuple tp;
1168  Form_pg_operator optup;
1169 
1171  if (!HeapTupleIsValid(tp)) /* shouldn't happen */
1172  elog(ERROR, "cache lookup failed for operator %u", opno);
1173  optup = (Form_pg_operator) GETSTRUCT(tp);
1174  *lefttype = optup->oprleft;
1175  *righttype = optup->oprright;
1176  ReleaseSysCache(tp);
1177 }
1178 
1179 /*
1180  * op_mergejoinable
1181  *
1182  * Returns true if the operator is potentially mergejoinable. (The planner
1183  * will fail to find any mergejoin plans unless there are suitable btree
1184  * opfamily entries for this operator and associated sortops. The pg_operator
1185  * flag is just a hint to tell the planner whether to bother looking.)
1186  *
1187  * In some cases (currently only array_eq and record_eq), mergejoinability
1188  * depends on the specific input data type the operator is invoked for, so
1189  * that must be passed as well. We currently assume that only one input's type
1190  * is needed to check this --- by convention, pass the left input's data type.
1191  */
1192 bool
1193 op_mergejoinable(Oid opno, Oid inputtype)
1194 {
1195  bool result = false;
1196  HeapTuple tp;
1197  TypeCacheEntry *typentry;
1198 
1199  /*
1200  * For array_eq or record_eq, we can sort if the element or field types
1201  * are all sortable. We could implement all the checks for that here, but
1202  * the typcache already does that and caches the results too, so let's
1203  * rely on the typcache.
1204  */
1205  if (opno == ARRAY_EQ_OP)
1206  {
1207  typentry = lookup_type_cache(inputtype, TYPECACHE_CMP_PROC);
1208  if (typentry->cmp_proc == F_BTARRAYCMP)
1209  result = true;
1210  }
1211  else if (opno == RECORD_EQ_OP)
1212  {
1213  typentry = lookup_type_cache(inputtype, TYPECACHE_CMP_PROC);
1214  if (typentry->cmp_proc == F_BTRECORDCMP)
1215  result = true;
1216  }
1217  else
1218  {
1219  /* For all other operators, rely on pg_operator.oprcanmerge */
1221  if (HeapTupleIsValid(tp))
1222  {
1224 
1225  result = optup->oprcanmerge;
1226  ReleaseSysCache(tp);
1227  }
1228  }
1229  return result;
1230 }
1231 
1232 /*
1233  * op_hashjoinable
1234  *
1235  * Returns true if the operator is hashjoinable. (There must be a suitable
1236  * hash opfamily entry for this operator if it is so marked.)
1237  *
1238  * In some cases (currently only array_eq), hashjoinability depends on the
1239  * specific input data type the operator is invoked for, so that must be
1240  * passed as well. We currently assume that only one input's type is needed
1241  * to check this --- by convention, pass the left input's data type.
1242  */
1243 bool
1244 op_hashjoinable(Oid opno, Oid inputtype)
1245 {
1246  bool result = false;
1247  HeapTuple tp;
1248  TypeCacheEntry *typentry;
1249 
1250  /* As in op_mergejoinable, let the typcache handle the hard cases */
1251  /* Eventually we'll need a similar case for record_eq ... */
1252  if (opno == ARRAY_EQ_OP)
1253  {
1254  typentry = lookup_type_cache(inputtype, TYPECACHE_HASH_PROC);
1255  if (typentry->hash_proc == F_HASH_ARRAY)
1256  result = true;
1257  }
1258  else
1259  {
1260  /* For all other operators, rely on pg_operator.oprcanhash */
1262  if (HeapTupleIsValid(tp))
1263  {
1265 
1266  result = optup->oprcanhash;
1267  ReleaseSysCache(tp);
1268  }
1269  }
1270  return result;
1271 }
1272 
1273 /*
1274  * op_strict
1275  *
1276  * Get the proisstrict flag for the operator's underlying function.
1277  */
1278 bool
1280 {
1281  RegProcedure funcid = get_opcode(opno);
1282 
1283  if (funcid == (RegProcedure) InvalidOid)
1284  elog(ERROR, "operator %u does not exist", opno);
1285 
1286  return func_strict((Oid) funcid);
1287 }
1288 
1289 /*
1290  * op_volatile
1291  *
1292  * Get the provolatile flag for the operator's underlying function.
1293  */
1294 char
1296 {
1297  RegProcedure funcid = get_opcode(opno);
1298 
1299  if (funcid == (RegProcedure) InvalidOid)
1300  elog(ERROR, "operator %u does not exist", opno);
1301 
1302  return func_volatile((Oid) funcid);
1303 }
1304 
1305 /*
1306  * get_commutator
1307  *
1308  * Returns the corresponding commutator of an operator.
1309  */
1310 Oid
1312 {
1313  HeapTuple tp;
1314 
1316  if (HeapTupleIsValid(tp))
1317  {
1319  Oid result;
1320 
1321  result = optup->oprcom;
1322  ReleaseSysCache(tp);
1323  return result;
1324  }
1325  else
1326  return InvalidOid;
1327 }
1328 
1329 /*
1330  * get_negator
1331  *
1332  * Returns the corresponding negator of an operator.
1333  */
1334 Oid
1336 {
1337  HeapTuple tp;
1338 
1340  if (HeapTupleIsValid(tp))
1341  {
1343  Oid result;
1344 
1345  result = optup->oprnegate;
1346  ReleaseSysCache(tp);
1347  return result;
1348  }
1349  else
1350  return InvalidOid;
1351 }
1352 
1353 /*
1354  * get_oprrest
1355  *
1356  * Returns procedure id for computing selectivity of an operator.
1357  */
1360 {
1361  HeapTuple tp;
1362 
1364  if (HeapTupleIsValid(tp))
1365  {
1367  RegProcedure result;
1368 
1369  result = optup->oprrest;
1370  ReleaseSysCache(tp);
1371  return result;
1372  }
1373  else
1374  return (RegProcedure) InvalidOid;
1375 }
1376 
1377 /*
1378  * get_oprjoin
1379  *
1380  * Returns procedure id for computing selectivity of a join.
1381  */
1384 {
1385  HeapTuple tp;
1386 
1388  if (HeapTupleIsValid(tp))
1389  {
1391  RegProcedure result;
1392 
1393  result = optup->oprjoin;
1394  ReleaseSysCache(tp);
1395  return result;
1396  }
1397  else
1398  return (RegProcedure) InvalidOid;
1399 }
1400 
1401 /* ---------- FUNCTION CACHE ---------- */
1402 
1403 /*
1404  * get_func_name
1405  * returns the name of the function with the given funcid
1406  *
1407  * Note: returns a palloc'd copy of the string, or NULL if no such function.
1408  */
1409 char *
1411 {
1412  HeapTuple tp;
1413 
1414  tp = SearchSysCache1(PROCOID, ObjectIdGetDatum(funcid));
1415  if (HeapTupleIsValid(tp))
1416  {
1417  Form_pg_proc functup = (Form_pg_proc) GETSTRUCT(tp);
1418  char *result;
1419 
1420  result = pstrdup(NameStr(functup->proname));
1421  ReleaseSysCache(tp);
1422  return result;
1423  }
1424  else
1425  return NULL;
1426 }
1427 
1428 /*
1429  * get_func_namespace
1430  *
1431  * Returns the pg_namespace OID associated with a given function.
1432  */
1433 Oid
1435 {
1436  HeapTuple tp;
1437 
1438  tp = SearchSysCache1(PROCOID, ObjectIdGetDatum(funcid));
1439  if (HeapTupleIsValid(tp))
1440  {
1441  Form_pg_proc functup = (Form_pg_proc) GETSTRUCT(tp);
1442  Oid result;
1443 
1444  result = functup->pronamespace;
1445  ReleaseSysCache(tp);
1446  return result;
1447  }
1448  else
1449  return InvalidOid;
1450 }
1451 
1452 /*
1453  * get_func_rettype
1454  * Given procedure id, return the function's result type.
1455  */
1456 Oid
1458 {
1459  HeapTuple tp;
1460  Oid result;
1461 
1462  tp = SearchSysCache1(PROCOID, ObjectIdGetDatum(funcid));
1463  if (!HeapTupleIsValid(tp))
1464  elog(ERROR, "cache lookup failed for function %u", funcid);
1465 
1466  result = ((Form_pg_proc) GETSTRUCT(tp))->prorettype;
1467  ReleaseSysCache(tp);
1468  return result;
1469 }
1470 
1471 /*
1472  * get_func_nargs
1473  * Given procedure id, return the number of arguments.
1474  */
1475 int
1477 {
1478  HeapTuple tp;
1479  int result;
1480 
1481  tp = SearchSysCache1(PROCOID, ObjectIdGetDatum(funcid));
1482  if (!HeapTupleIsValid(tp))
1483  elog(ERROR, "cache lookup failed for function %u", funcid);
1484 
1485  result = ((Form_pg_proc) GETSTRUCT(tp))->pronargs;
1486  ReleaseSysCache(tp);
1487  return result;
1488 }
1489 
1490 /*
1491  * get_func_signature
1492  * Given procedure id, return the function's argument and result types.
1493  * (The return value is the result type.)
1494  *
1495  * The arguments are returned as a palloc'd array.
1496  */
1497 Oid
1498 get_func_signature(Oid funcid, Oid **argtypes, int *nargs)
1499 {
1500  HeapTuple tp;
1501  Form_pg_proc procstruct;
1502  Oid result;
1503 
1504  tp = SearchSysCache1(PROCOID, ObjectIdGetDatum(funcid));
1505  if (!HeapTupleIsValid(tp))
1506  elog(ERROR, "cache lookup failed for function %u", funcid);
1507 
1508  procstruct = (Form_pg_proc) GETSTRUCT(tp);
1509 
1510  result = procstruct->prorettype;
1511  *nargs = (int) procstruct->pronargs;
1512  Assert(*nargs == procstruct->proargtypes.dim1);
1513  *argtypes = (Oid *) palloc(*nargs * sizeof(Oid));
1514  memcpy(*argtypes, procstruct->proargtypes.values, *nargs * sizeof(Oid));
1515 
1516  ReleaseSysCache(tp);
1517  return result;
1518 }
1519 
1520 /*
1521  * get_func_variadictype
1522  * Given procedure id, return the function's provariadic field.
1523  */
1524 Oid
1526 {
1527  HeapTuple tp;
1528  Oid result;
1529 
1530  tp = SearchSysCache1(PROCOID, ObjectIdGetDatum(funcid));
1531  if (!HeapTupleIsValid(tp))
1532  elog(ERROR, "cache lookup failed for function %u", funcid);
1533 
1534  result = ((Form_pg_proc) GETSTRUCT(tp))->provariadic;
1535  ReleaseSysCache(tp);
1536  return result;
1537 }
1538 
1539 /*
1540  * get_func_retset
1541  * Given procedure id, return the function's proretset flag.
1542  */
1543 bool
1545 {
1546  HeapTuple tp;
1547  bool result;
1548 
1549  tp = SearchSysCache1(PROCOID, ObjectIdGetDatum(funcid));
1550  if (!HeapTupleIsValid(tp))
1551  elog(ERROR, "cache lookup failed for function %u", funcid);
1552 
1553  result = ((Form_pg_proc) GETSTRUCT(tp))->proretset;
1554  ReleaseSysCache(tp);
1555  return result;
1556 }
1557 
1558 /*
1559  * func_strict
1560  * Given procedure id, return the function's proisstrict flag.
1561  */
1562 bool
1564 {
1565  HeapTuple tp;
1566  bool result;
1567 
1568  tp = SearchSysCache1(PROCOID, ObjectIdGetDatum(funcid));
1569  if (!HeapTupleIsValid(tp))
1570  elog(ERROR, "cache lookup failed for function %u", funcid);
1571 
1572  result = ((Form_pg_proc) GETSTRUCT(tp))->proisstrict;
1573  ReleaseSysCache(tp);
1574  return result;
1575 }
1576 
1577 /*
1578  * func_volatile
1579  * Given procedure id, return the function's provolatile flag.
1580  */
1581 char
1583 {
1584  HeapTuple tp;
1585  char result;
1586 
1587  tp = SearchSysCache1(PROCOID, ObjectIdGetDatum(funcid));
1588  if (!HeapTupleIsValid(tp))
1589  elog(ERROR, "cache lookup failed for function %u", funcid);
1590 
1591  result = ((Form_pg_proc) GETSTRUCT(tp))->provolatile;
1592  ReleaseSysCache(tp);
1593  return result;
1594 }
1595 
1596 /*
1597  * func_parallel
1598  * Given procedure id, return the function's proparallel flag.
1599  */
1600 char
1602 {
1603  HeapTuple tp;
1604  char result;
1605 
1606  tp = SearchSysCache1(PROCOID, ObjectIdGetDatum(funcid));
1607  if (!HeapTupleIsValid(tp))
1608  elog(ERROR, "cache lookup failed for function %u", funcid);
1609 
1610  result = ((Form_pg_proc) GETSTRUCT(tp))->proparallel;
1611  ReleaseSysCache(tp);
1612  return result;
1613 }
1614 
1615 /*
1616  * get_func_prokind
1617  * Given procedure id, return the routine kind.
1618  */
1619 char
1621 {
1622  HeapTuple tp;
1623  char result;
1624 
1625  tp = SearchSysCache1(PROCOID, ObjectIdGetDatum(funcid));
1626  if (!HeapTupleIsValid(tp))
1627  elog(ERROR, "cache lookup failed for function %u", funcid);
1628 
1629  result = ((Form_pg_proc) GETSTRUCT(tp))->prokind;
1630  ReleaseSysCache(tp);
1631  return result;
1632 }
1633 
1634 /*
1635  * get_func_leakproof
1636  * Given procedure id, return the function's leakproof field.
1637  */
1638 bool
1640 {
1641  HeapTuple tp;
1642  bool result;
1643 
1644  tp = SearchSysCache1(PROCOID, ObjectIdGetDatum(funcid));
1645  if (!HeapTupleIsValid(tp))
1646  elog(ERROR, "cache lookup failed for function %u", funcid);
1647 
1648  result = ((Form_pg_proc) GETSTRUCT(tp))->proleakproof;
1649  ReleaseSysCache(tp);
1650  return result;
1651 }
1652 
1653 /*
1654  * get_func_support
1655  *
1656  * Returns the support function OID associated with a given function,
1657  * or InvalidOid if there is none.
1658  */
1661 {
1662  HeapTuple tp;
1663 
1664  tp = SearchSysCache1(PROCOID, ObjectIdGetDatum(funcid));
1665  if (HeapTupleIsValid(tp))
1666  {
1667  Form_pg_proc functup = (Form_pg_proc) GETSTRUCT(tp);
1668  RegProcedure result;
1669 
1670  result = functup->prosupport;
1671  ReleaseSysCache(tp);
1672  return result;
1673  }
1674  else
1675  return (RegProcedure) InvalidOid;
1676 }
1677 
1678 /* ---------- RELATION CACHE ---------- */
1679 
1680 /*
1681  * get_relname_relid
1682  * Given name and namespace of a relation, look up the OID.
1683  *
1684  * Returns InvalidOid if there is no such relation.
1685  */
1686 Oid
1687 get_relname_relid(const char *relname, Oid relnamespace)
1688 {
1689  return GetSysCacheOid2(RELNAMENSP, Anum_pg_class_oid,
1690  PointerGetDatum(relname),
1691  ObjectIdGetDatum(relnamespace));
1692 }
1693 
1694 #ifdef NOT_USED
1695 /*
1696  * get_relnatts
1697  *
1698  * Returns the number of attributes for a given relation.
1699  */
1700 int
1701 get_relnatts(Oid relid)
1702 {
1703  HeapTuple tp;
1704 
1705  tp = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
1706  if (HeapTupleIsValid(tp))
1707  {
1708  Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
1709  int result;
1710 
1711  result = reltup->relnatts;
1712  ReleaseSysCache(tp);
1713  return result;
1714  }
1715  else
1716  return InvalidAttrNumber;
1717 }
1718 #endif
1719 
1720 /*
1721  * get_rel_name
1722  * Returns the name of a given relation.
1723  *
1724  * Returns a palloc'd copy of the string, or NULL if no such relation.
1725  *
1726  * NOTE: since relation name is not unique, be wary of code that uses this
1727  * for anything except preparing error messages.
1728  */
1729 char *
1731 {
1732  HeapTuple tp;
1733 
1734  tp = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
1735  if (HeapTupleIsValid(tp))
1736  {
1737  Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
1738  char *result;
1739 
1740  result = pstrdup(NameStr(reltup->relname));
1741  ReleaseSysCache(tp);
1742  return result;
1743  }
1744  else
1745  return NULL;
1746 }
1747 
1748 /*
1749  * get_rel_namespace
1750  *
1751  * Returns the pg_namespace OID associated with a given relation.
1752  */
1753 Oid
1755 {
1756  HeapTuple tp;
1757 
1758  tp = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
1759  if (HeapTupleIsValid(tp))
1760  {
1761  Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
1762  Oid result;
1763 
1764  result = reltup->relnamespace;
1765  ReleaseSysCache(tp);
1766  return result;
1767  }
1768  else
1769  return InvalidOid;
1770 }
1771 
1772 /*
1773  * get_rel_type_id
1774  *
1775  * Returns the pg_type OID associated with a given relation.
1776  *
1777  * Note: not all pg_class entries have associated pg_type OIDs; so be
1778  * careful to check for InvalidOid result.
1779  */
1780 Oid
1782 {
1783  HeapTuple tp;
1784 
1785  tp = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
1786  if (HeapTupleIsValid(tp))
1787  {
1788  Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
1789  Oid result;
1790 
1791  result = reltup->reltype;
1792  ReleaseSysCache(tp);
1793  return result;
1794  }
1795  else
1796  return InvalidOid;
1797 }
1798 
1799 /*
1800  * get_rel_relkind
1801  *
1802  * Returns the relkind associated with a given relation.
1803  */
1804 char
1806 {
1807  HeapTuple tp;
1808 
1809  tp = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
1810  if (HeapTupleIsValid(tp))
1811  {
1812  Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
1813  char result;
1814 
1815  result = reltup->relkind;
1816  ReleaseSysCache(tp);
1817  return result;
1818  }
1819  else
1820  return '\0';
1821 }
1822 
1823 /*
1824  * get_rel_relispartition
1825  *
1826  * Returns the relispartition flag associated with a given relation.
1827  */
1828 bool
1830 {
1831  HeapTuple tp;
1832 
1833  tp = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
1834  if (HeapTupleIsValid(tp))
1835  {
1836  Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
1837  bool result;
1838 
1839  result = reltup->relispartition;
1840  ReleaseSysCache(tp);
1841  return result;
1842  }
1843  else
1844  return false;
1845 }
1846 
1847 /*
1848  * get_rel_tablespace
1849  *
1850  * Returns the pg_tablespace OID associated with a given relation.
1851  *
1852  * Note: InvalidOid might mean either that we couldn't find the relation,
1853  * or that it is in the database's default tablespace.
1854  */
1855 Oid
1857 {
1858  HeapTuple tp;
1859 
1860  tp = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
1861  if (HeapTupleIsValid(tp))
1862  {
1863  Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
1864  Oid result;
1865 
1866  result = reltup->reltablespace;
1867  ReleaseSysCache(tp);
1868  return result;
1869  }
1870  else
1871  return InvalidOid;
1872 }
1873 
1874 /*
1875  * get_rel_persistence
1876  *
1877  * Returns the relpersistence associated with a given relation.
1878  */
1879 char
1881 {
1882  HeapTuple tp;
1883  Form_pg_class reltup;
1884  char result;
1885 
1886  tp = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
1887  if (!HeapTupleIsValid(tp))
1888  elog(ERROR, "cache lookup failed for relation %u", relid);
1889  reltup = (Form_pg_class) GETSTRUCT(tp);
1890  result = reltup->relpersistence;
1891  ReleaseSysCache(tp);
1892 
1893  return result;
1894 }
1895 
1896 
1897 /* ---------- TRANSFORM CACHE ---------- */
1898 
1899 Oid
1900 get_transform_fromsql(Oid typid, Oid langid, List *trftypes)
1901 {
1902  HeapTuple tup;
1903 
1904  if (!list_member_oid(trftypes, typid))
1905  return InvalidOid;
1906 
1907  tup = SearchSysCache2(TRFTYPELANG, typid, langid);
1908  if (HeapTupleIsValid(tup))
1909  {
1910  Oid funcid;
1911 
1912  funcid = ((Form_pg_transform) GETSTRUCT(tup))->trffromsql;
1913  ReleaseSysCache(tup);
1914  return funcid;
1915  }
1916  else
1917  return InvalidOid;
1918 }
1919 
1920 Oid
1921 get_transform_tosql(Oid typid, Oid langid, List *trftypes)
1922 {
1923  HeapTuple tup;
1924 
1925  if (!list_member_oid(trftypes, typid))
1926  return InvalidOid;
1927 
1928  tup = SearchSysCache2(TRFTYPELANG, typid, langid);
1929  if (HeapTupleIsValid(tup))
1930  {
1931  Oid funcid;
1932 
1933  funcid = ((Form_pg_transform) GETSTRUCT(tup))->trftosql;
1934  ReleaseSysCache(tup);
1935  return funcid;
1936  }
1937  else
1938  return InvalidOid;
1939 }
1940 
1941 
1942 /* ---------- TYPE CACHE ---------- */
1943 
1944 /*
1945  * get_typisdefined
1946  *
1947  * Given the type OID, determine whether the type is defined
1948  * (if not, it's only a shell).
1949  */
1950 bool
1952 {
1953  HeapTuple tp;
1954 
1956  if (HeapTupleIsValid(tp))
1957  {
1958  Form_pg_type typtup = (Form_pg_type) GETSTRUCT(tp);
1959  bool result;
1960 
1961  result = typtup->typisdefined;
1962  ReleaseSysCache(tp);
1963  return result;
1964  }
1965  else
1966  return false;
1967 }
1968 
1969 /*
1970  * get_typlen
1971  *
1972  * Given the type OID, return the length of the type.
1973  */
1974 int16
1976 {
1977  HeapTuple tp;
1978 
1980  if (HeapTupleIsValid(tp))
1981  {
1982  Form_pg_type typtup = (Form_pg_type) GETSTRUCT(tp);
1983  int16 result;
1984 
1985  result = typtup->typlen;
1986  ReleaseSysCache(tp);
1987  return result;
1988  }
1989  else
1990  return 0;
1991 }
1992 
1993 /*
1994  * get_typbyval
1995  *
1996  * Given the type OID, determine whether the type is returned by value or
1997  * not. Returns true if by value, false if by reference.
1998  */
1999 bool
2001 {
2002  HeapTuple tp;
2003 
2005  if (HeapTupleIsValid(tp))
2006  {
2007  Form_pg_type typtup = (Form_pg_type) GETSTRUCT(tp);
2008  bool result;
2009 
2010  result = typtup->typbyval;
2011  ReleaseSysCache(tp);
2012  return result;
2013  }
2014  else
2015  return false;
2016 }
2017 
2018 /*
2019  * get_typlenbyval
2020  *
2021  * A two-fer: given the type OID, return both typlen and typbyval.
2022  *
2023  * Since both pieces of info are needed to know how to copy a Datum,
2024  * many places need both. Might as well get them with one cache lookup
2025  * instead of two. Also, this routine raises an error instead of
2026  * returning a bogus value when given a bad type OID.
2027  */
2028 void
2029 get_typlenbyval(Oid typid, int16 *typlen, bool *typbyval)
2030 {
2031  HeapTuple tp;
2032  Form_pg_type typtup;
2033 
2035  if (!HeapTupleIsValid(tp))
2036  elog(ERROR, "cache lookup failed for type %u", typid);
2037  typtup = (Form_pg_type) GETSTRUCT(tp);
2038  *typlen = typtup->typlen;
2039  *typbyval = typtup->typbyval;
2040  ReleaseSysCache(tp);
2041 }
2042 
2043 /*
2044  * get_typlenbyvalalign
2045  *
2046  * A three-fer: given the type OID, return typlen, typbyval, typalign.
2047  */
2048 void
2049 get_typlenbyvalalign(Oid typid, int16 *typlen, bool *typbyval,
2050  char *typalign)
2051 {
2052  HeapTuple tp;
2053  Form_pg_type typtup;
2054 
2056  if (!HeapTupleIsValid(tp))
2057  elog(ERROR, "cache lookup failed for type %u", typid);
2058  typtup = (Form_pg_type) GETSTRUCT(tp);
2059  *typlen = typtup->typlen;
2060  *typbyval = typtup->typbyval;
2061  *typalign = typtup->typalign;
2062  ReleaseSysCache(tp);
2063 }
2064 
2065 /*
2066  * getTypeIOParam
2067  * Given a pg_type row, select the type OID to pass to I/O functions
2068  *
2069  * Formerly, all I/O functions were passed pg_type.typelem as their second
2070  * parameter, but we now have a more complex rule about what to pass.
2071  * This knowledge is intended to be centralized here --- direct references
2072  * to typelem elsewhere in the code are wrong, if they are associated with
2073  * I/O calls and not with actual subscripting operations! (But see
2074  * bootstrap.c's boot_get_type_io_data() if you need to change this.)
2075  *
2076  * As of PostgreSQL 8.1, output functions receive only the value itself
2077  * and not any auxiliary parameters, so the name of this routine is now
2078  * a bit of a misnomer ... it should be getTypeInputParam.
2079  */
2080 Oid
2082 {
2083  Form_pg_type typeStruct = (Form_pg_type) GETSTRUCT(typeTuple);
2084 
2085  /*
2086  * Array types get their typelem as parameter; everybody else gets their
2087  * own type OID as parameter.
2088  */
2089  if (OidIsValid(typeStruct->typelem))
2090  return typeStruct->typelem;
2091  else
2092  return typeStruct->oid;
2093 }
2094 
2095 /*
2096  * get_type_io_data
2097  *
2098  * A six-fer: given the type OID, return typlen, typbyval, typalign,
2099  * typdelim, typioparam, and IO function OID. The IO function
2100  * returned is controlled by IOFuncSelector
2101  */
2102 void
2104  IOFuncSelector which_func,
2105  int16 *typlen,
2106  bool *typbyval,
2107  char *typalign,
2108  char *typdelim,
2109  Oid *typioparam,
2110  Oid *func)
2111 {
2112  HeapTuple typeTuple;
2113  Form_pg_type typeStruct;
2114 
2115  /*
2116  * In bootstrap mode, pass it off to bootstrap.c. This hack allows us to
2117  * use array_in and array_out during bootstrap.
2118  */
2120  {
2121  Oid typinput;
2122  Oid typoutput;
2123 
2124  boot_get_type_io_data(typid,
2125  typlen,
2126  typbyval,
2127  typalign,
2128  typdelim,
2129  typioparam,
2130  &typinput,
2131  &typoutput);
2132  switch (which_func)
2133  {
2134  case IOFunc_input:
2135  *func = typinput;
2136  break;
2137  case IOFunc_output:
2138  *func = typoutput;
2139  break;
2140  default:
2141  elog(ERROR, "binary I/O not supported during bootstrap");
2142  break;
2143  }
2144  return;
2145  }
2146 
2147  typeTuple = SearchSysCache1(TYPEOID, ObjectIdGetDatum(typid));
2148  if (!HeapTupleIsValid(typeTuple))
2149  elog(ERROR, "cache lookup failed for type %u", typid);
2150  typeStruct = (Form_pg_type) GETSTRUCT(typeTuple);
2151 
2152  *typlen = typeStruct->typlen;
2153  *typbyval = typeStruct->typbyval;
2154  *typalign = typeStruct->typalign;
2155  *typdelim = typeStruct->typdelim;
2156  *typioparam = getTypeIOParam(typeTuple);
2157  switch (which_func)
2158  {
2159  case IOFunc_input:
2160  *func = typeStruct->typinput;
2161  break;
2162  case IOFunc_output:
2163  *func = typeStruct->typoutput;
2164  break;
2165  case IOFunc_receive:
2166  *func = typeStruct->typreceive;
2167  break;
2168  case IOFunc_send:
2169  *func = typeStruct->typsend;
2170  break;
2171  }
2172  ReleaseSysCache(typeTuple);
2173 }
2174 
2175 #ifdef NOT_USED
2176 char
2177 get_typalign(Oid typid)
2178 {
2179  HeapTuple tp;
2180 
2182  if (HeapTupleIsValid(tp))
2183  {
2184  Form_pg_type typtup = (Form_pg_type) GETSTRUCT(tp);
2185  char result;
2186 
2187  result = typtup->typalign;
2188  ReleaseSysCache(tp);
2189  return result;
2190  }
2191  else
2192  return 'i';
2193 }
2194 #endif
2195 
2196 char
2198 {
2199  HeapTuple tp;
2200 
2202  if (HeapTupleIsValid(tp))
2203  {
2204  Form_pg_type typtup = (Form_pg_type) GETSTRUCT(tp);
2205  char result;
2206 
2207  result = typtup->typstorage;
2208  ReleaseSysCache(tp);
2209  return result;
2210  }
2211  else
2212  return 'p';
2213 }
2214 
2215 /*
2216  * get_typdefault
2217  * Given a type OID, return the type's default value, if any.
2218  *
2219  * The result is a palloc'd expression node tree, or NULL if there
2220  * is no defined default for the datatype.
2221  *
2222  * NB: caller should be prepared to coerce result to correct datatype;
2223  * the returned expression tree might produce something of the wrong type.
2224  */
2225 Node *
2227 {
2228  HeapTuple typeTuple;
2230  Datum datum;
2231  bool isNull;
2232  Node *expr;
2233 
2234  typeTuple = SearchSysCache1(TYPEOID, ObjectIdGetDatum(typid));
2235  if (!HeapTupleIsValid(typeTuple))
2236  elog(ERROR, "cache lookup failed for type %u", typid);
2237  type = (Form_pg_type) GETSTRUCT(typeTuple);
2238 
2239  /*
2240  * typdefault and typdefaultbin are potentially null, so don't try to
2241  * access 'em as struct fields. Must do it the hard way with
2242  * SysCacheGetAttr.
2243  */
2244  datum = SysCacheGetAttr(TYPEOID,
2245  typeTuple,
2246  Anum_pg_type_typdefaultbin,
2247  &isNull);
2248 
2249  if (!isNull)
2250  {
2251  /* We have an expression default */
2252  expr = stringToNode(TextDatumGetCString(datum));
2253  }
2254  else
2255  {
2256  /* Perhaps we have a plain literal default */
2257  datum = SysCacheGetAttr(TYPEOID,
2258  typeTuple,
2259  Anum_pg_type_typdefault,
2260  &isNull);
2261 
2262  if (!isNull)
2263  {
2264  char *strDefaultVal;
2265 
2266  /* Convert text datum to C string */
2267  strDefaultVal = TextDatumGetCString(datum);
2268  /* Convert C string to a value of the given type */
2269  datum = OidInputFunctionCall(type->typinput, strDefaultVal,
2270  getTypeIOParam(typeTuple), -1);
2271  /* Build a Const node containing the value */
2272  expr = (Node *) makeConst(typid,
2273  -1,
2274  type->typcollation,
2275  type->typlen,
2276  datum,
2277  false,
2278  type->typbyval);
2279  pfree(strDefaultVal);
2280  }
2281  else
2282  {
2283  /* No default */
2284  expr = NULL;
2285  }
2286  }
2287 
2288  ReleaseSysCache(typeTuple);
2289 
2290  return expr;
2291 }
2292 
2293 /*
2294  * getBaseType
2295  * If the given type is a domain, return its base type;
2296  * otherwise return the type's own OID.
2297  */
2298 Oid
2300 {
2301  int32 typmod = -1;
2302 
2303  return getBaseTypeAndTypmod(typid, &typmod);
2304 }
2305 
2306 /*
2307  * getBaseTypeAndTypmod
2308  * If the given type is a domain, return its base type and typmod;
2309  * otherwise return the type's own OID, and leave *typmod unchanged.
2310  *
2311  * Note that the "applied typmod" should be -1 for every domain level
2312  * above the bottommost; therefore, if the passed-in typid is indeed
2313  * a domain, *typmod should be -1.
2314  */
2315 Oid
2317 {
2318  /*
2319  * We loop to find the bottom base type in a stack of domains.
2320  */
2321  for (;;)
2322  {
2323  HeapTuple tup;
2324  Form_pg_type typTup;
2325 
2326  tup = SearchSysCache1(TYPEOID, ObjectIdGetDatum(typid));
2327  if (!HeapTupleIsValid(tup))
2328  elog(ERROR, "cache lookup failed for type %u", typid);
2329  typTup = (Form_pg_type) GETSTRUCT(tup);
2330  if (typTup->typtype != TYPTYPE_DOMAIN)
2331  {
2332  /* Not a domain, so done */
2333  ReleaseSysCache(tup);
2334  break;
2335  }
2336 
2337  Assert(*typmod == -1);
2338  typid = typTup->typbasetype;
2339  *typmod = typTup->typtypmod;
2340 
2341  ReleaseSysCache(tup);
2342  }
2343 
2344  return typid;
2345 }
2346 
2347 /*
2348  * get_typavgwidth
2349  *
2350  * Given a type OID and a typmod value (pass -1 if typmod is unknown),
2351  * estimate the average width of values of the type. This is used by
2352  * the planner, which doesn't require absolutely correct results;
2353  * it's OK (and expected) to guess if we don't know for sure.
2354  */
2355 int32
2356 get_typavgwidth(Oid typid, int32 typmod)
2357 {
2358  int typlen = get_typlen(typid);
2359  int32 maxwidth;
2360 
2361  /*
2362  * Easy if it's a fixed-width type
2363  */
2364  if (typlen > 0)
2365  return typlen;
2366 
2367  /*
2368  * type_maximum_size knows the encoding of typmod for some datatypes;
2369  * don't duplicate that knowledge here.
2370  */
2371  maxwidth = type_maximum_size(typid, typmod);
2372  if (maxwidth > 0)
2373  {
2374  /*
2375  * For BPCHAR, the max width is also the only width. Otherwise we
2376  * need to guess about the typical data width given the max. A sliding
2377  * scale for percentage of max width seems reasonable.
2378  */
2379  if (typid == BPCHAROID)
2380  return maxwidth;
2381  if (maxwidth <= 32)
2382  return maxwidth; /* assume full width */
2383  if (maxwidth < 1000)
2384  return 32 + (maxwidth - 32) / 2; /* assume 50% */
2385 
2386  /*
2387  * Beyond 1000, assume we're looking at something like
2388  * "varchar(10000)" where the limit isn't actually reached often, and
2389  * use a fixed estimate.
2390  */
2391  return 32 + (1000 - 32) / 2;
2392  }
2393 
2394  /*
2395  * Oops, we have no idea ... wild guess time.
2396  */
2397  return 32;
2398 }
2399 
2400 /*
2401  * get_typtype
2402  *
2403  * Given the type OID, find if it is a basic type, a complex type, etc.
2404  * It returns the null char if the cache lookup fails...
2405  */
2406 char
2408 {
2409  HeapTuple tp;
2410 
2412  if (HeapTupleIsValid(tp))
2413  {
2414  Form_pg_type typtup = (Form_pg_type) GETSTRUCT(tp);
2415  char result;
2416 
2417  result = typtup->typtype;
2418  ReleaseSysCache(tp);
2419  return result;
2420  }
2421  else
2422  return '\0';
2423 }
2424 
2425 /*
2426  * type_is_rowtype
2427  *
2428  * Convenience function to determine whether a type OID represents
2429  * a "rowtype" type --- either RECORD or a named composite type
2430  * (including a domain over a named composite type).
2431  */
2432 bool
2434 {
2435  if (typid == RECORDOID)
2436  return true; /* easy case */
2437  switch (get_typtype(typid))
2438  {
2439  case TYPTYPE_COMPOSITE:
2440  return true;
2441  case TYPTYPE_DOMAIN:
2442  if (get_typtype(getBaseType(typid)) == TYPTYPE_COMPOSITE)
2443  return true;
2444  break;
2445  default:
2446  break;
2447  }
2448  return false;
2449 }
2450 
2451 /*
2452  * type_is_enum
2453  * Returns true if the given type is an enum type.
2454  */
2455 bool
2457 {
2458  return (get_typtype(typid) == TYPTYPE_ENUM);
2459 }
2460 
2461 /*
2462  * type_is_range
2463  * Returns true if the given type is a range type.
2464  */
2465 bool
2467 {
2468  return (get_typtype(typid) == TYPTYPE_RANGE);
2469 }
2470 
2471 /*
2472  * get_type_category_preferred
2473  *
2474  * Given the type OID, fetch its category and preferred-type status.
2475  * Throws error on failure.
2476  */
2477 void
2478 get_type_category_preferred(Oid typid, char *typcategory, bool *typispreferred)
2479 {
2480  HeapTuple tp;
2481  Form_pg_type typtup;
2482 
2484  if (!HeapTupleIsValid(tp))
2485  elog(ERROR, "cache lookup failed for type %u", typid);
2486  typtup = (Form_pg_type) GETSTRUCT(tp);
2487  *typcategory = typtup->typcategory;
2488  *typispreferred = typtup->typispreferred;
2489  ReleaseSysCache(tp);
2490 }
2491 
2492 /*
2493  * get_typ_typrelid
2494  *
2495  * Given the type OID, get the typrelid (InvalidOid if not a complex
2496  * type).
2497  */
2498 Oid
2500 {
2501  HeapTuple tp;
2502 
2504  if (HeapTupleIsValid(tp))
2505  {
2506  Form_pg_type typtup = (Form_pg_type) GETSTRUCT(tp);
2507  Oid result;
2508 
2509  result = typtup->typrelid;
2510  ReleaseSysCache(tp);
2511  return result;
2512  }
2513  else
2514  return InvalidOid;
2515 }
2516 
2517 /*
2518  * get_element_type
2519  *
2520  * Given the type OID, get the typelem (InvalidOid if not an array type).
2521  *
2522  * NB: this only considers varlena arrays to be true arrays; InvalidOid is
2523  * returned if the input is a fixed-length array type.
2524  */
2525 Oid
2527 {
2528  HeapTuple tp;
2529 
2531  if (HeapTupleIsValid(tp))
2532  {
2533  Form_pg_type typtup = (Form_pg_type) GETSTRUCT(tp);
2534  Oid result;
2535 
2536  if (typtup->typlen == -1)
2537  result = typtup->typelem;
2538  else
2539  result = InvalidOid;
2540  ReleaseSysCache(tp);
2541  return result;
2542  }
2543  else
2544  return InvalidOid;
2545 }
2546 
2547 /*
2548  * get_array_type
2549  *
2550  * Given the type OID, get the corresponding "true" array type.
2551  * Returns InvalidOid if no array type can be found.
2552  */
2553 Oid
2555 {
2556  HeapTuple tp;
2557  Oid result = InvalidOid;
2558 
2560  if (HeapTupleIsValid(tp))
2561  {
2562  result = ((Form_pg_type) GETSTRUCT(tp))->typarray;
2563  ReleaseSysCache(tp);
2564  }
2565  return result;
2566 }
2567 
2568 /*
2569  * get_promoted_array_type
2570  *
2571  * The "promoted" type is what you'd get from an ARRAY(SELECT ...)
2572  * construct, that is, either the corresponding "true" array type
2573  * if the input is a scalar type that has such an array type,
2574  * or the same type if the input is already a "true" array type.
2575  * Returns InvalidOid if neither rule is satisfied.
2576  */
2577 Oid
2579 {
2580  Oid array_type = get_array_type(typid);
2581 
2582  if (OidIsValid(array_type))
2583  return array_type;
2584  if (OidIsValid(get_element_type(typid)))
2585  return typid;
2586  return InvalidOid;
2587 }
2588 
2589 /*
2590  * get_base_element_type
2591  * Given the type OID, get the typelem, looking "through" any domain
2592  * to its underlying array type.
2593  *
2594  * This is equivalent to get_element_type(getBaseType(typid)), but avoids
2595  * an extra cache lookup. Note that it fails to provide any information
2596  * about the typmod of the array.
2597  */
2598 Oid
2600 {
2601  /*
2602  * We loop to find the bottom base type in a stack of domains.
2603  */
2604  for (;;)
2605  {
2606  HeapTuple tup;
2607  Form_pg_type typTup;
2608 
2609  tup = SearchSysCache1(TYPEOID, ObjectIdGetDatum(typid));
2610  if (!HeapTupleIsValid(tup))
2611  break;
2612  typTup = (Form_pg_type) GETSTRUCT(tup);
2613  if (typTup->typtype != TYPTYPE_DOMAIN)
2614  {
2615  /* Not a domain, so stop descending */
2616  Oid result;
2617 
2618  /* This test must match get_element_type */
2619  if (typTup->typlen == -1)
2620  result = typTup->typelem;
2621  else
2622  result = InvalidOid;
2623  ReleaseSysCache(tup);
2624  return result;
2625  }
2626 
2627  typid = typTup->typbasetype;
2628  ReleaseSysCache(tup);
2629  }
2630 
2631  /* Like get_element_type, silently return InvalidOid for bogus input */
2632  return InvalidOid;
2633 }
2634 
2635 /*
2636  * getTypeInputInfo
2637  *
2638  * Get info needed for converting values of a type to internal form
2639  */
2640 void
2641 getTypeInputInfo(Oid type, Oid *typInput, Oid *typIOParam)
2642 {
2643  HeapTuple typeTuple;
2644  Form_pg_type pt;
2645 
2646  typeTuple = SearchSysCache1(TYPEOID, ObjectIdGetDatum(type));
2647  if (!HeapTupleIsValid(typeTuple))
2648  elog(ERROR, "cache lookup failed for type %u", type);
2649  pt = (Form_pg_type) GETSTRUCT(typeTuple);
2650 
2651  if (!pt->typisdefined)
2652  ereport(ERROR,
2653  (errcode(ERRCODE_UNDEFINED_OBJECT),
2654  errmsg("type %s is only a shell",
2655  format_type_be(type))));
2656  if (!OidIsValid(pt->typinput))
2657  ereport(ERROR,
2658  (errcode(ERRCODE_UNDEFINED_FUNCTION),
2659  errmsg("no input function available for type %s",
2660  format_type_be(type))));
2661 
2662  *typInput = pt->typinput;
2663  *typIOParam = getTypeIOParam(typeTuple);
2664 
2665  ReleaseSysCache(typeTuple);
2666 }
2667 
2668 /*
2669  * getTypeOutputInfo
2670  *
2671  * Get info needed for printing values of a type
2672  */
2673 void
2674 getTypeOutputInfo(Oid type, Oid *typOutput, bool *typIsVarlena)
2675 {
2676  HeapTuple typeTuple;
2677  Form_pg_type pt;
2678 
2679  typeTuple = SearchSysCache1(TYPEOID, ObjectIdGetDatum(type));
2680  if (!HeapTupleIsValid(typeTuple))
2681  elog(ERROR, "cache lookup failed for type %u", type);
2682  pt = (Form_pg_type) GETSTRUCT(typeTuple);
2683 
2684  if (!pt->typisdefined)
2685  ereport(ERROR,
2686  (errcode(ERRCODE_UNDEFINED_OBJECT),
2687  errmsg("type %s is only a shell",
2688  format_type_be(type))));
2689  if (!OidIsValid(pt->typoutput))
2690  ereport(ERROR,
2691  (errcode(ERRCODE_UNDEFINED_FUNCTION),
2692  errmsg("no output function available for type %s",
2693  format_type_be(type))));
2694 
2695  *typOutput = pt->typoutput;
2696  *typIsVarlena = (!pt->typbyval) && (pt->typlen == -1);
2697 
2698  ReleaseSysCache(typeTuple);
2699 }
2700 
2701 /*
2702  * getTypeBinaryInputInfo
2703  *
2704  * Get info needed for binary input of values of a type
2705  */
2706 void
2707 getTypeBinaryInputInfo(Oid type, Oid *typReceive, Oid *typIOParam)
2708 {
2709  HeapTuple typeTuple;
2710  Form_pg_type pt;
2711 
2712  typeTuple = SearchSysCache1(TYPEOID, ObjectIdGetDatum(type));
2713  if (!HeapTupleIsValid(typeTuple))
2714  elog(ERROR, "cache lookup failed for type %u", type);
2715  pt = (Form_pg_type) GETSTRUCT(typeTuple);
2716 
2717  if (!pt->typisdefined)
2718  ereport(ERROR,
2719  (errcode(ERRCODE_UNDEFINED_OBJECT),
2720  errmsg("type %s is only a shell",
2721  format_type_be(type))));
2722  if (!OidIsValid(pt->typreceive))
2723  ereport(ERROR,
2724  (errcode(ERRCODE_UNDEFINED_FUNCTION),
2725  errmsg("no binary input function available for type %s",
2726  format_type_be(type))));
2727 
2728  *typReceive = pt->typreceive;
2729  *typIOParam = getTypeIOParam(typeTuple);
2730 
2731  ReleaseSysCache(typeTuple);
2732 }
2733 
2734 /*
2735  * getTypeBinaryOutputInfo
2736  *
2737  * Get info needed for binary output of values of a type
2738  */
2739 void
2740 getTypeBinaryOutputInfo(Oid type, Oid *typSend, bool *typIsVarlena)
2741 {
2742  HeapTuple typeTuple;
2743  Form_pg_type pt;
2744 
2745  typeTuple = SearchSysCache1(TYPEOID, ObjectIdGetDatum(type));
2746  if (!HeapTupleIsValid(typeTuple))
2747  elog(ERROR, "cache lookup failed for type %u", type);
2748  pt = (Form_pg_type) GETSTRUCT(typeTuple);
2749 
2750  if (!pt->typisdefined)
2751  ereport(ERROR,
2752  (errcode(ERRCODE_UNDEFINED_OBJECT),
2753  errmsg("type %s is only a shell",
2754  format_type_be(type))));
2755  if (!OidIsValid(pt->typsend))
2756  ereport(ERROR,
2757  (errcode(ERRCODE_UNDEFINED_FUNCTION),
2758  errmsg("no binary output function available for type %s",
2759  format_type_be(type))));
2760 
2761  *typSend = pt->typsend;
2762  *typIsVarlena = (!pt->typbyval) && (pt->typlen == -1);
2763 
2764  ReleaseSysCache(typeTuple);
2765 }
2766 
2767 /*
2768  * get_typmodin
2769  *
2770  * Given the type OID, return the type's typmodin procedure, if any.
2771  */
2772 Oid
2774 {
2775  HeapTuple tp;
2776 
2778  if (HeapTupleIsValid(tp))
2779  {
2780  Form_pg_type typtup = (Form_pg_type) GETSTRUCT(tp);
2781  Oid result;
2782 
2783  result = typtup->typmodin;
2784  ReleaseSysCache(tp);
2785  return result;
2786  }
2787  else
2788  return InvalidOid;
2789 }
2790 
2791 #ifdef NOT_USED
2792 /*
2793  * get_typmodout
2794  *
2795  * Given the type OID, return the type's typmodout procedure, if any.
2796  */
2797 Oid
2798 get_typmodout(Oid typid)
2799 {
2800  HeapTuple tp;
2801 
2803  if (HeapTupleIsValid(tp))
2804  {
2805  Form_pg_type typtup = (Form_pg_type) GETSTRUCT(tp);
2806  Oid result;
2807 
2808  result = typtup->typmodout;
2809  ReleaseSysCache(tp);
2810  return result;
2811  }
2812  else
2813  return InvalidOid;
2814 }
2815 #endif /* NOT_USED */
2816 
2817 /*
2818  * get_typcollation
2819  *
2820  * Given the type OID, return the type's typcollation attribute.
2821  */
2822 Oid
2824 {
2825  HeapTuple tp;
2826 
2828  if (HeapTupleIsValid(tp))
2829  {
2830  Form_pg_type typtup = (Form_pg_type) GETSTRUCT(tp);
2831  Oid result;
2832 
2833  result = typtup->typcollation;
2834  ReleaseSysCache(tp);
2835  return result;
2836  }
2837  else
2838  return InvalidOid;
2839 }
2840 
2841 
2842 /*
2843  * type_is_collatable
2844  *
2845  * Return whether the type cares about collations
2846  */
2847 bool
2849 {
2850  return OidIsValid(get_typcollation(typid));
2851 }
2852 
2853 
2854 /* ---------- STATISTICS CACHE ---------- */
2855 
2856 /*
2857  * get_attavgwidth
2858  *
2859  * Given the table and attribute number of a column, get the average
2860  * width of entries in the column. Return zero if no data available.
2861  *
2862  * Currently this is only consulted for individual tables, not for inheritance
2863  * trees, so we don't need an "inh" parameter.
2864  *
2865  * Calling a hook at this point looks somewhat strange, but is required
2866  * because the optimizer calls this function without any other way for
2867  * plug-ins to control the result.
2868  */
2869 int32
2871 {
2872  HeapTuple tp;
2873  int32 stawidth;
2874 
2876  {
2877  stawidth = (*get_attavgwidth_hook) (relid, attnum);
2878  if (stawidth > 0)
2879  return stawidth;
2880  }
2882  ObjectIdGetDatum(relid),
2883  Int16GetDatum(attnum),
2884  BoolGetDatum(false));
2885  if (HeapTupleIsValid(tp))
2886  {
2887  stawidth = ((Form_pg_statistic) GETSTRUCT(tp))->stawidth;
2888  ReleaseSysCache(tp);
2889  if (stawidth > 0)
2890  return stawidth;
2891  }
2892  return 0;
2893 }
2894 
2895 /*
2896  * get_attstatsslot
2897  *
2898  * Extract the contents of a "slot" of a pg_statistic tuple.
2899  * Returns true if requested slot type was found, else false.
2900  *
2901  * Unlike other routines in this file, this takes a pointer to an
2902  * already-looked-up tuple in the pg_statistic cache. We do this since
2903  * most callers will want to extract more than one value from the cache
2904  * entry, and we don't want to repeat the cache lookup unnecessarily.
2905  * Also, this API allows this routine to be used with statistics tuples
2906  * that have been provided by a stats hook and didn't really come from
2907  * pg_statistic.
2908  *
2909  * sslot: pointer to output area (typically, a local variable in the caller).
2910  * statstuple: pg_statistic tuple to be examined.
2911  * reqkind: STAKIND code for desired statistics slot kind.
2912  * reqop: STAOP value wanted, or InvalidOid if don't care.
2913  * flags: bitmask of ATTSTATSSLOT_VALUES and/or ATTSTATSSLOT_NUMBERS.
2914  *
2915  * If a matching slot is found, true is returned, and *sslot is filled thus:
2916  * staop: receives the actual STAOP value.
2917  * stacoll: receives the actual STACOLL value.
2918  * valuetype: receives actual datatype of the elements of stavalues.
2919  * values: receives pointer to an array of the slot's stavalues.
2920  * nvalues: receives number of stavalues.
2921  * numbers: receives pointer to an array of the slot's stanumbers (as float4).
2922  * nnumbers: receives number of stanumbers.
2923  *
2924  * valuetype/values/nvalues are InvalidOid/NULL/0 if ATTSTATSSLOT_VALUES
2925  * wasn't specified. Likewise, numbers/nnumbers are NULL/0 if
2926  * ATTSTATSSLOT_NUMBERS wasn't specified.
2927  *
2928  * If no matching slot is found, false is returned, and *sslot is zeroed.
2929  *
2930  * Note that the current API doesn't allow for searching for a slot with
2931  * a particular collation. If we ever actually support recording more than
2932  * one collation, we'll have to extend the API, but for now simple is good.
2933  *
2934  * The data referred to by the fields of sslot is locally palloc'd and
2935  * is independent of the original pg_statistic tuple. When the caller
2936  * is done with it, call free_attstatsslot to release the palloc'd data.
2937  *
2938  * If it's desirable to call free_attstatsslot when get_attstatsslot might
2939  * not have been called, memset'ing sslot to zeroes will allow that.
2940  */
2941 bool
2943  int reqkind, Oid reqop, int flags)
2944 {
2945  Form_pg_statistic stats = (Form_pg_statistic) GETSTRUCT(statstuple);
2946  int i;
2947  Datum val;
2948  bool isnull;
2949  ArrayType *statarray;
2950  Oid arrayelemtype;
2951  int narrayelem;
2952  HeapTuple typeTuple;
2953  Form_pg_type typeForm;
2954 
2955  /* initialize *sslot properly */
2956  memset(sslot, 0, sizeof(AttStatsSlot));
2957 
2958  for (i = 0; i < STATISTIC_NUM_SLOTS; i++)
2959  {
2960  if ((&stats->stakind1)[i] == reqkind &&
2961  (reqop == InvalidOid || (&stats->staop1)[i] == reqop))
2962  break;
2963  }
2964  if (i >= STATISTIC_NUM_SLOTS)
2965  return false; /* not there */
2966 
2967  sslot->staop = (&stats->staop1)[i];
2968  sslot->stacoll = (&stats->stacoll1)[i];
2969 
2970  /*
2971  * XXX Hopefully-temporary hack: if stacoll isn't set, inject the default
2972  * collation. This won't matter for non-collation-aware datatypes. For
2973  * those that are, this covers cases where stacoll has not been set. In
2974  * the short term we need this because some code paths involving type NAME
2975  * do not pass any collation to prefix_selectivity and related functions.
2976  * Even when that's been fixed, it's likely that some add-on typanalyze
2977  * functions won't get the word right away about filling stacoll during
2978  * ANALYZE, so we'll probably need this for awhile.
2979  */
2980  if (sslot->stacoll == InvalidOid)
2981  sslot->stacoll = DEFAULT_COLLATION_OID;
2982 
2983  if (flags & ATTSTATSSLOT_VALUES)
2984  {
2985  val = SysCacheGetAttr(STATRELATTINH, statstuple,
2986  Anum_pg_statistic_stavalues1 + i,
2987  &isnull);
2988  if (isnull)
2989  elog(ERROR, "stavalues is null");
2990 
2991  /*
2992  * Detoast the array if needed, and in any case make a copy that's
2993  * under control of this AttStatsSlot.
2994  */
2995  statarray = DatumGetArrayTypePCopy(val);
2996 
2997  /*
2998  * Extract the actual array element type, and pass it back in case the
2999  * caller needs it.
3000  */
3001  sslot->valuetype = arrayelemtype = ARR_ELEMTYPE(statarray);
3002 
3003  /* Need info about element type */
3004  typeTuple = SearchSysCache1(TYPEOID, ObjectIdGetDatum(arrayelemtype));
3005  if (!HeapTupleIsValid(typeTuple))
3006  elog(ERROR, "cache lookup failed for type %u", arrayelemtype);
3007  typeForm = (Form_pg_type) GETSTRUCT(typeTuple);
3008 
3009  /* Deconstruct array into Datum elements; NULLs not expected */
3010  deconstruct_array(statarray,
3011  arrayelemtype,
3012  typeForm->typlen,
3013  typeForm->typbyval,
3014  typeForm->typalign,
3015  &sslot->values, NULL, &sslot->nvalues);
3016 
3017  /*
3018  * If the element type is pass-by-reference, we now have a bunch of
3019  * Datums that are pointers into the statarray, so we need to keep
3020  * that until free_attstatsslot. Otherwise, all the useful info is in
3021  * sslot->values[], so we can free the array object immediately.
3022  */
3023  if (!typeForm->typbyval)
3024  sslot->values_arr = statarray;
3025  else
3026  pfree(statarray);
3027 
3028  ReleaseSysCache(typeTuple);
3029  }
3030 
3031  if (flags & ATTSTATSSLOT_NUMBERS)
3032  {
3033  val = SysCacheGetAttr(STATRELATTINH, statstuple,
3034  Anum_pg_statistic_stanumbers1 + i,
3035  &isnull);
3036  if (isnull)
3037  elog(ERROR, "stanumbers is null");
3038 
3039  /*
3040  * Detoast the array if needed, and in any case make a copy that's
3041  * under control of this AttStatsSlot.
3042  */
3043  statarray = DatumGetArrayTypePCopy(val);
3044 
3045  /*
3046  * We expect the array to be a 1-D float4 array; verify that. We don't
3047  * need to use deconstruct_array() since the array data is just going
3048  * to look like a C array of float4 values.
3049  */
3050  narrayelem = ARR_DIMS(statarray)[0];
3051  if (ARR_NDIM(statarray) != 1 || narrayelem <= 0 ||
3052  ARR_HASNULL(statarray) ||
3053  ARR_ELEMTYPE(statarray) != FLOAT4OID)
3054  elog(ERROR, "stanumbers is not a 1-D float4 array");
3055 
3056  /* Give caller a pointer directly into the statarray */
3057  sslot->numbers = (float4 *) ARR_DATA_PTR(statarray);
3058  sslot->nnumbers = narrayelem;
3059 
3060  /* We'll free the statarray in free_attstatsslot */
3061  sslot->numbers_arr = statarray;
3062  }
3063 
3064  return true;
3065 }
3066 
3067 /*
3068  * free_attstatsslot
3069  * Free data allocated by get_attstatsslot
3070  */
3071 void
3073 {
3074  /* The values[] array was separately palloc'd by deconstruct_array */
3075  if (sslot->values)
3076  pfree(sslot->values);
3077  /* The numbers[] array points into numbers_arr, do not pfree it */
3078  /* Free the detoasted array objects, if any */
3079  if (sslot->values_arr)
3080  pfree(sslot->values_arr);
3081  if (sslot->numbers_arr)
3082  pfree(sslot->numbers_arr);
3083 }
3084 
3085 /* ---------- PG_NAMESPACE CACHE ---------- */
3086 
3087 /*
3088  * get_namespace_name
3089  * Returns the name of a given namespace
3090  *
3091  * Returns a palloc'd copy of the string, or NULL if no such namespace.
3092  */
3093 char *
3095 {
3096  HeapTuple tp;
3097 
3099  if (HeapTupleIsValid(tp))
3100  {
3102  char *result;
3103 
3104  result = pstrdup(NameStr(nsptup->nspname));
3105  ReleaseSysCache(tp);
3106  return result;
3107  }
3108  else
3109  return NULL;
3110 }
3111 
3112 /*
3113  * get_namespace_name_or_temp
3114  * As above, but if it is this backend's temporary namespace, return
3115  * "pg_temp" instead.
3116  */
3117 char *
3119 {
3120  if (isTempNamespace(nspid))
3121  return "pg_temp";
3122  else
3123  return get_namespace_name(nspid);
3124 }
3125 
3126 /* ---------- PG_RANGE CACHE ---------- */
3127 
3128 /*
3129  * get_range_subtype
3130  * Returns the subtype of a given range type
3131  *
3132  * Returns InvalidOid if the type is not a range type.
3133  */
3134 Oid
3136 {
3137  HeapTuple tp;
3138 
3139  tp = SearchSysCache1(RANGETYPE, ObjectIdGetDatum(rangeOid));
3140  if (HeapTupleIsValid(tp))
3141  {
3142  Form_pg_range rngtup = (Form_pg_range) GETSTRUCT(tp);
3143  Oid result;
3144 
3145  result = rngtup->rngsubtype;
3146  ReleaseSysCache(tp);
3147  return result;
3148  }
3149  else
3150  return InvalidOid;
3151 }
3152 
3153 /* ---------- PG_INDEX CACHE ---------- */
3154 
3155 /*
3156  * get_index_column_opclass
3157  *
3158  * Given the index OID and column number,
3159  * return opclass of the index column
3160  * or InvalidOid if the index was not found
3161  * or column is non-key one.
3162  */
3163 Oid
3164 get_index_column_opclass(Oid index_oid, int attno)
3165 {
3166  HeapTuple tuple;
3168  Datum datum;
3169  bool isnull;
3170  oidvector *indclass;
3171  Oid opclass;
3172 
3173  /* First we need to know the column's opclass. */
3174 
3175  tuple = SearchSysCache1(INDEXRELID, ObjectIdGetDatum(index_oid));
3176  if (!HeapTupleIsValid(tuple))
3177  return InvalidOid;
3178 
3179  rd_index = (Form_pg_index) GETSTRUCT(tuple);
3180 
3181  /* caller is supposed to guarantee this */
3182  Assert(attno > 0 && attno <= rd_index->indnatts);
3183 
3184  /* Non-key attributes don't have an opclass */
3185  if (attno > rd_index->indnkeyatts)
3186  {
3187  ReleaseSysCache(tuple);
3188  return InvalidOid;
3189  }
3190 
3191  datum = SysCacheGetAttr(INDEXRELID, tuple,
3192  Anum_pg_index_indclass, &isnull);
3193  Assert(!isnull);
3194 
3195  indclass = ((oidvector *) DatumGetPointer(datum));
3196 
3197  Assert(attno <= indclass->dim1);
3198  opclass = indclass->values[attno - 1];
3199 
3200  ReleaseSysCache(tuple);
3201 
3202  return opclass;
3203 }
signed short int16
Definition: c.h:345
#define NIL
Definition: pg_list.h:65
Definition: c.h:588
bool op_in_opfamily(Oid opno, Oid opfamily)
Definition: lsyscache.c:63
get_attavgwidth_hook_type get_attavgwidth_hook
Definition: lsyscache.c:50
Oid get_transform_fromsql(Oid typid, Oid langid, List *trftypes)
Definition: lsyscache.c:1900
char get_typstorage(Oid typid)
Definition: lsyscache.c:2197
bool get_func_leakproof(Oid funcid)
Definition: lsyscache.c:1639
RegProcedure get_oprjoin(Oid opno)
Definition: lsyscache.c:1383
Oid getBaseTypeAndTypmod(Oid typid, int32 *typmod)
Definition: lsyscache.c:2316
bool get_compatible_hash_operators(Oid opno, Oid *lhs_opno, Oid *rhs_opno)
Definition: lsyscache.c:407
bool op_strict(Oid opno)
Definition: lsyscache.c:1279
FormData_pg_range * Form_pg_range
Definition: pg_range.h:55
int n_members
Definition: catcache.h:176
bool get_op_hash_functions(Oid opno, RegProcedure *lhs_procno, RegProcedure *rhs_procno)
Definition: lsyscache.c:507
Oid get_commutator(Oid opno)
Definition: lsyscache.c:1311
#define BTGreaterStrategyNumber
Definition: stratnum.h:33
void getTypeOutputInfo(Oid type, Oid *typOutput, bool *typIsVarlena)
Definition: lsyscache.c:2674
#define GETSTRUCT(TUP)
Definition: htup_details.h:655
FormData_pg_namespace * Form_pg_namespace
Definition: pg_namespace.h:51
Oid get_op_opfamily_sortfamily(Oid opno, Oid opfamily)
Definition: lsyscache.c:105
char * get_language_name(Oid langoid, bool missing_ok)
Definition: lsyscache.c:990
#define ATTSTATSSLOT_VALUES
Definition: lsyscache.h:39
Oid get_func_namespace(Oid funcid)
Definition: lsyscache.c:1434
char * get_constraint_name(Oid conoid)
Definition: lsyscache.c:969
Oid get_element_type(Oid typid)
Definition: lsyscache.c:2526
int nnumbers
Definition: lsyscache.h:54
void get_typlenbyvalalign(Oid typid, int16 *typlen, bool *typbyval, char *typalign)
Definition: lsyscache.c:2049
#define PointerGetDatum(X)
Definition: postgres.h:556
FormData_pg_amproc * Form_pg_amproc
Definition: pg_amproc.h:68
Oid get_array_type(Oid typid)
Definition: lsyscache.c:2554
char get_rel_relkind(Oid relid)
Definition: lsyscache.c:1805
char * get_collation_name(Oid colloid)
Definition: lsyscache.c:923
char * pstrdup(const char *in)
Definition: mcxt.c:1186
Oid get_equality_op_for_ordering_op(Oid opno, bool *reverse)
Definition: lsyscache.c:264
List * get_mergejoin_opfamilies(Oid opno)
Definition: lsyscache.c:363
regproc RegProcedure
Definition: c.h:505
Oid get_rel_namespace(Oid relid)
Definition: lsyscache.c:1754
#define Int16GetDatum(X)
Definition: postgres.h:451
Oid get_func_signature(Oid funcid, Oid **argtypes, int *nargs)
Definition: lsyscache.c:1498
Definition: nodes.h:525
bool get_typisdefined(Oid typid)
Definition: lsyscache.c:1951
bool get_collation_isdeterministic(Oid colloid)
Definition: lsyscache.c:942
uint16 StrategyNumber
Definition: stratnum.h:22
int errcode(int sqlerrcode)
Definition: elog.c:570
void * stringToNode(const char *str)
Definition: read.c:89
char get_typtype(Oid typid)
Definition: lsyscache.c:2407
char * format_type_be(Oid type_oid)
Definition: format_type.c:326
bool type_is_range(Oid typid)
Definition: lsyscache.c:2466
IOFuncSelector
Definition: lsyscache.h:30
int16 pronargs
Definition: pg_proc.h:82
bool op_mergejoinable(Oid opno, Oid inputtype)
Definition: lsyscache.c:1193
NameData relname
Definition: pg_class.h:35
unsigned int Oid
Definition: postgres_ext.h:31
Const * makeConst(Oid consttype, int32 consttypmod, Oid constcollid, int constlen, Datum constvalue, bool constisnull, bool constbyval)
Definition: makefuncs.c:297
FormData_pg_statistic * Form_pg_statistic
Definition: pg_statistic.h:134
List * lappend_oid(List *list, Oid datum)
Definition: list.c:358
#define OidIsValid(objectId)
Definition: c.h:638
Oid get_op_rettype(Oid opno)
Definition: lsyscache.c:1140
Oid get_func_rettype(Oid funcid)
Definition: lsyscache.c:1457
signed int int32
Definition: c.h:346
Oid get_rel_tablespace(Oid relid)
Definition: lsyscache.c:1856
CatCTup * members[FLEXIBLE_ARRAY_MEMBER]
Definition: catcache.h:178
bool get_typbyval(Oid typid)
Definition: lsyscache.c:2000
char * get_opname(Oid opno)
Definition: lsyscache.c:1117
bool get_opclass_opfamily_and_input_type(Oid opclass, Oid *opfamily, Oid *opcintype)
Definition: lsyscache.c:1064
Oid get_typ_typrelid(Oid typid)
Definition: lsyscache.c:2499
void pfree(void *pointer)
Definition: mcxt.c:1056
char typalign
Definition: pg_type.h:170
bool op_hashjoinable(Oid opno, Oid inputtype)
Definition: lsyscache.c:1244
FormData_pg_transform * Form_pg_transform
Definition: pg_transform.h:43
#define ATTSTATSSLOT_NUMBERS
Definition: lsyscache.h:40
void * values_arr
Definition: lsyscache.h:57
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
#define ERROR
Definition: elog.h:43
NameData attname
Definition: pg_attribute.h:40
#define SearchSysCacheExists3(cacheId, key1, key2, key3)
Definition: syscache.h:187
char * get_func_name(Oid funcid)
Definition: lsyscache.c:1410
#define ARR_DIMS(a)
Definition: array.h:282
HeapTuple SearchSysCache3(int cacheId, Datum key1, Datum key2, Datum key3)
Definition: syscache.c:1146
#define HTEqualStrategyNumber
Definition: stratnum.h:41
int32 type_maximum_size(Oid type_oid, int32 typemod)
Definition: format_type.c:395
Oid get_relname_relid(const char *relname, Oid relnamespace)
Definition: lsyscache.c:1687
#define ARR_DATA_PTR(a)
Definition: array.h:310
char * get_namespace_name(Oid nspid)
Definition: lsyscache.c:3094
Oid get_func_variadictype(Oid funcid)
Definition: lsyscache.c:1525
AttrNumber get_attnum(Oid relid, const char *attname)
Definition: lsyscache.c:806
float4 * numbers
Definition: lsyscache.h:53
Oid values[FLEXIBLE_ARRAY_MEMBER]
Definition: c.h:596
Oid get_opfamily_member(Oid opfamily, Oid lefttype, Oid righttype, int16 strategy)
Definition: lsyscache.c:163
FormData_pg_attribute * Form_pg_attribute
Definition: pg_attribute.h:200
bool isTempNamespace(Oid namespaceId)
Definition: namespace.c:3149
#define ARR_HASNULL(a)
Definition: array.h:279
#define SearchSysCacheList1(cacheId, key1)
Definition: syscache.h:210
void op_input_types(Oid opno, Oid *lefttype, Oid *righttype)
Definition: lsyscache.c:1165
Oid get_ordering_op_for_equality_op(Oid opno, bool use_lhs_type)
Definition: lsyscache.c:302
bool type_is_rowtype(Oid typid)
Definition: lsyscache.c:2433
HeapTuple SearchSysCache4(int cacheId, Datum key1, Datum key2, Datum key3, Datum key4)
Definition: syscache.c:1157
Oid get_atttype(Oid relid, AttrNumber attnum)
Definition: lsyscache.c:861
Oid get_typmodin(Oid typid)
Definition: lsyscache.c:2773
#define HASHSTANDARD_PROC
Definition: hash.h:337
void getTypeBinaryInputInfo(Oid type, Oid *typReceive, Oid *typIOParam)
Definition: lsyscache.c:2707
#define ereport(elevel, rest)
Definition: elog.h:141
void getTypeInputInfo(Oid type, Oid *typInput, Oid *typIOParam)
Definition: lsyscache.c:2641
bool get_rel_relispartition(Oid relid)
Definition: lsyscache.c:1829
List * lappend(List *list, void *datum)
Definition: list.c:322
char get_attgenerated(Oid relid, AttrNumber attnum)
Definition: lsyscache.c:836
FormData_pg_index * Form_pg_index
Definition: pg_index.h:66
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:1124
float float4
Definition: c.h:490
bool get_func_retset(Oid funcid)
Definition: lsyscache.c:1544
Oid get_promoted_array_type(Oid typid)
Definition: lsyscache.c:2578
#define ReleaseSysCacheList(x)
Definition: syscache.h:217
RegProcedure get_oprrest(Oid opno)
Definition: lsyscache.c:1359
#define TextDatumGetCString(d)
Definition: builtins.h:84
char get_func_prokind(Oid funcid)
Definition: lsyscache.c:1620
void getTypeBinaryOutputInfo(Oid type, Oid *typSend, bool *typIsVarlena)
Definition: lsyscache.c:2740
char op_volatile(Oid opno)
Definition: lsyscache.c:1295
List * get_op_btree_interpretation(Oid opno)
Definition: lsyscache.c:598
uintptr_t Datum
Definition: postgres.h:367
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1172
int32(* get_attavgwidth_hook_type)(Oid relid, AttrNumber attnum)
Definition: lsyscache.h:62
Datum SysCacheGetAttr(int cacheId, HeapTuple tup, AttrNumber attributeNumber, bool *isNull)
Definition: syscache.c:1385
#define DatumGetArrayTypePCopy(X)
Definition: array.h:250
Oid get_rel_type_id(Oid relid)
Definition: lsyscache.c:1781
FormData_pg_proc * Form_pg_proc
Definition: pg_proc.h:134
#define BoolGetDatum(X)
Definition: postgres.h:402
int32 get_typavgwidth(Oid typid, int32 typmod)
Definition: lsyscache.c:2356
TypeCacheEntry * lookup_type_cache(Oid type_id, int flags)
Definition: typcache.c:322
#define InvalidOid
Definition: postgres_ext.h:36
RegProcedure get_opcode(Oid opno)
Definition: lsyscache.c:1092
int16 attnum
Definition: pg_attribute.h:79
#define STATISTIC_NUM_SLOTS
Definition: pg_statistic.h:126
Oid get_typcollation(Oid typid)
Definition: lsyscache.c:2823
#define TYPECACHE_CMP_PROC
Definition: typcache.h:131
RegProcedure get_func_support(Oid funcid)
Definition: lsyscache.c:1660
FormData_pg_constraint * Form_pg_constraint
bool list_member_oid(const List *list, Oid datum)
Definition: list.c:675
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
bool get_attstatsslot(AttStatsSlot *sslot, HeapTuple statstuple, int reqkind, Oid reqop, int flags)
Definition: lsyscache.c:2942
#define Assert(condition)
Definition: c.h:732
Datum * values
Definition: lsyscache.h:50
Node * get_typdefault(Oid typid)
Definition: lsyscache.c:2226
bool equality_ops_are_compatible(Oid opno1, Oid opno2)
Definition: lsyscache.c:695
Oid get_opfamily_proc(Oid opfamily, Oid lefttype, Oid righttype, int16 procnum)
Definition: lsyscache.c:744
#define GetSysCacheOid2(cacheId, oidcol, key1, key2)
Definition: syscache.h:194
char func_parallel(Oid funcid)
Definition: lsyscache.c:1601
bool get_ordering_op_properties(Oid opno, Oid *opfamily, Oid *opcintype, int16 *strategy)
Definition: lsyscache.c:204
bool type_is_enum(Oid typid)
Definition: lsyscache.c:2456
void get_atttypetypmodcoll(Oid relid, AttrNumber attnum, Oid *typid, int32 *typmod, Oid *collid)
Definition: lsyscache.c:891
FormData_pg_type * Form_pg_type
Definition: pg_type.h:251
void get_typlenbyval(Oid typid, int16 *typlen, bool *typbyval)
Definition: lsyscache.c:2029
HeapTuple SearchSysCache2(int cacheId, Datum key1, Datum key2)
Definition: syscache.c:1135
HeapTuple SearchSysCacheAttName(Oid relid, const char *attname)
Definition: syscache.c:1265
#define ARR_NDIM(a)
Definition: array.h:278
Oid get_opclass_family(Oid opclass)
Definition: lsyscache.c:1019
FormData_pg_operator * Form_pg_operator
Definition: pg_operator.h:84
bool func_strict(Oid funcid)
Definition: lsyscache.c:1563
#define InvalidAttrNumber
Definition: attnum.h:23
FormData_pg_collation * Form_pg_collation
Definition: pg_collation.h:51
#define CharGetDatum(X)
Definition: postgres.h:416
Oid get_transform_tosql(Oid typid, Oid langid, List *trftypes)
Definition: lsyscache.c:1921
#define DatumGetPointer(X)
Definition: postgres.h:549
char get_rel_persistence(Oid relid)
Definition: lsyscache.c:1880
int get_func_nargs(Oid funcid)
Definition: lsyscache.c:1476
void deconstruct_array(ArrayType *array, Oid elmtype, int elmlen, bool elmbyval, char elmalign, Datum **elemsp, bool **nullsp, int *nelemsp)
Definition: arrayfuncs.c:3461
#define IsBootstrapProcessingMode()
Definition: miscadmin.h:374
int get_op_opfamily_strategy(Oid opno, Oid opfamily)
Definition: lsyscache.c:80
FormData_pg_class * Form_pg_class
Definition: pg_class.h:150
Oid get_base_element_type(Oid typid)
Definition: lsyscache.c:2599
char func_volatile(Oid funcid)
Definition: lsyscache.c:1582
Oid get_index_column_opclass(Oid index_oid, int attno)
Definition: lsyscache.c:3164
void get_op_opfamily_properties(Oid opno, Oid opfamily, bool ordering_op, int *strategy, Oid *lefttype, Oid *righttype)
Definition: lsyscache.c:133
int16 get_typlen(Oid typid)
Definition: lsyscache.c:1975
FormData_pg_language * Form_pg_language
Definition: pg_language.h:65
void * palloc(Size size)
Definition: mcxt.c:949
int errmsg(const char *fmt,...)
Definition: elog.c:784
char * get_namespace_name_or_temp(Oid nspid)
Definition: lsyscache.c:3118
FormData_pg_amop * Form_pg_amop
Definition: pg_amop.h:88
#define elog(elevel,...)
Definition: elog.h:226
int i
Oid getTypeIOParam(HeapTuple typeTuple)
Definition: lsyscache.c:2081
#define NameStr(name)
Definition: c.h:609
char * get_attname(Oid relid, AttrNumber attnum, bool missing_ok)
Definition: lsyscache.c:775
HeapTupleData tuple
Definition: catcache.h:121
void * numbers_arr
Definition: lsyscache.h:58
Oid get_negator(Oid opno)
Definition: lsyscache.c:1335
int32 get_attavgwidth(Oid relid, AttrNumber attnum)
Definition: lsyscache.c:2870
#define PG_USED_FOR_ASSERTS_ONLY
Definition: c.h:123
#define BTLessStrategyNumber
Definition: stratnum.h:29
Oid valuetype
Definition: lsyscache.h:49
Oid getBaseType(Oid typid)
Definition: lsyscache.c:2299
bool type_is_collatable(Oid typid)
Definition: lsyscache.c:2848
void get_type_category_preferred(Oid typid, char *typcategory, bool *typispreferred)
Definition: lsyscache.c:2478
FormData_pg_opclass * Form_pg_opclass
Definition: pg_opclass.h:83
Definition: pg_list.h:50
char * get_rel_name(Oid relid)
Definition: lsyscache.c:1730
Datum OidInputFunctionCall(Oid functionId, char *str, Oid typioparam, int32 typmod)
Definition: fmgr.c:1646
#define ARR_ELEMTYPE(a)
Definition: array.h:280
int16 AttrNumber
Definition: attnum.h:21
Oid get_range_subtype(Oid rangeOid)
Definition: lsyscache.c:3135
long val
Definition: informix.c:684
#define TYPECACHE_HASH_PROC
Definition: typcache.h:132
#define BTEqualStrategyNumber
Definition: stratnum.h:31
void boot_get_type_io_data(Oid typid, int16 *typlen, bool *typbyval, char *typalign, char *typdelim, Oid *typioparam, Oid *typinput, Oid *typoutput)
Definition: bootstrap.c:985
Oid get_opclass_input_type(Oid opclass)
Definition: lsyscache.c:1041
void get_type_io_data(Oid typid, IOFuncSelector which_func, int16 *typlen, bool *typbyval, char *typalign, char *typdelim, Oid *typioparam, Oid *func)
Definition: lsyscache.c:2103
void free_attstatsslot(AttStatsSlot *sslot)
Definition: lsyscache.c:3072