mirror of
https://github.com/MariaDB/server.git
synced 2025-07-27 18:02:13 +03:00
MDEV-24823 Crash with invalid multi-table update of view in 2nd execution of SP
Before this patch mergeable derived tables / view used in a multi-table update / delete were merged before the preparation stage. When the merge of a derived table / view is performed the on expression attached to it is fixed and ANDed with the where condition of the select S containing this derived table / view. It happens after the specification of the derived table / view has been merged into S. If the ON expression refers to a non existing field an error is reported and some other mergeable derived tables / views remain unmerged. It's not a problem if the multi-table update / delete statement is standalone. Yet if it is used in a stored procedure the select with incompletely merged derived tables / views may cause a problem for the second call of the procedure. This does not happen for select queries using derived tables / views, because in this case their specifications are merged after the preparation stage at which all ON expressions are fixed. This patch makes sure that merging of the derived tables / views used in a multi-table update / delete statement is performed after the preparation stage. Approved by Oleksandr Byelkin <sanja@mariadb.com>
This commit is contained in:
@ -1009,9 +1009,6 @@ int mysql_multi_delete_prepare(THD *thd)
|
||||
DELETE_ACL, SELECT_ACL, FALSE))
|
||||
DBUG_RETURN(TRUE);
|
||||
|
||||
if (lex->select_lex.handle_derived(thd->lex, DT_MERGE))
|
||||
DBUG_RETURN(TRUE);
|
||||
|
||||
/*
|
||||
Multi-delete can't be constructed over-union => we always have
|
||||
single SELECT on top and have to check underlying SELECTs of it
|
||||
@ -1039,6 +1036,12 @@ int mysql_multi_delete_prepare(THD *thd)
|
||||
target_tbl->table_name.str, "DELETE");
|
||||
DBUG_RETURN(TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
for (target_tbl= (TABLE_LIST*) aux_tables;
|
||||
target_tbl;
|
||||
target_tbl= target_tbl->next_local)
|
||||
{
|
||||
/*
|
||||
Check that table from which we delete is not used somewhere
|
||||
inside subqueries/view.
|
||||
@ -1083,12 +1086,6 @@ multi_delete::prepare(List<Item> &values, SELECT_LEX_UNIT *u)
|
||||
unit= u;
|
||||
do_delete= 1;
|
||||
THD_STAGE_INFO(thd, stage_deleting_from_main_table);
|
||||
SELECT_LEX *select_lex= u->first_select();
|
||||
if (select_lex->first_cond_optimization)
|
||||
{
|
||||
if (select_lex->handle_derived(thd->lex, DT_MERGE))
|
||||
DBUG_RETURN(TRUE);
|
||||
}
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user