diff --git a/mysql-test/r/func_str.result b/mysql-test/r/func_str.result index 911d6eea033..aed79e7f8fa 100644 --- a/mysql-test/r/func_str.result +++ b/mysql-test/r/func_str.result @@ -1030,3 +1030,13 @@ c res y,abc abc y,abc abc drop table t1; +select cast(rtrim(' 20.06 ') as decimal(19,2)); +cast(rtrim(' 20.06 ') as decimal(19,2)) +20.06 +select cast(ltrim(' 20.06 ') as decimal(19,2)); +cast(ltrim(' 20.06 ') as decimal(19,2)) +20.06 +select cast(rtrim(ltrim(' 20.06 ')) as decimal(19,2)); +cast(rtrim(ltrim(' 20.06 ')) as decimal(19,2)) +20.06 +End of 5.0 tests diff --git a/mysql-test/t/func_str.test b/mysql-test/t/func_str.test index ef20d766bce..85cedee0f4a 100644 --- a/mysql-test/t/func_str.test +++ b/mysql-test/t/func_str.test @@ -684,4 +684,11 @@ insert into t1 values ('y,abc'),('y,abc'); select c, substring_index(lcase(c), @q:=',', -1) as res from t1; drop table t1; -# End of 5.0 tests +# +# Bug #17043: Casting trimmed string to decimal loses precision +# +select cast(rtrim(' 20.06 ') as decimal(19,2)); +select cast(ltrim(' 20.06 ') as decimal(19,2)); +select cast(rtrim(ltrim(' 20.06 ')) as decimal(19,2)); + +--echo End of 5.0 tests diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index a3e47154bc3..60183ac9b5a 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -80,6 +80,20 @@ String *Item_str_func::check_well_formed_result(String *str) } +my_decimal *Item_str_func::val_decimal(my_decimal *decimal_value) +{ + DBUG_ASSERT(fixed == 1); + char buff[64]; + String *res, tmp(buff,sizeof(buff), &my_charset_bin); + res= val_str(&tmp); + if (!res) + return 0; + (void)str2my_decimal(E_DEC_FATAL_ERROR, (char*) res->ptr(), + res->length(), res->charset(), decimal_value); + return decimal_value; +} + + double Item_str_func::val_real() { DBUG_ASSERT(fixed == 1); diff --git a/sql/item_strfunc.h b/sql/item_strfunc.h index 6a95a9e5d1f..7d7b62df0dc 100644 --- a/sql/item_strfunc.h +++ b/sql/item_strfunc.h @@ -33,6 +33,7 @@ public: Item_str_func(List &list) :Item_func(list) {decimals=NOT_FIXED_DEC; } longlong val_int(); double val_real(); + my_decimal *val_decimal(my_decimal *); enum Item_result result_type () const { return STRING_RESULT; } void left_right_max_length(); String *check_well_formed_result(String *str);