- As described in , functions and
- operators marked IMMUTABLE can be evaluated when
- the query is planned rather than when it is executed. This means
- that constant parts of a subexpression that is not evaluated during
- query execution might still be evaluated during query planning.
+ As described in , there are various
+ situations in which subexpressions of an expression are evaluated at
+ different times, so that the principle that CASE
+ evaluates only necessary subexpressions is not ironclad. For
+ example a constant 1/0> subexpression will usually result in
+ a division-by-zero failure at planning time, even if it's within
+ a CASE arm that would never be entered at run time.
- A limitation of this technique is that a CASE> cannot
+ CASE> is not a cure-all for such issues, however.
+ One limitation of the technique illustrated above is that it does not
+ prevent early evaluation of constant subexpressions.
+ As described in , functions and
+ operators marked IMMUTABLE can be evaluated when
+ the query is planned rather than when it is executed. Thus for example
+SELECT CASE WHEN x > 0 THEN x ELSE 1/0 END FROM tab;
+
+ is likely to result in a division-by-zero failure due to the planner
+ trying to simplify the constant subexpression,
+ even if every row in the table has x > 0> so that the
+ ELSE> arm would never be entered at run time.
+
+
+ While that particular example might seem silly, related cases that don't
+ obviously involve constants can occur in queries executed within
+ functions, since the values of function arguments and local variables
+ can be inserted into queries as constants for planning purposes.
+ Within
PL/pgSQL> functions, for example, using an
+ IF>-THEN>-ELSE> statement to protect
+ a risky computation is much safer than just nesting it in a
+ CASE> expression.
+
+
+ Another limitation of the same kind is that a CASE> cannot
prevent evaluation of an aggregate expression contained within it,
- because aggregate expressions are computed before scalar>
+ because aggregate expressions are computed before other
expressions in a SELECT> list or HAVING> clause
are considered. For example, the following query can cause a
division-by-zero error despite seemingly having protected against it: