Commit d48cfa8a authored by unknown's avatar unknown

Bug #17043: Casting trimmed string to decimal loses precision

  Results of string functions were being converted to decimals by first
  being converted to integers, resulting in a loss of precision.


mysql-test/r/func_str.result:
  Add new results
mysql-test/t/func_str.test:
  Add new regression test
sql/item_strfunc.cc:
  Convert string function results to decimal using string-to-decimal conversion
sql/item_strfunc.h:
  Add Item_str_func::val_decimal()
parent 358e0883
...@@ -1030,3 +1030,13 @@ c res ...@@ -1030,3 +1030,13 @@ c res
y,abc abc y,abc abc
y,abc abc y,abc abc
drop table t1; 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
...@@ -684,4 +684,11 @@ insert into t1 values ('y,abc'),('y,abc'); ...@@ -684,4 +684,11 @@ insert into t1 values ('y,abc'),('y,abc');
select c, substring_index(lcase(c), @q:=',', -1) as res from t1; select c, substring_index(lcase(c), @q:=',', -1) as res from t1;
drop table 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
...@@ -80,6 +80,20 @@ String *Item_str_func::check_well_formed_result(String *str) ...@@ -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() double Item_str_func::val_real()
{ {
DBUG_ASSERT(fixed == 1); DBUG_ASSERT(fixed == 1);
......
...@@ -33,6 +33,7 @@ public: ...@@ -33,6 +33,7 @@ public:
Item_str_func(List<Item> &list) :Item_func(list) {decimals=NOT_FIXED_DEC; } Item_str_func(List<Item> &list) :Item_func(list) {decimals=NOT_FIXED_DEC; }
longlong val_int(); longlong val_int();
double val_real(); double val_real();
my_decimal *val_decimal(my_decimal *);
enum Item_result result_type () const { return STRING_RESULT; } enum Item_result result_type () const { return STRING_RESULT; }
void left_right_max_length(); void left_right_max_length();
String *check_well_formed_result(String *str); String *check_well_formed_result(String *str);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment