]> git.ipfire.org Git - thirdparty/postgresql.git/commitdiff
Make the numeric-OID cases of regprocin and friends be non-throwing.
authorTom Lane <tgl@sss.pgh.pa.us>
Sat, 24 Dec 2022 20:01:21 +0000 (15:01 -0500)
committerTom Lane <tgl@sss.pgh.pa.us>
Sat, 24 Dec 2022 20:01:21 +0000 (15:01 -0500)
While at it, use a common subroutine already.

This doesn't move the needle very far in terms of making these
functions non-throwing; the only case we're now able to trap is
numeric-OID-is-out-of-range.  Still, it seems like a pretty
non-controversial step in that direction.

src/backend/utils/adt/regproc.c

index 6d4c1c27a575f4351e6ee72905754da13c28c75b..a6d695d6cbfa392a29c79f4d143cd4169aa8dae8 100644 (file)
@@ -41,6 +41,8 @@
 #include "utils/syscache.h"
 #include "utils/varlena.h"
 
+static bool parseNumericOid(char *string, Oid *result, Node *escontext);
+static bool parseDashOrOid(char *string, Oid *result, Node *escontext);
 static void parseNameAndArgTypes(const char *string, bool allowNone,
                                                                 List **names, int *nargs, Oid *argtypes);
 
@@ -61,23 +63,13 @@ Datum
 regprocin(PG_FUNCTION_ARGS)
 {
        char       *pro_name_or_oid = PG_GETARG_CSTRING(0);
-       RegProcedure result = InvalidOid;
+       RegProcedure result;
        List       *names;
        FuncCandidateList clist;
 
-       /* '-' ? */
-       if (strcmp(pro_name_or_oid, "-") == 0)
-               PG_RETURN_OID(InvalidOid);
-
-       /* Numeric OID? */
-       if (pro_name_or_oid[0] >= '0' &&
-               pro_name_or_oid[0] <= '9' &&
-               strspn(pro_name_or_oid, "0123456789") == strlen(pro_name_or_oid))
-       {
-               result = DatumGetObjectId(DirectFunctionCall1(oidin,
-                                                                                                         CStringGetDatum(pro_name_or_oid)));
+       /* Handle "-" or numeric OID */
+       if (parseDashOrOid(pro_name_or_oid, &result, fcinfo->context))
                PG_RETURN_OID(result);
-       }
 
        /* Else it's a name, possibly schema-qualified */
 
@@ -230,25 +222,15 @@ Datum
 regprocedurein(PG_FUNCTION_ARGS)
 {
        char       *pro_name_or_oid = PG_GETARG_CSTRING(0);
-       RegProcedure result = InvalidOid;
+       RegProcedure result;
        List       *names;
        int                     nargs;
        Oid                     argtypes[FUNC_MAX_ARGS];
        FuncCandidateList clist;
 
-       /* '-' ? */
-       if (strcmp(pro_name_or_oid, "-") == 0)
-               PG_RETURN_OID(InvalidOid);
-
-       /* Numeric OID? */
-       if (pro_name_or_oid[0] >= '0' &&
-               pro_name_or_oid[0] <= '9' &&
-               strspn(pro_name_or_oid, "0123456789") == strlen(pro_name_or_oid))
-       {
-               result = DatumGetObjectId(DirectFunctionCall1(oidin,
-                                                                                                         CStringGetDatum(pro_name_or_oid)));
+       /* Handle "-" or numeric OID */
+       if (parseDashOrOid(pro_name_or_oid, &result, fcinfo->context))
                PG_RETURN_OID(result);
-       }
 
        /* The rest of this wouldn't work in bootstrap mode */
        if (IsBootstrapProcessingMode())
@@ -502,23 +484,13 @@ Datum
 regoperin(PG_FUNCTION_ARGS)
 {
        char       *opr_name_or_oid = PG_GETARG_CSTRING(0);
-       Oid                     result = InvalidOid;
+       Oid                     result;
        List       *names;
        FuncCandidateList clist;
 
-       /* '0' ? */
-       if (strcmp(opr_name_or_oid, "0") == 0)
-               PG_RETURN_OID(InvalidOid);
-
-       /* Numeric OID? */
-       if (opr_name_or_oid[0] >= '0' &&
-               opr_name_or_oid[0] <= '9' &&
-               strspn(opr_name_or_oid, "0123456789") == strlen(opr_name_or_oid))
-       {
-               result = DatumGetObjectId(DirectFunctionCall1(oidin,
-                                                                                                         CStringGetDatum(opr_name_or_oid)));
+       /* Handle "0" or numeric OID */
+       if (parseNumericOid(opr_name_or_oid, &result, fcinfo->context))
                PG_RETURN_OID(result);
-       }
 
        /* Else it's a name, possibly schema-qualified */
 
@@ -679,19 +651,9 @@ regoperatorin(PG_FUNCTION_ARGS)
        int                     nargs;
        Oid                     argtypes[FUNC_MAX_ARGS];
 
-       /* '0' ? */
-       if (strcmp(opr_name_or_oid, "0") == 0)
-               PG_RETURN_OID(InvalidOid);
-
-       /* Numeric OID? */
-       if (opr_name_or_oid[0] >= '0' &&
-               opr_name_or_oid[0] <= '9' &&
-               strspn(opr_name_or_oid, "0123456789") == strlen(opr_name_or_oid))
-       {
-               result = DatumGetObjectId(DirectFunctionCall1(oidin,
-                                                                                                         CStringGetDatum(opr_name_or_oid)));
+       /* Handle "0" or numeric OID */
+       if (parseNumericOid(opr_name_or_oid, &result, fcinfo->context))
                PG_RETURN_OID(result);
-       }
 
        /* The rest of this wouldn't work in bootstrap mode */
        if (IsBootstrapProcessingMode())
@@ -941,22 +903,12 @@ Datum
 regclassin(PG_FUNCTION_ARGS)
 {
        char       *class_name_or_oid = PG_GETARG_CSTRING(0);
-       Oid                     result = InvalidOid;
+       Oid                     result;
        List       *names;
 
-       /* '-' ? */
-       if (strcmp(class_name_or_oid, "-") == 0)
-               PG_RETURN_OID(InvalidOid);
-
-       /* Numeric OID? */
-       if (class_name_or_oid[0] >= '0' &&
-               class_name_or_oid[0] <= '9' &&
-               strspn(class_name_or_oid, "0123456789") == strlen(class_name_or_oid))
-       {
-               result = DatumGetObjectId(DirectFunctionCall1(oidin,
-                                                                                                         CStringGetDatum(class_name_or_oid)));
+       /* Handle "-" or numeric OID */
+       if (parseDashOrOid(class_name_or_oid, &result, fcinfo->context))
                PG_RETURN_OID(result);
-       }
 
        /* Else it's a name, possibly schema-qualified */
 
@@ -1093,22 +1045,12 @@ Datum
 regcollationin(PG_FUNCTION_ARGS)
 {
        char       *collation_name_or_oid = PG_GETARG_CSTRING(0);
-       Oid                     result = InvalidOid;
+       Oid                     result;
        List       *names;
 
-       /* '-' ? */
-       if (strcmp(collation_name_or_oid, "-") == 0)
-               PG_RETURN_OID(InvalidOid);
-
-       /* Numeric OID? */
-       if (collation_name_or_oid[0] >= '0' &&
-               collation_name_or_oid[0] <= '9' &&
-               strspn(collation_name_or_oid, "0123456789") == strlen(collation_name_or_oid))
-       {
-               result = DatumGetObjectId(DirectFunctionCall1(oidin,
-                                                                                                         CStringGetDatum(collation_name_or_oid)));
+       /* Handle "-" or numeric OID */
+       if (parseDashOrOid(collation_name_or_oid, &result, fcinfo->context))
                PG_RETURN_OID(result);
-       }
 
        /* Else it's a name, possibly schema-qualified */
 
@@ -1145,7 +1087,6 @@ to_regcollation(PG_FUNCTION_ARGS)
         */
        names = stringToQualifiedNameList(collation_name);
 
-       /* We might not even have permissions on this relation; don't lock it. */
        result = get_collation_oid(names, true);
 
        if (OidIsValid(result))
@@ -1251,22 +1192,12 @@ Datum
 regtypein(PG_FUNCTION_ARGS)
 {
        char       *typ_name_or_oid = PG_GETARG_CSTRING(0);
-       Oid                     result = InvalidOid;
+       Oid                     result;
        int32           typmod;
 
-       /* '-' ? */
-       if (strcmp(typ_name_or_oid, "-") == 0)
-               PG_RETURN_OID(InvalidOid);
-
-       /* Numeric OID? */
-       if (typ_name_or_oid[0] >= '0' &&
-               typ_name_or_oid[0] <= '9' &&
-               strspn(typ_name_or_oid, "0123456789") == strlen(typ_name_or_oid))
-       {
-               result = DatumGetObjectId(DirectFunctionCall1(oidin,
-                                                                                                         CStringGetDatum(typ_name_or_oid)));
+       /* Handle "-" or numeric OID */
+       if (parseDashOrOid(typ_name_or_oid, &result, fcinfo->context))
                PG_RETURN_OID(result);
-       }
 
        /* Else it's a type name, possibly schema-qualified or decorated */
 
@@ -1390,19 +1321,9 @@ regconfigin(PG_FUNCTION_ARGS)
        Oid                     result;
        List       *names;
 
-       /* '-' ? */
-       if (strcmp(cfg_name_or_oid, "-") == 0)
-               PG_RETURN_OID(InvalidOid);
-
-       /* Numeric OID? */
-       if (cfg_name_or_oid[0] >= '0' &&
-               cfg_name_or_oid[0] <= '9' &&
-               strspn(cfg_name_or_oid, "0123456789") == strlen(cfg_name_or_oid))
-       {
-               result = DatumGetObjectId(DirectFunctionCall1(oidin,
-                                                                                                         CStringGetDatum(cfg_name_or_oid)));
+       /* Handle "-" or numeric OID */
+       if (parseDashOrOid(cfg_name_or_oid, &result, fcinfo->context))
                PG_RETURN_OID(result);
-       }
 
        /* The rest of this wouldn't work in bootstrap mode */
        if (IsBootstrapProcessingMode())
@@ -1501,19 +1422,9 @@ regdictionaryin(PG_FUNCTION_ARGS)
        Oid                     result;
        List       *names;
 
-       /* '-' ? */
-       if (strcmp(dict_name_or_oid, "-") == 0)
-               PG_RETURN_OID(InvalidOid);
-
-       /* Numeric OID? */
-       if (dict_name_or_oid[0] >= '0' &&
-               dict_name_or_oid[0] <= '9' &&
-               strspn(dict_name_or_oid, "0123456789") == strlen(dict_name_or_oid))
-       {
-               result = DatumGetObjectId(DirectFunctionCall1(oidin,
-                                                                                                         CStringGetDatum(dict_name_or_oid)));
+       /* Handle "-" or numeric OID */
+       if (parseDashOrOid(dict_name_or_oid, &result, fcinfo->context))
                PG_RETURN_OID(result);
-       }
 
        /* The rest of this wouldn't work in bootstrap mode */
        if (IsBootstrapProcessingMode())
@@ -1612,19 +1523,9 @@ regrolein(PG_FUNCTION_ARGS)
        Oid                     result;
        List       *names;
 
-       /* '-' ? */
-       if (strcmp(role_name_or_oid, "-") == 0)
-               PG_RETURN_OID(InvalidOid);
-
-       /* Numeric OID? */
-       if (role_name_or_oid[0] >= '0' &&
-               role_name_or_oid[0] <= '9' &&
-               strspn(role_name_or_oid, "0123456789") == strlen(role_name_or_oid))
-       {
-               result = DatumGetObjectId(DirectFunctionCall1(oidin,
-                                                                                                         CStringGetDatum(role_name_or_oid)));
+       /* Handle "-" or numeric OID */
+       if (parseDashOrOid(role_name_or_oid, &result, fcinfo->context))
                PG_RETURN_OID(result);
-       }
 
        /* The rest of this wouldn't work in bootstrap mode */
        if (IsBootstrapProcessingMode())
@@ -1737,19 +1638,9 @@ regnamespacein(PG_FUNCTION_ARGS)
        Oid                     result;
        List       *names;
 
-       /* '-' ? */
-       if (strcmp(nsp_name_or_oid, "-") == 0)
-               PG_RETURN_OID(InvalidOid);
-
-       /* Numeric OID? */
-       if (nsp_name_or_oid[0] >= '0' &&
-               nsp_name_or_oid[0] <= '9' &&
-               strspn(nsp_name_or_oid, "0123456789") == strlen(nsp_name_or_oid))
-       {
-               result = DatumGetObjectId(DirectFunctionCall1(oidin,
-                                                                                                         CStringGetDatum(nsp_name_or_oid)));
+       /* Handle "-" or numeric OID */
+       if (parseDashOrOid(nsp_name_or_oid, &result, fcinfo->context))
                PG_RETURN_OID(result);
-       }
 
        /* The rest of this wouldn't work in bootstrap mode */
        if (IsBootstrapProcessingMode())
@@ -1911,6 +1802,53 @@ stringToQualifiedNameList(const char *string)
  *      SUPPORT ROUTINES                                                                                                                *
  *****************************************************************************/
 
+/*
+ * Given a C string, see if it is all-digits (and not empty).
+ * If so, convert directly to OID and return true.
+ * If it is not all-digits, return false.
+ *
+ * If escontext is an ErrorSaveContext node, any error in oidin() will be
+ * reported there instead of being thrown (but we still return true).
+ */
+static bool
+parseNumericOid(char *string, Oid *result, Node *escontext)
+{
+       if (string[0] >= '0' && string[0] <= '9' &&
+               strspn(string, "0123456789") == strlen(string))
+       {
+               Datum           oid_datum;
+
+               /* We need not care here whether oidin() fails or not. */
+               (void) DirectInputFunctionCallSafe(oidin, string,
+                                                                                  InvalidOid, -1,
+                                                                                  escontext,
+                                                                                  &oid_datum);
+               *result = DatumGetObjectId(oid_datum);
+               return true;
+       }
+
+       /* Prevent uninitialized-variable warnings from stupider compilers. */
+       *result = InvalidOid;
+       return false;
+}
+
+/*
+ * As above, but also accept "-" as meaning 0 (InvalidOid).
+ */
+static bool
+parseDashOrOid(char *string, Oid *result, Node *escontext)
+{
+       /* '-' ? */
+       if (strcmp(string, "-") == 0)
+       {
+               *result = InvalidOid;
+               return true;
+       }
+
+       /* Numeric OID? */
+       return parseNumericOid(string, result, escontext);
+}
+
 /*
  * Given a C string, parse it into a qualified function or operator name
  * followed by a parenthesized list of type names.  Reduce the