From 3f7e71439f6fb781a6eff0a70dfbf65ba9ef3540 Mon Sep 17 00:00:00 2001 From: Varun Gupta Date: Mon, 11 May 2020 19:56:14 +0530 Subject: MDEV-22498: SIGSEGV in Bitmap<64u>::merge on SELECT For the case when the optimizer does the IN-EXISTS transformation, the equality condition is injected in the WHERE OR HAVING clause of the subquery. If the select list of the subquery has a reference to the parent select make sure to use the reference and not the original item. --- mysql-test/r/subselect4.result | 32 ++++++++++++++++++++++++++++++++ mysql-test/t/subselect4.test | 24 ++++++++++++++++++++++++ sql/item_subselect.cc | 9 ++++++--- 3 files changed, 62 insertions(+), 3 deletions(-) diff --git a/mysql-test/r/subselect4.result b/mysql-test/r/subselect4.result index a7e2bd9d1b5..863105b24b6 100644 --- a/mysql-test/r/subselect4.result +++ b/mysql-test/r/subselect4.result @@ -2534,3 +2534,35 @@ x c1 1 drop table t1; +# +# MDEV-22498: SIGSEGV in Bitmap<64u>::merge on SELECT +# +set @save_sql_select_limit= @@sql_select_limit; +SET sql_select_limit=0; +CREATE TABLE t1(b INT, c INT); +CREATE TABLE t2(a INT, b INT); +INSERT INTO t1 VALUES (1,1),(2,2),(3,3); +INSERT INTO t2 VALUES (1,1),(2,2),(3,3); +EXPLAIN EXTENDED SELECT sum(a), t2.a, t2.b FROM t2 HAVING t2.a IN (SELECT t2.b FROM t1); +id select_type table type possible_keys key key_len ref rows filtered Extra +1 PRIMARY NULL NULL NULL NULL NULL NULL NULL NULL Zero limit +2 DEPENDENT SUBQUERY t1 ALL NULL NULL NULL NULL 3 100.00 +Warnings: +Note 1276 Field or reference 'test.t2.b' of SELECT #2 was resolved in SELECT #1 +Note 1276 Field or reference 'test.t2.b' of SELECT #2 was resolved in SELECT #1 +Note 1003 select sum(`test`.`t2`.`a`) AS `sum(a)`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b` from `test`.`t2` having (`test`.`t2`.`a`,(select `test`.`t2`.`b` from `test`.`t1` where ((`test`.`t2`.`a`) = `test`.`t2`.`b`))) +SELECT sum(a), t2.a, t2.b FROM t2 HAVING t2.a IN (SELECT t2.b FROM t1); +sum(a) a b +SET @@sql_select_limit= @save_sql_select_limit; +EXPLAIN EXTENDED SELECT sum(a), t2.a, t2.b FROM t2 HAVING t2.a IN (SELECT t2.b FROM t1); +id select_type table type possible_keys key key_len ref rows filtered Extra +1 PRIMARY t2 ALL NULL NULL NULL NULL 3 100.00 +2 DEPENDENT SUBQUERY t1 ALL NULL NULL NULL NULL 3 100.00 +Warnings: +Note 1276 Field or reference 'test.t2.b' of SELECT #2 was resolved in SELECT #1 +Note 1276 Field or reference 'test.t2.b' of SELECT #2 was resolved in SELECT #1 +Note 1003 select sum(`test`.`t2`.`a`) AS `sum(a)`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b` from `test`.`t2` having <`test`.`t2`.`a`,`test`.`t2`.`b`>((`test`.`t2`.`a`,(select `test`.`t2`.`b` from `test`.`t1` where ((`test`.`t2`.`a`) = `test`.`t2`.`b`)))) +SELECT sum(a), t2.a, t2.b FROM t2 HAVING t2.a IN (SELECT t2.b FROM t1); +sum(a) a b +6 1 1 +DROP TABLE t1,t2; diff --git a/mysql-test/t/subselect4.test b/mysql-test/t/subselect4.test index d5a40419185..f0b1d16be7b 100644 --- a/mysql-test/t/subselect4.test +++ b/mysql-test/t/subselect4.test @@ -2075,3 +2075,27 @@ insert into t1 values(2,1),(1,2); select (select c1 from t1 group by c1,c2 order by c1 limit 1) as x; (select c1 from t1 group by c1,c2 order by c1 limit 1); drop table t1; + +--echo # +--echo # MDEV-22498: SIGSEGV in Bitmap<64u>::merge on SELECT +--echo # + +set @save_sql_select_limit= @@sql_select_limit; +SET sql_select_limit=0; + +CREATE TABLE t1(b INT, c INT); +CREATE TABLE t2(a INT, b INT); +INSERT INTO t1 VALUES (1,1),(2,2),(3,3); +INSERT INTO t2 VALUES (1,1),(2,2),(3,3); + +let $query= +SELECT sum(a), t2.a, t2.b FROM t2 HAVING t2.a IN (SELECT t2.b FROM t1); + +eval EXPLAIN EXTENDED $query; +eval $query; + +SET @@sql_select_limit= @save_sql_select_limit; + +eval EXPLAIN EXTENDED $query; +eval $query; +DROP TABLE t1,t2; diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc index e3cb82df170..16ef8a192c5 100644 --- a/sql/item_subselect.cc +++ b/sql/item_subselect.cc @@ -2135,10 +2135,13 @@ Item_in_subselect::create_single_in_to_exists_cond(JOIN *join, } else { + /* + No need to use real_item for the item, as the ref items that are possible + in the subquery either belong to views or to the parent select. + For such case we need to refer to the reference and not to the original + item. + */ Item *item= (Item*) select_lex->item_list.head(); - if (item->type() != REF_ITEM || - ((Item_ref*)item)->ref_type() != Item_ref::VIEW_REF) - item= item->real_item(); if (select_lex->table_list.elements) { -- cgit v1.2.1