Repository navigation
EXTRACT EPOCH inconsistently extracts fractional seconds #26673
Copy link
Copy link
Labels
bugSomething isn't workingSomething isn't working
Description
Describe the bug
- Came out of reviewing [dbolympics] EPIC: Review "db olympics" results #26661
- Part of [EPIC] A Collection of Wrong Results Bugs - Q4 2026 #26672
When running EXTRACT EPOCH sometimes DataFusion extracts the fractional seconds, but sometimes does not
So extracting the epoch from 2.10 seconds gives 2.1 as expected, but extracting the epoc from 2.50 seconds returns `2.0 (dropping the fraction incorrectly)
To Reproduce
Reproducer
WITH cases (
description,
started_at,
finished_at,
expected_seconds
) AS (
VALUES
('1.25 seconds: fraction retained',
TIMESTAMP '2025-01-01 00:00:00.000000',
TIMESTAMP '2025-01-01 00:00:01.250000',
1.250000),
('2.10 seconds: fraction retained',
TIMESTAMP '2025-01-01 00:00:00.000000',
TIMESTAMP '2025-01-01 00:00:02.100000',
2.100000),
('2.50 seconds: fraction dropped',
TIMESTAMP '2025-01-01 00:00:00.000000',
TIMESTAMP '2025-01-01 00:00:02.500000',
2.500000),
('4.763 seconds: fraction dropped',
TIMESTAMP '2025-01-01 00:00:00.000000',
TIMESTAMP '2025-01-01 00:00:04.763000',
4.763000),
('12.923350 seconds: fraction dropped',
TIMESTAMP '2025-01-01 00:00:00.000000',
TIMESTAMP '2025-01-01 00:00:12.923350',
12.923350)
)
SELECT
description,
finished_at - started_at AS elapsed,
EXTRACT(EPOCH FROM (finished_at - started_at)) AS actual_seconds,
expected_seconds
FROM cases;Results in
+-------------------------------------+-----------------------------------------+----------------+------------------+
| description | elapsed | actual_seconds | expected_seconds |
+-------------------------------------+-----------------------------------------+----------------+------------------+
| 1.25 seconds: fraction retained | 0 days 0 hours 0 mins 1.250000000 secs | 1.25 | 1.25 |
| 2.10 seconds: fraction retained | 0 days 0 hours 0 mins 2.100000000 secs | 2.1 | 2.1 |
| 2.50 seconds: fraction dropped | 0 days 0 hours 0 mins 2.500000000 secs | 2.0 | 2.5 |
| 4.763 seconds: fraction dropped | 0 days 0 hours 0 mins 4.763000000 secs | 4.0 | 4.763 |
| 12.923350 seconds: fraction dropped | 0 days 0 hours 0 mins 12.923350000 secs | 12.0 | 12.92335 |
+-------------------------------------+-----------------------------------------+----------------+------------------+
5 row(s) fetched.
Elapsed 0.013 seconds.DataFusion CLI v55.1.0 produces:
1.25 seconds → actual 1.25, expected 1.25
2.10 seconds → actual 2.1, expected 2.1
2.50 seconds → actual 2.0, expected 2.5
4.763 seconds → actual 4.0, expected 4.763
12.923350 seconds → actual 12.0, expected 12.92335
Expected behavior
The fractional second part should be extracted consistently;
Additional context
THis seems similar to
Willingness to contribute
None
Metadata
Metadata
Assignees
Labels
bugSomething isn't workingSomething isn't working
Activity
mbutrovich commentedon Oct 23, 2026
Thanks @alamb for filing this. The cutoff is 2.147483647 seconds, which is
i32::MAXnanoseconds. That matches your cases (2.10 keeps its fraction, 2.50 loses it):As I read it,
epochsendsDurationtoseconds, which readsdate_part(array, Nanosecond)as anInt32array. For aDuration(ns), arrow-rs returns the total nanoseconds withtry_into().ok(), so the value is NULL abovei32::MAX.secondstreats a NULL sub-second part as zero. I have not stepped through it in a debugger. This looks like the sameInt32overflow onDurationas #14738.EXTRACT(EPOCH FROM INTERVAL '4.322 seconds')returns4.322, so only theDurationpath is affected. The same happens forDuration(µs)andDuration(ms)inputs.Kristofferjoha commentedon Oct 23, 2026
Trying to unassign myself, seems like you have it figured out
Kristofferjoha commentedon Oct 23, 2026
untake
mbutrovich commentedon Oct 23, 2026
Okay I can try to knock this out.
test: check EXTRACT(EPOCH) on the reproducer from apache#26673.
fix: keep fractional seconds in EXTRACT(EPOCH) for Duration (apache#2…