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:
@ -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 > 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>
|
||||
|
||||
|
Reference in New Issue
Block a user