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 }
|
|
|
|
SELECT toDateTime(-2, 2);
|
|
|
|
1970-01-01 03:00:00.00
|
|
|
|
SELECT toDateTime64(-2, 2);
|
|
|
|
1970-01-01 03:00:00.00
|
|
|
|
SELECT CAST(-1 AS DateTime64);
|
|
|
|
1970-01-01 03:00:00.000
|
|
|
|
SELECT CAST('2020-01-01 00:00:00.3' AS DateTime64);
|
|
|
|
2020-01-01 00:00:00.300
|
2021-02-05 19:06:23 +00:00
|
|
|
SELECT toDateTime64(bitShiftLeft(toUInt64(1),33), 2);
|
|
|
|
2106-02-07 09:28:15.00
|
2021-02-21 19:33:18 +00:00
|
|
|
SELECT toDateTime(-2., 2);
|
|
|
|
1970-01-01 03:00:00.00
|
|
|
|
SELECT toDateTime64(-2., 2);
|
|
|
|
1970-01-01 03:00:00.00
|
|
|
|
SELECT toDateTime64(toFloat32(bitShiftLeft(toUInt64(1),33)), 2);
|
|
|
|
2106-02-07 09:28:16.00
|
|
|
|
SELECT toDateTime64(toFloat64(bitShiftLeft(toUInt64(1),33)), 2);
|
|
|
|
2106-02-07 09:28:15.00
|