You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Internal error (nullability mismatch) when aggregating over CASE WHEN a < b THEN a ELSE ... END #26284
Aggregating over a projected CASE expression whose WHEN compares two columns fails with an internal error:
Internal error: Physical input schema should be the same as the one converted from logical input schema. Differences:
- field nullability at index 0 [x]: (physical) true vs (logical) false.
This issue was likely caused by a bug in DataFusion's code. ...
The logical schema marks CASE WHEN a < b THEN a ELSE 1 END as non-nullable (THEN a is only reached when a < b is true, so a isn't NULL there), but the physical CaseExpr reports it as nullable. The physical planner compares the two schemas for an aggregate's input, so queries that compute the expression below an aggregate fail, for example DISTINCT, UNION, or an aggregate over a subquery.
To Reproduce
CREATETABLEn(a INT, b INT) ASVALUES (NULL, 1), (0, 5), (7, 2);
SELECT DISTINCT CASE WHEN a < b THEN a ELSE 1 END AS x FROM n;
These fail the same way:
SELECTsum(x) FROM (SELECT CASE WHEN a < b THEN a ELSE 1 END AS x FROM n);
SELECT CASE WHEN a < b THEN a ELSE 1 END AS x FROM n UNIONSELECT2;
With WHEN a > 0 or WHEN a IS NOT NULL in place of a < b, the DISTINCT query works.
0 and 1 for the DISTINCT query, 2 for the sum, and 0, 1, 2 for the UNION, as in PostgreSQL.
Additional context
The logical side (expr_schema.rs) uses predicate_bounds::evaluate_bounds, which works out that NULL < b can't be true. The physical side (CaseExpr::nullable) replaces a with NULL and tries to constant-fold NULL < b. That still references b, so the result is inconclusive and the branch is treated as nullable.
Activity