List:Commits« Previous MessageNext Message »
From:holyfoot Date:May 12 2008 6:59am
Subject:bk commit into 5.1 tree (holyfoot:1.2582) BUG#36025
View as plain text  
Below is the list of changes that have just been committed into a local
5.1 repository of holyfoot.  When holyfoot does a push these changes
will be propagated to the main repository and, within 24 hours after the
push, to the public repository.
For information on how to access the public repository
see http://dev.mysql.com/doc/mysql/en/installing-source-tree.html

ChangeSet@stripped, 2008-05-12 09:58:57+05:00, holyfoot@stripped +4 -0
  Bug #36025 func_1.<engine>_storedproc test failing on Windows.
  
  Float types are of limited precision (15 digits for DOUBLE for example), so
  if the string representation has more than 15 digits, the precision of
  the initial string will be lost. Which is worse, different sprintf() versions
  can produce slightly different result on these data (what caused this bug).
  As we implement homegrovn double->string conversion in 6.0, this bug will
  disappear there. Still i'd propose this patch. Here we store the initial
  string representation of a 'float' value and use it to produce decimal if
  it's necessary. That way, we won't lost the precision up to 60 digits.

  mysql-test/r/type_newdecimal.result@stripped, 2008-05-12 09:58:54+05:00, holyfoot@stripped
+3 -0
    Bug #36025 func_1.<engine>_storedproc test failing on Windows
    
    test result

  mysql-test/t/type_newdecimal.test@stripped, 2008-05-12 09:58:54+05:00, holyfoot@stripped +7
-0
    Bug #36025 func_1.<engine>_storedproc test failing on Windows
    
    test case

  sql/item.cc@stripped, 2008-05-12 09:58:54+05:00, holyfoot@stripped +10 -1
    Bug #36025 func_1.<engine>_storedproc test failing on Windows.
    
    Store string representation of the double in the 'value_str' member.
    Then use this string to create decimal result rather than the 'value' itself.

  sql/item.h@stripped, 2008-05-12 09:58:54+05:00, holyfoot@stripped +10 -3
    Bug #36025 func_1.<engine>_storedproc test failing on Windows.
    
    Item_float::value_str member added to store string representation of the
    number

diff -Nrup a/mysql-test/r/type_newdecimal.result b/mysql-test/r/type_newdecimal.result
--- a/mysql-test/r/type_newdecimal.result	2007-11-17 22:42:14 +04:00
+++ b/mysql-test/r/type_newdecimal.result	2008-05-12 09:58:54 +05:00
@@ -1557,3 +1557,6 @@ Error	1264	Out of range value for column
 select cast(98.6 as decimal(2,0));
 cast(98.6 as decimal(2,0))
 99
+select cast(0.123456789098765432101234567890987654321e+29 as decimal(60,30));
+cast(0.123456789098765432101234567890987654321e+29 as decimal(60,30))
+12345678909876543210123456789.098765432100000000000000000000
diff -Nrup a/mysql-test/t/type_newdecimal.test b/mysql-test/t/type_newdecimal.test
--- a/mysql-test/t/type_newdecimal.test	2007-11-17 22:12:34 +04:00
+++ b/mysql-test/t/type_newdecimal.test	2008-05-12 09:58:54 +05:00
@@ -1238,3 +1238,10 @@ select cast(-3.4 as decimal(2,1));
 select cast(99.6 as decimal(2,0));
 select cast(-13.4 as decimal(2,1));
 select cast(98.6 as decimal(2,0));
+
+#
+# Bug #36025 funcs_1.<engine>_storedproc Test failing on Windows
+#    here we check that float->decimal conversion doesn't lose
+#    precision 
+
+select cast(0.123456789098765432101234567890987654321e+29 as decimal(60,30));
diff -Nrup a/sql/item.cc b/sql/item.cc
--- a/sql/item.cc	2008-04-23 18:10:18 +05:00
+++ b/sql/item.cc	2008-05-12 09:58:54 +05:00
@@ -2335,7 +2335,13 @@ my_decimal *Item_float::val_decimal(my_d
 {
   // following assert is redundant, because fixed=1 assigned in constructor
   DBUG_ASSERT(fixed == 1);
-  double2my_decimal(E_DEC_FATAL_ERROR, value, decimal_value);
+  if (value_str)
+  {
+    char *str_end= value_str + value_str_length;
+    str2my_decimal(E_DEC_FATAL_ERROR, value_str, decimal_value, &str_end);
+  }
+  else
+    double2my_decimal(E_DEC_FATAL_ERROR, value, decimal_value);
   return (decimal_value);
 }
 
@@ -4928,6 +4934,8 @@ Item_float::Item_float(const char *str_a
 {
   int error;
   char *end_not_used;
+  value_str= sql_strmake(str_arg, length);
+  value_str_length= length;
   value= my_strntod(&my_charset_bin, (char*) str_arg, length, &end_not_used,
                     &error);
   if (error)
@@ -4938,6 +4946,7 @@ Item_float::Item_float(const char *str_a
     */
     DBUG_ASSERT(str_arg[length] == 0);
     my_error(ER_ILLEGAL_VALUE_FOR_TYPE, MYF(0), "double", (char*) str_arg);
+    value_str= NULL;
   }
   presentation= name=(char*) str_arg;
   decimals=(uint8) nr_of_decimals(str_arg, str_arg+length);
diff -Nrup a/sql/item.h b/sql/item.h
--- a/sql/item.h	2008-03-12 12:21:09 +04:00
+++ b/sql/item.h	2008-05-12 09:58:54 +05:00
@@ -1786,17 +1786,19 @@ class Item_float :public Item_num
   char *presentation;
 public:
   double value;
+  char *value_str;
+  int value_str_length;
   // Item_real() :value(0) {}
   Item_float(const char *str_arg, uint length);
   Item_float(const char *str,double val_arg,uint decimal_par,uint length)
-    :value(val_arg)
+    :value(val_arg), value_str(NULL)
   {
     presentation= name=(char*) str;
     decimals=(uint8) decimal_par;
     max_length=length;
     fixed= 1;
   }
-  Item_float(double value_par, uint decimal_par) :presentation(0), value(value_par)
+  Item_float(double value_par, uint decimal_par) :presentation(0), value(value_par),
value_str(NULL)
   {
     decimals= (uint8) decimal_par;
     fixed= 1;
@@ -1822,7 +1824,12 @@ public:
   my_decimal *val_decimal(my_decimal *);
   bool basic_const_item() const { return 1; }
   Item *clone_item()
-  { return new Item_float(name, value, decimals, max_length); }
+  {
+    Item_float *clone= new Item_float(name, value, decimals, max_length);
+    clone->value_str= value_str;
+    clone->value_str_length= value_str_length;
+    return clone;
+  }
   Item_num *neg() { value= -value; return this; }
   virtual void print(String *str, enum_query_type query_type);
   bool eq(const Item *, bool binary_cmp) const;
Thread
bk commit into 5.1 tree (holyfoot:1.2582) BUG#36025holyfoot12 May