MySQL Lists are EOL. Please join:

List:Internals« Previous MessageNext Message »
From:holyfoot Date:October 15 2005 4:57pm
Subject:bk commit into 5.0 tree (hf:1.2045) BUG#13573
View as plain text  
Below is the list of changes that have just been committed into a local
5.0 repository of hf. When hf 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
  1.2045 05/10/15 21:57:32 hf@deer.(none) +5 -0
  Fix for bug #13573 (wrong data inserted for too big decimals)

  sql/my_decimal.h
    1.10 05/10/15 21:55:26 hf@deer.(none) +44 -16
    overflow handling added - so the result of operation gets maximum possible
    decimal value

  sql/my_decimal.cc
    1.11 05/10/15 21:55:26 hf@deer.(none) +1 -1
    overflow handling added

  sql/item_func.cc
    1.260 05/10/15 21:55:26 hf@deer.(none) +6 -6
    conditions fixed

  mysql-test/t/type_newdecimal.test
    1.30 05/10/15 21:55:26 hf@deer.(none) +15 -0
    test case added

  mysql-test/r/type_newdecimal.result
    1.32 05/10/15 21:55:26 hf@deer.(none) +25 -3
    result fixed

# This is a BitKeeper patch.  What follows are the unified diffs for the
# set of deltas contained in the patch.  The rest of the patch, the part
# that BitKeeper cares about, is below these diffs.
# User:	hf
# Host:	deer.(none)
# Root:	/home/hf/work/mysql-5.0.13573

--- 1.259/sql/item_func.cc	Fri Oct 14 12:04:23 2005
+++ 1.260/sql/item_func.cc	Sat Oct 15 21:55:26 2005
@@ -972,8 +972,8 @@
     return 0;
   val2= args[1]->val_decimal(&value2);
   if (!(null_value= (args[1]->null_value ||
-                     my_decimal_add(E_DEC_FATAL_ERROR, decimal_value, val1,
-                                    val2) > 1)))
+                     (my_decimal_add(E_DEC_FATAL_ERROR, decimal_value, val1,
+                                     val2) > 3))))
     return decimal_value;
   return 0;
 }
@@ -1045,8 +1045,8 @@
     return 0;
   val2= args[1]->val_decimal(&value2);
   if (!(null_value= (args[1]->null_value ||
-                     my_decimal_sub(E_DEC_FATAL_ERROR, decimal_value, val1,
-                                    val2) > 1)))
+                     (my_decimal_sub(E_DEC_FATAL_ERROR, decimal_value, val1,
+                                     val2) > 3))))
     return decimal_value;
   return 0;
 }
@@ -1083,8 +1083,8 @@
     return 0;
   val2= args[1]->val_decimal(&value2);
   if (!(null_value= (args[1]->null_value ||
-                     my_decimal_mul(E_DEC_FATAL_ERROR, decimal_value, val1,
-                                    val2) > 1)))
+                     (my_decimal_mul(E_DEC_FATAL_ERROR, decimal_value, val1,
+                                    val2) > 3))))
     return decimal_value;
   return 0;
 }

--- 1.31/mysql-test/r/type_newdecimal.result	Fri Sep 30 15:01:26 2005
+++ 1.32/mysql-test/r/type_newdecimal.result	Sat Oct 15 21:55:26 2005
@@ -846,15 +846,14 @@
 NULL
 select 9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999 as x;
 x
-999999999999999999999999999999999999999999999999999999999999999999999999999999999
+99999999999999999999999999999999999999999999999999999999999999999
 Warnings:
 Error	1292	Truncated incorrect DECIMAL value: ''
 select 9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999 + 1 as x;
 x
-NULL
+100000000000000000000000000000000000000000000000000000000000000000
 Warnings:
 Error	1292	Truncated incorrect DECIMAL value: ''
-Error	1292	Truncated incorrect DECIMAL value: ''
 select 0.190287977636363637 + 0.040372670 * 0 -  0;
 0.190287977636363637 + 0.040372670 * 0 -  0
 0.190287977636363637
@@ -1019,3 +1018,26 @@
 select cast(@non_existing_user_var/2 as DECIMAL);
 cast(@non_existing_user_var/2 as DECIMAL)
 NULL
+create table t1 (c1 decimal(64));
+insert into t1 values(
+89000000000000000000000000000000000000000000000000000000000000000000000000000000000000000);
+Warnings:
+Error	1292	Truncated incorrect DECIMAL value: ''
+Warning	1264	Out of range value adjusted for column 'c1' at row 1
+insert into t1 values(
+99999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999 *
+99999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999);
+Warnings:
+Error	1292	Truncated incorrect DECIMAL value: ''
+Error	1292	Truncated incorrect DECIMAL value: ''
+Error	1292	Truncated incorrect DECIMAL value: ''
+Warning	1264	Out of range value adjusted for column 'c1' at row 1
+insert into t1 values(1e100);
+Warnings:
+Warning	1264	Out of range value adjusted for column 'c1' at row 1
+select * from t1;
+c1
+9999999999999999999999999999999999999999999999999999999999999999
+9999999999999999999999999999999999999999999999999999999999999999
+9999999999999999999999999999999999999999999999999999999999999999
+drop table t1;

--- 1.29/mysql-test/t/type_newdecimal.test	Wed Sep 14 08:25:21 2005
+++ 1.30/mysql-test/t/type_newdecimal.test	Sat Oct 15 21:55:26 2005
@@ -1044,3 +1044,18 @@
 #
 
 select cast(@non_existing_user_var/2 as DECIMAL);
+
+
+#
+# Bug #13573 (Wrong data inserted for too big values)
+#
+
+create table t1 (c1 decimal(64));
+insert into t1 values(
+89000000000000000000000000000000000000000000000000000000000000000000000000000000000000000);
+insert into t1 values(
+99999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999 *
+99999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999);
+insert into t1 values(1e100);
+select * from t1;
+drop table t1;

--- 1.10/sql/my_decimal.cc	Fri May  6 19:04:22 2005
+++ 1.11/sql/my_decimal.cc	Sat Oct 15 21:55:26 2005
@@ -185,7 +185,7 @@
       }
     }
   }
-  check_result(mask, err);
+  check_result_and_overflow(mask, err, decimal_value);
   return err;
 }
 

--- 1.9/sql/my_decimal.h	Wed Jun  8 21:56:17 2005
+++ 1.10/sql/my_decimal.h	Sat Oct 15 21:55:26 2005
@@ -126,6 +126,19 @@
 }
 #endif /*MYSQL_CLIENT*/
 
+inline
+void max_my_decimal(my_decimal *to, int precision, int frac)
+{
+  DBUG_ASSERT((precision <= DECIMAL_MAX_PRECISION)&&
+              (frac <= DECIMAL_MAX_SCALE));
+  max_decimal(precision, frac, (decimal_t*) to);
+}
+
+inline void max_internal_decimal(my_decimal *to)
+{
+  max_my_decimal(to, DECIMAL_MAX_PRECISION, 0);
+}
+
 inline int check_result(uint mask, int result)
 {
   if (result & mask)
@@ -133,6 +146,18 @@
   return result;
 }
 
+inline int check_result_and_overflow(uint mask, int result, my_decimal *val)
+{
+  if (check_result(mask, result) & E_DEC_OVERFLOW)
+  {
+    bool sign= val->sign();
+    val->fix_buffer_pointer();
+    max_internal_decimal(val);
+    val->sign(sign);
+  }
+  return result;
+}
+
 inline uint my_decimal_length_to_precision(uint length, uint scale,
                                            bool unsigned_flag)
 {
@@ -256,7 +281,8 @@
 inline
 int str2my_decimal(uint mask, const char *str, my_decimal *d, char **end)
 {
-  return check_result(mask, string2decimal(str, (decimal_t*) d, end));
+  return check_result_and_overflow(mask, string2decimal(str,(decimal_t*)d,end),
+                                   d);
 }
 
 
@@ -274,7 +300,7 @@
 inline
 int double2my_decimal(uint mask, double val, my_decimal *d)
 {
-  return check_result(mask, double2decimal(val, (decimal_t*) d));
+  return check_result_and_overflow(mask, double2decimal(val, (decimal_t*)d), d);
 }
 
 
@@ -303,7 +329,9 @@
 int my_decimal_add(uint mask, my_decimal *res, const my_decimal *a,
 		   const my_decimal *b)
 {
-  return check_result(mask, decimal_add((decimal_t*) a, (decimal_t*) b, res));
+  return check_result_and_overflow(mask,
+                                   decimal_add((decimal_t*)a,(decimal_t*)b,res),
+                                   res);
 }
 
 
@@ -311,7 +339,9 @@
 int my_decimal_sub(uint mask, my_decimal *res, const my_decimal *a,
 		   const my_decimal *b)
 {
-  return check_result(mask, decimal_sub((decimal_t*) a, (decimal_t*) b, res));
+  return check_result_and_overflow(mask,
+                                   decimal_sub((decimal_t*)a,(decimal_t*)b,res),
+                                   res);
 }
 
 
@@ -319,7 +349,9 @@
 int my_decimal_mul(uint mask, my_decimal *res, const my_decimal *a,
 		   const my_decimal *b)
 {
-  return check_result(mask, decimal_mul((decimal_t*) a, (decimal_t*) b, res));
+  return check_result_and_overflow(mask,
+                                   decimal_mul((decimal_t*)a,(decimal_t*)b,res),
+                                   res);
 }
 
 
@@ -327,8 +359,10 @@
 int my_decimal_div(uint mask, my_decimal *res, const my_decimal *a,
 		   const my_decimal *b, int div_scale_inc)
 {
-  return check_result(mask, decimal_div((decimal_t*) a, (decimal_t*) b, res,
-					div_scale_inc));
+  return check_result_and_overflow(mask,
+                                   decimal_div((decimal_t*)a,(decimal_t*)b,res,
+                                               div_scale_inc),
+                                   res);
 }
 
 
@@ -336,7 +370,9 @@
 int my_decimal_mod(uint mask, my_decimal *res, const my_decimal *a,
 		   const my_decimal *b)
 {
-  return check_result(mask, decimal_mod((decimal_t*) a, (decimal_t*) b, res));
+  return check_result_and_overflow(mask,
+                                   decimal_mod((decimal_t*)a,(decimal_t*)b,res),
+                                   res);
 }
 
 
@@ -345,14 +381,6 @@
 int my_decimal_cmp(const my_decimal *a, const my_decimal *b)
 {
   return decimal_cmp((decimal_t*) a, (decimal_t*) b);
-}
-
-inline
-void max_my_decimal(my_decimal *to, int precision, int frac)
-{
-  DBUG_ASSERT((precision <= DECIMAL_MAX_PRECISION)&&
-              (frac <= DECIMAL_MAX_SCALE));
-  max_decimal(precision, frac, (decimal_t*) to);
 }
 
 #endif /*my_decimal_h*/
Thread
bk commit into 5.0 tree (hf:1.2045) BUG#13573holyfoot15 Oct