PostgreSQL Source Code  git master
regproc.c
Go to the documentation of this file.
1 /*-------------------------------------------------------------------------
2  *
3  * regproc.c
4  * Functions for the built-in types regproc, regclass, regtype, etc.
5  *
6  * These types are all binary-compatible with type Oid, and rely on Oid
7  * for comparison and so forth. Their only interesting behavior is in
8  * special I/O conversion routines.
9  *
10  *
11  * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group
12  * Portions Copyright (c) 1994, Regents of the University of California
13  *
14  *
15  * IDENTIFICATION
16  * src/backend/utils/adt/regproc.c
17  *
18  *-------------------------------------------------------------------------
19  */
20 #include "postgres.h"
21 
22 #include <ctype.h>
23 
24 #include "access/htup_details.h"
25 #include "catalog/namespace.h"
26 #include "catalog/pg_class.h"
27 #include "catalog/pg_collation.h"
28 #include "catalog/pg_operator.h"
29 #include "catalog/pg_proc.h"
30 #include "catalog/pg_ts_config.h"
31 #include "catalog/pg_ts_dict.h"
32 #include "catalog/pg_type.h"
33 #include "lib/stringinfo.h"
34 #include "miscadmin.h"
35 #include "parser/parse_type.h"
36 #include "parser/scansup.h"
37 #include "utils/acl.h"
38 #include "utils/builtins.h"
39 #include "utils/lsyscache.h"
40 #include "utils/regproc.h"
41 #include "utils/syscache.h"
42 #include "utils/varlena.h"
43 
44 static void parseNameAndArgTypes(const char *string, bool allowNone,
45  List **names, int *nargs, Oid *argtypes);
46 
47 
48 /*****************************************************************************
49  * USER I/O ROUTINES *
50  *****************************************************************************/
51 
52 /*
53  * regprocin - converts "proname" to proc OID
54  *
55  * We also accept a numeric OID, for symmetry with the output routine.
56  *
57  * '-' signifies unknown (OID 0). In all other cases, the input must
58  * match an existing pg_proc entry.
59  */
60 Datum
62 {
63  char *pro_name_or_oid = PG_GETARG_CSTRING(0);
64  RegProcedure result = InvalidOid;
65  List *names;
66  FuncCandidateList clist;
67 
68  /* '-' ? */
69  if (strcmp(pro_name_or_oid, "-") == 0)
71 
72  /* Numeric OID? */
73  if (pro_name_or_oid[0] >= '0' &&
74  pro_name_or_oid[0] <= '9' &&
75  strspn(pro_name_or_oid, "0123456789") == strlen(pro_name_or_oid))
76  {
78  CStringGetDatum(pro_name_or_oid)));
79  PG_RETURN_OID(result);
80  }
81 
82  /* Else it's a name, possibly schema-qualified */
83 
84  /*
85  * We should never get here in bootstrap mode, as all references should
86  * have been resolved by genbki.pl.
87  */
89  elog(ERROR, "regproc values must be OIDs in bootstrap mode");
90 
91  /*
92  * Normal case: parse the name into components and see if it matches any
93  * pg_proc entries in the current search path.
94  */
95  names = stringToQualifiedNameList(pro_name_or_oid);
96  clist = FuncnameGetCandidates(names, -1, NIL, false, false, false, false);
97 
98  if (clist == NULL)
99  ereport(ERROR,
100  (errcode(ERRCODE_UNDEFINED_FUNCTION),
101  errmsg("function \"%s\" does not exist", pro_name_or_oid)));
102  else if (clist->next != NULL)
103  ereport(ERROR,
104  (errcode(ERRCODE_AMBIGUOUS_FUNCTION),
105  errmsg("more than one function named \"%s\"",
106  pro_name_or_oid)));
107 
108  result = clist->oid;
109 
110  PG_RETURN_OID(result);
111 }
112 
113 /*
114  * to_regproc - converts "proname" to proc OID
115  *
116  * If the name is not found, we return NULL.
117  */
118 Datum
120 {
121  char *pro_name = text_to_cstring(PG_GETARG_TEXT_PP(0));
122  List *names;
123  FuncCandidateList clist;
124 
125  /*
126  * Parse the name into components and see if it matches any pg_proc
127  * entries in the current search path.
128  */
129  names = stringToQualifiedNameList(pro_name);
130  clist = FuncnameGetCandidates(names, -1, NIL, false, false, false, true);
131 
132  if (clist == NULL || clist->next != NULL)
133  PG_RETURN_NULL();
134 
135  PG_RETURN_OID(clist->oid);
136 }
137 
138 /*
139  * regprocout - converts proc OID to "pro_name"
140  */
141 Datum
143 {
144  RegProcedure proid = PG_GETARG_OID(0);
145  char *result;
146  HeapTuple proctup;
147 
148  if (proid == InvalidOid)
149  {
150  result = pstrdup("-");
151  PG_RETURN_CSTRING(result);
152  }
153 
154  proctup = SearchSysCache1(PROCOID, ObjectIdGetDatum(proid));
155 
156  if (HeapTupleIsValid(proctup))
157  {
158  Form_pg_proc procform = (Form_pg_proc) GETSTRUCT(proctup);
159  char *proname = NameStr(procform->proname);
160 
161  /*
162  * In bootstrap mode, skip the fancy namespace stuff and just return
163  * the proc name. (This path is only needed for debugging output
164  * anyway.)
165  */
167  result = pstrdup(proname);
168  else
169  {
170  char *nspname;
171  FuncCandidateList clist;
172 
173  /*
174  * Would this proc be found (uniquely!) by regprocin? If not,
175  * qualify it.
176  */
177  clist = FuncnameGetCandidates(list_make1(makeString(proname)),
178  -1, NIL, false, false, false, false);
179  if (clist != NULL && clist->next == NULL &&
180  clist->oid == proid)
181  nspname = NULL;
182  else
183  nspname = get_namespace_name(procform->pronamespace);
184 
185  result = quote_qualified_identifier(nspname, proname);
186  }
187 
188  ReleaseSysCache(proctup);
189  }
190  else
191  {
192  /* If OID doesn't match any pg_proc entry, return it numerically */
193  result = (char *) palloc(NAMEDATALEN);
194  snprintf(result, NAMEDATALEN, "%u", proid);
195  }
196 
197  PG_RETURN_CSTRING(result);
198 }
199 
200 /*
201  * regprocrecv - converts external binary format to regproc
202  */
203 Datum
205 {
206  /* Exactly the same as oidrecv, so share code */
207  return oidrecv(fcinfo);
208 }
209 
210 /*
211  * regprocsend - converts regproc to binary format
212  */
213 Datum
215 {
216  /* Exactly the same as oidsend, so share code */
217  return oidsend(fcinfo);
218 }
219 
220 
221 /*
222  * regprocedurein - converts "proname(args)" to proc OID
223  *
224  * We also accept a numeric OID, for symmetry with the output routine.
225  *
226  * '-' signifies unknown (OID 0). In all other cases, the input must
227  * match an existing pg_proc entry.
228  */
229 Datum
231 {
232  char *pro_name_or_oid = PG_GETARG_CSTRING(0);
233  RegProcedure result = InvalidOid;
234  List *names;
235  int nargs;
236  Oid argtypes[FUNC_MAX_ARGS];
237  FuncCandidateList clist;
238 
239  /* '-' ? */
240  if (strcmp(pro_name_or_oid, "-") == 0)
242 
243  /* Numeric OID? */
244  if (pro_name_or_oid[0] >= '0' &&
245  pro_name_or_oid[0] <= '9' &&
246  strspn(pro_name_or_oid, "0123456789") == strlen(pro_name_or_oid))
247  {
249  CStringGetDatum(pro_name_or_oid)));
250  PG_RETURN_OID(result);
251  }
252 
253  /* The rest of this wouldn't work in bootstrap mode */
255  elog(ERROR, "regprocedure values must be OIDs in bootstrap mode");
256 
257  /*
258  * Else it's a name and arguments. Parse the name and arguments, look up
259  * potential matches in the current namespace search list, and scan to see
260  * which one exactly matches the given argument types. (There will not be
261  * more than one match.)
262  */
263  parseNameAndArgTypes(pro_name_or_oid, false, &names, &nargs, argtypes);
264 
265  clist = FuncnameGetCandidates(names, nargs, NIL, false, false,
266  false, false);
267 
268  for (; clist; clist = clist->next)
269  {
270  if (memcmp(clist->args, argtypes, nargs * sizeof(Oid)) == 0)
271  break;
272  }
273 
274  if (clist == NULL)
275  ereport(ERROR,
276  (errcode(ERRCODE_UNDEFINED_FUNCTION),
277  errmsg("function \"%s\" does not exist", pro_name_or_oid)));
278 
279  result = clist->oid;
280 
281  PG_RETURN_OID(result);
282 }
283 
284 /*
285  * to_regprocedure - converts "proname(args)" to proc OID
286  *
287  * If the name is not found, we return NULL.
288  */
289 Datum
291 {
292  char *pro_name = text_to_cstring(PG_GETARG_TEXT_PP(0));
293  List *names;
294  int nargs;
295  Oid argtypes[FUNC_MAX_ARGS];
296  FuncCandidateList clist;
297 
298  /*
299  * Parse the name and arguments, look up potential matches in the current
300  * namespace search list, and scan to see which one exactly matches the
301  * given argument types. (There will not be more than one match.)
302  */
303  parseNameAndArgTypes(pro_name, false, &names, &nargs, argtypes);
304 
305  clist = FuncnameGetCandidates(names, nargs, NIL, false, false, false, true);
306 
307  for (; clist; clist = clist->next)
308  {
309  if (memcmp(clist->args, argtypes, nargs * sizeof(Oid)) == 0)
310  PG_RETURN_OID(clist->oid);
311  }
312 
313  PG_RETURN_NULL();
314 }
315 
316 /*
317  * format_procedure - converts proc OID to "pro_name(args)"
318  *
319  * This exports the useful functionality of regprocedureout for use
320  * in other backend modules. The result is a palloc'd string.
321  */
322 char *
323 format_procedure(Oid procedure_oid)
324 {
325  return format_procedure_extended(procedure_oid, 0);
326 }
327 
328 char *
330 {
332 }
333 
334 /*
335  * format_procedure_extended - converts procedure OID to "pro_name(args)"
336  *
337  * This exports the useful functionality of regprocedureout for use
338  * in other backend modules. The result is a palloc'd string, or NULL.
339  *
340  * Routine to produce regprocedure names; see format_procedure above.
341  *
342  * The following bits in 'flags' modify the behavior:
343  * - FORMAT_PROC_INVALID_AS_NULL
344  * if the procedure OID is invalid or unknown, return NULL instead
345  * of the numeric OID.
346  * - FORMAT_PROC_FORCE_QUALIFY
347  * always schema-qualify procedure names, regardless of search_path
348  */
349 char *
350 format_procedure_extended(Oid procedure_oid, bits16 flags)
351 {
352  char *result;
353  HeapTuple proctup;
354 
355  proctup = SearchSysCache1(PROCOID, ObjectIdGetDatum(procedure_oid));
356 
357  if (HeapTupleIsValid(proctup))
358  {
359  Form_pg_proc procform = (Form_pg_proc) GETSTRUCT(proctup);
360  char *proname = NameStr(procform->proname);
361  int nargs = procform->pronargs;
362  int i;
363  char *nspname;
365 
366  /* XXX no support here for bootstrap mode */
368 
369  initStringInfo(&buf);
370 
371  /*
372  * Would this proc be found (given the right args) by regprocedurein?
373  * If not, or if caller requests it, we need to qualify it.
374  */
375  if ((flags & FORMAT_PROC_FORCE_QUALIFY) == 0 &&
376  FunctionIsVisible(procedure_oid))
377  nspname = NULL;
378  else
379  nspname = get_namespace_name(procform->pronamespace);
380 
381  appendStringInfo(&buf, "%s(",
382  quote_qualified_identifier(nspname, proname));
383  for (i = 0; i < nargs; i++)
384  {
385  Oid thisargtype = procform->proargtypes.values[i];
386 
387  if (i > 0)
388  appendStringInfoChar(&buf, ',');
390  (flags & FORMAT_PROC_FORCE_QUALIFY) != 0 ?
391  format_type_be_qualified(thisargtype) :
392  format_type_be(thisargtype));
393  }
394  appendStringInfoChar(&buf, ')');
395 
396  result = buf.data;
397 
398  ReleaseSysCache(proctup);
399  }
400  else if ((flags & FORMAT_PROC_INVALID_AS_NULL) != 0)
401  {
402  /* If object is undefined, return NULL as wanted by caller */
403  result = NULL;
404  }
405  else
406  {
407  /* If OID doesn't match any pg_proc entry, return it numerically */
408  result = (char *) palloc(NAMEDATALEN);
409  snprintf(result, NAMEDATALEN, "%u", procedure_oid);
410  }
411 
412  return result;
413 }
414 
415 /*
416  * Output an objname/objargs representation for the procedure with the
417  * given OID. If it doesn't exist, an error is thrown.
418  *
419  * This can be used to feed get_object_address.
420  */
421 void
422 format_procedure_parts(Oid procedure_oid, List **objnames, List **objargs,
423  bool missing_ok)
424 {
425  HeapTuple proctup;
426  Form_pg_proc procform;
427  int nargs;
428  int i;
429 
430  proctup = SearchSysCache1(PROCOID, ObjectIdGetDatum(procedure_oid));
431 
432  if (!HeapTupleIsValid(proctup))
433  {
434  if (!missing_ok)
435  elog(ERROR, "cache lookup failed for procedure with OID %u", procedure_oid);
436  return;
437  }
438 
439  procform = (Form_pg_proc) GETSTRUCT(proctup);
440  nargs = procform->pronargs;
441 
442  *objnames = list_make2(get_namespace_name_or_temp(procform->pronamespace),
443  pstrdup(NameStr(procform->proname)));
444  *objargs = NIL;
445  for (i = 0; i < nargs; i++)
446  {
447  Oid thisargtype = procform->proargtypes.values[i];
448 
449  *objargs = lappend(*objargs, format_type_be_qualified(thisargtype));
450  }
451 
452  ReleaseSysCache(proctup);
453 }
454 
455 /*
456  * regprocedureout - converts proc OID to "pro_name(args)"
457  */
458 Datum
460 {
461  RegProcedure proid = PG_GETARG_OID(0);
462  char *result;
463 
464  if (proid == InvalidOid)
465  result = pstrdup("-");
466  else
467  result = format_procedure(proid);
468 
469  PG_RETURN_CSTRING(result);
470 }
471 
472 /*
473  * regprocedurerecv - converts external binary format to regprocedure
474  */
475 Datum
477 {
478  /* Exactly the same as oidrecv, so share code */
479  return oidrecv(fcinfo);
480 }
481 
482 /*
483  * regproceduresend - converts regprocedure to binary format
484  */
485 Datum
487 {
488  /* Exactly the same as oidsend, so share code */
489  return oidsend(fcinfo);
490 }
491 
492 
493 /*
494  * regoperin - converts "oprname" to operator OID
495  *
496  * We also accept a numeric OID, for symmetry with the output routine.
497  *
498  * '0' signifies unknown (OID 0). In all other cases, the input must
499  * match an existing pg_operator entry.
500  */
501 Datum
503 {
504  char *opr_name_or_oid = PG_GETARG_CSTRING(0);
505  Oid result = InvalidOid;
506  List *names;
507  FuncCandidateList clist;
508 
509  /* '0' ? */
510  if (strcmp(opr_name_or_oid, "0") == 0)
512 
513  /* Numeric OID? */
514  if (opr_name_or_oid[0] >= '0' &&
515  opr_name_or_oid[0] <= '9' &&
516  strspn(opr_name_or_oid, "0123456789") == strlen(opr_name_or_oid))
517  {
519  CStringGetDatum(opr_name_or_oid)));
520  PG_RETURN_OID(result);
521  }
522 
523  /* Else it's a name, possibly schema-qualified */
524 
525  /* The rest of this wouldn't work in bootstrap mode */
527  elog(ERROR, "regoper values must be OIDs in bootstrap mode");
528 
529  /*
530  * Normal case: parse the name into components and see if it matches any
531  * pg_operator entries in the current search path.
532  */
533  names = stringToQualifiedNameList(opr_name_or_oid);
534  clist = OpernameGetCandidates(names, '\0', false);
535 
536  if (clist == NULL)
537  ereport(ERROR,
538  (errcode(ERRCODE_UNDEFINED_FUNCTION),
539  errmsg("operator does not exist: %s", opr_name_or_oid)));
540  else if (clist->next != NULL)
541  ereport(ERROR,
542  (errcode(ERRCODE_AMBIGUOUS_FUNCTION),
543  errmsg("more than one operator named %s",
544  opr_name_or_oid)));
545 
546  result = clist->oid;
547 
548  PG_RETURN_OID(result);
549 }
550 
551 /*
552  * to_regoper - converts "oprname" to operator OID
553  *
554  * If the name is not found, we return NULL.
555  */
556 Datum
558 {
559  char *opr_name = text_to_cstring(PG_GETARG_TEXT_PP(0));
560  List *names;
561  FuncCandidateList clist;
562 
563  /*
564  * Parse the name into components and see if it matches any pg_operator
565  * entries in the current search path.
566  */
567  names = stringToQualifiedNameList(opr_name);
568  clist = OpernameGetCandidates(names, '\0', true);
569 
570  if (clist == NULL || clist->next != NULL)
571  PG_RETURN_NULL();
572 
573  PG_RETURN_OID(clist->oid);
574 }
575 
576 /*
577  * regoperout - converts operator OID to "opr_name"
578  */
579 Datum
581 {
582  Oid oprid = PG_GETARG_OID(0);
583  char *result;
584  HeapTuple opertup;
585 
586  if (oprid == InvalidOid)
587  {
588  result = pstrdup("0");
589  PG_RETURN_CSTRING(result);
590  }
591 
592  opertup = SearchSysCache1(OPEROID, ObjectIdGetDatum(oprid));
593 
594  if (HeapTupleIsValid(opertup))
595  {
596  Form_pg_operator operform = (Form_pg_operator) GETSTRUCT(opertup);
597  char *oprname = NameStr(operform->oprname);
598 
599  /*
600  * In bootstrap mode, skip the fancy namespace stuff and just return
601  * the oper name. (This path is only needed for debugging output
602  * anyway.)
603  */
605  result = pstrdup(oprname);
606  else
607  {
608  FuncCandidateList clist;
609 
610  /*
611  * Would this oper be found (uniquely!) by regoperin? If not,
612  * qualify it.
613  */
614  clist = OpernameGetCandidates(list_make1(makeString(oprname)),
615  '\0', false);
616  if (clist != NULL && clist->next == NULL &&
617  clist->oid == oprid)
618  result = pstrdup(oprname);
619  else
620  {
621  const char *nspname;
622 
623  nspname = get_namespace_name(operform->oprnamespace);
624  nspname = quote_identifier(nspname);
625  result = (char *) palloc(strlen(nspname) + strlen(oprname) + 2);
626  sprintf(result, "%s.%s", nspname, oprname);
627  }
628  }
629 
630  ReleaseSysCache(opertup);
631  }
632  else
633  {
634  /*
635  * If OID doesn't match any pg_operator entry, return it numerically
636  */
637  result = (char *) palloc(NAMEDATALEN);
638  snprintf(result, NAMEDATALEN, "%u", oprid);
639  }
640 
641  PG_RETURN_CSTRING(result);
642 }
643 
644 /*
645  * regoperrecv - converts external binary format to regoper
646  */
647 Datum
649 {
650  /* Exactly the same as oidrecv, so share code */
651  return oidrecv(fcinfo);
652 }
653 
654 /*
655  * regopersend - converts regoper to binary format
656  */
657 Datum
659 {
660  /* Exactly the same as oidsend, so share code */
661  return oidsend(fcinfo);
662 }
663 
664 
665 /*
666  * regoperatorin - converts "oprname(args)" to operator OID
667  *
668  * We also accept a numeric OID, for symmetry with the output routine.
669  *
670  * '0' signifies unknown (OID 0). In all other cases, the input must
671  * match an existing pg_operator entry.
672  */
673 Datum
675 {
676  char *opr_name_or_oid = PG_GETARG_CSTRING(0);
677  Oid result;
678  List *names;
679  int nargs;
680  Oid argtypes[FUNC_MAX_ARGS];
681 
682  /* '0' ? */
683  if (strcmp(opr_name_or_oid, "0") == 0)
685 
686  /* Numeric OID? */
687  if (opr_name_or_oid[0] >= '0' &&
688  opr_name_or_oid[0] <= '9' &&
689  strspn(opr_name_or_oid, "0123456789") == strlen(opr_name_or_oid))
690  {
692  CStringGetDatum(opr_name_or_oid)));
693  PG_RETURN_OID(result);
694  }
695 
696  /* The rest of this wouldn't work in bootstrap mode */
698  elog(ERROR, "regoperator values must be OIDs in bootstrap mode");
699 
700  /*
701  * Else it's a name and arguments. Parse the name and arguments, look up
702  * potential matches in the current namespace search list, and scan to see
703  * which one exactly matches the given argument types. (There will not be
704  * more than one match.)
705  */
706  parseNameAndArgTypes(opr_name_or_oid, true, &names, &nargs, argtypes);
707  if (nargs == 1)
708  ereport(ERROR,
709  (errcode(ERRCODE_UNDEFINED_PARAMETER),
710  errmsg("missing argument"),
711  errhint("Use NONE to denote the missing argument of a unary operator.")));
712  if (nargs != 2)
713  ereport(ERROR,
714  (errcode(ERRCODE_TOO_MANY_ARGUMENTS),
715  errmsg("too many arguments"),
716  errhint("Provide two argument types for operator.")));
717 
718  result = OpernameGetOprid(names, argtypes[0], argtypes[1]);
719 
720  if (!OidIsValid(result))
721  ereport(ERROR,
722  (errcode(ERRCODE_UNDEFINED_FUNCTION),
723  errmsg("operator does not exist: %s", opr_name_or_oid)));
724 
725  PG_RETURN_OID(result);
726 }
727 
728 /*
729  * to_regoperator - converts "oprname(args)" to operator OID
730  *
731  * If the name is not found, we return NULL.
732  */
733 Datum
735 {
736  char *opr_name_or_oid = text_to_cstring(PG_GETARG_TEXT_PP(0));
737  Oid result;
738  List *names;
739  int nargs;
740  Oid argtypes[FUNC_MAX_ARGS];
741 
742  /*
743  * Parse the name and arguments, look up potential matches in the current
744  * namespace search list, and scan to see which one exactly matches the
745  * given argument types. (There will not be more than one match.)
746  */
747  parseNameAndArgTypes(opr_name_or_oid, true, &names, &nargs, argtypes);
748  if (nargs == 1)
749  ereport(ERROR,
750  (errcode(ERRCODE_UNDEFINED_PARAMETER),
751  errmsg("missing argument"),
752  errhint("Use NONE to denote the missing argument of a unary operator.")));
753  if (nargs != 2)
754  ereport(ERROR,
755  (errcode(ERRCODE_TOO_MANY_ARGUMENTS),
756  errmsg("too many arguments"),
757  errhint("Provide two argument types for operator.")));
758 
759  result = OpernameGetOprid(names, argtypes[0], argtypes[1]);
760 
761  if (!OidIsValid(result))
762  PG_RETURN_NULL();
763 
764  PG_RETURN_OID(result);
765 }
766 
767 /*
768  * format_operator_extended - converts operator OID to "opr_name(args)"
769  *
770  * This exports the useful functionality of regoperatorout for use
771  * in other backend modules. The result is a palloc'd string, or NULL.
772  *
773  * The following bits in 'flags' modify the behavior:
774  * - FORMAT_OPERATOR_INVALID_AS_NULL
775  * if the operator OID is invalid or unknown, return NULL instead
776  * of the numeric OID.
777  * - FORMAT_OPERATOR_FORCE_QUALIFY
778  * always schema-qualify operator names, regardless of search_path
779  */
780 char *
781 format_operator_extended(Oid operator_oid, bits16 flags)
782 {
783  char *result;
784  HeapTuple opertup;
785 
786  opertup = SearchSysCache1(OPEROID, ObjectIdGetDatum(operator_oid));
787 
788  if (HeapTupleIsValid(opertup))
789  {
790  Form_pg_operator operform = (Form_pg_operator) GETSTRUCT(opertup);
791  char *oprname = NameStr(operform->oprname);
792  char *nspname;
794 
795  /* XXX no support here for bootstrap mode */
797 
798  initStringInfo(&buf);
799 
800  /*
801  * Would this oper be found (given the right args) by regoperatorin?
802  * If not, or if caller explicitly requests it, we need to qualify it.
803  */
804  if ((flags & FORMAT_OPERATOR_FORCE_QUALIFY) != 0 ||
805  !OperatorIsVisible(operator_oid))
806  {
807  nspname = get_namespace_name(operform->oprnamespace);
808  appendStringInfo(&buf, "%s.",
809  quote_identifier(nspname));
810  }
811 
812  appendStringInfo(&buf, "%s(", oprname);
813 
814  if (operform->oprleft)
815  appendStringInfo(&buf, "%s,",
816  (flags & FORMAT_OPERATOR_FORCE_QUALIFY) != 0 ?
817  format_type_be_qualified(operform->oprleft) :
818  format_type_be(operform->oprleft));
819  else
820  appendStringInfoString(&buf, "NONE,");
821 
822  if (operform->oprright)
823  appendStringInfo(&buf, "%s)",
824  (flags & FORMAT_OPERATOR_FORCE_QUALIFY) != 0 ?
825  format_type_be_qualified(operform->oprright) :
826  format_type_be(operform->oprright));
827  else
828  appendStringInfoString(&buf, "NONE)");
829 
830  result = buf.data;
831 
832  ReleaseSysCache(opertup);
833  }
834  else if ((flags & FORMAT_OPERATOR_INVALID_AS_NULL) != 0)
835  {
836  /* If object is undefined, return NULL as wanted by caller */
837  result = NULL;
838  }
839  else
840  {
841  /*
842  * If OID doesn't match any pg_operator entry, return it numerically
843  */
844  result = (char *) palloc(NAMEDATALEN);
845  snprintf(result, NAMEDATALEN, "%u", operator_oid);
846  }
847 
848  return result;
849 }
850 
851 char *
852 format_operator(Oid operator_oid)
853 {
854  return format_operator_extended(operator_oid, 0);
855 }
856 
857 char *
859 {
860  return format_operator_extended(operator_oid,
862 }
863 
864 void
865 format_operator_parts(Oid operator_oid, List **objnames, List **objargs,
866  bool missing_ok)
867 {
868  HeapTuple opertup;
869  Form_pg_operator oprForm;
870 
871  opertup = SearchSysCache1(OPEROID, ObjectIdGetDatum(operator_oid));
872  if (!HeapTupleIsValid(opertup))
873  {
874  if (!missing_ok)
875  elog(ERROR, "cache lookup failed for operator with OID %u",
876  operator_oid);
877  return;
878  }
879 
880  oprForm = (Form_pg_operator) GETSTRUCT(opertup);
881  *objnames = list_make2(get_namespace_name_or_temp(oprForm->oprnamespace),
882  pstrdup(NameStr(oprForm->oprname)));
883  *objargs = NIL;
884  if (oprForm->oprleft)
885  *objargs = lappend(*objargs,
886  format_type_be_qualified(oprForm->oprleft));
887  if (oprForm->oprright)
888  *objargs = lappend(*objargs,
889  format_type_be_qualified(oprForm->oprright));
890 
891  ReleaseSysCache(opertup);
892 }
893 
894 /*
895  * regoperatorout - converts operator OID to "opr_name(args)"
896  */
897 Datum
899 {
900  Oid oprid = PG_GETARG_OID(0);
901  char *result;
902 
903  if (oprid == InvalidOid)
904  result = pstrdup("0");
905  else
906  result = format_operator(oprid);
907 
908  PG_RETURN_CSTRING(result);
909 }
910 
911 /*
912  * regoperatorrecv - converts external binary format to regoperator
913  */
914 Datum
916 {
917  /* Exactly the same as oidrecv, so share code */
918  return oidrecv(fcinfo);
919 }
920 
921 /*
922  * regoperatorsend - converts regoperator to binary format
923  */
924 Datum
926 {
927  /* Exactly the same as oidsend, so share code */
928  return oidsend(fcinfo);
929 }
930 
931 
932 /*
933  * regclassin - converts "classname" to class OID
934  *
935  * We also accept a numeric OID, for symmetry with the output routine.
936  *
937  * '-' signifies unknown (OID 0). In all other cases, the input must
938  * match an existing pg_class entry.
939  */
940 Datum
942 {
943  char *class_name_or_oid = PG_GETARG_CSTRING(0);
944  Oid result = InvalidOid;
945  List *names;
946 
947  /* '-' ? */
948  if (strcmp(class_name_or_oid, "-") == 0)
950 
951  /* Numeric OID? */
952  if (class_name_or_oid[0] >= '0' &&
953  class_name_or_oid[0] <= '9' &&
954  strspn(class_name_or_oid, "0123456789") == strlen(class_name_or_oid))
955  {
957  CStringGetDatum(class_name_or_oid)));
958  PG_RETURN_OID(result);
959  }
960 
961  /* Else it's a name, possibly schema-qualified */
962 
963  /* The rest of this wouldn't work in bootstrap mode */
965  elog(ERROR, "regclass values must be OIDs in bootstrap mode");
966 
967  /*
968  * Normal case: parse the name into components and see if it matches any
969  * pg_class entries in the current search path.
970  */
971  names = stringToQualifiedNameList(class_name_or_oid);
972 
973  /* We might not even have permissions on this relation; don't lock it. */
974  result = RangeVarGetRelid(makeRangeVarFromNameList(names), NoLock, false);
975 
976  PG_RETURN_OID(result);
977 }
978 
979 /*
980  * to_regclass - converts "classname" to class OID
981  *
982  * If the name is not found, we return NULL.
983  */
984 Datum
986 {
988  Oid result;
989  List *names;
990 
991  /*
992  * Parse the name into components and see if it matches any pg_class
993  * entries in the current search path.
994  */
995  names = stringToQualifiedNameList(class_name);
996 
997  /* We might not even have permissions on this relation; don't lock it. */
998  result = RangeVarGetRelid(makeRangeVarFromNameList(names), NoLock, true);
999 
1000  if (OidIsValid(result))
1001  PG_RETURN_OID(result);
1002  else
1003  PG_RETURN_NULL();
1004 }
1005 
1006 /*
1007  * regclassout - converts class OID to "class_name"
1008  */
1009 Datum
1011 {
1012  Oid classid = PG_GETARG_OID(0);
1013  char *result;
1014  HeapTuple classtup;
1015 
1016  if (classid == InvalidOid)
1017  {
1018  result = pstrdup("-");
1019  PG_RETURN_CSTRING(result);
1020  }
1021 
1022  classtup = SearchSysCache1(RELOID, ObjectIdGetDatum(classid));
1023 
1024  if (HeapTupleIsValid(classtup))
1025  {
1026  Form_pg_class classform = (Form_pg_class) GETSTRUCT(classtup);
1027  char *classname = NameStr(classform->relname);
1028 
1029  /*
1030  * In bootstrap mode, skip the fancy namespace stuff and just return
1031  * the class name. (This path is only needed for debugging output
1032  * anyway.)
1033  */
1035  result = pstrdup(classname);
1036  else
1037  {
1038  char *nspname;
1039 
1040  /*
1041  * Would this class be found by regclassin? If not, qualify it.
1042  */
1043  if (RelationIsVisible(classid))
1044  nspname = NULL;
1045  else
1046  nspname = get_namespace_name(classform->relnamespace);
1047 
1048  result = quote_qualified_identifier(nspname, classname);
1049  }
1050 
1051  ReleaseSysCache(classtup);
1052  }
1053  else
1054  {
1055  /* If OID doesn't match any pg_class entry, return it numerically */
1056  result = (char *) palloc(NAMEDATALEN);
1057  snprintf(result, NAMEDATALEN, "%u", classid);
1058  }
1059 
1060  PG_RETURN_CSTRING(result);
1061 }
1062 
1063 /*
1064  * regclassrecv - converts external binary format to regclass
1065  */
1066 Datum
1068 {
1069  /* Exactly the same as oidrecv, so share code */
1070  return oidrecv(fcinfo);
1071 }
1072 
1073 /*
1074  * regclasssend - converts regclass to binary format
1075  */
1076 Datum
1078 {
1079  /* Exactly the same as oidsend, so share code */
1080  return oidsend(fcinfo);
1081 }
1082 
1083 
1084 /*
1085  * regcollationin - converts "collationname" to collation OID
1086  *
1087  * We also accept a numeric OID, for symmetry with the output routine.
1088  *
1089  * '-' signifies unknown (OID 0). In all other cases, the input must
1090  * match an existing pg_collation entry.
1091  */
1092 Datum
1094 {
1095  char *collation_name_or_oid = PG_GETARG_CSTRING(0);
1096  Oid result = InvalidOid;
1097  List *names;
1098 
1099  /* '-' ? */
1100  if (strcmp(collation_name_or_oid, "-") == 0)
1102 
1103  /* Numeric OID? */
1104  if (collation_name_or_oid[0] >= '0' &&
1105  collation_name_or_oid[0] <= '9' &&
1106  strspn(collation_name_or_oid, "0123456789") == strlen(collation_name_or_oid))
1107  {
1109  CStringGetDatum(collation_name_or_oid)));
1110  PG_RETURN_OID(result);
1111  }
1112 
1113  /* Else it's a name, possibly schema-qualified */
1114 
1115  /* The rest of this wouldn't work in bootstrap mode */
1117  elog(ERROR, "regcollation values must be OIDs in bootstrap mode");
1118 
1119  /*
1120  * Normal case: parse the name into components and see if it matches any
1121  * pg_collation entries in the current search path.
1122  */
1123  names = stringToQualifiedNameList(collation_name_or_oid);
1124 
1125  result = get_collation_oid(names, false);
1126 
1127  PG_RETURN_OID(result);
1128 }
1129 
1130 /*
1131  * to_regcollation - converts "collationname" to collation OID
1132  *
1133  * If the name is not found, we return NULL.
1134  */
1135 Datum
1137 {
1138  char *collation_name = text_to_cstring(PG_GETARG_TEXT_PP(0));
1139  Oid result;
1140  List *names;
1141 
1142  /*
1143  * Parse the name into components and see if it matches any pg_collation
1144  * entries in the current search path.
1145  */
1146  names = stringToQualifiedNameList(collation_name);
1147 
1148  /* We might not even have permissions on this relation; don't lock it. */
1149  result = get_collation_oid(names, true);
1150 
1151  if (OidIsValid(result))
1152  PG_RETURN_OID(result);
1153  else
1154  PG_RETURN_NULL();
1155 }
1156 
1157 /*
1158  * regcollationout - converts collation OID to "collation_name"
1159  */
1160 Datum
1162 {
1163  Oid collationid = PG_GETARG_OID(0);
1164  char *result;
1165  HeapTuple collationtup;
1166 
1167  if (collationid == InvalidOid)
1168  {
1169  result = pstrdup("-");
1170  PG_RETURN_CSTRING(result);
1171  }
1172 
1173  collationtup = SearchSysCache1(COLLOID, ObjectIdGetDatum(collationid));
1174 
1175  if (HeapTupleIsValid(collationtup))
1176  {
1177  Form_pg_collation collationform = (Form_pg_collation) GETSTRUCT(collationtup);
1178  char *collationname = NameStr(collationform->collname);
1179 
1180  /*
1181  * In bootstrap mode, skip the fancy namespace stuff and just return
1182  * the collation name. (This path is only needed for debugging output
1183  * anyway.)
1184  */
1186  result = pstrdup(collationname);
1187  else
1188  {
1189  char *nspname;
1190 
1191  /*
1192  * Would this collation be found by regcollationin? If not,
1193  * qualify it.
1194  */
1195  if (CollationIsVisible(collationid))
1196  nspname = NULL;
1197  else
1198  nspname = get_namespace_name(collationform->collnamespace);
1199 
1200  result = quote_qualified_identifier(nspname, collationname);
1201  }
1202 
1203  ReleaseSysCache(collationtup);
1204  }
1205  else
1206  {
1207  /* If OID doesn't match any pg_collation entry, return it numerically */
1208  result = (char *) palloc(NAMEDATALEN);
1209  snprintf(result, NAMEDATALEN, "%u", collationid);
1210  }
1211 
1212  PG_RETURN_CSTRING(result);
1213 }
1214 
1215 /*
1216  * regcollationrecv - converts external binary format to regcollation
1217  */
1218 Datum
1220 {
1221  /* Exactly the same as oidrecv, so share code */
1222  return oidrecv(fcinfo);
1223 }
1224 
1225 /*
1226  * regcollationsend - converts regcollation to binary format
1227  */
1228 Datum
1230 {
1231  /* Exactly the same as oidsend, so share code */
1232  return oidsend(fcinfo);
1233 }
1234 
1235 
1236 /*
1237  * regtypein - converts "typename" to type OID
1238  *
1239  * The type name can be specified using the full type syntax recognized by
1240  * the parser; for example, DOUBLE PRECISION and INTEGER[] will work and be
1241  * translated to the correct type names. (We ignore any typmod info
1242  * generated by the parser, however.)
1243  *
1244  * We also accept a numeric OID, for symmetry with the output routine,
1245  * and for possible use in bootstrap mode.
1246  *
1247  * '-' signifies unknown (OID 0). In all other cases, the input must
1248  * match an existing pg_type entry.
1249  */
1250 Datum
1252 {
1253  char *typ_name_or_oid = PG_GETARG_CSTRING(0);
1254  Oid result = InvalidOid;
1255  int32 typmod;
1256 
1257  /* '-' ? */
1258  if (strcmp(typ_name_or_oid, "-") == 0)
1260 
1261  /* Numeric OID? */
1262  if (typ_name_or_oid[0] >= '0' &&
1263  typ_name_or_oid[0] <= '9' &&
1264  strspn(typ_name_or_oid, "0123456789") == strlen(typ_name_or_oid))
1265  {
1267  CStringGetDatum(typ_name_or_oid)));
1268  PG_RETURN_OID(result);
1269  }
1270 
1271  /* Else it's a type name, possibly schema-qualified or decorated */
1272 
1273  /* The rest of this wouldn't work in bootstrap mode */
1275  elog(ERROR, "regtype values must be OIDs in bootstrap mode");
1276 
1277  /*
1278  * Normal case: invoke the full parser to deal with special cases such as
1279  * array syntax.
1280  */
1281  parseTypeString(typ_name_or_oid, &result, &typmod, false);
1282 
1283  PG_RETURN_OID(result);
1284 }
1285 
1286 /*
1287  * to_regtype - converts "typename" to type OID
1288  *
1289  * If the name is not found, we return NULL.
1290  */
1291 Datum
1293 {
1294  char *typ_name = text_to_cstring(PG_GETARG_TEXT_PP(0));
1295  Oid result;
1296  int32 typmod;
1297 
1298  /*
1299  * Invoke the full parser to deal with special cases such as array syntax.
1300  */
1301  parseTypeString(typ_name, &result, &typmod, true);
1302 
1303  if (OidIsValid(result))
1304  PG_RETURN_OID(result);
1305  else
1306  PG_RETURN_NULL();
1307 }
1308 
1309 /*
1310  * regtypeout - converts type OID to "typ_name"
1311  */
1312 Datum
1314 {
1315  Oid typid = PG_GETARG_OID(0);
1316  char *result;
1317  HeapTuple typetup;
1318 
1319  if (typid == InvalidOid)
1320  {
1321  result = pstrdup("-");
1322  PG_RETURN_CSTRING(result);
1323  }
1324 
1325  typetup = SearchSysCache1(TYPEOID, ObjectIdGetDatum(typid));
1326 
1327  if (HeapTupleIsValid(typetup))
1328  {
1329  Form_pg_type typeform = (Form_pg_type) GETSTRUCT(typetup);
1330 
1331  /*
1332  * In bootstrap mode, skip the fancy namespace stuff and just return
1333  * the type name. (This path is only needed for debugging output
1334  * anyway.)
1335  */
1337  {
1338  char *typname = NameStr(typeform->typname);
1339 
1340  result = pstrdup(typname);
1341  }
1342  else
1343  result = format_type_be(typid);
1344 
1345  ReleaseSysCache(typetup);
1346  }
1347  else
1348  {
1349  /* If OID doesn't match any pg_type entry, return it numerically */
1350  result = (char *) palloc(NAMEDATALEN);
1351  snprintf(result, NAMEDATALEN, "%u", typid);
1352  }
1353 
1354  PG_RETURN_CSTRING(result);
1355 }
1356 
1357 /*
1358  * regtyperecv - converts external binary format to regtype
1359  */
1360 Datum
1362 {
1363  /* Exactly the same as oidrecv, so share code */
1364  return oidrecv(fcinfo);
1365 }
1366 
1367 /*
1368  * regtypesend - converts regtype to binary format
1369  */
1370 Datum
1372 {
1373  /* Exactly the same as oidsend, so share code */
1374  return oidsend(fcinfo);
1375 }
1376 
1377 
1378 /*
1379  * regconfigin - converts "tsconfigname" to tsconfig OID
1380  *
1381  * We also accept a numeric OID, for symmetry with the output routine.
1382  *
1383  * '-' signifies unknown (OID 0). In all other cases, the input must
1384  * match an existing pg_ts_config entry.
1385  */
1386 Datum
1388 {
1389  char *cfg_name_or_oid = PG_GETARG_CSTRING(0);
1390  Oid result;
1391  List *names;
1392 
1393  /* '-' ? */
1394  if (strcmp(cfg_name_or_oid, "-") == 0)
1396 
1397  /* Numeric OID? */
1398  if (cfg_name_or_oid[0] >= '0' &&
1399  cfg_name_or_oid[0] <= '9' &&
1400  strspn(cfg_name_or_oid, "0123456789") == strlen(cfg_name_or_oid))
1401  {
1403  CStringGetDatum(cfg_name_or_oid)));
1404  PG_RETURN_OID(result);
1405  }
1406 
1407  /* The rest of this wouldn't work in bootstrap mode */
1409  elog(ERROR, "regconfig values must be OIDs in bootstrap mode");
1410 
1411  /*
1412  * Normal case: parse the name into components and see if it matches any
1413  * pg_ts_config entries in the current search path.
1414  */
1415  names = stringToQualifiedNameList(cfg_name_or_oid);
1416 
1417  result = get_ts_config_oid(names, false);
1418 
1419  PG_RETURN_OID(result);
1420 }
1421 
1422 /*
1423  * regconfigout - converts tsconfig OID to "tsconfigname"
1424  */
1425 Datum
1427 {
1428  Oid cfgid = PG_GETARG_OID(0);
1429  char *result;
1430  HeapTuple cfgtup;
1431 
1432  if (cfgid == InvalidOid)
1433  {
1434  result = pstrdup("-");
1435  PG_RETURN_CSTRING(result);
1436  }
1437 
1438  cfgtup = SearchSysCache1(TSCONFIGOID, ObjectIdGetDatum(cfgid));
1439 
1440  if (HeapTupleIsValid(cfgtup))
1441  {
1442  Form_pg_ts_config cfgform = (Form_pg_ts_config) GETSTRUCT(cfgtup);
1443  char *cfgname = NameStr(cfgform->cfgname);
1444  char *nspname;
1445 
1446  /*
1447  * Would this config be found by regconfigin? If not, qualify it.
1448  */
1449  if (TSConfigIsVisible(cfgid))
1450  nspname = NULL;
1451  else
1452  nspname = get_namespace_name(cfgform->cfgnamespace);
1453 
1454  result = quote_qualified_identifier(nspname, cfgname);
1455 
1456  ReleaseSysCache(cfgtup);
1457  }
1458  else
1459  {
1460  /* If OID doesn't match any pg_ts_config row, return it numerically */
1461  result = (char *) palloc(NAMEDATALEN);
1462  snprintf(result, NAMEDATALEN, "%u", cfgid);
1463  }
1464 
1465  PG_RETURN_CSTRING(result);
1466 }
1467 
1468 /*
1469  * regconfigrecv - converts external binary format to regconfig
1470  */
1471 Datum
1473 {
1474  /* Exactly the same as oidrecv, so share code */
1475  return oidrecv(fcinfo);
1476 }
1477 
1478 /*
1479  * regconfigsend - converts regconfig to binary format
1480  */
1481 Datum
1483 {
1484  /* Exactly the same as oidsend, so share code */
1485  return oidsend(fcinfo);
1486 }
1487 
1488 
1489 /*
1490  * regdictionaryin - converts "tsdictionaryname" to tsdictionary OID
1491  *
1492  * We also accept a numeric OID, for symmetry with the output routine.
1493  *
1494  * '-' signifies unknown (OID 0). In all other cases, the input must
1495  * match an existing pg_ts_dict entry.
1496  */
1497 Datum
1499 {
1500  char *dict_name_or_oid = PG_GETARG_CSTRING(0);
1501  Oid result;
1502  List *names;
1503 
1504  /* '-' ? */
1505  if (strcmp(dict_name_or_oid, "-") == 0)
1507 
1508  /* Numeric OID? */
1509  if (dict_name_or_oid[0] >= '0' &&
1510  dict_name_or_oid[0] <= '9' &&
1511  strspn(dict_name_or_oid, "0123456789") == strlen(dict_name_or_oid))
1512  {
1514  CStringGetDatum(dict_name_or_oid)));
1515  PG_RETURN_OID(result);
1516  }
1517 
1518  /* The rest of this wouldn't work in bootstrap mode */
1520  elog(ERROR, "regdictionary values must be OIDs in bootstrap mode");
1521 
1522  /*
1523  * Normal case: parse the name into components and see if it matches any
1524  * pg_ts_dict entries in the current search path.
1525  */
1526  names = stringToQualifiedNameList(dict_name_or_oid);
1527 
1528  result = get_ts_dict_oid(names, false);
1529 
1530  PG_RETURN_OID(result);
1531 }
1532 
1533 /*
1534  * regdictionaryout - converts tsdictionary OID to "tsdictionaryname"
1535  */
1536 Datum
1538 {
1539  Oid dictid = PG_GETARG_OID(0);
1540  char *result;
1541  HeapTuple dicttup;
1542 
1543  if (dictid == InvalidOid)
1544  {
1545  result = pstrdup("-");
1546  PG_RETURN_CSTRING(result);
1547  }
1548 
1549  dicttup = SearchSysCache1(TSDICTOID, ObjectIdGetDatum(dictid));
1550 
1551  if (HeapTupleIsValid(dicttup))
1552  {
1553  Form_pg_ts_dict dictform = (Form_pg_ts_dict) GETSTRUCT(dicttup);
1554  char *dictname = NameStr(dictform->dictname);
1555  char *nspname;
1556 
1557  /*
1558  * Would this dictionary be found by regdictionaryin? If not, qualify
1559  * it.
1560  */
1561  if (TSDictionaryIsVisible(dictid))
1562  nspname = NULL;
1563  else
1564  nspname = get_namespace_name(dictform->dictnamespace);
1565 
1566  result = quote_qualified_identifier(nspname, dictname);
1567 
1568  ReleaseSysCache(dicttup);
1569  }
1570  else
1571  {
1572  /* If OID doesn't match any pg_ts_dict row, return it numerically */
1573  result = (char *) palloc(NAMEDATALEN);
1574  snprintf(result, NAMEDATALEN, "%u", dictid);
1575  }
1576 
1577  PG_RETURN_CSTRING(result);
1578 }
1579 
1580 /*
1581  * regdictionaryrecv - converts external binary format to regdictionary
1582  */
1583 Datum
1585 {
1586  /* Exactly the same as oidrecv, so share code */
1587  return oidrecv(fcinfo);
1588 }
1589 
1590 /*
1591  * regdictionarysend - converts regdictionary to binary format
1592  */
1593 Datum
1595 {
1596  /* Exactly the same as oidsend, so share code */
1597  return oidsend(fcinfo);
1598 }
1599 
1600 /*
1601  * regrolein - converts "rolename" to role OID
1602  *
1603  * We also accept a numeric OID, for symmetry with the output routine.
1604  *
1605  * '-' signifies unknown (OID 0). In all other cases, the input must
1606  * match an existing pg_authid entry.
1607  */
1608 Datum
1610 {
1611  char *role_name_or_oid = PG_GETARG_CSTRING(0);
1612  Oid result;
1613  List *names;
1614 
1615  /* '-' ? */
1616  if (strcmp(role_name_or_oid, "-") == 0)
1618 
1619  /* Numeric OID? */
1620  if (role_name_or_oid[0] >= '0' &&
1621  role_name_or_oid[0] <= '9' &&
1622  strspn(role_name_or_oid, "0123456789") == strlen(role_name_or_oid))
1623  {
1625  CStringGetDatum(role_name_or_oid)));
1626  PG_RETURN_OID(result);
1627  }
1628 
1629  /* The rest of this wouldn't work in bootstrap mode */
1631  elog(ERROR, "regrole values must be OIDs in bootstrap mode");
1632 
1633  /* Normal case: see if the name matches any pg_authid entry. */
1634  names = stringToQualifiedNameList(role_name_or_oid);
1635 
1636  if (list_length(names) != 1)
1637  ereport(ERROR,
1638  (errcode(ERRCODE_INVALID_NAME),
1639  errmsg("invalid name syntax")));
1640 
1641  result = get_role_oid(strVal(linitial(names)), false);
1642 
1643  PG_RETURN_OID(result);
1644 }
1645 
1646 /*
1647  * to_regrole - converts "rolename" to role OID
1648  *
1649  * If the name is not found, we return NULL.
1650  */
1651 Datum
1653 {
1654  char *role_name = text_to_cstring(PG_GETARG_TEXT_PP(0));
1655  Oid result;
1656  List *names;
1657 
1658  names = stringToQualifiedNameList(role_name);
1659 
1660  if (list_length(names) != 1)
1661  ereport(ERROR,
1662  (errcode(ERRCODE_INVALID_NAME),
1663  errmsg("invalid name syntax")));
1664 
1665  result = get_role_oid(strVal(linitial(names)), true);
1666 
1667  if (OidIsValid(result))
1668  PG_RETURN_OID(result);
1669  else
1670  PG_RETURN_NULL();
1671 }
1672 
1673 /*
1674  * regroleout - converts role OID to "role_name"
1675  */
1676 Datum
1678 {
1679  Oid roleoid = PG_GETARG_OID(0);
1680  char *result;
1681 
1682  if (roleoid == InvalidOid)
1683  {
1684  result = pstrdup("-");
1685  PG_RETURN_CSTRING(result);
1686  }
1687 
1688  result = GetUserNameFromId(roleoid, true);
1689 
1690  if (result)
1691  {
1692  /* pstrdup is not really necessary, but it avoids a compiler warning */
1693  result = pstrdup(quote_identifier(result));
1694  }
1695  else
1696  {
1697  /* If OID doesn't match any role, return it numerically */
1698  result = (char *) palloc(NAMEDATALEN);
1699  snprintf(result, NAMEDATALEN, "%u", roleoid);
1700  }
1701 
1702  PG_RETURN_CSTRING(result);
1703 }
1704 
1705 /*
1706  * regrolerecv - converts external binary format to regrole
1707  */
1708 Datum
1710 {
1711  /* Exactly the same as oidrecv, so share code */
1712  return oidrecv(fcinfo);
1713 }
1714 
1715 /*
1716  * regrolesend - converts regrole to binary format
1717  */
1718 Datum
1720 {
1721  /* Exactly the same as oidsend, so share code */
1722  return oidsend(fcinfo);
1723 }
1724 
1725 /*
1726  * regnamespacein - converts "nspname" to namespace OID
1727  *
1728  * We also accept a numeric OID, for symmetry with the output routine.
1729  *
1730  * '-' signifies unknown (OID 0). In all other cases, the input must
1731  * match an existing pg_namespace entry.
1732  */
1733 Datum
1735 {
1736  char *nsp_name_or_oid = PG_GETARG_CSTRING(0);
1737  Oid result;
1738  List *names;
1739 
1740  /* '-' ? */
1741  if (strcmp(nsp_name_or_oid, "-") == 0)
1743 
1744  /* Numeric OID? */
1745  if (nsp_name_or_oid[0] >= '0' &&
1746  nsp_name_or_oid[0] <= '9' &&
1747  strspn(nsp_name_or_oid, "0123456789") == strlen(nsp_name_or_oid))
1748  {
1750  CStringGetDatum(nsp_name_or_oid)));
1751  PG_RETURN_OID(result);
1752  }
1753 
1754  /* The rest of this wouldn't work in bootstrap mode */
1756  elog(ERROR, "regnamespace values must be OIDs in bootstrap mode");
1757 
1758  /* Normal case: see if the name matches any pg_namespace entry. */
1759  names = stringToQualifiedNameList(nsp_name_or_oid);
1760 
1761  if (list_length(names) != 1)
1762  ereport(ERROR,
1763  (errcode(ERRCODE_INVALID_NAME),
1764  errmsg("invalid name syntax")));
1765 
1766  result = get_namespace_oid(strVal(linitial(names)), false);
1767 
1768  PG_RETURN_OID(result);
1769 }
1770 
1771 /*
1772  * to_regnamespace - converts "nspname" to namespace OID
1773  *
1774  * If the name is not found, we return NULL.
1775  */
1776 Datum
1778 {
1779  char *nsp_name = text_to_cstring(PG_GETARG_TEXT_PP(0));
1780  Oid result;
1781  List *names;
1782 
1783  names = stringToQualifiedNameList(nsp_name);
1784 
1785  if (list_length(names) != 1)
1786  ereport(ERROR,
1787  (errcode(ERRCODE_INVALID_NAME),
1788  errmsg("invalid name syntax")));
1789 
1790  result = get_namespace_oid(strVal(linitial(names)), true);
1791 
1792  if (OidIsValid(result))
1793  PG_RETURN_OID(result);
1794  else
1795  PG_RETURN_NULL();
1796 }
1797 
1798 /*
1799  * regnamespaceout - converts namespace OID to "nsp_name"
1800  */
1801 Datum
1803 {
1804  Oid nspid = PG_GETARG_OID(0);
1805  char *result;
1806 
1807  if (nspid == InvalidOid)
1808  {
1809  result = pstrdup("-");
1810  PG_RETURN_CSTRING(result);
1811  }
1812 
1813  result = get_namespace_name(nspid);
1814 
1815  if (result)
1816  {
1817  /* pstrdup is not really necessary, but it avoids a compiler warning */
1818  result = pstrdup(quote_identifier(result));
1819  }
1820  else
1821  {
1822  /* If OID doesn't match any namespace, return it numerically */
1823  result = (char *) palloc(NAMEDATALEN);
1824  snprintf(result, NAMEDATALEN, "%u", nspid);
1825  }
1826 
1827  PG_RETURN_CSTRING(result);
1828 }
1829 
1830 /*
1831  * regnamespacerecv - converts external binary format to regnamespace
1832  */
1833 Datum
1835 {
1836  /* Exactly the same as oidrecv, so share code */
1837  return oidrecv(fcinfo);
1838 }
1839 
1840 /*
1841  * regnamespacesend - converts regnamespace to binary format
1842  */
1843 Datum
1845 {
1846  /* Exactly the same as oidsend, so share code */
1847  return oidsend(fcinfo);
1848 }
1849 
1850 /*
1851  * text_regclass: convert text to regclass
1852  *
1853  * This could be replaced by CoerceViaIO, except that we need to treat
1854  * text-to-regclass as an implicit cast to support legacy forms of nextval()
1855  * and related functions.
1856  */
1857 Datum
1859 {
1861  Oid result;
1862  RangeVar *rv;
1863 
1865 
1866  /* We might not even have permissions on this relation; don't lock it. */
1867  result = RangeVarGetRelid(rv, NoLock, false);
1868 
1869  PG_RETURN_OID(result);
1870 }
1871 
1872 
1873 /*
1874  * Given a C string, parse it into a qualified-name list.
1875  */
1876 List *
1877 stringToQualifiedNameList(const char *string)
1878 {
1879  char *rawname;
1880  List *result = NIL;
1881  List *namelist;
1882  ListCell *l;
1883 
1884  /* We need a modifiable copy of the input string. */
1885  rawname = pstrdup(string);
1886 
1887  if (!SplitIdentifierString(rawname, '.', &namelist))
1888  ereport(ERROR,
1889  (errcode(ERRCODE_INVALID_NAME),
1890  errmsg("invalid name syntax")));
1891 
1892  if (namelist == NIL)
1893  ereport(ERROR,
1894  (errcode(ERRCODE_INVALID_NAME),
1895  errmsg("invalid name syntax")));
1896 
1897  foreach(l, namelist)
1898  {
1899  char *curname = (char *) lfirst(l);
1900 
1901  result = lappend(result, makeString(pstrdup(curname)));
1902  }
1903 
1904  pfree(rawname);
1905  list_free(namelist);
1906 
1907  return result;
1908 }
1909 
1910 /*****************************************************************************
1911  * SUPPORT ROUTINES *
1912  *****************************************************************************/
1913 
1914 /*
1915  * Given a C string, parse it into a qualified function or operator name
1916  * followed by a parenthesized list of type names. Reduce the
1917  * type names to an array of OIDs (returned into *nargs and *argtypes;
1918  * the argtypes array should be of size FUNC_MAX_ARGS). The function or
1919  * operator name is returned to *names as a List of Strings.
1920  *
1921  * If allowNone is true, accept "NONE" and return it as InvalidOid (this is
1922  * for unary operators).
1923  */
1924 static void
1925 parseNameAndArgTypes(const char *string, bool allowNone, List **names,
1926  int *nargs, Oid *argtypes)
1927 {
1928  char *rawname;
1929  char *ptr;
1930  char *ptr2;
1931  char *typename;
1932  bool in_quote;
1933  bool had_comma;
1934  int paren_count;
1935  Oid typeid;
1936  int32 typmod;
1937 
1938  /* We need a modifiable copy of the input string. */
1939  rawname = pstrdup(string);
1940 
1941  /* Scan to find the expected left paren; mustn't be quoted */
1942  in_quote = false;
1943  for (ptr = rawname; *ptr; ptr++)
1944  {
1945  if (*ptr == '"')
1946  in_quote = !in_quote;
1947  else if (*ptr == '(' && !in_quote)
1948  break;
1949  }
1950  if (*ptr == '\0')
1951  ereport(ERROR,
1952  (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
1953  errmsg("expected a left parenthesis")));
1954 
1955  /* Separate the name and parse it into a list */
1956  *ptr++ = '\0';
1957  *names = stringToQualifiedNameList(rawname);
1958 
1959  /* Check for the trailing right parenthesis and remove it */
1960  ptr2 = ptr + strlen(ptr);
1961  while (--ptr2 > ptr)
1962  {
1963  if (!scanner_isspace(*ptr2))
1964  break;
1965  }
1966  if (*ptr2 != ')')
1967  ereport(ERROR,
1968  (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
1969  errmsg("expected a right parenthesis")));
1970 
1971  *ptr2 = '\0';
1972 
1973  /* Separate the remaining string into comma-separated type names */
1974  *nargs = 0;
1975  had_comma = false;
1976 
1977  for (;;)
1978  {
1979  /* allow leading whitespace */
1980  while (scanner_isspace(*ptr))
1981  ptr++;
1982  if (*ptr == '\0')
1983  {
1984  /* End of string. Okay unless we had a comma before. */
1985  if (had_comma)
1986  ereport(ERROR,
1987  (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
1988  errmsg("expected a type name")));
1989  break;
1990  }
1991  typename = ptr;
1992  /* Find end of type name --- end of string or comma */
1993  /* ... but not a quoted or parenthesized comma */
1994  in_quote = false;
1995  paren_count = 0;
1996  for (; *ptr; ptr++)
1997  {
1998  if (*ptr == '"')
1999  in_quote = !in_quote;
2000  else if (*ptr == ',' && !in_quote && paren_count == 0)
2001  break;
2002  else if (!in_quote)
2003  {
2004  switch (*ptr)
2005  {
2006  case '(':
2007  case '[':
2008  paren_count++;
2009  break;
2010  case ')':
2011  case ']':
2012  paren_count--;
2013  break;
2014  }
2015  }
2016  }
2017  if (in_quote || paren_count != 0)
2018  ereport(ERROR,
2019  (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
2020  errmsg("improper type name")));
2021 
2022  ptr2 = ptr;
2023  if (*ptr == ',')
2024  {
2025  had_comma = true;
2026  *ptr++ = '\0';
2027  }
2028  else
2029  {
2030  had_comma = false;
2031  Assert(*ptr == '\0');
2032  }
2033  /* Lop off trailing whitespace */
2034  while (--ptr2 >= typename)
2035  {
2036  if (!scanner_isspace(*ptr2))
2037  break;
2038  *ptr2 = '\0';
2039  }
2040 
2041  if (allowNone && pg_strcasecmp(typename, "none") == 0)
2042  {
2043  /* Special case for NONE */
2044  typeid = InvalidOid;
2045  typmod = -1;
2046  }
2047  else
2048  {
2049  /* Use full parser to resolve the type name */
2050  parseTypeString(typename, &typeid, &typmod, false);
2051  }
2052  if (*nargs >= FUNC_MAX_ARGS)
2053  ereport(ERROR,
2054  (errcode(ERRCODE_TOO_MANY_ARGUMENTS),
2055  errmsg("too many arguments")));
2056 
2057  argtypes[*nargs] = typeid;
2058  (*nargs)++;
2059  }
2060 
2061  pfree(rawname);
2062 }
#define list_make2(x1, x2)
Definition: pg_list.h:208
#define NIL
Definition: pg_list.h:65
Datum regoperatorrecv(PG_FUNCTION_ARGS)
Definition: regproc.c:915
Datum regnamespaceout(PG_FUNCTION_ARGS)
Definition: regproc.c:1802
Datum regoperatorin(PG_FUNCTION_ARGS)
Definition: regproc.c:674
Datum regconfigsend(PG_FUNCTION_ARGS)
Definition: regproc.c:1482
Oid get_namespace_oid(const char *nspname, bool missing_ok)
Definition: namespace.c:3088
int errhint(const char *fmt,...)
Definition: elog.c:1156
NameData proname
Definition: pg_proc.h:35
#define GETSTRUCT(TUP)
Definition: htup_details.h:654
Datum regclassin(PG_FUNCTION_ARGS)
Definition: regproc.c:941
Datum regcollationin(PG_FUNCTION_ARGS)
Definition: regproc.c:1093
const char * quote_identifier(const char *ident)
Definition: ruleutils.c:11374
FormData_pg_ts_config * Form_pg_ts_config
Definition: pg_ts_config.h:48
Oid oprid(Operator op)
Definition: parse_oper.c:250
uint16 bits16
Definition: c.h:449
Datum regroleout(PG_FUNCTION_ARGS)
Definition: regproc.c:1677
Datum regrolesend(PG_FUNCTION_ARGS)
Definition: regproc.c:1719
#define RangeVarGetRelid(relation, lockmode, missing_ok)
Definition: namespace.h:79
Datum regoperout(PG_FUNCTION_ARGS)
Definition: regproc.c:580
Datum regdictionaryout(PG_FUNCTION_ARGS)
Definition: regproc.c:1537
#define DatumGetObjectId(X)
Definition: postgres.h:544
char * pstrdup(const char *in)
Definition: mcxt.c:1299
Datum to_regrole(PG_FUNCTION_ARGS)
Definition: regproc.c:1652
regproc RegProcedure
Definition: c.h:585
Datum to_regcollation(PG_FUNCTION_ARGS)
Definition: regproc.c:1136
Datum regoperin(PG_FUNCTION_ARGS)
Definition: regproc.c:502
#define strVal(v)
Definition: value.h:65
int errcode(int sqlerrcode)
Definition: elog.c:698
Oid get_ts_config_oid(List *names, bool missing_ok)
Definition: namespace.c:2724
Datum regrolerecv(PG_FUNCTION_ARGS)
Definition: regproc.c:1709
bool OperatorIsVisible(Oid oprid)
Definition: namespace.c:1792
char * format_type_be(Oid type_oid)
Definition: format_type.c:339
String * makeString(char *str)
Definition: value.c:51
char * format_operator(Oid operator_oid)
Definition: regproc.c:852
Datum to_regoper(PG_FUNCTION_ARGS)
Definition: regproc.c:557
bool FunctionIsVisible(Oid funcid)
Definition: namespace.c:1458
RangeVar * makeRangeVarFromNameList(List *names)
Definition: namespace.c:3107
Datum regtypeout(PG_FUNCTION_ARGS)
Definition: regproc.c:1313
#define DirectFunctionCall1(func, arg1)
Definition: fmgr.h:626
int pg_strcasecmp(const char *s1, const char *s2)
Definition: pgstrcasecmp.c:36
NameData relname
Definition: pg_class.h:38
unsigned int Oid
Definition: postgres_ext.h:31
Datum regopersend(PG_FUNCTION_ARGS)
Definition: regproc.c:658
#define OidIsValid(objectId)
Definition: c.h:710
Datum regtyperecv(PG_FUNCTION_ARGS)
Definition: regproc.c:1361
Datum regprocin(PG_FUNCTION_ARGS)
Definition: regproc.c:61
char * format_operator_extended(Oid operator_oid, bits16 flags)
Definition: regproc.c:781
signed int int32
Definition: c.h:429
FuncCandidateList OpernameGetCandidates(List *names, char oprkind, bool missing_schema_ok)
Definition: namespace.c:1631
Datum oidsend(PG_FUNCTION_ARGS)
Definition: oid.c:151
#define PG_GETARG_TEXT_PP(n)
Definition: fmgr.h:309
Oid get_role_oid(const char *rolname, bool missing_ok)
Definition: acl.c:5094
Datum regconfigout(PG_FUNCTION_ARGS)
Definition: regproc.c:1426
#define FUNC_MAX_ARGS
#define list_make1(x1)
Definition: pg_list.h:206
#define NAMEDATALEN
Datum text_regclass(PG_FUNCTION_ARGS)
Definition: regproc.c:1858
Datum regprocedureout(PG_FUNCTION_ARGS)
Definition: regproc.c:459
Datum oidrecv(PG_FUNCTION_ARGS)
Definition: oid.c:140
#define sprintf
Definition: port.h:219
Oid OpernameGetOprid(List *names, Oid oprleft, Oid oprright)
Definition: namespace.c:1528
Oid get_ts_dict_oid(List *names, bool missing_ok)
Definition: namespace.c:2471
Oid args[FLEXIBLE_ARRAY_MEMBER]
Definition: namespace.h:38
void pfree(void *pointer)
Definition: mcxt.c:1169
void appendStringInfo(StringInfo str, const char *fmt,...)
Definition: stringinfo.c:91
#define linitial(l)
Definition: pg_list.h:174
#define ObjectIdGetDatum(X)
Definition: postgres.h:551
#define ERROR
Definition: elog.h:46
Datum regprocedurein(PG_FUNCTION_ARGS)
Definition: regproc.c:230
bool TSConfigIsVisible(Oid cfgid)
Definition: namespace.c:2782
Datum regproceduresend(PG_FUNCTION_ARGS)
Definition: regproc.c:486
char * format_operator_qualified(Oid operator_oid)
Definition: regproc.c:858
Datum to_regprocedure(PG_FUNCTION_ARGS)
Definition: regproc.c:290
Datum regprocout(PG_FUNCTION_ARGS)
Definition: regproc.c:142
FormData_pg_ts_dict * Form_pg_ts_dict
Definition: pg_ts_dict.h:52
void appendStringInfoString(StringInfo str, const char *s)
Definition: stringinfo.c:176
Datum regtypesend(PG_FUNCTION_ARGS)
Definition: regproc.c:1371
Datum to_regproc(PG_FUNCTION_ARGS)
Definition: regproc.c:119
char * get_namespace_name(Oid nspid)
Definition: lsyscache.c:3316
#define NoLock
Definition: lockdefs.h:34
static char * buf
Definition: pg_test_fsync.c:68
#define PG_GETARG_OID(n)
Definition: fmgr.h:275
bool SplitIdentifierString(char *rawstring, char separator, List **namelist)
Definition: varlena.c:3746
Datum regclasssend(PG_FUNCTION_ARGS)
Definition: regproc.c:1077
#define CStringGetDatum(X)
Definition: postgres.h:622
Datum regrolein(PG_FUNCTION_ARGS)
Definition: regproc.c:1609
Datum regprocrecv(PG_FUNCTION_ARGS)
Definition: regproc.c:204
bool CollationIsVisible(Oid collid)
Definition: namespace.c:2093
Datum regdictionarysend(PG_FUNCTION_ARGS)
Definition: regproc.c:1594
Datum regprocsend(PG_FUNCTION_ARGS)
Definition: regproc.c:214
struct _FuncCandidateList * next
Definition: namespace.h:30
char * format_procedure_qualified(Oid procedure_oid)
Definition: regproc.c:329
Datum to_regtype(PG_FUNCTION_ARGS)
Definition: regproc.c:1292
List * textToQualifiedNameList(text *textval)
Definition: varlena.c:3688
List * lappend(List *list, void *datum)
Definition: list.c:336
NameData typname
Definition: pg_type.h:41
Datum regcollationout(PG_FUNCTION_ARGS)
Definition: regproc.c:1161
void appendStringInfoChar(StringInfo str, char ch)
Definition: stringinfo.c:188
void initStringInfo(StringInfo str)
Definition: stringinfo.c:59
bool TSDictionaryIsVisible(Oid dictId)
Definition: namespace.c:2529
char * quote_qualified_identifier(const char *qualifier, const char *ident)
Definition: ruleutils.c:11458
FuncCandidateList FuncnameGetCandidates(List *names, int nargs, List *argnames, bool expand_variadic, bool expand_defaults, bool include_out_arguments, bool missing_ok)
Definition: namespace.c:950
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:1127
Datum regtypein(PG_FUNCTION_ARGS)
Definition: regproc.c:1251
#define FORMAT_OPERATOR_INVALID_AS_NULL
Definition: regproc.h:24
uintptr_t Datum
Definition: postgres.h:411
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1175
char * format_procedure_extended(Oid procedure_oid, bits16 flags)
Definition: regproc.c:350
bool scanner_isspace(char ch)
Definition: scansup.c:117
FormData_pg_proc * Form_pg_proc
Definition: pg_proc.h:136
void parseTypeString(const char *str, Oid *typeid_p, int32 *typmod_p, bool missing_ok)
Definition: parse_type.c:782
void format_procedure_parts(Oid procedure_oid, List **objnames, List **objargs, bool missing_ok)
Definition: regproc.c:422
#define InvalidOid
Definition: postgres_ext.h:36
#define ereport(elevel,...)
Definition: elog.h:157
char * format_procedure(Oid procedure_oid)
Definition: regproc.c:323
#define FORMAT_PROC_INVALID_AS_NULL
Definition: regproc.h:19
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
char * GetUserNameFromId(Oid roleid, bool noerr)
Definition: miscinit.c:910
#define Assert(condition)
Definition: c.h:804
#define lfirst(lc)
Definition: pg_list.h:169
static void parseNameAndArgTypes(const char *string, bool allowNone, List **names, int *nargs, Oid *argtypes)
Definition: regproc.c:1925
Datum regclassout(PG_FUNCTION_ARGS)
Definition: regproc.c:1010
char * format_type_be_qualified(Oid type_oid)
Definition: format_type.c:349
#define PG_RETURN_CSTRING(x)
Definition: fmgr.h:362
const char * class_name
Definition: selinux.c:32
FormData_pg_type * Form_pg_type
Definition: pg_type.h:261
static int list_length(const List *l)
Definition: pg_list.h:149
Datum regnamespacesend(PG_FUNCTION_ARGS)
Definition: regproc.c:1844
Datum to_regnamespace(PG_FUNCTION_ARGS)
Definition: regproc.c:1777
FormData_pg_operator * Form_pg_operator
Definition: pg_operator.h:83
Datum regprocedurerecv(PG_FUNCTION_ARGS)
Definition: regproc.c:476
FormData_pg_collation * Form_pg_collation
Definition: pg_collation.h:56
#define IsBootstrapProcessingMode()
Definition: miscadmin.h:406
FormData_pg_class * Form_pg_class
Definition: pg_class.h:153
char * text_to_cstring(const text *t)
Definition: varlena.c:222
#define FORMAT_PROC_FORCE_QUALIFY
Definition: regproc.h:20
List * stringToQualifiedNameList(const char *string)
Definition: regproc.c:1877
Datum regdictionaryin(PG_FUNCTION_ARGS)
Definition: regproc.c:1498
Datum regnamespacerecv(PG_FUNCTION_ARGS)
Definition: regproc.c:1834
void format_operator_parts(Oid operator_oid, List **objnames, List **objargs, bool missing_ok)
Definition: regproc.c:865
void * palloc(Size size)
Definition: mcxt.c:1062
int errmsg(const char *fmt,...)
Definition: elog.c:909
bool RelationIsVisible(Oid relid)
Definition: namespace.c:709
char * get_namespace_name_or_temp(Oid nspid)
Definition: lsyscache.c:3340
void list_free(List *list)
Definition: list.c:1391
#define elog(elevel,...)
Definition: elog.h:232
Datum regoperatorout(PG_FUNCTION_ARGS)
Definition: regproc.c:898
int i
#define NameStr(name)
Definition: c.h:681
Datum to_regoperator(PG_FUNCTION_ARGS)
Definition: regproc.c:734
#define PG_GETARG_CSTRING(n)
Definition: fmgr.h:277
Definition: c.h:621
#define PG_FUNCTION_ARGS
Definition: fmgr.h:193
Datum oidin(PG_FUNCTION_ARGS)
Definition: oid.c:117
Datum regconfigrecv(PG_FUNCTION_ARGS)
Definition: regproc.c:1472
Datum regdictionaryrecv(PG_FUNCTION_ARGS)
Definition: regproc.c:1584
Datum regoperrecv(PG_FUNCTION_ARGS)
Definition: regproc.c:648
Datum regnamespacein(PG_FUNCTION_ARGS)
Definition: regproc.c:1734
Datum regconfigin(PG_FUNCTION_ARGS)
Definition: regproc.c:1387
Datum regcollationsend(PG_FUNCTION_ARGS)
Definition: regproc.c:1229
Oid get_collation_oid(List *name, bool missing_ok)
Definition: namespace.c:3646
Definition: pg_list.h:50
#define PG_RETURN_OID(x)
Definition: fmgr.h:360
#define snprintf
Definition: port.h:217
Datum regoperatorsend(PG_FUNCTION_ARGS)
Definition: regproc.c:925
#define PG_RETURN_NULL()
Definition: fmgr.h:345
#define FORMAT_OPERATOR_FORCE_QUALIFY
Definition: regproc.h:25
Datum to_regclass(PG_FUNCTION_ARGS)
Definition: regproc.c:985
Datum regcollationrecv(PG_FUNCTION_ARGS)
Definition: regproc.c:1219
Datum regclassrecv(PG_FUNCTION_ARGS)
Definition: regproc.c:1067