revision-id: 2432c973aea5b4e2d2d831b71c8b26f40d90205b (mariadb-10.3.6-161-g2432c97) parent(s): a53b99bf1333722b8f30fdbba7d7a40ce2485976 author: Igor Babaev committer: Igor Babaev timestamp: 2018-10-17 01:27:25 -0700 message: MDEV-17027 server crashes in Bitmap<64u>::merge The function and_new_conditions_to_optimized_cond() incorrectly handled the WHERE conditions with one multiple equality and one IN subquery predicate that could be converted into a jtbm semi-join. This could cause crashes. The fix code was prepared by Galina Shalygina. --- mysql-test/main/in_subq_cond_pushdown.result | 19 ++++++++++++ mysql-test/main/in_subq_cond_pushdown.test | 22 ++++++++++++++ sql/opt_subselect.cc | 44 ++++++++++++++-------------- 3 files changed, 63 insertions(+), 22 deletions(-) diff --git a/mysql-test/main/in_subq_cond_pushdown.result b/mysql-test/main/in_subq_cond_pushdown.result index 077edf7..0624889 100644 --- a/mysql-test/main/in_subq_cond_pushdown.result +++ b/mysql-test/main/in_subq_cond_pushdown.result @@ -3868,3 +3868,22 @@ WHERE dt1.id1 IN (SELECT t2.id2 FROM t2 HAVING t2.id2 >= 1)); r DROP TABLE t1,t2; +# +# MDEV-17027: IN subquery predicate with outer reference in the left part +# conjuncted with equality predicate +# +CREATE TABLE t1 (pk int, i1 int, v1 varchar(1)); +INSERT INTO t1 VALUES (3,2,'x'), (1,1,'y'), (4,2,'z'); +CREATE TABLE t2 (pk int, i1 int, v1 varchar(1)); +INSERT INTO t2 VALUES (5,2,'x'), (7,1,'x'); +CREATE TABLE t3 (pk int, i1 int, v1 varchar(1)); +INSERT INTO t3 VALUES (8,2,'x'), (7,1,'z'); +SELECT t3.i1 FROM t3 +WHERE EXISTS ( SELECT t2.v1 FROM t1,t2 +WHERE t1.v1 = t2.v1 AND +t3.i1 IN (SELECT t.i1 FROM t1 as t +GROUP BY i1 HAVING t.i1 < 3)); +i1 +2 +1 +DROP TABLE t1,t2,t3; diff --git a/mysql-test/main/in_subq_cond_pushdown.test b/mysql-test/main/in_subq_cond_pushdown.test index 4c0dd3d..2482fd9 100644 --- a/mysql-test/main/in_subq_cond_pushdown.test +++ b/mysql-test/main/in_subq_cond_pushdown.test @@ -838,3 +838,25 @@ SELECT 1 AS r FROM t2,t1,(SELECT * FROM t1) dt1 HAVING t2.id2 >= 1)); DROP TABLE t1,t2; + +--echo # +--echo # MDEV-17027: IN subquery predicate with outer reference in the left part +--echo # conjuncted with equality predicate +--echo # + +CREATE TABLE t1 (pk int, i1 int, v1 varchar(1)); +INSERT INTO t1 VALUES (3,2,'x'), (1,1,'y'), (4,2,'z'); + +CREATE TABLE t2 (pk int, i1 int, v1 varchar(1)); +INSERT INTO t2 VALUES (5,2,'x'), (7,1,'x'); + +CREATE TABLE t3 (pk int, i1 int, v1 varchar(1)); +INSERT INTO t3 VALUES (8,2,'x'), (7,1,'z'); + +SELECT t3.i1 FROM t3 + WHERE EXISTS ( SELECT t2.v1 FROM t1,t2 + WHERE t1.v1 = t2.v1 AND + t3.i1 IN (SELECT t.i1 FROM t1 as t + GROUP BY i1 HAVING t.i1 < 3)); + +DROP TABLE t1,t2,t3; diff --git a/sql/opt_subselect.cc b/sql/opt_subselect.cc index 4eeaefa..c4c30c9 100644 --- a/sql/opt_subselect.cc +++ b/sql/opt_subselect.cc @@ -5667,31 +5667,31 @@ Item *and_new_conditions_to_optimized_cond(THD *thd, Item *cond, } } + if (is_mult_eq) + { + Item_equal *eq_cond= (Item_equal *)cond; + eq_cond->upper_levels= 0; + eq_cond->merge_into_list(thd, &new_cond_equal.current_level, + false, false); + + while ((equality= it++)) + { + if (equality->const_item() && !equality->val_int()) + is_simplified_cond= true; + } + (*cond_eq)->copy(new_cond_equal); + } + if (new_cond_equal.current_level.elements > 0) { - if (is_mult_eq) + if (new_cond_equal.current_level.elements + + new_conds_list.elements == 1) { - Item_equal *eq_cond= (Item_equal *)cond; - eq_cond->upper_levels= 0; - eq_cond->merge_into_list(thd, &new_cond_equal.current_level, - false, false); - - while ((equality= it++)) - { - if (equality->const_item() && !equality->val_int()) - is_simplified_cond= true; - } - - if (new_cond_equal.current_level.elements + - new_conds_list.elements == 1) - { - it.rewind(); - equality= it++; - equality->fixed= 0; - if (equality->fix_fields(thd, NULL)) - return NULL; - } - (*cond_eq)->copy(new_cond_equal); + it.rewind(); + equality= it++; + equality->fixed= 0; + if (equality->fix_fields(thd, NULL)) + return NULL; } new_conds_list.append((List<Item> *)&new_cond_equal.current_level); }