fix: support RANGE window frames over TIME keys - #24515
Open
fornwall wants to merge 2 commits into
Open
Conversation
Signed-off-by: Fredrik Fornwall <fredrik@fornwall.net>
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #24515 +/- ##
==========================================
+ Coverage 81.27% 81.29% +0.01%
==========================================
Files 1116 1116
Lines 395073 395460 +387
Branches 395073 395460 +387
==========================================
+ Hits 321102 321474 +372
+ Misses 55176 55174 -2
- Partials 18795 18812 +17 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
nuno-faria
reviewed
Aug 21, 2026
Comment on lines
+7012
to
+7020
| # Finite offsets over time are rejected for both the start and end bound. | ||
| query error DataFusion error: type_coercion\ncaused by\nError during planning: RANGE with offset PRECEDING/FOLLOWING is not supported for ORDER BY type Time64\(µs\) | ||
| SELECT COUNT(*) OVER (ORDER BY x RANGE BETWEEN INTERVAL '1' HOUR PRECEDING AND CURRENT ROW) | ||
| FROM (VALUES (arrow_cast('01:00:00', 'Time64(Microsecond)'))) t(x) | ||
|
|
||
| query error DataFusion error: type_coercion\ncaused by\nError during planning: RANGE with offset PRECEDING/FOLLOWING is not supported for ORDER BY type Time64\(µs\) | ||
| SELECT COUNT(*) OVER (ORDER BY x RANGE BETWEEN CURRENT ROW AND INTERVAL '1' HOUR FOLLOWING) | ||
| FROM (VALUES (arrow_cast('01:00:00', 'Time64(Microsecond)'))) t(x) | ||
|
|
Contributor
There was a problem hiding this comment.
Thanks @fornwall. Any reason why this should not be supported for Time? They both work with Postgres and DuckDB:
SELECT COUNT(*) OVER (
ORDER BY x RANGE BETWEEN INTERVAL '1' HOUR PRECEDING AND CURRENT ROW)
FROM (
VALUES
(TIME '01:00:00'),
(TIME '02:00:00'),
(TIME '04:00:00'),
(TIME '05:00:00')
) t(x);
count
-------
1
2
1
2
Contributor
Author
There was a problem hiding this comment.
@nuno-faria We should support that as well!
But it requires some work to handle the non-wrapping around midnight part (ordinary time +/- interval wraps), so I think that's better in a follow up PR. Does that sound ok?
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Which issue does this PR close?
ORDER BYuses aTIMEcolumn #24514.Rationale for this change
Window functions ordered by
Time32orTime64currently fail with an internal error, even when no frame clause is specified.ORDER BYdefaults toRANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW, whose free bounds only require comparisons, and time values are orderable.Finite
RANGEoffsets over time remain unsupported because time and interval arithmetic wraps around the 24-hour clock, so DataFusion's frame bound computation (current_value ± offset) cannot produce meaningful bounds. PostgreSQL supports such offsets through dedicated non-wrappingin_rangelogic, which is left as possible future work.What changes are included in this PR?
Time32andTime64as comparison-onlyRANGEframe key types.PRECEDINGandFOLLOWINGoffsets during planning.Are these changes tested?
Yes. SQL logic tests cover all four Arrow time units, duplicate peer values, dictionary-wrapped time keys, aggregate and ranking windows, ascending and descending order, explicit free bounds, and finite offsets on both bound sides.
The full datafusion-sqllogictest suite and repository lint checks pass.
Are there any user-facing changes?
Yes. Free
RANGEframes overTIMEorder keys now return results instead of an internal error. Finite offsets are still rejected, now with a clear planning error instead of the internal error. There are no public API or breaking changes.AI usage: Created with Claude Code and Opus 5. I have reviewed the code and made modifications where it made sense.