The order of evaluation of subexpressions is not defined. In
- particular, subexpressions are not necessarily evaluated
- left-to-right, right-to-left, or according to the lexical
- precedence rules.
+ particular, the inputs of an operator or function are not necessarily
+ evaluated left-to-right or in any other fixed order.
Furthermore, if the result of an expression can be determined by
- evaluating only some parts of it, then some subexpressions
+ evaluating only some parts of it, then other subexpressions
might not be evaluated at all. For instance, if one wrote
SELECT true OR somefunc();
As a consequence, it is unwise to use functions with side effects
- as part of complex expressions.
+ as part of complex expressions. It is particularly dangerous to
+ rely on side effects or evaluation order in WHERE and HAVING clauses,
+ since those clauses are extensively reprocessed as part of
+ developing an execution plan. Boolean
+ expressions (AND/OR/NOT combinations) in those clauses may be reorganized
+ in any manner allowed by the laws of Boolean algebra.
+
+
+ When it is essential to force evaluation order, a CASE construct may
+ be used. For example, this is an untrustworthy way of trying to
+ avoid division by zero in a WHERE clause:
+SELECT ... WHERE x <> 0 AND y/x > 1.5;
+
+ but this is safe:
+SELECT ... WHERE CASE WHEN x <> 0 THEN y/x > 1.5 ELSE false END;
+
+ A CASE construct used in this fashion will defeat optimization attempts,
+ so it should only be done when necessary.