List:Commits« Previous MessageNext Message »
From:Gunnar von Boehn Date:February 7 2006 12:26pm
Subject:bk commit into 5.0 tree (gunnar:1.2032) BUG#8461
View as plain text  
Below is the list of changes that have just been committed into a local
5.0 repository of gvb. When gvb 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.2032 06/02/07 13:26:35 gunnar@stripped. +3 -0
  item_func.cc:
    fix for bug#8461
  
    BUG 8461 - TRUNCATE returns incorrect result if 2nd argument is negative
    Reason: Both TRUNCATE/ROUND converts INTEGERS to DOUBLE and back to INTEGERS
    Changed the integer routine to work on integers only.
    This bug affects 4.1, 5.0 and 5.1
    Fixing in 4.1 will need to change the routine to handle different types individually.
    5.0 did had different routines for different types already just the INTEGER routine was bad.

  mysql-test/r/func_math.result
    1.33 06/02/07 13:24:39 gunnar@stripped. +15 -0

  mysql-test/t/func_math.test
    1.26 06/02/07 13:24:35 gunnar@stripped. +14 -0

  sql/item_func.cc
    1.273 06/02/07 13:21:41 gunnar@stripped. +18 -16
    fix for bug#8461
    BUG 8461 - TRUNCATE returns incorrect result if 2nd argument is negative
    Reason: TRUNCATE converts INTEGERS to DOUBLE and back to INTEGERS
    Both ROUND and TRUNCATE are affected by this.
    Changed the integer routine to work on integers only.
    This bug affects 4.1 5,0 and 5
    Fixing in 4.1 will need to change the routine to handle different types individually.

# 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:	gunnar
# Host:	titan.
# Root:	/data/BK/mysql-5.0_8461_b

--- 1.272/sql/item_func.cc	2006-01-21 15:50:01 +01:00
+++ 1.273/sql/item_func.cc	2006-02-07 13:21:41 +01:00
@@ -1863,28 +1863,30 @@
     return value; // integer have not digits after point
 
   abs_dec= -dec;
-  double tmp;
-  /*
-    tmp2 is here to avoid return the value with 80 bit precision
-    This will fix that the test round(0.1,1) = round(0.1,1) is true
-  */
-  volatile double tmp2;
-
-  tmp= (abs_dec < array_elements(log_10) ?
-        log_10[abs_dec] : pow(10.0, (double) abs_dec));
-
+  longlong tmp;
+  
+  if(abs_dec >= array_elements(log_10_int))
+    return 0;
+  
+  tmp= log_10_int[abs_dec];
+  
   if (truncate)
   {
     if (unsigned_flag)
-      tmp2= floor(ulonglong2double(value)/tmp)*tmp;
-    else if (value >= 0)
-      tmp2= floor(((double)value)/tmp)*tmp;
+      value= (ulonglong(value)/tmp)*tmp;
     else
-      tmp2= ceil(((double)value)/tmp)*tmp;
+      value= (value/tmp)*tmp;
   }
   else
-    tmp2= rint(((double)value)/tmp)*tmp;
-  return (longlong)tmp2;
+  {
+    if (unsigned_flag)
+      value= ((ulonglong(value)+(tmp>>1))/tmp)*tmp;
+    else if ( value >= 0)
+      value= ((value+(tmp>>1))/tmp)*tmp;
+    else
+      value= ((value-(tmp>>1))/tmp)*tmp;
+  }
+  return value;
 }
 
 

--- 1.32/mysql-test/r/func_math.result	2005-10-28 03:45:56 +02:00
+++ 1.33/mysql-test/r/func_math.result	2006-02-07 13:24:39 +01:00
@@ -203,3 +203,18 @@
 Warnings:
 Error	1365	Division by 0
 set sql_mode='';
+select round(111,-10);
+round(111,-10)
+0
+select round(-5000111000111000155,-1);
+round(-5000111000111000155,-1)
+-5000111000111000160
+select round(15000111000111000155,-1);
+round(15000111000111000155,-1)
+15000111000111000160
+select truncate(-5000111000111000155,-1);
+truncate(-5000111000111000155,-1)
+-5000111000111000150
+select truncate(15000111000111000155,-1);
+truncate(15000111000111000155,-1)
+15000111000111000150

--- 1.25/mysql-test/t/func_math.test	2006-01-21 15:39:32 +01:00
+++ 1.26/mysql-test/t/func_math.test	2006-02-07 13:24:35 +01:00
@@ -141,3 +141,17 @@
 select log(-2,1);
 set sql_mode='';
 
+#
+# Bug #8461 truncate() and round() return false results 2nd argument negative.
+# 
+# round(a,-b) log_10(b) > a
+select round(111,-10);
+# round on bigint 
+select round(-5000111000111000155,-1);
+# round on unsigned bigint
+select round(15000111000111000155,-1);
+# truncate on bigint 
+select truncate(-5000111000111000155,-1);
+# truncate on unsigned bigint
+select truncate(15000111000111000155,-1);
+
Thread
bk commit into 5.0 tree (gunnar:1.2032) BUG#8461Gunnar von Boehn7 Feb