From c9494dc42d6cf68fb20fb8e54e6cb6367336271e Mon Sep 17 00:00:00 2001 From: Sergey Petrunya Date: Tue, 16 Aug 2011 21:42:25 +0400 Subject: [PATCH] BUG#818280: crash in do_copy_not_null() in maria-5.3 with semijoin - Make simplify_joins() set maybe_null=FALSE for tables that were on the inner sides of inner joins and then were moved to the inner sides of semi-joins. --- mysql-test/r/subselect_sj.result | 14 ++++++++++++++ mysql-test/r/subselect_sj_jcl6.result | 14 ++++++++++++++ mysql-test/t/subselect_sj.test | 16 ++++++++++++++++ sql/sql_select.cc | 12 ++++++++++++ 4 files changed, 56 insertions(+) diff --git a/mysql-test/r/subselect_sj.result b/mysql-test/r/subselect_sj.result index 517b6e63c6d..c09a44d26f1 100644 --- a/mysql-test/r/subselect_sj.result +++ b/mysql-test/r/subselect_sj.result @@ -1715,4 +1715,18 @@ f1 f2 f3 f3 0 NULL NULL NULL DROP TABLE t1, t2, t3, t4; set @tmp803457=@@optimizer_switch; +# +# BUG#818280: crash in do_copy_not_null() in maria-5.3 with semijoin +# +CREATE TABLE t1 ( c1 int NOT NULL , c2 int NOT NULL, PRIMARY KEY (c1)) ; +INSERT IGNORE INTO t1 VALUES (2,7),(1,3),(5,6); +CREATE TABLE t3 ( c1 int NOT NULL , c2 int NOT NULL, PRIMARY KEY (c1)) ; +INSERT IGNORE INTO t3 VALUES (2,7),(1,3),(5,6); +CREATE TABLE t2 ( c1 int NOT NULL , c5 int NOT NULL ); +INSERT IGNORE INTO t2 VALUES (2,2),(2,2),(5,6); +SELECT * FROM t1 WHERE c1 IN ( SELECT t3.c1 FROM t3 LEFT JOIN t2 ON t2 .c1 = t3 .c1 WHERE t2.c5 != 0 ); +c1 c2 +2 7 +5 6 +DROP TABLE t1, t2, t3; set optimizer_switch=@subselect_sj_tmp; diff --git a/mysql-test/r/subselect_sj_jcl6.result b/mysql-test/r/subselect_sj_jcl6.result index cc83b9ac99c..41beeb18ed5 100644 --- a/mysql-test/r/subselect_sj_jcl6.result +++ b/mysql-test/r/subselect_sj_jcl6.result @@ -1726,6 +1726,20 @@ f1 f2 f3 f3 0 NULL NULL NULL DROP TABLE t1, t2, t3, t4; set @tmp803457=@@optimizer_switch; +# +# BUG#818280: crash in do_copy_not_null() in maria-5.3 with semijoin +# +CREATE TABLE t1 ( c1 int NOT NULL , c2 int NOT NULL, PRIMARY KEY (c1)) ; +INSERT IGNORE INTO t1 VALUES (2,7),(1,3),(5,6); +CREATE TABLE t3 ( c1 int NOT NULL , c2 int NOT NULL, PRIMARY KEY (c1)) ; +INSERT IGNORE INTO t3 VALUES (2,7),(1,3),(5,6); +CREATE TABLE t2 ( c1 int NOT NULL , c5 int NOT NULL ); +INSERT IGNORE INTO t2 VALUES (2,2),(2,2),(5,6); +SELECT * FROM t1 WHERE c1 IN ( SELECT t3.c1 FROM t3 LEFT JOIN t2 ON t2 .c1 = t3 .c1 WHERE t2.c5 != 0 ); +c1 c2 +2 7 +5 6 +DROP TABLE t1, t2, t3; set optimizer_switch=@subselect_sj_tmp; # # BUG#49129: Wrong result with IN-subquery with join_cache_level=6 and firstmatch=off diff --git a/mysql-test/t/subselect_sj.test b/mysql-test/t/subselect_sj.test index 4930a79acd4..66c7b1bc549 100644 --- a/mysql-test/t/subselect_sj.test +++ b/mysql-test/t/subselect_sj.test @@ -1555,5 +1555,21 @@ SELECT * FROM t1 NATURAL LEFT JOIN (t2, t3 ) WHERE IFNULL(t2.f3,'foo') IN (SELEC DROP TABLE t1, t2, t3, t4; set @tmp803457=@@optimizer_switch; +--echo # +--echo # BUG#818280: crash in do_copy_not_null() in maria-5.3 with semijoin +--echo # +CREATE TABLE t1 ( c1 int NOT NULL , c2 int NOT NULL, PRIMARY KEY (c1)) ; +INSERT IGNORE INTO t1 VALUES (2,7),(1,3),(5,6); + +CREATE TABLE t3 ( c1 int NOT NULL , c2 int NOT NULL, PRIMARY KEY (c1)) ; +INSERT IGNORE INTO t3 VALUES (2,7),(1,3),(5,6); + +CREATE TABLE t2 ( c1 int NOT NULL , c5 int NOT NULL ); +INSERT IGNORE INTO t2 VALUES (2,2),(2,2),(5,6); + +SELECT * FROM t1 WHERE c1 IN ( SELECT t3.c1 FROM t3 LEFT JOIN t2 ON t2 .c1 = t3 .c1 WHERE t2.c5 != 0 ); + +DROP TABLE t1, t2, t3; + # The following command must be the last one the file set optimizer_switch=@subselect_sj_tmp; diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 5cc8078b9f0..83da3d157de 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -11928,6 +11928,18 @@ simplify_joins(JOIN *join, List *join_list, COND *conds, bool top, leave it intact (otherwise it is flattened) */ join->select_lex->sj_nests.push_back(table); + + /* + Also, walk through semi-join children and mark those that are now + top-level + */ + TABLE_LIST *tbl; + List_iterator it(nested_join->join_list); + while ((tbl= it++)) + { + if (!tbl->on_expr && tbl->table) + tbl->table->maybe_null= FALSE; + } } else if (nested_join && !table->on_expr) {