Describe the bug
Lossy cast constraint propagation can incorrectly identify the source column as constant and eliminate a required sort. Casting -0.5 and 0.5 to INT produces 0 for both inputs, but a filter on that cast causes ORDER BY on the original floating-point column to return the wrong order.
Reproduced on main at ccfe704806, without the integer widening changes proposed in #25407.
To Reproduce
This example requires no external files:
SET datafusion.execution.target_partitions = 1;
CREATE TABLE lossy (id INT, x DOUBLE)
AS VALUES (1, -0.5), (2, 0.5);
SELECT id
FROM lossy
WHERE CAST(x AS INT) = 0
ORDER BY x DESC;
Actual result:
Expected result:
Both rows satisfy the filter. Since 0.5 > -0.5, the row with id = 2 must precede the row with id = 1.
Expected behavior
A many-to-one cast must not propagate a singleton output constraint back as a singleton input constraint. The optimizer must retain the required ordering unless it can establish valid source-domain bounds.
Additional context
The relevant path is CastExpr::propagate_constraints, which casts the result interval back to the child type. For this example, casting the output interval [0, 0] back to Float64 yields [0.0, 0.0], excluding both valid inputs. This can make the source column appear constant and remove a necessary SortExec.
This is related to #23095 and #22906, but concerns physical interval constraint propagation rather than the logical/physical unwrap_cast predicate rewrite.
Related to #25407: this is an independently reproducible correctness fix that can be addressed before preserving source bounds in widening integer casts. It does not require enabling widening and would not by itself complete #25407.
The SQL above was verified as an SLT regression: it fails on the baseline and passes with an isolated guard against unsafe inverse propagation of lossy numeric casts. Safe existing propagation paths should retain regression coverage.
Describe the bug
Lossy cast constraint propagation can incorrectly identify the source column as constant and eliminate a required sort. Casting
-0.5and0.5toINTproduces0for both inputs, but a filter on that cast causesORDER BYon the original floating-point column to return the wrong order.Reproduced on
mainatccfe704806, without the integer widening changes proposed in #25407.To Reproduce
This example requires no external files:
Actual result:
Expected result:
Both rows satisfy the filter. Since
0.5 > -0.5, the row withid = 2must precede the row withid = 1.Expected behavior
A many-to-one cast must not propagate a singleton output constraint back as a singleton input constraint. The optimizer must retain the required ordering unless it can establish valid source-domain bounds.
Additional context
The relevant path is
CastExpr::propagate_constraints, which casts the result interval back to the child type. For this example, casting the output interval[0, 0]back toFloat64yields[0.0, 0.0], excluding both valid inputs. This can make the source column appear constant and remove a necessarySortExec.This is related to #23095 and #22906, but concerns physical interval constraint propagation rather than the logical/physical
unwrap_castpredicate rewrite.Related to #25407: this is an independently reproducible correctness fix that can be addressed before preserving source bounds in widening integer casts. It does not require enabling widening and would not by itself complete #25407.
The SQL above was verified as an SLT regression: it fails on the baseline and passes with an isolated guard against unsafe inverse propagation of lossy numeric casts. Safe existing propagation paths should retain regression coverage.