PostgreSQL Source Code: src/backend/utils/adt/regproc.c Source File

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

AltStyle によって変換されたページ (->オリジナル) /