Skip to content

Commit 1a61a59

Browse files
authored
fix date_bin overflows subtracting extreme nanosecond timestamp origin (#22251)
## Which issue does this PR close? - Closes #22210 ## Rationale for this change `date_bin` could overflow when subtracting extreme nanosecond timestamps, which could trigger a panic. This fix makes that path return an error instead, so the query safely returns `NULL` rather than crashing. ## What changes are included in this PR? - In date_bin.rs, the nanosecond path now uses `checked_sub` instead of direct subtraction, and returns an `ArrowError::InvalidArgumentError` on overflow. - In date_bin_errors.slt, a regression test was added for an extreme nanosecond timestamp case to verify that overflow returns `NULL` instead of panicking. ## Are these changes tested? - Yes. The new sqllogictest covers the regression scenario and verifies that extreme nanosecond timestamp input returns `NULL`. ## Are there any user-facing changes? - Yes. `date_bin` is now more robust for extreme nanosecond timestamp inputs and will return `NULL` instead of panicking.
1 parent 7e90f52 commit 1a61a59

2 files changed

Lines changed: 15 additions & 1 deletion

File tree

datafusion/functions/src/datetime/date_bin.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -321,7 +321,11 @@ impl Interval {
321321

322322
// return time in nanoseconds that the source timestamp falls into based on the stride and origin
323323
fn date_bin_nanos_interval(stride_nanos: i64, source: i64, origin: i64) -> Result<i64> {
324-
let time_diff = source - origin;
324+
let time_diff = source.checked_sub(origin).ok_or_else(|| {
325+
arrow::error::ArrowError::InvalidArgumentError(format!(
326+
"date_bin source timestamp {source} - origin {origin} overflows i64"
327+
))
328+
})?;
325329

326330
// distance from origin to bin
327331
let time_delta = compute_distance(time_diff, stride_nanos);

datafusion/sqllogictest/test_files/date_bin_errors.slt

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,4 +57,14 @@ select date_bin(
5757
timestamp '1984-01-07 00:00:00'
5858
) as b;
5959
----
60+
NULL
61+
62+
# Extreme timestamp overflow: source - origin overflows i64 (should return NULL, not panic)
63+
query P
64+
select date_bin(
65+
interval '1 nanosecond',
66+
arrow_cast(9223372036854775807, 'Timestamp(Nanosecond, None)'),
67+
arrow_cast(-9223372036854775808, 'Timestamp(Nanosecond, None)')
68+
);
69+
----
6070
NULL

0 commit comments

Comments
 (0)