Commit 09976a27 authored by unknown's avatar unknown
Browse files

Merge mysql.com.:/data/BK/mysql-5.0

into  mysql.com.:/data/BK/mysql-5.0_8461_b

parents 96268d4a c9bb7e1f
Loading
Loading
Loading
Loading
+15 −0
Original line number Diff line number Diff line
@@ -203,3 +203,18 @@ NULL
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
+14 −0
Original line number Diff line number Diff line
@@ -141,3 +141,17 @@ select log(2,-1);
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);
+18 −16
Original line number Diff line number Diff line
@@ -1863,28 +1863,30 @@ longlong Item_func_round::int_op()
    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;
  longlong tmp;
  
  tmp= (abs_dec < array_elements(log_10) ?
        log_10[abs_dec] : pow(10.0, (double) abs_dec));
  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;
}