1
0
mirror of https://github.com/postgres/postgres.git synced 2025-07-28 23:42:10 +03:00

Document evaluation-order considerations for aggregate functions.

The SELECT reference page didn't really address the question of when
aggregate function evaluation occurs, nor did the "expression evaluation
rules" documentation mention that CASE can't be used to control whether
an aggregate gets evaluated or not.  Improve that.

Per discussion of bug #11661.  Original text by Marti Raudsepp and Michael
Paquier, rewritten significantly by me.
This commit is contained in:
Tom Lane
2014-11-14 17:19:29 -05:00
parent 80eacaa3cd
commit 0ce627d465
2 changed files with 48 additions and 10 deletions

View File

@ -2426,6 +2426,28 @@ SELECT ... WHERE CASE WHEN x > 0 THEN y/x > 1.5 ELSE false END;
example, it would be better to sidestep the problem by writing
<literal>y &gt; 1.5*x</> instead.)
</para>
<para>
A limitation of this technique is that a <literal>CASE</> cannot
prevent evaluation of an aggregate expression contained within it,
because aggregate expressions are computed before <quote>scalar</>
expressions in a <literal>SELECT</> list or <literal>HAVING</> clause
are considered. For example, the following query can cause a
division-by-zero error despite seemingly having protected against it:
<programlisting>
SELECT CASE WHEN min(employees) > 0
THEN avg(expenses / employees)
END
FROM departments;
</programlisting>
The <function>min()</> and <function>avg()</> aggregates are computed
concurrently over all the input rows, so if any row
has <structfield>employees</> equal to zero, the division-by-zero error
will occur before there is any opportunity to test the result of
<function>min()</>. Instead, use a <literal>WHERE</>
or <literal>FILTER</> clause to prevent problematic input rows from
reaching an aggregate function in the first place.
</para>
</sect2>
</sect1>