You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
date_trunc panicked with message: called Option::unwrap() on a None value #8899
Even though a different timestamp works fine, e.g. 2023-10-29T02:00:00Z
To Reproduce
Run the above query in DataFusion CLI v34.0.0
❌2023-10-29T00:00:00Z panicked
$ datafusion-cli
DataFusion CLI v34.0.0
❯ SELECT date_trunc('week', arrow_cast(arrow_cast('2023-10-29T00:00:00Z', 'Timestamp(Nanosecond, Some("UTC"))'), 'Timestamp(Nanosecond, Some("Europe/Berlin"))'));
thread 'main' panicked at /private/tmp/datafusion-20231217-5103-4z8blm/arrow-datafusion-34.0.0/datafusion/physical-expr/src/datetime_expressions.rs:335:14:
called `Option::unwrap()`on a `None` value
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
I'd definitely take a noisy failure, such as this, than silently incorrect behaviour.
Edit: this approach will still fail if the provided timestamp is invalid, and so we should probably change it to error instead of panic, but I think this is the correct behaviour. Truncating a timestamp that doesn't correspond to an actual instant in time, I think should error 😄
I don't think it would, at least not in all cases. If we take the two times:
2024-10-27 02:30:00 +0100 (CET)
2024-10-27 02:30:00 +0200 (CEST)
which are both valid in the Europe/Berlin timezone. Then using earliest in a date_trunc('hour', ...) function would cause the result for the latter time to be 2024-10-27 02:00:00 +0100 essentially truncating to the wrong hour.
My thought is that in cases where the result is Ambiguous then the value that has the same offset as the input time should be chosen.
Edit: this approach will still fail if the provided timestamp is invalid
Is it possible for an invalid input value to get as far as the date_trunc function, or would it be caught sooner in the processing?
My thought is that in cases where the result is Ambiguous then the value that has the same offset as the input time should be chosen.
But what if the input doesn't have a fixed offset, i.e. some values are either side of DST 😅.
essentially truncating to the wrong hour.
Is it the wrong hour? If I input a timestamp of 2024-10-27 02:30:00 Europe/Berlin it would truncate to one of the possible representations of 2024-10-27 02:00:00 Europe/Berlin in UTC, the output is no more or less ambiguous than the input?
I guess we should probably see what postgres does.
Is it possible for an invalid input value to get as far as the date_trunc function, or would it be caught sooner in the processing?
As arrow stores all times as UTC I think it might be impossible 👍
Is it the wrong hour? If I input a timestamp of 2024-10-27 02:30:00 Europe/Berlin
That is not the only way you could end up with such a timestamp though. The more likely thing is to have a stream of input from a machine produced in UTC. If one wants to display the output in a local timezone then one could use a query like:
SELECT date_trunc('hour', arrow_cast(time, 'Timestamp(Nanosecond, Some("UTC"))')) AS hour, COUNT(*) FROM events GROUP BY hour
if the earliest is always chosen for the ambiguous cases this would produce results like:
Incidentally arrow doesn't like that time string so you can't input it anyway Parser error: Error parsing timestamp from '2024-10-27 02:30:00 Europe/Berlin': error computing timezone offset.
Incidentally arrow doesn't like that time string so you can't input it anyway Parser error: Error parsing timestamp from '2024-10-27 02:30:00 Europe/Berlin': error computing timezone offset.
You have to enable the chrono-tz feature to parse non-offset timezones, it definitely supports them
The more likely thing is to have a stream of input from a machine produced in UTC. If one wants to display the output in a local timezone then one could use a query like
if the earliest is always chosen for the ambiguous cases this would produce results like:
I think we should see what postgres does here, I'm not entirely sure what the correct behaviour here is, very little is intuitive or logical when it comes to DST
You have to enable the chrono-tz feature to parse non-offset timezones, it definitely supports them
I should have been clearer, '2024-10-26 02:30:00 Europe/Berlin' parses just fine. I think arrow is complaining because the time is ambiguous rather than not understood.
I would like to push back on this plan slightly. My problem is that at the beginning of the operation there is enough information to unambiguously truncate the time. It is only the implementation detail of converting to a local time and then back again that causes any given timestamp value to become ambiguous.
However changing the panic to an error would be a welcome step.
@mhilton could you possibly provide some example inputs / expected outputs for your proposal in #8899 (comment)?
This is what postgresql does for times around the DST switchover.
mhilton=# SET TIMEZONE='Europe/Berlin';
SET
mhilton=# SELECT date_trunc('day', column1) AS day, date_trunc('hour', column1) AS hour, column1 as time FROM (VALUES (TIMESTAMPTZ '2024-10-26 23:30:10Z'), (TIMESTAMPTZ '2024-10-27 00:30:10Z'), (TIMESTAMPTZ '2024-10-27 01:30:10Z'), (TIMESTAMPTZ '2024-10-27 02:30:10Z'));
day | hour | time
------------------------+------------------------+------------------------
2024-10-27 00:00:00+02 | 2024-10-27 01:00:00+02 | 2024-10-27 01:30:10+02
2024-10-27 00:00:00+02 | 2024-10-27 02:00:00+02 | 2024-10-27 02:30:10+02
2024-10-27 00:00:00+02 | 2024-10-27 02:00:00+01 | 2024-10-27 02:30:10+01
2024-10-27 00:00:00+02 | 2024-10-27 03:00:00+01 | 2024-10-27 03:30:10+01
Here I made the input UTC so that it is equivalent to how arrow stores timestamp values. As you can see the trucated hours that have the same wall-clock value (2nd and 3rd row) still maintain the offset value from the time that was truncated.
Activity
jayzhan211 commentedon Jan 18, 2024
The issue is due to the ambiguous time between
daylight saving timeand standard time in chrono.Return value of
dt.timezone().from_local_datetime(&datetime)https://github.com/chronotope/chrono/blob/5aaf74235778120b5984b46ced47478c1431d9a0/src/datetime/mod.rs#L693-L698
Therefore
.single()return None in this case.I think the we should convert it to NaiveDateTime to modify the time then convert back after.
https://github.com/apache/arrow-datafusion/blob/57e38fb16a9918fb16c2c50e2188cc22c0afe4ad/datafusion/physical-expr/src/datetime_expressions.rs#L234-L288
Ref
https://docs.rs/chrono/latest/chrono/struct.DateTime.html#method.with_second
https://docs.rs/chrono/latest/chrono/naive/struct.NaiveTime.html#method.with_second
tustvold commentedon Jan 19, 2024
Would https://docs.rs/chrono/latest/chrono/offset/enum.LocalResult.html#method.earliest work instead? It would take the earlier of the ambiguous time, which would be consistent with the truncating behaviour of date_trunc. Converting to NaiveDateTime raises the risk of extremely subtle bugs that are likely hard to detect/interpret?
I'd definitely take a noisy failure, such as this, than silently incorrect behaviour.
Edit: this approach will still fail if the provided timestamp is invalid, and so we should probably change it to error instead of panic, but I think this is the correct behaviour. Truncating a timestamp that doesn't correspond to an actual instant in time, I think should error 😄
mhilton commentedon Jan 19, 2024
I don't think it would, at least not in all cases. If we take the two times:
2024-10-27 02:30:00 +0100(CET)2024-10-27 02:30:00 +0200(CEST)which are both valid in the
Europe/Berlintimezone. Then usingearliestin adate_trunc('hour', ...)function would cause the result for the latter time to be2024-10-27 02:00:00 +0100essentially truncating to the wrong hour.My thought is that in cases where the result is
Ambiguousthen the value that has the same offset as the input time should be chosen.Is it possible for an invalid input value to get as far as the
date_truncfunction, or would it be caught sooner in the processing?tustvold commentedon Jan 19, 2024
But what if the input doesn't have a fixed offset, i.e. some values are either side of DST 😅.
Is it the wrong hour? If I input a timestamp of
2024-10-27 02:30:00 Europe/Berlinit would truncate to one of the possible representations of2024-10-27 02:00:00 Europe/Berlinin UTC, the output is no more or less ambiguous than the input?I guess we should probably see what postgres does.
As arrow stores all times as UTC I think it might be impossible 👍
mhilton commentedon Jan 19, 2024
That is not the only way you could end up with such a timestamp though. The more likely thing is to have a stream of input from a machine produced in UTC. If one wants to display the output in a local timezone then one could use a query like:
if the earliest is always chosen for the ambiguous cases this would produce results like:
Incidentally arrow doesn't like that time string so you can't input it anyway
Parser error: Error parsing timestamp from '2024-10-27 02:30:00 Europe/Berlin': error computing timezone offset.tustvold commentedon Jan 19, 2024
You have to enable the chrono-tz feature to parse non-offset timezones, it definitely supports them
I think we should see what postgres does here, I'm not entirely sure what the correct behaviour here is, very little is intuitive or logical when it comes to DST
mhilton commentedon Jan 19, 2024
I should have been clearer, '2024-10-26 02:30:00 Europe/Berlin' parses just fine. I think arrow is complaining because the time is ambiguous rather than not understood.
alamb commentedon Jan 29, 2024
The consensus seems to be to turn this from a panic into an error with a clear error message ideally with how they can fix / workaround the issue.
I will file a follow on ticket about potentially choosing one of the alternate behaviors described above where we can discuss it further
mhilton commentedon Jan 29, 2024
I would like to push back on this plan slightly. My problem is that at the beginning of the operation there is enough information to unambiguously truncate the time. It is only the implementation detail of converting to a local time and then back again that causes any given timestamp value to become ambiguous.
However changing the panic to an error would be a welcome step.
alamb commentedon Jan 29, 2024
Thanks @mhilton - so perhaps we should:
alamb commentedon Jan 29, 2024
@mhilton could you possibly provide some example inputs / expected outputs for your proposal in #8899 (comment)?
mhilton commentedon Jan 30, 2024
This is what postgresql does for times around the DST switchover.
Here I made the input UTC so that it is equivalent to how arrow stores timestamp values. As you can see the trucated hours that have the same wall-clock value (2nd and 3rd row) still maintain the offset value from the time that was truncated.
alamb commentedon Jan 30, 2024
There is a PR up to fix this from @mhilton 🙏 #9068