Re: [HACKERS] allow referring to functions without arguments when unique - Mailing list pgsql-hackers

From Michael Paquier
Subject Re: [HACKERS] allow referring to functions without arguments when unique
Date
Msg-id CAB7nPqSUXOLcbXEb3_g1YG54OVk_+iKmEtfXQBN-VEs2KPQ-Yg@mail.gmail.com
Whole thread Raw
In response to Re: [HACKERS] allow referring to functions without arguments when unique  (Michael Paquier <michael.paquier@gmail.com>)
Responses Re: [HACKERS] allow referring to functions without arguments whenunique  (Peter Eisentraut <peter.eisentraut@2ndquadrant.com>)
List pgsql-hackers
On Fri, Mar 3, 2017 at 4:12 PM, Michael Paquier
<michael.paquier@gmail.com> wrote:
> On Wed, Mar 1, 2017 at 11:50 AM, Peter Eisentraut
> <peter.eisentraut@2ndquadrant.com> wrote:
>> This is the "grand finale" that goes on top of the "DROP FUNCTION of
>> multiple functions" patch set.  The purpose is to allow referring to
>> functions without having to spell out the argument list, when the
>> function name is unique.  This is especially useful when having to
>> operate on "business logic" functions with many many arguments.  It's an
>> SQL standard feature, and it applies everywhere a function is referred
>> to in the grammar.  We already have the lookup logic for the regproc
>> type, and thanks to the grand refactoring of the parser representation
>> of functions, this is quite a small patch.  There is a bit of
>> reduce/reduce parser mystery, to keep the reviewer entertained.
>
> ... Which would be nice.
>
>> (The
>> equivalent could be implemented for aggregates and operators, but I
>> haven't done that here yet.)
>
> OK. After a lookup, I am just seeing opfamily, opclass missing, so
> this patch is doing it as you describe.
>
> I have read through the code once, still I am waiting for the DROP
> FUNCTION patches to be committed before doing a real hands-on.
>
> @@ -7198,6 +7198,33 @@ function_with_argtypes:
>                     n->objargs = extractArgTypes($2);
>                     $$ = n;
>                 }
> This may not have arguments listed, so is function_with_argtypes really adapted?
>
> +   /*
> +    * If no arguments were specified, the name must yield a unique candidate.
> +    */
> +   if (nargs == -1 && clist)
> +   {
> +       if (clist->next)
> +           ereport(ERROR,
> I would have used list_length here for clarity.
>
> --- a/src/backend/parser/parse_func.c
> +++ b/src/backend/parser/parse_func.c
> @@ -1914,6 +1914,21 @@ LookupFuncName(List *funcname, int nargs, const
> Oid *argtypes, bool noError)
> The comment at the top of LookupFuncName() needs a refresh. The caller
> can as well just use a function name without arguments.


+           /*
+            * Because of reduce/reduce conflicts, we can't use func_name
+            * below, but we can write it out the long way, which actually
+            * allows more cases.
+            */
+           | type_func_name_keyword
+               {
+                   ObjectWithArgs *n = makeNode(ObjectWithArgs);
+                   n->objname = list_make1(makeString(pstrdup($1)));
+                   n->args_unspecified = true;
+                   $$ = n;
+               }
+           | ColId
+               {
+                   ObjectWithArgs *n = makeNode(ObjectWithArgs);
+                   n->objname = list_make1(makeString($1));
+                   n->args_unspecified = true;
+                   $$ = n;
+               }
+           | ColId indirection
+               {
+                   ObjectWithArgs *n = makeNode(ObjectWithArgs);
+                   n->objname = check_func_name(lcons(makeString($1), $2),
+                                                 yyscanner);
+                   n->args_unspecified = true;
+                   $$ = n;
+               }
I have spent some time looking at this one. Another solution would be
to extend func_args to make the difference between an empty list and a
list with no arguments. This would need an intermediate structure for
parsing, and it does not seem worth the cost so I am fine with this
solution.

=# create schema popo;
CREATE SCHEMA
=# CREATE FUNCTION popo.dup2(int,int) RETURNS TABLE(f1 int, f2 text)
                                                         AS $$ SELECT
$1, CAST($1 AS text) || ' is text' $$
                                        LANGUAGE SQL;
CREATE FUNCTION
=# CREATE FUNCTION dup2(int,int) RETURNS TABLE(f1 int, f2 text)
                                                         AS $$ SELECT
$1, CAST($1 AS text) || ' is text' $$
                                        LANGUAGE SQL;
CREATE FUNCTION
=# set search_path to 'public,popo';
SET
Time: 0.463 ms
=# drop function dup2;
ERROR:  42883: function dup2() does not exist
LOCATION:  LookupFuncName, parse_func.c:1944
In this case I would have expected an error telling that the name is
ambiguous. FuncnameGetCandidates() returns an empty list.
-- 
Michael



pgsql-hackers by date:

Previous
From: Tom Lane
Date:
Subject: Re: [HACKERS] [NOVICE] opr_charset rule in gram.y
Next
From: Amit Kapila
Date:
Subject: Re: [HACKERS] Parallel seq. plan is not coming against inheritance orpartition table