Commit 2c9844a4 authored by Igor Babaev's avatar Igor Babaev

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.
parent 5543b755
...@@ -3181,6 +3181,7 @@ drop table t1,t2,t3; ...@@ -3181,6 +3181,7 @@ drop table t1,t2,t3;
# #
# MDEV-18896: IN subquery in WHERE of a table-less query used for INSERT # 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 t1 (a1 varchar(25));
create table t2 (a2 varchar(25)) ; create table t2 (a2 varchar(25)) ;
insert into t1 select 'xxx' from dual where 'xxx' in (select a2 from t2); insert into t1 select 'xxx' from dual where 'xxx' in (select a2 from t2);
......
...@@ -3195,6 +3195,7 @@ drop table t1,t2,t3; ...@@ -3195,6 +3195,7 @@ drop table t1,t2,t3;
# #
# MDEV-18896: IN subquery in WHERE of a table-less query used for INSERT # 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 t1 (a1 varchar(25));
create table t2 (a2 varchar(25)) ; create table t2 (a2 varchar(25)) ;
insert into t1 select 'xxx' from dual where 'xxx' in (select a2 from t2); insert into t1 select 'xxx' from dual where 'xxx' in (select a2 from t2);
......
...@@ -2873,6 +2873,8 @@ drop table t1,t2,t3; ...@@ -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 # MDEV-18896: IN subquery in WHERE of a table-less query used for INSERT
--echo # --echo #
set @@optimizer_switch= @subselect_sj_tmp;
create table t1 (a1 varchar(25)); create table t1 (a1 varchar(25));
create table t2 (a2 varchar(25)) ; create table t2 (a2 varchar(25)) ;
insert into t1 select 'xxx' from dual where 'xxx' in (select a2 from t2); insert into t1 select 'xxx' from dual where 'xxx' in (select a2 from t2);
......
...@@ -525,7 +525,7 @@ bool is_materialization_applicable(THD *thd, Item_in_subselect *in_subs, ...@@ -525,7 +525,7 @@ bool is_materialization_applicable(THD *thd, Item_in_subselect *in_subs,
parent_unit->first_select()->leaf_tables.elements && // 2 parent_unit->first_select()->leaf_tables.elements && // 2
(thd->lex->sql_command == SQLCOM_SELECT || // * (thd->lex->sql_command == SQLCOM_SELECT || // *
thd->lex->sql_command == SQLCOM_CREATE_TABLE) && // * 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) && subquery_types_allow_materialization(in_subs) &&
(in_subs->is_top_level_item() || //3 (in_subs->is_top_level_item() || //3
optimizer_flag(thd, optimizer_flag(thd,
......
...@@ -3034,6 +3034,13 @@ case SQLCOM_PREPARE: ...@@ -3034,6 +3034,13 @@ case SQLCOM_PREPARE:
*/ */
/* Skip first table, which is the table we are inserting in */ /* Skip first table, which is the table we are inserting in */
TABLE_LIST *second_table= first_table->next_local; 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->table_list.first= second_table;
select_lex->context.table_list= select_lex->context.table_list=
select_lex->context.first_name_resolution_table= second_table; select_lex->context.first_name_resolution_table= second_table;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment