diff options
author | unknown <cmiller@zippy.cornsilk.net> | 2007-02-13 10:54:04 -0500 |
---|---|---|
committer | unknown <cmiller@zippy.cornsilk.net> | 2007-02-13 10:54:04 -0500 |
commit | 82e677b9479e1152028c242ade16a0a374c6abc7 (patch) | |
tree | dd32c329ae576946f3a73dda88aa8e45b367f5c6 /sql/item_cmpfunc.cc | |
parent | 7c08621c5a434d7a5bb931889509176274b3a50e (diff) | |
parent | 8a34c4bb78ca1afe57819c8be276446f01087f11 (diff) | |
download | mariadb-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.cc | 49 |
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(); |