diff options
author | unknown <ramil/ram@ramil.myoffice.izhnet.ru> | 2007-01-31 12:53:36 +0400 |
---|---|---|
committer | unknown <ramil/ram@ramil.myoffice.izhnet.ru> | 2007-01-31 12:53:36 +0400 |
commit | dd1e0e7d6cf1c7c4c3cddf1f7436920f740a0e12 (patch) | |
tree | 2f6f9bd334f5e85e7faaa91f3debf91a9e3f7e89 /sql/item_cmpfunc.cc | |
parent | 4c7aeb3676ba1a284f0e18ea1ef00b19a72f3c84 (diff) | |
parent | abf7eb0627d1a652beaa2380dbb94c6ad0ae0a2a (diff) | |
download | mariadb-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.cc | 49 |
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(); |