revision-id: f6ad7b498d3b2334ebd59df49e0ca524d2f83203 (mariadb-5.5.60-48-gf6ad7b498d3) parent(s): d277c4682e4c6bb0e708296e6ae520c149dd78f4 author: Varun Gupta committer: Varun Gupta timestamp: 2018-07-24 03:34:00 +0530 message: MDEV-7865: Server crashes in Item_equal_iterator<List_iterator_fast, Item>::get_curr_field on query with impossible condition and OR/AND expressions If we have any of the 2 cases - item was an OR formula converted to one disjunct - item was an AND formula converted to one conjunct In these cases the disjunct/conjunct must be merged into the argument list of cond. So this item is mergesd with the equalities that existed on the upper level. The issue was the Item_fields inside the Item_equal objects that were merged , were still pointing to the old item_equal object and not to the new merged one. --- mysql-test/r/join.result | 22 ++++++++++++++++++++++ mysql-test/t/join.test | 22 ++++++++++++++++++++++ sql/item_cmpfunc.cc | 8 ++++++++ 3 files changed, 52 insertions(+) diff --git a/mysql-test/r/join.result b/mysql-test/r/join.result index 7b0e7807e39..c61141a60ea 100644 --- a/mysql-test/r/join.result +++ b/mysql-test/r/join.result @@ -1535,5 +1535,27 @@ ERROR 23000: Column 'c' in field list is ambiguous DROP PROCEDURE p1; DROP TABLE t1,t2,t3,t4,t5; # +# MDEV-7856:Server crashes in Item_equal_iterator<List_iterator_fast, Item>::get_curr_field on query +# with impossible condition and OR/AND expressions +# +CREATE TABLE t1 (i1 INT, a1 VARCHAR(8), b1 VARCHAR(8), KEY(b1)) ENGINE=MyISAM; +INSERT INTO t1 VALUES (1,'foo','foo'),(2,'bar','bar'); +CREATE TABLE t2 (i2 INT, b2 VARCHAR(8), KEY(b2)) ENGINE=MyISAM; +INSERT INTO t2 VALUES (1,'qux'),(2,'foo'); +CREATE TABLE t3 (b3 VARCHAR(8), b4 VARCHAR(8)) ENGINE=MyISAM; +INSERT INTO t3 VALUES ('foo', 'foo'); +explain +SELECT * FROM t1,t2,t3 +WHERE ( b3 = b2 or "impo"="expr" ) AND b2 = a1 and ( b2 > b1 OR i2 <> i1 ); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t3 system NULL NULL NULL NULL 1 +1 SIMPLE t2 ref b2 b2 11 const 1 +1 SIMPLE t1 ALL b1 NULL NULL NULL 2 Using where; Using join buffer (flat, BNL join) +SELECT * FROM t1,t2,t3 +WHERE ( b3 = b2 or "impo"="expr" ) AND b2 = a1 and ( b2 > b1 OR i2 <> i1 ); +i1 a1 b1 i2 b2 b3 b4 +1 foo foo 2 foo foo foo +drop table t1,t2,t3; +# # End of MariaDB 5.5 tests # diff --git a/mysql-test/t/join.test b/mysql-test/t/join.test index feafac57a7e..e1b6133917f 100644 --- a/mysql-test/t/join.test +++ b/mysql-test/t/join.test @@ -1208,6 +1208,28 @@ CALL p1; DROP PROCEDURE p1; DROP TABLE t1,t2,t3,t4,t5; +--echo # +--echo # MDEV-7856:Server crashes in Item_equal_iterator<List_iterator_fast, Item>::get_curr_field on query +--echo # with impossible condition and OR/AND expressions +--echo # + +CREATE TABLE t1 (i1 INT, a1 VARCHAR(8), b1 VARCHAR(8), KEY(b1)) ENGINE=MyISAM; +INSERT INTO t1 VALUES (1,'foo','foo'),(2,'bar','bar'); + +CREATE TABLE t2 (i2 INT, b2 VARCHAR(8), KEY(b2)) ENGINE=MyISAM; +INSERT INTO t2 VALUES (1,'qux'),(2,'foo'); + +CREATE TABLE t3 (b3 VARCHAR(8), b4 VARCHAR(8)) ENGINE=MyISAM; +INSERT INTO t3 VALUES ('foo', 'foo'); + +explain +SELECT * FROM t1,t2,t3 +WHERE ( b3 = b2 or "impo"="expr" ) AND b2 = a1 and ( b2 > b1 OR i2 <> i1 ); +SELECT * FROM t1,t2,t3 +WHERE ( b3 = b2 or "impo"="expr" ) AND b2 = a1 and ( b2 > b1 OR i2 <> i1 ); + +drop table t1,t2,t3; + --echo # --echo # End of MariaDB 5.5 tests --echo # diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index 6fb650b975b..b512ffed0e4 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -5898,7 +5898,15 @@ bool Item_equal::merge_with_check(Item_equal *item, bool save_merged) if (intersected) { if (!save_merged) + { + Item *item_it; + fi.rewind(); + while ((item_it= fi++)) + { + item_it->set_item_equal(this); + } merge(item); + } else { Item *c= item->get_const();