From 45a91d8cbbfb38926f839b9c3cec73a39c5ebffd Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 8 May 2014 22:56:36 +0300 Subject: [PATCH] MDEV-6193: Problems with multi-table updates that JOIN against read-only table All underlying tables should share the same lock type. --- mysql-test/r/multi_update.result | 10 ++++++++++ mysql-test/t/multi_update.test | 11 ++++++++++- sql/sql_update.cc | 8 ++++---- sql/table.cc | 21 +++++++++++++++++++++ sql/table.h | 1 + 5 files changed, 46 insertions(+), 5 deletions(-) diff --git a/mysql-test/r/multi_update.result b/mysql-test/r/multi_update.result index 7172693d685..aef001c5f95 100644 --- a/mysql-test/r/multi_update.result +++ b/mysql-test/r/multi_update.result @@ -797,6 +797,8 @@ DROP TABLE t1,t2; # # MDEV-6139: UPDATE w/ join against MRG_MyISAM table with read-only # sub-table fails +# MDEV-6193: Problems with multi-table updates that JOIN against +# read-only table # CREATE TABLE t1 ( id int(10) unsigned, @@ -812,5 +814,13 @@ b int(11) ) ENGINE=MRG_MyISAM UNION=(t3); FLUSH TABLES; update t1 join t2 using (id) set t1.a=t2.b; +create view v2 as select * from t2; +update t1 join v2 using (id) set t1.a=0; +create view v1 as select * from t3; +update t1 join v1 using (id) set t1.a=0; +update t1 join INFORMATION_SCHEMA.CHARACTER_SETS on (id=MAXLEN) set t1.a=0; +create view v3 as select t2.id, t3.b from t2 join t3 using(id); +update t1 join v3 using (id) set t1.a=0; +drop view v1, v2, v3; drop table t2, t3, t1; end of 5.5 tests diff --git a/mysql-test/t/multi_update.test b/mysql-test/t/multi_update.test index 7acebfbed53..12b534f1473 100644 --- a/mysql-test/t/multi_update.test +++ b/mysql-test/t/multi_update.test @@ -811,6 +811,8 @@ DROP TABLE t1,t2; --echo # --echo # MDEV-6139: UPDATE w/ join against MRG_MyISAM table with read-only --echo # sub-table fails +--echo # MDEV-6193: Problems with multi-table updates that JOIN against +--echo # read-only table --echo # CREATE TABLE t1 ( @@ -837,7 +839,14 @@ let $MYSQLD_DATADIR= `select @@datadir`; --enable_result_log update t1 join t2 using (id) set t1.a=t2.b; - +create view v2 as select * from t2; +update t1 join v2 using (id) set t1.a=0; +create view v1 as select * from t3; +update t1 join v1 using (id) set t1.a=0; +update t1 join INFORMATION_SCHEMA.CHARACTER_SETS on (id=MAXLEN) set t1.a=0; +create view v3 as select t2.id, t3.b from t2 join t3 using(id); +update t1 join v3 using (id) set t1.a=0; +drop view v1, v2, v3; drop table t2, t3, t1; --echo end of 5.5 tests diff --git a/sql/sql_update.cc b/sql/sql_update.cc index b60f21ca9d5..e785b1106cf 100644 --- a/sql/sql_update.cc +++ b/sql/sql_update.cc @@ -1300,11 +1300,11 @@ int mysql_multi_update_prepare(THD *thd) be write-locked (for example, trigger to be invoked might try to update this table). */ - tl->lock_type= read_lock_type_for_table(thd, lex, tl); + if (using_lock_tables) + tl->lock_type= read_lock_type_for_table(thd, lex, tl); + else + tl->set_lock_type(thd, read_lock_type_for_table(thd, lex, tl)); tl->updating= 0; - /* Update TABLE::lock_type accordingly. */ - if (!tl->placeholder() && !using_lock_tables) - tl->table->file->set_lock_type(tl->lock_type); } } for (tl= table_list; tl; tl= tl->next_local) diff --git a/sql/table.cc b/sql/table.cc index f859c624d6b..12906f429df 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -6811,6 +6811,27 @@ bool TABLE_LIST::change_refs_to_fields() } +void TABLE_LIST::set_lock_type(THD *thd, enum thr_lock_type lock) +{ + if (check_stack_overrun(thd, STACK_MIN_SIZE, (uchar *)&lock)) + return; + /* we call it only when table is opened and it is "leaf" table*/ + DBUG_ASSERT(table); + lock_type= lock; + /* table->file->get_table() can be 0 for derived tables */ + if (table->file && table->file->get_table()) + table->file->set_lock_type(lock); + if (is_merged_derived()) + { + for (TABLE_LIST *table= get_single_select()->get_table_list(); + table; + table= table->next_local) + { + table->set_lock_type(thd, lock); + } + } +} + uint TABLE_SHARE::actual_n_key_parts(THD *thd) { return use_ext_keys && diff --git a/sql/table.h b/sql/table.h index 94b1cf1eff4..5442d8fc024 100644 --- a/sql/table.h +++ b/sql/table.h @@ -2151,6 +2151,7 @@ struct TABLE_LIST } return false; } + void set_lock_type(THD* thd, enum thr_lock_type lock); private: bool prep_check_option(THD *thd, uint8 check_opt_type);