variadic flag doesn't work with "any" type

Started by Pavel Stehuleover 15 years ago8 messagesbugs
Jump to latest
#1Pavel Stehule
pavel.stehule@gmail.com

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

#2Tom Lane
tgl@sss.pgh.pa.us
In reply to: Pavel Stehule (#1)
Re: variadic flag doesn't work with "any" type

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

#3Pavel Stehule
pavel.stehule@gmail.com
In reply to: Tom Lane (#2)
Re: variadic flag doesn't work with "any" type

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

#4Tom Lane
tgl@sss.pgh.pa.us
In reply to: Pavel Stehule (#3)
Re: variadic flag doesn't work with "any" type

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

#5Pavel Stehule
pavel.stehule@gmail.com
In reply to: Tom Lane (#4)
Re: variadic flag doesn't work with "any" type

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 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.

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:

pstcoll.tgzapplication/x-gzip; name=pstcoll.tgzDownload
#6Tom Lane
tgl@sss.pgh.pa.us
In reply to: Pavel Stehule (#5)
Re: variadic flag doesn't work with "any" type

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

#7Pavel Stehule
pavel.stehule@gmail.com
In reply to: Tom Lane (#6)
Re: variadic flag doesn't work with "any" type

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 anyelement

OK, 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

#8Robert Haas
robertmhaas@gmail.com
In reply to: Pavel Stehule (#7)
Re: variadic flag doesn't work with "any" type

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 anyelement

OK, 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