1
0
mirror of https://github.com/MariaDB/server.git synced 2025-08-01 03:47:19 +03:00

hf's fix for bug #9060 (FORMAT returns incorrect result)

we need proper rounding there


mysql-test/r/func_math.result:
  test result fixed
mysql-test/t/func_math.test:
  test case added
sql/item_func.cc:
  my_double_round implementation added
sql/item_strfunc.cc:
  my_double_round used
sql/mysql_priv.h:
  my_double_round interface
This commit is contained in:
unknown
2005-05-20 01:04:08 +05:00
parent 9c1bc4252f
commit 4482604ec6
5 changed files with 24 additions and 8 deletions

View File

@ -120,6 +120,9 @@ ASIN(0.8+0.2)
SELECT ASIN(1.2-0.2); SELECT ASIN(1.2-0.2);
ASIN(1.2-0.2) ASIN(1.2-0.2)
1.5707963267949 1.5707963267949
select format(4.55, 1), format(4.551, 1);
format(4.55, 1) format(4.551, 1)
4.6 4.6
explain extended select degrees(pi()),radians(360); explain extended select degrees(pi()),radians(360);
id select_type table type possible_keys key key_len ref rows Extra id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL No tables used 1 SIMPLE NULL NULL NULL NULL NULL NULL NULL No tables used

View File

@ -54,6 +54,11 @@ SELECT ASIN(1.2-0.2);
#select floor(log(8)/log(2)); #select floor(log(8)/log(2));
#select floor(log(16)/log(2)); #select floor(log(16)/log(2));
#
# Bug #9060 (format returns incorrect result)
#
select format(4.55, 1), format(4.551, 1);
explain extended select degrees(pi()),radians(360); explain extended select degrees(pi()),radians(360);
# #

View File

@ -1880,22 +1880,16 @@ void Item_func_round::fix_length_and_dec()
} }
} }
double Item_func_round::real_op() double my_double_round(double value, int dec, bool truncate)
{ {
double value= args[0]->val_real();
int dec=(int) args[1]->val_int();
if (dec > 0)
decimals= dec; // to get correct output
uint abs_dec=abs(dec);
double tmp; double tmp;
uint abs_dec= abs(dec);
/* /*
tmp2 is here to avoid return the value with 80 bit precision 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 This will fix that the test round(0.1,1) = round(0.1,1) is true
*/ */
volatile double tmp2; volatile double tmp2;
if ((null_value=args[0]->null_value || args[1]->null_value))
return 0.0;
tmp=(abs_dec < array_elements(log_10) ? tmp=(abs_dec < array_elements(log_10) ?
log_10[abs_dec] : pow(10.0,(double) abs_dec)); log_10[abs_dec] : pow(10.0,(double) abs_dec));
@ -1912,6 +1906,18 @@ double Item_func_round::real_op()
} }
double Item_func_round::real_op()
{
double value= args[0]->val_real();
int dec= (int) args[1]->val_int();
if (!(null_value= args[0]->null_value || args[1]->null_value))
return my_double_round(value, dec, truncate);
return 0.0;
}
longlong Item_func_round::int_op() longlong Item_func_round::int_op()
{ {
longlong value= args[0]->val_int(); longlong value= args[0]->val_int();

View File

@ -1673,6 +1673,7 @@ String *Item_func_format::val_str(String *str)
int diff; int diff;
if ((null_value=args[0]->null_value)) if ((null_value=args[0]->null_value))
return 0; /* purecov: inspected */ return 0; /* purecov: inspected */
nr= my_double_round(nr, decimals, FALSE);
dec= decimals ? decimals+1 : 0; dec= decimals ? decimals+1 : 0;
/* Here default_charset() is right as this is not an automatic conversion */ /* Here default_charset() is right as this is not an automatic conversion */
str->set(nr,decimals, default_charset()); str->set(nr,decimals, default_charset());

View File

@ -1251,6 +1251,7 @@ ha_rows filesort(THD *thd, TABLE *form,struct st_sort_field *sortorder,
ha_rows max_rows, ha_rows *examined_rows); ha_rows max_rows, ha_rows *examined_rows);
void filesort_free_buffers(TABLE *table); void filesort_free_buffers(TABLE *table);
void change_double_for_sort(double nr,byte *to); void change_double_for_sort(double nr,byte *to);
double my_double_round(double value, int dec, bool truncate);
int get_quick_record(SQL_SELECT *select); int get_quick_record(SQL_SELECT *select);
int calc_weekday(long daynr,bool sunday_first_day_of_week); int calc_weekday(long daynr,bool sunday_first_day_of_week);
uint calc_week(TIME *l_time, uint week_behaviour, uint *year); uint calc_week(TIME *l_time, uint week_behaviour, uint *year);