From d682dc2e709c22bdd6012295b55d3908fe6c546d Mon Sep 17 00:00:00 2001 From: Alexander Barkov Date: Fri, 17 May 2019 08:08:11 +0400 Subject: [PATCH] MDEV-8919 Wrong result for CAST(9999999999999999999.0) --- mysql-test/main/cast.result | 98 ++++++++++++++++++- mysql-test/main/cast.test | 54 ++++++++++ .../suite/funcs_1/r/innodb_func_view.result | 42 ++++---- .../suite/funcs_1/r/memory_func_view.result | 42 ++++---- .../suite/funcs_1/r/myisam_func_view.result | 42 ++++---- sql/item.cc | 34 +++++++ sql/item.h | 2 + sql/sql_type.cc | 32 +++++- sql/sql_type.h | 1 + 9 files changed, 276 insertions(+), 71 deletions(-) diff --git a/mysql-test/main/cast.result b/mysql-test/main/cast.result index 17329cb596f..268999c9ca0 100644 --- a/mysql-test/main/cast.result +++ b/mysql-test/main/cast.result @@ -584,6 +584,8 @@ Note 1105 Cast to signed converted positive out-of-range integer to it's negativ select cast(1.0e+300 as signed int); cast(1.0e+300 as signed int) 9223372036854775807 +Warnings: +Note 1916 Got overflow when converting '1e300' to SIGNED BIGINT. Value truncated create table t1 select cast(1 as unsigned), cast(1 as signed), cast(1 as double(5,2)), cast(1 as decimal(5,3)), cast("A" as binary), cast("A" as char(100)), cast("2001-1-1" as DATE), cast("2001-1-1" as DATETIME), cast("1:2:3" as TIME); show create table t1; Table Create Table @@ -607,8 +609,8 @@ double_val cast_val -1e30 -9223372036854775808 1e30 9223372036854775807 Warnings: -Warning 1916 Got overflow when converting '-1e30' to INT. Value truncated -Warning 1916 Got overflow when converting '1e30' to INT. Value truncated +Note 1916 Got overflow when converting '-1e30' to SIGNED BIGINT. Value truncated +Note 1916 Got overflow when converting '1e30' to SIGNED BIGINT. Value truncated DROP TABLE t1; select isnull(date(NULL)), isnull(cast(NULL as DATE)); isnull(date(NULL)) isnull(cast(NULL as DATE)) @@ -1283,3 +1285,95 @@ SET sql_mode=DEFAULT; SELECT CAST(11068046444225730969 AS SIGNED); CAST(11068046444225730969 AS SIGNED) -7378697629483820647 +# +# MDEV-8919 Wrong result for CAST(9999999999999999999.0) +# +SET sql_mode=''; +SELECT CAST(9999999999999999999e0 AS UNSIGNED); +CAST(9999999999999999999e0 AS UNSIGNED) +10000000000000000000 +CREATE TABLE t1 (a BIGINT UNSIGNED); +INSERT INTO t1 VALUES (9999999999999999999e0); +SELECT * FROM t1; +a +10000000000000000000 +DROP TABLE t1; +SELECT CAST(9999999999999999999.0 AS UNSIGNED); +CAST(9999999999999999999.0 AS UNSIGNED) +9999999999999999999 +CREATE TABLE t1 (a BIGINT UNSIGNED); +INSERT INTO t1 VALUES (9999999999999999999.0); +SELECT * FROM t1; +a +9999999999999999999 +DROP TABLE t1; +SELECT CAST(-1.0 AS UNSIGNED); +CAST(-1.0 AS UNSIGNED) +0 +Warnings: +Warning 1916 Got overflow when converting '-1.0' to UNSIGNED INT. Value truncated +CREATE TABLE t1 (a BIGINT UNSIGNED); +INSERT INTO t1 VALUES (-1.0); +Warnings: +Warning 1264 Out of range value for column 'a' at row 1 +SELECT * FROM t1; +a +0 +DROP TABLE t1; +SELECT CAST(-1e0 AS UNSIGNED); +CAST(-1e0 AS UNSIGNED) +0 +Warnings: +Note 1916 Got overflow when converting '-1' to UNSIGNED BIGINT. Value truncated +CREATE TABLE t1 (a BIGINT UNSIGNED); +INSERT INTO t1 VALUES (-1e0); +Warnings: +Warning 1264 Out of range value for column 'a' at row 1 +SELECT * FROM t1; +a +0 +DROP TABLE t1; +SELECT CAST(-1e308 AS UNSIGNED); +CAST(-1e308 AS UNSIGNED) +0 +Warnings: +Note 1916 Got overflow when converting '-1e308' to UNSIGNED BIGINT. Value truncated +CREATE TABLE t1 (a BIGINT UNSIGNED); +INSERT INTO t1 VALUES (-1e308); +Warnings: +Warning 1264 Out of range value for column 'a' at row 1 +SELECT * FROM t1; +a +0 +DROP TABLE t1; +SELECT CAST(TIME'-00:00:01.123' AS UNSIGNED); +CAST(TIME'-00:00:01.123' AS UNSIGNED) +0 +Warnings: +Note 1916 Got overflow when converting '-00:00:01.123000' to UNSIGNED BIGINT. Value truncated +CREATE TABLE t1 (a BIGINT UNSIGNED); +INSERT INTO t1 VALUES (TIME'-00:00:01.123'); +Warnings: +Warning 1264 Out of range value for column 'a' at row 1 +SELECT * FROM t1; +a +0 +DROP TABLE t1; +CREATE TABLE t1 (a DOUBLE UNSIGNED); +INSERT INTO t1 VALUES (1.9e19); +SELECT CAST(a AS SIGNED), CAST(MIN(a) AS SIGNED) FROM t1; +CAST(a AS SIGNED) CAST(MIN(a) AS SIGNED) +9223372036854775807 9223372036854775807 +Warnings: +Note 1916 Got overflow when converting '1.9e19' to SIGNED BIGINT. Value truncated +Note 1916 Got overflow when converting '1.9e19' to SIGNED BIGINT. Value truncated +DROP TABLE t1; +CREATE TABLE t1 (a DECIMAL(30,1) UNSIGNED); +INSERT INTO t1 VALUES (1e19); +SELECT a, CAST(a AS SIGNED) FROM t1; +a CAST(a AS SIGNED) +10000000000000000000.0 9223372036854775807 +Warnings: +Warning 1916 Got overflow when converting '10000000000000000000.0' to INT. Value truncated +DROP TABLE t1; +SET sql_mode=DEFAULT; diff --git a/mysql-test/main/cast.test b/mysql-test/main/cast.test index f48d6d9f95f..4ec5470e892 100644 --- a/mysql-test/main/cast.test +++ b/mysql-test/main/cast.test @@ -730,3 +730,57 @@ SET sql_mode=DEFAULT; --echo # SELECT CAST(11068046444225730969 AS SIGNED); + +--echo # +--echo # MDEV-8919 Wrong result for CAST(9999999999999999999.0) +--echo # + +SET sql_mode=''; + +SELECT CAST(9999999999999999999e0 AS UNSIGNED); +CREATE TABLE t1 (a BIGINT UNSIGNED); +INSERT INTO t1 VALUES (9999999999999999999e0); +SELECT * FROM t1; +DROP TABLE t1; + +SELECT CAST(9999999999999999999.0 AS UNSIGNED); +CREATE TABLE t1 (a BIGINT UNSIGNED); +INSERT INTO t1 VALUES (9999999999999999999.0); +SELECT * FROM t1; +DROP TABLE t1; + +SELECT CAST(-1.0 AS UNSIGNED); +CREATE TABLE t1 (a BIGINT UNSIGNED); +INSERT INTO t1 VALUES (-1.0); +SELECT * FROM t1; +DROP TABLE t1; + +SELECT CAST(-1e0 AS UNSIGNED); +CREATE TABLE t1 (a BIGINT UNSIGNED); +INSERT INTO t1 VALUES (-1e0); +SELECT * FROM t1; +DROP TABLE t1; + +SELECT CAST(-1e308 AS UNSIGNED); +CREATE TABLE t1 (a BIGINT UNSIGNED); +INSERT INTO t1 VALUES (-1e308); +SELECT * FROM t1; +DROP TABLE t1; + +SELECT CAST(TIME'-00:00:01.123' AS UNSIGNED); +CREATE TABLE t1 (a BIGINT UNSIGNED); +INSERT INTO t1 VALUES (TIME'-00:00:01.123'); +SELECT * FROM t1; +DROP TABLE t1; + +CREATE TABLE t1 (a DOUBLE UNSIGNED); +INSERT INTO t1 VALUES (1.9e19); +SELECT CAST(a AS SIGNED), CAST(MIN(a) AS SIGNED) FROM t1; +DROP TABLE t1; + +CREATE TABLE t1 (a DECIMAL(30,1) UNSIGNED); +INSERT INTO t1 VALUES (1e19); +SELECT a, CAST(a AS SIGNED) FROM t1; +DROP TABLE t1; + +SET sql_mode=DEFAULT; diff --git a/mysql-test/suite/funcs_1/r/innodb_func_view.result b/mysql-test/suite/funcs_1/r/innodb_func_view.result index 7850e017fb2..e7e05016ecb 100644 --- a/mysql-test/suite/funcs_1/r/innodb_func_view.result +++ b/mysql-test/suite/funcs_1/r/innodb_func_view.result @@ -2473,12 +2473,12 @@ my_time, id FROM t1_values WHERE select_id = 93 OR select_id IS NULL order by id; CAST(my_time AS UNSIGNED INTEGER) my_time id NULL NULL 1 -18446744073701165657 -838:59:59 2 +0 -838:59:59 2 8385959 838:59:59 3 130000 13:00:00 4 100000 10:00:00 5 Warnings: -Note 1105 Cast to unsigned converted negative integer to it's positive complement +Note 1916 Got overflow when converting '-838:59:59' to UNSIGNED BIGINT. Value truncated SHOW CREATE VIEW v1; View Create View character_set_client collation_connection v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select cast(`t1_values`.`my_time` as unsigned) AS `CAST(my_time AS UNSIGNED INTEGER)`,`t1_values`.`my_time` AS `my_time`,`t1_values`.`id` AS `id` from `t1_values` latin1 latin1_swedish_ci @@ -2487,12 +2487,12 @@ WHERE v1.id IN (SELECT id FROM t1_values WHERE select_id = 93 OR select_id IS NULL) order by id; CAST(my_time AS UNSIGNED INTEGER) my_time id NULL NULL 1 -18446744073701165657 -838:59:59 2 +0 -838:59:59 2 8385959 838:59:59 3 130000 13:00:00 4 100000 10:00:00 5 Warnings: -Note 1105 Cast to unsigned converted negative integer to it's positive complement +Note 1916 Got overflow when converting '-838:59:59' to UNSIGNED BIGINT. Value truncated DROP VIEW v1; @@ -2581,15 +2581,14 @@ my_double, id FROM t1_values WHERE select_id = 89 OR select_id IS NULL order by id; CAST(my_double AS UNSIGNED INTEGER) my_double id NULL NULL 1 -9223372036854775808 -1.7976931348623e308 2 -9223372036854775807 1.7976931348623e308 3 +0 -1.7976931348623e308 2 +18446744073709551615 1.7976931348623e308 3 0 0 4 -18446744073709551615 -1 5 +0 -1 5 Warnings: -Warning 1916 Got overflow when converting '-1.7976931348623e308' to INT. Value truncated -Note 1105 Cast to unsigned converted negative integer to it's positive complement -Warning 1916 Got overflow when converting '1.7976931348623e308' to INT. Value truncated -Note 1105 Cast to unsigned converted negative integer to it's positive complement +Note 1916 Got overflow when converting '-1.7976931348623e308' to UNSIGNED BIGINT. Value truncated +Note 1916 Got overflow when converting '1.7976931348623e308' to UNSIGNED BIGINT. Value truncated +Note 1916 Got overflow when converting '-1' to UNSIGNED BIGINT. Value truncated SHOW CREATE VIEW v1; View Create View character_set_client collation_connection v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select cast(`t1_values`.`my_double` as unsigned) AS `CAST(my_double AS UNSIGNED INTEGER)`,`t1_values`.`my_double` AS `my_double`,`t1_values`.`id` AS `id` from `t1_values` latin1 latin1_swedish_ci @@ -2598,15 +2597,14 @@ WHERE v1.id IN (SELECT id FROM t1_values WHERE select_id = 89 OR select_id IS NULL) order by id; CAST(my_double AS UNSIGNED INTEGER) my_double id NULL NULL 1 -9223372036854775808 -1.7976931348623e308 2 -9223372036854775807 1.7976931348623e308 3 +0 -1.7976931348623e308 2 +18446744073709551615 1.7976931348623e308 3 0 0 4 -18446744073709551615 -1 5 +0 -1 5 Warnings: -Warning 1916 Got overflow when converting '-1.7976931348623e308' to INT. Value truncated -Note 1105 Cast to unsigned converted negative integer to it's positive complement -Warning 1916 Got overflow when converting '1.7976931348623e308' to INT. Value truncated -Note 1105 Cast to unsigned converted negative integer to it's positive complement +Note 1916 Got overflow when converting '-1.7976931348623e308' to UNSIGNED BIGINT. Value truncated +Note 1916 Got overflow when converting '1.7976931348623e308' to UNSIGNED BIGINT. Value truncated +Note 1916 Got overflow when converting '-1' to UNSIGNED BIGINT. Value truncated DROP VIEW v1; @@ -2964,8 +2962,8 @@ NULL NULL 1 0 0 4 -1 -1 5 Warnings: -Warning 1916 Got overflow when converting '-1.7976931348623e308' to INT. Value truncated -Warning 1916 Got overflow when converting '1.7976931348623e308' to INT. Value truncated +Note 1916 Got overflow when converting '-1.7976931348623e308' to SIGNED BIGINT. Value truncated +Note 1916 Got overflow when converting '1.7976931348623e308' to SIGNED BIGINT. Value truncated SHOW CREATE VIEW v1; View Create View character_set_client collation_connection v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select cast(`t1_values`.`my_double` as signed) AS `CAST(my_double AS SIGNED INTEGER)`,`t1_values`.`my_double` AS `my_double`,`t1_values`.`id` AS `id` from `t1_values` latin1 latin1_swedish_ci @@ -2979,8 +2977,8 @@ NULL NULL 1 0 0 4 -1 -1 5 Warnings: -Warning 1916 Got overflow when converting '-1.7976931348623e308' to INT. Value truncated -Warning 1916 Got overflow when converting '1.7976931348623e308' to INT. Value truncated +Note 1916 Got overflow when converting '-1.7976931348623e308' to SIGNED BIGINT. Value truncated +Note 1916 Got overflow when converting '1.7976931348623e308' to SIGNED BIGINT. Value truncated DROP VIEW v1; diff --git a/mysql-test/suite/funcs_1/r/memory_func_view.result b/mysql-test/suite/funcs_1/r/memory_func_view.result index 88bfa702be8..fc8899375d9 100644 --- a/mysql-test/suite/funcs_1/r/memory_func_view.result +++ b/mysql-test/suite/funcs_1/r/memory_func_view.result @@ -2474,12 +2474,12 @@ my_time, id FROM t1_values WHERE select_id = 93 OR select_id IS NULL order by id; CAST(my_time AS UNSIGNED INTEGER) my_time id NULL NULL 1 -18446744073701165657 -838:59:59 2 +0 -838:59:59 2 8385959 838:59:59 3 130000 13:00:00 4 100000 10:00:00 5 Warnings: -Note 1105 Cast to unsigned converted negative integer to it's positive complement +Note 1916 Got overflow when converting '-838:59:59' to UNSIGNED BIGINT. Value truncated SHOW CREATE VIEW v1; View Create View character_set_client collation_connection v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select cast(`t1_values`.`my_time` as unsigned) AS `CAST(my_time AS UNSIGNED INTEGER)`,`t1_values`.`my_time` AS `my_time`,`t1_values`.`id` AS `id` from `t1_values` latin1 latin1_swedish_ci @@ -2488,12 +2488,12 @@ WHERE v1.id IN (SELECT id FROM t1_values WHERE select_id = 93 OR select_id IS NULL) order by id; CAST(my_time AS UNSIGNED INTEGER) my_time id NULL NULL 1 -18446744073701165657 -838:59:59 2 +0 -838:59:59 2 8385959 838:59:59 3 130000 13:00:00 4 100000 10:00:00 5 Warnings: -Note 1105 Cast to unsigned converted negative integer to it's positive complement +Note 1916 Got overflow when converting '-838:59:59' to UNSIGNED BIGINT. Value truncated DROP VIEW v1; @@ -2582,15 +2582,14 @@ my_double, id FROM t1_values WHERE select_id = 89 OR select_id IS NULL order by id; CAST(my_double AS UNSIGNED INTEGER) my_double id NULL NULL 1 -9223372036854775808 -1.7976931348623e308 2 -9223372036854775807 1.7976931348623e308 3 +0 -1.7976931348623e308 2 +18446744073709551615 1.7976931348623e308 3 0 0 4 -18446744073709551615 -1 5 +0 -1 5 Warnings: -Warning 1916 Got overflow when converting '-1.7976931348623e308' to INT. Value truncated -Note 1105 Cast to unsigned converted negative integer to it's positive complement -Warning 1916 Got overflow when converting '1.7976931348623e308' to INT. Value truncated -Note 1105 Cast to unsigned converted negative integer to it's positive complement +Note 1916 Got overflow when converting '-1.7976931348623e308' to UNSIGNED BIGINT. Value truncated +Note 1916 Got overflow when converting '1.7976931348623e308' to UNSIGNED BIGINT. Value truncated +Note 1916 Got overflow when converting '-1' to UNSIGNED BIGINT. Value truncated SHOW CREATE VIEW v1; View Create View character_set_client collation_connection v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select cast(`t1_values`.`my_double` as unsigned) AS `CAST(my_double AS UNSIGNED INTEGER)`,`t1_values`.`my_double` AS `my_double`,`t1_values`.`id` AS `id` from `t1_values` latin1 latin1_swedish_ci @@ -2599,15 +2598,14 @@ WHERE v1.id IN (SELECT id FROM t1_values WHERE select_id = 89 OR select_id IS NULL) order by id; CAST(my_double AS UNSIGNED INTEGER) my_double id NULL NULL 1 -9223372036854775808 -1.7976931348623e308 2 -9223372036854775807 1.7976931348623e308 3 +0 -1.7976931348623e308 2 +18446744073709551615 1.7976931348623e308 3 0 0 4 -18446744073709551615 -1 5 +0 -1 5 Warnings: -Warning 1916 Got overflow when converting '-1.7976931348623e308' to INT. Value truncated -Note 1105 Cast to unsigned converted negative integer to it's positive complement -Warning 1916 Got overflow when converting '1.7976931348623e308' to INT. Value truncated -Note 1105 Cast to unsigned converted negative integer to it's positive complement +Note 1916 Got overflow when converting '-1.7976931348623e308' to UNSIGNED BIGINT. Value truncated +Note 1916 Got overflow when converting '1.7976931348623e308' to UNSIGNED BIGINT. Value truncated +Note 1916 Got overflow when converting '-1' to UNSIGNED BIGINT. Value truncated DROP VIEW v1; @@ -2965,8 +2963,8 @@ NULL NULL 1 0 0 4 -1 -1 5 Warnings: -Warning 1916 Got overflow when converting '-1.7976931348623e308' to INT. Value truncated -Warning 1916 Got overflow when converting '1.7976931348623e308' to INT. Value truncated +Note 1916 Got overflow when converting '-1.7976931348623e308' to SIGNED BIGINT. Value truncated +Note 1916 Got overflow when converting '1.7976931348623e308' to SIGNED BIGINT. Value truncated SHOW CREATE VIEW v1; View Create View character_set_client collation_connection v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select cast(`t1_values`.`my_double` as signed) AS `CAST(my_double AS SIGNED INTEGER)`,`t1_values`.`my_double` AS `my_double`,`t1_values`.`id` AS `id` from `t1_values` latin1 latin1_swedish_ci @@ -2980,8 +2978,8 @@ NULL NULL 1 0 0 4 -1 -1 5 Warnings: -Warning 1916 Got overflow when converting '-1.7976931348623e308' to INT. Value truncated -Warning 1916 Got overflow when converting '1.7976931348623e308' to INT. Value truncated +Note 1916 Got overflow when converting '-1.7976931348623e308' to SIGNED BIGINT. Value truncated +Note 1916 Got overflow when converting '1.7976931348623e308' to SIGNED BIGINT. Value truncated DROP VIEW v1; diff --git a/mysql-test/suite/funcs_1/r/myisam_func_view.result b/mysql-test/suite/funcs_1/r/myisam_func_view.result index 88bfa702be8..fc8899375d9 100644 --- a/mysql-test/suite/funcs_1/r/myisam_func_view.result +++ b/mysql-test/suite/funcs_1/r/myisam_func_view.result @@ -2474,12 +2474,12 @@ my_time, id FROM t1_values WHERE select_id = 93 OR select_id IS NULL order by id; CAST(my_time AS UNSIGNED INTEGER) my_time id NULL NULL 1 -18446744073701165657 -838:59:59 2 +0 -838:59:59 2 8385959 838:59:59 3 130000 13:00:00 4 100000 10:00:00 5 Warnings: -Note 1105 Cast to unsigned converted negative integer to it's positive complement +Note 1916 Got overflow when converting '-838:59:59' to UNSIGNED BIGINT. Value truncated SHOW CREATE VIEW v1; View Create View character_set_client collation_connection v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select cast(`t1_values`.`my_time` as unsigned) AS `CAST(my_time AS UNSIGNED INTEGER)`,`t1_values`.`my_time` AS `my_time`,`t1_values`.`id` AS `id` from `t1_values` latin1 latin1_swedish_ci @@ -2488,12 +2488,12 @@ WHERE v1.id IN (SELECT id FROM t1_values WHERE select_id = 93 OR select_id IS NULL) order by id; CAST(my_time AS UNSIGNED INTEGER) my_time id NULL NULL 1 -18446744073701165657 -838:59:59 2 +0 -838:59:59 2 8385959 838:59:59 3 130000 13:00:00 4 100000 10:00:00 5 Warnings: -Note 1105 Cast to unsigned converted negative integer to it's positive complement +Note 1916 Got overflow when converting '-838:59:59' to UNSIGNED BIGINT. Value truncated DROP VIEW v1; @@ -2582,15 +2582,14 @@ my_double, id FROM t1_values WHERE select_id = 89 OR select_id IS NULL order by id; CAST(my_double AS UNSIGNED INTEGER) my_double id NULL NULL 1 -9223372036854775808 -1.7976931348623e308 2 -9223372036854775807 1.7976931348623e308 3 +0 -1.7976931348623e308 2 +18446744073709551615 1.7976931348623e308 3 0 0 4 -18446744073709551615 -1 5 +0 -1 5 Warnings: -Warning 1916 Got overflow when converting '-1.7976931348623e308' to INT. Value truncated -Note 1105 Cast to unsigned converted negative integer to it's positive complement -Warning 1916 Got overflow when converting '1.7976931348623e308' to INT. Value truncated -Note 1105 Cast to unsigned converted negative integer to it's positive complement +Note 1916 Got overflow when converting '-1.7976931348623e308' to UNSIGNED BIGINT. Value truncated +Note 1916 Got overflow when converting '1.7976931348623e308' to UNSIGNED BIGINT. Value truncated +Note 1916 Got overflow when converting '-1' to UNSIGNED BIGINT. Value truncated SHOW CREATE VIEW v1; View Create View character_set_client collation_connection v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select cast(`t1_values`.`my_double` as unsigned) AS `CAST(my_double AS UNSIGNED INTEGER)`,`t1_values`.`my_double` AS `my_double`,`t1_values`.`id` AS `id` from `t1_values` latin1 latin1_swedish_ci @@ -2599,15 +2598,14 @@ WHERE v1.id IN (SELECT id FROM t1_values WHERE select_id = 89 OR select_id IS NULL) order by id; CAST(my_double AS UNSIGNED INTEGER) my_double id NULL NULL 1 -9223372036854775808 -1.7976931348623e308 2 -9223372036854775807 1.7976931348623e308 3 +0 -1.7976931348623e308 2 +18446744073709551615 1.7976931348623e308 3 0 0 4 -18446744073709551615 -1 5 +0 -1 5 Warnings: -Warning 1916 Got overflow when converting '-1.7976931348623e308' to INT. Value truncated -Note 1105 Cast to unsigned converted negative integer to it's positive complement -Warning 1916 Got overflow when converting '1.7976931348623e308' to INT. Value truncated -Note 1105 Cast to unsigned converted negative integer to it's positive complement +Note 1916 Got overflow when converting '-1.7976931348623e308' to UNSIGNED BIGINT. Value truncated +Note 1916 Got overflow when converting '1.7976931348623e308' to UNSIGNED BIGINT. Value truncated +Note 1916 Got overflow when converting '-1' to UNSIGNED BIGINT. Value truncated DROP VIEW v1; @@ -2965,8 +2963,8 @@ NULL NULL 1 0 0 4 -1 -1 5 Warnings: -Warning 1916 Got overflow when converting '-1.7976931348623e308' to INT. Value truncated -Warning 1916 Got overflow when converting '1.7976931348623e308' to INT. Value truncated +Note 1916 Got overflow when converting '-1.7976931348623e308' to SIGNED BIGINT. Value truncated +Note 1916 Got overflow when converting '1.7976931348623e308' to SIGNED BIGINT. Value truncated SHOW CREATE VIEW v1; View Create View character_set_client collation_connection v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select cast(`t1_values`.`my_double` as signed) AS `CAST(my_double AS SIGNED INTEGER)`,`t1_values`.`my_double` AS `my_double`,`t1_values`.`id` AS `id` from `t1_values` latin1 latin1_swedish_ci @@ -2980,8 +2978,8 @@ NULL NULL 1 0 0 4 -1 -1 5 Warnings: -Warning 1916 Got overflow when converting '-1.7976931348623e308' to INT. Value truncated -Warning 1916 Got overflow when converting '1.7976931348623e308' to INT. Value truncated +Note 1916 Got overflow when converting '-1.7976931348623e308' to SIGNED BIGINT. Value truncated +Note 1916 Got overflow when converting '1.7976931348623e308' to SIGNED BIGINT. Value truncated DROP VIEW v1; diff --git a/sql/item.cc b/sql/item.cc index 72231497a22..7d901c3333d 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -265,6 +265,40 @@ longlong Item::val_int_unsigned_typecast_from_str() } +longlong Item::val_int_signed_typecast_from_real() +{ + double nr= val_real(); + if (null_value) + return 0; + Converter_double_to_longlong conv(nr, false); + if (conv.error()) + { + THD *thd= current_thd; + push_warning_printf(thd, Sql_condition::WARN_LEVEL_NOTE, + ER_DATA_OVERFLOW, ER_THD(thd, ER_DATA_OVERFLOW), + ErrConvDouble(nr).ptr(), "SIGNED BIGINT"); + } + return conv.result(); +} + + +longlong Item::val_int_unsigned_typecast_from_real() +{ + double nr= val_real(); + if (null_value) + return 0; + Converter_double_to_longlong conv(nr, true); + if (conv.error()) + { + THD *thd= current_thd; + push_warning_printf(thd, Sql_condition::WARN_LEVEL_NOTE, + ER_DATA_OVERFLOW, ER_THD(thd, ER_DATA_OVERFLOW), + ErrConvDouble(nr).ptr(), "UNSIGNED BIGINT"); + } + return conv.result(); +} + + longlong Item::val_int_signed_typecast_from_int() { longlong value= val_int(); diff --git a/sql/item.h b/sql/item.h index ec474b81a08..0c6465f98f6 100644 --- a/sql/item.h +++ b/sql/item.h @@ -1247,12 +1247,14 @@ public: } longlong val_int_unsigned_typecast_from_int(); longlong val_int_unsigned_typecast_from_str(); + longlong val_int_unsigned_typecast_from_real(); /** Get a value for CAST(x AS UNSIGNED). Huge positive unsigned values are converted to negative complements. */ longlong val_int_signed_typecast_from_int(); + longlong val_int_signed_typecast_from_real(); /* This is just a shortcut to avoid the cast. You should still use diff --git a/sql/sql_type.cc b/sql/sql_type.cc index 347c440d154..e100e427068 100644 --- a/sql/sql_type.cc +++ b/sql/sql_type.cc @@ -4490,7 +4490,7 @@ void Type_handler_temporal_result::Item_get_date(THD *thd, Item *item, longlong Type_handler_real_result:: Item_val_int_signed_typecast(Item *item) const { - return item->val_int_signed_typecast_from_int(); + return item->val_int_signed_typecast_from_real(); } longlong Type_handler_int_result:: @@ -4502,7 +4502,7 @@ longlong Type_handler_int_result:: longlong Type_handler_decimal_result:: Item_val_int_signed_typecast(Item *item) const { - return item->val_int(); + return VDec(item).to_longlong(false); } longlong Type_handler_temporal_result:: @@ -4522,7 +4522,7 @@ longlong Type_handler_string_result:: longlong Type_handler_real_result:: Item_val_int_unsigned_typecast(Item *item) const { - return item->val_int_unsigned_typecast_from_int(); + return item->val_int_unsigned_typecast_from_real(); } longlong Type_handler_int_result:: @@ -4537,6 +4537,32 @@ longlong Type_handler_temporal_result:: return item->val_int_unsigned_typecast_from_int(); } +longlong Type_handler_time_common:: + Item_val_int_unsigned_typecast(Item *item) const +{ + /* + TODO: this should eventually be fixed to do rounding + when TIME_ROUND_FRACTIONAL is enabled, together with + Field_{tiny|short|long|longlong}::store_time_dec(). + See MDEV-19502. + */ + THD *thd= current_thd; + Time tm(thd, item); + DBUG_ASSERT(!tm.is_valid_time() == item->null_value); + if (!tm.is_valid_time()) + return 0; + longlong res= tm.to_longlong(); + if (res < 0) + { + push_warning_printf(thd, Sql_condition::WARN_LEVEL_NOTE, + ER_DATA_OVERFLOW, ER_THD(thd, ER_DATA_OVERFLOW), + ErrConvTime(tm.get_mysql_time()).ptr(), + "UNSIGNED BIGINT"); + return 0; + } + return res; +} + longlong Type_handler_string_result:: Item_val_int_unsigned_typecast(Item *item) const { diff --git a/sql/sql_type.h b/sql/sql_type.h index 69b592b8db7..5e6d1ec47f6 100644 --- a/sql/sql_type.h +++ b/sql/sql_type.h @@ -5199,6 +5199,7 @@ public: int Item_save_in_field(Item *item, Field *field, bool no_conversions) const; String *print_item_value(THD *thd, Item *item, String *str) const; Item_cache *Item_get_cache(THD *thd, const Item *item) const; + longlong Item_val_int_unsigned_typecast(Item *item) const; bool Item_hybrid_func_fix_attributes(THD *thd, const char *name, Type_handler_hybrid_field_type *,