mirror of
https://github.com/MariaDB/server.git
synced 2025-07-05 12:42:17 +03:00
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.
This commit is contained in:
@ -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
|
|||||||
|
|
||||||
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 @@ retry:
|
|||||||
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)
|
|||||||
{
|
{
|
||||||
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)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
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)
|
|||||||
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)
|
|||||||
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)
|
|||||||
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)
|
|||||||
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 @@ exit_merge:
|
|||||||
|
|
||||||
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)
|
|||||||
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)
|
|||||||
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)
|
|||||||
}
|
}
|
||||||
err:
|
err:
|
||||||
lex->current_select= save_current_select;
|
lex->current_select= save_current_select;
|
||||||
return res;
|
DBUG_RETURN(res);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -829,11 +836,12 @@ err:
|
|||||||
|
|
||||||
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)
|
|||||||
&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)
|
|||||||
|
|
||||||
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)
|
|||||||
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)
|
|||||||
|
|
||||||
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)
|
|||||||
/* 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
|
|||||||
}
|
}
|
||||||
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
|
|||||||
}
|
}
|
||||||
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()
|
||||||
{
|
{
|
||||||
|
Reference in New Issue
Block a user