I would like to create a function that given a value of any type, a dimension of the one-dimensional array and the column to set, will return a one-dimensional array filled with null values except for one given value at a given position.
The code bellow is what I created tentatively to do it but it does not work:
create function arraycol(v anyelement,n int,i int)
returns anyarray language plpgsql as $$
declare r anyarray;
begin
r=array_fill(null,array[n]);
r[i]=v;
return r;
end $$;
Is it possible to have the function return a polymorphic array type?
is it possible to create a variable of polymorphic element type?
2
Answers
You were close.
r anyarray;
isn’t valid syntax to declare a variable of the polymorphic input typeanyarray
. To declare a variable of polymorphic input type use the%TYPE
construct:Unfortunately in this case, we only have a parameter of type
anyelement
to work with, which makes it tricky. See:I use an
OUT
parameter or typeanyarray
instead, to simplify.Also, you need to pass the actual element type to the function
array_fill()
. An un-typednull
won’t do. To skip variable declaration completely I produce the typed null value ad-hoc withNULLIF(v, v)
:Equivalent variant without
array_fill()
. In the assignments, an un-typed null works:fiddle
Same call, same result. Example:
Of course, I’d put in checks to enforce sane input. Like, enforce dimension input > 1.
Postgres won’t let you
declare r anyarray;
ordeclare r v%type[]
. What it won’t mind at all is if you already have it declared by that point:It’s not strictly the same as returning via an
OUT
parameter –r
‘s argmode is the defaultIN
but effectively, it’s achieving pretty much the same goal, pretty much the same way as that.Demo at db<>fiddle:
One thing it won’t do is give you arrays of arrays.
Even if you swap out
anycompatiblenonarray
for a regularanycompatible
Which might be for the better, because all this feels very wrong.
Here’s how you can also do that in plain SQL:
Which according to the tests at the end of the demo is a nice way to butcher your performance.