Fix DateTime64 initialization (to match DateTime behaviour)
There was no specializations for toDateTime64(<numeric>), and because of
this default decimal conversion was used, however this is not enough for
DateTime/DateTime64 types, since the date may overflow and the proper
check is required (like DateTime has), and this what UBsan found [1]:
../src/IO/WriteHelpers.h:812:33: runtime error: index 508 out of bounds for type 'const char [201]' Received signal -3 Received signal Unknown signal (-3)
Backtrace:
(gdb) bt
0 LocalDateTime::LocalDateTime (this=0x7fffffff8418, year_=1970, month_=1 '\001', day_=1 '\001', hour_=2 '\002', minute_=0 '\000', second_=254 '\376') at LocalDateTime.h:83
1 0x00000000138a5edb in DB::writeDateTimeText<(char)45, (char)58, (char)32, (char)46> (datetime64=..., scale=7, buf=..., date_lut=...) at WriteHelpers.h:852
2 0x0000000019c379b4 in DB::DataTypeDateTime64::serializeText (this=0x7ffff5c4b0d8, column=..., row_num=0, ostr=..., settings=...) at DataTypeDateTime64.cpp:66
3 0x0000000019d297e4 in DB::IDataType::serializeAsText (this=0x7ffff5c4b0d8, column=..., row_num=0, ostr=..., settings=...) at IDataType.cpp:387
[1]: https://clickhouse-test-reports.s3.yandex.net/19527/cea8ae162ffbf92e5ed29304ab010704c5d611c8/fuzzer_ubsan/report.html#fail1
Also fix CAST for DateTime64
2021-02-05 19:06:23 +00:00
|
|
|
-- { echo }
|
2021-02-27 11:21:31 +00:00
|
|
|
-- These values are within the extended range of DateTime64 [1925-01-01, 2284-01-01)
|
2022-03-11 23:45:26 +00:00
|
|
|
SELECT toTimeZone(toDateTime(-2, 2), 'Asia/Istanbul');
|
2022-05-27 00:18:38 +00:00
|
|
|
1970-01-01 01:59:58.00
|
2022-03-11 23:45:26 +00:00
|
|
|
SELECT toDateTime64(-2, 2, 'Asia/Istanbul');
|
2022-05-27 00:18:38 +00:00
|
|
|
1970-01-01 01:59:58.00
|
2022-03-11 23:45:26 +00:00
|
|
|
SELECT CAST(-1 AS DateTime64(0, 'Asia/Istanbul'));
|
2022-05-27 00:18:38 +00:00
|
|
|
1970-01-01 01:59:59
|
2022-03-11 23:45:26 +00:00
|
|
|
SELECT CAST('2020-01-01 00:00:00.3' AS DateTime64(0, 'Asia/Istanbul'));
|
2021-02-22 17:44:24 +00:00
|
|
|
2020-01-01 00:00:00
|
2022-03-11 23:45:26 +00:00
|
|
|
SELECT toDateTime64(bitShiftLeft(toUInt64(1), 33), 2, 'Asia/Istanbul') FORMAT Null;
|
|
|
|
SELECT toTimeZone(toDateTime(-2., 2), 'Asia/Istanbul');
|
2022-10-03 18:05:16 +00:00
|
|
|
1970-01-01 01:59:58.00
|
2022-03-11 23:45:26 +00:00
|
|
|
SELECT toDateTime64(-2., 2, 'Asia/Istanbul');
|
2022-10-03 18:05:16 +00:00
|
|
|
1970-01-01 01:59:58.00
|
2022-03-11 23:45:26 +00:00
|
|
|
SELECT toDateTime64(toFloat32(bitShiftLeft(toUInt64(1),33)), 2, 'Asia/Istanbul');
|
2022-10-03 18:05:16 +00:00
|
|
|
2242-03-16 15:56:32.00
|
2022-03-11 23:45:26 +00:00
|
|
|
SELECT toDateTime64(toFloat64(bitShiftLeft(toUInt64(1),33)), 2, 'Asia/Istanbul') FORMAT Null;
|
2020-04-17 13:26:44 +00:00
|
|
|
-- These are outsize of extended range and hence clamped
|
2022-03-11 23:45:26 +00:00
|
|
|
SELECT toDateTime64(-1 * bitShiftLeft(toUInt64(1), 35), 2, 'Asia/Istanbul');
|
2022-07-25 17:06:11 +00:00
|
|
|
1900-01-01 01:56:56.00
|
2022-03-11 23:45:26 +00:00
|
|
|
SELECT CAST(-1 * bitShiftLeft(toUInt64(1), 35) AS DateTime64(3, 'Asia/Istanbul'));
|
2022-07-25 17:06:11 +00:00
|
|
|
1900-01-01 01:56:56.000
|
2022-03-11 23:45:26 +00:00
|
|
|
SELECT CAST(bitShiftLeft(toUInt64(1), 35) AS DateTime64(3, 'Asia/Istanbul'));
|
2022-07-25 17:06:11 +00:00
|
|
|
2299-12-31 23:59:59.000
|
2022-03-11 23:45:26 +00:00
|
|
|
SELECT toDateTime64(bitShiftLeft(toUInt64(1), 35), 2, 'Asia/Istanbul');
|
2022-07-25 17:06:11 +00:00
|
|
|
2299-12-31 23:59:59.00
|