You are viewing a plain text version of this content. The canonical link for it is here.
Posted to issues@spark.apache.org by "sepuri sai krishna (Jira)" <ji...@apache.org> on 2026/10/21 08:43:00 UTC
[jira] [Created] (SPARK-60418) Subexpression elimination evaluates a short-circuited IN list element
sepuri sai krishna created SPARK-60418:
------------------------------------------
Summary: Subexpression elimination evaluates a short-circuited IN list element
Key: SPARK-60418
URL: https://issues.apache.org/jira/browse/SPARK-60418
Project: Spark
Issue Type: Bug
Components: SQL
Affects Versions: 4.4.0
Reporter: sepuri sai krishna
{{In}} stops at the first list element that matches, in both {{eval}} and
generated code, but a later element is still evaluated ahead of the comparison
when it is a common subexpression. A query that should return rows then fails.
ANSI mode, default configuration:
{code:sql}
CREATE OR REPLACE TEMP VIEW t AS
SELECT cast(id as int) AS b, cast(2147483647 - id as int) AS y FROM range(1);
SELECT b IN (b, y + 1), b IN (b, y + 1, 7) FROM t;
-- b matches the first element of both lists, so y + 1 is never needed
-- expected: true, true
-- actual: [ARITHMETIC_OVERFLOW] overflow
{code}
Either {{IN}} on its own returns {{true}}, and so does the query with
{{spark.sql.subexpressionElimination.enabled}} set to {{false}}, so the error
comes from the elimination rather than from the query. It fails with whole-stage
codegen both on and off. A list of literals is not affected.
{{spark.sql.subexpressionElimination.skipForShortcutExpr}}, which exists to stop
elimination from evaluating short-circuited operands, does not help here: with it
set to {{true}} the same shape over {{AND}} stops failing, while the {{IN}} query
above still fails. {{In}} short-circuits the same way, and is already listed
alongside {{And}} and {{Or}} as conditionally evaluated in
{{OptimizeCsvJsonExprs}}.
Verified on master at 8d5b30a06f6.
---
## Why only one
The try_* candidate does not hold up. {{try_subtract(cast(s as date), cast(s as
date))}} does raise with elimination on and return NULL with it off, but NULL is
not what try_* promises:
- the numeric path, {{try_subtract(cast(s as int), 1)}}, raises the operand's
CAST_INVALID_INPUT in every mode, so try_* does not swallow operand errors by
design;
- what the docs promise is NULL on the operation's own overflow, and
{{try_add(date '2020-01-01', make_ym_interval(178956970, 0))}} returns NULL in
every mode, elimination on or off;
- the non-numeric path swallows operand errors only incidentally, because
{{TryEval}} wraps the whole subtree, and the code carries a
"TODO: support TRY eval mode on datetime arithmetic expressions" there.
So with elimination on, the non-numeric path becomes consistent with the numeric
one. Filing it as "try_* raises instead of returning NULL" would be arguing for
the anomalous behaviour.
--
This message was sent by Atlassian Jira
(v8.20.10#820010)
---------------------------------------------------------------------
To unsubscribe, e-mail: issues-unsubscribe@spark.apache.org
For additional commands, e-mail: issues-help@spark.apache.org