Simplify the implementations of the to_reg* functions.
authorTom Lane <tgl@sss.pgh.pa.us>
Tue, 27 Dec 2022 17:33:04 +0000 (12:33 -0500)
committerTom Lane <tgl@sss.pgh.pa.us>
Tue, 27 Dec 2022 17:33:04 +0000 (12:33 -0500)
Given the soft-input-error feature, we can reduce these functions
to be just thin wrappers around a soft-error call of the
corresponding datatype input function.  This means less code and
more certainty that the to_reg* functions match the normal input
behavior.

Notably, it also means that they will accept numeric OID input,
which they didn't before.  It's not clear to me if that omission
had more than laziness behind it, but it doesn't seem like
something we need to work hard to preserve.

Discussion: https://postgr.es/m/3910031.1672095600@sss.pgh.pa.us

doc/src/sgml/func.sgml
src/backend/utils/adt/regproc.c

index 836b9254fbc845f69eb1365cb630557224365335..3bf8d021c3c2a5e664194ed62991551aa84a4857 100644 (file)
@@ -24100,8 +24100,7 @@ SELECT collation for ('foo' COLLATE "de_DE");
         obtained by casting the string to type <type>regclass</type> (see
         <xref linkend="datatype-oid"/>); however, this function will return
         <literal>NULL</literal> rather than throwing an error if the name is
-        not found.  Also unlike the cast, this does not accept
-        a numeric OID as input.
+        not found.
        </para></entry>
       </row>
 
@@ -24118,8 +24117,7 @@ SELECT collation for ('foo' COLLATE "de_DE");
         obtained by casting the string to type <type>regcollation</type> (see
         <xref linkend="datatype-oid"/>); however, this function will return
         <literal>NULL</literal> rather than throwing an error if the name is
-        not found.  Also unlike the cast, this does not accept
-        a numeric OID as input.
+        not found.
        </para></entry>
       </row>
 
@@ -24136,8 +24134,7 @@ SELECT collation for ('foo' COLLATE "de_DE");
         obtained by casting the string to type <type>regnamespace</type> (see
         <xref linkend="datatype-oid"/>); however, this function will return
         <literal>NULL</literal> rather than throwing an error if the name is
-        not found.  Also unlike the cast, this does not accept
-        a numeric OID as input.
+        not found.
        </para></entry>
       </row>
 
@@ -24154,8 +24151,7 @@ SELECT collation for ('foo' COLLATE "de_DE");
         obtained by casting the string to type <type>regoper</type> (see
         <xref linkend="datatype-oid"/>); however, this function will return
         <literal>NULL</literal> rather than throwing an error if the name is
-        not found or is ambiguous.  Also unlike the cast, this does not accept
-        a numeric OID as input.
+        not found or is ambiguous.
        </para></entry>
       </row>
 
@@ -24172,8 +24168,7 @@ SELECT collation for ('foo' COLLATE "de_DE");
         obtained by casting the string to type <type>regoperator</type> (see
         <xref linkend="datatype-oid"/>); however, this function will return
         <literal>NULL</literal> rather than throwing an error if the name is
-        not found.  Also unlike the cast, this does not accept
-        a numeric OID as input.
+        not found.
        </para></entry>
       </row>
 
@@ -24190,8 +24185,7 @@ SELECT collation for ('foo' COLLATE "de_DE");
         obtained by casting the string to type <type>regproc</type> (see
         <xref linkend="datatype-oid"/>); however, this function will return
         <literal>NULL</literal> rather than throwing an error if the name is
-        not found or is ambiguous.  Also unlike the cast, this does not accept
-        a numeric OID as input.
+        not found or is ambiguous.
        </para></entry>
       </row>
 
@@ -24208,8 +24202,7 @@ SELECT collation for ('foo' COLLATE "de_DE");
         obtained by casting the string to type <type>regprocedure</type> (see
         <xref linkend="datatype-oid"/>); however, this function will return
         <literal>NULL</literal> rather than throwing an error if the name is
-        not found.  Also unlike the cast, this does not accept
-        a numeric OID as input.
+        not found.
        </para></entry>
       </row>
 
@@ -24226,8 +24219,7 @@ SELECT collation for ('foo' COLLATE "de_DE");
         obtained by casting the string to type <type>regrole</type> (see
         <xref linkend="datatype-oid"/>); however, this function will return
         <literal>NULL</literal> rather than throwing an error if the name is
-        not found.  Also unlike the cast, this does not accept
-        a numeric OID as input.
+        not found.
        </para></entry>
       </row>
 
@@ -24244,8 +24236,7 @@ SELECT collation for ('foo' COLLATE "de_DE");
         obtained by casting the string to type <type>regtype</type> (see
         <xref linkend="datatype-oid"/>); however, this function will return
         <literal>NULL</literal> rather than throwing an error if the name is
-        not found.  Also unlike the cast, this does not accept
-        a numeric OID as input.
+        not found.
        </para></entry>
       </row>
      </tbody>
index 14d76c856d7995365bdf2c683aa9cea510967791..3635a946330ad6b4a22df7049466b16b97e250e4 100644 (file)
@@ -118,24 +118,15 @@ Datum
 to_regproc(PG_FUNCTION_ARGS)
 {
    char       *pro_name = text_to_cstring(PG_GETARG_TEXT_PP(0));
-   List       *names;
-   FuncCandidateList clist;
+   Datum       result;
    ErrorSaveContext escontext = {T_ErrorSaveContext};
 
-   /*
-    * Parse the name into components and see if it matches any pg_proc
-    * entries in the current search path.
-    */
-   names = stringToQualifiedNameList(pro_name, (Node *) &escontext);
-   if (names == NIL)
-       PG_RETURN_NULL();
-
-   clist = FuncnameGetCandidates(names, -1, NIL, false, false, false, true);
-
-   if (clist == NULL || clist->next != NULL)
+   if (!DirectInputFunctionCallSafe(regprocin, pro_name,
+                                    InvalidOid, -1,
+                                    (Node *) &escontext,
+                                    &result))
        PG_RETURN_NULL();
-
-   PG_RETURN_OID(clist->oid);
+   PG_RETURN_DATUM(result);
 }
 
 /*
@@ -287,31 +278,15 @@ Datum
 to_regprocedure(PG_FUNCTION_ARGS)
 {
    char       *pro_name = text_to_cstring(PG_GETARG_TEXT_PP(0));
-   List       *names;
-   int         nargs;
-   Oid         argtypes[FUNC_MAX_ARGS];
-   FuncCandidateList clist;
+   Datum       result;
    ErrorSaveContext escontext = {T_ErrorSaveContext};
 
-   /*
-    * Parse the name and arguments, look up potential matches in the current
-    * namespace search list, and scan to see which one exactly matches the
-    * given argument types.    (There will not be more than one match.)
-    */
-   if (!parseNameAndArgTypes(pro_name, false,
-                             &names, &nargs, argtypes,
-                             (Node *) &escontext))
+   if (!DirectInputFunctionCallSafe(regprocedurein, pro_name,
+                                    InvalidOid, -1,
+                                    (Node *) &escontext,
+                                    &result))
        PG_RETURN_NULL();
-
-   clist = FuncnameGetCandidates(names, nargs, NIL, false, false, false, true);
-
-   for (; clist; clist = clist->next)
-   {
-       if (memcmp(clist->args, argtypes, nargs * sizeof(Oid)) == 0)
-           PG_RETURN_OID(clist->oid);
-   }
-
-   PG_RETURN_NULL();
+   PG_RETURN_DATUM(result);
 }
 
 /*
@@ -552,24 +527,15 @@ Datum
 to_regoper(PG_FUNCTION_ARGS)
 {
    char       *opr_name = text_to_cstring(PG_GETARG_TEXT_PP(0));
-   List       *names;
-   FuncCandidateList clist;
+   Datum       result;
    ErrorSaveContext escontext = {T_ErrorSaveContext};
 
-   /*
-    * Parse the name into components and see if it matches any pg_operator
-    * entries in the current search path.
-    */
-   names = stringToQualifiedNameList(opr_name, (Node *) &escontext);
-   if (names == NIL)
+   if (!DirectInputFunctionCallSafe(regoperin, opr_name,
+                                    InvalidOid, -1,
+                                    (Node *) &escontext,
+                                    &result))
        PG_RETURN_NULL();
-
-   clist = OpernameGetCandidates(names, '\0', true);
-
-   if (clist == NULL || clist->next != NULL)
-       PG_RETURN_NULL();
-
-   PG_RETURN_OID(clist->oid);
+   PG_RETURN_DATUM(result);
 }
 
 /*
@@ -728,31 +694,15 @@ Datum
 to_regoperator(PG_FUNCTION_ARGS)
 {
    char       *opr_name_or_oid = text_to_cstring(PG_GETARG_TEXT_PP(0));
-   Oid         result;
-   List       *names;
-   int         nargs;
-   Oid         argtypes[FUNC_MAX_ARGS];
+   Datum       result;
    ErrorSaveContext escontext = {T_ErrorSaveContext};
 
-   /*
-    * Parse the name and arguments, look up potential matches in the current
-    * namespace search list, and scan to see which one exactly matches the
-    * given argument types.    (There will not be more than one match.)
-    */
-   if (!parseNameAndArgTypes(opr_name_or_oid, true,
-                             &names, &nargs, argtypes,
-                             (Node *) &escontext))
-       PG_RETURN_NULL();
-
-   if (nargs != 2)
+   if (!DirectInputFunctionCallSafe(regoperatorin, opr_name_or_oid,
+                                    InvalidOid, -1,
+                                    (Node *) &escontext,
+                                    &result))
        PG_RETURN_NULL();
-
-   result = OpernameGetOprid(names, argtypes[0], argtypes[1]);
-
-   if (!OidIsValid(result))
-       PG_RETURN_NULL();
-
-   PG_RETURN_OID(result);
+   PG_RETURN_DATUM(result);
 }
 
 /*
@@ -975,25 +925,15 @@ Datum
 to_regclass(PG_FUNCTION_ARGS)
 {
    char       *class_name = text_to_cstring(PG_GETARG_TEXT_PP(0));
-   Oid         result;
-   List       *names;
+   Datum       result;
    ErrorSaveContext escontext = {T_ErrorSaveContext};
 
-   /*
-    * Parse the name into components and see if it matches any pg_class
-    * entries in the current search path.
-    */
-   names = stringToQualifiedNameList(class_name, (Node *) &escontext);
-   if (names == NIL)
-       PG_RETURN_NULL();
-
-   /* We might not even have permissions on this relation; don't lock it. */
-   result = RangeVarGetRelid(makeRangeVarFromNameList(names), NoLock, true);
-
-   if (OidIsValid(result))
-       PG_RETURN_OID(result);
-   else
+   if (!DirectInputFunctionCallSafe(regclassin, class_name,
+                                    InvalidOid, -1,
+                                    (Node *) &escontext,
+                                    &result))
        PG_RETURN_NULL();
+   PG_RETURN_DATUM(result);
 }
 
 /*
@@ -1128,24 +1068,15 @@ Datum
 to_regcollation(PG_FUNCTION_ARGS)
 {
    char       *collation_name = text_to_cstring(PG_GETARG_TEXT_PP(0));
-   Oid         result;
-   List       *names;
+   Datum       result;
    ErrorSaveContext escontext = {T_ErrorSaveContext};
 
-   /*
-    * Parse the name into components and see if it matches any pg_collation
-    * entries in the current search path.
-    */
-   names = stringToQualifiedNameList(collation_name, (Node *) &escontext);
-   if (names == NIL)
-       PG_RETURN_NULL();
-
-   result = get_collation_oid(names, true);
-
-   if (OidIsValid(result))
-       PG_RETURN_OID(result);
-   else
+   if (!DirectInputFunctionCallSafe(regcollationin, collation_name,
+                                    InvalidOid, -1,
+                                    (Node *) &escontext,
+                                    &result))
        PG_RETURN_NULL();
+   PG_RETURN_DATUM(result);
 }
 
 /*
@@ -1278,17 +1209,15 @@ Datum
 to_regtype(PG_FUNCTION_ARGS)
 {
    char       *typ_name = text_to_cstring(PG_GETARG_TEXT_PP(0));
-   Oid         result;
-   int32       typmod;
+   Datum       result;
    ErrorSaveContext escontext = {T_ErrorSaveContext};
 
-   /*
-    * Invoke the full parser to deal with special cases such as array syntax.
-    */
-   if (parseTypeString(typ_name, &result, &typmod, (Node *) &escontext))
-       PG_RETURN_OID(result);
-   else
+   if (!DirectInputFunctionCallSafe(regtypein, typ_name,
+                                    InvalidOid, -1,
+                                    (Node *) &escontext,
+                                    &result))
        PG_RETURN_NULL();
+   PG_RETURN_DATUM(result);
 }
 
 /*
@@ -1634,23 +1563,15 @@ Datum
 to_regrole(PG_FUNCTION_ARGS)
 {
    char       *role_name = text_to_cstring(PG_GETARG_TEXT_PP(0));
-   Oid         result;
-   List       *names;
+   Datum       result;
    ErrorSaveContext escontext = {T_ErrorSaveContext};
 
-   names = stringToQualifiedNameList(role_name, (Node *) &escontext);
-   if (names == NIL)
-       PG_RETURN_NULL();
-
-   if (list_length(names) != 1)
-       PG_RETURN_NULL();
-
-   result = get_role_oid(strVal(linitial(names)), true);
-
-   if (OidIsValid(result))
-       PG_RETURN_OID(result);
-   else
+   if (!DirectInputFunctionCallSafe(regrolein, role_name,
+                                    InvalidOid, -1,
+                                    (Node *) &escontext,
+                                    &result))
        PG_RETURN_NULL();
+   PG_RETURN_DATUM(result);
 }
 
 /*
@@ -1759,23 +1680,15 @@ Datum
 to_regnamespace(PG_FUNCTION_ARGS)
 {
    char       *nsp_name = text_to_cstring(PG_GETARG_TEXT_PP(0));
-   Oid         result;
-   List       *names;
+   Datum       result;
    ErrorSaveContext escontext = {T_ErrorSaveContext};
 
-   names = stringToQualifiedNameList(nsp_name, (Node *) &escontext);
-   if (names == NIL)
-       PG_RETURN_NULL();
-
-   if (list_length(names) != 1)
-       PG_RETURN_NULL();
-
-   result = get_namespace_oid(strVal(linitial(names)), true);
-
-   if (OidIsValid(result))
-       PG_RETURN_OID(result);
-   else
+   if (!DirectInputFunctionCallSafe(regnamespacein, nsp_name,
+                                    InvalidOid, -1,
+                                    (Node *) &escontext,
+                                    &result))
        PG_RETURN_NULL();
+   PG_RETURN_DATUM(result);
 }
 
 /*