I am trying to write a PostgreSQL array_agg() variant that returns the empty array '{}' instead of NULL. Trying to avoid the performance hit of custom aggregate functions with CREATE AGGRGATE, I tried to re-use the built-in array_agg_transfn and array_agg_finalfn. Starting from the code example in the documentation, an initial version similar to array_agg works (as DB superuser):
CREATE AGGREGATE array_agg_z (anynonarray)
(
sfunc = array_agg_transfn,
stype = internal,
finalfunc = array_agg_finalfn,
finalfunc_extra
);
And it returns NULL on empty input as expected:
=> SELECT array_agg_z(i) IS NULL FROM (SELECT 0 WHERE 1 = 2) t(i);
?column?
----------
t
(1 row)
Now, to change array_agg_z() to return empty array on empty input, I attempted to set the initcond to '{}' as follows:
CREATE AGGREGATE array_agg_z (anynonarray)
(
sfunc = array_agg_transfn,
stype = internal,
finalfunc = array_agg_finalfn,
initcond = '{}',
finalfunc_extra
);
Now it's giving an error:
=> SELECT array_agg_z(i) IS NULL FROM (SELECT 0 WHERE 1 = 2) t(i);
ERROR: cannot accept a value of type internal
How to work around this?
Or do I have to hack the C source code related to array_agg() to make this variant?
By the way, this is with PostgreSQL 12.
coalesce(array_agg(...), '{}')?