@@ -27,6 +27,7 @@ CREATE AGGREGATE <replaceable class="parameter">name</replaceable> ( [ <replacea
27
27
[ , SSPACE = <replaceable class="parameter">state_data_size</replaceable> ]
28
28
[ , FINALFUNC = <replaceable class="parameter">ffunc</replaceable> ]
29
29
[ , FINALFUNC_EXTRA ]
30
+ [ , FINALFUNC_MODIFY = { READ_ONLY | SHARABLE | READ_WRITE } ]
30
31
[ , COMBINEFUNC = <replaceable class="parameter">combinefunc</replaceable> ]
31
32
[ , SERIALFUNC = <replaceable class="parameter">serialfunc</replaceable> ]
32
33
[ , DESERIALFUNC = <replaceable class="parameter">deserialfunc</replaceable> ]
@@ -37,6 +38,7 @@ CREATE AGGREGATE <replaceable class="parameter">name</replaceable> ( [ <replacea
37
38
[ , MSSPACE = <replaceable class="parameter">mstate_data_size</replaceable> ]
38
39
[ , MFINALFUNC = <replaceable class="parameter">mffunc</replaceable> ]
39
40
[ , MFINALFUNC_EXTRA ]
41
+ [ , MFINALFUNC_MODIFY = { READ_ONLY | SHARABLE | READ_WRITE } ]
40
42
[ , MINITCOND = <replaceable class="parameter">minitial_condition</replaceable> ]
41
43
[ , SORTOP = <replaceable class="parameter">sort_operator</replaceable> ]
42
44
[ , PARALLEL = { SAFE | RESTRICTED | UNSAFE } ]
@@ -49,6 +51,7 @@ CREATE AGGREGATE <replaceable class="parameter">name</replaceable> ( [ [ <replac
49
51
[ , SSPACE = <replaceable class="parameter">state_data_size</replaceable> ]
50
52
[ , FINALFUNC = <replaceable class="parameter">ffunc</replaceable> ]
51
53
[ , FINALFUNC_EXTRA ]
54
+ [ , FINALFUNC_MODIFY = { READ_ONLY | SHARABLE | READ_WRITE } ]
52
55
[ , INITCOND = <replaceable class="parameter">initial_condition</replaceable> ]
53
56
[ , PARALLEL = { SAFE | RESTRICTED | UNSAFE } ]
54
57
[ , HYPOTHETICAL ]
@@ -63,6 +66,7 @@ CREATE AGGREGATE <replaceable class="parameter">name</replaceable> (
63
66
[ , SSPACE = <replaceable class="parameter">state_data_size</replaceable> ]
64
67
[ , FINALFUNC = <replaceable class="parameter">ffunc</replaceable> ]
65
68
[ , FINALFUNC_EXTRA ]
69
+ [ , FINALFUNC_MODIFY = { READ_ONLY | SHARABLE | READ_WRITE } ]
66
70
[ , COMBINEFUNC = <replaceable class="parameter">combinefunc</replaceable> ]
67
71
[ , SERIALFUNC = <replaceable class="parameter">serialfunc</replaceable> ]
68
72
[ , DESERIALFUNC = <replaceable class="parameter">deserialfunc</replaceable> ]
@@ -73,6 +77,7 @@ CREATE AGGREGATE <replaceable class="parameter">name</replaceable> (
73
77
[ , MSSPACE = <replaceable class="parameter">mstate_data_size</replaceable> ]
74
78
[ , MFINALFUNC = <replaceable class="parameter">mffunc</replaceable> ]
75
79
[ , MFINALFUNC_EXTRA ]
80
+ [ , MFINALFUNC_MODIFY = { READ_ONLY | SHARABLE | READ_WRITE } ]
76
81
[ , MINITCOND = <replaceable class="parameter">minitial_condition</replaceable> ]
77
82
[ , SORTOP = <replaceable class="parameter">sort_operator</replaceable> ]
78
83
)
@@ -197,7 +202,8 @@ CREATE AGGREGATE <replaceable class="parameter">name</replaceable> (
197
202
as described in <xref linkend="xaggr-moving-aggregates">. This requires
198
203
specifying the <literal>MSFUNC</>, <literal>MINVFUNC</>,
199
204
and <literal>MSTYPE</> parameters, and optionally
200
- the <literal>MSPACE</>, <literal>MFINALFUNC</>, <literal>MFINALFUNC_EXTRA</>,
205
+ the <literal>MSPACE</>, <literal>MFINALFUNC</>,
206
+ <literal>MFINALFUNC_EXTRA</>, <literal>MFINALFUNC_MODIFY</>,
201
207
and <literal>MINITCOND</> parameters. Except for <literal>MINVFUNC</>,
202
208
these parameters work like the corresponding simple-aggregate parameters
203
209
without <literal>M</>; they define a separate implementation of the
@@ -412,6 +418,21 @@ SELECT col FROM tab ORDER BY col USING sortop LIMIT 1;
412
418
</listitem>
413
419
</varlistentry>
414
420
421
+ <varlistentry>
422
+ <term><literal>FINALFUNC_MODIFY</> = { <literal>READ_ONLY</> | <literal>SHARABLE</> | <literal>READ_WRITE</> }</term>
423
+ <listitem>
424
+ <para>
425
+ This option specifies whether the final function is a pure function
426
+ that does not modify its arguments. <literal>READ_ONLY</> indicates
427
+ it does not; the other two values indicate that it may change the
428
+ transition state value. See <xref linkend="sql-createaggregate-notes"
429
+ endterm="sql-createaggregate-notes-title"> below for more detail. The
430
+ default is <literal>READ_ONLY</>, except for ordered-set aggregates,
431
+ for which the default is <literal>READ_WRITE</>.
432
+ </para>
433
+ </listitem>
434
+ </varlistentry>
435
+
415
436
<varlistentry>
416
437
<term><replaceable class="parameter">combinefunc</replaceable></term>
417
438
<listitem>
@@ -563,6 +584,16 @@ SELECT col FROM tab ORDER BY col USING sortop LIMIT 1;
563
584
</listitem>
564
585
</varlistentry>
565
586
587
+ <varlistentry>
588
+ <term><literal>MFINALFUNC_MODIFY</> = { <literal>READ_ONLY</> | <literal>SHARABLE</> | <literal>READ_WRITE</> }</term>
589
+ <listitem>
590
+ <para>
591
+ This option is like <literal>FINALFUNC_MODIFY</>, but it describes
592
+ the behavior of the moving-aggregate final function.
593
+ </para>
594
+ </listitem>
595
+ </varlistentry>
596
+
566
597
<varlistentry>
567
598
<term><replaceable class="parameter">minitial_condition</replaceable></term>
568
599
<listitem>
@@ -587,12 +618,12 @@ SELECT col FROM tab ORDER BY col USING sortop LIMIT 1;
587
618
</varlistentry>
588
619
589
620
<varlistentry>
590
- <term><literal>PARALLEL</ literal></term>
621
+ <term><literal>PARALLEL =</> { < literal>SAFE</> | <literal>RESTRICTED</> | <literal>UNSAFE</> } </term>
591
622
<listitem>
592
623
<para>
593
624
The meanings of <literal>PARALLEL SAFE</>, <literal>PARALLEL
594
625
RESTRICTED</>, and <literal>PARALLEL UNSAFE</> are the same as
595
- for <xref linkend="sql-createfunction">. An aggregate will not be
626
+ in <xref linkend="sql-createfunction">. An aggregate will not be
596
627
considered for parallelization if it is marked <literal>PARALLEL
597
628
UNSAFE</> (which is the default!) or <literal>PARALLEL RESTRICTED</>.
598
629
Note that the parallel-safety markings of the aggregate's support
@@ -624,8 +655,8 @@ SELECT col FROM tab ORDER BY col USING sortop LIMIT 1;
624
655
</para>
625
656
</refsect1>
626
657
627
- <refsect1>
628
- <title>Notes</title>
658
+ <refsect1 id="sql-createaggregate-notes" >
659
+ <title id="sql-createaggregate-notes-title" >Notes</title>
629
660
630
661
<para>
631
662
In parameters that specify support function names, you can write
@@ -634,6 +665,34 @@ SELECT col FROM tab ORDER BY col USING sortop LIMIT 1;
634
665
of the support functions are determined from other parameters.
635
666
</para>
636
667
668
+ <para>
669
+ Ordinarily, Postgres functions are expected to be true functions that
670
+ do not modify their input values. However, an aggregate transition
671
+ function, <emphasis>when used in the context of an aggregate</>,
672
+ is allowed to cheat and modify its transition-state argument in place.
673
+ This can provide substantial performance benefits compared to making
674
+ a fresh copy of the transition state each time.
675
+ </para>
676
+
677
+ <para>
678
+ Likewise, while an aggregate final function is normally expected not to
679
+ modify its input values, sometimes it is impractical to avoid modifying
680
+ the transition-state argument. Such behavior must be declared using
681
+ the <literal>FINALFUNC_MODIFY</> parameter. The <literal>READ_WRITE</>
682
+ value indicates that the final function modifies the transition state in
683
+ unspecified ways. This value prevents use of the aggregate as a window
684
+ function, and it also prevents merging of transition states for aggregate
685
+ calls that share the same input values and transition functions.
686
+ The <literal>SHARABLE</> value indicates that the transition function
687
+ cannot be applied after the final function, but multiple final-function
688
+ calls can be performed on the ending transition state value. This value
689
+ prevents use of the aggregate as a window function, but it allows merging
690
+ of transition states. (That is, the optimization of interest here is not
691
+ applying the same final function repeatedly, but applying different final
692
+ functions to the same ending transition state value. This is allowed as
693
+ long as none of the final functions are marked <literal>READ_WRITE</>.)
694
+ </para>
695
+
637
696
<para>
638
697
If an aggregate supports moving-aggregate mode, it will improve
639
698
calculation efficiency when the aggregate is used as a window function
@@ -671,7 +730,8 @@ SELECT col FROM tab ORDER BY col USING sortop LIMIT 1;
671
730
Note that whether or not the aggregate supports moving-aggregate
672
731
mode, <productname>PostgreSQL</productname> can handle a moving frame
673
732
end without recalculation; this is done by continuing to add new values
674
- to the aggregate's state. It is assumed that the final function does
733
+ to the aggregate's state. This is why use of an aggregate as a window
734
+ function requires that the final function be read-only: it must
675
735
not damage the aggregate's state value, so that the aggregation can be
676
736
continued even after an aggregate result value has been obtained for
677
737
one set of frame boundaries.
0 commit comments