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-2018, 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_attidentity
826  *
827  * Given the relation id and the attribute name,
828  * return the "attidentity" field from the attribute relation.
829  *
830  * Returns '\0' if not found.
831  *
832  * Since no identity is represented by '\0', this can also be used as a
833  * Boolean test.
834  */
835 char
837 {
838  HeapTuple tp;
839 
840  tp = SearchSysCache2(ATTNUM,
841  ObjectIdGetDatum(relid),
842  Int16GetDatum(attnum));
843  if (HeapTupleIsValid(tp))
844  {
846  char result;
847 
848  result = att_tup->attidentity;
849  ReleaseSysCache(tp);
850  return result;
851  }
852  else
853  return '\0';
854 }
855 
856 /*
857  * get_atttype
858  *
859  * Given the relation OID and the attribute number with the relation,
860  * return the attribute type OID.
861  */
862 Oid
864 {
865  HeapTuple tp;
866 
867  tp = SearchSysCache2(ATTNUM,
868  ObjectIdGetDatum(relid),
869  Int16GetDatum(attnum));
870  if (HeapTupleIsValid(tp))
871  {
873  Oid result;
874 
875  result = att_tup->atttypid;
876  ReleaseSysCache(tp);
877  return result;
878  }
879  else
880  return InvalidOid;
881 }
882 
883 /*
884  * get_atttypmod
885  *
886  * Given the relation id and the attribute number,
887  * return the "atttypmod" field from the attribute relation.
888  */
889 int32
891 {
892  HeapTuple tp;
893 
894  tp = SearchSysCache2(ATTNUM,
895  ObjectIdGetDatum(relid),
896  Int16GetDatum(attnum));
897  if (HeapTupleIsValid(tp))
898  {
900  int32 result;
901 
902  result = att_tup->atttypmod;
903  ReleaseSysCache(tp);
904  return result;
905  }
906  else
907  return -1;
908 }
909 
910 /*
911  * get_atttypetypmodcoll
912  *
913  * A three-fer: given the relation id and the attribute number,
914  * fetch atttypid, atttypmod, and attcollation in a single cache lookup.
915  *
916  * Unlike the otherwise-similar get_atttype/get_atttypmod, this routine
917  * raises an error if it can't obtain the information.
918  */
919 void
921  Oid *typid, int32 *typmod, Oid *collid)
922 {
923  HeapTuple tp;
924  Form_pg_attribute att_tup;
925 
926  tp = SearchSysCache2(ATTNUM,
927  ObjectIdGetDatum(relid),
928  Int16GetDatum(attnum));
929  if (!HeapTupleIsValid(tp))
930  elog(ERROR, "cache lookup failed for attribute %d of relation %u",
931  attnum, relid);
932  att_tup = (Form_pg_attribute) GETSTRUCT(tp);
933 
934  *typid = att_tup->atttypid;
935  *typmod = att_tup->atttypmod;
936  *collid = att_tup->attcollation;
937  ReleaseSysCache(tp);
938 }
939 
940 /* ---------- COLLATION CACHE ---------- */
941 
942 /*
943  * get_collation_name
944  * Returns the name of a given pg_collation entry.
945  *
946  * Returns a palloc'd copy of the string, or NULL if no such collation.
947  *
948  * NOTE: since collation name is not unique, be wary of code that uses this
949  * for anything except preparing error messages.
950  */
951 char *
953 {
954  HeapTuple tp;
955 
956  tp = SearchSysCache1(COLLOID, ObjectIdGetDatum(colloid));
957  if (HeapTupleIsValid(tp))
958  {
960  char *result;
961 
962  result = pstrdup(NameStr(colltup->collname));
963  ReleaseSysCache(tp);
964  return result;
965  }
966  else
967  return NULL;
968 }
969 
970 /* ---------- CONSTRAINT CACHE ---------- */
971 
972 /*
973  * get_constraint_name
974  * Returns the name of a given pg_constraint entry.
975  *
976  * Returns a palloc'd copy of the string, or NULL if no such constraint.
977  *
978  * NOTE: since constraint name is not unique, be wary of code that uses this
979  * for anything except preparing error messages.
980  */
981 char *
983 {
984  HeapTuple tp;
985 
987  if (HeapTupleIsValid(tp))
988  {
990  char *result;
991 
992  result = pstrdup(NameStr(contup->conname));
993  ReleaseSysCache(tp);
994  return result;
995  }
996  else
997  return NULL;
998 }
999 
1000 /* ---------- LANGUAGE CACHE ---------- */
1001 
1002 char *
1003 get_language_name(Oid langoid, bool missing_ok)
1004 {
1005  HeapTuple tp;
1006 
1007  tp = SearchSysCache1(LANGOID, ObjectIdGetDatum(langoid));
1008  if (HeapTupleIsValid(tp))
1009  {
1011  char *result;
1012 
1013  result = pstrdup(NameStr(lantup->lanname));
1014  ReleaseSysCache(tp);
1015  return result;
1016  }
1017 
1018  if (!missing_ok)
1019  elog(ERROR, "cache lookup failed for language %u",
1020  langoid);
1021  return NULL;
1022 }
1023 
1024 /* ---------- OPCLASS CACHE ---------- */
1025 
1026 /*
1027  * get_opclass_family
1028  *
1029  * Returns the OID of the operator family the opclass belongs to.
1030  */
1031 Oid
1033 {
1034  HeapTuple tp;
1035  Form_pg_opclass cla_tup;
1036  Oid result;
1037 
1038  tp = SearchSysCache1(CLAOID, ObjectIdGetDatum(opclass));
1039  if (!HeapTupleIsValid(tp))
1040  elog(ERROR, "cache lookup failed for opclass %u", opclass);
1041  cla_tup = (Form_pg_opclass) GETSTRUCT(tp);
1042 
1043  result = cla_tup->opcfamily;
1044  ReleaseSysCache(tp);
1045  return result;
1046 }
1047 
1048 /*
1049  * get_opclass_input_type
1050  *
1051  * Returns the OID of the datatype the opclass indexes.
1052  */
1053 Oid
1055 {
1056  HeapTuple tp;
1057  Form_pg_opclass cla_tup;
1058  Oid result;
1059 
1060  tp = SearchSysCache1(CLAOID, ObjectIdGetDatum(opclass));
1061  if (!HeapTupleIsValid(tp))
1062  elog(ERROR, "cache lookup failed for opclass %u", opclass);
1063  cla_tup = (Form_pg_opclass) GETSTRUCT(tp);
1064 
1065  result = cla_tup->opcintype;
1066  ReleaseSysCache(tp);
1067  return result;
1068 }
1069 
1070 /* ---------- OPERATOR CACHE ---------- */
1071 
1072 /*
1073  * get_opcode
1074  *
1075  * Returns the regproc id of the routine used to implement an
1076  * operator given the operator oid.
1077  */
1080 {
1081  HeapTuple tp;
1082 
1084  if (HeapTupleIsValid(tp))
1085  {
1087  RegProcedure result;
1088 
1089  result = optup->oprcode;
1090  ReleaseSysCache(tp);
1091  return result;
1092  }
1093  else
1094  return (RegProcedure) InvalidOid;
1095 }
1096 
1097 /*
1098  * get_opname
1099  * returns the name of the operator with the given opno
1100  *
1101  * Note: returns a palloc'd copy of the string, or NULL if no such operator.
1102  */
1103 char *
1105 {
1106  HeapTuple tp;
1107 
1109  if (HeapTupleIsValid(tp))
1110  {
1112  char *result;
1113 
1114  result = pstrdup(NameStr(optup->oprname));
1115  ReleaseSysCache(tp);
1116  return result;
1117  }
1118  else
1119  return NULL;
1120 }
1121 
1122 /*
1123  * get_op_rettype
1124  * Given operator oid, return the operator's result type.
1125  */
1126 Oid
1128 {
1129  HeapTuple tp;
1130 
1132  if (HeapTupleIsValid(tp))
1133  {
1135  Oid result;
1136 
1137  result = optup->oprresult;
1138  ReleaseSysCache(tp);
1139  return result;
1140  }
1141  else
1142  return InvalidOid;
1143 }
1144 
1145 /*
1146  * op_input_types
1147  *
1148  * Returns the left and right input datatypes for an operator
1149  * (InvalidOid if not relevant).
1150  */
1151 void
1152 op_input_types(Oid opno, Oid *lefttype, Oid *righttype)
1153 {
1154  HeapTuple tp;
1155  Form_pg_operator optup;
1156 
1158  if (!HeapTupleIsValid(tp)) /* shouldn't happen */
1159  elog(ERROR, "cache lookup failed for operator %u", opno);
1160  optup = (Form_pg_operator) GETSTRUCT(tp);
1161  *lefttype = optup->oprleft;
1162  *righttype = optup->oprright;
1163  ReleaseSysCache(tp);
1164 }
1165 
1166 /*
1167  * op_mergejoinable
1168  *
1169  * Returns true if the operator is potentially mergejoinable. (The planner
1170  * will fail to find any mergejoin plans unless there are suitable btree
1171  * opfamily entries for this operator and associated sortops. The pg_operator
1172  * flag is just a hint to tell the planner whether to bother looking.)
1173  *
1174  * In some cases (currently only array_eq and record_eq), mergejoinability
1175  * depends on the specific input data type the operator is invoked for, so
1176  * that must be passed as well. We currently assume that only one input's type
1177  * is needed to check this --- by convention, pass the left input's data type.
1178  */
1179 bool
1180 op_mergejoinable(Oid opno, Oid inputtype)
1181 {
1182  bool result = false;
1183  HeapTuple tp;
1184  TypeCacheEntry *typentry;
1185 
1186  /*
1187  * For array_eq or record_eq, we can sort if the element or field types
1188  * are all sortable. We could implement all the checks for that here, but
1189  * the typcache already does that and caches the results too, so let's
1190  * rely on the typcache.
1191  */
1192  if (opno == ARRAY_EQ_OP)
1193  {
1194  typentry = lookup_type_cache(inputtype, TYPECACHE_CMP_PROC);
1195  if (typentry->cmp_proc == F_BTARRAYCMP)
1196  result = true;
1197  }
1198  else if (opno == RECORD_EQ_OP)
1199  {
1200  typentry = lookup_type_cache(inputtype, TYPECACHE_CMP_PROC);
1201  if (typentry->cmp_proc == F_BTRECORDCMP)
1202  result = true;
1203  }
1204  else
1205  {
1206  /* For all other operators, rely on pg_operator.oprcanmerge */
1208  if (HeapTupleIsValid(tp))
1209  {
1211 
1212  result = optup->oprcanmerge;
1213  ReleaseSysCache(tp);
1214  }
1215  }
1216  return result;
1217 }
1218 
1219 /*
1220  * op_hashjoinable
1221  *
1222  * Returns true if the operator is hashjoinable. (There must be a suitable
1223  * hash opfamily entry for this operator if it is so marked.)
1224  *
1225  * In some cases (currently only array_eq), hashjoinability depends on the
1226  * specific input data type the operator is invoked for, so that must be
1227  * passed as well. We currently assume that only one input's type is needed
1228  * to check this --- by convention, pass the left input's data type.
1229  */
1230 bool
1231 op_hashjoinable(Oid opno, Oid inputtype)
1232 {
1233  bool result = false;
1234  HeapTuple tp;
1235  TypeCacheEntry *typentry;
1236 
1237  /* As in op_mergejoinable, let the typcache handle the hard cases */
1238  /* Eventually we'll need a similar case for record_eq ... */
1239  if (opno == ARRAY_EQ_OP)
1240  {
1241  typentry = lookup_type_cache(inputtype, TYPECACHE_HASH_PROC);
1242  if (typentry->hash_proc == F_HASH_ARRAY)
1243  result = true;
1244  }
1245  else
1246  {
1247  /* For all other operators, rely on pg_operator.oprcanhash */
1249  if (HeapTupleIsValid(tp))
1250  {
1252 
1253  result = optup->oprcanhash;
1254  ReleaseSysCache(tp);
1255  }
1256  }
1257  return result;
1258 }
1259 
1260 /*
1261  * op_strict
1262  *
1263  * Get the proisstrict flag for the operator's underlying function.
1264  */
1265 bool
1267 {
1268  RegProcedure funcid = get_opcode(opno);
1269 
1270  if (funcid == (RegProcedure) InvalidOid)
1271  elog(ERROR, "operator %u does not exist", opno);
1272 
1273  return func_strict((Oid) funcid);
1274 }
1275 
1276 /*
1277  * op_volatile
1278  *
1279  * Get the provolatile flag for the operator's underlying function.
1280  */
1281 char
1283 {
1284  RegProcedure funcid = get_opcode(opno);
1285 
1286  if (funcid == (RegProcedure) InvalidOid)
1287  elog(ERROR, "operator %u does not exist", opno);
1288 
1289  return func_volatile((Oid) funcid);
1290 }
1291 
1292 /*
1293  * get_commutator
1294  *
1295  * Returns the corresponding commutator of an operator.
1296  */
1297 Oid
1299 {
1300  HeapTuple tp;
1301 
1303  if (HeapTupleIsValid(tp))
1304  {
1306  Oid result;
1307 
1308  result = optup->oprcom;
1309  ReleaseSysCache(tp);
1310  return result;
1311  }
1312  else
1313  return InvalidOid;
1314 }
1315 
1316 /*
1317  * get_negator
1318  *
1319  * Returns the corresponding negator of an operator.
1320  */
1321 Oid
1323 {
1324  HeapTuple tp;
1325 
1327  if (HeapTupleIsValid(tp))
1328  {
1330  Oid result;
1331 
1332  result = optup->oprnegate;
1333  ReleaseSysCache(tp);
1334  return result;
1335  }
1336  else
1337  return InvalidOid;
1338 }
1339 
1340 /*
1341  * get_oprrest
1342  *
1343  * Returns procedure id for computing selectivity of an operator.
1344  */
1347 {
1348  HeapTuple tp;
1349 
1351  if (HeapTupleIsValid(tp))
1352  {
1354  RegProcedure result;
1355 
1356  result = optup->oprrest;
1357  ReleaseSysCache(tp);
1358  return result;
1359  }
1360  else
1361  return (RegProcedure) InvalidOid;
1362 }
1363 
1364 /*
1365  * get_oprjoin
1366  *
1367  * Returns procedure id for computing selectivity of a join.
1368  */
1371 {
1372  HeapTuple tp;
1373 
1375  if (HeapTupleIsValid(tp))
1376  {
1378  RegProcedure result;
1379 
1380  result = optup->oprjoin;
1381  ReleaseSysCache(tp);
1382  return result;
1383  }
1384  else
1385  return (RegProcedure) InvalidOid;
1386 }
1387 
1388 /* ---------- FUNCTION CACHE ---------- */
1389 
1390 /*
1391  * get_func_name
1392  * returns the name of the function with the given funcid
1393  *
1394  * Note: returns a palloc'd copy of the string, or NULL if no such function.
1395  */
1396 char *
1398 {
1399  HeapTuple tp;
1400 
1401  tp = SearchSysCache1(PROCOID, ObjectIdGetDatum(funcid));
1402  if (HeapTupleIsValid(tp))
1403  {
1404  Form_pg_proc functup = (Form_pg_proc) GETSTRUCT(tp);
1405  char *result;
1406 
1407  result = pstrdup(NameStr(functup->proname));
1408  ReleaseSysCache(tp);
1409  return result;
1410  }
1411  else
1412  return NULL;
1413 }
1414 
1415 /*
1416  * get_func_namespace
1417  *
1418  * Returns the pg_namespace OID associated with a given function.
1419  */
1420 Oid
1422 {
1423  HeapTuple tp;
1424 
1425  tp = SearchSysCache1(PROCOID, ObjectIdGetDatum(funcid));
1426  if (HeapTupleIsValid(tp))
1427  {
1428  Form_pg_proc functup = (Form_pg_proc) GETSTRUCT(tp);
1429  Oid result;
1430 
1431  result = functup->pronamespace;
1432  ReleaseSysCache(tp);
1433  return result;
1434  }
1435  else
1436  return InvalidOid;
1437 }
1438 
1439 /*
1440  * get_func_rettype
1441  * Given procedure id, return the function's result type.
1442  */
1443 Oid
1445 {
1446  HeapTuple tp;
1447  Oid result;
1448 
1449  tp = SearchSysCache1(PROCOID, ObjectIdGetDatum(funcid));
1450  if (!HeapTupleIsValid(tp))
1451  elog(ERROR, "cache lookup failed for function %u", funcid);
1452 
1453  result = ((Form_pg_proc) GETSTRUCT(tp))->prorettype;
1454  ReleaseSysCache(tp);
1455  return result;
1456 }
1457 
1458 /*
1459  * get_func_nargs
1460  * Given procedure id, return the number of arguments.
1461  */
1462 int
1464 {
1465  HeapTuple tp;
1466  int result;
1467 
1468  tp = SearchSysCache1(PROCOID, ObjectIdGetDatum(funcid));
1469  if (!HeapTupleIsValid(tp))
1470  elog(ERROR, "cache lookup failed for function %u", funcid);
1471 
1472  result = ((Form_pg_proc) GETSTRUCT(tp))->pronargs;
1473  ReleaseSysCache(tp);
1474  return result;
1475 }
1476 
1477 /*
1478  * get_func_signature
1479  * Given procedure id, return the function's argument and result types.
1480  * (The return value is the result type.)
1481  *
1482  * The arguments are returned as a palloc'd array.
1483  */
1484 Oid
1485 get_func_signature(Oid funcid, Oid **argtypes, int *nargs)
1486 {
1487  HeapTuple tp;
1488  Form_pg_proc procstruct;
1489  Oid result;
1490 
1491  tp = SearchSysCache1(PROCOID, ObjectIdGetDatum(funcid));
1492  if (!HeapTupleIsValid(tp))
1493  elog(ERROR, "cache lookup failed for function %u", funcid);
1494 
1495  procstruct = (Form_pg_proc) GETSTRUCT(tp);
1496 
1497  result = procstruct->prorettype;
1498  *nargs = (int) procstruct->pronargs;
1499  Assert(*nargs == procstruct->proargtypes.dim1);
1500  *argtypes = (Oid *) palloc(*nargs * sizeof(Oid));
1501  memcpy(*argtypes, procstruct->proargtypes.values, *nargs * sizeof(Oid));
1502 
1503  ReleaseSysCache(tp);
1504  return result;
1505 }
1506 
1507 /*
1508  * get_func_variadictype
1509  * Given procedure id, return the function's provariadic field.
1510  */
1511 Oid
1513 {
1514  HeapTuple tp;
1515  Oid result;
1516 
1517  tp = SearchSysCache1(PROCOID, ObjectIdGetDatum(funcid));
1518  if (!HeapTupleIsValid(tp))
1519  elog(ERROR, "cache lookup failed for function %u", funcid);
1520 
1521  result = ((Form_pg_proc) GETSTRUCT(tp))->provariadic;
1522  ReleaseSysCache(tp);
1523  return result;
1524 }
1525 
1526 /*
1527  * get_func_retset
1528  * Given procedure id, return the function's proretset flag.
1529  */
1530 bool
1532 {
1533  HeapTuple tp;
1534  bool result;
1535 
1536  tp = SearchSysCache1(PROCOID, ObjectIdGetDatum(funcid));
1537  if (!HeapTupleIsValid(tp))
1538  elog(ERROR, "cache lookup failed for function %u", funcid);
1539 
1540  result = ((Form_pg_proc) GETSTRUCT(tp))->proretset;
1541  ReleaseSysCache(tp);
1542  return result;
1543 }
1544 
1545 /*
1546  * func_strict
1547  * Given procedure id, return the function's proisstrict flag.
1548  */
1549 bool
1551 {
1552  HeapTuple tp;
1553  bool result;
1554 
1555  tp = SearchSysCache1(PROCOID, ObjectIdGetDatum(funcid));
1556  if (!HeapTupleIsValid(tp))
1557  elog(ERROR, "cache lookup failed for function %u", funcid);
1558 
1559  result = ((Form_pg_proc) GETSTRUCT(tp))->proisstrict;
1560  ReleaseSysCache(tp);
1561  return result;
1562 }
1563 
1564 /*
1565  * func_volatile
1566  * Given procedure id, return the function's provolatile flag.
1567  */
1568 char
1570 {
1571  HeapTuple tp;
1572  char result;
1573 
1574  tp = SearchSysCache1(PROCOID, ObjectIdGetDatum(funcid));
1575  if (!HeapTupleIsValid(tp))
1576  elog(ERROR, "cache lookup failed for function %u", funcid);
1577 
1578  result = ((Form_pg_proc) GETSTRUCT(tp))->provolatile;
1579  ReleaseSysCache(tp);
1580  return result;
1581 }
1582 
1583 /*
1584  * func_parallel
1585  * Given procedure id, return the function's proparallel flag.
1586  */
1587 char
1589 {
1590  HeapTuple tp;
1591  char result;
1592 
1593  tp = SearchSysCache1(PROCOID, ObjectIdGetDatum(funcid));
1594  if (!HeapTupleIsValid(tp))
1595  elog(ERROR, "cache lookup failed for function %u", funcid);
1596 
1597  result = ((Form_pg_proc) GETSTRUCT(tp))->proparallel;
1598  ReleaseSysCache(tp);
1599  return result;
1600 }
1601 
1602 /*
1603  * get_func_prokind
1604  * Given procedure id, return the routine kind.
1605  */
1606 char
1608 {
1609  HeapTuple tp;
1610  char result;
1611 
1612  tp = SearchSysCache1(PROCOID, ObjectIdGetDatum(funcid));
1613  if (!HeapTupleIsValid(tp))
1614  elog(ERROR, "cache lookup failed for function %u", funcid);
1615 
1616  result = ((Form_pg_proc) GETSTRUCT(tp))->prokind;
1617  ReleaseSysCache(tp);
1618  return result;
1619 }
1620 
1621 /*
1622  * get_func_leakproof
1623  * Given procedure id, return the function's leakproof field.
1624  */
1625 bool
1627 {
1628  HeapTuple tp;
1629  bool result;
1630 
1631  tp = SearchSysCache1(PROCOID, ObjectIdGetDatum(funcid));
1632  if (!HeapTupleIsValid(tp))
1633  elog(ERROR, "cache lookup failed for function %u", funcid);
1634 
1635  result = ((Form_pg_proc) GETSTRUCT(tp))->proleakproof;
1636  ReleaseSysCache(tp);
1637  return result;
1638 }
1639 
1640 /*
1641  * get_func_cost
1642  * Given procedure id, return the function's procost field.
1643  */
1644 float4
1646 {
1647  HeapTuple tp;
1648  float4 result;
1649 
1650  tp = SearchSysCache1(PROCOID, ObjectIdGetDatum(funcid));
1651  if (!HeapTupleIsValid(tp))
1652  elog(ERROR, "cache lookup failed for function %u", funcid);
1653 
1654  result = ((Form_pg_proc) GETSTRUCT(tp))->procost;
1655  ReleaseSysCache(tp);
1656  return result;
1657 }
1658 
1659 /*
1660  * get_func_rows
1661  * Given procedure id, return the function's prorows field.
1662  */
1663 float4
1665 {
1666  HeapTuple tp;
1667  float4 result;
1668 
1669  tp = SearchSysCache1(PROCOID, ObjectIdGetDatum(funcid));
1670  if (!HeapTupleIsValid(tp))
1671  elog(ERROR, "cache lookup failed for function %u", funcid);
1672 
1673  result = ((Form_pg_proc) GETSTRUCT(tp))->prorows;
1674  ReleaseSysCache(tp);
1675  return result;
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,
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_tablespace
1825  *
1826  * Returns the pg_tablespace OID associated with a given relation.
1827  *
1828  * Note: InvalidOid might mean either that we couldn't find the relation,
1829  * or that it is in the database's default tablespace.
1830  */
1831 Oid
1833 {
1834  HeapTuple tp;
1835 
1836  tp = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
1837  if (HeapTupleIsValid(tp))
1838  {
1839  Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
1840  Oid result;
1841 
1842  result = reltup->reltablespace;
1843  ReleaseSysCache(tp);
1844  return result;
1845  }
1846  else
1847  return InvalidOid;
1848 }
1849 
1850 /*
1851  * get_rel_persistence
1852  *
1853  * Returns the relpersistence associated with a given relation.
1854  */
1855 char
1857 {
1858  HeapTuple tp;
1859  Form_pg_class reltup;
1860  char result;
1861 
1862  tp = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
1863  if (!HeapTupleIsValid(tp))
1864  elog(ERROR, "cache lookup failed for relation %u", relid);
1865  reltup = (Form_pg_class) GETSTRUCT(tp);
1866  result = reltup->relpersistence;
1867  ReleaseSysCache(tp);
1868 
1869  return result;
1870 }
1871 
1872 
1873 /* ---------- TRANSFORM CACHE ---------- */
1874 
1875 Oid
1876 get_transform_fromsql(Oid typid, Oid langid, List *trftypes)
1877 {
1878  HeapTuple tup;
1879 
1880  if (!list_member_oid(trftypes, typid))
1881  return InvalidOid;
1882 
1883  tup = SearchSysCache2(TRFTYPELANG, typid, langid);
1884  if (HeapTupleIsValid(tup))
1885  {
1886  Oid funcid;
1887 
1888  funcid = ((Form_pg_transform) GETSTRUCT(tup))->trffromsql;
1889  ReleaseSysCache(tup);
1890  return funcid;
1891  }
1892  else
1893  return InvalidOid;
1894 }
1895 
1896 Oid
1897 get_transform_tosql(Oid typid, Oid langid, List *trftypes)
1898 {
1899  HeapTuple tup;
1900 
1901  if (!list_member_oid(trftypes, typid))
1902  return InvalidOid;
1903 
1904  tup = SearchSysCache2(TRFTYPELANG, typid, langid);
1905  if (HeapTupleIsValid(tup))
1906  {
1907  Oid funcid;
1908 
1909  funcid = ((Form_pg_transform) GETSTRUCT(tup))->trftosql;
1910  ReleaseSysCache(tup);
1911  return funcid;
1912  }
1913  else
1914  return InvalidOid;
1915 }
1916 
1917 
1918 /* ---------- TYPE CACHE ---------- */
1919 
1920 /*
1921  * get_typisdefined
1922  *
1923  * Given the type OID, determine whether the type is defined
1924  * (if not, it's only a shell).
1925  */
1926 bool
1928 {
1929  HeapTuple tp;
1930 
1932  if (HeapTupleIsValid(tp))
1933  {
1934  Form_pg_type typtup = (Form_pg_type) GETSTRUCT(tp);
1935  bool result;
1936 
1937  result = typtup->typisdefined;
1938  ReleaseSysCache(tp);
1939  return result;
1940  }
1941  else
1942  return false;
1943 }
1944 
1945 /*
1946  * get_typlen
1947  *
1948  * Given the type OID, return the length of the type.
1949  */
1950 int16
1952 {
1953  HeapTuple tp;
1954 
1956  if (HeapTupleIsValid(tp))
1957  {
1958  Form_pg_type typtup = (Form_pg_type) GETSTRUCT(tp);
1959  int16 result;
1960 
1961  result = typtup->typlen;
1962  ReleaseSysCache(tp);
1963  return result;
1964  }
1965  else
1966  return 0;
1967 }
1968 
1969 /*
1970  * get_typbyval
1971  *
1972  * Given the type OID, determine whether the type is returned by value or
1973  * not. Returns true if by value, false if by reference.
1974  */
1975 bool
1977 {
1978  HeapTuple tp;
1979 
1981  if (HeapTupleIsValid(tp))
1982  {
1983  Form_pg_type typtup = (Form_pg_type) GETSTRUCT(tp);
1984  bool result;
1985 
1986  result = typtup->typbyval;
1987  ReleaseSysCache(tp);
1988  return result;
1989  }
1990  else
1991  return false;
1992 }
1993 
1994 /*
1995  * get_typlenbyval
1996  *
1997  * A two-fer: given the type OID, return both typlen and typbyval.
1998  *
1999  * Since both pieces of info are needed to know how to copy a Datum,
2000  * many places need both. Might as well get them with one cache lookup
2001  * instead of two. Also, this routine raises an error instead of
2002  * returning a bogus value when given a bad type OID.
2003  */
2004 void
2006 {
2007  HeapTuple tp;
2008  Form_pg_type typtup;
2009 
2011  if (!HeapTupleIsValid(tp))
2012  elog(ERROR, "cache lookup failed for type %u", typid);
2013  typtup = (Form_pg_type) GETSTRUCT(tp);
2014  *typlen = typtup->typlen;
2015  *typbyval = typtup->typbyval;
2016  ReleaseSysCache(tp);
2017 }
2018 
2019 /*
2020  * get_typlenbyvalalign
2021  *
2022  * A three-fer: given the type OID, return typlen, typbyval, typalign.
2023  */
2024 void
2026  char *typalign)
2027 {
2028  HeapTuple tp;
2029  Form_pg_type typtup;
2030 
2032  if (!HeapTupleIsValid(tp))
2033  elog(ERROR, "cache lookup failed for type %u", typid);
2034  typtup = (Form_pg_type) GETSTRUCT(tp);
2035  *typlen = typtup->typlen;
2036  *typbyval = typtup->typbyval;
2037  *typalign = typtup->typalign;
2038  ReleaseSysCache(tp);
2039 }
2040 
2041 /*
2042  * getTypeIOParam
2043  * Given a pg_type row, select the type OID to pass to I/O functions
2044  *
2045  * Formerly, all I/O functions were passed pg_type.typelem as their second
2046  * parameter, but we now have a more complex rule about what to pass.
2047  * This knowledge is intended to be centralized here --- direct references
2048  * to typelem elsewhere in the code are wrong, if they are associated with
2049  * I/O calls and not with actual subscripting operations! (But see
2050  * bootstrap.c's boot_get_type_io_data() if you need to change this.)
2051  *
2052  * As of PostgreSQL 8.1, output functions receive only the value itself
2053  * and not any auxiliary parameters, so the name of this routine is now
2054  * a bit of a misnomer ... it should be getTypeInputParam.
2055  */
2056 Oid
2058 {
2059  Form_pg_type typeStruct = (Form_pg_type) GETSTRUCT(typeTuple);
2060 
2061  /*
2062  * Array types get their typelem as parameter; everybody else gets their
2063  * own type OID as parameter.
2064  */
2065  if (OidIsValid(typeStruct->typelem))
2066  return typeStruct->typelem;
2067  else
2068  return HeapTupleGetOid(typeTuple);
2069 }
2070 
2071 /*
2072  * get_type_io_data
2073  *
2074  * A six-fer: given the type OID, return typlen, typbyval, typalign,
2075  * typdelim, typioparam, and IO function OID. The IO function
2076  * returned is controlled by IOFuncSelector
2077  */
2078 void
2080  IOFuncSelector which_func,
2081  int16 *typlen,
2082  bool *typbyval,
2083  char *typalign,
2084  char *typdelim,
2085  Oid *typioparam,
2086  Oid *func)
2087 {
2088  HeapTuple typeTuple;
2089  Form_pg_type typeStruct;
2090 
2091  /*
2092  * In bootstrap mode, pass it off to bootstrap.c. This hack allows us to
2093  * use array_in and array_out during bootstrap.
2094  */
2096  {
2097  Oid typinput;
2098  Oid typoutput;
2099 
2100  boot_get_type_io_data(typid,
2101  typlen,
2102  typbyval,
2103  typalign,
2104  typdelim,
2105  typioparam,
2106  &typinput,
2107  &typoutput);
2108  switch (which_func)
2109  {
2110  case IOFunc_input:
2111  *func = typinput;
2112  break;
2113  case IOFunc_output:
2114  *func = typoutput;
2115  break;
2116  default:
2117  elog(ERROR, "binary I/O not supported during bootstrap");
2118  break;
2119  }
2120  return;
2121  }
2122 
2123  typeTuple = SearchSysCache1(TYPEOID, ObjectIdGetDatum(typid));
2124  if (!HeapTupleIsValid(typeTuple))
2125  elog(ERROR, "cache lookup failed for type %u", typid);
2126  typeStruct = (Form_pg_type) GETSTRUCT(typeTuple);
2127 
2128  *typlen = typeStruct->typlen;
2129  *typbyval = typeStruct->typbyval;
2130  *typalign = typeStruct->typalign;
2131  *typdelim = typeStruct->typdelim;
2132  *typioparam = getTypeIOParam(typeTuple);
2133  switch (which_func)
2134  {
2135  case IOFunc_input:
2136  *func = typeStruct->typinput;
2137  break;
2138  case IOFunc_output:
2139  *func = typeStruct->typoutput;
2140  break;
2141  case IOFunc_receive:
2142  *func = typeStruct->typreceive;
2143  break;
2144  case IOFunc_send:
2145  *func = typeStruct->typsend;
2146  break;
2147  }
2148  ReleaseSysCache(typeTuple);
2149 }
2150 
2151 #ifdef NOT_USED
2152 char
2153 get_typalign(Oid typid)
2154 {
2155  HeapTuple tp;
2156 
2158  if (HeapTupleIsValid(tp))
2159  {
2160  Form_pg_type typtup = (Form_pg_type) GETSTRUCT(tp);
2161  char result;
2162 
2163  result = typtup->typalign;
2164  ReleaseSysCache(tp);
2165  return result;
2166  }
2167  else
2168  return 'i';
2169 }
2170 #endif
2171 
2172 char
2174 {
2175  HeapTuple tp;
2176 
2178  if (HeapTupleIsValid(tp))
2179  {
2180  Form_pg_type typtup = (Form_pg_type) GETSTRUCT(tp);
2181  char result;
2182 
2183  result = typtup->typstorage;
2184  ReleaseSysCache(tp);
2185  return result;
2186  }
2187  else
2188  return 'p';
2189 }
2190 
2191 /*
2192  * get_typdefault
2193  * Given a type OID, return the type's default value, if any.
2194  *
2195  * The result is a palloc'd expression node tree, or NULL if there
2196  * is no defined default for the datatype.
2197  *
2198  * NB: caller should be prepared to coerce result to correct datatype;
2199  * the returned expression tree might produce something of the wrong type.
2200  */
2201 Node *
2203 {
2204  HeapTuple typeTuple;
2206  Datum datum;
2207  bool isNull;
2208  Node *expr;
2209 
2210  typeTuple = SearchSysCache1(TYPEOID, ObjectIdGetDatum(typid));
2211  if (!HeapTupleIsValid(typeTuple))
2212  elog(ERROR, "cache lookup failed for type %u", typid);
2213  type = (Form_pg_type) GETSTRUCT(typeTuple);
2214 
2215  /*
2216  * typdefault and typdefaultbin are potentially null, so don't try to
2217  * access 'em as struct fields. Must do it the hard way with
2218  * SysCacheGetAttr.
2219  */
2220  datum = SysCacheGetAttr(TYPEOID,
2221  typeTuple,
2222  Anum_pg_type_typdefaultbin,
2223  &isNull);
2224 
2225  if (!isNull)
2226  {
2227  /* We have an expression default */
2228  expr = stringToNode(TextDatumGetCString(datum));
2229  }
2230  else
2231  {
2232  /* Perhaps we have a plain literal default */
2233  datum = SysCacheGetAttr(TYPEOID,
2234  typeTuple,
2235  Anum_pg_type_typdefault,
2236  &isNull);
2237 
2238  if (!isNull)
2239  {
2240  char *strDefaultVal;
2241 
2242  /* Convert text datum to C string */
2243  strDefaultVal = TextDatumGetCString(datum);
2244  /* Convert C string to a value of the given type */
2245  datum = OidInputFunctionCall(type->typinput, strDefaultVal,
2246  getTypeIOParam(typeTuple), -1);
2247  /* Build a Const node containing the value */
2248  expr = (Node *) makeConst(typid,
2249  -1,
2250  type->typcollation,
2251  type->typlen,
2252  datum,
2253  false,
2254  type->typbyval);
2255  pfree(strDefaultVal);
2256  }
2257  else
2258  {
2259  /* No default */
2260  expr = NULL;
2261  }
2262  }
2263 
2264  ReleaseSysCache(typeTuple);
2265 
2266  return expr;
2267 }
2268 
2269 /*
2270  * getBaseType
2271  * If the given type is a domain, return its base type;
2272  * otherwise return the type's own OID.
2273  */
2274 Oid
2276 {
2277  int32 typmod = -1;
2278 
2279  return getBaseTypeAndTypmod(typid, &typmod);
2280 }
2281 
2282 /*
2283  * getBaseTypeAndTypmod
2284  * If the given type is a domain, return its base type and typmod;
2285  * otherwise return the type's own OID, and leave *typmod unchanged.
2286  *
2287  * Note that the "applied typmod" should be -1 for every domain level
2288  * above the bottommost; therefore, if the passed-in typid is indeed
2289  * a domain, *typmod should be -1.
2290  */
2291 Oid
2293 {
2294  /*
2295  * We loop to find the bottom base type in a stack of domains.
2296  */
2297  for (;;)
2298  {
2299  HeapTuple tup;
2300  Form_pg_type typTup;
2301 
2302  tup = SearchSysCache1(TYPEOID, ObjectIdGetDatum(typid));
2303  if (!HeapTupleIsValid(tup))
2304  elog(ERROR, "cache lookup failed for type %u", typid);
2305  typTup = (Form_pg_type) GETSTRUCT(tup);
2306  if (typTup->typtype != TYPTYPE_DOMAIN)
2307  {
2308  /* Not a domain, so done */
2309  ReleaseSysCache(tup);
2310  break;
2311  }
2312 
2313  Assert(*typmod == -1);
2314  typid = typTup->typbasetype;
2315  *typmod = typTup->typtypmod;
2316 
2317  ReleaseSysCache(tup);
2318  }
2319 
2320  return typid;
2321 }
2322 
2323 /*
2324  * get_typavgwidth
2325  *
2326  * Given a type OID and a typmod value (pass -1 if typmod is unknown),
2327  * estimate the average width of values of the type. This is used by
2328  * the planner, which doesn't require absolutely correct results;
2329  * it's OK (and expected) to guess if we don't know for sure.
2330  */
2331 int32
2332 get_typavgwidth(Oid typid, int32 typmod)
2333 {
2334  int typlen = get_typlen(typid);
2335  int32 maxwidth;
2336 
2337  /*
2338  * Easy if it's a fixed-width type
2339  */
2340  if (typlen > 0)
2341  return typlen;
2342 
2343  /*
2344  * type_maximum_size knows the encoding of typmod for some datatypes;
2345  * don't duplicate that knowledge here.
2346  */
2347  maxwidth = type_maximum_size(typid, typmod);
2348  if (maxwidth > 0)
2349  {
2350  /*
2351  * For BPCHAR, the max width is also the only width. Otherwise we
2352  * need to guess about the typical data width given the max. A sliding
2353  * scale for percentage of max width seems reasonable.
2354  */
2355  if (typid == BPCHAROID)
2356  return maxwidth;
2357  if (maxwidth <= 32)
2358  return maxwidth; /* assume full width */
2359  if (maxwidth < 1000)
2360  return 32 + (maxwidth - 32) / 2; /* assume 50% */
2361 
2362  /*
2363  * Beyond 1000, assume we're looking at something like
2364  * "varchar(10000)" where the limit isn't actually reached often, and
2365  * use a fixed estimate.
2366  */
2367  return 32 + (1000 - 32) / 2;
2368  }
2369 
2370  /*
2371  * Oops, we have no idea ... wild guess time.
2372  */
2373  return 32;
2374 }
2375 
2376 /*
2377  * get_typtype
2378  *
2379  * Given the type OID, find if it is a basic type, a complex type, etc.
2380  * It returns the null char if the cache lookup fails...
2381  */
2382 char
2384 {
2385  HeapTuple tp;
2386 
2388  if (HeapTupleIsValid(tp))
2389  {
2390  Form_pg_type typtup = (Form_pg_type) GETSTRUCT(tp);
2391  char result;
2392 
2393  result = typtup->typtype;
2394  ReleaseSysCache(tp);
2395  return result;
2396  }
2397  else
2398  return '\0';
2399 }
2400 
2401 /*
2402  * type_is_rowtype
2403  *
2404  * Convenience function to determine whether a type OID represents
2405  * a "rowtype" type --- either RECORD or a named composite type
2406  * (including a domain over a named composite type).
2407  */
2408 bool
2410 {
2411  if (typid == RECORDOID)
2412  return true; /* easy case */
2413  switch (get_typtype(typid))
2414  {
2415  case TYPTYPE_COMPOSITE:
2416  return true;
2417  case TYPTYPE_DOMAIN:
2418  if (get_typtype(getBaseType(typid)) == TYPTYPE_COMPOSITE)
2419  return true;
2420  break;
2421  default:
2422  break;
2423  }
2424  return false;
2425 }
2426 
2427 /*
2428  * type_is_enum
2429  * Returns true if the given type is an enum type.
2430  */
2431 bool
2433 {
2434  return (get_typtype(typid) == TYPTYPE_ENUM);
2435 }
2436 
2437 /*
2438  * type_is_range
2439  * Returns true if the given type is a range type.
2440  */
2441 bool
2443 {
2444  return (get_typtype(typid) == TYPTYPE_RANGE);
2445 }
2446 
2447 /*
2448  * get_type_category_preferred
2449  *
2450  * Given the type OID, fetch its category and preferred-type status.
2451  * Throws error on failure.
2452  */
2453 void
2454 get_type_category_preferred(Oid typid, char *typcategory, bool *typispreferred)
2455 {
2456  HeapTuple tp;
2457  Form_pg_type typtup;
2458 
2460  if (!HeapTupleIsValid(tp))
2461  elog(ERROR, "cache lookup failed for type %u", typid);
2462  typtup = (Form_pg_type) GETSTRUCT(tp);
2463  *typcategory = typtup->typcategory;
2464  *typispreferred = typtup->typispreferred;
2465  ReleaseSysCache(tp);
2466 }
2467 
2468 /*
2469  * get_typ_typrelid
2470  *
2471  * Given the type OID, get the typrelid (InvalidOid if not a complex
2472  * type).
2473  */
2474 Oid
2476 {
2477  HeapTuple tp;
2478 
2480  if (HeapTupleIsValid(tp))
2481  {
2482  Form_pg_type typtup = (Form_pg_type) GETSTRUCT(tp);
2483  Oid result;
2484 
2485  result = typtup->typrelid;
2486  ReleaseSysCache(tp);
2487  return result;
2488  }
2489  else
2490  return InvalidOid;
2491 }
2492 
2493 /*
2494  * get_element_type
2495  *
2496  * Given the type OID, get the typelem (InvalidOid if not an array type).
2497  *
2498  * NB: this only considers varlena arrays to be true arrays; InvalidOid is
2499  * returned if the input is a fixed-length array type.
2500  */
2501 Oid
2503 {
2504  HeapTuple tp;
2505 
2507  if (HeapTupleIsValid(tp))
2508  {
2509  Form_pg_type typtup = (Form_pg_type) GETSTRUCT(tp);
2510  Oid result;
2511 
2512  if (typtup->typlen == -1)
2513  result = typtup->typelem;
2514  else
2515  result = InvalidOid;
2516  ReleaseSysCache(tp);
2517  return result;
2518  }
2519  else
2520  return InvalidOid;
2521 }
2522 
2523 /*
2524  * get_array_type
2525  *
2526  * Given the type OID, get the corresponding "true" array type.
2527  * Returns InvalidOid if no array type can be found.
2528  */
2529 Oid
2531 {
2532  HeapTuple tp;
2533  Oid result = InvalidOid;
2534 
2536  if (HeapTupleIsValid(tp))
2537  {
2538  result = ((Form_pg_type) GETSTRUCT(tp))->typarray;
2539  ReleaseSysCache(tp);
2540  }
2541  return result;
2542 }
2543 
2544 /*
2545  * get_promoted_array_type
2546  *
2547  * The "promoted" type is what you'd get from an ARRAY(SELECT ...)
2548  * construct, that is, either the corresponding "true" array type
2549  * if the input is a scalar type that has such an array type,
2550  * or the same type if the input is already a "true" array type.
2551  * Returns InvalidOid if neither rule is satisfied.
2552  */
2553 Oid
2555 {
2556  Oid array_type = get_array_type(typid);
2557 
2558  if (OidIsValid(array_type))
2559  return array_type;
2560  if (OidIsValid(get_element_type(typid)))
2561  return typid;
2562  return InvalidOid;
2563 }
2564 
2565 /*
2566  * get_base_element_type
2567  * Given the type OID, get the typelem, looking "through" any domain
2568  * to its underlying array type.
2569  *
2570  * This is equivalent to get_element_type(getBaseType(typid)), but avoids
2571  * an extra cache lookup. Note that it fails to provide any information
2572  * about the typmod of the array.
2573  */
2574 Oid
2576 {
2577  /*
2578  * We loop to find the bottom base type in a stack of domains.
2579  */
2580  for (;;)
2581  {
2582  HeapTuple tup;
2583  Form_pg_type typTup;
2584 
2585  tup = SearchSysCache1(TYPEOID, ObjectIdGetDatum(typid));
2586  if (!HeapTupleIsValid(tup))
2587  break;
2588  typTup = (Form_pg_type) GETSTRUCT(tup);
2589  if (typTup->typtype != TYPTYPE_DOMAIN)
2590  {
2591  /* Not a domain, so stop descending */
2592  Oid result;
2593 
2594  /* This test must match get_element_type */
2595  if (typTup->typlen == -1)
2596  result = typTup->typelem;
2597  else
2598  result = InvalidOid;
2599  ReleaseSysCache(tup);
2600  return result;
2601  }
2602 
2603  typid = typTup->typbasetype;
2604  ReleaseSysCache(tup);
2605  }
2606 
2607  /* Like get_element_type, silently return InvalidOid for bogus input */
2608  return InvalidOid;
2609 }
2610 
2611 /*
2612  * getTypeInputInfo
2613  *
2614  * Get info needed for converting values of a type to internal form
2615  */
2616 void
2617 getTypeInputInfo(Oid type, Oid *typInput, Oid *typIOParam)
2618 {
2619  HeapTuple typeTuple;
2620  Form_pg_type pt;
2621 
2622  typeTuple = SearchSysCache1(TYPEOID, ObjectIdGetDatum(type));
2623  if (!HeapTupleIsValid(typeTuple))
2624  elog(ERROR, "cache lookup failed for type %u", type);
2625  pt = (Form_pg_type) GETSTRUCT(typeTuple);
2626 
2627  if (!pt->typisdefined)
2628  ereport(ERROR,
2629  (errcode(ERRCODE_UNDEFINED_OBJECT),
2630  errmsg("type %s is only a shell",
2631  format_type_be(type))));
2632  if (!OidIsValid(pt->typinput))
2633  ereport(ERROR,
2634  (errcode(ERRCODE_UNDEFINED_FUNCTION),
2635  errmsg("no input function available for type %s",
2636  format_type_be(type))));
2637 
2638  *typInput = pt->typinput;
2639  *typIOParam = getTypeIOParam(typeTuple);
2640 
2641  ReleaseSysCache(typeTuple);
2642 }
2643 
2644 /*
2645  * getTypeOutputInfo
2646  *
2647  * Get info needed for printing values of a type
2648  */
2649 void
2650 getTypeOutputInfo(Oid type, Oid *typOutput, bool *typIsVarlena)
2651 {
2652  HeapTuple typeTuple;
2653  Form_pg_type pt;
2654 
2655  typeTuple = SearchSysCache1(TYPEOID, ObjectIdGetDatum(type));
2656  if (!HeapTupleIsValid(typeTuple))
2657  elog(ERROR, "cache lookup failed for type %u", type);
2658  pt = (Form_pg_type) GETSTRUCT(typeTuple);
2659 
2660  if (!pt->typisdefined)
2661  ereport(ERROR,
2662  (errcode(ERRCODE_UNDEFINED_OBJECT),
2663  errmsg("type %s is only a shell",
2664  format_type_be(type))));
2665  if (!OidIsValid(pt->typoutput))
2666  ereport(ERROR,
2667  (errcode(ERRCODE_UNDEFINED_FUNCTION),
2668  errmsg("no output function available for type %s",
2669  format_type_be(type))));
2670 
2671  *typOutput = pt->typoutput;
2672  *typIsVarlena = (!pt->typbyval) && (pt->typlen == -1);
2673 
2674  ReleaseSysCache(typeTuple);
2675 }
2676 
2677 /*
2678  * getTypeBinaryInputInfo
2679  *
2680  * Get info needed for binary input of values of a type
2681  */
2682 void
2683 getTypeBinaryInputInfo(Oid type, Oid *typReceive, Oid *typIOParam)
2684 {
2685  HeapTuple typeTuple;
2686  Form_pg_type pt;
2687 
2688  typeTuple = SearchSysCache1(TYPEOID, ObjectIdGetDatum(type));
2689  if (!HeapTupleIsValid(typeTuple))
2690  elog(ERROR, "cache lookup failed for type %u", type);
2691  pt = (Form_pg_type) GETSTRUCT(typeTuple);
2692 
2693  if (!pt->typisdefined)
2694  ereport(ERROR,
2695  (errcode(ERRCODE_UNDEFINED_OBJECT),
2696  errmsg("type %s is only a shell",
2697  format_type_be(type))));
2698  if (!OidIsValid(pt->typreceive))
2699  ereport(ERROR,
2700  (errcode(ERRCODE_UNDEFINED_FUNCTION),
2701  errmsg("no binary input function available for type %s",
2702  format_type_be(type))));
2703 
2704  *typReceive = pt->typreceive;
2705  *typIOParam = getTypeIOParam(typeTuple);
2706 
2707  ReleaseSysCache(typeTuple);
2708 }
2709 
2710 /*
2711  * getTypeBinaryOutputInfo
2712  *
2713  * Get info needed for binary output of values of a type
2714  */
2715 void
2716 getTypeBinaryOutputInfo(Oid type, Oid *typSend, bool *typIsVarlena)
2717 {
2718  HeapTuple typeTuple;
2719  Form_pg_type pt;
2720 
2721  typeTuple = SearchSysCache1(TYPEOID, ObjectIdGetDatum(type));
2722  if (!HeapTupleIsValid(typeTuple))
2723  elog(ERROR, "cache lookup failed for type %u", type);
2724  pt = (Form_pg_type) GETSTRUCT(typeTuple);
2725 
2726  if (!pt->typisdefined)
2727  ereport(ERROR,
2728  (errcode(ERRCODE_UNDEFINED_OBJECT),
2729  errmsg("type %s is only a shell",
2730  format_type_be(type))));
2731  if (!OidIsValid(pt->typsend))
2732  ereport(ERROR,
2733  (errcode(ERRCODE_UNDEFINED_FUNCTION),
2734  errmsg("no binary output function available for type %s",
2735  format_type_be(type))));
2736 
2737  *typSend = pt->typsend;
2738  *typIsVarlena = (!pt->typbyval) && (pt->typlen == -1);
2739 
2740  ReleaseSysCache(typeTuple);
2741 }
2742 
2743 /*
2744  * get_typmodin
2745  *
2746  * Given the type OID, return the type's typmodin procedure, if any.
2747  */
2748 Oid
2750 {
2751  HeapTuple tp;
2752 
2754  if (HeapTupleIsValid(tp))
2755  {
2756  Form_pg_type typtup = (Form_pg_type) GETSTRUCT(tp);
2757  Oid result;
2758 
2759  result = typtup->typmodin;
2760  ReleaseSysCache(tp);
2761  return result;
2762  }
2763  else
2764  return InvalidOid;
2765 }
2766 
2767 #ifdef NOT_USED
2768 /*
2769  * get_typmodout
2770  *
2771  * Given the type OID, return the type's typmodout procedure, if any.
2772  */
2773 Oid
2774 get_typmodout(Oid typid)
2775 {
2776  HeapTuple tp;
2777 
2779  if (HeapTupleIsValid(tp))
2780  {
2781  Form_pg_type typtup = (Form_pg_type) GETSTRUCT(tp);
2782  Oid result;
2783 
2784  result = typtup->typmodout;
2785  ReleaseSysCache(tp);
2786  return result;
2787  }
2788  else
2789  return InvalidOid;
2790 }
2791 #endif /* NOT_USED */
2792 
2793 /*
2794  * get_typcollation
2795  *
2796  * Given the type OID, return the type's typcollation attribute.
2797  */
2798 Oid
2800 {
2801  HeapTuple tp;
2802 
2804  if (HeapTupleIsValid(tp))
2805  {
2806  Form_pg_type typtup = (Form_pg_type) GETSTRUCT(tp);
2807  Oid result;
2808 
2809  result = typtup->typcollation;
2810  ReleaseSysCache(tp);
2811  return result;
2812  }
2813  else
2814  return InvalidOid;
2815 }
2816 
2817 
2818 /*
2819  * type_is_collatable
2820  *
2821  * Return whether the type cares about collations
2822  */
2823 bool
2825 {
2826  return OidIsValid(get_typcollation(typid));
2827 }
2828 
2829 
2830 /* ---------- STATISTICS CACHE ---------- */
2831 
2832 /*
2833  * get_attavgwidth
2834  *
2835  * Given the table and attribute number of a column, get the average
2836  * width of entries in the column. Return zero if no data available.
2837  *
2838  * Currently this is only consulted for individual tables, not for inheritance
2839  * trees, so we don't need an "inh" parameter.
2840  *
2841  * Calling a hook at this point looks somewhat strange, but is required
2842  * because the optimizer calls this function without any other way for
2843  * plug-ins to control the result.
2844  */
2845 int32
2847 {
2848  HeapTuple tp;
2849  int32 stawidth;
2850 
2852  {
2853  stawidth = (*get_attavgwidth_hook) (relid, attnum);
2854  if (stawidth > 0)
2855  return stawidth;
2856  }
2858  ObjectIdGetDatum(relid),
2859  Int16GetDatum(attnum),
2860  BoolGetDatum(false));
2861  if (HeapTupleIsValid(tp))
2862  {
2863  stawidth = ((Form_pg_statistic) GETSTRUCT(tp))->stawidth;
2864  ReleaseSysCache(tp);
2865  if (stawidth > 0)
2866  return stawidth;
2867  }
2868  return 0;
2869 }
2870 
2871 /*
2872  * get_attstatsslot
2873  *
2874  * Extract the contents of a "slot" of a pg_statistic tuple.
2875  * Returns true if requested slot type was found, else false.
2876  *
2877  * Unlike other routines in this file, this takes a pointer to an
2878  * already-looked-up tuple in the pg_statistic cache. We do this since
2879  * most callers will want to extract more than one value from the cache
2880  * entry, and we don't want to repeat the cache lookup unnecessarily.
2881  * Also, this API allows this routine to be used with statistics tuples
2882  * that have been provided by a stats hook and didn't really come from
2883  * pg_statistic.
2884  *
2885  * sslot: pointer to output area (typically, a local variable in the caller).
2886  * statstuple: pg_statistic tuple to be examined.
2887  * reqkind: STAKIND code for desired statistics slot kind.
2888  * reqop: STAOP value wanted, or InvalidOid if don't care.
2889  * flags: bitmask of ATTSTATSSLOT_VALUES and/or ATTSTATSSLOT_NUMBERS.
2890  *
2891  * If a matching slot is found, true is returned, and *sslot is filled thus:
2892  * staop: receives the actual STAOP value.
2893  * valuetype: receives actual datatype of the elements of stavalues.
2894  * values: receives pointer to an array of the slot's stavalues.
2895  * nvalues: receives number of stavalues.
2896  * numbers: receives pointer to an array of the slot's stanumbers (as float4).
2897  * nnumbers: receives number of stanumbers.
2898  *
2899  * valuetype/values/nvalues are InvalidOid/NULL/0 if ATTSTATSSLOT_VALUES
2900  * wasn't specified. Likewise, numbers/nnumbers are NULL/0 if
2901  * ATTSTATSSLOT_NUMBERS wasn't specified.
2902  *
2903  * If no matching slot is found, false is returned, and *sslot is zeroed.
2904  *
2905  * The data referred to by the fields of sslot is locally palloc'd and
2906  * is independent of the original pg_statistic tuple. When the caller
2907  * is done with it, call free_attstatsslot to release the palloc'd data.
2908  *
2909  * If it's desirable to call free_attstatsslot when get_attstatsslot might
2910  * not have been called, memset'ing sslot to zeroes will allow that.
2911  */
2912 bool
2914  int reqkind, Oid reqop, int flags)
2915 {
2916  Form_pg_statistic stats = (Form_pg_statistic) GETSTRUCT(statstuple);
2917  int i;
2918  Datum val;
2919  bool isnull;
2920  ArrayType *statarray;
2921  Oid arrayelemtype;
2922  int narrayelem;
2923  HeapTuple typeTuple;
2924  Form_pg_type typeForm;
2925 
2926  /* initialize *sslot properly */
2927  memset(sslot, 0, sizeof(AttStatsSlot));
2928 
2929  for (i = 0; i < STATISTIC_NUM_SLOTS; i++)
2930  {
2931  if ((&stats->stakind1)[i] == reqkind &&
2932  (reqop == InvalidOid || (&stats->staop1)[i] == reqop))
2933  break;
2934  }
2935  if (i >= STATISTIC_NUM_SLOTS)
2936  return false; /* not there */
2937 
2938  sslot->staop = (&stats->staop1)[i];
2939 
2940  if (flags & ATTSTATSSLOT_VALUES)
2941  {
2942  val = SysCacheGetAttr(STATRELATTINH, statstuple,
2943  Anum_pg_statistic_stavalues1 + i,
2944  &isnull);
2945  if (isnull)
2946  elog(ERROR, "stavalues is null");
2947 
2948  /*
2949  * Detoast the array if needed, and in any case make a copy that's
2950  * under control of this AttStatsSlot.
2951  */
2952  statarray = DatumGetArrayTypePCopy(val);
2953 
2954  /*
2955  * Extract the actual array element type, and pass it back in case the
2956  * caller needs it.
2957  */
2958  sslot->valuetype = arrayelemtype = ARR_ELEMTYPE(statarray);
2959 
2960  /* Need info about element type */
2961  typeTuple = SearchSysCache1(TYPEOID, ObjectIdGetDatum(arrayelemtype));
2962  if (!HeapTupleIsValid(typeTuple))
2963  elog(ERROR, "cache lookup failed for type %u", arrayelemtype);
2964  typeForm = (Form_pg_type) GETSTRUCT(typeTuple);
2965 
2966  /* Deconstruct array into Datum elements; NULLs not expected */
2967  deconstruct_array(statarray,
2968  arrayelemtype,
2969  typeForm->typlen,
2970  typeForm->typbyval,
2971  typeForm->typalign,
2972  &sslot->values, NULL, &sslot->nvalues);
2973 
2974  /*
2975  * If the element type is pass-by-reference, we now have a bunch of
2976  * Datums that are pointers into the statarray, so we need to keep
2977  * that until free_attstatsslot. Otherwise, all the useful info is in
2978  * sslot->values[], so we can free the array object immediately.
2979  */
2980  if (!typeForm->typbyval)
2981  sslot->values_arr = statarray;
2982  else
2983  pfree(statarray);
2984 
2985  ReleaseSysCache(typeTuple);
2986  }
2987 
2988  if (flags & ATTSTATSSLOT_NUMBERS)
2989  {
2990  val = SysCacheGetAttr(STATRELATTINH, statstuple,
2991  Anum_pg_statistic_stanumbers1 + i,
2992  &isnull);
2993  if (isnull)
2994  elog(ERROR, "stanumbers is null");
2995 
2996  /*
2997  * Detoast the array if needed, and in any case make a copy that's
2998  * under control of this AttStatsSlot.
2999  */
3000  statarray = DatumGetArrayTypePCopy(val);
3001 
3002  /*
3003  * We expect the array to be a 1-D float4 array; verify that. We don't
3004  * need to use deconstruct_array() since the array data is just going
3005  * to look like a C array of float4 values.
3006  */
3007  narrayelem = ARR_DIMS(statarray)[0];
3008  if (ARR_NDIM(statarray) != 1 || narrayelem <= 0 ||
3009  ARR_HASNULL(statarray) ||
3010  ARR_ELEMTYPE(statarray) != FLOAT4OID)
3011  elog(ERROR, "stanumbers is not a 1-D float4 array");
3012 
3013  /* Give caller a pointer directly into the statarray */
3014  sslot->numbers = (float4 *) ARR_DATA_PTR(statarray);
3015  sslot->nnumbers = narrayelem;
3016 
3017  /* We'll free the statarray in free_attstatsslot */
3018  sslot->numbers_arr = statarray;
3019  }
3020 
3021  return true;
3022 }
3023 
3024 /*
3025  * free_attstatsslot
3026  * Free data allocated by get_attstatsslot
3027  */
3028 void
3030 {
3031  /* The values[] array was separately palloc'd by deconstruct_array */
3032  if (sslot->values)
3033  pfree(sslot->values);
3034  /* The numbers[] array points into numbers_arr, do not pfree it */
3035  /* Free the detoasted array objects, if any */
3036  if (sslot->values_arr)
3037  pfree(sslot->values_arr);
3038  if (sslot->numbers_arr)
3039  pfree(sslot->numbers_arr);
3040 }
3041 
3042 /* ---------- PG_NAMESPACE CACHE ---------- */
3043 
3044 /*
3045  * get_namespace_name
3046  * Returns the name of a given namespace
3047  *
3048  * Returns a palloc'd copy of the string, or NULL if no such namespace.
3049  */
3050 char *
3052 {
3053  HeapTuple tp;
3054 
3056  if (HeapTupleIsValid(tp))
3057  {
3059  char *result;
3060 
3061  result = pstrdup(NameStr(nsptup->nspname));
3062  ReleaseSysCache(tp);
3063  return result;
3064  }
3065  else
3066  return NULL;
3067 }
3068 
3069 /*
3070  * get_namespace_name_or_temp
3071  * As above, but if it is this backend's temporary namespace, return
3072  * "pg_temp" instead.
3073  */
3074 char *
3076 {
3077  if (isTempNamespace(nspid))
3078  return "pg_temp";
3079  else
3080  return get_namespace_name(nspid);
3081 }
3082 
3083 /* ---------- PG_RANGE CACHE ---------- */
3084 
3085 /*
3086  * get_range_subtype
3087  * Returns the subtype of a given range type
3088  *
3089  * Returns InvalidOid if the type is not a range type.
3090  */
3091 Oid
3093 {
3094  HeapTuple tp;
3095 
3096  tp = SearchSysCache1(RANGETYPE, ObjectIdGetDatum(rangeOid));
3097  if (HeapTupleIsValid(tp))
3098  {
3099  Form_pg_range rngtup = (Form_pg_range) GETSTRUCT(tp);
3100  Oid result;
3101 
3102  result = rngtup->rngsubtype;
3103  ReleaseSysCache(tp);
3104  return result;
3105  }
3106  else
3107  return InvalidOid;
3108 }
signed short int16
Definition: c.h:312
char typcategory
Definition: pg_type.h:84
#define NIL
Definition: pg_list.h:69
int32 get_atttypmod(Oid relid, AttrNumber attnum)
Definition: lsyscache.c:890
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:1876
char get_typstorage(Oid typid)
Definition: lsyscache.c:2173
bool get_func_leakproof(Oid funcid)
Definition: lsyscache.c:1626
RegProcedure get_oprjoin(Oid opno)
Definition: lsyscache.c:1370
Oid getBaseTypeAndTypmod(Oid typid, int32 *typmod)
Definition: lsyscache.c:2292
void * stringToNode(char *str)
Definition: read.c:39
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:1266
FormData_pg_range * Form_pg_range
Definition: pg_range.h:55
int n_members
Definition: catcache.h:176
char get_attidentity(Oid relid, AttrNumber attnum)
Definition: lsyscache.c:836
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:1298
#define BTGreaterStrategyNumber
Definition: stratnum.h:33
void getTypeOutputInfo(Oid type, Oid *typOutput, bool *typIsVarlena)
Definition: lsyscache.c:2650
Oid relnamespace
Definition: pg_class.h:32
#define GETSTRUCT(TUP)
Definition: htup_details.h:673
FormData_pg_namespace * Form_pg_namespace
Definition: pg_namespace.h:49
Oid get_op_opfamily_sortfamily(Oid opno, Oid opfamily)
Definition: lsyscache.c:105
int16 typlen
Definition: pg_type.h:55
char * get_language_name(Oid langoid, bool missing_ok)
Definition: lsyscache.c:1003
#define ATTSTATSSLOT_VALUES
Definition: lsyscache.h:39
Oid get_func_namespace(Oid funcid)
Definition: lsyscache.c:1421
char * get_constraint_name(Oid conoid)
Definition: lsyscache.c:982
Oid get_element_type(Oid typid)
Definition: lsyscache.c:2502
int nnumbers
Definition: lsyscache.h:53
void get_typlenbyvalalign(Oid typid, int16 *typlen, bool *typbyval, char *typalign)
Definition: lsyscache.c:2025
float4 get_func_rows(Oid funcid)
Definition: lsyscache.c:1664
#define PointerGetDatum(X)
Definition: postgres.h:539
FormData_pg_amproc * Form_pg_amproc
Definition: pg_amproc.h:66
#define HTEqualStrategyNumber
Definition: hash.h:336
Oid get_array_type(Oid typid)
Definition: lsyscache.c:2530
char get_rel_relkind(Oid relid)
Definition: lsyscache.c:1805
char * get_collation_name(Oid colloid)
Definition: lsyscache.c:952
char * pstrdup(const char *in)
Definition: mcxt.c:1161
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:472
Oid get_rel_namespace(Oid relid)
Definition: lsyscache.c:1754
#define Int16GetDatum(X)
Definition: postgres.h:434
Oid get_func_signature(Oid funcid, Oid **argtypes, int *nargs)
Definition: lsyscache.c:1485
Definition: nodes.h:517
bool get_typisdefined(Oid typid)
Definition: lsyscache.c:1927
uint16 StrategyNumber
Definition: stratnum.h:22
int errcode(int sqlerrcode)
Definition: elog.c:575
char get_typtype(Oid typid)
Definition: lsyscache.c:2383
char * format_type_be(Oid type_oid)
Definition: format_type.c:328
bool type_is_range(Oid typid)
Definition: lsyscache.c:2442
IOFuncSelector
Definition: lsyscache.h:30
int16 pronargs
Definition: pg_proc.h:80
float4 get_func_cost(Oid funcid)
Definition: lsyscache.c:1645
bool op_mergejoinable(Oid opno, Oid inputtype)
Definition: lsyscache.c:1180
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:298
FormData_pg_statistic * Form_pg_statistic
Definition: pg_statistic.h:127
List * lappend_oid(List *list, Oid datum)
Definition: list.c:164
#define OidIsValid(objectId)
Definition: c.h:605
Oid get_op_rettype(Oid opno)
Definition: lsyscache.c:1127
Oid get_func_rettype(Oid funcid)
Definition: lsyscache.c:1444
signed int int32
Definition: c.h:313
#define GetSysCacheOid2(cacheId, key1, key2)
Definition: syscache.h:193
Oid get_rel_tablespace(Oid relid)
Definition: lsyscache.c:1832
CatCTup * members[FLEXIBLE_ARRAY_MEMBER]
Definition: catcache.h:178
bool get_typbyval(Oid typid)
Definition: lsyscache.c:1976
char * get_opname(Oid opno)
Definition: lsyscache.c:1104
Oid get_typ_typrelid(Oid typid)
Definition: lsyscache.c:2475
void pfree(void *pointer)
Definition: mcxt.c:1031
char typalign
Definition: pg_type.h:167
bool op_hashjoinable(Oid opno, Oid inputtype)
Definition: lsyscache.c:1231
FormData_pg_transform * Form_pg_transform
Definition: pg_transform.h:42
#define ATTSTATSSLOT_NUMBERS
Definition: lsyscache.h:40
void * values_arr
Definition: lsyscache.h:56
#define ObjectIdGetDatum(X)
Definition: postgres.h:490
#define ERROR
Definition: elog.h:43
NameData attname
Definition: pg_attribute.h:40
#define SearchSysCacheExists3(cacheId, key1, key2, key3)
Definition: syscache.h:186
char * get_func_name(Oid funcid)
Definition: lsyscache.c:1397
#define ARR_DIMS(a)
Definition: array.h:279
HeapTuple SearchSysCache3(int cacheId, Datum key1, Datum key2, Datum key3)
Definition: syscache.c:1134
int32 type_maximum_size(Oid type_oid, int32 typemod)
Definition: format_type.c:397
Oid get_relname_relid(const char *relname, Oid relnamespace)
Definition: lsyscache.c:1687
#define ARR_DATA_PTR(a)
Definition: array.h:307
char * get_namespace_name(Oid nspid)
Definition: lsyscache.c:3051
Oid get_func_variadictype(Oid funcid)
Definition: lsyscache.c:1512
AttrNumber get_attnum(Oid relid, const char *attname)
Definition: lsyscache.c:806
float4 * numbers
Definition: lsyscache.h:52
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:197
bool isTempNamespace(Oid namespaceId)
Definition: namespace.c:3137
#define ARR_HASNULL(a)
Definition: array.h:276
#define SearchSysCacheList1(cacheId, key1)
Definition: syscache.h:209
void op_input_types(Oid opno, Oid *lefttype, Oid *righttype)
Definition: lsyscache.c:1152
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:2409
HeapTuple SearchSysCache4(int cacheId, Datum key1, Datum key2, Datum key3, Datum key4)
Definition: syscache.c:1145
Oid get_atttype(Oid relid, AttrNumber attnum)
Definition: lsyscache.c:863
Oid get_typmodin(Oid typid)
Definition: lsyscache.c:2749
#define HASHSTANDARD_PROC
Definition: hash.h:351
void getTypeBinaryInputInfo(Oid type, Oid *typReceive, Oid *typIOParam)
Definition: lsyscache.c:2683
#define ereport(elevel, rest)
Definition: elog.h:122
void getTypeInputInfo(Oid type, Oid *typInput, Oid *typIOParam)
Definition: lsyscache.c:2617
List * lappend(List *list, void *datum)
Definition: list.c:128
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:1112
float float4
Definition: c.h:457
bool get_func_retset(Oid funcid)
Definition: lsyscache.c:1531
Oid get_promoted_array_type(Oid typid)
Definition: lsyscache.c:2554
#define ReleaseSysCacheList(x)
Definition: syscache.h:216
RegProcedure get_oprrest(Oid opno)
Definition: lsyscache.c:1346
#define TextDatumGetCString(d)
Definition: builtins.h:96
char get_func_prokind(Oid funcid)
Definition: lsyscache.c:1607
void getTypeBinaryOutputInfo(Oid type, Oid *typSend, bool *typIsVarlena)
Definition: lsyscache.c:2716
char op_volatile(Oid opno)
Definition: lsyscache.c:1282
List * get_op_btree_interpretation(Oid opno)
Definition: lsyscache.c:598
uintptr_t Datum
Definition: postgres.h:365
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1160
int32(* get_attavgwidth_hook_type)(Oid relid, AttrNumber attnum)
Definition: lsyscache.h:61
Datum SysCacheGetAttr(int cacheId, HeapTuple tup, AttrNumber attributeNumber, bool *isNull)
Definition: syscache.c:1368
#define DatumGetArrayTypePCopy(X)
Definition: array.h:247
Oid get_rel_type_id(Oid relid)
Definition: lsyscache.c:1781
FormData_pg_proc * Form_pg_proc
Definition: pg_proc.h:132
#define BoolGetDatum(X)
Definition: postgres.h:385
int32 get_typavgwidth(Oid typid, int32 typmod)
Definition: lsyscache.c:2332
TypeCacheEntry * lookup_type_cache(Oid type_id, int flags)
Definition: typcache.c:321
#define InvalidOid
Definition: postgres_ext.h:36
RegProcedure get_opcode(Oid opno)
Definition: lsyscache.c:1079
int16 attnum
Definition: pg_attribute.h:79
#define STATISTIC_NUM_SLOTS
Definition: pg_statistic.h:119
Oid get_typcollation(Oid typid)
Definition: lsyscache.c:2799
#define TYPECACHE_CMP_PROC
Definition: typcache.h:130
FormData_pg_constraint * Form_pg_constraint
bool list_member_oid(const List *list, Oid datum)
Definition: list.c:505
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
bool get_attstatsslot(AttStatsSlot *sslot, HeapTuple statstuple, int reqkind, Oid reqop, int flags)
Definition: lsyscache.c:2913
#define Assert(condition)
Definition: c.h:699
Datum * values
Definition: lsyscache.h:49
Node * get_typdefault(Oid typid)
Definition: lsyscache.c:2202
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
char func_parallel(Oid funcid)
Definition: lsyscache.c:1588
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:2432
void get_atttypetypmodcoll(Oid relid, AttrNumber attnum, Oid *typid, int32 *typmod, Oid *collid)
Definition: lsyscache.c:920
FormData_pg_type * Form_pg_type
Definition: pg_type.h:247
void get_typlenbyval(Oid typid, int16 *typlen, bool *typbyval)
Definition: lsyscache.c:2005
HeapTuple SearchSysCache2(int cacheId, Datum key1, Datum key2)
Definition: syscache.c:1123
HeapTuple SearchSysCacheAttName(Oid relid, const char *attname)
Definition: syscache.c:1248
#define ARR_NDIM(a)
Definition: array.h:275
Oid get_opclass_family(Oid opclass)
Definition: lsyscache.c:1032
FormData_pg_operator * Form_pg_operator
Definition: pg_operator.h:82
bool func_strict(Oid funcid)
Definition: lsyscache.c:1550
#define InvalidAttrNumber
Definition: attnum.h:23
FormData_pg_collation * Form_pg_collation
Definition: pg_collation.h:50
#define CharGetDatum(X)
Definition: postgres.h:399
Oid get_transform_tosql(Oid typid, Oid langid, List *trftypes)
Definition: lsyscache.c:1897
char get_rel_persistence(Oid relid)
Definition: lsyscache.c:1856
int get_func_nargs(Oid funcid)
Definition: lsyscache.c:1463
void deconstruct_array(ArrayType *array, Oid elmtype, int elmlen, bool elmbyval, char elmalign, Datum **elemsp, bool **nullsp, int *nelemsp)
Definition: arrayfuncs.c:3449
#define IsBootstrapProcessingMode()
Definition: miscadmin.h:372
int get_op_opfamily_strategy(Oid opno, Oid opfamily)
Definition: lsyscache.c:80
FormData_pg_class * Form_pg_class
Definition: pg_class.h:92
Oid get_base_element_type(Oid typid)
Definition: lsyscache.c:2575
char func_volatile(Oid funcid)
Definition: lsyscache.c:1569
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:1951
FormData_pg_language * Form_pg_language
Definition: pg_language.h:49
void * palloc(Size size)
Definition: mcxt.c:924
int errmsg(const char *fmt,...)
Definition: elog.c:797
char * get_namespace_name_or_temp(Oid nspid)
Definition: lsyscache.c:3075
FormData_pg_amop * Form_pg_amop
Definition: pg_amop.h:86
int i
Oid getTypeIOParam(HeapTuple typeTuple)
Definition: lsyscache.c:2057
#define NameStr(name)
Definition: c.h:576
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:57
#define elog
Definition: elog.h:219
#define HeapTupleGetOid(tuple)
Definition: htup_details.h:712
Oid get_negator(Oid opno)
Definition: lsyscache.c:1322
int32 get_attavgwidth(Oid relid, AttrNumber attnum)
Definition: lsyscache.c:2846
#define BTLessStrategyNumber
Definition: stratnum.h:29
Oid valuetype
Definition: lsyscache.h:48
Oid getBaseType(Oid typid)
Definition: lsyscache.c:2275
bool type_is_collatable(Oid typid)
Definition: lsyscache.c:2824
void get_type_category_preferred(Oid typid, char *typcategory, bool *typispreferred)
Definition: lsyscache.c:2454
FormData_pg_opclass * Form_pg_opclass
Definition: pg_opclass.h:81
Definition: pg_list.h:45
char * get_rel_name(Oid relid)
Definition: lsyscache.c:1730
Datum OidInputFunctionCall(Oid functionId, char *str, Oid typioparam, int32 typmod)
Definition: fmgr.c:1823
#define ARR_ELEMTYPE(a)
Definition: array.h:277
int16 AttrNumber
Definition: attnum.h:21
Oid get_range_subtype(Oid rangeOid)
Definition: lsyscache.c:3092
long val
Definition: informix.c:689
#define TYPECACHE_HASH_PROC
Definition: typcache.h:131
#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:959
Oid get_opclass_input_type(Oid opclass)
Definition: lsyscache.c:1054
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:2079
void free_attstatsslot(AttStatsSlot *sslot)
Definition: lsyscache.c:3029
bool typbyval
Definition: pg_type.h:65