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