Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1p9wSB-0003v8-Fm for pgsql-hackers@arkaria.postgresql.org; Mon, 26 Dec 2022 23:00:19 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.92) (envelope-from ) id 1p9wS8-00065o-Ik for pgsql-hackers@arkaria.postgresql.org; Mon, 26 Dec 2022 23:00:16 +0000 Received: from makus.postgresql.org ([2001:4800:3e1:1::229]) by malur.postgresql.org with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1p9wS8-00065b-0z for pgsql-hackers@lists.postgresql.org; Mon, 26 Dec 2022 23:00:16 +0000 Received: from sss.pgh.pa.us ([66.207.139.130]) by makus.postgresql.org with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1p9wS0-0007Sm-TH for pgsql-hackers@lists.postgresql.org; Mon, 26 Dec 2022 23:00:14 +0000 Received: from sss1.sss.pgh.pa.us (localhost [127.0.0.1]) by sss.pgh.pa.us (8.15.2/8.15.2) with ESMTP id 2BQN00UQ3910032; Mon, 26 Dec 2022 18:00:00 -0500 From: Tom Lane To: Robert Haas cc: Andrew Dunstan , Amul Sul , Andres Freund , Alexander Korotkov , "David G. Johnston" , Corey Huinker , Alvaro Herrera , Joe Conway , Nikita Glukhov , PostgreSQL Hackers Subject: Re: Error-safe user functions In-reply-to: <3342239.1671988406@sss.pgh.pa.us> References: <4009543.1670422833@sss.pgh.pa.us> <6acddf68-7cb7-e9e7-a5a7-0abc87b3c55b@dunslane.net> <4111458.1670444176@sss.pgh.pa.us> <3211.1670452341@sss.pgh.pa.us> <20221207233518.sudtaxn6omtvpzvr@awork3.anarazel.de> <186288.1670517119@sss.pgh.pa.us> <20221208215836.3naznqmal2m32hzc@awork3.anarazel.de> <512551.1670540229@sss.pgh.pa.us> <20221209023351.l362yejerfoq3lfp@awork3.anarazel.de> <633426.1670554790@sss.pgh.pa.us> <01ff2051-806d-af2f-4f9e-793f7ba9a3f8@dunslane.net> <778369.1670598993@sss.pgh.pa.us> <5aaf7c66-9df9-21a9-1ff4-02c7848def52@dunslane.net> <3bac9841-fe07-713d-fa42-606c225567d6@dunslane.net> <1436686.1670701118@sss.pgh.pa.us> <2b1e7d56-6f37-bad9-9702-053ab55ecf60@dunslane.net> <1805344.1670779451@sss.pgh.pa.us> <1863335.1670783397@sss.pgh.pa.us> <2687377.1671033604@sss.p! gh.pa.us> <3038346.1671060258@sss.pgh.pa.us> <3564577.1671142683@sss.pgh.pa.us> <3819056.1671215496@sss.pgh.pa.us> <3342239.1671988406@sss.pgh.pa.us> Comments: In-reply-to Tom Lane message dated "Sun, 25 Dec 2022 12:13:26 -0500" MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="----- =_aaaaaaaaaa0" Content-ID: <3909930.1672095508.0@sss.pgh.pa.us> Date: Mon, 26 Dec 2022 18:00:00 -0500 Message-ID: <3910031.1672095600@sss.pgh.pa.us> List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk ------- =_aaaaaaaaaa0 Content-Type: text/plain; charset="us-ascii" Content-ID: <3909930.1672095508.1@sss.pgh.pa.us> I wrote: > (Perhaps we should go further than this, and convert all these > functions to just be DirectInputFunctionCallSafe wrappers > around the corresponding input functions? That would save > some duplicative code, but I've not done it here.) I looked closer at that idea, and realized that it would do more than just save some code: it'd cause the to_regfoo functions to accept numeric OIDs, as they did not before (and are documented not to). It is unclear to me whether that inconsistency with the input functions is really desirable or not --- but I don't offhand see a good argument for it. If we change this though, it should probably happen in a separate commit. Accordingly, here's a delta patch doing that. regards, tom lane ------- =_aaaaaaaaaa0 Content-Type: text/x-diff; name="change-to_regproc-implementation.patch"; charset="us-ascii" Content-ID: <3909930.1672095508.2@sss.pgh.pa.us> Content-Description: change-to_regproc-implementation.patch Content-Transfer-Encoding: quoted-printable diff --git a/doc/src/sgml/func.sgml b/doc/src/sgml/func.sgml index 836b9254fb..3bf8d021c3 100644 --- a/doc/src/sgml/func.sgml +++ b/doc/src/sgml/func.sgml @@ -24100,8 +24100,7 @@ SELECT collation for ('foo' COLLATE "de_DE"); obtained by casting the string to type regclass (see ); however, this function will re= turn NULL 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. = @@ -24118,8 +24117,7 @@ SELECT collation for ('foo' COLLATE "de_DE"); obtained by casting the string to type regcollation = (see ); however, this function will re= turn NULL 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. = @@ -24136,8 +24134,7 @@ SELECT collation for ('foo' COLLATE "de_DE"); obtained by casting the string to type regnamespace = (see ); however, this function will re= turn NULL 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. = @@ -24154,8 +24151,7 @@ SELECT collation for ('foo' COLLATE "de_DE"); obtained by casting the string to type regoper (see ); however, this function will re= turn NULL rather than throwing an error if the name= is - not found or is ambiguous. Also unlike the cast, this does not a= ccept - a numeric OID as input. + not found or is ambiguous. = @@ -24172,8 +24168,7 @@ SELECT collation for ('foo' COLLATE "de_DE"); obtained by casting the string to type regoperator (= see ); however, this function will re= turn NULL 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. = @@ -24190,8 +24185,7 @@ SELECT collation for ('foo' COLLATE "de_DE"); obtained by casting the string to type regproc (see ); however, this function will re= turn NULL rather than throwing an error if the name= is - not found or is ambiguous. Also unlike the cast, this does not a= ccept - a numeric OID as input. + not found or is ambiguous. = @@ -24208,8 +24202,7 @@ SELECT collation for ('foo' COLLATE "de_DE"); obtained by casting the string to type regprocedure = (see ); however, this function will re= turn NULL 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. = @@ -24226,8 +24219,7 @@ SELECT collation for ('foo' COLLATE "de_DE"); obtained by casting the string to type regrole (see ); however, this function will re= turn NULL 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. = @@ -24244,8 +24236,7 @@ SELECT collation for ('foo' COLLATE "de_DE"); obtained by casting the string to type regtype (see ); however, this function will re= turn NULL 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. diff --git a/src/backend/utils/adt/regproc.c b/src/backend/utils/adt/regpr= oc.c index 14d76c856d..3635a94633 100644 --- a/src/backend/utils/adt/regproc.c +++ b/src/backend/utils/adt/regproc.c @@ -118,24 +118,15 @@ Datum to_regproc(PG_FUNCTION_ARGS) { char *pro_name =3D text_to_cstring(PG_GETARG_TEXT_PP(0)); - List *names; - FuncCandidateList clist; + Datum result; ErrorSaveContext escontext =3D {T_ErrorSaveContext}; = - /* - * Parse the name into components and see if it matches any pg_proc - * entries in the current search path. - */ - names =3D stringToQualifiedNameList(pro_name, (Node *) &escontext); - if (names =3D=3D NIL) - PG_RETURN_NULL(); - - clist =3D FuncnameGetCandidates(names, -1, NIL, false, false, false, tru= e); - - if (clist =3D=3D NULL || clist->next !=3D 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 =3D text_to_cstring(PG_GETARG_TEXT_PP(0)); - List *names; - int nargs; - Oid argtypes[FUNC_MAX_ARGS]; - FuncCandidateList clist; + Datum result; ErrorSaveContext escontext =3D {T_ErrorSaveContext}; = - /* - * Parse the name and arguments, look up potential matches in the curren= t - * 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 =3D FuncnameGetCandidates(names, nargs, NIL, false, false, false, = true); - - for (; clist; clist =3D clist->next) - { - if (memcmp(clist->args, argtypes, nargs * sizeof(Oid)) =3D=3D 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 =3D text_to_cstring(PG_GETARG_TEXT_PP(0)); - List *names; - FuncCandidateList clist; + Datum result; ErrorSaveContext escontext =3D {T_ErrorSaveContext}; = - /* - * Parse the name into components and see if it matches any pg_operator - * entries in the current search path. - */ - names =3D stringToQualifiedNameList(opr_name, (Node *) &escontext); - if (names =3D=3D NIL) + if (!DirectInputFunctionCallSafe(regoperin, opr_name, + InvalidOid, -1, + (Node *) &escontext, + &result)) PG_RETURN_NULL(); - - clist =3D OpernameGetCandidates(names, '\0', true); - - if (clist =3D=3D NULL || clist->next !=3D 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 =3D text_to_cstring(PG_GETARG_TEXT_PP(0)); - Oid result; - List *names; - int nargs; - Oid argtypes[FUNC_MAX_ARGS]; + Datum result; ErrorSaveContext escontext =3D {T_ErrorSaveContext}; = - /* - * Parse the name and arguments, look up potential matches in the curren= t - * 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 !=3D 2) + if (!DirectInputFunctionCallSafe(regoperatorin, opr_name_or_oid, + InvalidOid, -1, + (Node *) &escontext, + &result)) PG_RETURN_NULL(); - - result =3D 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 =3D text_to_cstring(PG_GETARG_TEXT_PP(0)); - Oid result; - List *names; + Datum result; ErrorSaveContext escontext =3D {T_ErrorSaveContext}; = - /* - * Parse the name into components and see if it matches any pg_class - * entries in the current search path. - */ - names =3D stringToQualifiedNameList(class_name, (Node *) &escontext); - if (names =3D=3D NIL) - PG_RETURN_NULL(); - - /* We might not even have permissions on this relation; don't lock it. *= / - result =3D RangeVarGetRelid(makeRangeVarFromNameList(names), NoLock, tru= e); - - 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 =3D text_to_cstring(PG_GETARG_TEXT_PP(0)); - Oid result; - List *names; + Datum result; ErrorSaveContext escontext =3D {T_ErrorSaveContext}; = - /* - * Parse the name into components and see if it matches any pg_collation - * entries in the current search path. - */ - names =3D stringToQualifiedNameList(collation_name, (Node *) &escontext)= ; - if (names =3D=3D NIL) - PG_RETURN_NULL(); - - result =3D 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 =3D text_to_cstring(PG_GETARG_TEXT_PP(0)); - Oid result; - int32 typmod; + Datum result; ErrorSaveContext escontext =3D {T_ErrorSaveContext}; = - /* - * Invoke the full parser to deal with special cases such as array synta= x. - */ - 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 =3D text_to_cstring(PG_GETARG_TEXT_PP(0)); - Oid result; - List *names; + Datum result; ErrorSaveContext escontext =3D {T_ErrorSaveContext}; = - names =3D stringToQualifiedNameList(role_name, (Node *) &escontext); - if (names =3D=3D NIL) - PG_RETURN_NULL(); - - if (list_length(names) !=3D 1) - PG_RETURN_NULL(); - - result =3D 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 =3D text_to_cstring(PG_GETARG_TEXT_PP(0)); - Oid result; - List *names; + Datum result; ErrorSaveContext escontext =3D {T_ErrorSaveContext}; = - names =3D stringToQualifiedNameList(nsp_name, (Node *) &escontext); - if (names =3D=3D NIL) - PG_RETURN_NULL(); - - if (list_length(names) !=3D 1) - PG_RETURN_NULL(); - - result =3D 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); } = /* ------- =_aaaaaaaaaa0--