variadic function support
Hello
this patch enhance current syntax of CREATE FUNCTION statement. It
allows creating functions with variable number of arguments. This
version is different than last my patches. It doesn't need patching
PL. Basic idea is transformation of real arguments (related to
declared variadic argument) to array. All changes are mostly in
parser.
Demo:
CREATE FUNCTION public.least(double precision[]) RETURNS double precision AS $$
SELECT min($1[i])
FROM generate_subscripts($1,1) g(i)
$$ LANGUAGE SQL VARIADIC;
SELECT public.least(3,2,1);
least
-------
1
(1 row)
SELECT public.least(3,2,1,0,-1);
least
-------
-1
CREATE FUNCTION concat(varchar, anyarray) RETURNS varchar AS $$
SELECT array_to_string($2, $1);
$$ LANGUAGE SQL VARIADIC;
SELECT concat('-',2008,10,12);
concat
------------
2008-10-12
(1 row)
Regards
Pavel Stehule
Attachments:
variadic.1.0.0.diff.gzapplication/x-gzip; name=variadic.1.0.0.diff.gzDownload+0-1
Pavel Stehule wrote:
Hello
this patch enhance current syntax of CREATE FUNCTION statement. It
allows creating functions with variable number of arguments. This
version is different than last my patches. It doesn't need patching
PL. Basic idea is transformation of real arguments (related to
declared variadic argument) to array. All changes are mostly in
parser.Demo:
CREATE FUNCTION public.least(double precision[]) RETURNS double precision AS $$
SELECT min($1[i])
FROM generate_subscripts($1,1) g(i)
$$ LANGUAGE SQL VARIADIC;SELECT public.least(3,2,1);
least
-------
1
(1 row)SELECT public.least(3,2,1,0,-1);
least
-------
-1
CREATE FUNCTION concat(varchar, anyarray) RETURNS varchar AS $$
SELECT array_to_string($2, $1);
$$ LANGUAGE SQL VARIADIC;SELECT concat('-',2008,10,12);
concat
------------
2008-10-12
(1 row)
And what about a function that takes 2 arrays as arguments?
This proposal strikes me as half-baked. Either we need proper and full
support for variadic functions, or we don't, but I don't think we need
syntactic sugar like the above (or maybe in this case it's really
syntactic saccharine).
cheers
andrew
Andrew Dunstan <andrew@dunslane.net> writes:
This proposal strikes me as half-baked. Either we need proper and full
support for variadic functions, or we don't, but I don't think we need
syntactic sugar like the above (or maybe in this case it's really
syntactic saccharine).
What would you consider "proper and full support"?
regards, tom lane
Tom Lane wrote:
Andrew Dunstan <andrew@dunslane.net> writes:
This proposal strikes me as half-baked. Either we need proper and full
support for variadic functions, or we don't, but I don't think we need
syntactic sugar like the above (or maybe in this case it's really
syntactic saccharine).What would you consider "proper and full support"?
I don't know. But this doesn't feel like it.
I'm not even sure it's possible to so in any sane way alongside overloading.
cheers
andrew
Andrew Dunstan <andrew@dunslane.net> writes:
Tom Lane wrote:
What would you consider "proper and full support"?
I don't know. But this doesn't feel like it.
That's a fairly weak argument for rejecting a patch that provides a
feature many people have asked for.
I thought the patch was pretty clever, actually. The main functionality
complaint someone might level against it is that all the variadic
arguments have to be (coercible to) the same type. However, that's
still pretty useful, and I don't see a reasonable solution that provides
more generality than that in a type-safe way. I'm quite happy that you
can't write sprintf() using this ;-)
A different line of argument is whether this functionality is
sufficiently badly needed that we should get out in front of the SQL
standard on providing it, and risk being stuck with legacy behavior
if they eventually adopt some other mechanism to solve the same problem.
I'm not sure how worried I am about that. There are certainly a
boatload of Postgres-isms in and around CREATE FUNCTION already,
so it's hard to make a case against "just one more".
regards, tom lane
Tom Lane wrote:
Andrew Dunstan <andrew@dunslane.net> writes:
Tom Lane wrote:
What would you consider "proper and full support"?
I don't know. But this doesn't feel like it.
That's a fairly weak argument for rejecting a patch that provides a
feature many people have asked for.
OK. Let me be a bit more specific. I think (forcing myself to be a bit
more analytic than I have been up to now) my main objection is that the
variadic part of the parameters should be marked explicitly in the
formal parameter list.
I don't mind having it limited to a single typed array - as you say we
probably don't want someone implementing sprintf.
But if I have
foo( a text, b int[])
it looks odd if both these calls are legal:
foo('a',1,2,3,)
foo('a',ARRAY[1,2,3])
which I understand would be the case with the current patch.
I'm also still curious to know how the following would be handled:
foo(a text[], b text[])
cheers
andrew
Andrew Dunstan <andrew@dunslane.net> writes:
But if I have
foo( a text, b int[])
it looks odd if both these calls are legal:
foo('a',1,2,3,)
foo('a',ARRAY[1,2,3])
which I understand would be the case with the current patch.
Maybe I misunderstand what is supposed to happen, but I believe that
if the function is marked VARIADIC then the second case would in fact
be rejected: the signature of the function for parameter-matching
purposes is text followed by one or more ints, never text and int[].
I'm also still curious to know how the following would be handled:
foo(a text[], b text[])
I think a is just text[], full stop. Only the last parameter is
interpreted differently for variadic.
Your point about the syntax is good though. It would be better if
the syntax were like
create function foo (a text, variadic b int[])
or maybe even better
create function foo (a text, variadic b int)
since (a) this makes it much more obvious to the reader what the
function might match, and (b) it leaves the door open for marking
multiple parameters as variadic, if we can figure out what that means.
regards, tom lane
Tom Lane wrote:
Your point about the syntax is good though. It would be better if
the syntax were likecreate function foo (a text, variadic b int[])
or maybe even better
create function foo (a text, variadic b int)
since (a) this makes it much more obvious to the reader what the
function might match, and (b) it leaves the door open for marking
multiple parameters as variadic, if we can figure out what that means.
Yes. I understand from the family Java expert that (surface syntax
issues aside) the second is similar to the way Java does this, in fact,
so there's some precedent. That would mean that your first would
actually mean each variadic arg has to be an array of ints, which we
might well want to provide for.
So with that modification I'll be lots happier with the feature.
cheers
andrew
2008/6/23 Andrew Dunstan <andrew@dunslane.net>:
And what about a function that takes 2 arrays as arguments?
only last argument is evaluated as variadic
so function
create or replace function foo(a int[], b int[]) ... variadic
is called
select foo(array[1,2,3], 1,2,3,4,5,6)
This proposal strikes me as half-baked. Either we need proper and full
support for variadic functions, or we don't, but I don't think we need
syntactic sugar like the above (or maybe in this case it's really syntactic
saccharine).
there is some functions like Oracle's least,greater, decode that needs
this feature. So I can write wrappers. For me most important are new
possibility for C procedures. All this work is related to my JSON
support proposal.
Pavel
Show quoted text
cheers
andrew
2008/6/24 Andrew Dunstan <andrew@dunslane.net>:
Tom Lane wrote:
Your point about the syntax is good though. It would be better if
the syntax were likecreate function foo (a text, variadic b int[])
or maybe even better
create function foo (a text, variadic b int)
since (a) this makes it much more obvious to the reader what the
function might match, and (b) it leaves the door open for marking
multiple parameters as variadic, if we can figure out what that means.Yes. I understand from the family Java expert that (surface syntax issues
aside) the second is similar to the way Java does this, in fact, so there's
some precedent. That would mean that your first would actually mean each
variadic arg has to be an array of ints, which we might well want to provide
for.So with that modification I'll be lots happier with the feature.
I don't see problem with your syntax. It well block combination OUT
and VARIADIC parameter - my one request, variadic parameter have to be
array. It's more consistent with following procedure implementation -
inside procedures is really array.
sample:
CREATE OR REPLACE least(varidic values numeric[]) --< ARRAY
RETURNS numeric AS $$
SELECT $1[i] --< ARRAY
FROM
Regards
Pavel Stehule
p.s. with one exception "any", because there isn't possible array from "any"
Show quoted text
cheers
andrew
2008/6/24 Tom Lane <tgl@sss.pgh.pa.us>:
Andrew Dunstan <andrew@dunslane.net> writes:
But if I have
foo( a text, b int[])
it looks odd if both these calls are legal:
foo('a',1,2,3,)
foo('a',ARRAY[1,2,3])
which I understand would be the case with the current patch.Maybe I misunderstand what is supposed to happen, but I believe that
if the function is marked VARIADIC then the second case would in fact
be rejected: the signature of the function for parameter-matching
purposes is text followed by one or more ints, never text and int[].I'm also still curious to know how the following would be handled:
foo(a text[], b text[])I think a is just text[], full stop. Only the last parameter is
interpreted differently for variadic.Your point about the syntax is good though. It would be better if
the syntax were likecreate function foo (a text, variadic b int[])
or maybe even better
create function foo (a text, variadic b int)
since (a) this makes it much more obvious to the reader what the
function might match, and (b) it leaves the door open for marking
multiple parameters as variadic, if we can figure out what that means.
(b) has one disadvantage - argument type is different than real
parameter - and internally it is little bit cleaner (doesn't need
changes in executor). So there is two forces in opposite. a) clean
function's declaration, b) clean function definition. This syntax is
limited - I am not able implement all cases of Oracle's decode
functions - but I hope it's good compromise between functionality and
simplicity.
note - variant b doesn't block multiple parameters as variadic - is
same case as a. array or not array is unimportant - I need different
types so I can choose what is first variadic argument and what is
second.
Academic question is using structured arrays - some like
create or replace function decode(s_value anyelement1, variadic
(s_value anyalement1, o_value anyelement)[])
returns anyelement as $$
select ($2[i]).o_value
from generate_subcripts($1,1) g(i)
where ($2[i]).s_value = $1;
$$ language sql;
regards
Pavel Stehule
Show quoted text
regards, tom lane
Hello
this version implements syntax based on argmodes.
CREATE FUNCTION mleast(variadic numeric[]) RETURNS numeric AS $$
SELECT min($1[i])
FROM generate_subscripts($1,1) g(i);
$$ LANGUAGE SQL;
Regards
Pavel Stehule
2008/6/24 Tom Lane <tgl@sss.pgh.pa.us>:
Show quoted text
Andrew Dunstan <andrew@dunslane.net> writes:
But if I have
foo( a text, b int[])
it looks odd if both these calls are legal:
foo('a',1,2,3,)
foo('a',ARRAY[1,2,3])
which I understand would be the case with the current patch.Maybe I misunderstand what is supposed to happen, but I believe that
if the function is marked VARIADIC then the second case would in fact
be rejected: the signature of the function for parameter-matching
purposes is text followed by one or more ints, never text and int[].I'm also still curious to know how the following would be handled:
foo(a text[], b text[])I think a is just text[], full stop. Only the last parameter is
interpreted differently for variadic.Your point about the syntax is good though. It would be better if
the syntax were likecreate function foo (a text, variadic b int[])
or maybe even better
create function foo (a text, variadic b int)
since (a) this makes it much more obvious to the reader what the
function might match, and (b) it leaves the door open for marking
multiple parameters as variadic, if we can figure out what that means.regards, tom lane
Attachments:
variadic.2.0.0.difftext/x-patch; name=variadic.2.0.0.diffDownload+427-109
"Pavel Stehule" <pavel.stehule@gmail.com> writes:
Tom Lane wrote:
Your point about the syntax is good though. It would be better if
the syntax were like
create function foo (a text, variadic b int[])
or maybe even better
create function foo (a text, variadic b int)
I don't see problem with your syntax. It well block combination OUT
and VARIADIC parameter - my one request, variadic parameter have to be
array.
Well, we should certainly store the parameter type as an array in
proargtypes, because that makes this feature transparent to all the
PLs. However, it doesn't follow that the CREATE FUNCTION syntax
has to specify the array type rather than the element type. I think
the Java precedent might be good reason to go with using the element
type in the function declaration.
regards, tom lane
2008/6/25 Tom Lane <tgl@sss.pgh.pa.us>:
"Pavel Stehule" <pavel.stehule@gmail.com> writes:
Tom Lane wrote:
Your point about the syntax is good though. It would be better if
the syntax were like
create function foo (a text, variadic b int[])
or maybe even better
create function foo (a text, variadic b int)I don't see problem with your syntax. It well block combination OUT
and VARIADIC parameter - my one request, variadic parameter have to be
array.Well, we should certainly store the parameter type as an array in
proargtypes, because that makes this feature transparent to all the
PLs. However, it doesn't follow that the CREATE FUNCTION syntax
has to specify the array type rather than the element type. I think
the Java precedent might be good reason to go with using the element
type in the function declaration.
There is only one break - psql functions description. It needs
publishing get_element_type function and ofcourse all managers need
update.
regards
Pavel
Show quoted text
regards, tom lane
2008/6/25 Tom Lane <tgl@sss.pgh.pa.us>:
"Pavel Stehule" <pavel.stehule@gmail.com> writes:
Tom Lane wrote:
Your point about the syntax is good though. It would be better if
the syntax were like
create function foo (a text, variadic b int[])
or maybe even better
create function foo (a text, variadic b int)I don't see problem with your syntax. It well block combination OUT
and VARIADIC parameter - my one request, variadic parameter have to be
array.Well, we should certainly store the parameter type as an array in
proargtypes, because that makes this feature transparent to all the
PLs. However, it doesn't follow that the CREATE FUNCTION syntax
has to specify the array type rather than the element type. I think
the Java precedent might be good reason to go with using the element
type in the function declaration.
it's strange.I looked for some info
http://en.wikipedia.org/wiki/Variadic_function#Variadic_functions_in_C.23_and_Java
C# use array
Does somebody know some about variadic functions in ADA?
Regards
Pavel Stehule
Show quoted text
regards, tom lane
2008/6/25 Tom Lane <tgl@sss.pgh.pa.us>:
"Pavel Stehule" <pavel.stehule@gmail.com> writes:
Tom Lane wrote:
Your point about the syntax is good though. It would be better if
the syntax were like
create function foo (a text, variadic b int[])
or maybe even better
create function foo (a text, variadic b int)I don't see problem with your syntax. It well block combination OUT
and VARIADIC parameter - my one request, variadic parameter have to be
array.Well, we should certainly store the parameter type as an array in
proargtypes, because that makes this feature transparent to all the
PLs. However, it doesn't follow that the CREATE FUNCTION syntax
has to specify the array type rather than the element type. I think
the Java precedent might be good reason to go with using the element
type in the function declaration.
I afraid so Java syntax isn't good inspiration
http://www.java-tips.org/java-se-tips/java.lang/using-the-varargs-language-feature.html
http://www.clanproductions.com/java5.html
they use symbol ... like specific synonym to [].
public Method getMethod(String name, Class... parameterTypes)
I didn't find any info about vararg in Oracle - it uses collection and
it allows implicit constructors for emulation o variadic functions -
but "variadic" argument isn't scalar too. So I invite any opinions
about it.
Regards
Pavel Stehule
Show quoted text
regards, tom lane
Pavel Stehule wrote:
I afraid so Java syntax isn't good inspiration
http://www.java-tips.org/java-se-tips/java.lang/using-the-varargs-language-feature.html
http://www.clanproductions.com/java5.htmlthey use symbol ... like specific synonym to [].
public Method getMethod(String name, Class... parameterTypes)
Well, ... is really more the equivalent of your "variadic" keyword, I think.
public Method getMethod(String name, Class[] ... parameterTypes)
would mean each variadic argument would be an array of Class.
cheers
andrew
2008/6/25 Tom Lane <tgl@sss.pgh.pa.us>:
"Pavel Stehule" <pavel.stehule@gmail.com> writes:
Tom Lane wrote:
Your point about the syntax is good though. It would be better if
the syntax were like
create function foo (a text, variadic b int[])
or maybe even better
create function foo (a text, variadic b int)I don't see problem with your syntax. It well block combination OUT
and VARIADIC parameter - my one request, variadic parameter have to be
array.Well, we should certainly store the parameter type as an array in
proargtypes, because that makes this feature transparent to all the
PLs. However, it doesn't follow that the CREATE FUNCTION syntax
has to specify the array type rather than the element type. I think
the Java precedent might be good reason to go with using the element
type in the function declaration.
I am playing with this now and two versions of proargtypes is 30% more
ugly code - mostly pg_dump and paradoxically remove function -
because currently RemoveFuncStatement lost argmode, so I am missing
info about variadic parameter and I can't simply transformation from
element to array. I thing, it isn't good way.
Regards
Pavel Stehule
Show quoted text
regards, tom lane
2008/6/25 Tom Lane <tgl@sss.pgh.pa.us>:
"Pavel Stehule" <pavel.stehule@gmail.com> writes:
Tom Lane wrote:
Your point about the syntax is good though. It would be better if
the syntax were like
create function foo (a text, variadic b int[])
or maybe even better
create function foo (a text, variadic b int)I don't see problem with your syntax. It well block combination OUT
and VARIADIC parameter - my one request, variadic parameter have to be
array.Well, we should certainly store the parameter type as an array in
proargtypes, because that makes this feature transparent to all the
PLs. However, it doesn't follow that the CREATE FUNCTION syntax
has to specify the array type rather than the element type. I think
the Java precedent might be good reason to go with using the element
type in the function declaration.regards, tom lane
Hello
this is third variant with variadic argumen as scalar. But I still
strongly prefer second variant with conformance declared variadic
array with used array variable.
Regards
Pavel Stehule
Attachments:
variadic.2.2.1.difftext/x-patch; name=variadic.2.2.1.diffDownload+524-145
On Mon, 2008-06-23 at 15:13 +0200, Pavel Stehule wrote:
this patch enhance current syntax of CREATE FUNCTION statement. It
allows creating functions with variable number of arguments. This
version is different than last my patches. It doesn't need patching
PL. Basic idea is transformation of real arguments (related to
declared variadic argument) to array. All changes are mostly in
parser.
Something for the TODO.
An added thought with regard to variadic functions:
when we have them, we should be able to parse/transform repeated
operator sequences into a call to a variadic function, if it exists.
e.g. w || x || y || z can be transformed into a call to
concat_variadic(w, x, y, z)
This can then be made to perform better than
concat(concat(concat(w, x), y), z)
which would involve lots of wasted memory copies.
--
Simon Riggs www.2ndQuadrant.com
PostgreSQL Training, Services and Support