summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorunknown <sanja@askmonty.org>2014-05-08 22:56:36 +0300
committerunknown <sanja@askmonty.org>2014-05-08 22:56:36 +0300
commit45a91d8cbbfb38926f839b9c3cec73a39c5ebffd (patch)
tree38d2449ef8c78990fed2349baa5be05497d327c9
parent3f80740aa8fb24a0f9798e7239f0adb9f910e0a6 (diff)
downloadmariadb-git-45a91d8cbbfb38926f839b9c3cec73a39c5ebffd.tar.gz
MDEV-6193: Problems with multi-table updates that JOIN against read-only table
All underlying tables should share the same lock type.
-rw-r--r--mysql-test/r/multi_update.result10
-rw-r--r--mysql-test/t/multi_update.test11
-rw-r--r--sql/sql_update.cc8
-rw-r--r--sql/table.cc21
-rw-r--r--sql/table.h1
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);