summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIgor Babaev <igor@askmonty.org>2021-01-19 08:02:37 -0800
committerIgor Babaev <igor@askmonty.org>2021-01-19 08:04:02 -0800
commitb22285e4821b49546de9b88990bbc9c453dc14b2 (patch)
treed1967e1bedf49ac07c5192502ca690acaeb8f342
parent3caccc7bcd7d28730d5d741480665c0b52135963 (diff)
downloadmariadb-git-b22285e4821b49546de9b88990bbc9c453dc14b2.tar.gz
MDEV-16940 Server crashes in unsafe_key_update upon attempt to update view
through 2nd execution of SP This bug caused a server crash on the second call of any stored procedure that contained an UPDATE statement over a multi-table view reporting an error message at the prepare stage. On the first call of the stored procedure after reporting an error at the preparation stage of the UPDATE statement finished without calling the function SELECT_LEX::save_prep_leaf_tables() for the SELECT used as the definition of the view. This left the SELECT_LEX structure used by the UPDATE statement in an inconsistent state for second call of the stored procedure. Approved by Oleksandr Byelkin <sanja@mariadb.com>
-rw-r--r--mysql-test/r/view.result16
-rw-r--r--mysql-test/t/view.test22
-rw-r--r--sql/sql_lex.cc3
-rw-r--r--sql/sql_update.cc3
4 files changed, 44 insertions, 0 deletions
diff --git a/mysql-test/r/view.result b/mysql-test/r/view.result
index 0da11c7c355..e48a99f6aff 100644
--- a/mysql-test/r/view.result
+++ b/mysql-test/r/view.result
@@ -6802,5 +6802,21 @@ drop database db1;
create database test;
use test;
#
+# MDEV-16940: update of multi-table view returning error used in SP
+#
+CREATE TABLE t1 (a INT) ENGINE=MyISAM;
+INSERT INTO t1 VALUES (1), (2);
+CREATE TABLE t2 (b INT) ENGINE=MyISAM;
+INSERT INTO t2 VALUES (2), (3);
+CREATE VIEW v1 AS SELECT a, b FROM t1,t2;
+CREATE PROCEDURE sp1() UPDATE v1 SET a = 8, b = 9;
+CALL sp1;
+ERROR HY000: Can not modify more than one base table through a join view 'test.v1'
+CALL sp1;
+ERROR HY000: Can not modify more than one base table through a join view 'test.v1'
+DROP PROCEDURE sp1;
+DROP VIEW v1;
+DROP TABLE t1, t2;
+#
# End of 10.2 tests
#
diff --git a/mysql-test/t/view.test b/mysql-test/t/view.test
index 2486887600b..b5ce6a1cabf 100644
--- a/mysql-test/t/view.test
+++ b/mysql-test/t/view.test
@@ -6522,5 +6522,27 @@ create database test;
use test;
--echo #
+--echo # MDEV-16940: update of multi-table view returning error used in SP
+--echo #
+
+CREATE TABLE t1 (a INT) ENGINE=MyISAM;
+INSERT INTO t1 VALUES (1), (2);
+CREATE TABLE t2 (b INT) ENGINE=MyISAM;
+INSERT INTO t2 VALUES (2), (3);
+
+CREATE VIEW v1 AS SELECT a, b FROM t1,t2;
+
+CREATE PROCEDURE sp1() UPDATE v1 SET a = 8, b = 9;
+
+--error ER_VIEW_MULTIUPDATE
+CALL sp1;
+--error ER_VIEW_MULTIUPDATE
+CALL sp1;
+
+DROP PROCEDURE sp1;
+DROP VIEW v1;
+DROP TABLE t1, t2;
+
+--echo #
--echo # End of 10.2 tests
--echo #
diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc
index 77e6b2b6571..5059e4f656e 100644
--- a/sql/sql_lex.cc
+++ b/sql/sql_lex.cc
@@ -4585,6 +4585,9 @@ bool LEX::save_prep_leaf_tables()
bool st_select_lex::save_prep_leaf_tables(THD *thd)
{
+ if (prep_leaf_list_state == SAVED)
+ return FALSE;
+
List_iterator_fast<TABLE_LIST> li(leaf_tables);
TABLE_LIST *table;
diff --git a/sql/sql_update.cc b/sql/sql_update.cc
index 7454d16d55d..01743a6751e 100644
--- a/sql/sql_update.cc
+++ b/sql/sql_update.cc
@@ -1398,6 +1398,9 @@ bool Multiupdate_prelocking_strategy::handle_end(THD *thd)
if (select_lex->handle_derived(thd->lex, DT_MERGE))
DBUG_RETURN(1);
+ if (thd->lex->save_prep_leaf_tables())
+ DBUG_RETURN(1);
+
List<Item> *fields= &lex->select_lex.item_list;
if (setup_fields_with_no_wrap(thd, Ref_ptr_array(),
*fields, MARK_COLUMNS_WRITE, 0, 0))