diff --git a/mysql-test/r/cast.result b/mysql-test/r/cast.result index eb50d10ce4f..e196ba294d7 100644 --- a/mysql-test/r/cast.result +++ b/mysql-test/r/cast.result @@ -601,8 +601,8 @@ double_val cast_val -1e30 -9223372036854775808 1e30 9223372036854775807 Warnings: -Warning 1292 Truncated incorrect INTEGER value: '-1e30' -Warning 1292 Truncated incorrect INTEGER value: '1e30' +Warning 1916 Got overflow when converting '-1e30' to INT. Value truncated. +Warning 1916 Got overflow when converting '1e30' to INT. Value truncated. DROP TABLE t1; select isnull(date(NULL)), isnull(cast(NULL as DATE)); isnull(date(NULL)) isnull(cast(NULL as DATE)) diff --git a/mysql-test/r/dyncol.result b/mysql-test/r/dyncol.result index 1c26ca16153..ad46cddb785 100644 --- a/mysql-test/r/dyncol.result +++ b/mysql-test/r/dyncol.result @@ -236,7 +236,7 @@ select column_get(column_create(1, 99999999999999999999999999999 AS double), 1 a column_get(column_create(1, 99999999999999999999999999999 AS double), 1 as unsigned int) 18446744073709551615 Warnings: -Warning 1916 Got overflow when converting '1e+29' to UNSIGNED INT. Value truncated. +Warning 1916 Got overflow when converting '1e29' to UNSIGNED INT. Value truncated. select column_get(column_create(1, 999.9 AS double), 1 as unsigned int); column_get(column_create(1, 999.9 AS double), 1 as unsigned int) 1000 @@ -330,7 +330,7 @@ select column_get(column_create(1, -99999999999999999999999999999 AS double), 1 column_get(column_create(1, -99999999999999999999999999999 AS double), 1 as int) -9223372036854775808 Warnings: -Warning 1916 Got overflow when converting '-1e+29' to INT. Value truncated. +Warning 1916 Got overflow when converting '-1e29' to INT. Value truncated. select column_get(column_create(1, "-1212III" AS char), 1 as int); column_get(column_create(1, "-1212III" AS char), 1 as int) -1212 diff --git a/mysql-test/r/type_enum.result b/mysql-test/r/type_enum.result index f0152d08c32..14f5d97f426 100644 --- a/mysql-test/r/type_enum.result +++ b/mysql-test/r/type_enum.result @@ -2151,7 +2151,7 @@ CREATE TABLE t1 (a DOUBLE); INSERT INTO t1 VALUES (9e100); ALTER TABLE t1 MODIFY a ENUM('9e200','9e100'); Warnings: -Warning 1292 Truncated incorrect INTEGER value: '9e100' +Warning 1916 Got overflow when converting '9e100' to INT. Value truncated. Warning 1265 Data truncated for column 'a' at row 1 SELECT * FROM t1; a 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 357c8200f34..1264342fa8a 100644 --- a/mysql-test/suite/funcs_1/r/innodb_func_view.result +++ b/mysql-test/suite/funcs_1/r/innodb_func_view.result @@ -916,8 +916,8 @@ AaBbCcDdEeFfGgHhIiJjÄäÜüÖö 1.7976931348623e308 3 0 4 -1 5 Warnings: -Warning 1292 Truncated incorrect INTEGER value: '-1.7976931348623e308' -Warning 1292 Truncated incorrect INTEGER value: '1.7976931348623e308' +Warning 1916 Got overflow when converting '-1.7976931348623e308' to INT. Value truncated. +Warning 1916 Got overflow when converting '1.7976931348623e308' to INT. 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 left('AaBbCcDdEeFfGgHhIiJjÄäÜüÖö',`t1_values`.`my_double`) AS `LEFT('AaBbCcDdEeFfGgHhIiJjÄäÜüÖö', my_double)`,`t1_values`.`my_double` AS `my_double`,`t1_values`.`id` AS `id` from `t1_values` latin1 latin1_swedish_ci @@ -931,8 +931,8 @@ AaBbCcDdEeFfGgHhIiJjÄäÜüÖö 1.7976931348623e308 3 0 4 -1 5 Warnings: -Warning 1292 Truncated incorrect INTEGER value: '-1.7976931348623e308' -Warning 1292 Truncated incorrect INTEGER value: '1.7976931348623e308' +Warning 1916 Got overflow when converting '-1.7976931348623e308' to INT. Value truncated. +Warning 1916 Got overflow when converting '1.7976931348623e308' to INT. Value truncated. DROP VIEW v1; @@ -2586,9 +2586,9 @@ NULL NULL 1 0 0 4 18446744073709551615 -1 5 Warnings: -Warning 1292 Truncated incorrect INTEGER value: '-1.7976931348623e308' +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 1292 Truncated incorrect INTEGER value: '1.7976931348623e308' +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 SHOW CREATE VIEW v1; View Create View character_set_client collation_connection @@ -2603,9 +2603,9 @@ NULL NULL 1 0 0 4 18446744073709551615 -1 5 Warnings: -Warning 1292 Truncated incorrect INTEGER value: '-1.7976931348623e308' +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 1292 Truncated incorrect INTEGER value: '1.7976931348623e308' +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 DROP VIEW v1; @@ -2964,8 +2964,8 @@ NULL NULL 1 0 0 4 -1 -1 5 Warnings: -Warning 1292 Truncated incorrect INTEGER value: '-1.7976931348623e308' -Warning 1292 Truncated incorrect INTEGER value: '1.7976931348623e308' +Warning 1916 Got overflow when converting '-1.7976931348623e308' to INT. Value truncated. +Warning 1916 Got overflow when converting '1.7976931348623e308' to INT. 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 +2979,8 @@ NULL NULL 1 0 0 4 -1 -1 5 Warnings: -Warning 1292 Truncated incorrect INTEGER value: '-1.7976931348623e308' -Warning 1292 Truncated incorrect INTEGER value: '1.7976931348623e308' +Warning 1916 Got overflow when converting '-1.7976931348623e308' to INT. Value truncated. +Warning 1916 Got overflow when converting '1.7976931348623e308' to INT. 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 df57c83164e..c78cf163ada 100644 --- a/mysql-test/suite/funcs_1/r/memory_func_view.result +++ b/mysql-test/suite/funcs_1/r/memory_func_view.result @@ -917,8 +917,8 @@ AaBbCcDdEeFfGgHhIiJjÄäÜüÖö 1.7976931348623e308 3 0 4 -1 5 Warnings: -Warning 1292 Truncated incorrect INTEGER value: '-1.7976931348623e308' -Warning 1292 Truncated incorrect INTEGER value: '1.7976931348623e308' +Warning 1916 Got overflow when converting '-1.7976931348623e308' to INT. Value truncated. +Warning 1916 Got overflow when converting '1.7976931348623e308' to INT. 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 left('AaBbCcDdEeFfGgHhIiJjÄäÜüÖö',`t1_values`.`my_double`) AS `LEFT('AaBbCcDdEeFfGgHhIiJjÄäÜüÖö', my_double)`,`t1_values`.`my_double` AS `my_double`,`t1_values`.`id` AS `id` from `t1_values` latin1 latin1_swedish_ci @@ -932,8 +932,8 @@ AaBbCcDdEeFfGgHhIiJjÄäÜüÖö 1.7976931348623e308 3 0 4 -1 5 Warnings: -Warning 1292 Truncated incorrect INTEGER value: '-1.7976931348623e308' -Warning 1292 Truncated incorrect INTEGER value: '1.7976931348623e308' +Warning 1916 Got overflow when converting '-1.7976931348623e308' to INT. Value truncated. +Warning 1916 Got overflow when converting '1.7976931348623e308' to INT. Value truncated. DROP VIEW v1; @@ -2587,9 +2587,9 @@ NULL NULL 1 0 0 4 18446744073709551615 -1 5 Warnings: -Warning 1292 Truncated incorrect INTEGER value: '-1.7976931348623e308' +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 1292 Truncated incorrect INTEGER value: '1.7976931348623e308' +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 SHOW CREATE VIEW v1; View Create View character_set_client collation_connection @@ -2604,9 +2604,9 @@ NULL NULL 1 0 0 4 18446744073709551615 -1 5 Warnings: -Warning 1292 Truncated incorrect INTEGER value: '-1.7976931348623e308' +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 1292 Truncated incorrect INTEGER value: '1.7976931348623e308' +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 DROP VIEW v1; @@ -2965,8 +2965,8 @@ NULL NULL 1 0 0 4 -1 -1 5 Warnings: -Warning 1292 Truncated incorrect INTEGER value: '-1.7976931348623e308' -Warning 1292 Truncated incorrect INTEGER value: '1.7976931348623e308' +Warning 1916 Got overflow when converting '-1.7976931348623e308' to INT. Value truncated. +Warning 1916 Got overflow when converting '1.7976931348623e308' to INT. 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 +2980,8 @@ NULL NULL 1 0 0 4 -1 -1 5 Warnings: -Warning 1292 Truncated incorrect INTEGER value: '-1.7976931348623e308' -Warning 1292 Truncated incorrect INTEGER value: '1.7976931348623e308' +Warning 1916 Got overflow when converting '-1.7976931348623e308' to INT. Value truncated. +Warning 1916 Got overflow when converting '1.7976931348623e308' to INT. 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 df57c83164e..c78cf163ada 100644 --- a/mysql-test/suite/funcs_1/r/myisam_func_view.result +++ b/mysql-test/suite/funcs_1/r/myisam_func_view.result @@ -917,8 +917,8 @@ AaBbCcDdEeFfGgHhIiJjÄäÜüÖö 1.7976931348623e308 3 0 4 -1 5 Warnings: -Warning 1292 Truncated incorrect INTEGER value: '-1.7976931348623e308' -Warning 1292 Truncated incorrect INTEGER value: '1.7976931348623e308' +Warning 1916 Got overflow when converting '-1.7976931348623e308' to INT. Value truncated. +Warning 1916 Got overflow when converting '1.7976931348623e308' to INT. 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 left('AaBbCcDdEeFfGgHhIiJjÄäÜüÖö',`t1_values`.`my_double`) AS `LEFT('AaBbCcDdEeFfGgHhIiJjÄäÜüÖö', my_double)`,`t1_values`.`my_double` AS `my_double`,`t1_values`.`id` AS `id` from `t1_values` latin1 latin1_swedish_ci @@ -932,8 +932,8 @@ AaBbCcDdEeFfGgHhIiJjÄäÜüÖö 1.7976931348623e308 3 0 4 -1 5 Warnings: -Warning 1292 Truncated incorrect INTEGER value: '-1.7976931348623e308' -Warning 1292 Truncated incorrect INTEGER value: '1.7976931348623e308' +Warning 1916 Got overflow when converting '-1.7976931348623e308' to INT. Value truncated. +Warning 1916 Got overflow when converting '1.7976931348623e308' to INT. Value truncated. DROP VIEW v1; @@ -2587,9 +2587,9 @@ NULL NULL 1 0 0 4 18446744073709551615 -1 5 Warnings: -Warning 1292 Truncated incorrect INTEGER value: '-1.7976931348623e308' +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 1292 Truncated incorrect INTEGER value: '1.7976931348623e308' +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 SHOW CREATE VIEW v1; View Create View character_set_client collation_connection @@ -2604,9 +2604,9 @@ NULL NULL 1 0 0 4 18446744073709551615 -1 5 Warnings: -Warning 1292 Truncated incorrect INTEGER value: '-1.7976931348623e308' +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 1292 Truncated incorrect INTEGER value: '1.7976931348623e308' +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 DROP VIEW v1; @@ -2965,8 +2965,8 @@ NULL NULL 1 0 0 4 -1 -1 5 Warnings: -Warning 1292 Truncated incorrect INTEGER value: '-1.7976931348623e308' -Warning 1292 Truncated incorrect INTEGER value: '1.7976931348623e308' +Warning 1916 Got overflow when converting '-1.7976931348623e308' to INT. Value truncated. +Warning 1916 Got overflow when converting '1.7976931348623e308' to INT. 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 +2980,8 @@ NULL NULL 1 0 0 4 -1 -1 5 Warnings: -Warning 1292 Truncated incorrect INTEGER value: '-1.7976931348623e308' -Warning 1292 Truncated incorrect INTEGER value: '1.7976931348623e308' +Warning 1916 Got overflow when converting '-1.7976931348623e308' to INT. Value truncated. +Warning 1916 Got overflow when converting '1.7976931348623e308' to INT. Value truncated. DROP VIEW v1; diff --git a/sql/field.cc b/sql/field.cc index c684e6a8046..bd7f7c3f689 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -4288,16 +4288,13 @@ int Field_longlong::store(const char *from,uint len,CHARSET_INFO *cs) int Field_longlong::store(double nr) { ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED; - bool error; - longlong res; + Converter_double_to_longlong conv(nr, unsigned_flag); - res= double_to_longlong(nr, unsigned_flag, &error); - - if (error) + if (conv.error()) set_warning(ER_WARN_DATA_OUT_OF_RANGE, 1); - int8store(ptr,res); - return error; + int8store(ptr, conv.result()); + return conv.error(); } @@ -4698,53 +4695,61 @@ int truncate_double(double *nr, uint field_length, uint dec, /* Convert double to longlong / ulonglong. - If double is outside of range, adjust return value and set error. + If double is outside of the supported range, + adjust m_result and set m_error. - SYNOPSIS - double_to_longlong() - nr Number to convert - unsigned_flag 1 if result is unsigned - error Will be set to 1 in case of overflow. + @param nr Number to convert + @param unsigned_flag true if result is unsigned */ -longlong double_to_longlong(double nr, bool unsigned_flag, bool *error) +Value_source:: +Converter_double_to_longlong::Converter_double_to_longlong(double nr, + bool unsigned_flag) + :m_error(false) { - longlong res; - - *error= 0; - nr= rint(nr); if (unsigned_flag) { if (nr < 0) { - res= 0; - *error= 1; + m_result= 0; + m_error= true; } else if (nr >= (double) ULONGLONG_MAX) { - res= ~(longlong) 0; - *error= 1; + m_result= ~(longlong) 0; + m_error= true; } else - res= (longlong) double2ulonglong(nr); + m_result= (longlong) double2ulonglong(nr); } else { if (nr <= (double) LONGLONG_MIN) { - res= LONGLONG_MIN; - *error= (nr < (double) LONGLONG_MIN); + m_result= LONGLONG_MIN; + m_error= (nr < (double) LONGLONG_MIN); } else if (nr >= (double) (ulonglong) LONGLONG_MAX) { - res= LONGLONG_MAX; - *error= (nr > (double) LONGLONG_MAX); + m_result= LONGLONG_MAX; + m_error= (nr > (double) LONGLONG_MAX); } else - res= (longlong) nr; + m_result= (longlong) nr; } - return res; +} + + +void Value_source:: +Converter_double_to_longlong::push_warning(THD *thd, + double nr, + bool unsigned_flag) +{ + push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN, + ER_DATA_OVERFLOW, ER_THD(thd, ER_DATA_OVERFLOW), + ErrConvDouble(nr).ptr(), + unsigned_flag ? "UNSIGNED INT" : "INT"); } @@ -4769,27 +4774,6 @@ double Field_double::val_real(void) return j; } -longlong Field_double::val_int(void) -{ - ASSERT_COLUMN_MARKED_FOR_READ; - double j; - longlong res; - bool error; - float8get(j,ptr); - - res= double_to_longlong(j, 0, &error); - if (error) - { - THD *thd= get_thd(); - ErrConvDouble err(j); - push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN, - ER_TRUNCATED_WRONG_VALUE, - ER_THD(thd, ER_TRUNCATED_WRONG_VALUE), "INTEGER", - err.ptr()); - } - return res; -} - my_decimal *Field_real::val_decimal(my_decimal *decimal_value) { diff --git a/sql/field.h b/sql/field.h index 05e0615a163..13a0e914845 100644 --- a/sql/field.h +++ b/sql/field.h @@ -80,6 +80,35 @@ protected: Warn_filter_all() :Warn_filter(true, true) { } }; + class Converter_double_to_longlong + { + protected: + bool m_error; + longlong m_result; + public: + Converter_double_to_longlong(double nr, bool unsigned_flag); + longlong result() const { return m_result; } + bool error() const { return m_error; } + void push_warning(THD *thd, double nr, bool unsigned_flag); + }; + class Converter_double_to_longlong_with_warn: + public Converter_double_to_longlong + { + public: + Converter_double_to_longlong_with_warn(THD *thd, double nr, + bool unsigned_flag) + :Converter_double_to_longlong(nr, unsigned_flag) + { + if (m_error) + push_warning(thd, nr, unsigned_flag); + } + Converter_double_to_longlong_with_warn(double nr, bool unsigned_flag) + :Converter_double_to_longlong(nr, unsigned_flag) + { + if (m_error) + push_warning(current_thd, nr, unsigned_flag); + } + }; // String-to-number converters class Converter_string_to_number @@ -406,7 +435,6 @@ struct st_cache_field; int field_conv(Field *to,Field *from); int truncate_double(double *nr, uint field_length, uint dec, bool unsigned_flag, double max_value); -longlong double_to_longlong(double nr, bool unsigned_flag, bool *error); inline uint get_enum_pack_length(int elements) { @@ -2148,7 +2176,13 @@ public: int store(longlong nr, bool unsigned_val); int reset(void) { bzero(ptr,sizeof(double)); return 0; } double val_real(void); - longlong val_int(void); + longlong val_int(void) + { + Converter_double_to_longlong conv(Field_double::val_real(), false); + if (conv.error()) + conv.push_warning(get_thd(), Field_double::val_real(), false); + return conv.result(); + } String *val_str(String*,String *); bool send_binary(Protocol *protocol); int cmp(const uchar *,const uchar *); diff --git a/sql/item.cc b/sql/item.cc index 65b8cf25c9b..2fb507cd720 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -374,14 +374,6 @@ longlong Item::val_int_from_date() } -longlong Item::val_int_from_real() -{ - DBUG_ASSERT(fixed == 1); - bool error; - return double_to_longlong(val_real(), false /*unsigned_flag*/, &error); -} - - double Item::val_real_from_date() { DBUG_ASSERT(fixed == 1); diff --git a/sql/item.h b/sql/item.h index 2e0afe1ce1a..e43b4d50e46 100644 --- a/sql/item.h +++ b/sql/item.h @@ -1041,7 +1041,11 @@ public: my_decimal *val_decimal_from_time(my_decimal *decimal_value); longlong val_int_from_decimal(); longlong val_int_from_date(); - longlong val_int_from_real(); + longlong val_int_from_real() + { + DBUG_ASSERT(fixed == 1); + return Converter_double_to_longlong_with_warn(val_real(), false).result(); + } longlong val_int_from_str(int *error); double val_real_from_decimal(); double val_real_from_date(); diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index 76ae66b9cfe..3f5f0505d4c 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -4960,23 +4960,8 @@ longlong Item_dyncol_get::val_int() unsigned_flag= 0; // Make it possible for caller to detect sign return val.x.long_value; case DYN_COL_DOUBLE: - { - bool error; - longlong num; - - num= double_to_longlong(val.x.double_value, unsigned_flag, &error); - if (error) - { - char buff[30]; - sprintf(buff, "%lg", val.x.double_value); - push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN, - ER_DATA_OVERFLOW, - ER_THD(thd, ER_DATA_OVERFLOW), - buff, - unsigned_flag ? "UNSIGNED INT" : "INT"); - } - return num; - } + return Converter_double_to_longlong_with_warn(thd, val.x.double_value, + unsigned_flag).result(); case DYN_COL_STRING: { int error;