LCOV - differential code coverage report
Current view: top level - src/backend/utils/adt - regproc.c (source / functions) Coverage Total Hit UNC LBC UIC UBC GBC GIC GNC CBC EUB ECB DUB DCB
Current: Differential Code Coverage HEAD vs 15 Lines: 76.6 % 625 479 18 30 87 11 29 259 118 73 83 305 23 71
Current Date: 2023-04-08 17:13:01 Functions: 63.6 % 66 42 24 39 3 17 39 7 3
Baseline: 15 Line coverage date bins:
Baseline Date: 2023-04-08 15:09:40 (60,120] days: 87.0 % 138 120 18 2 118
Legend: Lines: hit not hit (240..) days: 73.7 % 487 359 30 87 11 29 257 73 83 305
Function coverage date bins:
(60,120] days: 100.0 % 3 3 3
(240..) days: 32.8 % 119 39 24 39 17 39

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

Generated by: LCOV version v1.16-55-g56c0a2a