diff options
-rw-r--r-- | mysql-test/r/type_newdecimal.result | 39 | ||||
-rw-r--r-- | mysql-test/t/type_newdecimal.test | 27 | ||||
-rw-r--r-- | sql/item_cmpfunc.cc | 16 |
3 files changed, 82 insertions, 0 deletions
diff --git a/mysql-test/r/type_newdecimal.result b/mysql-test/r/type_newdecimal.result index 2f6a3ea2a61..56a04971fa1 100644 --- a/mysql-test/r/type_newdecimal.result +++ b/mysql-test/r/type_newdecimal.result @@ -2243,3 +2243,42 @@ DROP TABLE t1; # # End of 10.1 tests # +# +# Bug#18408499 UNSIGNED BIGINT HIGH VALUES +# WRONG NUMERICAL COMPARISON RESULTS +# +CREATE TABLE t1(value DECIMAL(24,0) NOT NULL); +INSERT INTO t1(value) +VALUES('100000000000000000000001'), +('100000000000000000000002'), +('100000000000000000000003'); +SELECT * FROM t1 WHERE value = '100000000000000000000002'; +value +100000000000000000000002 +SELECT * FROM t1 WHERE '100000000000000000000002' = value; +value +100000000000000000000002 +SELECT * FROM t1 WHERE value + 0 = '100000000000000000000002'; +value +100000000000000000000002 +SELECT * FROM t1 WHERE value = 100000000000000000000002; +value +100000000000000000000002 +SELECT * FROM t1 WHERE value + 0 = 100000000000000000000002; +value +100000000000000000000002 +PREPARE stmt FROM 'SELECT * FROM t1 WHERE value = ?'; +set @a="100000000000000000000002"; +EXECUTE stmt using @a; +value +100000000000000000000002 +set @a=100000000000000000000002; +EXECUTE stmt using @a; +value +100000000000000000000002 +DEALLOCATE PREPARE stmt; +ALTER TABLE t1 ADD INDEX value (value); +SELECT * FROM t1 WHERE value = '100000000000000000000002'; +value +100000000000000000000002 +DROP TABLE t1; diff --git a/mysql-test/t/type_newdecimal.test b/mysql-test/t/type_newdecimal.test index b84d01e93be..6fb8fd4f97d 100644 --- a/mysql-test/t/type_newdecimal.test +++ b/mysql-test/t/type_newdecimal.test @@ -1738,3 +1738,30 @@ DROP TABLE t1; --echo # --echo # End of 10.1 tests --echo # + +--echo # +--echo # Bug#18408499 UNSIGNED BIGINT HIGH VALUES +--echo # WRONG NUMERICAL COMPARISON RESULTS +--echo # + +CREATE TABLE t1(value DECIMAL(24,0) NOT NULL); +INSERT INTO t1(value) +VALUES('100000000000000000000001'), + ('100000000000000000000002'), + ('100000000000000000000003'); +SELECT * FROM t1 WHERE value = '100000000000000000000002'; +SELECT * FROM t1 WHERE '100000000000000000000002' = value; +SELECT * FROM t1 WHERE value + 0 = '100000000000000000000002'; +SELECT * FROM t1 WHERE value = 100000000000000000000002; +SELECT * FROM t1 WHERE value + 0 = 100000000000000000000002; + +PREPARE stmt FROM 'SELECT * FROM t1 WHERE value = ?'; +set @a="100000000000000000000002"; +EXECUTE stmt using @a; +set @a=100000000000000000000002; +EXECUTE stmt using @a; +DEALLOCATE PREPARE stmt; + +ALTER TABLE t1 ADD INDEX value (value); +SELECT * FROM t1 WHERE value = '100000000000000000000002'; +DROP TABLE t1; diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index 7a7b2ca2933..e78f73ee03c 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -655,6 +655,22 @@ int Arg_comparator::set_cmp_func(Item_func_or_sum *owner_arg, return 0; } + if (m_compare_type == REAL_RESULT && + (((*a)->result_type() == DECIMAL_RESULT && !(*a)->const_item() && + (*b)->result_type() == STRING_RESULT && (*b)->const_item()) || + ((*b)->result_type() == DECIMAL_RESULT && !(*b)->const_item() && + (*a)->result_type() == STRING_RESULT && (*a)->const_item()))) + { + /* + <non-const decimal expression> <cmp> <const string expression> + or + <const string expression> <cmp> <non-const decimal expression> + + Do comparison as decimal rather than float, in order not to lose precision. + */ + m_compare_type= DECIMAL_RESULT; + } + if (m_compare_type == INT_RESULT && (*a)->field_type() == MYSQL_TYPE_YEAR && (*b)->field_type() == MYSQL_TYPE_YEAR) |