summaryrefslogtreecommitdiff
path: root/sql/item_cmpfunc.cc
diff options
context:
space:
mode:
authorunknown <ramil/ram@ramil.myoffice.izhnet.ru>2007-01-31 12:53:36 +0400
committerunknown <ramil/ram@ramil.myoffice.izhnet.ru>2007-01-31 12:53:36 +0400
commitdd1e0e7d6cf1c7c4c3cddf1f7436920f740a0e12 (patch)
tree2f6f9bd334f5e85e7faaa91f3debf91a9e3f7e89 /sql/item_cmpfunc.cc
parent4c7aeb3676ba1a284f0e18ea1ef00b19a72f3c84 (diff)
parentabf7eb0627d1a652beaa2380dbb94c6ad0ae0a2a (diff)
downloadmariadb-git-dd1e0e7d6cf1c7c4c3cddf1f7436920f740a0e12.tar.gz
Merge mysql.com:/home/ram/work/b19690/b19690.5.0
into mysql.com:/home/ram/work/b19690/b19690.5.1 mysql-test/r/type_float.result: Auto merged mysql-test/t/type_float.test: Auto merged sql/field.cc: Auto merged sql/init.cc: Auto merged sql/item_cmpfunc.cc: Auto merged sql/item_cmpfunc.h: Auto merged sql/mysql_priv.h: Auto merged sql/mysqld.cc: Auto merged sql/field.h: merging sql/item_sum.cc: 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 5bf15231c44..7ba7d4b6138 100644
--- a/sql/item_cmpfunc.cc
+++ b/sql/item_cmpfunc.cc
@@ -470,8 +470,19 @@ int Arg_comparator::set_compare_func(Item_bool_func2 *item, Item_result type)
break;
}
case DECIMAL_RESULT:
+ break;
case 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;
+ }
break;
+ }
default:
DBUG_ASSERT(0);
}
@@ -610,6 +621,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_real();
+ if (!(*a)->null_value)
+ {
+ val2= (*b)->val_real();
+ 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_real();
+ double val2= (*b)->val_real();
+ 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();