definition to serve for multiple input data types.
Here is an example of a polymorphic aggregate:
<programlisting>
CREATE AGGREGATE array_accum (anycompatible)
(
sfunc = array_append,
stype = anycompatiblearray,
initcond = '{}'
);
</programlisting>
Here, the actual state type for any given aggregate call is the array type
having the actual input type as elements. The behavior of the aggregate
is to concatenate all the inputs into an array of that type.
(Note: the built-in aggregate <function>array_agg</function> provides similar
functionality, with better performance than this definition would have.)
</para>
<para>
Here's the output using two different actual data types as arguments:
<programlisting>
SELECT attrelid::regclass, array_accum(attname)
FROM pg_attribute
WHERE attnum > 0 AND attrelid = 'pg_tablespace'::regclass
GROUP BY attrelid;
attrelid | array_accum
---------------+---------------------------------------
pg_tablespace | {spcname,spcowner,spcacl,spcoptions}
(1 row)
SELECT attrelid::regclass, array_accum(atttypid::regtype)
FROM pg_attribute
WHERE attnum > 0 AND attrelid = 'pg_tablespace'::regclass
GROUP BY attrelid;
attrelid | array_accum
---------------+---------------------------
pg_tablespace | {name,oid,aclitem[],text[]}
(1 row)
</programlisting>
</para>
<para>
Ordinarily, an aggregate function with a polymorphic result type has a
polymorphic state type, as in the above example. This is necessary
because otherwise the final function cannot be declared sensibly: it
would need to have a polymorphic result type but no polymorphic argument
type, which <command>CREATE FUNCTION</command> will reject on the grounds that
the result type cannot be deduced from a call. But sometimes it is
inconvenient to use a polymorphic state type. The most common case is
where the aggregate support functions are to be written in C and the
state type should be declared as <type>internal</type> because there is
no SQL-level equivalent for it. To address this case, it is possible to
declare the final function as taking extra <quote>dummy</quote> arguments
that match the input arguments of the aggregate. Such dummy arguments
are always passed as null values since no specific value is available when the
final function is called. Their only use is to allow a polymorphic
final function's result type to be connected to the aggregate's input
type(s). For example, the definition of the built-in
aggregate <function>array_agg</function> is equivalent to
<programlisting>
CREATE FUNCTION array_agg_transfn(internal, anynonarray)
RETURNS internal ...;
CREATE FUNCTION array_agg_finalfn(internal, anynonarray)
RETURNS anyarray ...;
CREATE AGGREGATE array_agg (anynonarray)
(
sfunc = array_agg_transfn,
stype = internal,
finalfunc = array_agg_finalfn,
finalfunc_extra
);
</programlisting>
Here, the <literal>finalfunc_extra</literal> option specifies that the final
function receives, in addition to the state value, extra dummy
argument(s) corresponding to the aggregate's input argument(s).
The extra <type>anynonarray</type> argument allows the declaration
of <function>array_agg_finalfn</function> to be valid.
</para>
<para>
An aggregate function can be made to accept a varying number of arguments
by declaring its last argument as a <literal>VARIADIC</literal> array, in much
the same fashion as for regular functions; see
<xref linkend="xfunc-sql-variadic-functions"/>. The aggregate's transition
function(s) must have the same array type as their last argument. The
transition function(s) typically would also be marked <literal>VARIADIC</literal>,
but this is not strictly required.
</para>
<note>
<para>
Variadic aggregates are easily misused in connection with
the <literal>ORDER BY</literal> option (see <xref linkend="syntax-aggregates"/>),