summaryrefslogtreecommitdiff
path: root/sql/item_cmpfunc.cc
diff options
context:
space:
mode:
authorunknown <cmiller@zippy.cornsilk.net>2007-02-13 10:54:04 -0500
committerunknown <cmiller@zippy.cornsilk.net>2007-02-13 10:54:04 -0500
commit82e677b9479e1152028c242ade16a0a374c6abc7 (patch)
treedd32c329ae576946f3a73dda88aa8e45b367f5c6 /sql/item_cmpfunc.cc
parent7c08621c5a434d7a5bb931889509176274b3a50e (diff)
parent8a34c4bb78ca1afe57819c8be276446f01087f11 (diff)
downloadmariadb-git-82e677b9479e1152028c242ade16a0a374c6abc7.tar.gz
Merge bk-internal.mysql.com:/home/bk/mysql-4.1
into zippy.cornsilk.net:/home/cmiller/work/mysql/mysql-4.1-maint sql/item.cc: Auto merged sql/item_cmpfunc.cc: Auto merged sql/item_cmpfunc.h: Auto merged sql/sql_select.cc: Auto merged
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 91546c2282c..ffb60754381 100644
--- a/sql/item_cmpfunc.cc
+++ b/sql/item_cmpfunc.cc
@@ -352,6 +352,17 @@ int Arg_comparator::set_compare_func(Item_bool_func2 *item, Item_result type)
func= &Arg_comparator::compare_e_int_diff_signedness;
}
}
+ 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;
}
@@ -459,6 +470,44 @@ int Arg_comparator::compare_e_real()
return test(val1 == val2);
}
+
+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();