Thread: why VARIADIC functions executed on array input?
CREATE FUNCTION foo (VARIADIC anyarray) RETURNS void AS $$ DECLARE BEGIN END $$ LANGUAGE plpgsql; SELECT foo (ARRAY[1]); I would expect an error: Like: ERROR: function f3oo(integer[]) does not exist But I get this error: ERROR: could not find array type for data type integer[] Why VARIADIC functions are found on array input? In my opinion it makes no sense and the disadvantage is that overloading with a function like: CREATE OR REPLACE FUNCTION foo (anyarray) doesn't work. Greetings Tjibbe see example in: http://sqlfiddle.com/#!15/300e8/1 -- +31 6 29401726 tjibbe@rijpma.org Jacobusstraat 185 3012 JM Rotterdam
On Wed, Feb 19, 2014 at 8:17 AM, Tjibbe <tjibbe@rijpma.org> wrote: > CREATE FUNCTION foo (VARIADIC anyarray) RETURNS void AS $$ > DECLARE > BEGIN > END > $$ LANGUAGE plpgsql; > SELECT foo (ARRAY[1]); > > I would expect an error: Like: > ERROR: function f3oo(integer[]) does not exist > > But I get this error: > ERROR: could not find array type for data type integer[] > > Why VARIADIC functions are found on array input? In my opinion it > makes no sense and the disadvantage is that overloading with a > function like: CREATE OR REPLACE FUNCTION foo (anyarray) doesn't > work. There are three things working against you here. #1: sql (and pl/pgsql) level functions have very simple variadic handling. They only support a single type which is converted to array #2: postgres isn't smart enough to make arrays of arrays. This can be worked around in other cases but not here since you're not in control of the array creating statement. That might be fixed some day but won't help you in this case unless the way dimensions work is restructured (which I think unlikely). #3: the right way to do variadic functions is variadic "any", but via #1 you can only do this in C. When you add these together, it comes up with sql level user defined variadic functions can't take array arguments. The workaround isn't too bad: just work everything to text. CREATE FUNCTION foo (VARIADIC anyarray) RETURNS void AS $$ DECLARE r record; BEGIN FOR r IN SELECT unnest(unnest($1)::text[]) LOOP RAISE NOTICE '%', r; END LOOP; END $$ LANGUAGE plpgsql; select foo(array[1,2,3]::text, array['foo','bar']::text); NOTICE: (1) NOTICE: (2) NOTICE: (3) NOTICE: (foo) NOTICE: (bar) foo ----- (1 row) note: the elements inside may have to be casted back from text depending on what you want to do with them. merlin
Hello
2014-02-19 15:17 GMT+01:00 Tjibbe <tjibbe@rijpma.org>:
CREATE FUNCTION foo (VARIADIC anyarray) RETURNS void AS $$
DECLARE
BEGIN
END
$$ LANGUAGE plpgsql;
SELECT foo (ARRAY[1]);
I would expect an error: Like:
ERROR: function f3oo(integer[]) does not exist
But I get this error:
ERROR: could not find array type for data type integer[]
Why VARIADIC functions are found on array input? In my opinion it
makes no sense and the disadvantage is that overloading with a
function like: CREATE OR REPLACE FUNCTION foo (anyarray) doesn't
work.
A variadic functions are exception in mechanism, how postgres choose any specific function. Usually parser try to search function with same name and most similar parameter types list. Variadic functions works differently - we try to dynamically prepare parameter list to be able consume values specified by caller. This mechanism has some corner cases - we are not able detect all possible ambiguous parameters in creation time, and some times it raises little bit unclean messages, but generally it works well - but every enhancing is welcome
Regards
Pavel
Pavel
Greetings Tjibbe
see example in: http://sqlfiddle.com/#!15/300e8/1
--
+31 6 29401726
tjibbe@rijpma.org
Jacobusstraat 185
3012 JM Rotterdam
--
Sent via pgsql-general mailing list (pgsql-general@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-general