summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVarun Gupta <varun.gupta@mariadb.com>2020-05-11 19:56:14 +0530
committerVarun Gupta <varun.gupta@mariadb.com>2020-05-11 20:01:11 +0530
commit3f7e71439f6fb781a6eff0a70dfbf65ba9ef3540 (patch)
treefb151e6dc4a0404178434229129ad3909bf33e20
parent1887b5ae87ac0d1519f95a1e2f59efe09aded98f (diff)
downloadmariadb-git-10.1-mdev22498.tar.gz
MDEV-22498: SIGSEGV in Bitmap<64u>::merge on SELECT10.1-mdev22498
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.
-rw-r--r--mysql-test/r/subselect4.result32
-rw-r--r--mysql-test/t/subselect4.test24
-rw-r--r--sql/item_subselect.cc9
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 <in_optimizer>(`test`.`t2`.`a`,<exists>(select `test`.`t2`.`b` from `test`.`t1` where (<cache>(`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 <expr_cache><`test`.`t2`.`a`,`test`.`t2`.`b`>(<in_optimizer>(`test`.`t2`.`a`,<exists>(select `test`.`t2`.`b` from `test`.`t1` where (<cache>(`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)
{