Skip to content

Commit 0512962

Browse files
authored
fix date_trunc overflows converting extreme non-ns timestamps to nanoseconds (#22262)
## Which issue does this PR close? - Closes #22209 ## Rationale for this change `date_trunc` can panic during planning and constant folding when it receives extreme non-nanosecond timestamps. The overflow happens while converting values to nanoseconds, so a valid SQL query can crash the planner instead of returning a proper error. This change makes that path fail gracefully with a planning error. ## What changes are included in this PR? - Adds overflow checks to the timestamp scale conversion used by `date_trunc`. - Converts the panic into a normal out-of-range planning error. - Adds regression coverage for extreme `Timestamp(Second)`, `Timestamp(Millisecond)`, and `Timestamp(Microsecond)` inputs. - Adds a SQL-level regression test for the `arrow_cast(...)` plus `date_trunc(...)` repro. ## Are these changes tested? - Yes. I added regression tests and verified the repro now returns an error instead of panicking. ## Are there any user-facing changes? - Yes. Out-of-range timestamp inputs now produce a planning error rather than aborting the query with a panic.
1 parent 1a61a59 commit 0512962

2 files changed

Lines changed: 13 additions & 1 deletion

File tree

datafusion/functions/src/datetime/date_trunc.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -718,7 +718,13 @@ fn general_date_trunc(
718718
};
719719

720720
// convert to nanoseconds
721-
let nano = date_trunc_coarse(granularity, scale * value, tz)?;
721+
let nano = date_trunc_coarse(
722+
granularity,
723+
value
724+
.checked_mul(scale)
725+
.ok_or_else(|| exec_datafusion_err!("Timestamp {value} out of range"))?,
726+
tz,
727+
)?;
722728

723729
let result = match tu {
724730
Second => match granularity {

datafusion/sqllogictest/test_files/datetime/timestamps.slt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2428,6 +2428,12 @@ SELECT arrow_typeof(date_trunc('hour', TIME '14:30:45'));
24282428
----
24292429
Time64(ns)
24302430

2431+
query error DataFusion error: Execution error: Timestamp 9223372036854775807 out of range
2432+
SELECT date_trunc(
2433+
'hour',
2434+
arrow_cast(9223372036854775807, 'Timestamp(Second, None)')
2435+
);
2436+
24312437
# Error for granularities not valid for Time types
24322438
query error date_trunc does not support 'day' granularity for Time types
24332439
SELECT date_trunc('day', TIME '14:30:45');

0 commit comments

Comments
 (0)