Re: Error-safe user functions - Mailing list pgsql-hackers
From | Tom Lane |
---|---|
Subject | Re: Error-safe user functions |
Date | |
Msg-id | 3910031.1672095600@sss.pgh.pa.us Whole thread Raw |
In response to | Re: Error-safe user functions (Tom Lane <tgl@sss.pgh.pa.us>) |
Responses |
Re: Error-safe user functions
|
List | pgsql-hackers |
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 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 <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> diff --git a/src/backend/utils/adt/regproc.c b/src/backend/utils/adt/regproc.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 = 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); } /*
pgsql-hackers by date: