summaryrefslogtreecommitdiff
path: root/sql/sql_delete.cc
diff options
context:
space:
mode:
authorIgor Babaev <igor@askmonty.org>2021-04-22 20:02:08 -0700
committerIgor Babaev <igor@askmonty.org>2021-04-22 20:02:08 -0700
commite3a25793be936d9682a711a00d6b4bf708b6fb8d (patch)
tree6f1047164d7df4499687d1e598d7b46128fcf200 /sql/sql_delete.cc
parent6f271302b649ee11e7987b46fe24824c2ca2be7c (diff)
downloadmariadb-git-e3a25793be936d9682a711a00d6b4bf708b6fb8d.tar.gz
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>
Diffstat (limited to 'sql/sql_delete.cc')
-rw-r--r--sql/sql_delete.cc15
1 files changed, 6 insertions, 9 deletions
diff --git a/sql/sql_delete.cc b/sql/sql_delete.cc
index 0857c4e5457..c78e8ed510e 100644
--- a/sql/sql_delete.cc
+++ b/sql/sql_delete.cc
@@ -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);
}