Bug #63468 | different behavior for int/bigint of comparing | ||
---|---|---|---|
Submitted: | 29 Nov 2011 8:12 | Modified: | 29 Nov 2011 11:08 |
Reporter: | liu hickey (OCA) | Email Updates: | |
Status: | Verified | Impact on me: | |
Category: | MySQL Server: Data Types | Severity: | S3 (Non-critical) |
Version: | 5.1/5.5 | OS: | Any |
Assigned to: | CPU Architecture: | Any | |
Tags: | int/bigint; compare; different hehavior |
[29 Nov 2011 8:12]
liu hickey
[29 Nov 2011 11:08]
MySQL Verification Team
Thank you for the bug report. h:\dbs>h:\dbs\5.5\bin\mysql -uroot --port=3540 --prompt="mysql 5.5 >" Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 8 Server version: 5.5.18-log Source distribution Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved. Oracle is a registered trademark of Oracle Corporation and/or its affiliates. Other names may be trademarks of their respective owners. Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. mysql 5.5 >use test Database changed mysql 5.5 >create table tmp_zx1 (a bigint); Query OK, 0 rows affected (0.27 sec) mysql 5.5 >create table tmp_zx2 (a int); Query OK, 0 rows affected (0.28 sec) mysql 5.5 >insert into tmp_zx1 values (2); Query OK, 1 row affected (0.09 sec) mysql 5.5 >insert into tmp_zx2 values (2); Query OK, 1 row affected (0.04 sec) mysql 5.5 >select * from tmp_zx1; +------+ | a | +------+ | 2 | +------+ 1 row in set (0.00 sec) mysql 5.5 >select * from tmp_zx2; +------+ | a | +------+ | 2 | +------+ 1 row in set (0.00 sec) mysql 5.5 >select * from tmp_zx1 where a>=2.1; +------+ | a | +------+ | 2 | +------+ 1 row in set (0.01 sec) mysql 5.5 >select * from tmp_zx2 where a>=2.1; Empty set (0.00 sec) mysql 5.5 >
[29 Nov 2011 12:38]
zhai weixiang
a suggest fix for this
Attachment: bigint.diff (application/octet-stream, text), 1.23 KiB.
[30 Nov 2011 13:30]
Lixun Peng
This is my patch base on hickey liu's patch
Attachment: bug897970_fix_bigint_cmp.patch (text/x-patch), 2.18 KiB.
[30 Nov 2011 13:31]
Lixun Peng
root@localhost : test 09:11:12> select * from t_bigint where id>=1.1; +----+ | id | +----+ | 2 | +----+ 1 row in set (0.00 sec) root@localhost : test 09:11:23> select * from t_bigint where id>=1; +----+ | id | +----+ | 1 | | 2 | +----+ 2 rows in set (0.00 sec) root@localhost : test 09:11:26> SELECT id, id >= 1 FROM t_bigint; +----+---------+ | id | id >= 1 | +----+---------+ | 1 | 1 | | 2 | 1 | +----+---------+ 2 rows in set (0.00 sec) root@localhost : test 09:11:29> SELECT id, id >= 1.1 FROM t_bigint; +----+-----------+ | id | id >= 1.1 | +----+-----------+ | 1 | 0 | | 2 | 1 | +----+-----------+ 2 rows in set (0.00 sec) http://bugs.mysql.com/bug.php?id=63502 This bug the same.
[1 Dec 2011 12:01]
Lixun Peng
--- Percona-Server-5.1.59/sql/field.h 2011-08-11 21:52:53.000000000 +0800 +++ Percona-Server-5.1.59-debug/sql/field.h 2011-12-01 19:26:13.000000000 +0800 @@ -1065,7 +1065,7 @@ void sort_string(uchar *buff,uint length); uint32 pack_length() const { return 8; } void sql_type(String &str) const; - bool can_be_compared_as_longlong() const { return TRUE; } + //bool can_be_compared_as_longlong() const { return TRUE; } uint32 max_display_length() { return 20; } virtual uchar *pack(uchar* to, const uchar *from, uint max_length __attribute__((unused)), Maybe commentted the "can_be_compared_as_longlong() " of Field_longlong can fix this bug?
[1 Dec 2011 12:33]
zhai weixiang
Hi, Lixun Peng i've test your patch ,and find a failed test case while running mysql-test-run as follows: ============================================================================== TEST RESULT TIME (ms) ------------------------------------------------------------ worker[1] Using MTR_BUILD_THREAD 300, with reserved ports 13000..13009 main.type_year [ fail ] Test ended at 2011-12-01 13:33:01 CURRENT_TEST: main.type_year --- /u01/mysql-b2b/mysql-test/r/type_year.result 2011-12-01 05:35:17.000000000 +0300 +++ /u01/mysql-b2b/mysql-test/r/type_year.reject 2011-12-01 08:33:01.000000000 +0300 @@ -199,11 +199,11 @@ yy c2 00 2000 Warnings: -Warning 1292 Truncated incorrect DOUBLE value: 'test' +Warning 1292 Truncated incorrect DECIMAL value: 'test' SELECT * FROM t4 WHERE yyyy = 'test'; yyyy c4 Warnings: -Warning 1292 Truncated incorrect DOUBLE value: 'test' +Warning 1292 Truncated incorrect DECIMAL value: 'test' SELECT * FROM t2 WHERE yy = '1999'; yy c2 99 1999
[2 Dec 2011 10:10]
Lixun Peng
I think this failure of warning is doesn't matter. But the patch can't fix "SELECT id, id >= 1.1e0 FROM t_bigint" and "SELECT id, id >= "1.1" FROM t_bigint" case. I fix again. --- Percona-Server-5.1.59/sql/item_cmpfunc.cc 2011-08-11 21:52:53.000000000 +0800 +++ Percona-Server-5.1.59-debug/sql/item_cmpfunc.cc 2011-12-02 17:04:35.000000000 +0800 @@ -506,13 +506,24 @@ !(field_item->is_datetime() && args[1]->result_type() == STRING_RESULT)) { - if (convert_constant_item(thd, field_item, &args[1])) + if (!(field_item->field->type() == MYSQL_TYPE_LONGLONG && + (args[1]->real_item()->type() == DECIMAL_ITEM || + (args[1]->real_item()->type() == REAL_ITEM && + args[1]->cmp_context == REAL_RESULT ) || + (args[1]->real_item()->type() == STRING_ITEM && + args[1]->cmp_context == REAL_RESULT ))) && + convert_constant_item(thd, field_item, &args[1]) ) { cmp.set_cmp_func(this, tmp_arg, tmp_arg+1, INT_RESULT); // Works for all types. args[0]->cmp_context= args[1]->cmp_context= INT_RESULT; return; - } + } else { + cmp.set_cmp_func(this, tmp_arg, tmp_arg+1, + DECIMAL_RESULT); // Works for all types. + args[0]->cmp_context= args[1]->cmp_context= DECIMAL_RESULT; + return; + } } } if (args[1]->real_item()->type() == FIELD_ITEM) @@ -522,13 +533,24 @@ !(field_item->is_datetime() && args[0]->result_type() == STRING_RESULT)) { - if (convert_constant_item(thd, field_item, &args[0])) + if (!(field_item->field->type() == MYSQL_TYPE_LONGLONG && + (args[0]->real_item()->type() == DECIMAL_ITEM || + (args[0]->real_item()->type() == REAL_ITEM && + args[0]->cmp_context == REAL_RESULT ) || + (args[0]->real_item()->type() == STRING_ITEM && + args[0]->cmp_context == REAL_RESULT))) && + convert_constant_item(thd, field_item, &args[0]) ) { cmp.set_cmp_func(this, tmp_arg, tmp_arg+1, - INT_RESULT); // Works for all types. + INT_RESULT); // Works for all types. args[0]->cmp_context= args[1]->cmp_context= INT_RESULT; return; - } + } else { + cmp.set_cmp_func(this, tmp_arg, tmp_arg+1, + DECIMAL_RESULT); // Works for all types. + args[0]->cmp_context= args[1]->cmp_context= DECIMAL_RESULT; + return; + } } } }
[2 Dec 2011 10:12]
Lixun Peng
this is the newest patch
Attachment: bug897970_fix_bigint_cmp_ver2.patch (text/x-patch), 2.44 KiB.