| <!-- doc/src/sgml/xaggr.sgml --> |
| |
| <sect1 id="xaggr"> |
| <title>User-Defined Aggregates</title> |
| |
| <indexterm zone="xaggr"> |
| <primary>aggregate function</primary> |
| <secondary>user-defined</secondary> |
| </indexterm> |
| |
| <para> |
| Aggregate functions in <productname>PostgreSQL</productname> |
| are defined in terms of <firstterm>state values</firstterm> |
| and <firstterm>state transition functions</firstterm>. |
| That is, an aggregate operates using a state value that is updated |
| as each successive input row is processed. |
| To define a new aggregate |
| function, one selects a data type for the state value, |
| an initial value for the state, and a state transition |
| function. The state transition function takes the previous state |
| value and the aggregate's input value(s) for the current row, and |
| returns a new state value. |
| A <firstterm>final function</firstterm> |
| can also be specified, in case the desired result of the aggregate |
| is different from the data that needs to be kept in the running |
| state value. The final function takes the ending state value |
| and returns whatever is wanted as the aggregate result. |
| In principle, the transition and final functions are just ordinary |
| functions that could also be used outside the context of the |
| aggregate. (In practice, it's often helpful for performance reasons |
| to create specialized transition functions that can only work when |
| called as part of an aggregate.) |
| </para> |
| |
| <para> |
| Thus, in addition to the argument and result data types seen by a user |
| of the aggregate, there is an internal state-value data type that |
| might be different from both the argument and result types. |
| </para> |
| |
| <para> |
| If we define an aggregate that does not use a final function, |
| we have an aggregate that computes a running function of |
| the column values from each row. <function>sum</function> is an |
| example of this kind of aggregate. <function>sum</function> starts at |
| zero and always adds the current row's value to |
| its running total. For example, if we want to make a <function>sum</function> |
| aggregate to work on a data type for complex numbers, |
| we only need the addition function for that data type. |
| The aggregate definition would be: |
| |
| <programlisting> |
| CREATE AGGREGATE sum (complex) |
| ( |
| sfunc = complex_add, |
| stype = complex, |
| initcond = '(0,0)' |
| ); |
| </programlisting> |
| |
| which we might use like this: |
| |
| <programlisting> |
| SELECT sum(a) FROM test_complex; |
| |
| sum |
| ----------- |
| (34,53.9) |
| </programlisting> |
| |
| (Notice that we are relying on function overloading: there is more than |
| one aggregate named <function>sum</function>, but |
| <productname>PostgreSQL</productname> can figure out which kind |
| of sum applies to a column of type <type>complex</type>.) |
| </para> |
| |
| <para> |
| The above definition of <function>sum</function> will return zero |
| (the initial state value) if there are no nonnull input values. |
| Perhaps we want to return null in that case instead — the SQL standard |
| expects <function>sum</function> to behave that way. We can do this simply by |
| omitting the <literal>initcond</literal> phrase, so that the initial state |
| value is null. Ordinarily this would mean that the <literal>sfunc</literal> |
| would need to check for a null state-value input. But for |
| <function>sum</function> and some other simple aggregates like |
| <function>max</function> and <function>min</function>, |
| it is sufficient to insert the first nonnull input value into |
| the state variable and then start applying the transition function |
| at the second nonnull input value. <productname>PostgreSQL</productname> |
| will do that automatically if the initial state value is null and |
| the transition function is marked <quote>strict</quote> (i.e., not to be called |
| for null inputs). |
| </para> |
| |
| <para> |
| Another bit of default behavior for a <quote>strict</quote> transition function |
| is that the previous state value is retained unchanged whenever a |
| null input value is encountered. Thus, null values are ignored. If you |
| need some other behavior for null inputs, do not declare your |
| transition function as strict; instead code it to test for null inputs and |
| do whatever is needed. |
| </para> |
| |
| <para> |
| <function>avg</function> (average) is a more complex example of an aggregate. |
| It requires |
| two pieces of running state: the sum of the inputs and the count |
| of the number of inputs. The final result is obtained by dividing |
| these quantities. Average is typically implemented by using an |
| array as the state value. For example, |
| the built-in implementation of <function>avg(float8)</function> |
| looks like: |
| |
| <programlisting> |
| CREATE AGGREGATE avg (float8) |
| ( |
| sfunc = float8_accum, |
| stype = float8[], |
| finalfunc = float8_avg, |
| initcond = '{0,0,0}' |
| ); |
| </programlisting> |
| </para> |
| |
| <note> |
| <para> |
| <function>float8_accum</function> requires a three-element array, not just |
| two elements, because it accumulates the sum of squares as well as |
| the sum and count of the inputs. This is so that it can be used for |
| some other aggregates as well as <function>avg</function>. |
| </para> |
| </note> |
| |
| <para> |
| Aggregate function calls in SQL allow <literal>DISTINCT</literal> |
| and <literal>ORDER BY</literal> options that control which rows are fed |
| to the aggregate's transition function and in what order. These |
| options are implemented behind the scenes and are not the concern |
| of the aggregate's support functions. |
| </para> |
| |
| <para> |
| For further details see the |
| <xref linkend="sql-createaggregate"/> |
| command. |
| </para> |
| |
| <sect2 id="xaggr-moving-aggregates"> |
| <title>Moving-Aggregate Mode</title> |
| |
| <indexterm> |
| <primary>moving-aggregate mode</primary> |
| </indexterm> |
| |
| <indexterm> |
| <primary>aggregate function</primary> |
| <secondary>moving aggregate</secondary> |
| </indexterm> |
| |
| <para> |
| Aggregate functions can optionally support <firstterm>moving-aggregate |
| mode</firstterm>, which allows substantially faster execution of aggregate |
| functions within windows with moving frame starting points. |
| (See <xref linkend="tutorial-window"/> |
| and <xref linkend="syntax-window-functions"/> for information about use of |
| aggregate functions as window functions.) |
| The basic idea is that in addition to a normal <quote>forward</quote> |
| transition function, the aggregate provides an <firstterm>inverse |
| transition function</firstterm>, which allows rows to be removed from the |
| aggregate's running state value when they exit the window frame. |
| For example a <function>sum</function> aggregate, which uses addition as the |
| forward transition function, would use subtraction as the inverse |
| transition function. Without an inverse transition function, the window |
| function mechanism must recalculate the aggregate from scratch each time |
| the frame starting point moves, resulting in run time proportional to the |
| number of input rows times the average frame length. With an inverse |
| transition function, the run time is only proportional to the number of |
| input rows. |
| </para> |
| |
| <para> |
| The inverse transition function is passed the current state value and the |
| aggregate input value(s) for the earliest row included in the current |
| state. It must reconstruct what the state value would have been if the |
| given input row had never been aggregated, but only the rows following |
| it. This sometimes requires that the forward transition function keep |
| more state than is needed for plain aggregation mode. Therefore, the |
| moving-aggregate mode uses a completely separate implementation from the |
| plain mode: it has its own state data type, its own forward transition |
| function, and its own final function if needed. These can be the same as |
| the plain mode's data type and functions, if there is no need for extra |
| state. |
| </para> |
| |
| <para> |
| As an example, we could extend the <function>sum</function> aggregate given above |
| to support moving-aggregate mode like this: |
| |
| <programlisting> |
| CREATE AGGREGATE sum (complex) |
| ( |
| sfunc = complex_add, |
| stype = complex, |
| initcond = '(0,0)', |
| msfunc = complex_add, |
| minvfunc = complex_sub, |
| mstype = complex, |
| minitcond = '(0,0)' |
| ); |
| </programlisting> |
| |
| The parameters whose names begin with <literal>m</literal> define the |
| moving-aggregate implementation. Except for the inverse transition |
| function <literal>minvfunc</literal>, they correspond to the plain-aggregate |
| parameters without <literal>m</literal>. |
| </para> |
| |
| <para> |
| The forward transition function for moving-aggregate mode is not allowed |
| to return null as the new state value. If the inverse transition |
| function returns null, this is taken as an indication that the inverse |
| function cannot reverse the state calculation for this particular input, |
| and so the aggregate calculation will be redone from scratch for the |
| current frame starting position. This convention allows moving-aggregate |
| mode to be used in situations where there are some infrequent cases that |
| are impractical to reverse out of the running state value. The inverse |
| transition function can <quote>punt</quote> on these cases, and yet still come |
| out ahead so long as it can work for most cases. As an example, an |
| aggregate working with floating-point numbers might choose to punt when |
| a <literal>NaN</literal> (not a number) input has to be removed from the running |
| state value. |
| </para> |
| |
| <para> |
| When writing moving-aggregate support functions, it is important to be |
| sure that the inverse transition function can reconstruct the correct |
| state value exactly. Otherwise there might be user-visible differences |
| in results depending on whether the moving-aggregate mode is used. |
| An example of an aggregate for which adding an inverse transition |
| function seems easy at first, yet where this requirement cannot be met |
| is <function>sum</function> over <type>float4</type> or <type>float8</type> inputs. A |
| naive declaration of <function>sum(<type>float8</type>)</function> could be |
| |
| <programlisting> |
| CREATE AGGREGATE unsafe_sum (float8) |
| ( |
| stype = float8, |
| sfunc = float8pl, |
| mstype = float8, |
| msfunc = float8pl, |
| minvfunc = float8mi |
| ); |
| </programlisting> |
| |
| This aggregate, however, can give wildly different results than it would |
| have without the inverse transition function. For example, consider |
| |
| <programlisting> |
| SELECT |
| unsafe_sum(x) OVER (ORDER BY n ROWS BETWEEN CURRENT ROW AND 1 FOLLOWING) |
| FROM (VALUES (1, 1.0e20::float8), |
| (2, 1.0::float8)) AS v (n,x); |
| </programlisting> |
| |
| This query returns <literal>0</literal> as its second result, rather than the |
| expected answer of <literal>1</literal>. The cause is the limited precision of |
| floating-point values: adding <literal>1</literal> to <literal>1e20</literal> results |
| in <literal>1e20</literal> again, and so subtracting <literal>1e20</literal> from that |
| yields <literal>0</literal>, not <literal>1</literal>. Note that this is a limitation |
| of floating-point arithmetic in general, not a limitation |
| of <productname>PostgreSQL</productname>. |
| </para> |
| |
| </sect2> |
| |
| <sect2 id="xaggr-polymorphic-aggregates"> |
| <title>Polymorphic and Variadic Aggregates</title> |
| |
| <indexterm> |
| <primary>aggregate function</primary> |
| <secondary>polymorphic</secondary> |
| </indexterm> |
| |
| <indexterm> |
| <primary>aggregate function</primary> |
| <secondary>variadic</secondary> |
| </indexterm> |
| |
| <para> |
| Aggregate functions can use polymorphic |
| state transition functions or final functions, so that the same functions |
| can be used to implement multiple aggregates. |
| See <xref linkend="extend-types-polymorphic"/> |
| for an explanation of polymorphic functions. |
| Going a step further, the aggregate function itself can be specified |
| with polymorphic input type(s) and state type, allowing a single |
| aggregate 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"/>), |
| 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 for |
| an ordered-set aggregate is <emphasis>not</emphasis> done behind the scenes, |
| but is the responsibility of the aggregate's support functions. |
| The typical implementation approach is to keep a reference to |
| a <quote>tuplesort</quote> object in the aggregate's state value, feed the |
| incoming rows into that object, and then complete the sorting and |
| read out the data in the final function. This design allows the |
| final function to perform special operations such as injecting |
| additional <quote>hypothetical</quote> rows into the data to be sorted. |
| While normal aggregates can often be implemented with support |
| functions written in <application>PL/pgSQL</application> or another |
| PL language, ordered-set aggregates generally have to be written in |
| C, since their state values aren't definable as any SQL data type. |
| (In the above example, notice that the state value is declared as |
| type <type>internal</type> — this is typical.) |
| Also, because the final function performs the sort, it is not possible |
| to continue adding input rows by executing the transition function again |
| later. This means the final function is not <literal>READ_ONLY</literal>; |
| it must be declared in <link linkend="sql-createaggregate"><command>CREATE AGGREGATE</command></link> |
| as <literal>READ_WRITE</literal>, or as <literal>SHAREABLE</literal> if |
| it's possible for additional final-function calls to make use of the |
| already-sorted state. |
| </para> |
| |
| <para> |
| The state transition function for an ordered-set aggregate receives |
| the current state value plus the aggregated input values for |
| each row, and returns the updated state value. This is the |
| same definition as for normal aggregates, but note that the direct |
| arguments (if any) are not provided. The final function receives |
| the last state value, the values of the direct arguments if any, |
| and (if <literal>finalfunc_extra</literal> is specified) null values |
| corresponding to the aggregated input(s). As with normal |
| aggregates, <literal>finalfunc_extra</literal> is only really useful if the |
| aggregate is polymorphic; then the extra dummy argument(s) are needed |
| to connect the final function's result type to the aggregate's input |
| type(s). |
| </para> |
| |
| <para> |
| Currently, ordered-set aggregates cannot be used as window functions, |
| and therefore there is no need for them to support moving-aggregate mode. |
| </para> |
| |
| </sect2> |
| |
| <sect2 id="xaggr-partial-aggregates"> |
| <title>Partial Aggregation</title> |
| |
| <indexterm> |
| <primary>aggregate function</primary> |
| <secondary>partial aggregation</secondary> |
| </indexterm> |
| |
| <para> |
| Optionally, an aggregate function can support <firstterm>partial |
| aggregation</firstterm>. The idea of partial aggregation is to run the aggregate's |
| state transition function over different subsets of the input data |
| independently, and then to combine the state values resulting from those |
| subsets to produce the same state value that would have resulted from |
| scanning all the input in a single operation. This mode can be used for |
| parallel aggregation by having different worker processes scan different |
| portions of a table. Each worker produces a partial state value, and at |
| the end those state values are combined to produce a final state value. |
| (In the future this mode might also be used for purposes such as combining |
| aggregations over local and remote tables; but that is not implemented |
| yet.) |
| </para> |
| |
| <para> |
| To support partial aggregation, the aggregate definition must provide |
| a <firstterm>combine function</firstterm>, which takes two values of the |
| aggregate's state type (representing the results of aggregating over two |
| subsets of the input rows) and produces a new value of the state type, |
| representing what the state would have been after aggregating over the |
| combination of those sets of rows. It is unspecified what the relative |
| order of the input rows from the two sets would have been. This means |
| that it's usually impossible to define a useful combine function for |
| aggregates that are sensitive to input row order. |
| </para> |
| |
| <para> |
| As simple examples, <literal>MAX</literal> and <literal>MIN</literal> aggregates can be |
| made to support partial aggregation by specifying the combine function as |
| the same greater-of-two or lesser-of-two comparison function that is used |
| as their transition function. <literal>SUM</literal> aggregates just need an |
| addition function as combine function. (Again, this is the same as their |
| transition function, unless the state value is wider than the input data |
| type.) |
| </para> |
| |
| <para> |
| The combine function is treated much like a transition function that |
| happens to take a value of the state type, not of the underlying input |
| type, as its second argument. In particular, the rules for dealing |
| with null values and strict functions are similar. Also, if the aggregate |
| definition specifies a non-null <literal>initcond</literal>, keep in mind that |
| that will be used not only as the initial state for each partial |
| aggregation run, but also as the initial state for the combine function, |
| which will be called to combine each partial result into that state. |
| </para> |
| |
| <para> |
| If the aggregate's state type is declared as <type>internal</type>, it is |
| the combine function's responsibility that its result is allocated in |
| the correct memory context for aggregate state values. This means in |
| particular that when the first input is <literal>NULL</literal> it's invalid |
| to simply return the second input, as that value will be in the wrong |
| context and will not have sufficient lifespan. |
| </para> |
| |
| <para> |
| When the aggregate's state type is declared as <type>internal</type>, it is |
| usually also appropriate for the aggregate definition to provide a |
| <firstterm>serialization function</firstterm> and a <firstterm>deserialization |
| function</firstterm>, which allow such a state value to be copied from one process |
| to another. Without these functions, parallel aggregation cannot be |
| performed, and future applications such as local/remote aggregation will |
| probably not work either. |
| </para> |
| |
| <para> |
| A serialization function must take a single argument of |
| type <type>internal</type> and return a result of type <type>bytea</type>, which |
| represents the state value packaged up into a flat blob of bytes. |
| Conversely, a deserialization function reverses that conversion. It must |
| take two arguments of types <type>bytea</type> and <type>internal</type>, and |
| return a result of type <type>internal</type>. (The second argument is unused |
| and is always zero, but it is required for type-safety reasons.) The |
| result of the deserialization function should simply be allocated in the |
| current memory context, as unlike the combine function's result, it is not |
| long-lived. |
| </para> |
| |
| <para> |
| Worth noting also is that for an aggregate to be executed in parallel, |
| the aggregate itself must be marked <literal>PARALLEL SAFE</literal>. The |
| parallel-safety markings on its support functions are not consulted. |
| </para> |
| |
| </sect2> |
| |
| <sect2 id="xaggr-support-functions"> |
| <title>Support Functions for Aggregates</title> |
| |
| <indexterm> |
| <primary>aggregate function</primary> |
| <secondary>support functions for</secondary> |
| </indexterm> |
| |
| <para> |
| A function written in C can detect that it is being called as an |
| aggregate support function by calling |
| <function>AggCheckCallContext</function>, for example: |
| <programlisting> |
| if (AggCheckCallContext(fcinfo, NULL)) |
| </programlisting> |
| One reason for checking this is that when it is true, the first input |
| must be a temporary state value and can therefore safely be modified |
| in-place rather than allocating a new copy. |
| See <function>int8inc()</function> for an example. |
| (While aggregate transition functions are always allowed to modify |
| the transition value in-place, aggregate final functions are generally |
| discouraged from doing so; if they do so, the behavior must be declared |
| when creating the aggregate. See <xref linkend="sql-createaggregate"/> |
| for more detail.) |
| </para> |
| |
| <para> |
| The second argument of <function>AggCheckCallContext</function> can be used to |
| retrieve the memory context in which aggregate state values are being kept. |
| This is useful for transition functions that wish to use <quote>expanded</quote> |
| objects (see <xref linkend="xtypes-toast"/>) as their state values. |
| On first call, the transition function should return an expanded object |
| whose memory context is a child of the aggregate state context, and then |
| keep returning the same expanded object on subsequent calls. See |
| <function>array_append()</function> for an example. (<function>array_append()</function> |
| is not the transition function of any built-in aggregate, but it is written |
| to behave efficiently when used as transition function of a custom |
| aggregate.) |
| </para> |
| |
| <para> |
| Another support routine available to aggregate functions written in C |
| is <function>AggGetAggref</function>, which returns the <literal>Aggref</literal> |
| parse node that defines the aggregate call. This is mainly useful |
| for ordered-set aggregates, which can inspect the substructure of |
| the <literal>Aggref</literal> node to find out what sort ordering they are |
| supposed to implement. Examples can be found |
| in <filename>orderedsetaggs.c</filename> in the <productname>PostgreSQL</productname> |
| source code. |
| </para> |
| |
| </sect2> |
| |
| </sect1> |