From e57492c214ea6cfb9ed48e939f84324b44379066 Mon Sep 17 00:00:00 2001 From: Joanna Hulboj Date: Wed, 1 Feb 2023 18:22:06 +0000 Subject: [PATCH] Improve behaviour of conversion into Date for boundary value 65535 --- src/Functions/FunctionsConversion.h | 4 +- ...lumn_consistent_insert_behaviour.reference | 27 +++++++ ...ate_column_consistent_insert_behaviour.sql | 72 +++++++++++++++++++ 3 files changed, 101 insertions(+), 2 deletions(-) create mode 100644 tests/queries/0_stateless/02540_date_column_consistent_insert_behaviour.reference create mode 100644 tests/queries/0_stateless/02540_date_column_consistent_insert_behaviour.sql diff --git a/src/Functions/FunctionsConversion.h b/src/Functions/FunctionsConversion.h index d1c0d80d346..eb0cddb47c3 100644 --- a/src/Functions/FunctionsConversion.h +++ b/src/Functions/FunctionsConversion.h @@ -374,7 +374,7 @@ struct ToDateTransform32Or64 static NO_SANITIZE_UNDEFINED ToType execute(const FromType & from, const DateLUTImpl & time_zone) { // since converting to Date, no need in values outside of default LUT range. - return (from < DATE_LUT_MAX_DAY_NUM) + return (from <= DATE_LUT_MAX_DAY_NUM) ? from : time_zone.toDayNum(std::min(time_t(from), time_t(0xFFFFFFFF))); } @@ -391,7 +391,7 @@ struct ToDateTransform32Or64Signed /// The function should be monotonic (better for query optimizations), so we saturate instead of overflow. if (from < 0) return 0; - return (from < DATE_LUT_MAX_DAY_NUM) + return (from <= DATE_LUT_MAX_DAY_NUM) ? static_cast(from) : time_zone.toDayNum(std::min(time_t(from), time_t(0xFFFFFFFF))); } diff --git a/tests/queries/0_stateless/02540_date_column_consistent_insert_behaviour.reference b/tests/queries/0_stateless/02540_date_column_consistent_insert_behaviour.reference new file mode 100644 index 00000000000..276c1456af6 --- /dev/null +++ b/tests/queries/0_stateless/02540_date_column_consistent_insert_behaviour.reference @@ -0,0 +1,27 @@ +2149-06-06 65535 +2149-06-06 toUInt16(65535) +2149-06-06 toInt32(65535) +2149-06-06 toUInt32(65535) +2149-06-06 toDate(65535) +2149-06-06 CAST(65535 as UInt16) +2149-06-06 CAST(65535 as Int32) +2149-06-06 CAST(65535 as UInt32) +2149-06-06 CAST(65535 as Date) +2149-06-05 65534 +2149-06-05 toUInt16(65534) +2149-06-05 toInt32(65534) +2149-06-05 toUInt32(65534) +2149-06-05 toDate(65534) +2149-06-05 CAST(65534 as UInt16) +2149-06-05 CAST(65534 as Int32) +2149-06-05 CAST(65534 as UInt32) +2149-06-05 CAST(65534 as Date) +1970-01-01 65536 +1970-01-01 toUInt16(65536) +1970-01-01 toInt32(65536) +1970-01-01 toUInt32(65536) +1970-01-01 toDate(65536) +1970-01-01 CAST(65536 as UInt16) +1970-01-01 CAST(65536 as Int32) +1970-01-01 CAST(65536 as UInt32) +1970-01-01 CAST(65536 as Date) diff --git a/tests/queries/0_stateless/02540_date_column_consistent_insert_behaviour.sql b/tests/queries/0_stateless/02540_date_column_consistent_insert_behaviour.sql new file mode 100644 index 00000000000..20614f648ab --- /dev/null +++ b/tests/queries/0_stateless/02540_date_column_consistent_insert_behaviour.sql @@ -0,0 +1,72 @@ +DROP TABLE IF EXISTS 02540_date; +CREATE TABLE 02540_date (txt String, x Date) engine=Memory; + +-- Date: Supported range of values: [1970-01-01, 2149-06-06]. +-- ^----closed interval---^ + +INSERT INTO 02540_date VALUES('65535', 65535); +INSERT INTO 02540_date VALUES('toUInt16(65535)', toUInt16(65535)); -- #43370 weird one -> used to be 1970-01-01 +INSERT INTO 02540_date VALUES('toInt32(65535)', toInt32(65535)); +INSERT INTO 02540_date VALUES('toUInt32(65535)', toUInt32(65535)); +INSERT INTO 02540_date VALUES('toDate(65535)', toDate(65535)); + +INSERT INTO 02540_date VALUES('CAST(65535 as UInt16)', CAST(65535 as UInt16)); +INSERT INTO 02540_date VALUES('CAST(65535 as Int32)', CAST(65535 as Int32)); +INSERT INTO 02540_date VALUES('CAST(65535 as UInt32)', CAST(65535 as UInt32)); +INSERT INTO 02540_date VALUES('CAST(65535 as Date)', CAST(65535 as Date)); + +INSERT INTO 02540_date VALUES('65534', 65534); +INSERT INTO 02540_date VALUES('toUInt16(65534)', toUInt16(65534)); +INSERT INTO 02540_date VALUES('toInt32(65534)', toInt32(65534)); +INSERT INTO 02540_date VALUES('toUInt32(65534)', toUInt32(65534)); +INSERT INTO 02540_date VALUES('toDate(65534)', toDate(65534)); + +INSERT INTO 02540_date VALUES('CAST(65534 as UInt16)', CAST(65534 as UInt16)); +INSERT INTO 02540_date VALUES('CAST(65534 as Int32)', CAST(65534 as Int32)); +INSERT INTO 02540_date VALUES('CAST(65534 as UInt32)', CAST(65534 as UInt32)); +INSERT INTO 02540_date VALUES('CAST(65534 as Date)', CAST(65534 as Date)); + +INSERT INTO 02540_date VALUES('65536', 65536); +INSERT INTO 02540_date VALUES('toUInt16(65536)', toUInt16(65536)); +INSERT INTO 02540_date VALUES('toInt32(65536)', toInt32(65536)); +INSERT INTO 02540_date VALUES('toUInt32(65536)', toUInt32(65536)); +INSERT INTO 02540_date VALUES('toDate(65536)', toDate(65536)); + +INSERT INTO 02540_date VALUES('CAST(65536 as UInt16)', CAST(65536 as UInt16)); +INSERT INTO 02540_date VALUES('CAST(65536 as Int32)', CAST(65536 as Int32)); +INSERT INTO 02540_date VALUES('CAST(65536 as UInt32)', CAST(65536 as UInt32)); +INSERT INTO 02540_date VALUES('CAST(65536 as Date)', CAST(65536 as Date)); + + +SELECT x, txt FROM 02540_date WHERE txt == '65535'; +SELECT x, txt FROM 02540_date WHERE txt == 'toUInt16(65535)'; +SELECT x, txt FROM 02540_date WHERE txt == 'toInt32(65535)'; +SELECT x, txt FROM 02540_date WHERE txt == 'toUInt32(65535)'; +SELECT x, txt FROM 02540_date WHERE txt == 'toDate(65535)'; + +SELECT x, txt FROM 02540_date WHERE txt == 'CAST(65535 as UInt16)'; +SELECT x, txt FROM 02540_date WHERE txt == 'CAST(65535 as Int32)'; +SELECT x, txt FROM 02540_date WHERE txt == 'CAST(65535 as UInt32)'; +SELECT x, txt FROM 02540_date WHERE txt == 'CAST(65535 as Date)'; + +SELECT x, txt FROM 02540_date WHERE txt == '65534'; +SELECT x, txt FROM 02540_date WHERE txt == 'toUInt16(65534)'; +SELECT x, txt FROM 02540_date WHERE txt == 'toInt32(65534)'; +SELECT x, txt FROM 02540_date WHERE txt == 'toUInt32(65534)'; +SELECT x, txt FROM 02540_date WHERE txt == 'toDate(65534)'; + +SELECT x, txt FROM 02540_date WHERE txt == 'CAST(65534 as UInt16)'; +SELECT x, txt FROM 02540_date WHERE txt == 'CAST(65534 as Int32)'; +SELECT x, txt FROM 02540_date WHERE txt == 'CAST(65534 as UInt32)'; +SELECT x, txt FROM 02540_date WHERE txt == 'CAST(65534 as Date)'; + +SELECT x, txt FROM 02540_date WHERE txt == '65536'; +SELECT x, txt FROM 02540_date WHERE txt == 'toUInt16(65536)'; +SELECT x, txt FROM 02540_date WHERE txt == 'toInt32(65536)'; +SELECT x, txt FROM 02540_date WHERE txt == 'toUInt32(65536)'; +SELECT x, txt FROM 02540_date WHERE txt == 'toDate(65536)'; + +SELECT x, txt FROM 02540_date WHERE txt == 'CAST(65536 as UInt16)'; +SELECT x, txt FROM 02540_date WHERE txt == 'CAST(65536 as Int32)'; +SELECT x, txt FROM 02540_date WHERE txt == 'CAST(65536 as UInt32)'; +SELECT x, txt FROM 02540_date WHERE txt == 'CAST(65536 as Date)';