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
Window function with nullable UNIQUE ORDER BY key uses ROWS frame and returns wrong results for NULL peers #26720
A window function with ORDER BY and no explicit frame should use the default frame RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW, under which rows that tie on the ORDER BY key are peers and see the same result.
When the first ORDER BY column has a UNIQUE constraint, the SQL planner assumes there can be no ties and switches to ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW. That is only equivalent if the column is also NOT NULL. A nullable UNIQUE column allows several NULL rows, and those rows sort together as peers. With the ROWS frame they get running results that depend on the order they happen to arrive in.
To Reproduce
CREATETABLEt (u INT, x INT, UNIQUE(u));
INSERT INTO t VALUES (NULL, 1), (NULL, 2), (NULL, 3), (5, 10);
SELECT u, x,
sum(x) OVER (ORDER BY u NULLS FIRST) AS s,
count(*) OVER (ORDER BY u NULLS FIRST) AS c
FROM t ORDER BY u NULLS FIRST, x;
The check is in datafusion/sql/src/expr/function.rs (is_ordering_strict): it accepts any Dependency::Single functional dependency on the column without checking FunctionalDependence::is_valid_across_nulls. This is the same class of bug as #23818 (ORDER BY key pruning) and #23819 (GROUP BY / DISTINCT), which were fixed by adding that check.
Activity
fix: keep RANGE default window frame for nullable UNIQUE ORDER BY keys (