mirror of
https://github.com/MariaDB/server.git
synced 2025-08-01 03:47:19 +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:
@ -4623,6 +4623,27 @@ bool st_select_lex::save_prep_leaf_tables(THD *thd)
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Set exclude_from_table_unique_test for selects of this select and all selects
|
||||
belonging to the underlying units of derived tables or views
|
||||
*/
|
||||
|
||||
void st_select_lex::set_unique_exclude()
|
||||
{
|
||||
exclude_from_table_unique_test= TRUE;
|
||||
for (SELECT_LEX_UNIT *unit= first_inner_unit();
|
||||
unit;
|
||||
unit= unit->next_unit())
|
||||
{
|
||||
if (unit->derived && unit->derived->is_view_or_derived())
|
||||
{
|
||||
for (SELECT_LEX *sl= unit->first_select(); sl; sl= sl->next_select())
|
||||
sl->set_unique_exclude();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Return true if this select_lex has been converted into a semi-join nest
|
||||
within 'ancestor'.
|
||||
|
Reference in New Issue
Block a user