<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"/>),
since the parser cannot tell whether the wrong number of actual arguments
have been given in such a combination. Keep in mind that everything to
the right of <literal>ORDER BY</literal> is a sort key, not an argument to the
aggregate. For example, in
<programlisting>
SELECT myaggregate(a ORDER BY a, b, c) FROM ...
</programlisting>
the parser will see this as a single aggregate function argument and
three sort keys. However, the user might have intended
<programlisting>
SELECT myaggregate(a, b, c ORDER BY a) FROM ...
</programlisting>
If <literal>myaggregate</literal> is variadic, both these calls could be
perfectly valid.
</para>
<para>
For the same reason, it's wise to think twice before creating aggregate
functions with the same names and different numbers of regular arguments.
</para>
</note>
</sect2>
<sect2 id="xaggr-ordered-set-aggregates">
<title>Ordered-Set Aggregates</title>
<indexterm>
<primary>aggregate function</primary>
<secondary>ordered set</secondary>
</indexterm>
<para>
The aggregates we have been describing so far are <quote>normal</quote>
aggregates. <productname>PostgreSQL</productname> also
supports <firstterm>ordered-set aggregates</firstterm>, which differ from
normal aggregates in two key ways. First, in addition to ordinary
aggregated arguments that are evaluated once per input row, an
ordered-set aggregate can have <quote>direct</quote> arguments that are
evaluated only once per aggregation operation. Second, the syntax
for the ordinary aggregated arguments specifies a sort ordering
for them explicitly. An ordered-set aggregate is usually
used to implement a computation that depends on a specific row
ordering, for instance rank or percentile, so that the sort ordering
is a required aspect of any call. For example, the built-in
definition of <function>percentile_disc</function> is equivalent to:
<programlisting>
CREATE FUNCTION ordered_set_transition(internal, anyelement)
RETURNS internal ...;
CREATE FUNCTION percentile_disc_final(internal, float8, anyelement)
RETURNS anyelement ...;
CREATE AGGREGATE percentile_disc (float8 ORDER BY anyelement)
(
sfunc = ordered_set_transition,
stype = internal,
finalfunc = percentile_disc_final,
finalfunc_extra
);
</programlisting>
This aggregate takes a <type>float8</type> direct argument (the percentile
fraction) and an aggregated input that can be of any sortable data type.
It could be used to obtain a median household income like this:
<programlisting>
SELECT percentile_disc(0.5) WITHIN GROUP (ORDER BY income) FROM households;
percentile_disc
-----------------
50489
</programlisting>
Here, <literal>0.5</literal> is a direct argument; it would make no sense
for the percentile fraction to be a value varying across rows.
</para>
<para>
Unlike the case for normal aggregates, the sorting of input rows