From a4b0063d7b1078a538e16a82132d4b696fa1a3de Mon Sep 17 00:00:00 2001 From: Alexander Barkov Date: Fri, 26 Jun 2015 10:58:51 +0400 Subject: [PATCH] MDEV-8256 A part of a ROW comparison is erroneously optimized away Item_func_eq's created during conversion of a ROW equality to a conjunction of scalar equalities did not set cmp_context for its arguments properly, so some of these created Item_func_eq could be later erroneously eliminated. --- mysql-test/r/ctype_utf8.result | 31 +++++++++++++++++++++++++++++++ mysql-test/t/ctype_utf8.test | 14 ++++++++++++++ sql/item_cmpfunc.h | 8 ++++++++ sql/sql_select.cc | 4 ++-- 4 files changed, 55 insertions(+), 2 deletions(-) diff --git a/mysql-test/r/ctype_utf8.result b/mysql-test/r/ctype_utf8.result index 56027e68f3f..5a990fda971 100644 --- a/mysql-test/r/ctype_utf8.result +++ b/mysql-test/r/ctype_utf8.result @@ -9970,5 +9970,36 @@ SET NAMES utf8; SELECT * FROM `test😁😁test`; ERROR HY000: Invalid utf8 character string: 'test\xF0\x9F\x98\x81\xF0\x9F\x98\x81test' # +#MDEV-8256 A part of a ROW comparison is erroneously optimized away +# +SET NAMES utf8; +CREATE TABLE t1 (a VARCHAR(10) CHARACTER SET utf8); +INSERT INTO t1 VALUES ('1e1'),('1é1'); +SELECT * FROM t1 WHERE a=10; +a +1e1 +Warnings: +Warning 1292 Truncated incorrect DOUBLE value: '1é1' +SELECT * FROM t1 WHERE a='1e1'; +a +1e1 +1é1 +SELECT * FROM t1 WHERE a=10 AND a='1e1'; +a +1e1 +Warnings: +Warning 1292 Truncated incorrect DOUBLE value: '1é1' +SELECT * FROM t1 WHERE (a,a)=(10,'1e1'); +a +1e1 +Warnings: +Warning 1292 Truncated incorrect DOUBLE value: '1é1' +EXPLAIN EXTENDED SELECT * FROM t1 WHERE (a,a)=(10,'1e1'); +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00 Using where +Warnings: +Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where ((`test`.`t1`.`a` = 10) and (`test`.`t1`.`a` = '1e1')) +DROP TABLE t1; +# # End of 10.1 tests # diff --git a/mysql-test/t/ctype_utf8.test b/mysql-test/t/ctype_utf8.test index dba00e96491..8b557626ae7 100644 --- a/mysql-test/t/ctype_utf8.test +++ b/mysql-test/t/ctype_utf8.test @@ -1789,6 +1789,20 @@ SET NAMES utf8; --error ER_INVALID_CHARACTER_STRING SELECT * FROM `test😁😁test`; +--echo # +--echo #MDEV-8256 A part of a ROW comparison is erroneously optimized away +--echo # +SET NAMES utf8; +CREATE TABLE t1 (a VARCHAR(10) CHARACTER SET utf8); +INSERT INTO t1 VALUES ('1e1'),('1é1'); +SELECT * FROM t1 WHERE a=10; +SELECT * FROM t1 WHERE a='1e1'; +SELECT * FROM t1 WHERE a=10 AND a='1e1'; +SELECT * FROM t1 WHERE (a,a)=(10,'1e1'); +EXPLAIN EXTENDED SELECT * FROM t1 WHERE (a,a)=(10,'1e1'); +DROP TABLE t1; + + --echo # --echo # End of 10.1 tests --echo # diff --git a/sql/item_cmpfunc.h b/sql/item_cmpfunc.h index c9b6b30f5b1..6e5385829a2 100644 --- a/sql/item_cmpfunc.h +++ b/sql/item_cmpfunc.h @@ -325,6 +325,14 @@ public: { return cmp.set_cmp_func(this, tmp_arg, tmp_arg + 1, true); } + bool set_cmp_func_and_arg_cmp_context() + { + if (set_cmp_func()) + return true; + tmp_arg[0]->cmp_context= tmp_arg[1]->cmp_context= + item_cmp_type(tmp_arg[0]->result_type(), tmp_arg[1]->result_type()); + return false; + } CHARSET_INFO *compare_collation() const { return cmp.cmp_collation.collation; } Arg_comparator *get_comparator() { return &cmp; } diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 120031ff75f..02335ddf0f7 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -12566,7 +12566,7 @@ static bool check_simple_equality(THD *thd, Item *left_item, Item *right_item, Item_func_eq *eq_item; if (!(eq_item= new (thd->mem_root) Item_func_eq(orig_left_item, orig_right_item)) || - eq_item->set_cmp_func()) + eq_item->set_cmp_func_and_arg_cmp_context()) return FALSE; eq_item->quick_fix_field(); item= eq_item; @@ -12660,7 +12660,7 @@ static bool check_row_equality(THD *thd, Item *left_row, Item_row *right_row, { Item_func_eq *eq_item; if (!(eq_item= new Item_func_eq(left_item, right_item)) || - eq_item->set_cmp_func()) + eq_item->set_cmp_func_and_arg_cmp_context()) return FALSE; eq_item->quick_fix_field(); eq_list->push_back(eq_item);