summaryrefslogtreecommitdiff
path: root/sql/item_cmpfunc.cc
diff options
context:
space:
mode:
authorunknown <ramil/ram@mysql.com/ramil.myoffice.izhnet.ru>2007-01-31 10:07:56 +0400
committerunknown <ramil/ram@mysql.com/ramil.myoffice.izhnet.ru>2007-01-31 10:07:56 +0400
commit86ed0e9806de37febafbd4664abf48ac6db3034d (patch)
tree6c9ed97252bdf7ef1a2212592492c3c907f573aa /sql/item_cmpfunc.cc
parent7d4477f866d26b8bd8e941e6484d843cc30c83c8 (diff)
parentfaad73550c157388ffb7b1606e3f896ed7b276ac (diff)
downloadmariadb-git-86ed0e9806de37febafbd4664abf48ac6db3034d.tar.gz
Merge mysql.com:/home/ram/work/b19690/b19690.4.1
into mysql.com:/home/ram/work/b19690/b19690.5.0 mysql-test/r/type_float.result: Auto merged mysql-test/t/type_float.test: Auto merged sql/field.cc: Auto merged sql/item_cmpfunc.h: Auto merged sql/mysqld.cc: Auto merged sql/field.h: merging sql/init.cc: merging sql/item_cmpfunc.cc: merging sql/mysql_priv.h: merging sql/sql_select.cc: merging
Diffstat (limited to 'sql/item_cmpfunc.cc')
-rw-r--r--sql/item_cmpfunc.cc49
1 files changed, 49 insertions, 0 deletions
diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc
index 936ae04e93d..0daba495f62 100644
--- a/sql/item_cmpfunc.cc
+++ b/sql/item_cmpfunc.cc
@@ -422,6 +422,17 @@ int Arg_comparator::set_compare_func(Item_bool_func2 *item, Item_result type)
default:
DBUG_ASSERT(0);
}
+ else if (type == REAL_RESULT)
+ {
+ if ((*a)->decimals < NOT_FIXED_DEC && (*b)->decimals < NOT_FIXED_DEC)
+ {
+ precision= 5 * log_01[max((*a)->decimals, (*b)->decimals)];
+ if (func == &Arg_comparator::compare_real)
+ func= &Arg_comparator::compare_real_fixed;
+ else if (func == &Arg_comparator::compare_e_real)
+ func= &Arg_comparator::compare_e_real_fixed;
+ }
+ }
return 0;
}
@@ -557,6 +568,44 @@ int Arg_comparator::compare_e_decimal()
return test(my_decimal_cmp(val1, val2) == 0);
}
+
+int Arg_comparator::compare_real_fixed()
+{
+ /*
+ Fix yet another manifestation of Bug#2338. 'Volatile' will instruct
+ gcc to flush double values out of 80-bit Intel FPU registers before
+ performing the comparison.
+ */
+ volatile double val1, val2;
+ val1= (*a)->val();
+ if (!(*a)->null_value)
+ {
+ val2= (*b)->val();
+ if (!(*b)->null_value)
+ {
+ owner->null_value= 0;
+ if (val1 == val2 || fabs(val1 - val2) < precision)
+ return 0;
+ if (val1 < val2)
+ return -1;
+ return 1;
+ }
+ }
+ owner->null_value= 1;
+ return -1;
+}
+
+
+int Arg_comparator::compare_e_real_fixed()
+{
+ double val1= (*a)->val();
+ double val2= (*b)->val();
+ if ((*a)->null_value || (*b)->null_value)
+ return test((*a)->null_value && (*b)->null_value);
+ return test(val1 == val2 || fabs(val1 - val2) < precision);
+}
+
+
int Arg_comparator::compare_int_signed()
{
longlong val1= (*a)->val_int();