From 472671e133da77f280e87cb47c6544c75572df6b Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Wed, 23 Mar 2011 16:56:55 -0400 Subject: [PATCH] Improve user-defined-aggregates documentation. On closer inspection, that two-element initcond value seems to have been a little white lie to avoid explaining the full behavior of float8_accum. But if people are going to expect the examples to be exactly correct, I suppose we'd better explain. Per comment from Thom Brown. --- doc/src/sgml/xaggr.sgml | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/doc/src/sgml/xaggr.sgml b/doc/src/sgml/xaggr.sgml index 9fc0722f45..811934bd75 100644 --- a/doc/src/sgml/xaggr.sgml +++ b/doc/src/sgml/xaggr.sgml @@ -70,7 +70,7 @@ SELECT sum(a) FROM test_complex; expects sum to behave that way. We can do this simply by omitting the initcond phrase, so that the initial state condition is null. Ordinarily this would mean that the sfunc - would need to check for a null state-condition input, but for + would need to check for a null state-condition input. But for sum and some other simple aggregates like max and min, it is sufficient to insert the first nonnull input value into @@ -95,8 +95,8 @@ SELECT sum(a) FROM test_complex; 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 a - two-element array as the state value. For example, + these quantities. Average is typically implemented by using an + array as the state value. For example, the built-in implementation of avg(float8) looks like: @@ -109,6 +109,11 @@ CREATE AGGREGATE avg (float8) initcond = '{0,0,0}' ); + + (float8_accum 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 besides avg.) @@ -174,12 +179,13 @@ if (AggCheckCallContext(fcinfo, NULL)) One reason for checking this is that when it is true for a transition function, the first input must be a temporary transition value and can therefore safely be modified - in-place rather than allocating a new copy. (This is the only + in-place rather than allocating a new copy. + See int8inc() for an example. + (This is the only case where it is safe for a function to modify a pass-by-reference input. In particular, aggregate final functions should not modify their inputs in any case, because in some cases they will be re-executed on the same final transition value.) - See int8inc() for an example. -- 2.40.0