Repository navigation
fix: reject date_bin strides that are not positive - #26070
Conversation
Negative strides had no defined semantics: a negative fixed stride rounds toward the origin, and a negative month stride is not monotonic. Like PostgreSQL, `date_bin` now returns an error for a stride that is not greater than zero, which also covers the zero stride. With only positive strides, `output_ordering` no longer special-cases negative month strides (added in apache#25815), and `compute_distance` / `compute_distance_wide` round down with `rem_euclid`. Closes apache#25856.
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #26070 +/- ##
==========================================
+ Coverage 82.69% 82.80% +0.11%
==========================================
Files 1147 1149 +2
Lines 447348 452193 +4845
Branches 447348 452193 +4845
==========================================
+ Hits 369936 374448 +4512
+ Misses 54999 54946 -53
- Partials 22413 22799 +386 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
|
do other systems allow negative date_bin strides? Update: postgres does not: #25856 (comment) So this sounds good to me |
| } | ||
|
|
||
| // `compute_distance` in i128. `stride` is non-zero, and `time_diff` is far | ||
| // `compute_distance` in i128. `stride` is positive, and `time_diff` is far |
| ### `date_bin` rejects strides that are not positive | ||
|
|
||
| `date_bin` now returns an error when its stride is not greater than zero. | ||
| This matches PostgreSQL for fixed strides (PostgreSQL does not support month |
There was a problem hiding this comment.
Perhaps we can link to the posgres docs for this claim: https://www.postgresql.org/docs/current/functions-datetime.html#FUNCTIONS-DATETIME-BIN
There was a problem hiding this comment.
Done, linked the PostgreSQL docs.
| `date_bin` now returns an error when its stride is not greater than zero. | ||
| This matches PostgreSQL for fixed strides (PostgreSQL does not support month | ||
| strides at all), and DataFusion applies the same rule to month strides. A zero | ||
| stride was already an error; its message is now |
There was a problem hiding this comment.
I am not sure we need to explicitly say the error message
| `DATE_BIN stride must be greater than zero`. | ||
|
|
||
| Previously, a negative stride was accepted but its bins were not well defined. | ||
| It returned the same bin as the positive stride only when the timestamp was at |
There was a problem hiding this comment.
rather than explain in detail what used to happen, I think we could just link to the ticket and cut this entry down a buncg
There was a problem hiding this comment.
Cut it down to a short summary plus the link to #25856.
mhilton
left a comment
There was a problem hiding this comment.
Thanks for this. It makes everything much simpler and more understandable.
Which issue does this PR close?
Rationale for this change
date_binaccepted negative strides, but they had no defined semantics:date_bin(INTERVAL '-1 month', ts, TIMESTAMP '2023-01-31')bins 2023-01-01 to 2023-02-28 and 2023-01-31 to itself.#25815 worked around the second one by not propagating ordering for negative month strides. As discussed in #25856,
date_binnow rejects strides that are not positive. This matches PostgreSQL for fixed strides (PostgreSQL does not support month strides at all), and DataFusion applies the same rule to month strides. A positive stride already bins timestamps before the origin, so a negative stride adds nothing, and an error is better than silently taking the absolute value of an accidental negative.What changes are included in this PR?
date_binreturnsDATE_BIN stride must be greater than zerofor a stride that is not positive. This covers negative months, negative days or nanoseconds, intervals whose parts add up to a negative stride, and TIME inputs. The zero-stride error is folded into this message.output_orderingno longer special-cases negative month strides: any constant stride preserves the order of the source.compute_distanceandcompute_distance_wideround down withrem_euclid. For a positive stride this is the same as the old truncate-then-step-back logic, and the two functions still match. Overflow neari64::MINstill returns an error, which becomes NULL.date_bindocs say the interval must be greater than zero, and the 56.0.0 upgrade guide describes the change.What is the testing strategy for this PR?
date_bin_errors.slt: error cases for negative month, year, minute, day and nanosecond strides, an interval whose parts add up to a negative stride, scalar and column inputs at second and nanosecond precision, and TIME inputs. The-1 nanosecondcase replaces the unit test for thei64::MIN % -1overflow from panic: date_bin compute_distance subtracts past i64::MIN #22215, which can no longer be reached.timestamps.slt: the negative-month ordering cases from fix: bin coarse date_bin timestamps in i128 and restore ordering #25815 are replaced by the error tests above. The positive-month control stays, and the zero-stride cases expect the new message.test_date_bincovers negativeIntervalDayTimestrides, which SQL interval literals cannot produce.output_ordering_requires_constant_stridereplacesoutput_ordering_requires_monotonic_stride.Are there any user-facing changes?
Yes, this is a breaking change: a negative
date_binstride is now an error. Previously it returned the same bins as the positive stride when the source was at or after the origin (for month strides, only when the source's day of month was not earlier than the origin's), and a bin later than the source otherwise. The zero-stride error message also changes. Both are documented in the 56.0.0 upgrade guide.