mirror of
https://github.com/postgres/postgres.git
synced 2025-08-30 06:01:21 +03:00
Allow polymorphic aggregates to have non-polymorphic state data types.
Before 9.4, such an aggregate couldn't be declared, because its final function would have to have polymorphic result type but no polymorphic argument, which CREATE FUNCTION would quite properly reject. The ordered-set-aggregate patch found a workaround: allow the final function to be declared as accepting additional dummy arguments that have types matching the aggregate's regular input arguments. However, we failed to notice that this problem applies just as much to regular aggregates, despite the fact that we had a built-in regular aggregate array_agg() that was known to be undeclarable in SQL because its final function had an illegal signature. So what we should have done, and what this patch does, is to decouple the extra-dummy-arguments behavior from ordered-set aggregates and make it generally available for all aggregate declarations. We have to put this into 9.4 rather than waiting till later because it slightly alters the rules for declaring ordered-set aggregates. The patch turned out a bit bigger than I'd hoped because it proved necessary to record the extra-arguments option in a new pg_aggregate column. I'd thought we could just look at the final function's pronargs at runtime, but that didn't work well for variadic final functions. It's probably just as well though, because it simplifies life for pg_dump to record the option explicitly. While at it, fix array_agg() to have a valid final-function signature, and add an opr_sanity test to notice future deviations from polymorphic consistency. I also marked the percentile_cont() aggregates as not needing extra arguments, since they don't.
This commit is contained in:
@@ -26,12 +26,14 @@ CREATE AGGREGATE <replaceable class="parameter">name</replaceable> ( [ <replacea
|
||||
STYPE = <replaceable class="PARAMETER">state_data_type</replaceable>
|
||||
[ , SSPACE = <replaceable class="PARAMETER">state_data_size</replaceable> ]
|
||||
[ , FINALFUNC = <replaceable class="PARAMETER">ffunc</replaceable> ]
|
||||
[ , FINALFUNC_EXTRA ]
|
||||
[ , INITCOND = <replaceable class="PARAMETER">initial_condition</replaceable> ]
|
||||
[ , MSFUNC = <replaceable class="PARAMETER">msfunc</replaceable> ]
|
||||
[ , MINVFUNC = <replaceable class="PARAMETER">minvfunc</replaceable> ]
|
||||
[ , MSTYPE = <replaceable class="PARAMETER">mstate_data_type</replaceable> ]
|
||||
[ , MSSPACE = <replaceable class="PARAMETER">mstate_data_size</replaceable> ]
|
||||
[ , MFINALFUNC = <replaceable class="PARAMETER">mffunc</replaceable> ]
|
||||
[ , MFINALFUNC_EXTRA ]
|
||||
[ , MINITCOND = <replaceable class="PARAMETER">minitial_condition</replaceable> ]
|
||||
[ , SORTOP = <replaceable class="PARAMETER">sort_operator</replaceable> ]
|
||||
)
|
||||
@@ -42,6 +44,7 @@ CREATE AGGREGATE <replaceable class="parameter">name</replaceable> ( [ [ <replac
|
||||
STYPE = <replaceable class="PARAMETER">state_data_type</replaceable>
|
||||
[ , SSPACE = <replaceable class="PARAMETER">state_data_size</replaceable> ]
|
||||
[ , FINALFUNC = <replaceable class="PARAMETER">ffunc</replaceable> ]
|
||||
[ , FINALFUNC_EXTRA ]
|
||||
[ , INITCOND = <replaceable class="PARAMETER">initial_condition</replaceable> ]
|
||||
[ , HYPOTHETICAL ]
|
||||
)
|
||||
@@ -54,12 +57,14 @@ CREATE AGGREGATE <replaceable class="PARAMETER">name</replaceable> (
|
||||
STYPE = <replaceable class="PARAMETER">state_data_type</replaceable>
|
||||
[ , SSPACE = <replaceable class="PARAMETER">state_data_size</replaceable> ]
|
||||
[ , FINALFUNC = <replaceable class="PARAMETER">ffunc</replaceable> ]
|
||||
[ , FINALFUNC_EXTRA ]
|
||||
[ , INITCOND = <replaceable class="PARAMETER">initial_condition</replaceable> ]
|
||||
[ , MSFUNC = <replaceable class="PARAMETER">sfunc</replaceable> ]
|
||||
[ , MINVFUNC = <replaceable class="PARAMETER">invfunc</replaceable> ]
|
||||
[ , MSTYPE = <replaceable class="PARAMETER">state_data_type</replaceable> ]
|
||||
[ , MSSPACE = <replaceable class="PARAMETER">state_data_size</replaceable> ]
|
||||
[ , MFINALFUNC = <replaceable class="PARAMETER">ffunc</replaceable> ]
|
||||
[ , MFINALFUNC_EXTRA ]
|
||||
[ , MINITCOND = <replaceable class="PARAMETER">initial_condition</replaceable> ]
|
||||
[ , SORTOP = <replaceable class="PARAMETER">sort_operator</replaceable> ]
|
||||
)
|
||||
@@ -166,12 +171,25 @@ CREATE AGGREGATE <replaceable class="PARAMETER">name</replaceable> (
|
||||
input rows.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Sometimes it is useful to declare the final function as taking not just
|
||||
the state value, but extra parameters corresponding to the aggregate's
|
||||
input values. The main reason for doing this is if the final function
|
||||
is polymorphic and the state value's data type would be inadequate to
|
||||
pin down the result type. These extra parameters are always passed as
|
||||
NULL (and so the final function must not be strict when
|
||||
the <literal>FINALFUNC_EXTRA</> option is used), but nonetheless they
|
||||
are valid parameters. The final function could for example make use
|
||||
of <function>get_fn_expr_argtype</> to identify the actual argument type
|
||||
in the current call.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
An aggregate can optionally support <firstterm>moving-aggregate mode</>,
|
||||
as described in <xref linkend="xaggr-moving-aggregates">. This requires
|
||||
specifying the <literal>MSFUNC</>, <literal>MINVFUNC</>,
|
||||
and <literal>MSTYPE</> parameters, and optionally
|
||||
the <literal>MSPACE</>, <literal>MFINALFUNC</>,
|
||||
the <literal>MSPACE</>, <literal>MFINALFUNC</>, <literal>MFINALFUNC_EXTRA</>,
|
||||
and <literal>MINITCOND</> parameters. Except for <literal>MINVFUNC</>,
|
||||
these parameters work like the corresponding simple-aggregate parameters
|
||||
without <literal>M</>; they define a separate implementation of the
|
||||
@@ -361,12 +379,16 @@ SELECT col FROM tab ORDER BY col USING sortop LIMIT 1;
|
||||
<para>
|
||||
For ordered-set (including hypothetical-set) aggregates, the
|
||||
final function receives not only the final state value,
|
||||
but also the values of all the direct arguments, followed by
|
||||
null values corresponding to each aggregated argument.
|
||||
(The reason for including the aggregated arguments in the function
|
||||
signature is that this may be necessary to allow correct resolution
|
||||
of the aggregate result type, when a polymorphic aggregate is
|
||||
being defined.)
|
||||
but also the values of all the direct arguments.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
If <literal>FINALFUNC_EXTRA</> is specified, then in addition to the
|
||||
final state value and any direct arguments, the final function
|
||||
receives extra NULL values corresponding to the aggregate's regular
|
||||
(aggregated) arguments. This is mainly useful to allow correct
|
||||
resolution of the aggregate result type when a polymorphic aggregate
|
||||
is being defined.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
@@ -438,9 +460,11 @@ SELECT col FROM tab ORDER BY col USING sortop LIMIT 1;
|
||||
The name of the final function called to compute the aggregate's
|
||||
result after all input rows have been traversed, when using
|
||||
moving-aggregate mode. This works the same as <replaceable>ffunc</>,
|
||||
except that its input type is <replaceable>mstate_data_type</>.
|
||||
except that its first argument's type
|
||||
is <replaceable>mstate_data_type</> and extra dummy arguments are
|
||||
specified by writing <literal>MFINALFUNC_EXTRA</>.
|
||||
The aggregate result type determined by <replaceable>mffunc</>
|
||||
and <replaceable>mstate_data_type</> must match that determined by the
|
||||
or <replaceable>mstate_data_type</> must match that determined by the
|
||||
aggregate's regular implementation.
|
||||
</para>
|
||||
</listitem>
|
||||
@@ -494,6 +518,13 @@ SELECT col FROM tab ORDER BY col USING sortop LIMIT 1;
|
||||
<refsect1>
|
||||
<title>Notes</title>
|
||||
|
||||
<para>
|
||||
In parameters that specify support function names, you can write
|
||||
a schema name if needed, for example <literal>SFUNC = public.sum</>.
|
||||
Do not write argument types there, however — the argument types
|
||||
of the support functions are determined from other parameters.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
If an aggregate supports moving-aggregate mode, it will improve
|
||||
calculation efficiency when the aggregate is used as a window function
|
||||
|
Reference in New Issue
Block a user