Re: allow referring to functions without arguments when unique

From: Michael Paquier <michael(dot)paquier(at)gmail(dot)com>
To: Peter Eisentraut <peter(dot)eisentraut(at)2ndquadrant(dot)com>
Cc: pgsql-hackers <pgsql-hackers(at)postgresql(dot)org>
Subject: Re: allow referring to functions without arguments when unique
Date: 2017-03-07 05:32:52
Message-ID: CAB7nPqSUXOLcbXEb3_g1YG54OVk_+iKmEtfXQBN-VEs2KPQ-Yg@mail.gmail.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

On Fri, Mar 3, 2017 at 4:12 PM, Michael Paquier
<michael(dot)paquier(at)gmail(dot)com> wrote:
> On Wed, Mar 1, 2017 at 11:50 AM, Peter Eisentraut
> <peter(dot)eisentraut(at)2ndquadrant(dot)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

In response to

Responses

Browse pgsql-hackers by date

  From Date Subject
Next Message Amit Kapila 2017-03-07 05:48:17 Re: Parallel seq. plan is not coming against inheritance or partition table
Previous Message Tom Lane 2017-03-07 05:30:13 Re: [NOVICE] opr_charset rule in gram.y