Zoltán Borók-Nagy created IMPALA-15517:
------------------------------------------
Summary: Codegen'd AND/OR evaluate both operands, so queries with
failing functions depend on codegen
Key: IMPALA-15517
URL: https://issues.apache.org/jira/browse/IMPALA-15517
Project: IMPALA
Issue Type: Bug
Components: Backend
Reporter: Zoltán Borók-Nagy
The interpreted AndPredicate / OrPredicate short-circuit: the right operand is
not
evaluated if the left one already decides the result. The codegen'd
CompoundPredicate
(compound-predicates.cc) calls both operands unconditionally and combines their
results.
For functions that can raise an error, the result of a query therefore depends
on whether
codegen is enabled.
Repro on master:
{code:sql}
SELECT count(*) FROM functional_parquet.alltypes
WHERE bool_col OR (int_col = 1000
AND CAST(int_col + 100 AS DECIMAL(38,0)) * CAST(1e37 AS DECIMAL(38,0)) > 0);
{code}
* with DISABLE_CODEGEN=true: returns 3650
* with the default options: fails with "UDF ERROR: Decimal expression
overflowed"
'int_col = 1000' is false for every row, so the multiplication is never needed.
Only nested AND/OR are affected. Top-level conjuncts are separate expressions,
and
EvalConjuncts() stops at the first false one with codegen too.
Since codegen can be disabled by the planner (e.g.
DISABLE_CODEGEN_ROWS_THRESHOLD), the same
query can succeed on a small table and fail on a large one. Affected are the
functions that
call FunctionContext::SetError(), e.g. DECIMAL overflow with DECIMAL_V2, and
the strict
variant_get() once expressions on VARIANT are codegen'd (IMPALA-15141).
Suggested fix: generate short-circuit control flow in CompoundPredicate
codegen: evaluate the
left operand, return early if it decides the result (false for AND, true for
OR), and only
call the right operand otherwise. The performance impact should be measured.
Workaround: CASE and IF() evaluate their branches lazily with codegen as well.
--
This message was sent by Atlassian Jira
(v8.20.10#820010)