Commit d48cfa8a authored by unknown's avatar unknown
Browse files

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
Loading
Loading
Loading
Loading
+10 −0
Original line number Diff line number Diff line
@@ -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
+8 −1
Original line number Diff line number Diff line
@@ -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
+14 −0
Original line number Diff line number Diff line
@@ -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);
+1 −0
Original line number Diff line number Diff line
@@ -33,6 +33,7 @@ class Item_str_func :public Item_func
  Item_str_func(List<Item> &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);