Commit 321ff25f authored by unknown's avatar unknown

MDEV-5740: Assertion `!derived->first_select()->exclude_from_table_unique_test...

MDEV-5740: Assertion `!derived->first_select()->exclude_from_table_unique_test || derived->outer_select()-> exclude_from_table_unique_test' failed on 2nd execution of PS with derived_merge

Do not check tables of executed units.
Debug info about stages of derived tables execution added.
parent 1f2ef574
...@@ -2356,6 +2356,46 @@ id select_type table type possible_keys key key_len ref rows Extra ...@@ -2356,6 +2356,46 @@ id select_type table type possible_keys key key_len ref rows Extra
3 DEPENDENT SUBQUERY pi ref gallery_id gallery_id 4 test.gal.id 4 Using temporary; Using filesort 3 DEPENDENT SUBQUERY pi ref gallery_id gallery_id 4 test.gal.id 4 Using temporary; Using filesort
drop table galleries, pictures; drop table galleries, pictures;
# #
# MDEV-5740: Assertion
#`!derived->first_select()->exclude_from_table_unique_test ||
#derived->outer_select()-> exclude_from_table_unique_test'
#failed on 2nd execution of PS with derived_merge
#
set @save_optimizer_switch5740=@@optimizer_switch;
SET optimizer_switch = 'derived_merge=on';
CREATE TABLE t1 (a INT);
INSERT INTO t1 VALUES (1),(2);
CREATE TABLE t2 (b INT);
INSERT INTO t2 VALUES (3),(4);
PREPARE stmt FROM '
INSERT INTO t1 SELECT * FROM t2 UNION SELECT * FROM (SELECT * FROM t1) AS sq
';
EXECUTE stmt;
select * from t1;
a
1
2
3
4
1
2
EXECUTE stmt;
select * from t1;
a
1
2
3
4
1
2
3
4
1
2
deallocate prepare stmt;
drop table t1,t2;
set optimizer_switch=@save_optimizer_switch5740;
#
# end of 5.3 tests # end of 5.3 tests
# #
set optimizer_switch=@exit_optimizer_switch; set optimizer_switch=@exit_optimizer_switch;
......
...@@ -1703,6 +1703,33 @@ ORDER BY gallery_name ASC ...@@ -1703,6 +1703,33 @@ ORDER BY gallery_name ASC
drop table galleries, pictures; drop table galleries, pictures;
--echo #
--echo # MDEV-5740: Assertion
--echo #`!derived->first_select()->exclude_from_table_unique_test ||
--echo #derived->outer_select()-> exclude_from_table_unique_test'
--echo #failed on 2nd execution of PS with derived_merge
--echo #
set @save_optimizer_switch5740=@@optimizer_switch;
SET optimizer_switch = 'derived_merge=on';
CREATE TABLE t1 (a INT);
INSERT INTO t1 VALUES (1),(2);
CREATE TABLE t2 (b INT);
INSERT INTO t2 VALUES (3),(4);
PREPARE stmt FROM '
INSERT INTO t1 SELECT * FROM t2 UNION SELECT * FROM (SELECT * FROM t1) AS sq
';
EXECUTE stmt;
select * from t1;
EXECUTE stmt;
select * from t1;
deallocate prepare stmt;
drop table t1,t2;
set optimizer_switch=@save_optimizer_switch5740;
--echo # --echo #
--echo # end of 5.3 tests --echo # end of 5.3 tests
--echo # --echo #
......
...@@ -1735,6 +1735,17 @@ TABLE_LIST* unique_table(THD *thd, TABLE_LIST *table, TABLE_LIST *table_list, ...@@ -1735,6 +1735,17 @@ TABLE_LIST* unique_table(THD *thd, TABLE_LIST *table, TABLE_LIST *table_list,
DBUG_PRINT("info", ("real table: %s.%s", d_name, t_name)); DBUG_PRINT("info", ("real table: %s.%s", d_name, t_name));
for (TABLE_LIST *tl= table_list;;) for (TABLE_LIST *tl= table_list;;)
{ {
if (tl &&
tl->select_lex && tl->select_lex->master_unit() &&
tl->select_lex->master_unit()->executed)
{
/*
There is no sense to check tables of already executed parts
of the query
*/
tl= tl->next_global;
continue;
}
if (((! (res= find_table_in_global_list(tl, d_name, t_name))) && if (((! (res= find_table_in_global_list(tl, d_name, t_name))) &&
(! (res= mysql_lock_have_duplicate(thd, table, tl)))) || (! (res= mysql_lock_have_duplicate(thd, table, tl)))) ||
((!res->table || res->table != table->table) && ((!res->table || res->table != table->table) &&
......
...@@ -64,8 +64,10 @@ mysql_handle_derived(LEX *lex, uint phases) ...@@ -64,8 +64,10 @@ mysql_handle_derived(LEX *lex, uint phases)
{ {
bool res= FALSE; bool res= FALSE;
THD *thd= lex->thd; THD *thd= lex->thd;
DBUG_ENTER("mysql_handle_derived");
DBUG_PRINT("enter", ("phases: 0x%x", phases));
if (!lex->derived_tables) if (!lex->derived_tables)
return FALSE; DBUG_RETURN(FALSE);
lex->thd->derived_tables_processing= TRUE; lex->thd->derived_tables_processing= TRUE;
...@@ -123,7 +125,7 @@ mysql_handle_derived(LEX *lex, uint phases) ...@@ -123,7 +125,7 @@ mysql_handle_derived(LEX *lex, uint phases)
} }
} }
lex->thd->derived_tables_processing= FALSE; lex->thd->derived_tables_processing= FALSE;
return res; DBUG_RETURN(res);
} }
/* /*
...@@ -163,8 +165,10 @@ mysql_handle_single_derived(LEX *lex, TABLE_LIST *derived, uint phases) ...@@ -163,8 +165,10 @@ mysql_handle_single_derived(LEX *lex, TABLE_LIST *derived, uint phases)
THD *thd= lex->thd; THD *thd= lex->thd;
uint8 allowed_phases= (derived->is_merged_derived() ? DT_PHASES_MERGE : uint8 allowed_phases= (derived->is_merged_derived() ? DT_PHASES_MERGE :
DT_PHASES_MATERIALIZE); DT_PHASES_MATERIALIZE);
DBUG_ENTER("mysql_handle_single_derived");
DBUG_PRINT("enter", ("phases: 0x%x allowed: 0x%x", phases, allowed_phases));
if (!lex->derived_tables) if (!lex->derived_tables)
return FALSE; DBUG_RETURN(FALSE);
lex->thd->derived_tables_processing= TRUE; lex->thd->derived_tables_processing= TRUE;
...@@ -186,7 +190,7 @@ mysql_handle_single_derived(LEX *lex, TABLE_LIST *derived, uint phases) ...@@ -186,7 +190,7 @@ mysql_handle_single_derived(LEX *lex, TABLE_LIST *derived, uint phases)
break; break;
} }
lex->thd->derived_tables_processing= FALSE; lex->thd->derived_tables_processing= FALSE;
return res; DBUG_RETURN(res);
} }
...@@ -353,16 +357,17 @@ bool mysql_derived_merge(THD *thd, LEX *lex, TABLE_LIST *derived) ...@@ -353,16 +357,17 @@ bool mysql_derived_merge(THD *thd, LEX *lex, TABLE_LIST *derived)
uint tablenr; uint tablenr;
SELECT_LEX *parent_lex= derived->select_lex; SELECT_LEX *parent_lex= derived->select_lex;
Query_arena *arena, backup; Query_arena *arena, backup;
DBUG_ENTER("mysql_derived_merge");
if (derived->merged) if (derived->merged)
return FALSE; DBUG_RETURN(FALSE);
if (dt_select->uncacheable & UNCACHEABLE_RAND) if (dt_select->uncacheable & UNCACHEABLE_RAND)
{ {
/* There is random function => fall back to materialization. */ /* There is random function => fall back to materialization. */
derived->change_refs_to_fields(); derived->change_refs_to_fields();
derived->set_materialized_derived(); derived->set_materialized_derived();
return FALSE; DBUG_RETURN(FALSE);
} }
if (thd->lex->sql_command == SQLCOM_UPDATE_MULTI || if (thd->lex->sql_command == SQLCOM_UPDATE_MULTI ||
...@@ -466,7 +471,7 @@ bool mysql_derived_merge(THD *thd, LEX *lex, TABLE_LIST *derived) ...@@ -466,7 +471,7 @@ bool mysql_derived_merge(THD *thd, LEX *lex, TABLE_LIST *derived)
exit_merge: exit_merge:
if (arena) if (arena)
thd->restore_active_arena(arena, &backup); thd->restore_active_arena(arena, &backup);
return res; DBUG_RETURN(res);
} }
...@@ -492,14 +497,15 @@ bool mysql_derived_merge(THD *thd, LEX *lex, TABLE_LIST *derived) ...@@ -492,14 +497,15 @@ bool mysql_derived_merge(THD *thd, LEX *lex, TABLE_LIST *derived)
bool mysql_derived_merge_for_insert(THD *thd, LEX *lex, TABLE_LIST *derived) bool mysql_derived_merge_for_insert(THD *thd, LEX *lex, TABLE_LIST *derived)
{ {
DBUG_ENTER("mysql_derived_merge_for_insert");
if (derived->merged_for_insert) if (derived->merged_for_insert)
return FALSE; DBUG_RETURN(FALSE);
if (derived->is_materialized_derived()) if (derived->is_materialized_derived())
return mysql_derived_prepare(thd, lex, derived); DBUG_RETURN(mysql_derived_prepare(thd, lex, derived));
if (!derived->is_multitable()) if (!derived->is_multitable())
{ {
if (!derived->single_table_updatable()) if (!derived->single_table_updatable())
return derived->create_field_translation(thd); DBUG_RETURN(derived->create_field_translation(thd));
if (derived->merge_underlying_list) if (derived->merge_underlying_list)
{ {
derived->table= derived->merge_underlying_list->table; derived->table= derived->merge_underlying_list->table;
...@@ -507,7 +513,7 @@ bool mysql_derived_merge_for_insert(THD *thd, LEX *lex, TABLE_LIST *derived) ...@@ -507,7 +513,7 @@ bool mysql_derived_merge_for_insert(THD *thd, LEX *lex, TABLE_LIST *derived)
derived->merged_for_insert= TRUE; derived->merged_for_insert= TRUE;
} }
} }
return FALSE; DBUG_RETURN(FALSE);
} }
...@@ -764,9 +770,10 @@ bool mysql_derived_optimize(THD *thd, LEX *lex, TABLE_LIST *derived) ...@@ -764,9 +770,10 @@ bool mysql_derived_optimize(THD *thd, LEX *lex, TABLE_LIST *derived)
SELECT_LEX *save_current_select= lex->current_select; SELECT_LEX *save_current_select= lex->current_select;
bool res= FALSE; bool res= FALSE;
DBUG_ENTER("mysql_derived_optimize");
if (unit->optimized) if (unit->optimized)
return FALSE; DBUG_RETURN(FALSE);
lex->current_select= first_select; lex->current_select= first_select;
if (unit->is_union()) if (unit->is_union())
...@@ -806,7 +813,7 @@ bool mysql_derived_optimize(THD *thd, LEX *lex, TABLE_LIST *derived) ...@@ -806,7 +813,7 @@ bool mysql_derived_optimize(THD *thd, LEX *lex, TABLE_LIST *derived)
} }
err: err:
lex->current_select= save_current_select; lex->current_select= save_current_select;
return res; DBUG_RETURN(res);
} }
...@@ -829,11 +836,12 @@ bool mysql_derived_optimize(THD *thd, LEX *lex, TABLE_LIST *derived) ...@@ -829,11 +836,12 @@ bool mysql_derived_optimize(THD *thd, LEX *lex, TABLE_LIST *derived)
bool mysql_derived_create(THD *thd, LEX *lex, TABLE_LIST *derived) bool mysql_derived_create(THD *thd, LEX *lex, TABLE_LIST *derived)
{ {
DBUG_ENTER("mysql_derived_create");
TABLE *table= derived->table; TABLE *table= derived->table;
SELECT_LEX_UNIT *unit= derived->get_unit(); SELECT_LEX_UNIT *unit= derived->get_unit();
if (table->created) if (table->created)
return FALSE; DBUG_RETURN(FALSE);
select_union *result= (select_union*)unit->result; select_union *result= (select_union*)unit->result;
if (table->s->db_type() == TMP_ENGINE_HTON) if (table->s->db_type() == TMP_ENGINE_HTON)
{ {
...@@ -843,13 +851,13 @@ bool mysql_derived_create(THD *thd, LEX *lex, TABLE_LIST *derived) ...@@ -843,13 +851,13 @@ bool mysql_derived_create(THD *thd, LEX *lex, TABLE_LIST *derived)
&result->tmp_table_param.recinfo, &result->tmp_table_param.recinfo,
(unit->first_select()->options | (unit->first_select()->options |
thd->options | TMP_TABLE_ALL_COLUMNS))) thd->options | TMP_TABLE_ALL_COLUMNS)))
return(TRUE); DBUG_RETURN(TRUE);
} }
if (open_tmp_table(table)) if (open_tmp_table(table))
return TRUE; DBUG_RETURN(TRUE);
table->file->extra(HA_EXTRA_WRITE_CACHE); table->file->extra(HA_EXTRA_WRITE_CACHE);
table->file->extra(HA_EXTRA_IGNORE_DUP_KEY); table->file->extra(HA_EXTRA_IGNORE_DUP_KEY);
return FALSE; DBUG_RETURN(FALSE);
} }
...@@ -879,11 +887,12 @@ bool mysql_derived_create(THD *thd, LEX *lex, TABLE_LIST *derived) ...@@ -879,11 +887,12 @@ bool mysql_derived_create(THD *thd, LEX *lex, TABLE_LIST *derived)
bool mysql_derived_fill(THD *thd, LEX *lex, TABLE_LIST *derived) bool mysql_derived_fill(THD *thd, LEX *lex, TABLE_LIST *derived)
{ {
DBUG_ENTER("mysql_derived_fill");
SELECT_LEX_UNIT *unit= derived->get_unit(); SELECT_LEX_UNIT *unit= derived->get_unit();
bool res= FALSE; bool res= FALSE;
if (unit->executed && !unit->uncacheable && !unit->describe) if (unit->executed && !unit->uncacheable && !unit->describe)
return FALSE; DBUG_RETURN(FALSE);
/*check that table creation passed without problems. */ /*check that table creation passed without problems. */
DBUG_ASSERT(derived->table && derived->table->created); DBUG_ASSERT(derived->table && derived->table->created);
SELECT_LEX *first_select= unit->first_select(); SELECT_LEX *first_select= unit->first_select();
...@@ -925,7 +934,7 @@ bool mysql_derived_fill(THD *thd, LEX *lex, TABLE_LIST *derived) ...@@ -925,7 +934,7 @@ bool mysql_derived_fill(THD *thd, LEX *lex, TABLE_LIST *derived)
unit->cleanup(); unit->cleanup();
lex->current_select= save_current_select; lex->current_select= save_current_select;
return res; DBUG_RETURN(res);
} }
...@@ -949,6 +958,7 @@ bool mysql_derived_fill(THD *thd, LEX *lex, TABLE_LIST *derived) ...@@ -949,6 +958,7 @@ bool mysql_derived_fill(THD *thd, LEX *lex, TABLE_LIST *derived)
bool mysql_derived_reinit(THD *thd, LEX *lex, TABLE_LIST *derived) bool mysql_derived_reinit(THD *thd, LEX *lex, TABLE_LIST *derived)
{ {
DBUG_ENTER("mysql_derived_reinit");
st_select_lex_unit *unit= derived->get_unit(); st_select_lex_unit *unit= derived->get_unit();
if (derived->table) if (derived->table)
...@@ -958,5 +968,5 @@ bool mysql_derived_reinit(THD *thd, LEX *lex, TABLE_LIST *derived) ...@@ -958,5 +968,5 @@ bool mysql_derived_reinit(THD *thd, LEX *lex, TABLE_LIST *derived)
/* for derived tables & PS (which can't be reset by Item_subquery) */ /* for derived tables & PS (which can't be reset by Item_subquery) */
unit->reinit_exec_mechanism(); unit->reinit_exec_mechanism();
unit->set_thd(thd); unit->set_thd(thd);
return FALSE; DBUG_RETURN(FALSE);
} }
...@@ -1791,9 +1791,11 @@ struct TABLE_LIST ...@@ -1791,9 +1791,11 @@ struct TABLE_LIST
} }
inline void set_merged_derived() inline void set_merged_derived()
{ {
DBUG_ENTER("set_merged_derived");
derived_type= ((derived_type & DTYPE_MASK) | derived_type= ((derived_type & DTYPE_MASK) |
DTYPE_TABLE | DTYPE_MERGE); DTYPE_TABLE | DTYPE_MERGE);
set_check_merged(); set_check_merged();
DBUG_VOID_RETURN;
} }
inline bool is_materialized_derived() inline bool is_materialized_derived()
{ {
...@@ -1801,9 +1803,11 @@ struct TABLE_LIST ...@@ -1801,9 +1803,11 @@ struct TABLE_LIST
} }
void set_materialized_derived() void set_materialized_derived()
{ {
DBUG_ENTER("set_materialized_derived");
derived_type= ((derived_type & DTYPE_MASK) | derived_type= ((derived_type & DTYPE_MASK) |
DTYPE_TABLE | DTYPE_MATERIALIZE); DTYPE_TABLE | DTYPE_MATERIALIZE);
set_check_materialized(); set_check_materialized();
DBUG_VOID_RETURN;
} }
inline bool is_multitable() inline bool is_multitable()
{ {
......
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