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#36025 | holyfoot | 12 May |