Commit f210d1dd authored by unknown's avatar unknown

Merge mysqldev@production.mysql.com:my/mysql-5.0-build

into neptunus.(none):/home/msvensson/mysql/mysql-5.0-build


sql/item_func.cc:
  Auto merged
parents 4422b071 4482604e
...@@ -120,6 +120,9 @@ ASIN(0.8+0.2) ...@@ -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
......
...@@ -54,6 +54,11 @@ SELECT ASIN(1.2-0.2); ...@@ -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);
# #
......
...@@ -1880,22 +1880,16 @@ void Item_func_round::fix_length_and_dec() ...@@ -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() ...@@ -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();
......
...@@ -1673,6 +1673,7 @@ String *Item_func_format::val_str(String *str) ...@@ -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());
......
...@@ -1251,6 +1251,7 @@ ha_rows filesort(THD *thd, TABLE *form,struct st_sort_field *sortorder, ...@@ -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);
......
...@@ -98,6 +98,12 @@ static Geometry::Class_info ...@@ -98,6 +98,12 @@ static Geometry::Class_info
geometrycollection_class("GEOMETRYCOLLECTION",Geometry::wkb_geometrycollection, geometrycollection_class("GEOMETRYCOLLECTION",Geometry::wkb_geometrycollection,
create_geometrycollection); create_geometrycollection);
static void get_point(double *x, double *y, const char *data)
{
float8get(*x, data);
float8get(*y, data + SIZEOF_STORED_DOUBLE);
}
/***************************** Geometry *******************************/ /***************************** Geometry *******************************/
Geometry::Class_info *Geometry::find_class(const char *name, uint32 len) Geometry::Class_info *Geometry::find_class(const char *name, uint32 len)
...@@ -268,14 +274,13 @@ const char *Geometry::append_points(String *txt, uint32 n_points, ...@@ -268,14 +274,13 @@ const char *Geometry::append_points(String *txt, uint32 n_points,
{ {
while (n_points--) while (n_points--)
{ {
double d; double x,y;
data+= offset; data+= offset;
float8get(d, data); get_point(&x, &y, data);
txt->qs_append(d);
txt->qs_append(' ');
float8get(d, data + SIZEOF_STORED_DOUBLE);
data+= SIZEOF_STORED_DOUBLE * 2; data+= SIZEOF_STORED_DOUBLE * 2;
txt->qs_append(d); txt->qs_append(x);
txt->qs_append(' ');
txt->qs_append(y);
txt->qs_append(','); txt->qs_append(',');
} }
return data; return data;
...@@ -428,8 +433,7 @@ bool Gis_line_string::get_data_as_wkt(String *txt, const char **end) const ...@@ -428,8 +433,7 @@ bool Gis_line_string::get_data_as_wkt(String *txt, const char **end) const
while (n_points--) while (n_points--)
{ {
double x, y; double x, y;
float8get(x, data); get_point(&x, &y, data);
float8get(y, data + SIZEOF_STORED_DOUBLE);
data+= SIZEOF_STORED_DOUBLE * 2; data+= SIZEOF_STORED_DOUBLE * 2;
txt->qs_append(x); txt->qs_append(x);
txt->qs_append(' '); txt->qs_append(' ');
...@@ -462,15 +466,13 @@ int Gis_line_string::length(double *len) const ...@@ -462,15 +466,13 @@ int Gis_line_string::length(double *len) const
if (n_points < 1 || no_data(data, SIZEOF_STORED_DOUBLE * 2 * n_points)) if (n_points < 1 || no_data(data, SIZEOF_STORED_DOUBLE * 2 * n_points))
return 1; return 1;
float8get(prev_x, data); get_point(&prev_x, &prev_y, data);
float8get(prev_y, data + SIZEOF_STORED_DOUBLE);
data+= SIZEOF_STORED_DOUBLE*2; data+= SIZEOF_STORED_DOUBLE*2;
while (--n_points) while (--n_points)
{ {
double x, y; double x, y;
float8get(x, data); get_point(&x, &y, data);
float8get(y, data + SIZEOF_STORED_DOUBLE);
data+= SIZEOF_STORED_DOUBLE * 2; data+= SIZEOF_STORED_DOUBLE * 2;
*len+= sqrt(pow(prev_x-x,2)+pow(prev_y-y,2)); *len+= sqrt(pow(prev_x-x,2)+pow(prev_y-y,2));
prev_x= x; prev_x= x;
...@@ -499,13 +501,11 @@ int Gis_line_string::is_closed(int *closed) const ...@@ -499,13 +501,11 @@ int Gis_line_string::is_closed(int *closed) const
return 1; return 1;
/* Get first point */ /* Get first point */
float8get(x1, data); get_point(&x1, &y1, data);
float8get(y1, data + SIZEOF_STORED_DOUBLE);
/* get last point */ /* get last point */
data+= SIZEOF_STORED_DOUBLE*2 + (n_points-2)*POINT_DATA_SIZE; data+= SIZEOF_STORED_DOUBLE*2 + (n_points-2)*POINT_DATA_SIZE;
float8get(x2, data); get_point(&x2, &y2, data);
float8get(y2, data + SIZEOF_STORED_DOUBLE);
*closed= (x1==x2) && (y1==y2); *closed= (x1==x2) && (y1==y2);
return 0; return 0;
...@@ -683,15 +683,13 @@ int Gis_polygon::area(double *ar, const char **end_of_data) const ...@@ -683,15 +683,13 @@ int Gis_polygon::area(double *ar, const char **end_of_data) const
n_points= uint4korr(data); n_points= uint4korr(data);
if (no_data(data, (SIZEOF_STORED_DOUBLE*2) * n_points)) if (no_data(data, (SIZEOF_STORED_DOUBLE*2) * n_points))
return 1; return 1;
float8get(prev_x, data+4); get_point(&prev_x, &prev_y, data+4);
float8get(prev_y, data+(4+SIZEOF_STORED_DOUBLE));
data+= (4+SIZEOF_STORED_DOUBLE*2); data+= (4+SIZEOF_STORED_DOUBLE*2);
while (--n_points) // One point is already read while (--n_points) // One point is already read
{ {
double x, y; double x, y;
float8get(x, data); get_point(&x, &y, data);
float8get(y, data + SIZEOF_STORED_DOUBLE);
data+= (SIZEOF_STORED_DOUBLE*2); data+= (SIZEOF_STORED_DOUBLE*2);
/* QQ: Is the following prev_x+x right ? */ /* QQ: Is the following prev_x+x right ? */
lr_area+= (prev_x + x)* (prev_y - y); lr_area+= (prev_x + x)* (prev_y - y);
...@@ -781,7 +779,8 @@ int Gis_polygon::interior_ring_n(uint32 num, String *result) const ...@@ -781,7 +779,8 @@ int Gis_polygon::interior_ring_n(uint32 num, String *result) const
int Gis_polygon::centroid_xy(double *x, double *y) const int Gis_polygon::centroid_xy(double *x, double *y) const
{ {
uint32 n_linear_rings; uint32 n_linear_rings;
double res_area, res_cx, res_cy; double res_area;
double res_cx, res_cy;
const char *data= m_data; const char *data= m_data;
bool first_loop= 1; bool first_loop= 1;
LINT_INIT(res_area); LINT_INIT(res_area);
...@@ -807,15 +806,13 @@ int Gis_polygon::centroid_xy(double *x, double *y) const ...@@ -807,15 +806,13 @@ int Gis_polygon::centroid_xy(double *x, double *y) const
data+= 4; data+= 4;
if (no_data(data, (SIZEOF_STORED_DOUBLE*2) * n_points)) if (no_data(data, (SIZEOF_STORED_DOUBLE*2) * n_points))
return 1; return 1;
float8get(prev_x, data); get_point(&prev_x, &prev_y, data);
float8get(prev_y, data+SIZEOF_STORED_DOUBLE);
data+= (SIZEOF_STORED_DOUBLE*2); data+= (SIZEOF_STORED_DOUBLE*2);
while (--n_points) // One point is already read while (--n_points) // One point is already read
{ {
double x, y; double x, y;
float8get(x, data); get_point(&x, &y, data);
float8get(y, data + SIZEOF_STORED_DOUBLE);
data+= (SIZEOF_STORED_DOUBLE*2); data+= (SIZEOF_STORED_DOUBLE*2);
/* QQ: Is the following prev_x+x right ? */ /* QQ: Is the following prev_x+x right ? */
cur_area+= (prev_x + x) * (prev_y - y); cur_area+= (prev_x + x) * (prev_y - y);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment