Home Explore Blog CI



postgresql

5th chunk of `doc/src/sgml/xaggr.sgml`
4a4ac0df9a6ed4a8f361ef1357960042a2b03874040ebfe40000000100000fbd
 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 &gt; 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 &gt; 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"/>),

Title: Polymorphic and Variadic Aggregates
Summary
Polymorphic aggregates can serve multiple input data types, and their state type can be declared as internal for C-based support functions, while variadic aggregates can accept a varying number of arguments using a VARIADIC array, allowing for flexible and dynamic aggregation functionality.