[Commits] 2c9844a: MDEV-18896 Crash in convert_join_subqueries_to_semijoins : Correction

IgorBabaev igor at mariadb.com
Sun May 19 21:44:34 EEST 2019


revision-id: 2c9844a438c5f0bddcb037a1e05978118f48abb6 (mariadb-5.5.64-6-g2c9844a)
parent(s): 5543b75550962f07b4adcd47a6e52accec0a7d0f
author: Igor Babaev
committer: Igor Babaev
timestamp: 2019-05-19 11:44:34 -0700
message:

MDEV-18896 Crash in convert_join_subqueries_to_semijoins : Correction

This patch complements the original patch for MDEV-18896 that prevents
conversions to semi-joins in tableless selects used in INSERT statements
in post-5.5 versions of the server.
The test case was corrected as well to ensure that potential conversion
to jtbm semi-joins is also checked (the problem was that one of
the preceeding testcases in subselect_sj.test did not restore the
state of the optimizer switch leaving the 'materialization' in the state
'off' and so blocking this check).
Noticed an inconsistency in the state of select_lex::table_list used
in INSERT statements and left a comment about this.

---
 mysql-test/r/subselect_sj.result      | 1 +
 mysql-test/r/subselect_sj_jcl6.result | 1 +
 mysql-test/t/subselect_sj.test        | 2 ++
 sql/opt_subselect.cc                  | 2 +-
 sql/sql_parse.cc                      | 7 +++++++
 5 files changed, 12 insertions(+), 1 deletion(-)

diff --git a/mysql-test/r/subselect_sj.result b/mysql-test/r/subselect_sj.result
index 73c620b..d0b8b62 100644
--- a/mysql-test/r/subselect_sj.result
+++ b/mysql-test/r/subselect_sj.result
@@ -3181,6 +3181,7 @@ drop table t1,t2,t3;
 #
 # MDEV-18896: IN subquery in WHERE of a table-less query used for INSERT
 #
+set @@optimizer_switch= @subselect_sj_tmp;
 create table t1 (a1 varchar(25));
 create table t2 (a2 varchar(25)) ;
 insert into t1 select 'xxx' from dual where 'xxx' in (select a2 from t2);
diff --git a/mysql-test/r/subselect_sj_jcl6.result b/mysql-test/r/subselect_sj_jcl6.result
index 03cf368..e9a8b73 100644
--- a/mysql-test/r/subselect_sj_jcl6.result
+++ b/mysql-test/r/subselect_sj_jcl6.result
@@ -3195,6 +3195,7 @@ drop table t1,t2,t3;
 #
 # MDEV-18896: IN subquery in WHERE of a table-less query used for INSERT
 #
+set @@optimizer_switch= @subselect_sj_tmp;
 create table t1 (a1 varchar(25));
 create table t2 (a2 varchar(25)) ;
 insert into t1 select 'xxx' from dual where 'xxx' in (select a2 from t2);
diff --git a/mysql-test/t/subselect_sj.test b/mysql-test/t/subselect_sj.test
index aabb21b..6b59049 100644
--- a/mysql-test/t/subselect_sj.test
+++ b/mysql-test/t/subselect_sj.test
@@ -2873,6 +2873,8 @@ drop table t1,t2,t3;
 --echo # MDEV-18896: IN subquery in WHERE of a table-less query used for INSERT
 --echo #
 
+set @@optimizer_switch= @subselect_sj_tmp;
+
 create table t1 (a1 varchar(25));
 create table t2 (a2 varchar(25)) ;
 insert into t1 select 'xxx' from dual where 'xxx' in (select a2 from t2);
diff --git a/sql/opt_subselect.cc b/sql/opt_subselect.cc
index fee68d3..a0e19af 100644
--- a/sql/opt_subselect.cc
+++ b/sql/opt_subselect.cc
@@ -525,7 +525,7 @@ bool is_materialization_applicable(THD *thd, Item_in_subselect *in_subs,
         parent_unit->first_select()->leaf_tables.elements &&          // 2
         (thd->lex->sql_command == SQLCOM_SELECT ||                     // *
          thd->lex->sql_command == SQLCOM_CREATE_TABLE) &&              // *
-        child_select->outer_select()->leaf_tables.elements &&           // 2A
+        child_select->outer_select()->table_list.first &&            // 2A
         subquery_types_allow_materialization(in_subs) &&
         (in_subs->is_top_level_item() ||                               //3
          optimizer_flag(thd,
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index 4ed2bca..1d5733a 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -3034,6 +3034,13 @@ case SQLCOM_PREPARE:
       */
       /* Skip first table, which is the table we are inserting in */
       TABLE_LIST *second_table= first_table->next_local;
+      /*
+        This is a hack: this leaves select_lex->table_list in an inconsistent
+        state as 'elements' does not contain number of elements in the list.
+        Moreover, if second_table == NULL then 'next' becomes invalid.
+        TODO: fix it by removing the front element (restoring of it should
+        be done properly as well)
+      */
       select_lex->table_list.first= second_table;
       select_lex->context.table_list= 
         select_lex->context.first_name_resolution_table= second_table;


More information about the commits mailing list