variadic flag doesn't work with "any" type
Hello
There is missing expansion for variadic parameter from any array to
real parameters when variadic type is "any".
It can be solved on C level, but in this moment we have not a access
to parser, so we don't know, if variadic flag was used or not.
Regards
Pavel Stehule
Pavel Stehule <pavel.stehule@gmail.com> writes:
There is missing expansion for variadic parameter from any array to
real parameters when variadic type is "any".
That's not a bug, it's intentional. Variadic any is intended to let the
C function accept any old parameter list. We should not assume that we
should do something special with a parameter that happens to be an array.
Possibly variadic anyarray will do what you are after.
regards, tom lane
2010/12/9 Tom Lane <tgl@sss.pgh.pa.us>:
Pavel Stehule <pavel.stehule@gmail.com> writes:
There is missing expansion for variadic parameter from any array to
real parameters when variadic type is "any".That's not a bug, it's intentional. Variadic any is intended to let the
C function accept any old parameter list. We should not assume that we
should do something special with a parameter that happens to be an array.Possibly variadic anyarray will do what you are after.
I didn't explain it well, sorry
so I have a function foo(variadic "any")
usual calling like foo(10,20) or foo('a',10) working perfectly. But I
have a problem with call with VARIADIC keyword
like foo(VARIADIC ARRAY[10,20]) or foo(VARIADIC ARRAY['a','10']).
Keyword VARIADIC is allowed, and this a calling doesn't raise any
error. But there isn't transformation to standard parameters. It's in
negation to other than "any" types. And because parser doesn't expand
array to parameters and just ignore VARIADIC keyword I am must not fix
it inside custom function.
so:
FUNCTION foo(VARIADIC text[])
-------- CALL foo(10,20,20) ---> real call
foo(ARRAY['10','20','20']);
-------- CALL foo (VARIADIC ARRAY['10','20','20']) --->
real call foo(ARRAY['10','20','20'])
-- same mechanism should be for "any" type - in reverse order
FUNCTION foo(VARIADIC "any")
-------- CALL foo(10,20,20) ---> real call foo(10,20,20);
-------- CALL foo(VARIADIC ARRAY[10,20,20]) ---> real
call foo(10,20,20) -- but it doesn't work now.
Pavel
Show quoted text
regards, tom lane
Pavel Stehule <pavel.stehule@gmail.com> writes:
I didn't explain it well, sorry
so I have a function foo(variadic "any")
usual calling like foo(10,20) or foo('a',10) working perfectly. But I
have a problem with call with VARIADIC keyword
like foo(VARIADIC ARRAY[10,20]) or foo(VARIADIC ARRAY['a','10']).
Keyword VARIADIC is allowed, and this a calling doesn't raise any
error.
What exactly is the use-case for that? You can't expect that an array
will hold the parameter list, since the parameters might not be all the
same type.
-------- CALL foo(VARIADIC ARRAY[10,20,20]) ---> real
call foo(10,20,20) -- but it doesn't work now.
I'm not convinced it should work that way. Even if you had convinced me
that this was sensible and had a real use-case, making it work like that
would take a whole bunch of mechanism that doesn't exist.
regards, tom lane
2010/12/9 Tom Lane <tgl@sss.pgh.pa.us>:
Pavel Stehule <pavel.stehule@gmail.com> writes:
I didn't explain it well, sorry
so I have a function foo(variadic "any")
usual calling like foo(10,20) or foo('a',10) working perfectly. But I
have a problem with call with VARIADIC keywordlike foo(VARIADIC ARRAY[10,20]) or foo(VARIADIC ARRAY['a','10']).
Keyword VARIADIC is allowed, and this a calling doesn't raise any
error.What exactly is the use-case for that? You can't expect that an array
will hold the parameter list, since the parameters might not be all the
same type.
I am working on function that can help with record updating. It's
based on polymorphic types. I would to allow a multiple modification
per one call - like UPDATE statement does.
some like:
record_set_fields(anyelement, key text, value "any" [, key text, value
"any" [..]]) returns anyelement
because we cannot work with pairs of params I designed interface
CREATE FUNCTION record_set_fields(anyelement, VARIADIC "any") RETURNS anyelement
most often case working well:
SELECT record_set_fields(row(0,0,0,0,0,0), 'f1', 10, 'f2', 20, 'f3', 30)
I prefer "any" type because a user must not use a quotes for values -
and I am able to do late conversion based on record tuple desc. But
sometimes can be interesting to use a VARIADIC value - so list of
pairs (key, value) can be created dynamically - (now I don't talk if
this is good way or not). And because we have a VARIADIC value for
VARIADIC parameter, it should be no problem - It works for non "any"
types now.
I would to do some like:
DECLARE change_set text[];
BEGIN
change_set = ARRAY(SELECT CASE WHEN i % 2 = 1 THEN 'f' || (i / 2)
ELSE (-100)::text END FROM generate_series(1,10) g(i));
-- change_set = {f0,-100,f1,-100,f2,-100,f3,-100,f4,-100}
NEW := record_set_fields(NEW, VARIADIC change_set);
...
RETURN NEW;
but NEW := record_set_fields(NEW, VARIADIC change_set) doesn't work
now - because keyword VARIADIC hasn't necessary effect for "any" type.
It's just quietly ignored. Isn't a problem to expand array inside
custom function - but I don't have a info if VARIADIC keyword was used
or not.
From some custom function's perspective there isn't difference between
(when "any" type is used):
SELECT foo(VARIADIC arrayval) and SELECT foo(arrayval).
I don't know when I have to raise exception and when I have to expand array.
Regards
Pavel
p.s. I found a workaroud - but it's a workaround and needs twice code.
I have to define second record_set_fields(anyelement, VARIADIC
anyarray), and this variant is chosen when VARIADIC value is used. But
I afraid about stability of this solution.
Show quoted text
-------- CALL foo(VARIADIC ARRAY[10,20,20]) ---> real
call foo(10,20,20) -- but it doesn't work now.I'm not convinced it should work that way. Even if you had convinced me
that this was sensible and had a real use-case, making it work like that
would take a whole bunch of mechanism that doesn't exist.regards, tom lane
Attachments:
Pavel Stehule <pavel.stehule@gmail.com> writes:
2010/12/9 Tom Lane <tgl@sss.pgh.pa.us>:
What exactly is the use-case for that?
I am working on function that can help with record updating. It's
based on polymorphic types. I would to allow a multiple modification
per one call - like UPDATE statement does.
some like:
record_set_fields(anyelement, key text, value "any" [, key text, value
"any" [..]]) returns anyelement
OK, makes sense, since you don't want to constrain the values to be all
the same datatype.
sometimes can be interesting to use a VARIADIC value - so list of
pairs (key, value) can be created dynamically - (now I don't talk if
this is good way or not).
That can't work unless you constrain all the values to be text (to match
the column-name parameters), which more or less defeats the entire point
of the function. So I see no interesting use-case for VARIADIC here.
regards, tom lane
2010/12/10 Tom Lane <tgl@sss.pgh.pa.us>:
Pavel Stehule <pavel.stehule@gmail.com> writes:
2010/12/9 Tom Lane <tgl@sss.pgh.pa.us>:
What exactly is the use-case for that?
I am working on function that can help with record updating. It's
based on polymorphic types. I would to allow a multiple modification
per one call - like UPDATE statement does.
some like:
record_set_fields(anyelement, key text, value "any" [, key text, value
"any" [..]]) returns anyelementOK, makes sense, since you don't want to constrain the values to be all
the same datatype.
ok, can I send a patch?
Pavel
Show quoted text
sometimes can be interesting to use a VARIADIC value - so list of
pairs (key, value) can be created dynamically - (now I don't talk if
this is good way or not).That can't work unless you constrain all the values to be text (to match
the column-name parameters), which more or less defeats the entire point
of the function. So I see no interesting use-case for VARIADIC here.regards, tom lane
On Fri, Dec 10, 2010 at 2:44 PM, Pavel Stehule <pavel.stehule@gmail.com> wrote:
2010/12/10 Tom Lane <tgl@sss.pgh.pa.us>:
Pavel Stehule <pavel.stehule@gmail.com> writes:
2010/12/9 Tom Lane <tgl@sss.pgh.pa.us>:
What exactly is the use-case for that?
I am working on function that can help with record updating. It's
based on polymorphic types. I would to allow a multiple modification
per one call - like UPDATE statement does.
some like:
record_set_fields(anyelement, key text, value "any" [, key text, value
"any" [..]]) returns anyelementOK, makes sense, since you don't want to constrain the values to be all
the same datatype.ok, can I send a patch?
In the part of Tom's email you didn't quote, he wrote "this can't
work". Did you miss that part?
--
Robert Haas
EnterpriseDB: http://www.enterprisedb.com
The Enterprise PostgreSQL Company