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