Variadic polymorpic functions

Started by Vincenzo Romanoabout 16 years ago25 messagesgeneral
Jump to latest
#1Vincenzo Romano
vincenzo.romano@notorand.it

Hi all.

I'm using the printf() function as seen here:
http://wiki.postgresql.org/wiki/Sprintf

What I see is that when I call that function with just 1 argument,
it's always OK.
As here:
-- code
mp1=# SELECT printf( '%',now() );
printf
-------------------------------
2010-01-22 18:31:24.045347+01
(1 row)

Time: 0.565 ms
tmp1=# SELECT printf( '%',3.1415926535 );
printf
--------------
3.1415926535
(1 row)

Time: 0.529 ms
-- end code

As soon as I put a second argument I get an arror:
-- code
tmp1=# SELECT printf( '% %',now(),42 );
ERROR: function printf(unknown, timestamp with time zone, integer)
does not exist
LINE 1: SELECT printf( '% %',now(),42 );
^
HINT: No function matches the given name and argument types. You
might need to add explicit type casts.
-- end code

which disapperas as soon as I cast all the parameters to text:
-- code
tmp1=# SELECT printf( '% %',now()::text,42::text );
printf
----------------------------------
2010-01-22 18:33:10.357877+01 42
(1 row)

Time: 1.956 ms
-- end code
or when all argument types have the same type:
-- code
tmp1=# SELECT printf( '% %',now(),now() );
printf
-------------------------------------------------------------
2010-01-22 18:34:07.055344+01 2010-01-22 18:34:07.055344+01
(1 row)

Time: 0.589 ms
-- end code
I was expecting that a "variadic polymorphic" function was able to
accept a "variable number of arguments of different types" (a-la C),
while it looks to me that it actually means "variable number of
arguments of a single type".

Is this limitation intentional or is it a bug?

--
Vincenzo Romano
NotOrAnd Information Technologies
NON QVIETIS MARIBVS NAVTA PERITVS

#2Tom Lane
tgl@sss.pgh.pa.us
In reply to: Vincenzo Romano (#1)
Re: Variadic polymorpic functions

Vincenzo Romano <vincenzo.romano@notorand.it> writes:

I'm using the printf() function as seen here:
http://wiki.postgresql.org/wiki/Sprintf

... which is "variadic anyarray".

I was expecting that a "variadic polymorphic" function was able to
accept a "variable number of arguments of different types" (a-la C),
while it looks to me that it actually means "variable number of
arguments of a single type".

Yup. The array can only contain one element type.

regards, tom lane

#3Vincenzo Romano
vincenzo.romano@notorand.it
In reply to: Tom Lane (#2)
Re: Variadic polymorpic functions

2010/1/22 Tom Lane <tgl@sss.pgh.pa.us>:

Vincenzo Romano <vincenzo.romano@notorand.it> writes:

I'm using the printf() function as seen here:
http://wiki.postgresql.org/wiki/Sprintf

... which is "variadic anyarray".

I was expecting that a "variadic polymorphic" function was able to
accept a "variable number of arguments of different types" (a-la C),
while it looks to me that it actually means "variable number of
arguments of a single type".

Yup.  The array can only contain one element type.

Understood.
So there's no way to have a function accepting a VARIADIC ANY. Right?

--
Vincenzo Romano
NotOrAnd Information Technologies
NON QVIETIS MARIBVS NAVTA PERITVS

#4Tom Lane
tgl@sss.pgh.pa.us
In reply to: Vincenzo Romano (#3)
Re: Variadic polymorpic functions

Vincenzo Romano <vincenzo.romano@notorand.it> writes:

So there's no way to have a function accepting a VARIADIC ANY. Right?

Not in PL functions. You can do it in C if you're desperate (but you
then have to deal with each argument individually --- they're not formed
into an array).

regards, tom lane

#5Vincenzo Romano
vincenzo.romano@notorand.it
In reply to: Tom Lane (#4)
Re: Variadic polymorpic functions

2010/1/22 Tom Lane <tgl@sss.pgh.pa.us>:

Vincenzo Romano <vincenzo.romano@notorand.it> writes:

So there's no way to have a function accepting a VARIADIC ANY. Right?

Not in PL functions.  You can do it in C if you're desperate (but you
then have to deal with each argument individually --- they're not formed
into an array).

How would then be declared such a function with the body written in C?

--
Vincenzo Romano
NotOrAnd Information Technologies
NON QVIETIS MARIBVS NAVTA PERITVS

#6Tom Lane
tgl@sss.pgh.pa.us
In reply to: Vincenzo Romano (#5)
Re: Variadic polymorpic functions

Vincenzo Romano <vincenzo.romano@notorand.it> writes:

2010/1/22 Tom Lane <tgl@sss.pgh.pa.us>:

Vincenzo Romano <vincenzo.romano@notorand.it> writes:

So there's no way to have a function accepting a VARIADIC ANY. Right?

Not in PL functions. �You can do it in C if you're desperate (but you
then have to deal with each argument individually --- they're not formed
into an array).

How would then be declared such a function with the body written in C?

I think "variadic any" is exactly it, but too lazy to go look.

regards, tom lane

#7Vincenzo Romano
vincenzo.romano@notorand.it
In reply to: Tom Lane (#6)
Re: Variadic polymorpic functions

2010/1/22 Tom Lane <tgl@sss.pgh.pa.us>:

Vincenzo Romano <vincenzo.romano@notorand.it> writes:

2010/1/22 Tom Lane <tgl@sss.pgh.pa.us>:

Vincenzo Romano <vincenzo.romano@notorand.it> writes:

So there's no way to have a function accepting a VARIADIC ANY. Right?

Not in PL functions.  You can do it in C if you're desperate (but you
then have to deal with each argument individually --- they're not formed
into an array).

How would then be declared such a function with the body written in C?

I think "variadic any" is exactly it, but too lazy to go look.

I fear there's no way!

tmp1=# CREATE FUNCTION q( fmt text, variadic args any )
RETURNS void
LANGUAGE plpgsql
AS $function$
declare
begin
end;
$function$;

ERROR: syntax error at or near "any"
LINE 1: CREATE FUNCTION q( fmt text, variadic args any )
^
tmp1=# CREATE FUNCTION q( fmt text, variadic args anyelement )
RETURNS void
LANGUAGE plpgsql
AS $function$
declare
begin
end;
$function$;

ERROR: VARIADIC parameter must be an array
#

--
Vincenzo Romano
NotOrAnd Information Technologies
NON QVIETIS MARIBVS NAVTA PERITVS

#8Tom Lane
tgl@sss.pgh.pa.us
In reply to: Vincenzo Romano (#7)
Re: Variadic polymorpic functions

Vincenzo Romano <vincenzo.romano@notorand.it> writes:

I think "variadic any" is exactly it, but too lazy to go look.

I fear there's no way!

tmp1=# CREATE FUNCTION q( fmt text, variadic args any )

More like this:

regression=# CREATE FUNCTION q( fmt text, variadic args "any" )
regression-# RETURNS void
regression-# LANGUAGE plpgsql
regression-# AS $function$
regression$# declare
regression$# begin
regression$# end;
regression$# $function$;
ERROR: PL/pgSQL functions cannot accept type "any"

ANY without quotes is a reserved word ...

regards, tom lane

#9Vincenzo Romano
vincenzo.romano@notorand.it
In reply to: Tom Lane (#8)
Re: Variadic polymorpic functions

2010/1/22 Tom Lane <tgl@sss.pgh.pa.us>:

Vincenzo Romano <vincenzo.romano@notorand.it> writes:

I think "variadic any" is exactly it, but too lazy to go look.

I fear there's no way!

tmp1=# CREATE FUNCTION q( fmt text, variadic args any )

More like this:

regression=# CREATE FUNCTION q( fmt text, variadic args "any" )
regression-# RETURNS void
regression-# LANGUAGE plpgsql
regression-# AS $function$
regression$# declare
regression$# begin
regression$# end;
regression$# $function$;
ERROR:  PL/pgSQL functions cannot accept type "any"

ANY without quotes is a reserved word ...

And this would allow for a stdarg-like argument list?

--
Vincenzo Romano
NotOrAnd Information Technologies
NON QVIETIS MARIBVS NAVTA PERITVS

#10Tom Lane
tgl@sss.pgh.pa.us
In reply to: Vincenzo Romano (#9)
Re: Variadic polymorpic functions

Vincenzo Romano <vincenzo.romano@notorand.it> writes:

2010/1/22 Tom Lane <tgl@sss.pgh.pa.us>:

regression=# CREATE FUNCTION q( fmt text, variadic args "any" )

And this would allow for a stdarg-like argument list?

Yeah, it should work, given suitable C code.

regards, tom lane

#11Vincenzo Romano
vincenzo.romano@notorand.it
In reply to: Tom Lane (#10)
Re: Variadic polymorpic functions

2010/1/22 Tom Lane <tgl@sss.pgh.pa.us>:

Vincenzo Romano <vincenzo.romano@notorand.it> writes:

2010/1/22 Tom Lane <tgl@sss.pgh.pa.us>:

regression=# CREATE FUNCTION q( fmt text, variadic args "any" )

And this would allow for a stdarg-like argument list?

Yeah, it should work, given suitable C code.

Great!

--
Vincenzo Romano
NotOrAnd Information Technologies
NON QVIETIS MARIBVS NAVTA PERITVS

#12Pavel Stehule
pavel.stehule@gmail.com
In reply to: Vincenzo Romano (#11)
Re: Variadic polymorpic functions

2010/1/22 Vincenzo Romano <vincenzo.romano@notorand.it>:

2010/1/22 Tom Lane <tgl@sss.pgh.pa.us>:

Vincenzo Romano <vincenzo.romano@notorand.it> writes:

2010/1/22 Tom Lane <tgl@sss.pgh.pa.us>:

regression=# CREATE FUNCTION q( fmt text, variadic args "any" )

And this would allow for a stdarg-like argument list?

Yeah, it should work, given suitable C code.

Great!

I wrote this function year ago.

look on content

http://pgfoundry.org/projects/pstcollection/

Regards
Pavel Stehule

Show quoted text

--
Vincenzo Romano
NotOrAnd Information Technologies
NON QVIETIS MARIBVS NAVTA PERITVS

--
Sent via pgsql-general mailing list (pgsql-general@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-general

#13Vincenzo Romano
vincenzo.romano@notorand.it
In reply to: Pavel Stehule (#12)
Re: Variadic polymorpic functions

2010/1/23 Pavel Stehule <pavel.stehule@gmail.com>:

2010/1/22 Vincenzo Romano <vincenzo.romano@notorand.it>:

2010/1/22 Tom Lane <tgl@sss.pgh.pa.us>:

Vincenzo Romano <vincenzo.romano@notorand.it> writes:

2010/1/22 Tom Lane <tgl@sss.pgh.pa.us>:

regression=# CREATE FUNCTION q( fmt text, variadic args "any" )

And this would allow for a stdarg-like argument list?

Yeah, it should work, given suitable C code.

Great!

I wrote this function year ago.

look on content

http://pgfoundry.org/projects/pstcollection/

Pavel,
that format() function should be included into official contribs.
What about HOWTO compile?

#14Pavel Stehule
pavel.stehule@gmail.com
In reply to: Vincenzo Romano (#13)
Re: Variadic polymorpic functions

2010/1/25 Vincenzo Romano <vincenzo.romano@notorand.it>:

2010/1/23 Pavel Stehule <pavel.stehule@gmail.com>:

2010/1/22 Vincenzo Romano <vincenzo.romano@notorand.it>:

2010/1/22 Tom Lane <tgl@sss.pgh.pa.us>:

Vincenzo Romano <vincenzo.romano@notorand.it> writes:

2010/1/22 Tom Lane <tgl@sss.pgh.pa.us>:

regression=# CREATE FUNCTION q( fmt text, variadic args "any" )

And this would allow for a stdarg-like argument list?

Yeah, it should work, given suitable C code.

Great!

I wrote this function year ago.

look on content

http://pgfoundry.org/projects/pstcollection/

Pavel,
that format() function should be included into official contribs.
What about HOWTO compile?

There are not consensus about final semantic - some people prefer
sprintf like, some others PostgreSQL RAISE NOTICE like. so I'll keep
it outside. I looking on source of pstcollection - missing
documentation, missing regress test. I never rebuild it outside
PostgreSQL source tree - so it could be problem. Now: copy src to
contrib directory, make, make install - like standard contrib module.

If you would to add some doc or notes, please, add it.

Pavel

Show quoted text
#15Vincenzo Romano
vincenzo.romano@notorand.it
In reply to: Pavel Stehule (#14)
Re: Variadic polymorpic functions

2010/1/25 Pavel Stehule <pavel.stehule@gmail.com>:

2010/1/25 Vincenzo Romano <vincenzo.romano@notorand.it>:

2010/1/23 Pavel Stehule <pavel.stehule@gmail.com>:

2010/1/22 Vincenzo Romano <vincenzo.romano@notorand.it>:

2010/1/22 Tom Lane <tgl@sss.pgh.pa.us>:

Vincenzo Romano <vincenzo.romano@notorand.it> writes:

2010/1/22 Tom Lane <tgl@sss.pgh.pa.us>:

regression=# CREATE FUNCTION q( fmt text, variadic args "any" )

And this would allow for a stdarg-like argument list?

Yeah, it should work, given suitable C code.

Great!

I wrote this function year ago.

look on content

http://pgfoundry.org/projects/pstcollection/

Pavel,
that format() function should be included into official contribs.
What about HOWTO compile?

There are not consensus about final semantic - some people prefer
sprintf like, some others PostgreSQL RAISE NOTICE like. so I'll keep
it outside. I looking on source of pstcollection - missing
documentation, missing regress test. I never rebuild it outside
PostgreSQL source tree - so it could be problem. Now: copy src to
contrib directory, make, make install - like standard contrib module.

If you would to add some doc or notes, please, add it.

I figured that out (from the Makefile)
USE_PGXS=1 make install

--
Vincenzo Romano
NotOrAnd Information Technologies
NON QVIETIS MARIBVS NAVTA PERITVS

#16Pavel Stehule
pavel.stehule@gmail.com
In reply to: Vincenzo Romano (#15)
Re: Variadic polymorpic functions

2010/1/25 Vincenzo Romano <vincenzo.romano@notorand.it>:

2010/1/25 Pavel Stehule <pavel.stehule@gmail.com>:

2010/1/25 Vincenzo Romano <vincenzo.romano@notorand.it>:

2010/1/23 Pavel Stehule <pavel.stehule@gmail.com>:

2010/1/22 Vincenzo Romano <vincenzo.romano@notorand.it>:

2010/1/22 Tom Lane <tgl@sss.pgh.pa.us>:

Vincenzo Romano <vincenzo.romano@notorand.it> writes:

2010/1/22 Tom Lane <tgl@sss.pgh.pa.us>:

regression=# CREATE FUNCTION q( fmt text, variadic args "any" )

And this would allow for a stdarg-like argument list?

Yeah, it should work, given suitable C code.

Great!

I wrote this function year ago.

look on content

http://pgfoundry.org/projects/pstcollection/

Pavel,
that format() function should be included into official contribs.
What about HOWTO compile?

There are not consensus about final semantic - some people prefer
sprintf like, some others PostgreSQL RAISE NOTICE like. so I'll keep
it outside. I looking on source of pstcollection - missing
documentation, missing regress test. I never rebuild it outside
PostgreSQL source tree - so it could be problem. Now: copy src to
contrib directory, make, make install - like standard contrib module.

If you would to add some doc or notes, please, add it.

I figured that out (from the Makefile)
USE_PGXS=1 make install

ok, if you would, add account on pgfoundry

I'll add you to developer group for pstcollection

Pavel

Show quoted text

--
Vincenzo Romano
NotOrAnd Information Technologies
NON QVIETIS MARIBVS NAVTA PERITVS

#17Vincenzo Romano
vincenzo.romano@notorand.it
In reply to: Pavel Stehule (#14)
Re: Variadic polymorpic functions

2010/1/25 Pavel Stehule <pavel.stehule@gmail.com>:

2010/1/25 Vincenzo Romano <vincenzo.romano@notorand.it>:

2010/1/23 Pavel Stehule <pavel.stehule@gmail.com>:

2010/1/22 Vincenzo Romano <vincenzo.romano@notorand.it>:

2010/1/22 Tom Lane <tgl@sss.pgh.pa.us>:

Vincenzo Romano <vincenzo.romano@notorand.it> writes:

2010/1/22 Tom Lane <tgl@sss.pgh.pa.us>:

regression=# CREATE FUNCTION q( fmt text, variadic args "any" )

And this would allow for a stdarg-like argument list?

Yeah, it should work, given suitable C code.

Great!

I wrote this function year ago.

look on content

http://pgfoundry.org/projects/pstcollection/

Pavel,
that format() function should be included into official contribs.
What about HOWTO compile?

There are not consensus about final semantic - some people prefer
sprintf like, some others PostgreSQL RAISE NOTICE like.

Whatever you prefer would be OK as far as it is documented.
In my opinion, the main usage for such a function is in the dynamic SQL code
generation in PL/PgSQL functions:

EXECUTE pst.format( .... );

In this very case the sprintf-like syntax/semantics would be much more
powerful, but
the current one is OK if you think that there's nothing similar at the moment.

Again, this function looks to be a badly missing one and including it
at least into the
default contrib collection would help a lot of users.

--
Vincenzo Romano
NotOrAnd Information Technologies
NON QVIETIS MARIBVS NAVTA PERITVS

#18Pavel Stehule
pavel.stehule@gmail.com
In reply to: Vincenzo Romano (#17)
Re: Variadic polymorpic functions

2010/1/25 Vincenzo Romano <vincenzo.romano@notorand.it>:

2010/1/25 Pavel Stehule <pavel.stehule@gmail.com>:

2010/1/25 Vincenzo Romano <vincenzo.romano@notorand.it>:

2010/1/23 Pavel Stehule <pavel.stehule@gmail.com>:

2010/1/22 Vincenzo Romano <vincenzo.romano@notorand.it>:

2010/1/22 Tom Lane <tgl@sss.pgh.pa.us>:

Vincenzo Romano <vincenzo.romano@notorand.it> writes:

2010/1/22 Tom Lane <tgl@sss.pgh.pa.us>:

regression=# CREATE FUNCTION q( fmt text, variadic args "any" )

And this would allow for a stdarg-like argument list?

Yeah, it should work, given suitable C code.

Great!

I wrote this function year ago.

look on content

http://pgfoundry.org/projects/pstcollection/

Pavel,
that format() function should be included into official contribs.
What about HOWTO compile?

There are not consensus about final semantic - some people prefer
sprintf like, some others PostgreSQL RAISE NOTICE like.

Whatever you prefer would be OK as far as it is documented.
In my opinion, the main usage for such a function is in the dynamic SQL code
generation in PL/PgSQL functions:

EXECUTE pst.format( .... );

It could be used for expansion packed values - like formated error messages, ...

In this very case the sprintf-like syntax/semantics would be much more
powerful, but
the current one is OK if you think that there's nothing similar at the moment.

sprintf is more powerful, but more complex too. You don't need some
specific number formating. We have a formating function to_char, so
sprintf is duplicate.

Again, this function looks to be a badly missing one and including it
at least into the
default contrib collection would help a lot of users.

I can remove date function from pstcol and I can move it to some
string helper function contrib module.

Pavel

Show quoted text

--
Vincenzo Romano
NotOrAnd Information Technologies
NON QVIETIS MARIBVS NAVTA PERITVS

#19Pavel Stehule
pavel.stehule@gmail.com
In reply to: Vincenzo Romano (#17)
Re: Variadic polymorpic functions

Hello

I add sprintf function. Now I think, we can add new contrib module
(string functions) with both function - format and sprintf. These
functions are relative different, so they can exists separately.
Format is simpler and faster. Sprintf is more powerful but slower.

postgres=# select pst.format('now is %', current_time);
format
---------------------------
now is 16:34:26.203728+01
(1 row)

postgres=# select pst.sprintf('now is %s', current_time);
sprintf
--------------------------
now is 16:34:45.24919+01

Regards
Pavel Stehule

2010/1/25 Vincenzo Romano <vincenzo.romano@notorand.it>:

Show quoted text

2010/1/25 Pavel Stehule <pavel.stehule@gmail.com>:

2010/1/25 Vincenzo Romano <vincenzo.romano@notorand.it>:

2010/1/23 Pavel Stehule <pavel.stehule@gmail.com>:

2010/1/22 Vincenzo Romano <vincenzo.romano@notorand.it>:

2010/1/22 Tom Lane <tgl@sss.pgh.pa.us>:

Vincenzo Romano <vincenzo.romano@notorand.it> writes:

2010/1/22 Tom Lane <tgl@sss.pgh.pa.us>:

regression=# CREATE FUNCTION q( fmt text, variadic args "any" )

And this would allow for a stdarg-like argument list?

Yeah, it should work, given suitable C code.

Great!

I wrote this function year ago.

look on content

http://pgfoundry.org/projects/pstcollection/

Pavel,
that format() function should be included into official contribs.
What about HOWTO compile?

There are not consensus about final semantic - some people prefer
sprintf like, some others PostgreSQL RAISE NOTICE like.

Whatever you prefer would be OK as far as it is documented.
In my opinion, the main usage for such a function is in the dynamic SQL code
generation in PL/PgSQL functions:

EXECUTE pst.format( .... );

In this very case the sprintf-like syntax/semantics would be much more
powerful, but
the current one is OK if you think that there's nothing similar at the moment.

Again, this function looks to be a badly missing one and including it
at least into the
default contrib collection would help a lot of users.

--
Vincenzo Romano
NotOrAnd Information Technologies
NON QVIETIS MARIBVS NAVTA PERITVS

Attachments:

pstcoll.tar.gzapplication/x-gzip; name=pstcoll.tar.gzDownload
#20Vincenzo Romano
vincenzo.romano@notorand.it
In reply to: Pavel Stehule (#19)
Re: Variadic polymorpic functions

2010/1/27 Pavel Stehule <pavel.stehule@gmail.com>:

Hello

I add sprintf function. Now I think, we can add new contrib module
(string functions) with both function - format and sprintf. These
functions are relative different, so they can exists separately.
Format is simpler and faster. Sprintf is more powerful but slower.

postgres=# select pst.format('now is %', current_time);
         format
---------------------------
 now is 16:34:26.203728+01
(1 row)

postgres=# select pst.sprintf('now is %s', current_time);
        sprintf
--------------------------
 now is 16:34:45.24919+01

Regards
Pavel Stehule

Yeah!

But why still on separate schema?
I'd rather put them all in the public one, so you don't need the "pst." anymore.
Just like (most of) all other contrib mudules ...

#21Pavel Stehule
pavel.stehule@gmail.com
In reply to: Vincenzo Romano (#20)
#22Tom Lane
tgl@sss.pgh.pa.us
In reply to: Vincenzo Romano (#20)
#23Vincenzo Romano
vincenzo.romano@notorand.it
In reply to: Pavel Stehule (#21)
#24Pavel Stehule
pavel.stehule@gmail.com
In reply to: Tom Lane (#22)
#25Vincenzo Romano
vincenzo.romano@notorand.it
In reply to: Tom Lane (#22)