Saturate date/datetime to zero.#29953
Conversation
src/Functions/DateTimeTransforms.h
Outdated
There was a problem hiding this comment.
We have a comment says that 1970-01-01 is used as the date part: https://github.com/ClickHouse/ClickHouse/blob/c6e02a534f97720471e67c5d9cfddbc0fef62b1f/src/Functions/DateTimeTransforms.h#L239
However the old behavior apparently uses 1970-01-02 which most likely to avoid overflow. After this PR it's ok.
There was a problem hiding this comment.
I recommend not changing toTime as it has more chance to break some use cases.
There was a problem hiding this comment.
Ok. I'll change the comment instead.
There was a problem hiding this comment.
Check for western time zones, like America/Los_Angeles.
|
Is it pr-backward-incompatible? |
|
Overflow has implementation defined behaviour in ClickHouse, and this behaviour is changed. |
b413a93 to
9e0d0ae
Compare
|
Perf test is showing a small slowdown. |
Maybe we can build another lookup table in DateTimeLUT for this purpose. Not sure if it's appropriate. |
|
Maybe we can optimize something to compensate this slowdown... |
027a2a7 to
38b1e2f
Compare
There was a problem hiding this comment.
@alesapin Could you explain why we choose 10000 month for TTL? It leads to implementation defined date overflow.
17a22c5 to
70344d5
Compare
|
There is one warning from gcc. |
d024387 to
903df9d
Compare
Fixed. |
It's interesting that my local clickhouse benchmark comparison shows the opposite result: tests/performance/parallel_index.xml: |
006bef2 to
cab5f4f
Compare
|
The changes in performance look insignificant. Ok to merge. |
|
@amosbird Please close the issues that were fixed. |
|
Only one issue left #25284 . |
| select toStartOfQuarter(toDateTime(0, 'America/Los_Angeles')); | ||
| select toStartOfYear(toDateTime(0, 'America/Los_Angeles')); | ||
| select toTime(toDateTime(0, 'America/Los_Angeles'), 'America/Los_Angeles'); | ||
| select toStartOfMinute(toDateTime(0, 'America/Los_Angeles')); |
There was a problem hiding this comment.
@amosbird Any reason that you decided not to saturate toStartOfMinute and friends?
There was a problem hiding this comment.
It should be.
┌─toStartOfMinute(toDateTime(0, 'America/Los_Angeles'))─┐
│ 1969-12-31 16:00:00 │
└───────────────────────────────────────────────────────┘
There was a problem hiding this comment.
Actually it does not always work.
toStartOfHour
Does not work for partial hours timezones, i.e. America/Paramaribo
┌─toStartOfHour(toDateTime(0, 'America/Paramaribo'))─┐
│ 2106-02-07 02:58:16 │
└────────────────────────────────────────────────────┘toStartOfMinute
Does not work for partial minutes timezones, Africa/Monrovia - which is very special timezone, #27080 for the reference.
$ TZ=Africa/Monrovia date -d@1
Wed Dec 31 11:15:31 PM MMT 1969
^^┌─toStartOfMinute(toDateTime(0, 'Africa/Monrovia'))─┐
│ 2106-02-07 06:27:46 │
└───────────────────────────────────────────────────┘And this breaks monotonicity of the function.
It can be fixed to avoid breaking monotonicity, but this will make the result of functions incorrect and also breaks backward compatibility for negative timestamps.
Also note, that it had been changed already in 21.4 select toDateTime(1, 'Africa/Monrovia') dt, toStartOfMinute(dt):
- 21.3:
1970-01-01 00:43:01 1970-01-01 00:43:00 - 21.4:
1969-12-31 23:15:31 1969-12-31 23:15:30Date time64 extended range #9404
… flakiness It is possible for toStartOfMinute() to give different result for 0 and 59, for partial timezones (timezone that does not starts from 00:00, like Africa/Monrovia). Before ClickHouse#36656 it fails for another reason, because of overflows [1], but now it fails because it simply return different minutes. [1]: ClickHouse#29953 (comment) Simply pin the UTC there. Fixes: ClickHouse#37786 Signed-off-by: Azat Khuzhin <[email protected]>
Changelog category (leave one):
Changelog entry (a user-readable short description of the changes that goes to CHANGELOG.md):
Now date time conversion functions that generates time before 1970-01-01 00:00:00 will be saturated to zero instead of overflow.
#2327
#3470
#12377
#17354
#18511
#22928
#25284
#26137
#27150
#29835
Detailed description / Documentation draft:
.