summaryrefslogtreecommitdiff
path: root/mysql-test
diff options
context:
space:
mode:
authorVladislav Vaintroub <vvaintroub@mysql.com>2010-02-16 23:19:47 +0100
committerVladislav Vaintroub <vvaintroub@mysql.com>2010-02-16 23:19:47 +0100
commitd4b10d1fd541505c850c32895d8a1f8308d35c15 (patch)
treebb2aacb96d3588f443a65da32dbfa2b6508efb80 /mysql-test
parent09dfcfa14bda0d57493a3a15949a8e50a73f6d88 (diff)
parentcbb02487f6b0e95b35e2ee6f3e3242108a75deca (diff)
downloadmariadb-git-d4b10d1fd541505c850c32895d8a1f8308d35c15.tar.gz
merge
Diffstat (limited to 'mysql-test')
-rw-r--r--mysql-test/extra/binlog_tests/drop_table.test34
-rw-r--r--mysql-test/extra/binlog_tests/mix_innodb_myisam_binlog.test4
-rw-r--r--mysql-test/extra/rpl_tests/rpl_innodb.test67
-rw-r--r--mysql-test/include/commit.inc8
-rw-r--r--mysql-test/include/handler.inc1008
-rw-r--r--mysql-test/include/implicit_commit_helper.inc5
-rw-r--r--mysql-test/include/mix1.inc3
-rw-r--r--mysql-test/include/mix2.inc2
-rw-r--r--mysql-test/include/mtr_warnings.sql8
-rw-r--r--mysql-test/lib/v1/mtr_report.pl3
-rw-r--r--mysql-test/r/commit_1innodb.result8
-rw-r--r--mysql-test/r/create.result26
-rw-r--r--mysql-test/r/debug_sync.result2
-rw-r--r--mysql-test/r/drop.result2
-rw-r--r--mysql-test/r/drop_debug.result4
-rw-r--r--mysql-test/r/flush.result22
-rw-r--r--mysql-test/r/flush_block_commit.result18
-rw-r--r--mysql-test/r/flush_block_commit_notembedded.result15
-rw-r--r--mysql-test/r/flush_table.result17
-rw-r--r--mysql-test/r/handler_innodb.result958
-rw-r--r--mysql-test/r/handler_myisam.result956
-rw-r--r--mysql-test/r/implicit_commit.result1061
-rw-r--r--mysql-test/r/information_schema.result77
-rw-r--r--mysql-test/r/innodb-lock.result39
-rw-r--r--mysql-test/r/innodb.result3
-rw-r--r--mysql-test/r/innodb_mysql.result3
-rw-r--r--mysql-test/r/innodb_mysql_lock.result88
-rw-r--r--mysql-test/r/innodb_mysql_sync.result26
-rw-r--r--mysql-test/r/kill.result103
-rw-r--r--mysql-test/r/lock.result276
-rw-r--r--mysql-test/r/lock_multi.result255
-rw-r--r--mysql-test/r/lock_sync.result30
-rw-r--r--mysql-test/r/lowercase_table2.result16
-rw-r--r--mysql-test/r/mdl_sync.result2377
-rw-r--r--mysql-test/r/merge.result426
-rw-r--r--mysql-test/r/merge_recover.result103
-rw-r--r--mysql-test/r/mix2_myisam.result2
-rw-r--r--mysql-test/r/mysqld--help-notwin.result9
-rw-r--r--mysql-test/r/mysqld--help-win.result9
-rw-r--r--mysql-test/r/not_embedded_server.result16
-rw-r--r--mysql-test/r/partition.result9
-rw-r--r--mysql-test/r/partition_column_prune.result6
-rw-r--r--mysql-test/r/partition_innodb.result44
-rw-r--r--mysql-test/r/partition_innodb_semi_consistent.result2
-rw-r--r--mysql-test/r/partition_pruning.result2
-rw-r--r--mysql-test/r/partition_sync.result32
-rw-r--r--mysql-test/r/ps.result28
-rw-r--r--mysql-test/r/ps_ddl.result95
-rw-r--r--mysql-test/r/ps_ddl1.result2
-rw-r--r--mysql-test/r/repair.result26
-rw-r--r--mysql-test/r/schema.result36
-rw-r--r--mysql-test/r/sp-error.result13
-rw-r--r--mysql-test/r/sp-lock.result697
-rw-r--r--mysql-test/r/sp-threads.result2
-rw-r--r--mysql-test/r/sp.result65
-rw-r--r--mysql-test/r/trigger.result20
-rw-r--r--mysql-test/r/truncate.result101
-rw-r--r--mysql-test/r/truncate_coverage.result73
-rw-r--r--mysql-test/r/variables.result4
-rw-r--r--mysql-test/r/view.result42
-rw-r--r--mysql-test/r/view_grant.result4
-rw-r--r--mysql-test/suite/binlog/r/binlog_row_drop_tbl.result16
-rw-r--r--mysql-test/suite/binlog/r/binlog_row_mix_innodb_myisam.result1
-rw-r--r--mysql-test/suite/binlog/r/binlog_stm_drop_tbl.result15
-rw-r--r--mysql-test/suite/binlog/r/binlog_stm_mix_innodb_myisam.result1
-rw-r--r--mysql-test/suite/binlog/t/binlog_row_drop_tbl.test5
-rw-r--r--mysql-test/suite/binlog/t/binlog_stm_drop_tbl.test5
-rw-r--r--mysql-test/suite/binlog/t/binlog_stm_row.test2
-rw-r--r--mysql-test/suite/funcs_1/datadict/processlist_val.inc10
-rw-r--r--mysql-test/suite/funcs_1/r/processlist_val_no_prot.result6
-rw-r--r--mysql-test/suite/funcs_1/r/processlist_val_ps.result6
-rw-r--r--mysql-test/suite/ndb/r/ndb_index_ordered.result15
-rw-r--r--mysql-test/suite/ndb/t/disabled.def1
-rw-r--r--mysql-test/suite/ndb/t/ndb_index_ordered.test36
-rw-r--r--mysql-test/suite/parts/r/partition_special_innodb.result6
-rw-r--r--mysql-test/suite/parts/t/partition_special_innodb.test4
-rw-r--r--mysql-test/suite/rpl/r/rpl_mixed_row_innodb.result45
-rw-r--r--mysql-test/suite/rpl/r/rpl_sp.result45
-rw-r--r--mysql-test/suite/rpl/r/rpl_stm_innodb.result45
-rw-r--r--mysql-test/suite/rpl/r/rpl_stm_loadfile.result2
-rw-r--r--mysql-test/suite/rpl/r/rpl_trigger.result2
-rw-r--r--mysql-test/suite/rpl/r/rpl_view_multi.result90
-rw-r--r--mysql-test/suite/rpl/t/disabled.def2
-rw-r--r--mysql-test/suite/rpl/t/rpl_killed_ddl.test7
-rw-r--r--mysql-test/suite/rpl/t/rpl_sp.test61
-rw-r--r--mysql-test/suite/rpl/t/rpl_view_multi.test145
-rw-r--r--mysql-test/suite/rpl_ndb/r/rpl_ndb_binlog_format_errors.result4
-rw-r--r--mysql-test/suite/rpl_ndb/t/rpl_ndb_binlog_format_errors.test4
-rw-r--r--mysql-test/suite/sys_vars/r/autocommit_func.result2
-rw-r--r--mysql-test/suite/sys_vars/r/concurrent_insert_func.result4
-rw-r--r--mysql-test/suite/sys_vars/r/delayed_insert_limit_func.result8
-rw-r--r--mysql-test/suite/sys_vars/r/lock_wait_timeout_basic.result177
-rw-r--r--mysql-test/suite/sys_vars/r/query_cache_wlock_invalidate_func.result13
-rw-r--r--mysql-test/suite/sys_vars/r/sql_low_priority_updates_func.result6
-rw-r--r--mysql-test/suite/sys_vars/r/table_lock_wait_timeout_basic.result98
-rw-r--r--mysql-test/suite/sys_vars/t/autocommit_func.test4
-rw-r--r--mysql-test/suite/sys_vars/t/concurrent_insert_func.test4
-rw-r--r--mysql-test/suite/sys_vars/t/delayed_insert_limit_func.test12
-rw-r--r--mysql-test/suite/sys_vars/t/lock_wait_timeout_basic.test213
-rw-r--r--mysql-test/suite/sys_vars/t/query_cache_wlock_invalidate_func.test13
-rw-r--r--mysql-test/suite/sys_vars/t/rpl_semi_sync_master_enabled_basic.test1
-rw-r--r--mysql-test/suite/sys_vars/t/rpl_semi_sync_master_timeout_basic.test1
-rw-r--r--mysql-test/suite/sys_vars/t/rpl_semi_sync_master_trace_level_basic.test1
-rw-r--r--mysql-test/suite/sys_vars/t/rpl_semi_sync_master_wait_no_slave_basic.test1
-rw-r--r--mysql-test/suite/sys_vars/t/rpl_semi_sync_slave_enabled_basic.test1
-rw-r--r--mysql-test/suite/sys_vars/t/rpl_semi_sync_slave_trace_level_basic.test1
-rw-r--r--mysql-test/suite/sys_vars/t/sql_low_priority_updates_func.test14
-rw-r--r--mysql-test/suite/sys_vars/t/table_lock_wait_timeout_basic.test171
-rw-r--r--mysql-test/t/create.test38
-rw-r--r--mysql-test/t/debug_sync.test2
-rw-r--r--mysql-test/t/delayed.test2
-rw-r--r--mysql-test/t/disabled.def3
-rw-r--r--mysql-test/t/drop.test2
-rw-r--r--mysql-test/t/drop_debug.test3
-rw-r--r--mysql-test/t/flush.test35
-rw-r--r--mysql-test/t/flush_block_commit.test33
-rw-r--r--mysql-test/t/flush_block_commit_notembedded.test27
-rw-r--r--mysql-test/t/flush_table.test25
-rw-r--r--mysql-test/t/implicit_commit.test1162
-rw-r--r--mysql-test/t/information_schema.test93
-rw-r--r--mysql-test/t/innodb-lock.test49
-rw-r--r--mysql-test/t/innodb.test10
-rw-r--r--mysql-test/t/innodb_mysql_lock-master.opt1
-rw-r--r--mysql-test/t/innodb_mysql_lock.test175
-rw-r--r--mysql-test/t/innodb_mysql_sync.test48
-rw-r--r--mysql-test/t/insert_notembedded.test2
-rw-r--r--mysql-test/t/kill.test237
-rw-r--r--mysql-test/t/lock.test335
-rw-r--r--mysql-test/t/lock_multi.test498
-rw-r--r--mysql-test/t/lock_sync.test71
-rw-r--r--mysql-test/t/lowercase_table2.test14
-rw-r--r--mysql-test/t/mdl_sync.test3468
-rw-r--r--mysql-test/t/merge-big.test4
-rw-r--r--mysql-test/t/merge.test445
-rw-r--r--mysql-test/t/merge_recover-master.opt1
-rw-r--r--mysql-test/t/merge_recover.test113
-rw-r--r--mysql-test/t/multi_update.test11
-rw-r--r--mysql-test/t/not_embedded_server.test23
-rw-r--r--mysql-test/t/partition.test13
-rw-r--r--mysql-test/t/partition_innodb-master.opt1
-rw-r--r--mysql-test/t/partition_innodb.test2
-rw-r--r--mysql-test/t/partition_innodb_semi_consistent.test2
-rw-r--r--mysql-test/t/partition_sync.test52
-rw-r--r--mysql-test/t/ps.test41
-rw-r--r--mysql-test/t/ps_ddl.test83
-rw-r--r--mysql-test/t/ps_ddl1.test2
-rw-r--r--mysql-test/t/query_cache_28249.test6
-rw-r--r--mysql-test/t/read_only_innodb.test2
-rw-r--r--mysql-test/t/repair.test30
-rw-r--r--mysql-test/t/schema.test93
-rw-r--r--mysql-test/t/sp-error.test32
-rw-r--r--mysql-test/t/sp-lock.test898
-rw-r--r--mysql-test/t/sp.test85
-rw-r--r--mysql-test/t/sp_notembedded.test2
-rw-r--r--mysql-test/t/sp_sync.test2
-rw-r--r--mysql-test/t/status.test2
-rw-r--r--mysql-test/t/trigger.test25
-rw-r--r--mysql-test/t/trigger_notembedded.test2
-rw-r--r--mysql-test/t/truncate.test96
-rw-r--r--mysql-test/t/truncate_coverage.test164
-rw-r--r--mysql-test/t/variables.test4
-rw-r--r--mysql-test/t/view.test47
-rw-r--r--mysql-test/t/view_grant.test4
-rw-r--r--mysql-test/t/xa.test3
164 files changed, 18505 insertions, 836 deletions
diff --git a/mysql-test/extra/binlog_tests/drop_table.test b/mysql-test/extra/binlog_tests/drop_table.test
new file mode 100644
index 00000000000..c55cbb67560
--- /dev/null
+++ b/mysql-test/extra/binlog_tests/drop_table.test
@@ -0,0 +1,34 @@
+#
+# Bug#989: If DROP TABLE while there's an active transaction, wrong binlog order
+#
+
+--disable_warnings
+DROP TABLE IF EXISTS t1;
+--enable_warnings
+
+connect (con1,localhost,root,,);
+connect (con2,localhost,root,,);
+
+connection con1;
+RESET MASTER;
+CREATE TABLE t1 (a INT);
+SET AUTOCOMMIT=OFF;
+BEGIN;
+INSERT INTO t1 VALUES(1);
+
+connection con2;
+--send DROP TABLE t1;
+
+connection con1;
+COMMIT;
+
+connection con2;
+--reap
+
+connection default;
+
+--disconnect con1
+--disconnect con2
+
+let $VERSION=`select version()`;
+source include/show_binlog_events.inc;
diff --git a/mysql-test/extra/binlog_tests/mix_innodb_myisam_binlog.test b/mysql-test/extra/binlog_tests/mix_innodb_myisam_binlog.test
index 4abf21a9930..e59438c9a28 100644
--- a/mysql-test/extra/binlog_tests/mix_innodb_myisam_binlog.test
+++ b/mysql-test/extra/binlog_tests/mix_innodb_myisam_binlog.test
@@ -205,6 +205,10 @@ select (@after:=unix_timestamp())*0; # always give repeatable output
# the bug, the reap would return immediately after the insert into t2.
select (@after-@before) >= 2;
+connection con3;
+commit;
+
+connection con2;
drop table t1,t2;
commit;
diff --git a/mysql-test/extra/rpl_tests/rpl_innodb.test b/mysql-test/extra/rpl_tests/rpl_innodb.test
index c866b68466d..5bea93a0192 100644
--- a/mysql-test/extra/rpl_tests/rpl_innodb.test
+++ b/mysql-test/extra/rpl_tests/rpl_innodb.test
@@ -118,6 +118,71 @@ connection master;
FLUSH LOGS;
DROP DATABASE mysqltest1;
--- source include/master-slave-end.inc
--echo End of 5.1 tests
+
+--echo #
+--echo # Bug#39675 rename tables on innodb tables with pending
+--echo # transactions causes slave data issue.
+--echo #
+
+--disable_warnings
+DROP TABLE IF EXISTS t1;
+DROP TABLE IF EXISTS t2;
+DROP TABLE IF EXISTS t3;
+--enable_warnings
+
+CREATE TABLE t1 (
+ id INT PRIMARY KEY auto_increment,
+ b INT DEFAULT NULL
+) ENGINE=InnoDB;
+
+CREATE TABLE t2 (
+ id INT PRIMARY KEY auto_increment,
+ b INT DEFAULT NULL
+) ENGINE=InnoDB;
+
+INSERT INTO t1 (b) VALUES (1),(2),(3);
+
+BEGIN;
+INSERT INTO t1(b) VALUES (4);
+
+--echo -------- switch to master1 --------
+connection master1;
+--send RENAME TABLE t1 TO t3, t2 TO t1;
+
+--echo -------- switch to master --------
+connection master;
+# Need to wait until RENAME is received
+let $wait_condition=
+ SELECT COUNT(*) = 1 FROM information_schema.processlist
+ WHERE info = "RENAME TABLE t1 TO t3, t2 TO t1" and
+ state = "Waiting for table";
+--source include/wait_condition.inc
+
+COMMIT;
+
+--echo -------- switch to master1 --------
+connection master1;
+--reap
+
+--echo -------- switch to master --------
+connection master;
+SELECT * FROM t1;
+SELECT * FROM t3;
+
+sync_slave_with_master;
+
+--echo -------- switch to slave --------
+connection slave;
+SELECT * FROM t1;
+SELECT * FROM t3;
+
+--echo -------- switch to master --------
+connection master;
+DROP TABLE t1;
+DROP TABLE t3;
+
+--echo End of 6.0 tests
+
+--source include/master-slave-end.inc
diff --git a/mysql-test/include/commit.inc b/mysql-test/include/commit.inc
index 4336d3be0ed..59d4f6be524 100644
--- a/mysql-test/include/commit.inc
+++ b/mysql-test/include/commit.inc
@@ -729,15 +729,15 @@ call p_verify_status_increment(2, 0, 4, 4);
alter table t3 add column (b int);
call p_verify_status_increment(2, 0, 2, 0);
alter table t3 rename t4;
-call p_verify_status_increment(1, 0, 1, 0);
+call p_verify_status_increment(2, 0, 2, 0);
rename table t4 to t3;
-call p_verify_status_increment(1, 0, 1, 0);
+call p_verify_status_increment(0, 0, 0, 0);
truncate table t3;
call p_verify_status_increment(2, 0, 2, 0);
create view v1 as select * from t2;
-call p_verify_status_increment(1, 0, 1, 0);
+call p_verify_status_increment(2, 0, 2, 0);
check table t1;
-call p_verify_status_increment(3, 0, 3, 0);
+call p_verify_status_increment(2, 0, 2, 0);
--echo # Sic: after this bug is fixed, CHECK leaves no pending transaction
commit;
call p_verify_status_increment(0, 0, 0, 0);
diff --git a/mysql-test/include/handler.inc b/mysql-test/include/handler.inc
index 6e7f53ba9b2..4b2e64e3bb5 100644
--- a/mysql-test/include/handler.inc
+++ b/mysql-test/include/handler.inc
@@ -518,12 +518,15 @@ connect (flush,localhost,root,,);
connection flush;
--echo connection: flush
--send flush tables;
-connection default;
---echo connection: default
+connect (waiter,localhost,root,,);
+connection waiter;
+--echo connection: waiter
let $wait_condition=
select count(*) = 1 from information_schema.processlist
where state = "Flushing tables";
--source include/wait_condition.inc
+connection default;
+--echo connection: default
handler t2 open;
handler t2 read first;
handler t1 read next;
@@ -540,7 +543,7 @@ disconnect flush;
#
--disable_warnings
-drop table if exists t1,t2;
+drop table if exists t1, t0;
--enable_warnings
create table t1 (c1 int);
--echo connection: default
@@ -549,24 +552,47 @@ handler t1 read first;
connect (flush,localhost,root,,);
connection flush;
--echo connection: flush
---send rename table t1 to t2;
-connection default;
---echo connection: default
+--send rename table t1 to t0;
+connection waiter;
+--echo connection: waiter
let $wait_condition=
select count(*) = 1 from information_schema.processlist
- where state = "Waiting for table" and info = "rename table t1 to t2";
+ where state = "Waiting for table" and info = "rename table t1 to t0";
--source include/wait_condition.inc
-handler t2 open;
-handler t2 read first;
---error ER_NO_SUCH_TABLE
-handler t1 read next;
-handler t1 close;
-handler t2 close;
+connection default;
+--echo connection: default
+--echo #
+--echo # RENAME placed two pending locks and waits.
+--echo # When HANDLER t0 OPEN does open_tables(), it calls
+--echo # mysql_ha_flush(), which in turn closes the open HANDLER for t1.
+--echo # RENAME TABLE gets unblocked. If it gets scheduled quickly
+--echo # and manages to complete before open_tables()
+--echo # of HANDLER t0 OPEN, open_tables() and therefore the whole
+--echo # HANDLER t0 OPEN succeeds. Otherwise open_tables()
+--echo # notices a pending or active exclusive metadata lock on t2
+--echo # and the whole HANDLER t0 OPEN fails with ER_LOCK_DEADLOCK
+--echo # error.
+--echo #
+--error 0, ER_LOCK_DEADLOCK
+handler t0 open;
+--error 0, ER_UNKNOWN_TABLE
+handler t0 close;
+--echo connection: flush
connection flush;
reap;
+--error ER_UNKNOWN_TABLE
+handler t1 read next;
+--error ER_UNKNOWN_TABLE
+handler t1 close;
connection default;
-drop table t2;
+drop table t0;
+connection flush;
disconnect flush;
+--source include/wait_until_disconnected.inc
+connection waiter;
+disconnect waiter;
+--source include/wait_until_disconnected.inc
+connection default;
#
# Bug#30882 Dropping a temporary table inside a stored function may cause a server crash
@@ -699,27 +725,61 @@ handler t1 read a next;
# Bug#41112: crash in mysql_ha_close_table/get_lock_data with alter table
#
+connect(con1,localhost,root,,);
+connect(con2,localhost,root,,);
+
+connection default;
--disable_warnings
drop table if exists t1;
--enable_warnings
+--echo # First test case which is supposed trigger the execution
+--echo # path on which problem was discovered.
create table t1 (a int);
insert into t1 values (1);
handler t1 open;
-connect(con1,localhost,root,,);
+connection con1;
+lock table t1 write;
send alter table t1 engine=memory;
-connection default;
+connection con2;
let $wait_condition=
select count(*) = 1 from information_schema.processlist
- where state = "rename result table" and info = "alter table t1 engine=memory";
+ where state = "Waiting for table" and info = "alter table t1 engine=memory";
--source include/wait_condition.inc
+connection default;
--error ER_ILLEGAL_HA
handler t1 read a next;
handler t1 close;
connection con1;
--reap
+unlock tables;
+drop table t1;
+--echo # Now test case which was reported originally but which no longer
+--echo # triggers execution path which has caused the problem.
+connection default;
+create table t1 (a int, key(a));
+insert into t1 values (1);
+handler t1 open;
+connection con1;
+send alter table t1 engine=memory;
+connection con2;
+let $wait_condition=
+ select count(*) = 1 from information_schema.processlist
+ where state = "Waiting for table" and info = "alter table t1 engine=memory";
+--source include/wait_condition.inc
+connection default;
+--echo # Since S metadata lock was already acquired at HANDLER OPEN time
+--echo # and TL_READ lock requested by HANDLER READ is compatible with
+--echo # ALTER's TL_WRITE_ALLOW_READ the below statement should succeed
+--echo # without waiting. The old version of table should be used in it.
+handler t1 read a next;
+handler t1 close;
+connection con1;
drop table t1;
disconnect con1;
--source include/wait_until_disconnected.inc
+connection con2;
+disconnect con2;
+--source include/wait_until_disconnected.inc
connection default;
#
@@ -729,3 +789,917 @@ USE information_schema;
--error ER_WRONG_USAGE
HANDLER COLUMNS OPEN;
USE test;
+
+--echo #
+--echo # Add test coverage for HANDLER and LOCK TABLES, HANDLER and DDL.
+--echo #
+--disable_warnings
+drop table if exists t1, t2, t3;
+--enable_warnings
+create table t1 (a int, key a (a));
+insert into t1 (a) values (1), (2), (3), (4), (5);
+create table t2 (a int, key a (a)) select * from t1;
+create temporary table t3 (a int, key a (a)) select * from t2;
+handler t1 open;
+handler t2 open;
+handler t3 open;
+--echo #
+--echo # No HANDLER sql is allowed under LOCK TABLES.
+--echo # But it does not implicitly closes all handlers.
+--echo #
+lock table t1 read;
+--error ER_LOCK_OR_ACTIVE_TRANSACTION
+handler t1 open;
+--error ER_LOCK_OR_ACTIVE_TRANSACTION
+handler t1 read next;
+--error ER_LOCK_OR_ACTIVE_TRANSACTION
+handler t2 close;
+--error ER_LOCK_OR_ACTIVE_TRANSACTION
+handler t3 open;
+--echo # After UNLOCK TABLES handlers should be around and
+--echo # we should be able to continue reading through them.
+unlock tables;
+handler t1 read next;
+handler t1 close;
+handler t2 read next;
+handler t2 close;
+handler t3 read next;
+handler t3 close;
+drop temporary table t3;
+--echo #
+--echo # Other operations that implicitly close handler:
+--echo #
+--echo # TRUNCATE
+--echo #
+handler t1 open;
+truncate table t1;
+--error ER_UNKNOWN_TABLE
+handler t1 read next;
+handler t1 open;
+--echo #
+--echo # CREATE TRIGGER
+--echo #
+create trigger t1_ai after insert on t1 for each row set @a=1;
+--error ER_UNKNOWN_TABLE
+handler t1 read next;
+--echo #
+--echo # DROP TRIGGER
+--echo #
+handler t1 open;
+drop trigger t1_ai;
+--error ER_UNKNOWN_TABLE
+handler t1 read next;
+--echo #
+--echo # ALTER TABLE
+--echo #
+handler t1 open;
+alter table t1 add column b int;
+--error ER_UNKNOWN_TABLE
+handler t1 read next;
+--echo #
+--echo # ANALYZE TABLE
+--echo #
+handler t1 open;
+analyze table t1;
+--error ER_UNKNOWN_TABLE
+handler t1 read next;
+--echo #
+--echo # OPTIMIZE TABLE
+--echo #
+handler t1 open;
+optimize table t1;
+--error ER_UNKNOWN_TABLE
+handler t1 read next;
+--echo #
+--echo # REPAIR TABLE
+--echo #
+handler t1 open;
+repair table t1;
+--error ER_UNKNOWN_TABLE
+handler t1 read next;
+--echo #
+--echo # DROP TABLE, naturally.
+--echo #
+handler t1 open;
+drop table t1;
+--error ER_UNKNOWN_TABLE
+handler t1 read next;
+create table t1 (a int, b int, key a (a)) select a from t2;
+--echo #
+--echo # RENAME TABLE, naturally
+--echo #
+handler t1 open;
+rename table t1 to t3;
+--error ER_UNKNOWN_TABLE
+handler t1 read next;
+--echo #
+--echo # CREATE TABLE (even with IF NOT EXISTS clause,
+--echo # and the table exists).
+--echo #
+handler t2 open;
+create table if not exists t2 (a int);
+--error ER_UNKNOWN_TABLE
+handler t2 read next;
+rename table t3 to t1;
+drop table t2;
+--echo #
+--echo # FLUSH TABLE doesn't close the table but loses the position
+--echo #
+handler t1 open;
+handler t1 read a prev;
+flush table t1;
+handler t1 read a prev;
+handler t1 close;
+--echo #
+--echo # FLUSH TABLES WITH READ LOCK behaves like FLUSH TABLE.
+--echo #
+handler t1 open;
+handler t1 read a prev;
+flush tables with read lock;
+handler t1 read a prev;
+handler t1 close;
+unlock tables;
+--echo #
+--echo # Let us also check that these operations behave in similar
+--echo # way under LOCK TABLES.
+--echo #
+--echo # TRUNCATE under LOCK TABLES.
+--echo #
+handler t1 open;
+lock tables t1 write;
+truncate table t1;
+unlock tables;
+--error ER_UNKNOWN_TABLE
+handler t1 read next;
+handler t1 open;
+--echo #
+--echo # CREATE TRIGGER under LOCK TABLES.
+--echo #
+lock tables t1 write;
+create trigger t1_ai after insert on t1 for each row set @a=1;
+unlock tables;
+--error ER_UNKNOWN_TABLE
+handler t1 read next;
+--echo #
+--echo # DROP TRIGGER under LOCK TABLES.
+--echo #
+handler t1 open;
+lock tables t1 write;
+drop trigger t1_ai;
+unlock tables;
+--error ER_UNKNOWN_TABLE
+handler t1 read next;
+--echo #
+--echo # ALTER TABLE under LOCK TABLES.
+--echo #
+handler t1 open;
+lock tables t1 write;
+alter table t1 drop column b;
+unlock tables;
+--error ER_UNKNOWN_TABLE
+handler t1 read next;
+--echo #
+--echo # ANALYZE TABLE under LOCK TABLES.
+--echo #
+handler t1 open;
+lock tables t1 write;
+analyze table t1;
+unlock tables;
+--error ER_UNKNOWN_TABLE
+handler t1 read next;
+--echo #
+--echo # OPTIMIZE TABLE under LOCK TABLES.
+--echo #
+handler t1 open;
+lock tables t1 write;
+optimize table t1;
+unlock tables;
+--error ER_UNKNOWN_TABLE
+handler t1 read next;
+--echo #
+--echo # REPAIR TABLE under LOCK TABLES.
+--echo #
+handler t1 open;
+lock tables t1 write;
+repair table t1;
+unlock tables;
+--error ER_UNKNOWN_TABLE
+handler t1 read next;
+--echo #
+--echo # DROP TABLE under LOCK TABLES, naturally.
+--echo #
+handler t1 open;
+lock tables t1 write;
+drop table t1;
+unlock tables;
+--error ER_UNKNOWN_TABLE
+handler t1 read next;
+create table t1 (a int, b int, key a (a));
+insert into t1 (a) values (1), (2), (3), (4), (5);
+--echo #
+--echo # FLUSH TABLE doesn't close the table but loses the position
+--echo #
+handler t1 open;
+handler t1 read a prev;
+lock tables t1 write;
+flush table t1;
+unlock tables;
+handler t1 read a prev;
+handler t1 close;
+--echo #
+--echo # Explore the effect of HANDLER locks on concurrent DDL
+--echo #
+handler t1 open;
+--echo # Establishing auxiliary connections con1, con2, con3
+connect(con1, localhost, root,,);
+connect(con2, localhost, root,,);
+connect(con3, localhost, root,,);
+--echo # --> connection con1;
+connection con1;
+--echo # Sending:
+--send drop table t1
+--echo # We can't use connection 'default' as wait_condition will
+--echo # autoclose handlers.
+--echo # --> connection con2
+connection con2;
+--echo # Waitng for 'drop table t1' to get blocked...
+let $wait_condition=select count(*)=1 from information_schema.processlist where state='Waiting for table' and info='drop table t1';
+--source include/wait_condition.inc
+--echo # --> connection default
+connection default;
+handler t1 read a prev;
+handler t1 read a prev;
+handler t1 close;
+--echo # --> connection con1
+connection con1;
+--echo # Reaping 'drop table t1'...
+--reap
+--echo # --> connection default
+connection default;
+--echo #
+--echo # Explore the effect of HANDLER locks in parallel with SELECT
+--echo #
+create table t1 (a int, key a (a));
+insert into t1 (a) values (1), (2), (3), (4), (5);
+begin;
+select * from t1;
+handler t1 open;
+handler t1 read a prev;
+handler t1 read a prev;
+handler t1 close;
+--echo # --> connection con1;
+connection con1;
+--echo # Sending:
+--send drop table t1
+--echo # --> connection con2
+connection con2;
+--echo # Waiting for 'drop table t1' to get blocked...
+let $wait_condition=select count(*)=1 from information_schema.processlist where state='Waiting for table' and info='drop table t1';
+--source include/wait_condition.inc
+--echo # --> connection default
+connection default;
+--echo # We can still use the table, it's part of the transaction
+select * from t1;
+--echo # Such are the circumstances that t1 is a part of transaction,
+--echo # thus we can reopen it in the handler
+handler t1 open;
+--echo # We can commit the transaction, it doesn't close the handler
+--echo # and doesn't let DROP to proceed.
+commit;
+handler t1 read a prev;
+handler t1 read a prev;
+handler t1 read a prev;
+handler t1 close;
+--echo # --> connection con1
+connection con1;
+--echo # Now drop can proceed
+--echo # Reaping 'drop table t1'...
+--reap
+--echo # --> connection default
+connection default;
+--echo #
+--echo # Demonstrate that HANDLER locks and transaction locks
+--echo # reside in the same context, and we don't back-off
+--echo # when have transaction or handler locks.
+--echo #
+create table t1 (a int, key a (a));
+insert into t1 (a) values (1), (2), (3), (4), (5);
+create table t0 (a int, key a (a));
+insert into t0 (a) values (1), (2), (3), (4), (5);
+begin;
+select * from t1;
+--echo # --> connection con2
+connection con2;
+--echo # Sending:
+send rename table t0 to t3, t1 to t0, t3 to t1;
+--echo # --> connection con1
+connection con1;
+--echo # Waiting for 'rename table ...' to get blocked...
+let $wait_condition=select count(*)=1 from information_schema.processlist
+where state='Waiting for table' and info='rename table t0 to t3, t1 to t0, t3 to t1';
+--source include/wait_condition.inc
+--echo # --> connection default
+connection default;
+--error ER_LOCK_DEADLOCK
+handler t0 open;
+--error ER_LOCK_DEADLOCK
+select * from t0;
+handler t1 open;
+commit;
+handler t1 close;
+--echo # --> connection con2
+connection con2;
+--echo # Reaping 'rename table ...'...
+--reap
+--echo # --> connection default
+connection default;
+handler t1 open;
+handler t1 read a prev;
+handler t1 close;
+drop table t0;
+--echo #
+--echo # Originally there was a deadlock error in this test.
+--echo # With implementation of deadlock detector
+--echo # we no longer deadlock, but block and wait on a lock.
+--echo # The HANDLER is auto-closed as soon as the connection
+--echo # sees a pending conflicting lock against it.
+--echo #
+create table t2 (a int, key a (a));
+handler t1 open;
+--echo # --> connection con1
+connection con1;
+lock tables t2 read;
+--echo # --> connection con2
+connection con2;
+--echo # Sending 'drop table t2'...
+--send drop table t2
+--echo # --> connection con1
+connection con1;
+--echo # Waiting for 'drop table t2' to get blocked...
+let $wait_condition=select count(*)=1 from information_schema.processlist where state='Waiting for table' and info='drop table t2';
+--source include/wait_condition.inc
+--echo # --> connection default
+connection default;
+--echo # Sending 'select * from t2'
+send select * from t2;
+--echo # --> connection con1
+connection con1;
+--echo # Waiting for 'select * from t2' to get blocked...
+let $wait_condition=select count(*)=1 from information_schema.processlist where state='Waiting for table' and info='select * from t2';
+unlock tables;
+--echo # --> connection con2
+connection con2;
+--echo # Reaping 'drop table t2'...
+--reap
+--echo # --> connection default
+connection default;
+--echo # Reaping 'select * from t2'
+--error ER_NO_SUCH_TABLE
+reap;
+handler t1 close;
+
+--echo #
+--echo # ROLLBACK TO SAVEPOINT releases transactional locks,
+--echo # but has no effect on open HANDLERs
+--echo #
+create table t2 like t1;
+create table t3 like t1;
+begin;
+--echo # Have something before the savepoint
+select * from t3;
+savepoint sv;
+handler t1 open;
+handler t1 read a first;
+handler t1 read a next;
+select * from t2;
+--echo # --> connection con1
+connection con1;
+--echo # Sending:
+--send drop table t1
+--echo # --> connection con2
+connection con2;
+--echo # Sending:
+--send drop table t2
+--echo # --> connection default
+connection default;
+--echo # Let DROP TABLE statements sync in. We must use
+--echo # a separate connection for that, because otherwise SELECT
+--echo # will auto-close the HANDLERs, becaues there are pending
+--echo # exclusive locks against them.
+--echo # --> connection con3
+connection con3;
+--echo # Waiting for 'drop table t1' to get blocked...
+let $wait_condition=select count(*)=1 from information_schema.processlist where state='Waiting for table' and info='drop table t1';
+--source include/wait_condition.inc
+--echo # Waiting for 'drop table t2' to get blocked...
+let $wait_condition=select count(*)=1 from information_schema.processlist where state='Waiting for table' and info='drop table t2';
+--source include/wait_condition.inc
+--echo # Demonstrate that t2 lock was released and t2 was dropped
+--echo # after ROLLBACK TO SAVEPOINT
+--echo # --> connection default
+connection default;
+rollback to savepoint sv;
+--echo # --> connection con2
+connection con2;
+--echo # Reaping 'drop table t2'...
+--reap
+--echo # Demonstrate that ROLLBACK TO SAVEPOINT didn't release the handler
+--echo # lock.
+--echo # --> connection default
+connection default;
+handler t1 read a next;
+handler t1 read a next;
+--echo # Demonstrate that the drop will go through as soon as we close the
+--echo # HANDLER
+handler t1 close;
+--echo # connection con1
+connection con1;
+--echo # Reaping 'drop table t1'...
+--reap
+--echo # --> connection default
+connection default;
+commit;
+drop table t3;
+--echo #
+--echo # A few special cases when using SAVEPOINT/ROLLBACK TO
+--echo # SAVEPOINT and HANDLER.
+--echo #
+--echo # Show that rollback to the savepoint taken in the beginning
+--echo # of the transaction doesn't release mdl lock on
+--echo # the HANDLER that was opened later.
+--echo #
+create table t1 (a int, key a(a));
+insert into t1 (a) values (1), (2), (3), (4), (5);
+create table t2 like t1;
+begin;
+savepoint sv;
+handler t1 open;
+handler t1 read a first;
+handler t1 read a next;
+select * from t2;
+--echo # --> connection con1
+connection con1;
+--echo # Sending:
+--send drop table t1
+--echo # --> connection con2
+connection con2;
+--echo # Sending:
+--send drop table t2
+--echo # --> connection default
+connection default;
+--echo # Let DROP TABLE statements sync in. We must use
+--echo # a separate connection for that, because otherwise SELECT
+--echo # will auto-close the HANDLERs, becaues there are pending
+--echo # exclusive locks against them.
+--echo # --> connection con3
+connection con3;
+--echo # Waiting for 'drop table t1' to get blocked...
+let $wait_condition=select count(*)=1 from information_schema.processlist where state='Waiting for table' and info='drop table t1';
+--source include/wait_condition.inc
+--echo # Waiting for 'drop table t2' to get blocked...
+let $wait_condition=select count(*)=1 from information_schema.processlist where state='Waiting for table' and info='drop table t2';
+--source include/wait_condition.inc
+--echo # Demonstrate that t2 lock was released and t2 was dropped
+--echo # after ROLLBACK TO SAVEPOINT
+--echo # --> connection default
+connection default;
+rollback to savepoint sv;
+--echo # --> connection con2
+connection con2;
+--echo # Reaping 'drop table t2'...
+--reap
+--echo # Demonstrate that ROLLBACK TO SAVEPOINT didn't release the handler
+--echo # lock.
+--echo # --> connection default
+connection default;
+handler t1 read a next;
+handler t1 read a next;
+--echo # Demonstrate that the drop will go through as soon as we close the
+--echo # HANDLER
+handler t1 close;
+--echo # connection con1
+connection con1;
+--echo # Reaping 'drop table t1'...
+--reap
+--echo # --> connection default
+connection default;
+commit;
+--echo #
+--echo # Show that rollback to the savepoint taken in the beginning
+--echo # of the transaction works properly (no valgrind warnins, etc),
+--echo # even though it's done after the HANDLER mdl lock that was there
+--echo # at the beginning is released and added again.
+--echo #
+create table t1 (a int, key a(a));
+insert into t1 (a) values (1), (2), (3), (4), (5);
+create table t2 like t1;
+create table t3 like t1;
+insert into t3 (a) select a from t1;
+begin;
+handler t1 open;
+savepoint sv;
+handler t1 read a first;
+select * from t2;
+handler t1 close;
+handler t3 open;
+handler t3 read a first;
+rollback to savepoint sv;
+--echo # --> connection con1
+connection con1;
+drop table t1, t2;
+--echo # Sending:
+--send drop table t3
+--echo # Let DROP TABLE statement sync in.
+--echo # --> connection con2
+connection con2;
+--echo # Waiting for 'drop table t3' to get blocked...
+let $wait_condition=select count(*)=1 from information_schema.processlist where state='Waiting for table' and info='drop table t3';
+--source include/wait_condition.inc
+--echo # Demonstrate that ROLLBACK TO SAVEPOINT didn't release the handler
+--echo # lock.
+--echo # --> connection default
+connection default;
+handler t3 read a next;
+--echo # Demonstrate that the drop will go through as soon as we close the
+--echo # HANDLER
+handler t3 close;
+--echo # connection con1
+connection con1;
+--echo # Reaping 'drop table t3'...
+--reap
+--echo # --> connection default
+connection default;
+commit;
+
+--echo #
+--echo # If we have to wait on an exclusive locks while having
+--echo # an open HANDLER, ER_LOCK_DEADLOCK is reported.
+--echo #
+create table t1 (a int, key a(a));
+create table t2 like t1;
+handler t1 open;
+--echo # --> connection con1
+connection con1;
+lock table t1 write, t2 write;
+--echo # --> connection default
+connection default;
+send drop table t2;
+--echo # --> connection con2
+connection con2;
+--echo # Waiting for 'drop table t2' to get blocked...
+let $wait_condition=select count(*)=1 from information_schema.processlist where state='Waiting for table' and info='drop table t2';
+--source include/wait_condition.inc
+--echo # --> connection con1
+connection con1;
+--error ER_LOCK_DEADLOCK
+drop table t1;
+unlock tables;
+--echo # --> connection default
+connection default;
+reap;
+
+--echo # Demonstrate that there is no deadlock with FLUSH TABLE,
+--echo # even though it is waiting for the other table to go away
+create table t2 like t1;
+--echo # Sending:
+--send flush table t2
+--echo # --> connection con2
+connection con2;
+drop table t1;
+--echo # --> connection con1
+connection con1;
+unlock tables;
+--echo # --> connection default
+connection default;
+--echo # Reaping 'flush table t2'...
+--reap
+drop table t2;
+
+--echo #
+--echo # Bug #46224 HANDLER statements within a transaction might
+--echo # lead to deadlocks
+--echo #
+create table t1 (a int, key a(a));
+insert into t1 values (1), (2);
+
+--echo # --> connection default
+connection default;
+begin;
+select * from t1;
+handler t1 open;
+
+--echo # --> connection con1
+connection con1;
+--echo # Sending:
+--send lock tables t1 write
+
+--echo # --> connection con2
+connection con2;
+--echo # Check that 'lock tables t1 write' waits until transaction which
+--echo # has read from the table commits.
+let $wait_condition=
+ select count(*) = 1 from information_schema.processlist
+ where state = "Waiting for table" and info = "lock tables t1 write";
+--source include/wait_condition.inc
+
+--echo # --> connection default
+connection default;
+--echo # The below 'handler t1 read ...' should not be blocked as
+--echo # 'lock tables t1 write' has not succeeded yet.
+handler t1 read a next;
+
+--echo # Unblock 'lock tables t1 write'.
+commit;
+
+--echo # --> connection con1
+connection con1;
+--echo # Reap 'lock tables t1 write'.
+--reap
+
+--echo # --> connection default
+connection default;
+--echo # Sending:
+--send handler t1 read a next
+
+--echo # --> connection con1
+connection con1;
+--echo # Waiting for 'handler t1 read a next' to get blocked...
+let $wait_condition=
+ select count(*) = 1 from information_schema.processlist
+ where state = "Table lock" and info = "handler t1 read a next";
+--source include/wait_condition.inc
+
+--echo # The below 'drop table t1' should be able to proceed without
+--echo # waiting as it will force HANDLER to be closed.
+drop table t1;
+unlock tables;
+
+--echo # --> connection default
+connection default;
+--echo # Reaping 'handler t1 read a next'...
+--error ER_NO_SUCH_TABLE
+--reap
+handler t1 close;
+
+--echo # --> connection con1
+connection con1;
+disconnect con1;
+--source include/wait_until_disconnected.inc
+--echo # --> connection con2
+connection con2;
+disconnect con2;
+--source include/wait_until_disconnected.inc
+--echo # --> connection con3
+connection con3;
+disconnect con3;
+--source include/wait_until_disconnected.inc
+connection default;
+
+--echo #
+--echo # A temporary table test.
+--echo # Check that we don't loose positions of HANDLER opened
+--echo # against a temporary table.
+--echo #
+create table t1 (a int, b int, key a (a));
+insert into t1 (a) values (1), (2), (3), (4), (5);
+create temporary table t2 (a int, b int, key a (a));
+insert into t2 (a) select a from t1;
+handler t1 open;
+handler t1 read a next;
+handler t2 open;
+handler t2 read a next;
+flush table t1;
+handler t2 read a next;
+--echo # Sic: the position is lost
+handler t1 read a next;
+select * from t1;
+--echo # Sic: the position is not lost
+handler t2 read a next;
+--error ER_CANT_REOPEN_TABLE
+select * from t2;
+handler t2 read a next;
+drop table t1;
+drop temporary table t2;
+
+--echo #
+--echo # A test for lock_table_names()/unlock_table_names() function.
+--echo # It should work properly in presence of open HANDLER.
+--echo #
+create table t1 (a int, b int, key a (a));
+create table t2 like t1;
+create table t3 like t1;
+create table t4 like t1;
+handler t1 open;
+handler t2 open;
+rename table t4 to t5, t3 to t4, t5 to t3;
+handler t1 read first;
+handler t2 read first;
+drop table t1, t2, t3, t4;
+
+--echo #
+--echo # A test for FLUSH TABLES WITH READ LOCK and HANDLER statements.
+--echo #
+set autocommit=0;
+create table t1 (a int, b int, key a (a));
+insert into t1 (a, b) values (1, 1), (2, 1), (3, 2), (4, 2), (5, 5);
+create table t2 like t1;
+insert into t2 (a, b) select a, b from t1;
+create table t3 like t1;
+insert into t3 (a, b) select a, b from t1;
+commit;
+flush tables with read lock;
+handler t1 open;
+lock table t1 read;
+--error ER_LOCK_OR_ACTIVE_TRANSACTION
+handler t1 read next;
+--echo # This implicitly leaves LOCK TABLES but doesn't drop the GLR
+--error ER_NO_SUCH_TABLE
+lock table not_exists_write read;
+--echo # We still have the read lock.
+--error ER_CANT_UPDATE_WITH_READLOCK
+drop table t1;
+handler t1 read next;
+handler t1 close;
+handler t1 open;
+select a from t2;
+handler t1 read next;
+flush tables with read lock;
+handler t2 open;
+flush tables with read lock;
+handler t1 read next;
+select a from t3;
+handler t2 read next;
+handler t1 close;
+rollback;
+handler t2 close;
+--error ER_CANT_UPDATE_WITH_READLOCK
+drop table t1;
+commit;
+flush tables;
+--error ER_CANT_UPDATE_WITH_READLOCK
+drop table t1;
+unlock tables;
+drop table t1;
+set autocommit=default;
+drop table t2, t3;
+
+--echo #
+--echo # HANDLER statement and operation-type aware metadata locks.
+--echo # Check that when we clone a ticket for HANDLER we downrade
+--echo # the lock.
+--echo #
+--echo # Establish an auxiliary connection con1.
+connect (con1,localhost,root,,);
+--echo # -> connection default
+connection default;
+create table t1 (a int, b int, key a (a));
+insert into t1 (a, b) values (1, 1), (2, 1), (3, 2), (4, 2), (5, 5);
+begin;
+insert into t1 (a, b) values (6, 6);
+handler t1 open;
+handler t1 read a last;
+insert into t1 (a, b) values (7, 7);
+handler t1 read a last;
+commit;
+--echo # -> connection con1
+connection con1;
+--echo # Demonstrate that the HANDLER doesn't hold MDL_SHARED_WRITE.
+lock table t1 write;
+unlock tables;
+--echo # -> connection default
+connection default;
+handler t1 read a prev;
+handler t1 close;
+--echo # Cleanup.
+drop table t1;
+--echo # -> connection con1
+connection con1;
+disconnect con1;
+--source include/wait_until_disconnected.inc
+--echo # -> connection default
+connection default;
+
+--echo #
+--echo # A test for Bug#50555 "handler commands crash server in
+--echo # my_hash_first()".
+--echo #
+--error ER_UNKNOWN_TABLE
+handler no_such_table read no_such_index first;
+--error ER_UNKNOWN_TABLE
+handler no_such_table close;
+
+
+--echo #
+--echo # Bug#50907 Assertion `hash_tables->table->next == __null' on
+--echo # HANDLER OPEN
+--echo #
+
+--disable_warnings
+DROP TABLE IF EXISTS t1, t2;
+--enable_warnings
+
+CREATE TEMPORARY TABLE t1 (i INT);
+CREATE TEMPORARY TABLE t2 (i INT);
+
+# This used to trigger the assert
+HANDLER t2 OPEN;
+
+# This also used to trigger the assert
+HANDLER t2 READ FIRST;
+
+HANDLER t2 CLOSE;
+DROP TABLE t1, t2;
+
+
+--echo #
+--echo # Bug#50912 Assertion `ticket->m_type >= mdl_request->type'
+--echo # failed on HANDLER + I_S
+--echo #
+
+--disable_warnings
+DROP TABLE IF EXISTS t1;
+--enable_warnings
+
+CREATE TABLE t1 (id INT);
+HANDLER t1 OPEN;
+
+# This used to trigger the assert.
+SELECT table_name, table_comment FROM information_schema.tables
+ WHERE table_schema= 'test' AND table_name= 't1';
+
+HANDLER t1 CLOSE;
+DROP TABLE t1;
+
+
+--echo #
+--echo # Test for bug #50908 "Assertion `handler_tables_hash.records == 0'
+--echo # failed in enter_locked_tables_mode".
+--echo #
+--disable_warnings
+drop tables if exists t1, t2;
+drop function if exists f1;
+--enable_warnings
+create table t1 (i int);
+insert into t1 values (1), (2);
+create table t2 (j int);
+insert into t2 values (1);
+create function f1() returns int return (select count(*) from t2);
+--echo # Check that open HANDLER survives statement executed in
+--echo # prelocked mode.
+handler t1 open;
+handler t1 read next;
+--echo # The below statement were aborted due to an assertion failure.
+select f1() from t2;
+handler t1 read next;
+handler t1 close;
+--echo # Check that the same happens under GLOBAL READ LOCK.
+flush tables with read lock;
+handler t1 open;
+handler t1 read next;
+select f1() from t2;
+handler t1 read next;
+unlock tables;
+handler t1 close;
+--echo # Now, check that the same happens if LOCK TABLES is executed.
+handler t1 open;
+handler t1 read next;
+lock table t2 read;
+select * from t2;
+unlock tables;
+handler t1 read next;
+handler t1 close;
+--echo # Finally, check scenario with GRL and LOCK TABLES.
+flush tables with read lock;
+handler t1 open;
+handler t1 read next;
+lock table t2 read;
+select * from t2;
+--echo # This unlocks both tables and GRL.
+unlock tables;
+handler t1 read next;
+handler t1 close;
+--echo # Clean-up.
+drop function f1;
+drop tables t1, t2;
+
+
+--echo #
+--echo # Test for bug #51136 "Crash in pthread_rwlock_rdlock on TEMPORARY +
+--echo # HANDLER + LOCK + SP".
+--echo # Also see additional coverage for this bug in flush.test.
+--echo #
+--disable_warnings
+drop tables if exists t1, t2;
+--enable_warnings
+create table t1 (i int);
+create temporary table t2 (j int);
+handler t1 open;
+lock table t2 read;
+--echo # This commit should not release any MDL locks.
+commit;
+unlock tables;
+--echo # The below statement crashed before the bug fix as it
+--echo # has attempted to release metadata lock which was
+--echo # already released by commit.
+handler t1 close;
+drop tables t1, t2;
diff --git a/mysql-test/include/implicit_commit_helper.inc b/mysql-test/include/implicit_commit_helper.inc
new file mode 100644
index 00000000000..5e87b2db079
--- /dev/null
+++ b/mysql-test/include/implicit_commit_helper.inc
@@ -0,0 +1,5 @@
+INSERT INTO db1.trans (a) VALUES (1);
+--disable_result_log
+eval $statement;
+--enable_result_log
+CALL db1.test_if_commit();
diff --git a/mysql-test/include/mix1.inc b/mysql-test/include/mix1.inc
index 194d9e41108..66648aaf1bf 100644
--- a/mysql-test/include/mix1.inc
+++ b/mysql-test/include/mix1.inc
@@ -899,6 +899,8 @@ CREATE PROCEDURE p1 ()
BEGIN
DECLARE i INT DEFAULT 50;
DECLARE cnt INT;
+ # Continue even in the presence of ER_LOCK_DEADLOCK.
+ DECLARE CONTINUE HANDLER FOR 1213 BEGIN END;
START TRANSACTION;
ALTER TABLE t1 ENGINE=InnoDB;
COMMIT;
@@ -1392,6 +1394,7 @@ SELECT * FROM t1;
connection con2;
--reap
SELECT * FROM t1;
+COMMIT;
--echo # Switch to connection con1
connection con1;
diff --git a/mysql-test/include/mix2.inc b/mysql-test/include/mix2.inc
index b4c4a9b8836..001d4cf44d4 100644
--- a/mysql-test/include/mix2.inc
+++ b/mysql-test/include/mix2.inc
@@ -1994,6 +1994,7 @@ commit;
connection b;
set autocommit = 0;
update t1 set b = 5 where a = 2;
+commit;
connection a;
delimiter |;
create trigger t1t before insert on t1 for each row begin set NEW.b = NEW.a * 10 + 5, NEW.c = NEW.a / 10; end |
@@ -2056,6 +2057,7 @@ update t2 set b = b + 5 where a = 1;
update t3 set b = b + 5 where a = 1;
update t4 set b = b + 5 where a = 1;
insert into t5(a) values(20);
+commit;
connection b;
set autocommit = 0;
insert into t1(a) values(7);
diff --git a/mysql-test/include/mtr_warnings.sql b/mysql-test/include/mtr_warnings.sql
index 00e8c4e6c95..e62dba8ae82 100644
--- a/mysql-test/include/mtr_warnings.sql
+++ b/mysql-test/include/mtr_warnings.sql
@@ -194,6 +194,14 @@ INSERT INTO global_suppressions VALUES
("Slave I/O: Get master COLLATION_SERVER failed with error:.*"),
("Slave I/O: Get master TIME_ZONE failed with error:.*"),
+ /*
+ BUG#42147 - Concurrent DML and LOCK TABLE ... READ for InnoDB
+ table cause warnings in errlog
+ Note: This is a temporary suppression until Bug#42147 can be
+ fixed properly. See bug page for more information.
+ */
+ ("Found lock of type 6 that is write and read locked"),
+
("THE_LAST_SUPPRESSION")||
diff --git a/mysql-test/lib/v1/mtr_report.pl b/mysql-test/lib/v1/mtr_report.pl
index 3c78c3ca064..36aba983c34 100644
--- a/mysql-test/lib/v1/mtr_report.pl
+++ b/mysql-test/lib/v1/mtr_report.pl
@@ -376,6 +376,9 @@ sub mtr_report_stats ($) {
/Slave: Can't DROP 'c7'.* 1091/ or
/Slave: Key column 'c6'.* 1072/ or
+ # Warnings generated until bug#42147 is properly resolved
+ /Found lock of type 6 that is write and read locked/ or
+
# rpl_idempotency.test produces warnings for the slave.
($testname eq 'rpl.rpl_idempotency' and
(/Slave: Can\'t find record in \'t1\' Error_code: 1032/ or
diff --git a/mysql-test/r/commit_1innodb.result b/mysql-test/r/commit_1innodb.result
index cf8c0e085c9..f789e412233 100644
--- a/mysql-test/r/commit_1innodb.result
+++ b/mysql-test/r/commit_1innodb.result
@@ -842,11 +842,11 @@ call p_verify_status_increment(2, 0, 2, 0);
SUCCESS
alter table t3 rename t4;
-call p_verify_status_increment(1, 0, 1, 0);
+call p_verify_status_increment(2, 0, 2, 0);
SUCCESS
rename table t4 to t3;
-call p_verify_status_increment(1, 0, 1, 0);
+call p_verify_status_increment(0, 0, 0, 0);
SUCCESS
truncate table t3;
@@ -854,13 +854,13 @@ call p_verify_status_increment(2, 0, 2, 0);
SUCCESS
create view v1 as select * from t2;
-call p_verify_status_increment(1, 0, 1, 0);
+call p_verify_status_increment(2, 0, 2, 0);
SUCCESS
check table t1;
Table Op Msg_type Msg_text
test.t1 check status OK
-call p_verify_status_increment(3, 0, 3, 0);
+call p_verify_status_increment(2, 0, 2, 0);
SUCCESS
# Sic: after this bug is fixed, CHECK leaves no pending transaction
diff --git a/mysql-test/r/create.result b/mysql-test/r/create.result
index 55e8e15b6a9..4e5fa213eab 100644
--- a/mysql-test/r/create.result
+++ b/mysql-test/r/create.result
@@ -785,7 +785,7 @@ drop table t1;
create table t1 select * from t2;
ERROR 42S02: Table 'test.t2' doesn't exist
create table t1 select * from t1;
-ERROR HY000: You can't specify target table 't1' for update in FROM clause
+ERROR 42S02: Table 'test.t1' doesn't exist
create table t1 select coalesce('a' collate latin1_swedish_ci,'b' collate latin1_bin);
ERROR HY000: Illegal mix of collations (latin1_swedish_ci,EXPLICIT) and (latin1_bin,EXPLICIT) for operation 'coalesce'
create table t1 (primary key(a)) select "b" as b;
@@ -805,6 +805,11 @@ Note 1050 Table 't1' already exists
select * from t1;
i
1
+create table if not exists t1 select * from t1;
+ERROR HY000: You can't specify target table 't1' for update in FROM clause
+select * from t1;
+i
+1
create table t1 select coalesce('a' collate latin1_swedish_ci,'b' collate latin1_bin);
ERROR HY000: Illegal mix of collations (latin1_swedish_ci,EXPLICIT) and (latin1_bin,EXPLICIT) for operation 'coalesce'
select * from t1;
@@ -1953,3 +1958,22 @@ END ;|
ERROR 42000: This version of MySQL doesn't yet support 'multiple triggers with the same action time and event for one table'
DROP TABLE t1;
DROP TABLE B;
+#
+# Bug #47107 assert in notify_shared_lock on incorrect
+# CREATE TABLE , HANDLER
+#
+DROP TABLE IF EXISTS t1;
+CREATE TABLE t1(f1 integer);
+# The following CREATE TABLEs before gave an assert.
+HANDLER t1 OPEN AS A;
+CREATE TABLE t1 SELECT 1 AS f2;
+ERROR 42S01: Table 't1' already exists
+HANDLER t1 OPEN AS A;
+CREATE TABLE t1(f1 integer);
+ERROR 42S01: Table 't1' already exists
+CREATE TABLE t2(f1 integer);
+HANDLER t1 OPEN AS A;
+CREATE TABLE t1 LIKE t2;
+ERROR 42S01: Table 't1' already exists
+DROP TABLE t2;
+DROP TABLE t1;
diff --git a/mysql-test/r/debug_sync.result b/mysql-test/r/debug_sync.result
index 8b46334204c..25fdf523200 100644
--- a/mysql-test/r/debug_sync.result
+++ b/mysql-test/r/debug_sync.result
@@ -263,7 +263,7 @@ DROP TABLE t1;
SET DEBUG_SYNC= 'RESET';
DROP TABLE IF EXISTS t1;
CREATE TABLE t1 (c1 INT);
-LOCK TABLE t1 WRITE;
+LOCK TABLE t1 READ;
connection con1
SET DEBUG_SYNC= 'wait_for_lock SIGNAL locked EXECUTE 2';
INSERT INTO t1 VALUES (1);
diff --git a/mysql-test/r/drop.result b/mysql-test/r/drop.result
index ae75f21955e..17ec2b09a0a 100644
--- a/mysql-test/r/drop.result
+++ b/mysql-test/r/drop.result
@@ -79,8 +79,8 @@ drop table t1;
drop database if exists mysqltest;
drop table if exists t1;
create table t1 (i int);
-lock tables t1 read;
create database mysqltest;
+lock tables t1 read;
drop table t1;
show open tables;
drop database mysqltest;
diff --git a/mysql-test/r/drop_debug.result b/mysql-test/r/drop_debug.result
index 75346b88bc6..f2c89034451 100644
--- a/mysql-test/r/drop_debug.result
+++ b/mysql-test/r/drop_debug.result
@@ -7,12 +7,16 @@ DROP DATABASE IF EXISTS mysql_test;
CREATE DATABASE mysql_test;
CREATE TABLE mysql_test.t1(a INT);
+CREATE TABLE mysql_test.t2(b INT);
+CREATE TABLE mysql_test.t3(c INT);
SET SESSION DEBUG = "+d,bug43138";
DROP DATABASE mysql_test;
Warnings:
Error 1051 Unknown table 't1'
+Error 1051 Unknown table 't2'
+Error 1051 Unknown table 't3'
SET SESSION DEBUG = "-d,bug43138";
diff --git a/mysql-test/r/flush.result b/mysql-test/r/flush.result
index b978304f59d..2136bcd92f1 100644
--- a/mysql-test/r/flush.result
+++ b/mysql-test/r/flush.result
@@ -33,6 +33,9 @@ flush tables with read lock;
ERROR HY000: Can't execute the given command because you have active locked tables or an active transaction
lock table t1 read;
flush tables with read lock;
+ERROR HY000: Can't execute the given command because you have active locked tables or an active transaction
+unlock tables;
+flush tables with read lock;
lock table t1 write;
ERROR HY000: Can't execute the query because you have a conflicting read lock
lock table t1 read;
@@ -46,6 +49,7 @@ flush tables with read lock;
ERROR HY000: Can't execute the given command because you have active locked tables or an active transaction
lock table t1 read, t2 read, t3 read;
flush tables with read lock;
+ERROR HY000: Can't execute the given command because you have active locked tables or an active transaction
unlock tables;
drop table t1, t2, t3;
create table t1 (c1 int);
@@ -69,6 +73,7 @@ ERROR HY000: Can't execute the given command because you have active locked tabl
unlock tables;
lock tables t1 read;
flush tables with read lock;
+ERROR HY000: Can't execute the given command because you have active locked tables or an active transaction
unlock tables;
drop table t1, t2;
set session low_priority_updates=default;
@@ -89,3 +94,20 @@ unlock tables;
set global general_log= @old_general_log;
set global read_only= @old_read_only;
End of 5.1 tests
+#
+# Additional test for bug #51136 "Crash in pthread_rwlock_rdlock
+# on TEMPORARY + HANDLER + LOCK + SP".
+# Also see the main test for this bug in include/handler.inc.
+#
+drop tables if exists t1, t2;
+create table t1 (i int);
+create temporary table t2 (j int);
+flush tables with read lock;
+lock table t2 read;
+# This commit should not release any MDL locks.
+commit;
+# The below statement crashed before the bug fix as it
+# has attempted to release global shared metadata lock
+# which was already released by commit.
+unlock tables;
+drop tables t1, t2;
diff --git a/mysql-test/r/flush_block_commit.result b/mysql-test/r/flush_block_commit.result
index d2197beaaab..7062d05c2d7 100644
--- a/mysql-test/r/flush_block_commit.result
+++ b/mysql-test/r/flush_block_commit.result
@@ -1,3 +1,4 @@
+# Save the initial number of concurrent sessions
# Establish connection con1 (user=root)
# Establish connection con2 (user=root)
# Establish connection con3 (user=root)
@@ -8,15 +9,17 @@ BEGIN;
INSERT INTO t1 VALUES(1);
# Switch to connection con2
FLUSH TABLES WITH READ LOCK;
-SELECT * FROM t1;
-a
# Switch to connection con1
+# Sending:
COMMIT;
# Switch to connection con2
+# Wait until COMMIT gets blocked.
+# Verify that 'con1' was blocked and data did not move.
SELECT * FROM t1;
a
UNLOCK TABLES;
# Switch to connection con1
+# Reaping COMMIT
# Switch to connection con1
BEGIN;
SELECT * FROM t1 FOR UPDATE;
@@ -32,6 +35,7 @@ COMMIT;
# Switch to connection con2
a
1
+COMMIT;
# Switch to connection con3
UNLOCK TABLES;
# Switch to connection con2
@@ -40,8 +44,6 @@ COMMIT;
BEGIN;
INSERT INTO t1 VALUES(10);
FLUSH TABLES WITH READ LOCK;
-COMMIT;
-UNLOCK TABLES;
# Switch to connection con2
FLUSH TABLES WITH READ LOCK;
UNLOCK TABLES;
@@ -53,5 +55,11 @@ a
SHOW CREATE DATABASE test;
Database Create Database
test CREATE DATABASE `test` /*!40100 DEFAULT CHARACTER SET latin1 */
-DROP TABLE t1;
+COMMIT;
+# Cleanup
# Switch to connection default and close connections con1, con2, con3
+# We commit open transactions when we disconnect: only then we can
+# drop the table.
+DROP TABLE t1;
+# End of 4.1 tests
+# Wait till all disconnects are completed
diff --git a/mysql-test/r/flush_block_commit_notembedded.result b/mysql-test/r/flush_block_commit_notembedded.result
index 4348dbd67e5..6d8af3f5864 100644
--- a/mysql-test/r/flush_block_commit_notembedded.result
+++ b/mysql-test/r/flush_block_commit_notembedded.result
@@ -1,17 +1,20 @@
+# Save the initial number of concurrent sessions
# Establish connection con1 (user=root)
# Establish connection con2 (user=root)
# Switch to connection con1
CREATE TABLE t1 (a INT) ENGINE=innodb;
RESET MASTER;
SET AUTOCOMMIT=0;
-INSERT t1 VALUES (1);
+SELECT 1;
+1
+1
# Switch to connection con2
FLUSH TABLES WITH READ LOCK;
SHOW MASTER STATUS;
File Position Binlog_Do_DB Binlog_Ignore_DB
master-bin.000001 107
# Switch to connection con1
-COMMIT;
+INSERT INTO t1 VALUES (1);
# Switch to connection con2
SHOW MASTER STATUS;
File Position Binlog_Do_DB Binlog_Ignore_DB
@@ -20,4 +23,12 @@ UNLOCK TABLES;
# Switch to connection con1
DROP TABLE t1;
SET AUTOCOMMIT=1;
+create table t1 (a int) engine=innodb;
+flush tables with read lock;
+begin;
+insert into t1 values (1);;
+unlock tables;
+commit;
+drop table t1;
# Switch to connection default and close connections con1 and con2
+# Wait till all disconnects are completed
diff --git a/mysql-test/r/flush_table.result b/mysql-test/r/flush_table.result
index 8821bade6b4..2b0ee1cb205 100644
--- a/mysql-test/r/flush_table.result
+++ b/mysql-test/r/flush_table.result
@@ -3,21 +3,14 @@ create table t1 (a int not null auto_increment primary key);
insert into t1 values(0);
lock table t1 read;
flush table t1;
+ERROR HY000: Table 't1' was locked with a READ lock and can't be updated
+unlock tables;
+lock table t1 write;
+flush table t1;
check table t1;
Table Op Msg_type Msg_text
test.t1 check status OK
unlock tables;
-lock table t1 read;
-lock table t1 read;
-flush table t1;
-select * from t1;
-a
-1
-unlock tables;
-select * from t1;
-a
-1
-unlock tables;
lock table t1 write;
lock table t1 read;
flush table t1;
@@ -26,7 +19,7 @@ a
1
unlock tables;
unlock tables;
-lock table t1 read;
+lock table t1 write;
lock table t1 write;
flush table t1;
select * from t1;
diff --git a/mysql-test/r/handler_innodb.result b/mysql-test/r/handler_innodb.result
index 957fc30acef..58083194b83 100644
--- a/mysql-test/r/handler_innodb.result
+++ b/mysql-test/r/handler_innodb.result
@@ -548,6 +548,7 @@ c1
1
connection: flush
flush tables;;
+connection: waiter
connection: default
handler t2 open;
handler t2 read first;
@@ -559,23 +560,36 @@ c1
handler t1 close;
handler t2 close;
drop table t1,t2;
-drop table if exists t1,t2;
+drop table if exists t1, t0;
create table t1 (c1 int);
connection: default
handler t1 open;
handler t1 read first;
c1
connection: flush
-rename table t1 to t2;;
+rename table t1 to t0;;
+connection: waiter
connection: default
-handler t2 open;
-handler t2 read first;
-c1
+#
+# RENAME placed two pending locks and waits.
+# When HANDLER t0 OPEN does open_tables(), it calls
+# mysql_ha_flush(), which in turn closes the open HANDLER for t1.
+# RENAME TABLE gets unblocked. If it gets scheduled quickly
+# and manages to complete before open_tables()
+# of HANDLER t0 OPEN, open_tables() and therefore the whole
+# HANDLER t0 OPEN succeeds. Otherwise open_tables()
+# notices a pending or active exclusive metadata lock on t2
+# and the whole HANDLER t0 OPEN fails with ER_LOCK_DEADLOCK
+# error.
+#
+handler t0 open;
+handler t0 close;
+connection: flush
handler t1 read next;
-ERROR 42S02: Table 'test.t1' doesn't exist
+ERROR 42S02: Unknown table 't1' in HANDLER
handler t1 close;
-handler t2 close;
-drop table t2;
+ERROR 42S02: Unknown table 't1' in HANDLER
+drop table t0;
drop table if exists t1;
create temporary table t1 (a int, b char(1), key a(a), key b(a,b));
insert into t1 values (0,"a"),(1,"b"),(2,"c"),(3,"d"),(4,"e"),
@@ -731,15 +745,943 @@ drop table t1;
handler t1 read a next;
ERROR 42S02: Unknown table 't1' in HANDLER
drop table if exists t1;
+# First test case which is supposed trigger the execution
+# path on which problem was discovered.
create table t1 (a int);
insert into t1 values (1);
handler t1 open;
+lock table t1 write;
alter table t1 engine=memory;
handler t1 read a next;
ERROR HY000: Table storage engine for 't1' doesn't have this option
handler t1 close;
+unlock tables;
+drop table t1;
+# Now test case which was reported originally but which no longer
+# triggers execution path which has caused the problem.
+create table t1 (a int, key(a));
+insert into t1 values (1);
+handler t1 open;
+alter table t1 engine=memory;
+# Since S metadata lock was already acquired at HANDLER OPEN time
+# and TL_READ lock requested by HANDLER READ is compatible with
+# ALTER's TL_WRITE_ALLOW_READ the below statement should succeed
+# without waiting. The old version of table should be used in it.
+handler t1 read a next;
+a
+1
+handler t1 close;
drop table t1;
USE information_schema;
HANDLER COLUMNS OPEN;
ERROR HY000: Incorrect usage of HANDLER OPEN and information_schema
USE test;
+#
+# Add test coverage for HANDLER and LOCK TABLES, HANDLER and DDL.
+#
+drop table if exists t1, t2, t3;
+create table t1 (a int, key a (a));
+insert into t1 (a) values (1), (2), (3), (4), (5);
+create table t2 (a int, key a (a)) select * from t1;
+create temporary table t3 (a int, key a (a)) select * from t2;
+handler t1 open;
+handler t2 open;
+handler t3 open;
+#
+# No HANDLER sql is allowed under LOCK TABLES.
+# But it does not implicitly closes all handlers.
+#
+lock table t1 read;
+handler t1 open;
+ERROR HY000: Can't execute the given command because you have active locked tables or an active transaction
+handler t1 read next;
+ERROR HY000: Can't execute the given command because you have active locked tables or an active transaction
+handler t2 close;
+ERROR HY000: Can't execute the given command because you have active locked tables or an active transaction
+handler t3 open;
+ERROR HY000: Can't execute the given command because you have active locked tables or an active transaction
+# After UNLOCK TABLES handlers should be around and
+# we should be able to continue reading through them.
+unlock tables;
+handler t1 read next;
+a
+1
+handler t1 close;
+handler t2 read next;
+a
+1
+handler t2 close;
+handler t3 read next;
+a
+1
+handler t3 close;
+drop temporary table t3;
+#
+# Other operations that implicitly close handler:
+#
+# TRUNCATE
+#
+handler t1 open;
+truncate table t1;
+handler t1 read next;
+ERROR 42S02: Unknown table 't1' in HANDLER
+handler t1 open;
+#
+# CREATE TRIGGER
+#
+create trigger t1_ai after insert on t1 for each row set @a=1;
+handler t1 read next;
+ERROR 42S02: Unknown table 't1' in HANDLER
+#
+# DROP TRIGGER
+#
+handler t1 open;
+drop trigger t1_ai;
+handler t1 read next;
+ERROR 42S02: Unknown table 't1' in HANDLER
+#
+# ALTER TABLE
+#
+handler t1 open;
+alter table t1 add column b int;
+handler t1 read next;
+ERROR 42S02: Unknown table 't1' in HANDLER
+#
+# ANALYZE TABLE
+#
+handler t1 open;
+analyze table t1;
+Table Op Msg_type Msg_text
+test.t1 analyze status OK
+handler t1 read next;
+ERROR 42S02: Unknown table 't1' in HANDLER
+#
+# OPTIMIZE TABLE
+#
+handler t1 open;
+optimize table t1;
+Table Op Msg_type Msg_text
+test.t1 optimize note Table does not support optimize, doing recreate + analyze instead
+test.t1 optimize status OK
+handler t1 read next;
+ERROR 42S02: Unknown table 't1' in HANDLER
+#
+# REPAIR TABLE
+#
+handler t1 open;
+repair table t1;
+Table Op Msg_type Msg_text
+test.t1 repair note The storage engine for the table doesn't support repair
+handler t1 read next;
+ERROR 42S02: Unknown table 't1' in HANDLER
+#
+# DROP TABLE, naturally.
+#
+handler t1 open;
+drop table t1;
+handler t1 read next;
+ERROR 42S02: Unknown table 't1' in HANDLER
+create table t1 (a int, b int, key a (a)) select a from t2;
+#
+# RENAME TABLE, naturally
+#
+handler t1 open;
+rename table t1 to t3;
+handler t1 read next;
+ERROR 42S02: Unknown table 't1' in HANDLER
+#
+# CREATE TABLE (even with IF NOT EXISTS clause,
+# and the table exists).
+#
+handler t2 open;
+create table if not exists t2 (a int);
+Warnings:
+Note 1050 Table 't2' already exists
+handler t2 read next;
+ERROR 42S02: Unknown table 't2' in HANDLER
+rename table t3 to t1;
+drop table t2;
+#
+# FLUSH TABLE doesn't close the table but loses the position
+#
+handler t1 open;
+handler t1 read a prev;
+b a
+NULL 5
+flush table t1;
+handler t1 read a prev;
+b a
+NULL 5
+handler t1 close;
+#
+# FLUSH TABLES WITH READ LOCK behaves like FLUSH TABLE.
+#
+handler t1 open;
+handler t1 read a prev;
+b a
+NULL 5
+flush tables with read lock;
+handler t1 read a prev;
+b a
+NULL 5
+handler t1 close;
+unlock tables;
+#
+# Let us also check that these operations behave in similar
+# way under LOCK TABLES.
+#
+# TRUNCATE under LOCK TABLES.
+#
+handler t1 open;
+lock tables t1 write;
+truncate table t1;
+unlock tables;
+handler t1 read next;
+ERROR 42S02: Unknown table 't1' in HANDLER
+handler t1 open;
+#
+# CREATE TRIGGER under LOCK TABLES.
+#
+lock tables t1 write;
+create trigger t1_ai after insert on t1 for each row set @a=1;
+unlock tables;
+handler t1 read next;
+ERROR 42S02: Unknown table 't1' in HANDLER
+#
+# DROP TRIGGER under LOCK TABLES.
+#
+handler t1 open;
+lock tables t1 write;
+drop trigger t1_ai;
+unlock tables;
+handler t1 read next;
+ERROR 42S02: Unknown table 't1' in HANDLER
+#
+# ALTER TABLE under LOCK TABLES.
+#
+handler t1 open;
+lock tables t1 write;
+alter table t1 drop column b;
+unlock tables;
+handler t1 read next;
+ERROR 42S02: Unknown table 't1' in HANDLER
+#
+# ANALYZE TABLE under LOCK TABLES.
+#
+handler t1 open;
+lock tables t1 write;
+analyze table t1;
+Table Op Msg_type Msg_text
+test.t1 analyze status OK
+unlock tables;
+handler t1 read next;
+ERROR 42S02: Unknown table 't1' in HANDLER
+#
+# OPTIMIZE TABLE under LOCK TABLES.
+#
+handler t1 open;
+lock tables t1 write;
+optimize table t1;
+Table Op Msg_type Msg_text
+test.t1 optimize note Table does not support optimize, doing recreate + analyze instead
+test.t1 optimize status OK
+unlock tables;
+handler t1 read next;
+ERROR 42S02: Unknown table 't1' in HANDLER
+#
+# REPAIR TABLE under LOCK TABLES.
+#
+handler t1 open;
+lock tables t1 write;
+repair table t1;
+Table Op Msg_type Msg_text
+test.t1 repair note The storage engine for the table doesn't support repair
+unlock tables;
+handler t1 read next;
+ERROR 42S02: Unknown table 't1' in HANDLER
+#
+# DROP TABLE under LOCK TABLES, naturally.
+#
+handler t1 open;
+lock tables t1 write;
+drop table t1;
+unlock tables;
+handler t1 read next;
+ERROR 42S02: Unknown table 't1' in HANDLER
+create table t1 (a int, b int, key a (a));
+insert into t1 (a) values (1), (2), (3), (4), (5);
+#
+# FLUSH TABLE doesn't close the table but loses the position
+#
+handler t1 open;
+handler t1 read a prev;
+a b
+5 NULL
+lock tables t1 write;
+flush table t1;
+unlock tables;
+handler t1 read a prev;
+a b
+5 NULL
+handler t1 close;
+#
+# Explore the effect of HANDLER locks on concurrent DDL
+#
+handler t1 open;
+# Establishing auxiliary connections con1, con2, con3
+# --> connection con1;
+# Sending:
+drop table t1 ;
+# We can't use connection 'default' as wait_condition will
+# autoclose handlers.
+# --> connection con2
+# Waitng for 'drop table t1' to get blocked...
+# --> connection default
+handler t1 read a prev;
+a b
+5 NULL
+handler t1 read a prev;
+a b
+4 NULL
+handler t1 close;
+# --> connection con1
+# Reaping 'drop table t1'...
+# --> connection default
+#
+# Explore the effect of HANDLER locks in parallel with SELECT
+#
+create table t1 (a int, key a (a));
+insert into t1 (a) values (1), (2), (3), (4), (5);
+begin;
+select * from t1;
+a
+1
+2
+3
+4
+5
+handler t1 open;
+handler t1 read a prev;
+a
+5
+handler t1 read a prev;
+a
+4
+handler t1 close;
+# --> connection con1;
+# Sending:
+drop table t1 ;
+# --> connection con2
+# Waiting for 'drop table t1' to get blocked...
+# --> connection default
+# We can still use the table, it's part of the transaction
+select * from t1;
+a
+1
+2
+3
+4
+5
+# Such are the circumstances that t1 is a part of transaction,
+# thus we can reopen it in the handler
+handler t1 open;
+# We can commit the transaction, it doesn't close the handler
+# and doesn't let DROP to proceed.
+commit;
+handler t1 read a prev;
+a
+5
+handler t1 read a prev;
+a
+4
+handler t1 read a prev;
+a
+3
+handler t1 close;
+# --> connection con1
+# Now drop can proceed
+# Reaping 'drop table t1'...
+# --> connection default
+#
+# Demonstrate that HANDLER locks and transaction locks
+# reside in the same context, and we don't back-off
+# when have transaction or handler locks.
+#
+create table t1 (a int, key a (a));
+insert into t1 (a) values (1), (2), (3), (4), (5);
+create table t0 (a int, key a (a));
+insert into t0 (a) values (1), (2), (3), (4), (5);
+begin;
+select * from t1;
+a
+1
+2
+3
+4
+5
+# --> connection con2
+# Sending:
+rename table t0 to t3, t1 to t0, t3 to t1;
+# --> connection con1
+# Waiting for 'rename table ...' to get blocked...
+# --> connection default
+handler t0 open;
+ERROR 40001: Deadlock found when trying to get lock; try restarting transaction
+select * from t0;
+ERROR 40001: Deadlock found when trying to get lock; try restarting transaction
+handler t1 open;
+commit;
+handler t1 close;
+# --> connection con2
+# Reaping 'rename table ...'...
+# --> connection default
+handler t1 open;
+handler t1 read a prev;
+a
+5
+handler t1 close;
+drop table t0;
+#
+# Originally there was a deadlock error in this test.
+# With implementation of deadlock detector
+# we no longer deadlock, but block and wait on a lock.
+# The HANDLER is auto-closed as soon as the connection
+# sees a pending conflicting lock against it.
+#
+create table t2 (a int, key a (a));
+handler t1 open;
+# --> connection con1
+lock tables t2 read;
+# --> connection con2
+# Sending 'drop table t2'...
+drop table t2;
+# --> connection con1
+# Waiting for 'drop table t2' to get blocked...
+# --> connection default
+# Sending 'select * from t2'
+select * from t2;
+# --> connection con1
+# Waiting for 'select * from t2' to get blocked...
+unlock tables;
+# --> connection con2
+# Reaping 'drop table t2'...
+# --> connection default
+# Reaping 'select * from t2'
+ERROR 42S02: Table 'test.t2' doesn't exist
+handler t1 close;
+#
+# ROLLBACK TO SAVEPOINT releases transactional locks,
+# but has no effect on open HANDLERs
+#
+create table t2 like t1;
+create table t3 like t1;
+begin;
+# Have something before the savepoint
+select * from t3;
+a
+savepoint sv;
+handler t1 open;
+handler t1 read a first;
+a
+1
+handler t1 read a next;
+a
+2
+select * from t2;
+a
+# --> connection con1
+# Sending:
+drop table t1;
+# --> connection con2
+# Sending:
+drop table t2;
+# --> connection default
+# Let DROP TABLE statements sync in. We must use
+# a separate connection for that, because otherwise SELECT
+# will auto-close the HANDLERs, becaues there are pending
+# exclusive locks against them.
+# --> connection con3
+# Waiting for 'drop table t1' to get blocked...
+# Waiting for 'drop table t2' to get blocked...
+# Demonstrate that t2 lock was released and t2 was dropped
+# after ROLLBACK TO SAVEPOINT
+# --> connection default
+rollback to savepoint sv;
+# --> connection con2
+# Reaping 'drop table t2'...
+# Demonstrate that ROLLBACK TO SAVEPOINT didn't release the handler
+# lock.
+# --> connection default
+handler t1 read a next;
+a
+3
+handler t1 read a next;
+a
+4
+# Demonstrate that the drop will go through as soon as we close the
+# HANDLER
+handler t1 close;
+# connection con1
+# Reaping 'drop table t1'...
+# --> connection default
+commit;
+drop table t3;
+#
+# A few special cases when using SAVEPOINT/ROLLBACK TO
+# SAVEPOINT and HANDLER.
+#
+# Show that rollback to the savepoint taken in the beginning
+# of the transaction doesn't release mdl lock on
+# the HANDLER that was opened later.
+#
+create table t1 (a int, key a(a));
+insert into t1 (a) values (1), (2), (3), (4), (5);
+create table t2 like t1;
+begin;
+savepoint sv;
+handler t1 open;
+handler t1 read a first;
+a
+1
+handler t1 read a next;
+a
+2
+select * from t2;
+a
+# --> connection con1
+# Sending:
+drop table t1;
+# --> connection con2
+# Sending:
+drop table t2;
+# --> connection default
+# Let DROP TABLE statements sync in. We must use
+# a separate connection for that, because otherwise SELECT
+# will auto-close the HANDLERs, becaues there are pending
+# exclusive locks against them.
+# --> connection con3
+# Waiting for 'drop table t1' to get blocked...
+# Waiting for 'drop table t2' to get blocked...
+# Demonstrate that t2 lock was released and t2 was dropped
+# after ROLLBACK TO SAVEPOINT
+# --> connection default
+rollback to savepoint sv;
+# --> connection con2
+# Reaping 'drop table t2'...
+# Demonstrate that ROLLBACK TO SAVEPOINT didn't release the handler
+# lock.
+# --> connection default
+handler t1 read a next;
+a
+3
+handler t1 read a next;
+a
+4
+# Demonstrate that the drop will go through as soon as we close the
+# HANDLER
+handler t1 close;
+# connection con1
+# Reaping 'drop table t1'...
+# --> connection default
+commit;
+#
+# Show that rollback to the savepoint taken in the beginning
+# of the transaction works properly (no valgrind warnins, etc),
+# even though it's done after the HANDLER mdl lock that was there
+# at the beginning is released and added again.
+#
+create table t1 (a int, key a(a));
+insert into t1 (a) values (1), (2), (3), (4), (5);
+create table t2 like t1;
+create table t3 like t1;
+insert into t3 (a) select a from t1;
+begin;
+handler t1 open;
+savepoint sv;
+handler t1 read a first;
+a
+1
+select * from t2;
+a
+handler t1 close;
+handler t3 open;
+handler t3 read a first;
+a
+1
+rollback to savepoint sv;
+# --> connection con1
+drop table t1, t2;
+# Sending:
+drop table t3;
+# Let DROP TABLE statement sync in.
+# --> connection con2
+# Waiting for 'drop table t3' to get blocked...
+# Demonstrate that ROLLBACK TO SAVEPOINT didn't release the handler
+# lock.
+# --> connection default
+handler t3 read a next;
+a
+2
+# Demonstrate that the drop will go through as soon as we close the
+# HANDLER
+handler t3 close;
+# connection con1
+# Reaping 'drop table t3'...
+# --> connection default
+commit;
+#
+# If we have to wait on an exclusive locks while having
+# an open HANDLER, ER_LOCK_DEADLOCK is reported.
+#
+create table t1 (a int, key a(a));
+create table t2 like t1;
+handler t1 open;
+# --> connection con1
+lock table t1 write, t2 write;
+# --> connection default
+drop table t2;
+# --> connection con2
+# Waiting for 'drop table t2' to get blocked...
+# --> connection con1
+drop table t1;
+ERROR 40001: Deadlock found when trying to get lock; try restarting transaction
+unlock tables;
+# --> connection default
+# Demonstrate that there is no deadlock with FLUSH TABLE,
+# even though it is waiting for the other table to go away
+create table t2 like t1;
+# Sending:
+flush table t2;
+# --> connection con2
+drop table t1;
+# --> connection con1
+unlock tables;
+# --> connection default
+# Reaping 'flush table t2'...
+drop table t2;
+#
+# Bug #46224 HANDLER statements within a transaction might
+# lead to deadlocks
+#
+create table t1 (a int, key a(a));
+insert into t1 values (1), (2);
+# --> connection default
+begin;
+select * from t1;
+a
+1
+2
+handler t1 open;
+# --> connection con1
+# Sending:
+lock tables t1 write;
+# --> connection con2
+# Check that 'lock tables t1 write' waits until transaction which
+# has read from the table commits.
+# --> connection default
+# The below 'handler t1 read ...' should not be blocked as
+# 'lock tables t1 write' has not succeeded yet.
+handler t1 read a next;
+a
+1
+# Unblock 'lock tables t1 write'.
+commit;
+# --> connection con1
+# Reap 'lock tables t1 write'.
+# --> connection default
+# Sending:
+handler t1 read a next;
+# --> connection con1
+# Waiting for 'handler t1 read a next' to get blocked...
+# The below 'drop table t1' should be able to proceed without
+# waiting as it will force HANDLER to be closed.
+drop table t1;
+unlock tables;
+# --> connection default
+# Reaping 'handler t1 read a next'...
+ERROR 42S02: Table 'test.t1' doesn't exist
+handler t1 close;
+# --> connection con1
+# --> connection con2
+# --> connection con3
+#
+# A temporary table test.
+# Check that we don't loose positions of HANDLER opened
+# against a temporary table.
+#
+create table t1 (a int, b int, key a (a));
+insert into t1 (a) values (1), (2), (3), (4), (5);
+create temporary table t2 (a int, b int, key a (a));
+insert into t2 (a) select a from t1;
+handler t1 open;
+handler t1 read a next;
+a b
+1 NULL
+handler t2 open;
+handler t2 read a next;
+a b
+1 NULL
+flush table t1;
+handler t2 read a next;
+a b
+2 NULL
+# Sic: the position is lost
+handler t1 read a next;
+a b
+1 NULL
+select * from t1;
+a b
+1 NULL
+2 NULL
+3 NULL
+4 NULL
+5 NULL
+# Sic: the position is not lost
+handler t2 read a next;
+a b
+3 NULL
+select * from t2;
+ERROR HY000: Can't reopen table: 't2'
+handler t2 read a next;
+a b
+4 NULL
+drop table t1;
+drop temporary table t2;
+#
+# A test for lock_table_names()/unlock_table_names() function.
+# It should work properly in presence of open HANDLER.
+#
+create table t1 (a int, b int, key a (a));
+create table t2 like t1;
+create table t3 like t1;
+create table t4 like t1;
+handler t1 open;
+handler t2 open;
+rename table t4 to t5, t3 to t4, t5 to t3;
+handler t1 read first;
+a b
+handler t2 read first;
+a b
+drop table t1, t2, t3, t4;
+#
+# A test for FLUSH TABLES WITH READ LOCK and HANDLER statements.
+#
+set autocommit=0;
+create table t1 (a int, b int, key a (a));
+insert into t1 (a, b) values (1, 1), (2, 1), (3, 2), (4, 2), (5, 5);
+create table t2 like t1;
+insert into t2 (a, b) select a, b from t1;
+create table t3 like t1;
+insert into t3 (a, b) select a, b from t1;
+commit;
+flush tables with read lock;
+handler t1 open;
+lock table t1 read;
+handler t1 read next;
+ERROR HY000: Can't execute the given command because you have active locked tables or an active transaction
+# This implicitly leaves LOCK TABLES but doesn't drop the GLR
+lock table not_exists_write read;
+ERROR 42S02: Table 'test.not_exists_write' doesn't exist
+# We still have the read lock.
+drop table t1;
+ERROR HY000: Can't execute the query because you have a conflicting read lock
+handler t1 read next;
+a b
+1 1
+handler t1 close;
+handler t1 open;
+select a from t2;
+a
+1
+2
+3
+4
+5
+handler t1 read next;
+a b
+1 1
+flush tables with read lock;
+handler t2 open;
+flush tables with read lock;
+handler t1 read next;
+a b
+1 1
+select a from t3;
+a
+1
+2
+3
+4
+5
+handler t2 read next;
+a b
+1 1
+handler t1 close;
+rollback;
+handler t2 close;
+drop table t1;
+ERROR HY000: Can't execute the query because you have a conflicting read lock
+commit;
+flush tables;
+drop table t1;
+ERROR HY000: Can't execute the query because you have a conflicting read lock
+unlock tables;
+drop table t1;
+set autocommit=default;
+drop table t2, t3;
+#
+# HANDLER statement and operation-type aware metadata locks.
+# Check that when we clone a ticket for HANDLER we downrade
+# the lock.
+#
+# Establish an auxiliary connection con1.
+# -> connection default
+create table t1 (a int, b int, key a (a));
+insert into t1 (a, b) values (1, 1), (2, 1), (3, 2), (4, 2), (5, 5);
+begin;
+insert into t1 (a, b) values (6, 6);
+handler t1 open;
+handler t1 read a last;
+a b
+6 6
+insert into t1 (a, b) values (7, 7);
+handler t1 read a last;
+a b
+7 7
+commit;
+# -> connection con1
+# Demonstrate that the HANDLER doesn't hold MDL_SHARED_WRITE.
+lock table t1 write;
+unlock tables;
+# -> connection default
+handler t1 read a prev;
+a b
+6 6
+handler t1 close;
+# Cleanup.
+drop table t1;
+# -> connection con1
+# -> connection default
+#
+# A test for Bug#50555 "handler commands crash server in
+# my_hash_first()".
+#
+handler no_such_table read no_such_index first;
+ERROR 42S02: Unknown table 'no_such_table' in HANDLER
+handler no_such_table close;
+ERROR 42S02: Unknown table 'no_such_table' in HANDLER
+#
+# Bug#50907 Assertion `hash_tables->table->next == __null' on
+# HANDLER OPEN
+#
+DROP TABLE IF EXISTS t1, t2;
+CREATE TEMPORARY TABLE t1 (i INT);
+CREATE TEMPORARY TABLE t2 (i INT);
+HANDLER t2 OPEN;
+HANDLER t2 READ FIRST;
+i
+HANDLER t2 CLOSE;
+DROP TABLE t1, t2;
+#
+# Bug#50912 Assertion `ticket->m_type >= mdl_request->type'
+# failed on HANDLER + I_S
+#
+DROP TABLE IF EXISTS t1;
+CREATE TABLE t1 (id INT);
+HANDLER t1 OPEN;
+SELECT table_name, table_comment FROM information_schema.tables
+WHERE table_schema= 'test' AND table_name= 't1';
+table_name table_comment
+t1
+HANDLER t1 CLOSE;
+DROP TABLE t1;
+#
+# Test for bug #50908 "Assertion `handler_tables_hash.records == 0'
+# failed in enter_locked_tables_mode".
+#
+drop tables if exists t1, t2;
+drop function if exists f1;
+create table t1 (i int);
+insert into t1 values (1), (2);
+create table t2 (j int);
+insert into t2 values (1);
+create function f1() returns int return (select count(*) from t2);
+# Check that open HANDLER survives statement executed in
+# prelocked mode.
+handler t1 open;
+handler t1 read next;
+i
+1
+# The below statement were aborted due to an assertion failure.
+select f1() from t2;
+f1()
+1
+handler t1 read next;
+i
+2
+handler t1 close;
+# Check that the same happens under GLOBAL READ LOCK.
+flush tables with read lock;
+handler t1 open;
+handler t1 read next;
+i
+1
+select f1() from t2;
+f1()
+1
+handler t1 read next;
+i
+2
+unlock tables;
+handler t1 close;
+# Now, check that the same happens if LOCK TABLES is executed.
+handler t1 open;
+handler t1 read next;
+i
+1
+lock table t2 read;
+select * from t2;
+j
+1
+unlock tables;
+handler t1 read next;
+i
+2
+handler t1 close;
+# Finally, check scenario with GRL and LOCK TABLES.
+flush tables with read lock;
+handler t1 open;
+handler t1 read next;
+i
+1
+lock table t2 read;
+select * from t2;
+j
+1
+# This unlocks both tables and GRL.
+unlock tables;
+handler t1 read next;
+i
+2
+handler t1 close;
+# Clean-up.
+drop function f1;
+drop tables t1, t2;
+#
+# Test for bug #51136 "Crash in pthread_rwlock_rdlock on TEMPORARY +
+# HANDLER + LOCK + SP".
+# Also see additional coverage for this bug in flush.test.
+#
+drop tables if exists t1, t2;
+create table t1 (i int);
+create temporary table t2 (j int);
+handler t1 open;
+lock table t2 read;
+# This commit should not release any MDL locks.
+commit;
+unlock tables;
+# The below statement crashed before the bug fix as it
+# has attempted to release metadata lock which was
+# already released by commit.
+handler t1 close;
+drop tables t1, t2;
diff --git a/mysql-test/r/handler_myisam.result b/mysql-test/r/handler_myisam.result
index 90a1bdfe6be..dd199e40574 100644
--- a/mysql-test/r/handler_myisam.result
+++ b/mysql-test/r/handler_myisam.result
@@ -547,6 +547,7 @@ c1
1
connection: flush
flush tables;;
+connection: waiter
connection: default
handler t2 open;
handler t2 read first;
@@ -558,23 +559,36 @@ c1
handler t1 close;
handler t2 close;
drop table t1,t2;
-drop table if exists t1,t2;
+drop table if exists t1, t0;
create table t1 (c1 int);
connection: default
handler t1 open;
handler t1 read first;
c1
connection: flush
-rename table t1 to t2;;
+rename table t1 to t0;;
+connection: waiter
connection: default
-handler t2 open;
-handler t2 read first;
-c1
+#
+# RENAME placed two pending locks and waits.
+# When HANDLER t0 OPEN does open_tables(), it calls
+# mysql_ha_flush(), which in turn closes the open HANDLER for t1.
+# RENAME TABLE gets unblocked. If it gets scheduled quickly
+# and manages to complete before open_tables()
+# of HANDLER t0 OPEN, open_tables() and therefore the whole
+# HANDLER t0 OPEN succeeds. Otherwise open_tables()
+# notices a pending or active exclusive metadata lock on t2
+# and the whole HANDLER t0 OPEN fails with ER_LOCK_DEADLOCK
+# error.
+#
+handler t0 open;
+handler t0 close;
+connection: flush
handler t1 read next;
-ERROR 42S02: Table 'test.t1' doesn't exist
+ERROR 42S02: Unknown table 't1' in HANDLER
handler t1 close;
-handler t2 close;
-drop table t2;
+ERROR 42S02: Unknown table 't1' in HANDLER
+drop table t0;
drop table if exists t1;
create temporary table t1 (a int, b char(1), key a(a), key b(a,b));
insert into t1 values (0,"a"),(1,"b"),(2,"c"),(3,"d"),(4,"e"),
@@ -729,19 +743,945 @@ drop table t1;
handler t1 read a next;
ERROR 42S02: Unknown table 't1' in HANDLER
drop table if exists t1;
+# First test case which is supposed trigger the execution
+# path on which problem was discovered.
create table t1 (a int);
insert into t1 values (1);
handler t1 open;
+lock table t1 write;
alter table t1 engine=memory;
handler t1 read a next;
ERROR HY000: Table storage engine for 't1' doesn't have this option
handler t1 close;
+unlock tables;
+drop table t1;
+# Now test case which was reported originally but which no longer
+# triggers execution path which has caused the problem.
+create table t1 (a int, key(a));
+insert into t1 values (1);
+handler t1 open;
+alter table t1 engine=memory;
+# Since S metadata lock was already acquired at HANDLER OPEN time
+# and TL_READ lock requested by HANDLER READ is compatible with
+# ALTER's TL_WRITE_ALLOW_READ the below statement should succeed
+# without waiting. The old version of table should be used in it.
+handler t1 read a next;
+a
+1
+handler t1 close;
drop table t1;
USE information_schema;
HANDLER COLUMNS OPEN;
ERROR HY000: Incorrect usage of HANDLER OPEN and information_schema
USE test;
#
+# Add test coverage for HANDLER and LOCK TABLES, HANDLER and DDL.
+#
+drop table if exists t1, t2, t3;
+create table t1 (a int, key a (a));
+insert into t1 (a) values (1), (2), (3), (4), (5);
+create table t2 (a int, key a (a)) select * from t1;
+create temporary table t3 (a int, key a (a)) select * from t2;
+handler t1 open;
+handler t2 open;
+handler t3 open;
+#
+# No HANDLER sql is allowed under LOCK TABLES.
+# But it does not implicitly closes all handlers.
+#
+lock table t1 read;
+handler t1 open;
+ERROR HY000: Can't execute the given command because you have active locked tables or an active transaction
+handler t1 read next;
+ERROR HY000: Can't execute the given command because you have active locked tables or an active transaction
+handler t2 close;
+ERROR HY000: Can't execute the given command because you have active locked tables or an active transaction
+handler t3 open;
+ERROR HY000: Can't execute the given command because you have active locked tables or an active transaction
+# After UNLOCK TABLES handlers should be around and
+# we should be able to continue reading through them.
+unlock tables;
+handler t1 read next;
+a
+1
+handler t1 close;
+handler t2 read next;
+a
+1
+handler t2 close;
+handler t3 read next;
+a
+1
+handler t3 close;
+drop temporary table t3;
+#
+# Other operations that implicitly close handler:
+#
+# TRUNCATE
+#
+handler t1 open;
+truncate table t1;
+handler t1 read next;
+ERROR 42S02: Unknown table 't1' in HANDLER
+handler t1 open;
+#
+# CREATE TRIGGER
+#
+create trigger t1_ai after insert on t1 for each row set @a=1;
+handler t1 read next;
+ERROR 42S02: Unknown table 't1' in HANDLER
+#
+# DROP TRIGGER
+#
+handler t1 open;
+drop trigger t1_ai;
+handler t1 read next;
+ERROR 42S02: Unknown table 't1' in HANDLER
+#
+# ALTER TABLE
+#
+handler t1 open;
+alter table t1 add column b int;
+handler t1 read next;
+ERROR 42S02: Unknown table 't1' in HANDLER
+#
+# ANALYZE TABLE
+#
+handler t1 open;
+analyze table t1;
+Table Op Msg_type Msg_text
+test.t1 analyze status Table is already up to date
+handler t1 read next;
+ERROR 42S02: Unknown table 't1' in HANDLER
+#
+# OPTIMIZE TABLE
+#
+handler t1 open;
+optimize table t1;
+Table Op Msg_type Msg_text
+test.t1 optimize status OK
+handler t1 read next;
+ERROR 42S02: Unknown table 't1' in HANDLER
+#
+# REPAIR TABLE
+#
+handler t1 open;
+repair table t1;
+Table Op Msg_type Msg_text
+test.t1 repair status OK
+handler t1 read next;
+ERROR 42S02: Unknown table 't1' in HANDLER
+#
+# DROP TABLE, naturally.
+#
+handler t1 open;
+drop table t1;
+handler t1 read next;
+ERROR 42S02: Unknown table 't1' in HANDLER
+create table t1 (a int, b int, key a (a)) select a from t2;
+#
+# RENAME TABLE, naturally
+#
+handler t1 open;
+rename table t1 to t3;
+handler t1 read next;
+ERROR 42S02: Unknown table 't1' in HANDLER
+#
+# CREATE TABLE (even with IF NOT EXISTS clause,
+# and the table exists).
+#
+handler t2 open;
+create table if not exists t2 (a int);
+Warnings:
+Note 1050 Table 't2' already exists
+handler t2 read next;
+ERROR 42S02: Unknown table 't2' in HANDLER
+rename table t3 to t1;
+drop table t2;
+#
+# FLUSH TABLE doesn't close the table but loses the position
+#
+handler t1 open;
+handler t1 read a prev;
+b a
+NULL 5
+flush table t1;
+handler t1 read a prev;
+b a
+NULL 5
+handler t1 close;
+#
+# FLUSH TABLES WITH READ LOCK behaves like FLUSH TABLE.
+#
+handler t1 open;
+handler t1 read a prev;
+b a
+NULL 5
+flush tables with read lock;
+handler t1 read a prev;
+b a
+NULL 5
+handler t1 close;
+unlock tables;
+#
+# Let us also check that these operations behave in similar
+# way under LOCK TABLES.
+#
+# TRUNCATE under LOCK TABLES.
+#
+handler t1 open;
+lock tables t1 write;
+truncate table t1;
+unlock tables;
+handler t1 read next;
+ERROR 42S02: Unknown table 't1' in HANDLER
+handler t1 open;
+#
+# CREATE TRIGGER under LOCK TABLES.
+#
+lock tables t1 write;
+create trigger t1_ai after insert on t1 for each row set @a=1;
+unlock tables;
+handler t1 read next;
+ERROR 42S02: Unknown table 't1' in HANDLER
+#
+# DROP TRIGGER under LOCK TABLES.
+#
+handler t1 open;
+lock tables t1 write;
+drop trigger t1_ai;
+unlock tables;
+handler t1 read next;
+ERROR 42S02: Unknown table 't1' in HANDLER
+#
+# ALTER TABLE under LOCK TABLES.
+#
+handler t1 open;
+lock tables t1 write;
+alter table t1 drop column b;
+unlock tables;
+handler t1 read next;
+ERROR 42S02: Unknown table 't1' in HANDLER
+#
+# ANALYZE TABLE under LOCK TABLES.
+#
+handler t1 open;
+lock tables t1 write;
+analyze table t1;
+Table Op Msg_type Msg_text
+test.t1 analyze status Table is already up to date
+unlock tables;
+handler t1 read next;
+ERROR 42S02: Unknown table 't1' in HANDLER
+#
+# OPTIMIZE TABLE under LOCK TABLES.
+#
+handler t1 open;
+lock tables t1 write;
+optimize table t1;
+Table Op Msg_type Msg_text
+test.t1 optimize status OK
+unlock tables;
+handler t1 read next;
+ERROR 42S02: Unknown table 't1' in HANDLER
+#
+# REPAIR TABLE under LOCK TABLES.
+#
+handler t1 open;
+lock tables t1 write;
+repair table t1;
+Table Op Msg_type Msg_text
+test.t1 repair status OK
+unlock tables;
+handler t1 read next;
+ERROR 42S02: Unknown table 't1' in HANDLER
+#
+# DROP TABLE under LOCK TABLES, naturally.
+#
+handler t1 open;
+lock tables t1 write;
+drop table t1;
+unlock tables;
+handler t1 read next;
+ERROR 42S02: Unknown table 't1' in HANDLER
+create table t1 (a int, b int, key a (a));
+insert into t1 (a) values (1), (2), (3), (4), (5);
+#
+# FLUSH TABLE doesn't close the table but loses the position
+#
+handler t1 open;
+handler t1 read a prev;
+a b
+5 NULL
+lock tables t1 write;
+flush table t1;
+unlock tables;
+handler t1 read a prev;
+a b
+5 NULL
+handler t1 close;
+#
+# Explore the effect of HANDLER locks on concurrent DDL
+#
+handler t1 open;
+# Establishing auxiliary connections con1, con2, con3
+# --> connection con1;
+# Sending:
+drop table t1 ;
+# We can't use connection 'default' as wait_condition will
+# autoclose handlers.
+# --> connection con2
+# Waitng for 'drop table t1' to get blocked...
+# --> connection default
+handler t1 read a prev;
+a b
+5 NULL
+handler t1 read a prev;
+a b
+4 NULL
+handler t1 close;
+# --> connection con1
+# Reaping 'drop table t1'...
+# --> connection default
+#
+# Explore the effect of HANDLER locks in parallel with SELECT
+#
+create table t1 (a int, key a (a));
+insert into t1 (a) values (1), (2), (3), (4), (5);
+begin;
+select * from t1;
+a
+1
+2
+3
+4
+5
+handler t1 open;
+handler t1 read a prev;
+a
+5
+handler t1 read a prev;
+a
+4
+handler t1 close;
+# --> connection con1;
+# Sending:
+drop table t1 ;
+# --> connection con2
+# Waiting for 'drop table t1' to get blocked...
+# --> connection default
+# We can still use the table, it's part of the transaction
+select * from t1;
+a
+1
+2
+3
+4
+5
+# Such are the circumstances that t1 is a part of transaction,
+# thus we can reopen it in the handler
+handler t1 open;
+# We can commit the transaction, it doesn't close the handler
+# and doesn't let DROP to proceed.
+commit;
+handler t1 read a prev;
+a
+5
+handler t1 read a prev;
+a
+4
+handler t1 read a prev;
+a
+3
+handler t1 close;
+# --> connection con1
+# Now drop can proceed
+# Reaping 'drop table t1'...
+# --> connection default
+#
+# Demonstrate that HANDLER locks and transaction locks
+# reside in the same context, and we don't back-off
+# when have transaction or handler locks.
+#
+create table t1 (a int, key a (a));
+insert into t1 (a) values (1), (2), (3), (4), (5);
+create table t0 (a int, key a (a));
+insert into t0 (a) values (1), (2), (3), (4), (5);
+begin;
+select * from t1;
+a
+1
+2
+3
+4
+5
+# --> connection con2
+# Sending:
+rename table t0 to t3, t1 to t0, t3 to t1;
+# --> connection con1
+# Waiting for 'rename table ...' to get blocked...
+# --> connection default
+handler t0 open;
+ERROR 40001: Deadlock found when trying to get lock; try restarting transaction
+select * from t0;
+ERROR 40001: Deadlock found when trying to get lock; try restarting transaction
+handler t1 open;
+commit;
+handler t1 close;
+# --> connection con2
+# Reaping 'rename table ...'...
+# --> connection default
+handler t1 open;
+handler t1 read a prev;
+a
+5
+handler t1 close;
+drop table t0;
+#
+# Originally there was a deadlock error in this test.
+# With implementation of deadlock detector
+# we no longer deadlock, but block and wait on a lock.
+# The HANDLER is auto-closed as soon as the connection
+# sees a pending conflicting lock against it.
+#
+create table t2 (a int, key a (a));
+handler t1 open;
+# --> connection con1
+lock tables t2 read;
+# --> connection con2
+# Sending 'drop table t2'...
+drop table t2;
+# --> connection con1
+# Waiting for 'drop table t2' to get blocked...
+# --> connection default
+# Sending 'select * from t2'
+select * from t2;
+# --> connection con1
+# Waiting for 'select * from t2' to get blocked...
+unlock tables;
+# --> connection con2
+# Reaping 'drop table t2'...
+# --> connection default
+# Reaping 'select * from t2'
+ERROR 42S02: Table 'test.t2' doesn't exist
+handler t1 close;
+#
+# ROLLBACK TO SAVEPOINT releases transactional locks,
+# but has no effect on open HANDLERs
+#
+create table t2 like t1;
+create table t3 like t1;
+begin;
+# Have something before the savepoint
+select * from t3;
+a
+savepoint sv;
+handler t1 open;
+handler t1 read a first;
+a
+1
+handler t1 read a next;
+a
+2
+select * from t2;
+a
+# --> connection con1
+# Sending:
+drop table t1;
+# --> connection con2
+# Sending:
+drop table t2;
+# --> connection default
+# Let DROP TABLE statements sync in. We must use
+# a separate connection for that, because otherwise SELECT
+# will auto-close the HANDLERs, becaues there are pending
+# exclusive locks against them.
+# --> connection con3
+# Waiting for 'drop table t1' to get blocked...
+# Waiting for 'drop table t2' to get blocked...
+# Demonstrate that t2 lock was released and t2 was dropped
+# after ROLLBACK TO SAVEPOINT
+# --> connection default
+rollback to savepoint sv;
+# --> connection con2
+# Reaping 'drop table t2'...
+# Demonstrate that ROLLBACK TO SAVEPOINT didn't release the handler
+# lock.
+# --> connection default
+handler t1 read a next;
+a
+3
+handler t1 read a next;
+a
+4
+# Demonstrate that the drop will go through as soon as we close the
+# HANDLER
+handler t1 close;
+# connection con1
+# Reaping 'drop table t1'...
+# --> connection default
+commit;
+drop table t3;
+#
+# A few special cases when using SAVEPOINT/ROLLBACK TO
+# SAVEPOINT and HANDLER.
+#
+# Show that rollback to the savepoint taken in the beginning
+# of the transaction doesn't release mdl lock on
+# the HANDLER that was opened later.
+#
+create table t1 (a int, key a(a));
+insert into t1 (a) values (1), (2), (3), (4), (5);
+create table t2 like t1;
+begin;
+savepoint sv;
+handler t1 open;
+handler t1 read a first;
+a
+1
+handler t1 read a next;
+a
+2
+select * from t2;
+a
+# --> connection con1
+# Sending:
+drop table t1;
+# --> connection con2
+# Sending:
+drop table t2;
+# --> connection default
+# Let DROP TABLE statements sync in. We must use
+# a separate connection for that, because otherwise SELECT
+# will auto-close the HANDLERs, becaues there are pending
+# exclusive locks against them.
+# --> connection con3
+# Waiting for 'drop table t1' to get blocked...
+# Waiting for 'drop table t2' to get blocked...
+# Demonstrate that t2 lock was released and t2 was dropped
+# after ROLLBACK TO SAVEPOINT
+# --> connection default
+rollback to savepoint sv;
+# --> connection con2
+# Reaping 'drop table t2'...
+# Demonstrate that ROLLBACK TO SAVEPOINT didn't release the handler
+# lock.
+# --> connection default
+handler t1 read a next;
+a
+3
+handler t1 read a next;
+a
+4
+# Demonstrate that the drop will go through as soon as we close the
+# HANDLER
+handler t1 close;
+# connection con1
+# Reaping 'drop table t1'...
+# --> connection default
+commit;
+#
+# Show that rollback to the savepoint taken in the beginning
+# of the transaction works properly (no valgrind warnins, etc),
+# even though it's done after the HANDLER mdl lock that was there
+# at the beginning is released and added again.
+#
+create table t1 (a int, key a(a));
+insert into t1 (a) values (1), (2), (3), (4), (5);
+create table t2 like t1;
+create table t3 like t1;
+insert into t3 (a) select a from t1;
+begin;
+handler t1 open;
+savepoint sv;
+handler t1 read a first;
+a
+1
+select * from t2;
+a
+handler t1 close;
+handler t3 open;
+handler t3 read a first;
+a
+1
+rollback to savepoint sv;
+# --> connection con1
+drop table t1, t2;
+# Sending:
+drop table t3;
+# Let DROP TABLE statement sync in.
+# --> connection con2
+# Waiting for 'drop table t3' to get blocked...
+# Demonstrate that ROLLBACK TO SAVEPOINT didn't release the handler
+# lock.
+# --> connection default
+handler t3 read a next;
+a
+2
+# Demonstrate that the drop will go through as soon as we close the
+# HANDLER
+handler t3 close;
+# connection con1
+# Reaping 'drop table t3'...
+# --> connection default
+commit;
+#
+# If we have to wait on an exclusive locks while having
+# an open HANDLER, ER_LOCK_DEADLOCK is reported.
+#
+create table t1 (a int, key a(a));
+create table t2 like t1;
+handler t1 open;
+# --> connection con1
+lock table t1 write, t2 write;
+# --> connection default
+drop table t2;
+# --> connection con2
+# Waiting for 'drop table t2' to get blocked...
+# --> connection con1
+drop table t1;
+ERROR 40001: Deadlock found when trying to get lock; try restarting transaction
+unlock tables;
+# --> connection default
+# Demonstrate that there is no deadlock with FLUSH TABLE,
+# even though it is waiting for the other table to go away
+create table t2 like t1;
+# Sending:
+flush table t2;
+# --> connection con2
+drop table t1;
+# --> connection con1
+unlock tables;
+# --> connection default
+# Reaping 'flush table t2'...
+drop table t2;
+#
+# Bug #46224 HANDLER statements within a transaction might
+# lead to deadlocks
+#
+create table t1 (a int, key a(a));
+insert into t1 values (1), (2);
+# --> connection default
+begin;
+select * from t1;
+a
+1
+2
+handler t1 open;
+# --> connection con1
+# Sending:
+lock tables t1 write;
+# --> connection con2
+# Check that 'lock tables t1 write' waits until transaction which
+# has read from the table commits.
+# --> connection default
+# The below 'handler t1 read ...' should not be blocked as
+# 'lock tables t1 write' has not succeeded yet.
+handler t1 read a next;
+a
+1
+# Unblock 'lock tables t1 write'.
+commit;
+# --> connection con1
+# Reap 'lock tables t1 write'.
+# --> connection default
+# Sending:
+handler t1 read a next;
+# --> connection con1
+# Waiting for 'handler t1 read a next' to get blocked...
+# The below 'drop table t1' should be able to proceed without
+# waiting as it will force HANDLER to be closed.
+drop table t1;
+unlock tables;
+# --> connection default
+# Reaping 'handler t1 read a next'...
+ERROR 42S02: Table 'test.t1' doesn't exist
+handler t1 close;
+# --> connection con1
+# --> connection con2
+# --> connection con3
+#
+# A temporary table test.
+# Check that we don't loose positions of HANDLER opened
+# against a temporary table.
+#
+create table t1 (a int, b int, key a (a));
+insert into t1 (a) values (1), (2), (3), (4), (5);
+create temporary table t2 (a int, b int, key a (a));
+insert into t2 (a) select a from t1;
+handler t1 open;
+handler t1 read a next;
+a b
+1 NULL
+handler t2 open;
+handler t2 read a next;
+a b
+1 NULL
+flush table t1;
+handler t2 read a next;
+a b
+2 NULL
+# Sic: the position is lost
+handler t1 read a next;
+a b
+1 NULL
+select * from t1;
+a b
+1 NULL
+2 NULL
+3 NULL
+4 NULL
+5 NULL
+# Sic: the position is not lost
+handler t2 read a next;
+a b
+3 NULL
+select * from t2;
+ERROR HY000: Can't reopen table: 't2'
+handler t2 read a next;
+a b
+4 NULL
+drop table t1;
+drop temporary table t2;
+#
+# A test for lock_table_names()/unlock_table_names() function.
+# It should work properly in presence of open HANDLER.
+#
+create table t1 (a int, b int, key a (a));
+create table t2 like t1;
+create table t3 like t1;
+create table t4 like t1;
+handler t1 open;
+handler t2 open;
+rename table t4 to t5, t3 to t4, t5 to t3;
+handler t1 read first;
+a b
+handler t2 read first;
+a b
+drop table t1, t2, t3, t4;
+#
+# A test for FLUSH TABLES WITH READ LOCK and HANDLER statements.
+#
+set autocommit=0;
+create table t1 (a int, b int, key a (a));
+insert into t1 (a, b) values (1, 1), (2, 1), (3, 2), (4, 2), (5, 5);
+create table t2 like t1;
+insert into t2 (a, b) select a, b from t1;
+create table t3 like t1;
+insert into t3 (a, b) select a, b from t1;
+commit;
+flush tables with read lock;
+handler t1 open;
+lock table t1 read;
+handler t1 read next;
+ERROR HY000: Can't execute the given command because you have active locked tables or an active transaction
+# This implicitly leaves LOCK TABLES but doesn't drop the GLR
+lock table not_exists_write read;
+ERROR 42S02: Table 'test.not_exists_write' doesn't exist
+# We still have the read lock.
+drop table t1;
+ERROR HY000: Can't execute the query because you have a conflicting read lock
+handler t1 read next;
+a b
+1 1
+handler t1 close;
+handler t1 open;
+select a from t2;
+a
+1
+2
+3
+4
+5
+handler t1 read next;
+a b
+1 1
+flush tables with read lock;
+handler t2 open;
+flush tables with read lock;
+handler t1 read next;
+a b
+1 1
+select a from t3;
+a
+1
+2
+3
+4
+5
+handler t2 read next;
+a b
+1 1
+handler t1 close;
+rollback;
+handler t2 close;
+drop table t1;
+ERROR HY000: Can't execute the query because you have a conflicting read lock
+commit;
+flush tables;
+drop table t1;
+ERROR HY000: Can't execute the query because you have a conflicting read lock
+unlock tables;
+drop table t1;
+set autocommit=default;
+drop table t2, t3;
+#
+# HANDLER statement and operation-type aware metadata locks.
+# Check that when we clone a ticket for HANDLER we downrade
+# the lock.
+#
+# Establish an auxiliary connection con1.
+# -> connection default
+create table t1 (a int, b int, key a (a));
+insert into t1 (a, b) values (1, 1), (2, 1), (3, 2), (4, 2), (5, 5);
+begin;
+insert into t1 (a, b) values (6, 6);
+handler t1 open;
+handler t1 read a last;
+a b
+6 6
+insert into t1 (a, b) values (7, 7);
+handler t1 read a last;
+a b
+7 7
+commit;
+# -> connection con1
+# Demonstrate that the HANDLER doesn't hold MDL_SHARED_WRITE.
+lock table t1 write;
+unlock tables;
+# -> connection default
+handler t1 read a prev;
+a b
+6 6
+handler t1 close;
+# Cleanup.
+drop table t1;
+# -> connection con1
+# -> connection default
+#
+# A test for Bug#50555 "handler commands crash server in
+# my_hash_first()".
+#
+handler no_such_table read no_such_index first;
+ERROR 42S02: Unknown table 'no_such_table' in HANDLER
+handler no_such_table close;
+ERROR 42S02: Unknown table 'no_such_table' in HANDLER
+#
+# Bug#50907 Assertion `hash_tables->table->next == __null' on
+# HANDLER OPEN
+#
+DROP TABLE IF EXISTS t1, t2;
+CREATE TEMPORARY TABLE t1 (i INT);
+CREATE TEMPORARY TABLE t2 (i INT);
+HANDLER t2 OPEN;
+HANDLER t2 READ FIRST;
+i
+HANDLER t2 CLOSE;
+DROP TABLE t1, t2;
+#
+# Bug#50912 Assertion `ticket->m_type >= mdl_request->type'
+# failed on HANDLER + I_S
+#
+DROP TABLE IF EXISTS t1;
+CREATE TABLE t1 (id INT);
+HANDLER t1 OPEN;
+SELECT table_name, table_comment FROM information_schema.tables
+WHERE table_schema= 'test' AND table_name= 't1';
+table_name table_comment
+t1
+HANDLER t1 CLOSE;
+DROP TABLE t1;
+#
+# Test for bug #50908 "Assertion `handler_tables_hash.records == 0'
+# failed in enter_locked_tables_mode".
+#
+drop tables if exists t1, t2;
+drop function if exists f1;
+create table t1 (i int);
+insert into t1 values (1), (2);
+create table t2 (j int);
+insert into t2 values (1);
+create function f1() returns int return (select count(*) from t2);
+# Check that open HANDLER survives statement executed in
+# prelocked mode.
+handler t1 open;
+handler t1 read next;
+i
+1
+# The below statement were aborted due to an assertion failure.
+select f1() from t2;
+f1()
+1
+handler t1 read next;
+i
+2
+handler t1 close;
+# Check that the same happens under GLOBAL READ LOCK.
+flush tables with read lock;
+handler t1 open;
+handler t1 read next;
+i
+1
+select f1() from t2;
+f1()
+1
+handler t1 read next;
+i
+2
+unlock tables;
+handler t1 close;
+# Now, check that the same happens if LOCK TABLES is executed.
+handler t1 open;
+handler t1 read next;
+i
+1
+lock table t2 read;
+select * from t2;
+j
+1
+unlock tables;
+handler t1 read next;
+i
+2
+handler t1 close;
+# Finally, check scenario with GRL and LOCK TABLES.
+flush tables with read lock;
+handler t1 open;
+handler t1 read next;
+i
+1
+lock table t2 read;
+select * from t2;
+j
+1
+# This unlocks both tables and GRL.
+unlock tables;
+handler t1 read next;
+i
+2
+handler t1 close;
+# Clean-up.
+drop function f1;
+drop tables t1, t2;
+#
+# Test for bug #51136 "Crash in pthread_rwlock_rdlock on TEMPORARY +
+# HANDLER + LOCK + SP".
+# Also see additional coverage for this bug in flush.test.
+#
+drop tables if exists t1, t2;
+create table t1 (i int);
+create temporary table t2 (j int);
+handler t1 open;
+lock table t2 read;
+# This commit should not release any MDL locks.
+commit;
+unlock tables;
+# The below statement crashed before the bug fix as it
+# has attempted to release metadata lock which was
+# already released by commit.
+handler t1 close;
+drop tables t1, t2;
+#
# BUG #46456: HANDLER OPEN + TRUNCATE + DROP (temporary) TABLE, crash
#
CREATE TABLE t1 AS SELECT 1 AS f1;
diff --git a/mysql-test/r/implicit_commit.result b/mysql-test/r/implicit_commit.result
new file mode 100644
index 00000000000..8c330550a3b
--- /dev/null
+++ b/mysql-test/r/implicit_commit.result
@@ -0,0 +1,1061 @@
+SET GLOBAL EVENT_SCHEDULER = OFF;
+SET BINLOG_FORMAT = STATEMENT;
+CREATE DATABASE db1;
+USE db1;
+CREATE TABLE t1 (a INT, KEY a(a)) ENGINE=INNODB;
+INSERT INTO t1 VALUES (1),(2),(3),(4),(5);
+CREATE TABLE t3 (a INT) ENGINE=MyISAM;
+INSERT INTO t3 SELECT * FROM t1;
+CREATE TABLE trans (a INT) ENGINE=INNODB;
+CREATE PROCEDURE test_if_commit()
+BEGIN
+ROLLBACK;
+SELECT IF (COUNT(*) > 0, "YES", "NO") AS "IMPLICIT COMMIT" FROM trans;
+DELETE FROM trans;
+COMMIT;
+END|
+SET AUTOCOMMIT = FALSE;
+#
+# SQLCOM_SELECT
+#
+INSERT INTO db1.trans (a) VALUES (1);
+select 1 as res from t1 where (1) in (select * from t1);
+CALL db1.test_if_commit();
+IMPLICIT COMMIT
+NO
+#
+# SQLCOM_CREATE_TABLE LIKE
+#
+INSERT INTO db1.trans (a) VALUES (1);
+create table t2 like t1;
+CALL db1.test_if_commit();
+IMPLICIT COMMIT
+YES
+#
+# SQLCOM_SHOW_CREATE
+#
+INSERT INTO db1.trans (a) VALUES (1);
+show create table t2;
+CALL db1.test_if_commit();
+IMPLICIT COMMIT
+NO
+#
+# SQLCOM_DROP_TABLE
+#
+INSERT INTO db1.trans (a) VALUES (1);
+drop table t2;
+CALL db1.test_if_commit();
+IMPLICIT COMMIT
+YES
+#
+# SQLCOM_CREATE_TABLE TEMPORARY
+#
+INSERT INTO db1.trans (a) VALUES (1);
+create temporary table t2 as select * from t1;
+CALL db1.test_if_commit();
+IMPLICIT COMMIT
+NO
+#
+# SQLCOM_DROP_TABLE TEMPORARY
+#
+INSERT INTO db1.trans (a) VALUES (1);
+drop temporary table t2;
+CALL db1.test_if_commit();
+IMPLICIT COMMIT
+NO
+#
+# SQLCOM_CREATE_TABLE
+#
+INSERT INTO db1.trans (a) VALUES (1);
+create table t2 as select * from t1;
+CALL db1.test_if_commit();
+IMPLICIT COMMIT
+YES
+#
+# SQLCOM_UPDATE
+#
+INSERT INTO db1.trans (a) VALUES (1);
+update t2 set a=a+1 where (1) in (select * from t1);
+CALL db1.test_if_commit();
+IMPLICIT COMMIT
+NO
+#
+# SQLCOM_INSERT
+#
+INSERT INTO db1.trans (a) VALUES (1);
+insert into t2 set a=((1) in (select * from t1));
+CALL db1.test_if_commit();
+IMPLICIT COMMIT
+NO
+#
+# SQLCOM_INSERT_SELECT
+#
+INSERT INTO db1.trans (a) VALUES (1);
+insert into t2 select * from t1;
+CALL db1.test_if_commit();
+IMPLICIT COMMIT
+NO
+#
+# SQLCOM_REPLACE
+#
+INSERT INTO db1.trans (a) VALUES (1);
+replace t2 set a=((1) in (select * from t1));
+CALL db1.test_if_commit();
+IMPLICIT COMMIT
+NO
+#
+# SQLCOM_REPLACE_SELECT
+#
+INSERT INTO db1.trans (a) VALUES (1);
+replace t2 select * from t1;
+CALL db1.test_if_commit();
+IMPLICIT COMMIT
+NO
+#
+# SQLCOM_DELETE
+#
+INSERT INTO db1.trans (a) VALUES (1);
+delete from t2 where (1) in (select * from t1);
+CALL db1.test_if_commit();
+IMPLICIT COMMIT
+NO
+#
+# SQLCOM_DELETE_MULTI
+#
+INSERT INTO db1.trans (a) VALUES (1);
+delete t2, t3 from t2, t3 where (1) in (select * from t1);
+CALL db1.test_if_commit();
+IMPLICIT COMMIT
+NO
+#
+# SQLCOM_UPDATE_MULTI
+#
+select * from t2;
+a
+INSERT INTO db1.trans (a) VALUES (1);
+update t2, t3 set t3.a=t2.a, t2.a=null where (1) in (select * from t1);
+CALL db1.test_if_commit();
+IMPLICIT COMMIT
+NO
+#
+# SQLCOM_LOAD
+#
+create table t4 (a varchar(100));
+INSERT INTO db1.trans (a) VALUES (1);
+load data infile '../../std_data/words.dat' into table t4;
+CALL db1.test_if_commit();
+IMPLICIT COMMIT
+NO
+drop table t4;
+#
+# SQLCOM_SHOW_DATABASES
+#
+INSERT INTO db1.trans (a) VALUES (1);
+show databases where (1) in (select * from t1);
+CALL db1.test_if_commit();
+IMPLICIT COMMIT
+NO
+#
+# SQLCOM_SHOW_TABLES
+#
+INSERT INTO db1.trans (a) VALUES (1);
+show tables where (1) in (select * from t1);
+CALL db1.test_if_commit();
+IMPLICIT COMMIT
+NO
+#
+# SQLCOM_SHOW_FIELDS
+#
+INSERT INTO db1.trans (a) VALUES (1);
+show fields from t1 where (1) in (select * from t1);
+CALL db1.test_if_commit();
+IMPLICIT COMMIT
+NO
+#
+# SQLCOM_SHOW_KEYS
+#
+INSERT INTO db1.trans (a) VALUES (1);
+show keys from t1 where (1) in (select * from t1);
+CALL db1.test_if_commit();
+IMPLICIT COMMIT
+NO
+#
+# SQLCOM_SHOW_VARIABLES
+#
+INSERT INTO db1.trans (a) VALUES (1);
+show variables where (1) in (select * from t1);
+CALL db1.test_if_commit();
+IMPLICIT COMMIT
+NO
+#
+# SQLCOM_SHOW_STATUS
+#
+INSERT INTO db1.trans (a) VALUES (1);
+show status where (1) in (select * from t1);
+CALL db1.test_if_commit();
+IMPLICIT COMMIT
+NO
+#
+# SQLCOM_SHOW_ENGINE_MUTEX
+#
+INSERT INTO db1.trans (a) VALUES (1);
+show engine all mutex;
+CALL db1.test_if_commit();
+IMPLICIT COMMIT
+NO
+#
+# SQLCOM_SHOW_PROCESSLIST
+#
+INSERT INTO db1.trans (a) VALUES (1);
+show processlist;
+CALL db1.test_if_commit();
+IMPLICIT COMMIT
+NO
+#
+# SQLCOM_SHOW_ENGINE_LOGS
+#
+INSERT INTO db1.trans (a) VALUES (1);
+show engine all logs;
+CALL db1.test_if_commit();
+IMPLICIT COMMIT
+NO
+#
+# SQLCOM_SHOW_ENGINE_STATUS
+#
+INSERT INTO db1.trans (a) VALUES (1);
+show engine all status;
+CALL db1.test_if_commit();
+IMPLICIT COMMIT
+NO
+#
+# SQLCOM_SHOW_CHARSETS
+#
+INSERT INTO db1.trans (a) VALUES (1);
+show charset where (1) in (select * from t1);
+CALL db1.test_if_commit();
+IMPLICIT COMMIT
+NO
+#
+# SQLCOM_SHOW_COLLATIONS
+#
+INSERT INTO db1.trans (a) VALUES (1);
+show collation where (1) in (select * from t1);
+CALL db1.test_if_commit();
+IMPLICIT COMMIT
+NO
+#
+# SQLCOM_SHOW_TABLE_STATUS
+#
+INSERT INTO db1.trans (a) VALUES (1);
+show table status where (1) in (select * from t1);
+CALL db1.test_if_commit();
+IMPLICIT COMMIT
+NO
+#
+# SQLCOM_SHOW_TRIGGERS
+#
+INSERT INTO db1.trans (a) VALUES (1);
+show triggers where (1) in (select * from t1);
+CALL db1.test_if_commit();
+IMPLICIT COMMIT
+NO
+#
+# SQLCOM_SHOW_OPEN_TABLES
+#
+INSERT INTO db1.trans (a) VALUES (1);
+show open tables where (1) in (select * from t1);
+CALL db1.test_if_commit();
+IMPLICIT COMMIT
+NO
+#
+# SQLCOM_SHOW_STATUS_PROC
+#
+INSERT INTO db1.trans (a) VALUES (1);
+show procedure status where (1) in (select * from t1);
+CALL db1.test_if_commit();
+IMPLICIT COMMIT
+NO
+#
+# SQLCOM_SHOW_STATUS_FUNC
+#
+INSERT INTO db1.trans (a) VALUES (1);
+show function status where (1) in (select * from t1);
+CALL db1.test_if_commit();
+IMPLICIT COMMIT
+NO
+#
+# SQLCOM_SET_OPTION
+#
+INSERT INTO db1.trans (a) VALUES (1);
+set @a=((1) in (select * from t1));
+CALL db1.test_if_commit();
+IMPLICIT COMMIT
+NO
+#
+# SQLCOM_DO
+#
+INSERT INTO db1.trans (a) VALUES (1);
+do ((1) in (select * from t1));
+CALL db1.test_if_commit();
+IMPLICIT COMMIT
+NO
+#
+# SQLCOM_CALL
+#
+create procedure p1(a int) begin end;
+INSERT INTO db1.trans (a) VALUES (1);
+call p1((1) in (select * from t1));
+CALL db1.test_if_commit();
+IMPLICIT COMMIT
+NO
+drop procedure p1;
+#
+# SQLCOM_CREATE_VIEW
+#
+INSERT INTO db1.trans (a) VALUES (1);
+create view v1 as select * from t1;
+CALL db1.test_if_commit();
+IMPLICIT COMMIT
+YES
+#
+# SQLCOM_ALTER_VIEW
+#
+INSERT INTO db1.trans (a) VALUES (1);
+alter view v1 as select 2;
+CALL db1.test_if_commit();
+IMPLICIT COMMIT
+YES
+#
+# SQLCOM_DROP_VIEW
+#
+INSERT INTO db1.trans (a) VALUES (1);
+drop view v1;
+CALL db1.test_if_commit();
+IMPLICIT COMMIT
+YES
+#
+# SQLCOM_CREATE_INDEX
+#
+INSERT INTO db1.trans (a) VALUES (1);
+create index idx1 on t1(a);
+CALL db1.test_if_commit();
+IMPLICIT COMMIT
+YES
+#
+# SQLCOM_DROP_INDEX
+#
+INSERT INTO db1.trans (a) VALUES (1);
+drop index idx1 on t1;
+CALL db1.test_if_commit();
+IMPLICIT COMMIT
+YES
+#
+# SQLCOM_ALTER_TABLE
+#
+INSERT INTO db1.trans (a) VALUES (1);
+alter table t1 add column b int;
+CALL db1.test_if_commit();
+IMPLICIT COMMIT
+YES
+INSERT INTO db1.trans (a) VALUES (1);
+alter table t1 change b c int;
+CALL db1.test_if_commit();
+IMPLICIT COMMIT
+YES
+INSERT INTO db1.trans (a) VALUES (1);
+alter table t1 drop column c;
+CALL db1.test_if_commit();
+IMPLICIT COMMIT
+YES
+#
+# SQLCOM_ALTER_TABLE TEMPORARY
+#
+create temporary table t4 (a int);
+INSERT INTO db1.trans (a) VALUES (1);
+alter table t1 add column b int;
+CALL db1.test_if_commit();
+IMPLICIT COMMIT
+YES
+INSERT INTO db1.trans (a) VALUES (1);
+alter table t1 change b c int;
+CALL db1.test_if_commit();
+IMPLICIT COMMIT
+YES
+INSERT INTO db1.trans (a) VALUES (1);
+alter table t1 drop column c;
+CALL db1.test_if_commit();
+IMPLICIT COMMIT
+YES
+drop table t4;
+#
+# SQLCOM_TRUNCATE
+#
+insert into t2 select * from t1;
+INSERT INTO db1.trans (a) VALUES (1);
+truncate table t2;
+CALL db1.test_if_commit();
+IMPLICIT COMMIT
+YES
+insert into t2 select * from t1;
+#
+# SQLCOM_TRUNCATE TEMPORARY
+#
+create temporary table t4 as select * from t1;
+INSERT INTO db1.trans (a) VALUES (1);
+truncate table t4;
+CALL db1.test_if_commit();
+IMPLICIT COMMIT
+YES
+drop temporary table t4;
+#
+# SQLCOM_SHOW_MASTER_STAT
+#
+INSERT INTO db1.trans (a) VALUES (1);
+show master status;
+CALL db1.test_if_commit();
+IMPLICIT COMMIT
+NO
+#
+# SQLCOM_SHOW_SLAVE_STAT
+#
+INSERT INTO db1.trans (a) VALUES (1);
+show slave status;
+CALL db1.test_if_commit();
+IMPLICIT COMMIT
+NO
+#
+# SQLCOM_GRANT
+#
+INSERT INTO db1.trans (a) VALUES (1);
+grant all on test.t1 to mysqltest_2@localhost with grant option;
+CALL db1.test_if_commit();
+IMPLICIT COMMIT
+YES
+#
+# SQLCOM_REVOKE
+#
+INSERT INTO db1.trans (a) VALUES (1);
+revoke select on test.t1 from mysqltest_2@localhost;
+CALL db1.test_if_commit();
+IMPLICIT COMMIT
+YES
+#
+# SQLCOM_REVOKE_ALL
+#
+INSERT INTO db1.trans (a) VALUES (1);
+revoke all on test.t1 from mysqltest_2@localhost;
+CALL db1.test_if_commit();
+IMPLICIT COMMIT
+YES
+drop user mysqltest_2@localhost;
+#
+# SQLCOM_SHOW_GRANTS
+#
+INSERT INTO db1.trans (a) VALUES (1);
+show grants;
+CALL db1.test_if_commit();
+IMPLICIT COMMIT
+NO
+INSERT INTO db1.trans (a) VALUES (1);
+show grants for current_user();
+CALL db1.test_if_commit();
+IMPLICIT COMMIT
+NO
+#
+# SQLCOM_LOCK_TABLES
+#
+INSERT INTO db1.trans (a) VALUES (1);
+lock tables t1 write, trans write;
+CALL db1.test_if_commit();
+IMPLICIT COMMIT
+YES
+#
+# SQLCOM_UNLOCK_TABLES
+#
+INSERT INTO db1.trans (a) VALUES (1);
+unlock tables;
+CALL db1.test_if_commit();
+IMPLICIT COMMIT
+YES
+#
+# SQLCOM_CREATE_DB
+#
+INSERT INTO db1.trans (a) VALUES (1);
+create database db2;
+CALL db1.test_if_commit();
+IMPLICIT COMMIT
+YES
+#
+# SQLCOM_CHANGE_DB
+#
+create table db2.t1 (a int);
+insert into db2.t1 values (1);
+commit;
+INSERT INTO db1.trans (a) VALUES (1);
+use db2;
+CALL db1.test_if_commit();
+IMPLICIT COMMIT
+NO
+#
+# SQLCOM_SHOW_CREATE_DB
+#
+INSERT INTO db1.trans (a) VALUES (1);
+show create database db2;
+CALL db1.test_if_commit();
+IMPLICIT COMMIT
+NO
+#
+# SQLCOM_ALTER_DB
+#
+#
+# SQLCOM_ALTER_DB_UPGRADE
+#
+#
+# SQLCOM_DROP_DB
+#
+use db1;
+INSERT INTO db1.trans (a) VALUES (1);
+drop database db2;
+CALL db1.test_if_commit();
+IMPLICIT COMMIT
+YES
+#
+# SQLCOM_REPAIR
+#
+INSERT INTO db1.trans (a) VALUES (1);
+repair table t2;
+CALL db1.test_if_commit();
+IMPLICIT COMMIT
+YES
+INSERT INTO db1.trans (a) VALUES (1);
+repair table t2 use_frm;
+CALL db1.test_if_commit();
+IMPLICIT COMMIT
+YES
+#
+# SQLCOM_OPTIMIZE
+#
+INSERT INTO db1.trans (a) VALUES (1);
+optimize table t1;
+CALL db1.test_if_commit();
+IMPLICIT COMMIT
+YES
+#
+# SQLCOM_CHECK
+#
+INSERT INTO db1.trans (a) VALUES (1);
+check table t1;
+CALL db1.test_if_commit();
+IMPLICIT COMMIT
+YES
+INSERT INTO db1.trans (a) VALUES (1);
+check table t1 extended;
+CALL db1.test_if_commit();
+IMPLICIT COMMIT
+YES
+#
+# SQLCOM_ASSIGN_TO_KEYCACHE
+#
+set global keycache.key_buffer_size=128*1024;
+INSERT INTO db1.trans (a) VALUES (1);
+cache index t3 in keycache;
+CALL db1.test_if_commit();
+IMPLICIT COMMIT
+YES
+set global keycache.key_buffer_size=0;
+#
+# SQLCOM_PRELOAD_KEYS
+#
+INSERT INTO db1.trans (a) VALUES (1);
+load index into cache t3;
+CALL db1.test_if_commit();
+IMPLICIT COMMIT
+YES
+#
+# SQLCOM_FLUSH
+#
+INSERT INTO db1.trans (a) VALUES (1);
+flush local privileges;
+CALL db1.test_if_commit();
+IMPLICIT COMMIT
+YES
+INSERT INTO db1.trans (a) VALUES (1);
+flush privileges;
+CALL db1.test_if_commit();
+IMPLICIT COMMIT
+YES
+#
+# SQLCOM_KILL
+#
+#
+# SQLCOM_ANALYZE
+#
+INSERT INTO db1.trans (a) VALUES (1);
+analyze table t1;
+CALL db1.test_if_commit();
+IMPLICIT COMMIT
+YES
+#
+# SQLCOM_ROLLBACK
+#
+INSERT INTO db1.trans (a) VALUES (1);
+rollback;
+CALL db1.test_if_commit();
+IMPLICIT COMMIT
+NO
+#
+# SQLCOM_ROLLBACK_TO_SAVEPOINT
+#
+#
+# SQLCOM_COMMIT
+#
+INSERT INTO db1.trans (a) VALUES (1);
+commit;
+CALL db1.test_if_commit();
+IMPLICIT COMMIT
+YES
+#
+# SQLCOM_SAVEPOINT
+#
+INSERT INTO db1.trans (a) VALUES (1);
+savepoint sp1;
+CALL db1.test_if_commit();
+IMPLICIT COMMIT
+NO
+#
+# SQLCOM_RELEASE_SAVEPOINT
+#
+#
+# SQLCOM_SLAVE_START
+#
+#
+# SQLCOM_SLAVE_STOP
+#
+#
+# SQLCOM_BEGIN
+#
+INSERT INTO db1.trans (a) VALUES (1);
+begin;
+CALL db1.test_if_commit();
+IMPLICIT COMMIT
+YES
+#
+# SQLCOM_CHANGE_MASTER
+#
+#
+# SQLCOM_RENAME_TABLE
+#
+INSERT INTO db1.trans (a) VALUES (1);
+rename table t3 to t4;
+CALL db1.test_if_commit();
+IMPLICIT COMMIT
+YES
+INSERT INTO db1.trans (a) VALUES (1);
+rename table t4 to t3;
+CALL db1.test_if_commit();
+IMPLICIT COMMIT
+YES
+#
+# SQLCOM_RESET
+#
+#
+# SQLCOM_PURGE
+#
+#
+# SQLCOM_PURGE_BEFORE
+#
+#
+# SQLCOM_SHOW_BINLOGS
+#
+#
+# SQLCOM_HA_OPEN
+#
+INSERT INTO db1.trans (a) VALUES (1);
+handler t1 open as ha1;
+CALL db1.test_if_commit();
+IMPLICIT COMMIT
+NO
+#
+# SQLCOM_HA_READ
+#
+INSERT INTO db1.trans (a) VALUES (1);
+handler ha1 read a first;
+CALL db1.test_if_commit();
+IMPLICIT COMMIT
+NO
+#
+# SQLCOM_HA_CLOSE
+#
+INSERT INTO db1.trans (a) VALUES (1);
+handler ha1 close;
+CALL db1.test_if_commit();
+IMPLICIT COMMIT
+NO
+#
+# SQLCOM_SHOW_SLAVE_HOSTS
+#
+INSERT INTO db1.trans (a) VALUES (1);
+show slave hosts;
+CALL db1.test_if_commit();
+IMPLICIT COMMIT
+NO
+#
+# SQLCOM_SHOW_BINLOG_EVENTS
+#
+INSERT INTO db1.trans (a) VALUES (1);
+show binlog events;
+CALL db1.test_if_commit();
+IMPLICIT COMMIT
+NO
+#
+# SQLCOM_SHOW_NEW_MASTER
+#
+#
+# SQLCOM_SHOW_WARNS
+#
+INSERT INTO db1.trans (a) VALUES (1);
+show warnings;
+CALL db1.test_if_commit();
+IMPLICIT COMMIT
+NO
+#
+# SQLCOM_EMPTY_QUERY
+#
+#
+# SQLCOM_SHOW_ERRORS
+#
+INSERT INTO db1.trans (a) VALUES (1);
+show errors;
+CALL db1.test_if_commit();
+IMPLICIT COMMIT
+NO
+#
+# SQLCOM_SHOW_STORAGE_ENGINES
+#
+INSERT INTO db1.trans (a) VALUES (1);
+show engines;
+CALL db1.test_if_commit();
+IMPLICIT COMMIT
+NO
+#
+# SQLCOM_SHOW_PRIVILEGES
+#
+INSERT INTO db1.trans (a) VALUES (1);
+show privileges;
+CALL db1.test_if_commit();
+IMPLICIT COMMIT
+NO
+#
+# SQLCOM_HELP
+#
+INSERT INTO db1.trans (a) VALUES (1);
+help 'foo';
+CALL db1.test_if_commit();
+IMPLICIT COMMIT
+NO
+#
+# SQLCOM_CREATE_USER
+#
+INSERT INTO db1.trans (a) VALUES (1);
+create user trxusr1;
+CALL db1.test_if_commit();
+IMPLICIT COMMIT
+YES
+#
+# SQLCOM_RENAME_USER
+#
+INSERT INTO db1.trans (a) VALUES (1);
+rename user 'trxusr1' to 'trxusr2';
+CALL db1.test_if_commit();
+IMPLICIT COMMIT
+YES
+#
+# SQLCOM_DROP_USER
+#
+INSERT INTO db1.trans (a) VALUES (1);
+drop user trxusr2;
+CALL db1.test_if_commit();
+IMPLICIT COMMIT
+YES
+#
+# SQLCOM_CHECKSUM
+#
+INSERT INTO db1.trans (a) VALUES (1);
+checksum table t1;
+CALL db1.test_if_commit();
+IMPLICIT COMMIT
+NO
+#
+# SQLCOM_CREATE_PROCEDURE
+#
+INSERT INTO db1.trans (a) VALUES (1);
+create procedure p1(a int) begin end;
+CALL db1.test_if_commit();
+IMPLICIT COMMIT
+YES
+#
+# SQLCOM_ALTER_PROCEDURE
+#
+INSERT INTO db1.trans (a) VALUES (1);
+alter procedure p1 comment 'foobar';
+CALL db1.test_if_commit();
+IMPLICIT COMMIT
+YES
+#
+# SQLCOM_SHOW_CREATE_PROC
+#
+INSERT INTO db1.trans (a) VALUES (1);
+show create procedure p1;
+CALL db1.test_if_commit();
+IMPLICIT COMMIT
+NO
+#
+# SQLCOM_SHOW_STATUS_PROC
+#
+INSERT INTO db1.trans (a) VALUES (1);
+show procedure status;
+CALL db1.test_if_commit();
+IMPLICIT COMMIT
+NO
+#
+# SQLCOM_SHOW_PROC_CODE
+#
+INSERT INTO db1.trans (a) VALUES (1);
+show procedure code p1;
+CALL db1.test_if_commit();
+IMPLICIT COMMIT
+NO
+#
+# SQLCOM_DROP_PROCEDURE
+#
+INSERT INTO db1.trans (a) VALUES (1);
+drop procedure p1;
+CALL db1.test_if_commit();
+IMPLICIT COMMIT
+YES
+#
+# SQLCOM_CREATE_FUNCTION
+#
+#
+# SQLCOM_DROP_FUNCTION
+#
+#
+# SQLCOM_CREATE_SPFUNCTION
+#
+INSERT INTO db1.trans (a) VALUES (1);
+create function f1() returns int return 69;
+CALL db1.test_if_commit();
+IMPLICIT COMMIT
+YES
+#
+# SQLCOM_ALTER_FUNCTION
+#
+INSERT INTO db1.trans (a) VALUES (1);
+alter function f1 comment 'comment';
+CALL db1.test_if_commit();
+IMPLICIT COMMIT
+YES
+#
+# SQLCOM_SHOW_CREATE_FUNC
+#
+INSERT INTO db1.trans (a) VALUES (1);
+show create function f1;
+CALL db1.test_if_commit();
+IMPLICIT COMMIT
+NO
+#
+# SQLCOM_SHOW_STATUS_FUNC
+#
+INSERT INTO db1.trans (a) VALUES (1);
+show function status like '%f%';
+CALL db1.test_if_commit();
+IMPLICIT COMMIT
+NO
+#
+# SQLCOM_SHOW_FUNC_CODE
+#
+INSERT INTO db1.trans (a) VALUES (1);
+show function code f1;
+CALL db1.test_if_commit();
+IMPLICIT COMMIT
+NO
+#
+# SQLCOM_PREPARE
+#
+INSERT INTO db1.trans (a) VALUES (1);
+prepare stmt1 from "insert into t1 values (5)";
+CALL db1.test_if_commit();
+IMPLICIT COMMIT
+NO
+#
+# SQLCOM_EXECUTE
+#
+INSERT INTO db1.trans (a) VALUES (1);
+execute stmt1;
+CALL db1.test_if_commit();
+IMPLICIT COMMIT
+NO
+#
+# SQLCOM_DEALLOCATE_PREPARE
+#
+INSERT INTO db1.trans (a) VALUES (1);
+deallocate prepare stmt1;
+CALL db1.test_if_commit();
+IMPLICIT COMMIT
+NO
+#
+# SQLCOM_CREATE_TRIGGER
+#
+INSERT INTO db1.trans (a) VALUES (1);
+create trigger trg1 before insert on t1 for each row set @a:=1;
+CALL db1.test_if_commit();
+IMPLICIT COMMIT
+YES
+#
+# SQLCOM_SHOW_CREATE_TRIGGER
+#
+INSERT INTO db1.trans (a) VALUES (1);
+show create trigger trg1;
+CALL db1.test_if_commit();
+IMPLICIT COMMIT
+NO
+#
+# SQLCOM_DROP_TRIGGER
+#
+INSERT INTO db1.trans (a) VALUES (1);
+drop trigger trg1;
+CALL db1.test_if_commit();
+IMPLICIT COMMIT
+YES
+#
+# SQLCOM_XA_START
+#
+#
+# SQLCOM_XA_END
+#
+#
+# SQLCOM_XA_PREPARE
+#
+#
+# SQLCOM_XA_COMMIT
+#
+#
+# SQLCOM_XA_ROLLBACK
+#
+#
+# SQLCOM_XA_RECOVER
+#
+#
+# SQLCOM_ALTER_TABLESPACE
+#
+#
+# SQLCOM_INSTALL_PLUGIN
+#
+#
+# SQLCOM_SHOW_PLUGINS
+#
+#
+# SQLCOM_UNINSTALL_PLUGIN
+#
+#
+# SQLCOM_SHOW_AUTHORS
+#
+INSERT INTO db1.trans (a) VALUES (1);
+show authors;
+CALL db1.test_if_commit();
+IMPLICIT COMMIT
+NO
+#
+# SQLCOM_BINLOG_BASE64_EVENT
+#
+#
+# SQLCOM_SHOW_CONTRIBUTORS
+#
+INSERT INTO db1.trans (a) VALUES (1);
+show contributors;
+CALL db1.test_if_commit();
+IMPLICIT COMMIT
+NO
+#
+# SQLCOM_CREATE_SERVER
+#
+#
+# SQLCOM_ALTER_SERVER
+#
+#
+# SQLCOM_DROP_SERVER
+#
+#
+# SQLCOM_CREATE_EVENT
+#
+INSERT INTO db1.trans (a) VALUES (1);
+create event ev1 on schedule every 1 second do insert into t1 values (6);
+CALL db1.test_if_commit();
+IMPLICIT COMMIT
+YES
+#
+# SQLCOM_ALTER_EVENT
+#
+INSERT INTO db1.trans (a) VALUES (1);
+alter event ev1 rename to ev2 disable;
+CALL db1.test_if_commit();
+IMPLICIT COMMIT
+YES
+#
+# SQLCOM_SHOW_CREATE_EVENT
+#
+INSERT INTO db1.trans (a) VALUES (1);
+show create event ev2;
+CALL db1.test_if_commit();
+IMPLICIT COMMIT
+NO
+#
+# SQLCOM_SHOW_EVENTS
+#
+INSERT INTO db1.trans (a) VALUES (1);
+show events;
+CALL db1.test_if_commit();
+IMPLICIT COMMIT
+NO
+#
+# SQLCOM_DROP_EVENT
+#
+INSERT INTO db1.trans (a) VALUES (1);
+drop event ev2;
+CALL db1.test_if_commit();
+IMPLICIT COMMIT
+YES
+#
+# SQLCOM_BACKUP
+#
+#
+# SQLCOM_SHOW_ARCHIVE
+#
+#
+# SQLCOM_RESTORE
+#
+#
+# SQLCOM_BACKUP_TEST
+#
+#
+# SQLCOM_SHOW_PROFILE
+#
+INSERT INTO db1.trans (a) VALUES (1);
+show profile memory;
+CALL db1.test_if_commit();
+IMPLICIT COMMIT
+NO
+#
+# SQLCOM_SHOW_PROFILES
+#
+INSERT INTO db1.trans (a) VALUES (1);
+show profiles;
+CALL db1.test_if_commit();
+IMPLICIT COMMIT
+NO
+DROP TABLE t1;
+DROP TABLE t2;
+DROP TABLE t3;
+USE test;
+DROP DATABASE db1;
+End of tests
diff --git a/mysql-test/r/information_schema.result b/mysql-test/r/information_schema.result
index 3041c195b59..aedddf7571f 100644
--- a/mysql-test/r/information_schema.result
+++ b/mysql-test/r/information_schema.result
@@ -1682,6 +1682,57 @@ DROP USER nonpriv;
DROP TABLE db1.t1;
DROP DATABASE db1;
End of 5.1 tests.
+#
+# Additional test for WL#3726 "DDL locking for all metadata objects"
+# To avoid possible deadlocks process of filling of I_S tables should
+# use high-priority metadata lock requests when opening tables.
+# Below we just test that we really use high-priority lock request
+# since reproducing a deadlock will require much more complex test.
+#
+drop tables if exists t1, t2, t3;
+create table t1 (i int);
+create table t2 (j int primary key auto_increment);
+# Switching to connection 'con3726_1'
+lock table t2 read;
+# Switching to connection 'con3726_2'
+# RENAME below will be blocked by 'lock table t2 read' above but
+# will add two pending requests for exclusive metadata locks.
+rename table t2 to t3;
+# Switching to connection 'default'
+# These statements should not be blocked by pending lock requests
+select table_name, column_name, data_type from information_schema.columns
+where table_schema = 'test' and table_name in ('t1', 't2');
+table_name column_name data_type
+t1 i int
+t2 j int
+select table_name, auto_increment from information_schema.tables
+where table_schema = 'test' and table_name in ('t1', 't2');
+table_name auto_increment
+t1 NULL
+t2 1
+# Switching to connection 'con3726_1'
+unlock tables;
+# Switching to connection 'con3726_2'
+# Switching to connection 'default'
+drop tables t1, t3;
+EXPLAIN SELECT * FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE KEY_COLUMN_USAGE ALL NULL NULL NULL NULL NULL Open_full_table; Scanned all databases
+EXPLAIN SELECT * FROM INFORMATION_SCHEMA.PARTITIONS WHERE TABLE_NAME='t1';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE PARTITIONS ALL NULL TABLE_NAME NULL NULL NULL Using where; Open_full_table; Scanned 1 database
+EXPLAIN SELECT * FROM INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS
+WHERE CONSTRAINT_SCHEMA='test';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE REFERENTIAL_CONSTRAINTS ALL NULL CONSTRAINT_SCHEMA NULL NULL NULL Using where; Open_full_table; Scanned 1 database
+EXPLAIN SELECT * FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS
+WHERE TABLE_NAME='t1' and TABLE_SCHEMA='test';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE TABLE_CONSTRAINTS ALL NULL TABLE_SCHEMA,TABLE_NAME NULL NULL NULL Using where; Open_full_table; Scanned 0 databases
+EXPLAIN SELECT * FROM INFORMATION_SCHEMA.TRIGGERS
+WHERE EVENT_OBJECT_SCHEMA='test';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE TRIGGERS ALL NULL EVENT_OBJECT_SCHEMA NULL NULL NULL Using where; Open_frm_only; Scanned 1 database
create table information_schema.t1 (f1 INT);
ERROR 42000: Access denied for user 'root'@'localhost' to database 'information_schema'
drop table information_schema.t1;
@@ -1720,28 +1771,10 @@ ERROR 42000: Access denied for user 'root'@'localhost' to database 'information_
LOCK TABLES t1 READ, information_schema.tables READ;
ERROR 42000: Access denied for user 'root'@'localhost' to database 'information_schema'
DROP TABLE t1;
-EXPLAIN SELECT * FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE;
-id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE KEY_COLUMN_USAGE ALL NULL NULL NULL NULL NULL Open_full_table; Scanned all databases
-EXPLAIN SELECT * FROM INFORMATION_SCHEMA.PARTITIONS WHERE TABLE_NAME='t1';
-id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE PARTITIONS ALL NULL TABLE_NAME NULL NULL NULL Using where; Open_full_table; Scanned 1 database
-EXPLAIN SELECT * FROM INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS
-WHERE CONSTRAINT_SCHEMA='test';
-id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE REFERENTIAL_CONSTRAINTS ALL NULL CONSTRAINT_SCHEMA NULL NULL NULL Using where; Open_full_table; Scanned 1 database
-EXPLAIN SELECT * FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS
-WHERE TABLE_NAME='t1' and TABLE_SCHEMA='test';
-id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE TABLE_CONSTRAINTS ALL NULL TABLE_SCHEMA,TABLE_NAME NULL NULL NULL Using where; Open_full_table; Scanned 0 databases
-EXPLAIN SELECT * FROM INFORMATION_SCHEMA.TRIGGERS
-WHERE EVENT_OBJECT_SCHEMA='test';
-id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE TRIGGERS ALL NULL EVENT_OBJECT_SCHEMA NULL NULL NULL Using where; Open_frm_only; Scanned 1 database
SELECT *
-FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE
-LEFT JOIN INFORMATION_SCHEMA.COLUMNS
-USING (TABLE_SCHEMA, TABLE_NAME, COLUMN_NAME)
-WHERE COLUMNS.TABLE_SCHEMA = 'test'
+FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE
+LEFT JOIN INFORMATION_SCHEMA.COLUMNS
+USING (TABLE_SCHEMA, TABLE_NAME, COLUMN_NAME)
+WHERE COLUMNS.TABLE_SCHEMA = 'test'
AND COLUMNS.TABLE_NAME = 't1';
TABLE_SCHEMA TABLE_NAME COLUMN_NAME CONSTRAINT_CATALOG CONSTRAINT_SCHEMA CONSTRAINT_NAME TABLE_CATALOG ORDINAL_POSITION POSITION_IN_UNIQUE_CONSTRAINT REFERENCED_TABLE_SCHEMA REFERENCED_TABLE_NAME REFERENCED_COLUMN_NAME TABLE_CATALOG ORDINAL_POSITION COLUMN_DEFAULT IS_NULLABLE DATA_TYPE CHARACTER_MAXIMUM_LENGTH CHARACTER_OCTET_LENGTH NUMERIC_PRECISION NUMERIC_SCALE CHARACTER_SET_NAME COLLATION_NAME COLUMN_TYPE COLUMN_KEY EXTRA PRIVILEGES COLUMN_COMMENT
diff --git a/mysql-test/r/innodb-lock.result b/mysql-test/r/innodb-lock.result
index 4ace4065c34..ab7e9aa7b25 100644
--- a/mysql-test/r/innodb-lock.result
+++ b/mysql-test/r/innodb-lock.result
@@ -25,6 +25,12 @@ id x
0 2
commit;
drop table t1;
+#
+# Old lock method (where LOCK TABLE was ignored by InnoDB) no longer
+# works due to fix for bugs #46272 "MySQL 5.4.4, new MDL: unnecessary
+# deadlock" and bug #37346 "innodb does not detect deadlock between
+# update and alter table".
+#
set @@innodb_table_locks=0;
create table t1 (id integer primary key, x integer) engine=INNODB;
insert into t1 values(0, 0),(1,1),(2,2);
@@ -32,26 +38,27 @@ commit;
SELECT * from t1 where id = 0 FOR UPDATE;
id x
0 0
+# Connection 'con2'.
set autocommit=0;
set @@innodb_table_locks=0;
-lock table t1 write;
-update t1 set x=10 where id = 2;
-SELECT * from t1 where id = 2;
-id x
-2 2
-UPDATE t1 set x=3 where id = 2;
-commit;
-SELECT * from t1;
+# The following statement should block because SQL-level lock
+# is taken on t1 which will wait until concurrent transaction
+# is commited.
+# Sending:
+lock table t1 write;;
+# Connection 'con1'.
+# Wait until LOCK TABLE is blocked on SQL-level lock.
+# We should be able to do UPDATEs and SELECTs within transaction.
+update t1 set x=1 where id = 0;
+select * from t1;
id x
-0 0
+0 1
1 1
-2 3
+2 2
+# Unblock LOCK TABLE.
commit;
+# Connection 'con2'.
+# Reap LOCK TABLE.
unlock tables;
-commit;
-select * from t1;
-id x
-0 0
-1 1
-2 10
+# Connection 'con1'.
drop table t1;
diff --git a/mysql-test/r/innodb.result b/mysql-test/r/innodb.result
index 6cee55482e3..4f2009764fc 100644
--- a/mysql-test/r/innodb.result
+++ b/mysql-test/r/innodb.result
@@ -2834,10 +2834,10 @@ t2 CREATE TABLE `t2` (
DROP TABLE t2,t1;
create table t1(a int not null, b int, c int, d int, primary key(a)) engine=innodb;
insert into t1(a) values (1),(2),(3);
+create trigger t1t before insert on t1 for each row begin set NEW.b = NEW.a * 10 + 5, NEW.c = NEW.a / 10; end |
commit;
set autocommit = 0;
update t1 set b = 5 where a = 2;
-create trigger t1t before insert on t1 for each row begin set NEW.b = NEW.a * 10 + 5, NEW.c = NEW.a / 10; end |
set autocommit = 0;
insert into t1(a) values (10),(20),(30),(40),(50),(60),(70),(80),(90),(100),
(11),(21),(31),(41),(51),(61),(71),(81),(91),(101),
@@ -2885,6 +2885,7 @@ insert into t2(a) values(8);
delete from t2 where a = 3;
update t4 set b = b + 1 where a = 3;
commit;
+commit;
drop trigger t1t;
drop trigger t2t;
drop trigger t3t;
diff --git a/mysql-test/r/innodb_mysql.result b/mysql-test/r/innodb_mysql.result
index 76ff2cfc0f3..bccb5caf7d4 100644
--- a/mysql-test/r/innodb_mysql.result
+++ b/mysql-test/r/innodb_mysql.result
@@ -1105,6 +1105,8 @@ CREATE PROCEDURE p1 ()
BEGIN
DECLARE i INT DEFAULT 50;
DECLARE cnt INT;
+# Continue even in the presence of ER_LOCK_DEADLOCK.
+DECLARE CONTINUE HANDLER FOR 1213 BEGIN END;
START TRANSACTION;
ALTER TABLE t1 ENGINE=InnoDB;
COMMIT;
@@ -1618,6 +1620,7 @@ a b
SELECT * FROM t1;
a b
1 init+con1+con2
+COMMIT;
# Switch to connection con1
# 3. test for updated key column:
TRUNCATE t1;
diff --git a/mysql-test/r/innodb_mysql_lock.result b/mysql-test/r/innodb_mysql_lock.result
new file mode 100644
index 00000000000..375ae8aeb12
--- /dev/null
+++ b/mysql-test/r/innodb_mysql_lock.result
@@ -0,0 +1,88 @@
+#
+# Bug #22876 Four-way deadlock
+#
+DROP TABLE IF EXISTS t1;
+# Connection 1
+set @@autocommit=0;
+CREATE TABLE t1(s1 INT UNIQUE) ENGINE=innodb;
+INSERT INTO t1 VALUES (1);
+# Connection 2
+set @@autocommit=0;
+INSERT INTO t1 VALUES (2);
+INSERT INTO t1 VALUES (1);
+# Connection 3
+set @@autocommit=0;
+DROP TABLE t1;
+# Connection 1
+# Connection 1 is now holding the lock.
+# Issuing insert from connection 1 while connection 2&3
+# is waiting for the lock should give a deadlock error.
+INSERT INTO t1 VALUES (2);
+ERROR 40001: Deadlock found when trying to get lock; try restarting transaction
+# Cleanup
+commit;
+set @@autocommit=1;
+commit;
+set @@autocommit=1;
+set @@autocommit=1;
+#
+# Test for bug #37346 "innodb does not detect deadlock between update
+# and alter table".
+#
+drop table if exists t1;
+create table t1 (c1 int primary key, c2 int, c3 int) engine=InnoDB;
+insert into t1 values (1,1,0),(2,2,0),(3,3,0),(4,4,0),(5,5,0);
+begin;
+# Run statement which acquires X-lock on one of table's rows.
+update t1 set c3=c3+1 where c2=3;
+#
+# Switching to connection 'con37346'.
+# The below ALTER TABLE statement should wait till transaction
+# in connection 'default' is complete and then succeed.
+# It should not deadlock or fail with ER_LOCK_DEADLOCK error.
+# Sending:
+alter table t1 add column c4 int;;
+#
+# Switching to connection 'default'.
+# Wait until the above ALTER TABLE gets blocked because this
+# connection holds SW metadata lock on table to be altered.
+# The below statement should succeed. It should not
+# deadlock or end with ER_LOCK_DEADLOCK error.
+update t1 set c3=c3+1 where c2=4;
+# Unblock ALTER TABLE by committing transaction.
+commit;
+#
+# Switching to connection 'con37346'.
+# Reaping ALTER TABLE.
+#
+# Switching to connection 'default'.
+drop table t1;
+#
+# Bug #42147 Concurrent DML and LOCK TABLE ... READ for InnoDB
+# table cause warnings in errlog
+#
+#
+# Note that this test for now relies on a global suppression of
+# the warning "Found lock of type 6 that is write and read locked"
+# This suppression rule can be removed once Bug#42147 is properly
+# fixed. See bug page for more info.
+#
+DROP TABLE IF EXISTS t1;
+CREATE TABLE t1 (i INT) engine= innodb;
+# Connection 2
+# Get user-level lock
+SELECT get_lock('bug42147_lock', 60);
+get_lock('bug42147_lock', 60)
+1
+# Connection 1
+INSERT INTO t1 SELECT get_lock('bug42147_lock', 60);
+# Connection 2
+LOCK TABLES t1 READ;
+SELECT release_lock('bug42147_lock');
+release_lock('bug42147_lock')
+1
+# Connection 1
+# Connection 2
+UNLOCK TABLES;
+# Connection 1
+DROP TABLE t1;
diff --git a/mysql-test/r/innodb_mysql_sync.result b/mysql-test/r/innodb_mysql_sync.result
new file mode 100644
index 00000000000..039d8b74c07
--- /dev/null
+++ b/mysql-test/r/innodb_mysql_sync.result
@@ -0,0 +1,26 @@
+#
+# Bug 42074 concurrent optimize table and
+# alter table = Assertion failed: thd->is_error()
+#
+DROP TABLE IF EXISTS t1;
+# Create InnoDB table
+CREATE TABLE t1 (id INT) engine=innodb;
+# Connection 1
+# Start optimizing table
+SET DEBUG_SYNC='ha_admin_try_alter SIGNAL optimize_started WAIT_FOR table_altered';
+OPTIMIZE TABLE t1;
+# Connection 2
+# Change table to engine=memory
+SET DEBUG_SYNC='now WAIT_FOR optimize_started';
+ALTER TABLE t1 engine=memory;
+SET DEBUG_SYNC='now SIGNAL table_altered';
+# Connection 1
+# Complete optimization
+Table Op Msg_type Msg_text
+test.t1 optimize note Table does not support optimize, doing recreate + analyze instead
+test.t1 optimize error Got error -1 from storage engine
+test.t1 optimize status Operation failed
+Warnings:
+Error 1030 Got error -1 from storage engine
+DROP TABLE t1;
+SET DEBUG_SYNC='RESET';
diff --git a/mysql-test/r/kill.result b/mysql-test/r/kill.result
index 8b6830d4798..1f4f4bb32eb 100644
--- a/mysql-test/r/kill.result
+++ b/mysql-test/r/kill.result
@@ -138,4 +138,107 @@ KILL CONNECTION_ID();
# of close of the connection socket
SELECT 1;
Got one of the listed errors
+#
+# Additional test for WL#3726 "DDL locking for all metadata objects"
+# Check that DDL and DML statements waiting for metadata locks can
+# be killed. Note that we don't cover all situations here since it
+# can be tricky to write test case for some of them (e.g. REPAIR or
+# ALTER and other statements under LOCK TABLES).
+#
+drop tables if exists t1, t2, t3;
+create table t1 (i int primary key);
+# Test for RENAME TABLE
+# Switching to connection 'blocker'
+lock table t1 read;
+# Switching to connection 'ddl'
+rename table t1 to t2;
+# Switching to connection 'default'
+kill query ID;
+# Switching to connection 'ddl'
+ERROR 70100: Query execution was interrupted
+# Test for DROP TABLE
+drop table t1;
+# Switching to connection 'default'
+kill query ID;
+# Switching to connection 'ddl'
+ERROR 70100: Query execution was interrupted
+# Test for CREATE TRIGGER
+create trigger t1_bi before insert on t1 for each row set @a:=1;
+# Switching to connection 'default'
+kill query ID;
+# Switching to connection 'ddl'
+ERROR 70100: Query execution was interrupted
+#
+# Tests for various kinds of ALTER TABLE
+#
+# Full-blown ALTER which should copy table
+alter table t1 add column j int;
+# Switching to connection 'default'
+kill query ID;
+# Switching to connection 'ddl'
+ERROR 70100: Query execution was interrupted
+# Two kinds of simple ALTER
+alter table t1 rename to t2;
+# Switching to connection 'default'
+kill query ID;
+# Switching to connection 'ddl'
+ERROR 70100: Query execution was interrupted
+alter table t1 disable keys;
+# Switching to connection 'default'
+kill query ID;
+# Switching to connection 'ddl'
+ERROR 70100: Query execution was interrupted
+# Fast ALTER
+alter table t1 alter column i set default 100;
+# Switching to connection 'default'
+kill query ID;
+# Switching to connection 'ddl'
+ERROR 70100: Query execution was interrupted
+# Special case which is triggered only for MERGE tables.
+# Switching to connection 'blocker'
+unlock tables;
+create table t2 (i int primary key) engine=merge union=(t1);
+lock tables t2 read;
+# Switching to connection 'ddl'
+alter table t2 alter column i set default 100;
+# Switching to connection 'default'
+kill query ID;
+# Switching to connection 'ddl'
+ERROR 70100: Query execution was interrupted
+# Test for DML waiting for meta-data lock
+# Switching to connection 'blocker'
+unlock tables;
+drop table t2;
+create table t2 (k int);
+lock tables t1 read;
+# Switching to connection 'ddl'
+rename tables t1 to t3, t2 to t1;
+# Switching to connection 'dml'
+insert into t2 values (1);
+# Switching to connection 'default'
+kill query ID2;
+# Switching to connection 'dml'
+ERROR 70100: Query execution was interrupted
+# Switching to connection 'blocker'
+unlock tables;
+# Switching to connection 'ddl'
+# Test for DML waiting for tables to be flushed
+# Switching to connection 'blocker'
+lock tables t1 read;
+# Switching to connection 'ddl'
+# Let us mark locked table t1 as old
+flush tables;
+# Switching to connection 'dml'
+select * from t1;
+# Switching to connection 'default'
+kill query ID2;
+# Switching to connection 'dml'
+ERROR 70100: Query execution was interrupted
+# Switching to connection 'blocker'
+unlock tables;
+# Switching to connection 'ddl'
+# Cleanup.
+# Switching to connection 'default'
+drop table t3;
+drop table t1;
set @@global.concurrent_insert= @old_concurrent_insert;
diff --git a/mysql-test/r/lock.result b/mysql-test/r/lock.result
index 1f8f6aa04ae..c1e1ccb5bce 100644
--- a/mysql-test/r/lock.result
+++ b/mysql-test/r/lock.result
@@ -1,4 +1,4 @@
-drop table if exists t1,t2;
+drop table if exists t1,t2,t3;
CREATE TABLE t1 ( `id` int(11) NOT NULL default '0', `id2` int(11) NOT NULL default '0', `id3` int(11) NOT NULL default '0', `dummy1` char(30) default NULL, PRIMARY KEY (`id`,`id2`), KEY `index_id3` (`id3`)) ENGINE=MyISAM;
insert into t1 (id,id2) values (1,1),(1,2),(1,3);
LOCK TABLE t1 WRITE;
@@ -41,7 +41,7 @@ lock tables t1 write;
check table t2;
Table Op Msg_type Msg_text
test.t2 check Error Table 't2' was not locked with LOCK TABLES
-test.t2 check error Corrupt
+test.t2 check status Operation failed
insert into t1 select index1,nr from t1;
ERROR HY000: Table 't1' was not locked with LOCK TABLES
unlock tables;
@@ -128,13 +128,14 @@ select * from v_bug5719;
1
1
drop view v_bug5719;
+ERROR HY000: Can't execute the given command because you have active locked tables or an active transaction
sic: did not left LOCK TABLES mode automatically
select * from t1;
ERROR HY000: Table 't1' was not locked with LOCK TABLES
unlock tables;
-create view v_bug5719 as select * from t1;
+create or replace view v_bug5719 as select * from t1;
lock tables v_bug5719 write;
select * from v_bug5719;
a
@@ -150,6 +151,12 @@ select * from t2;
a
select * from t3;
ERROR HY000: Table 't3' was not locked with LOCK TABLES
+Dropping of implicitly locked table is disallowed.
+drop table t1;
+ERROR HY000: Table 't1' was locked with a READ lock and can't be updated
+unlock tables;
+Now let us also lock table explicitly and drop it.
+lock tables t1 write, v_bug5719 write;
drop table t1;
sic: left LOCK TABLES mode
@@ -200,3 +207,266 @@ ERROR HY000: Table 't2' was locked with a READ lock and can't be updated
UNLOCK TABLES;
DROP TABLE t1,t2;
End of 5.1 tests.
+#
+# Ensure that FLUSH TABLES doesn't substitute a base locked table
+# with a temporary one.
+#
+drop table if exists t1, t2;
+create table t1 (a int);
+create table t2 (a int);
+lock table t1 write, t2 write;
+create temporary table t1 (a int);
+flush table t1;
+drop temporary table t1;
+select * from t1;
+a
+unlock tables;
+drop table t1, t2;
+#
+# Ensure that REPAIR .. USE_FRM works under LOCK TABLES.
+#
+drop table if exists t1, t2;
+create table t1 (a int);
+create table t2 (a int);
+lock table t1 write, t2 write;
+repair table t1 use_frm;
+Table Op Msg_type Msg_text
+test.t1 repair status OK
+repair table t1 use_frm;
+Table Op Msg_type Msg_text
+test.t1 repair status OK
+select * from t1;
+a
+select * from t2;
+a
+repair table t2 use_frm;
+Table Op Msg_type Msg_text
+test.t2 repair status OK
+repair table t2 use_frm;
+Table Op Msg_type Msg_text
+test.t2 repair status OK
+select * from t1;
+a
+unlock tables;
+drop table t1, t2;
+#
+# Ensure that mi_copy_status is called for two instances
+# of the same table when it is reopened after a flush.
+#
+drop table if exists t1;
+drop view if exists v1;
+create table t1 (c1 int);
+create view v1 as select * from t1;
+lock tables t1 write, v1 write;
+flush table t1;
+insert into t1 values (33);
+flush table t1;
+select * from t1;
+c1
+33
+unlock tables;
+drop table t1;
+drop view v1;
+#
+# WL#4284: Transactional DDL locking
+#
+drop table if exists t1;
+create table t1 (a int);
+set autocommit= 0;
+insert into t1 values (1);
+lock table t1 write;
+# Disconnect
+# Ensure that metadata locks will be released if there is an open
+# transaction (autocommit=off) in conjunction with lock tables.
+drop table t1;
+# Same problem but now for BEGIN
+drop table if exists t1;
+create table t1 (a int);
+begin;
+insert into t1 values (1);
+# Disconnect
+# Ensure that metadata locks held by the transaction are released.
+drop table t1;
+#
+# Coverage for situations when we try to execute DDL on tables
+# which are locked by LOCK TABLES only implicitly.
+#
+drop tables if exists t1, t2;
+drop view if exists v1;
+drop function if exists f1;
+create table t1 (i int);
+create table t2 (j int);
+#
+# Try to perform DDL on table which is locked through view.
+create view v1 as select * from t2;
+lock tables t1 write, v1 write;
+flush table t2;
+ERROR HY000: Table 't2' was locked with a READ lock and can't be updated
+drop table t2;
+ERROR HY000: Table 't2' was locked with a READ lock and can't be updated
+alter table t2 add column k int;
+ERROR HY000: Table 't2' was locked with a READ lock and can't be updated
+create trigger t2_bi before insert on t2 for each row set @a:=1;
+ERROR HY000: Table 't2' was locked with a READ lock and can't be updated
+# Repair produces error as part of its result set.
+repair table t2;
+Table Op Msg_type Msg_text
+test.t2 repair Error Table 't2' was locked with a READ lock and can't be updated
+test.t2 repair status Operation failed
+unlock tables;
+drop view v1;
+#
+# Now, try DDL on table which is locked through routine.
+create function f1 () returns int
+begin
+insert into t2 values (1);
+return 0;
+end|
+create view v1 as select f1() from t1;
+lock tables v1 read;
+flush table t2;
+ERROR HY000: Table 't2' was locked with a READ lock and can't be updated
+drop table t2;
+ERROR HY000: Table 't2' was locked with a READ lock and can't be updated
+alter table t2 add column k int;
+ERROR HY000: Table 't2' was locked with a READ lock and can't be updated
+create trigger t2_bi before insert on t2 for each row set @a:=1;
+ERROR HY000: Table 't2' was locked with a READ lock and can't be updated
+# Repair produces error as part of its result set.
+repair table t2;
+Table Op Msg_type Msg_text
+test.t2 repair Error Table 't2' was locked with a READ lock and can't be updated
+test.t2 repair status Operation failed
+unlock tables;
+drop view v1;
+drop function f1;
+#
+# Finally, try DDL on table which is locked thanks to trigger.
+create trigger t1_ai after insert on t1 for each row insert into t2 values (1);
+lock tables t1 write;
+flush table t2;
+ERROR HY000: Table 't2' was locked with a READ lock and can't be updated
+drop table t2;
+ERROR HY000: Table 't2' was locked with a READ lock and can't be updated
+alter table t2 add column k int;
+ERROR HY000: Table 't2' was locked with a READ lock and can't be updated
+create trigger t2_bi before insert on t2 for each row set @a:=1;
+ERROR HY000: Table 't2' was locked with a READ lock and can't be updated
+# Repair produces error as part of its result set.
+repair table t2;
+Table Op Msg_type Msg_text
+test.t2 repair Error Table 't2' was locked with a READ lock and can't be updated
+test.t2 repair status Operation failed
+unlock tables;
+drop trigger t1_ai;
+drop tables t1, t2;
+#
+# Bug#45035 " Altering table under LOCK TABLES results in
+# "Error 1213 Deadlock found..."
+#
+# When reopening tables under LOCK TABLES after ALTER TABLE,
+# 6.0 used to be taking thr_lock locks one by one, and
+# that would lead to a lock conflict.
+# Check that taking all locks at once works.
+#
+drop table if exists t1;
+create table t1 (i int);
+lock tables t1 write, t1 as a read, t1 as b read;
+alter table t1 add column j int;
+unlock tables;
+drop table t1;
+create temporary table t1 (i int);
+#
+# This is just for test coverage purposes,
+# when this is allowed, remove the --error.
+#
+lock tables t1 write, t1 as a read, t1 as b read;
+ERROR HY000: Can't reopen table: 't1'
+alter table t1 add column j int;
+unlock tables;
+drop table t1;
+#
+# Separate case for partitioned tables is important
+# because each partition has an own thr_lock object.
+#
+create table t1 (i int) partition by list (i)
+(partition p0 values in (1),
+partition p1 values in (2,3),
+partition p2 values in (4,5));
+lock tables t1 write, t1 as a read, t1 as b read;
+alter table t1 add column j int;
+unlock tables;
+drop table t1;
+#
+# Bug #43272 HANDLER SQL command does not work under LOCK TABLES
+#
+DROP TABLE IF EXISTS t1;
+CREATE TABLE t1 (a INT);
+LOCK TABLE t1 WRITE;
+# HANDLER commands are not allowed in LOCK TABLES mode
+HANDLER t1 OPEN;
+ERROR HY000: Can't execute the given command because you have active locked tables or an active transaction
+HANDLER t1 READ FIRST;
+ERROR HY000: Can't execute the given command because you have active locked tables or an active transaction
+HANDLER t1 CLOSE;
+ERROR HY000: Can't execute the given command because you have active locked tables or an active transaction
+UNLOCK TABLES;
+DROP TABLE t1;
+#
+# Bug#45066 FLUSH TABLES WITH READ LOCK deadlocks against
+# LOCK TABLE
+#
+DROP TABLE IF EXISTS t1;
+CREATE TABLE t1(a INT);
+LOCK TABLE t1 READ;
+FLUSH TABLES;
+ERROR HY000: Table 't1' was locked with a READ lock and can't be updated
+LOCK TABLE t1 WRITE;
+FLUSH TABLES;
+#
+# If you allow the next combination, you reintroduce bug Bug#45066
+#
+LOCK TABLE t1 READ;
+FLUSH TABLES WITH READ LOCK;
+ERROR HY000: Can't execute the given command because you have active locked tables or an active transaction
+LOCK TABLE t1 WRITE;
+FLUSH TABLES WITH READ LOCK;
+ERROR HY000: Can't execute the given command because you have active locked tables or an active transaction
+UNLOCK TABLES;
+DROP TABLE t1;
+#
+# Simplified test for bug #48538 "Assertion in thr_lock() on LOAD DATA
+# CONCURRENT INFILE".
+#
+DROP TABLE IF EXISTS t1;
+CREATE TABLE t1 (f1 INT, f2 INT) ENGINE = MEMORY;
+CREATE TRIGGER t1_ai AFTER INSERT ON t1 FOR EACH ROW
+UPDATE LOW_PRIORITY t1 SET f2 = 7;
+# Statement below should fail with ER_CANT_UPDATE_USED_TABLE_IN_SF_OR_TRG
+# error instead of failing on assertion in table-level locking subsystem.
+INSERT INTO t1(f1) VALUES(0);
+ERROR HY000: Can't update table 't1' in stored function/trigger because it is already used by statement which invoked this stored function/trigger.
+DROP TABLE t1;
+#
+# Bug#43685 Lock table affects other non-related tables
+#
+DROP TABLE IF EXISTS t1, t2;
+CREATE TABLE t1 (id INT);
+CREATE TABLE t2 (id INT);
+# Connection default
+LOCK TABLE t1 WRITE;
+ANALYZE TABLE t1;
+Table Op Msg_type Msg_text
+test.t1 analyze status Table is already up to date
+# Connection con2
+LOCK TABLE t2 WRITE;
+# This used to hang until the first connection
+# unlocked t1.
+FLUSH TABLE t2;
+UNLOCK TABLES;
+# Connection default
+UNLOCK TABLES;
+DROP TABLE t1, t2;
+#
+# End of 6.0 tests.
+#
diff --git a/mysql-test/r/lock_multi.result b/mysql-test/r/lock_multi.result
index 3f1165fd069..c440dafb228 100644
--- a/mysql-test/r/lock_multi.result
+++ b/mysql-test/r/lock_multi.result
@@ -1,21 +1,39 @@
drop table if exists t1,t2;
create table t1(n int);
insert into t1 values (1);
-lock tables t1 write;
+select get_lock("mysqltest_lock", 100);
+get_lock("mysqltest_lock", 100)
+1
+update t1 set n = 2 and get_lock('mysqltest_lock', 100);
update low_priority t1 set n = 4;
select n from t1;
-unlock tables;
+select release_lock("mysqltest_lock");
+release_lock("mysqltest_lock")
+1
+select release_lock("mysqltest_lock");
+release_lock("mysqltest_lock")
+1
n
4
drop table t1;
create table t1(n int);
insert into t1 values (1);
-lock tables t1 read;
+select get_lock("mysqltest_lock", 100);
+get_lock("mysqltest_lock", 100)
+1
+select n from t1 where get_lock('mysqltest_lock', 100);
update low_priority t1 set n = 4;
select n from t1;
n
1
-unlock tables;
+select release_lock("mysqltest_lock");
+release_lock("mysqltest_lock")
+1
+n
+1
+select release_lock("mysqltest_lock");
+release_lock("mysqltest_lock")
+1
drop table t1;
create table t1 (a int, b int);
create table t2 (c int, d int);
@@ -35,6 +53,7 @@ create table t2 (a int);
lock table t1 write, t2 write;
insert t1 select * from t2;
drop table t2;
+unlock tables;
ERROR 42S02: Table 'test.t2' doesn't exist
drop table t1;
create table t1 (a int);
@@ -42,6 +61,7 @@ create table t2 (a int);
lock table t1 write, t2 write, t1 as t1_2 write, t2 as t2_2 write;
insert t1 select * from t2;
drop table t2;
+unlock tables;
ERROR 42S02: Table 'test.t2' doesn't exist
drop table t1;
End of 4.1 tests
@@ -72,9 +92,10 @@ CREATE TABLE t1 (c1 int);
LOCK TABLE t1 WRITE;
FLUSH TABLES WITH READ LOCK;
CREATE TABLE t2 (c1 int);
+ERROR HY000: Table 't2' was not locked with LOCK TABLES
UNLOCK TABLES;
UNLOCK TABLES;
-DROP TABLE t1, t2;
+DROP TABLE t1;
CREATE TABLE t1 (c1 int);
LOCK TABLE t1 WRITE;
FLUSH TABLES WITH READ LOCK;
@@ -203,7 +224,7 @@ drop table if exists t1,t2;
create table t1 (a int);
flush status;
lock tables t1 read;
-insert into t1 values(1);;
+insert into t1 values(1);
unlock tables;
drop table t1;
select @tlwa < @tlwb;
@@ -219,3 +240,225 @@ flush tables with read lock;;
connection: default
flush tables;
drop table t1;
+#
+# Test for bug #46272 "MySQL 5.4.4, new MDL: unnecessary deadlock".
+#
+drop table if exists t1;
+create table t1 (c1 int primary key, c2 int, c3 int);
+insert into t1 values (1,1,0),(2,2,0),(3,3,0),(4,4,0),(5,5,0);
+begin;
+update t1 set c3=c3+1 where c2=3;
+#
+# Switching to connection 'con46272'.
+# The below ALTER TABLE statement should wait till transaction
+# in connection 'default' is complete and then succeed.
+# It should not deadlock or fail with ER_LOCK_DEADLOCK error.
+# Sending:
+alter table t1 add column c4 int;;
+#
+# Switching to connection 'default'.
+# Wait until the above ALTER TABLE gets blocked because this
+# connection holds SW metadata lock on table to be altered.
+# The below statement should succeed. It should not
+# deadlock or end with ER_LOCK_DEADLOCK error.
+update t1 set c3=c3+1 where c2=4;
+# Unblock ALTER TABLE by committing transaction.
+commit;
+#
+# Switching to connection 'con46272'.
+# Reaping ALTER TABLE.
+#
+# Switching to connection 'default'.
+drop table t1;
+#
+# Bug#47249 assert in MDL_global_lock::is_lock_type_compatible
+#
+DROP TABLE IF EXISTS t1;
+DROP VIEW IF EXISTS v1;
+#
+# Test 1: LOCK TABLES v1 WRITE, t1 READ;
+#
+# Thanks to the fact that we no longer allow DDL on tables
+# which are locked for write implicitly, the exact scenario
+# in which assert was failing is no longer repeatable.
+CREATE TABLE t1 ( f1 integer );
+CREATE VIEW v1 AS SELECT f1 FROM t1 ;
+LOCK TABLES v1 WRITE, t1 READ;
+FLUSH TABLE t1;
+ERROR HY000: Table 't1' was locked with a READ lock and can't be updated
+UNLOCK TABLES;
+DROP TABLE t1;
+DROP VIEW v1;
+#
+# Test 2: LOCK TABLES t1 WRITE, v1 READ;
+#
+CREATE TABLE t1 ( f1 integer );
+CREATE VIEW v1 AS SELECT f1 FROM t1 ;
+# Connection 2
+LOCK TABLES t1 WRITE, v1 READ;
+FLUSH TABLE t1;
+# Connection 1
+LOCK TABLES t1 WRITE;
+FLUSH TABLE t1;
+DROP TABLE t1;
+DROP VIEW v1;
+#
+# Test for bug #50913 "Deadlock between open_and_lock_tables_derived
+# and MDL". Also see additional coverage in mdl_sync.test.
+#
+drop table if exists t1;
+drop view if exists v1;
+create table t1 (i int);
+create view v1 as select i from t1;
+begin;
+select * from t1;
+i
+# Switching to connection 'con50913'.
+# Sending:
+alter table t1 add column j int;
+# Switching to connection 'default'.
+# Wait until ALTER TABLE gets blocked.
+# The below statement should try to acquire SW lock on 't1'
+# and therefore should get ER_LOCK_DEADLOCK error. Before
+# bug fix it acquired SR lock and hung on thr_lock.c lock.
+delete a from t1 as a where i = 1;
+ERROR 40001: Deadlock found when trying to get lock; try restarting transaction
+# Unblock ALTER TABLE.
+commit;
+# Switching to connection 'con50913'.
+# Reaping ALTER TABLE;
+# Switching to connection 'default'.
+begin;
+select * from v1;
+i
+# Switching to connection 'con50913'.
+# Sending:
+alter table t1 drop column j;
+# Switching to connection 'default'.
+# Wait until ALTER TABLE gets blocked.
+# The below statement should try to acquire SW lock on 't1'
+# and therefore should get ER_LOCK_DEADLOCK error. Before
+# bug fix it acquired SR lock and hung on thr_lock.c lock.
+insert into v1 values (1);
+ERROR 40001: Deadlock found when trying to get lock; try restarting transaction
+# Unblock ALTER TABLE.
+commit;
+# Switching to connection 'con50913'.
+# Reaping ALTER TABLE;
+# Switching to connection 'default'.
+drop view v1;
+drop table t1;
+#
+# Bug#45225 Locking: hang if drop table with no timeout
+#
+# These tests also provide function coverage for the
+# lock_wait_timeout server variable.
+#
+DROP TABLE IF EXISTS t1;
+CREATE TABLE t1 (id int);
+SET SESSION lock_wait_timeout= 1;
+#
+# Test 1: acquire exclusive lock
+#
+# Connection default
+START TRANSACTION;
+INSERT INTO t1 VALUES (1);
+# Connection 2
+DROP TABLE t1;
+ERROR HY000: Lock wait timeout exceeded; try restarting transaction
+# Connection default
+COMMIT;
+#
+# Test 2: upgrade shared lock
+#
+# Connection default
+START TRANSACTION;
+SELECT * FROM t1;
+id
+1
+# Connection 2
+ALTER TABLE t1 RENAME TO t2;
+ERROR HY000: Lock wait timeout exceeded; try restarting transaction
+# Connection default
+COMMIT;
+#
+# Test 3: acquire shared lock
+#
+# Connection default
+LOCK TABLE t1 WRITE;
+# Connection 2
+INSERT INTO t1(id) VALUES (2);
+ERROR HY000: Lock wait timeout exceeded; try restarting transaction
+# Connection default
+UNLOCK TABLES;
+#
+# Test 4: table level locks
+#
+# Connection default
+LOCK TABLE t1 READ;
+# Connection 2
+INSERT INTO t1(id) VALUES(4);
+ERROR HY000: Lock wait timeout exceeded; try restarting transaction
+# Connection default
+UNLOCK TABLES;
+#
+# Test 5: Waiting on Table Definition Cache (TDC)
+#
+# Connection default
+LOCK TABLE t1 READ;
+# Connection con3
+# Sending:
+FLUSH TABLES;
+# Connection con2
+SELECT * FROM t1;
+ERROR HY000: Lock wait timeout exceeded; try restarting transaction
+# Connection default
+UNLOCK TABLES;
+# Connection con3
+# Reaping: FLUSH TABLES
+#
+# Test 6: Timeouts in I_S queries
+#
+# Connection default
+CREATE TABLE t2 (id INT);
+LOCK TABLE t2 WRITE;
+# Connection con3
+# Sending:
+DROP TABLE t1, t2;
+# Connection con2
+SELECT table_name, table_comment FROM information_schema.tables
+WHERE table_schema= 'test' AND table_name= 't1';
+table_name table_comment
+t1 Lock wait timeout exceeded; try restarting transaction
+# Connection default
+UNLOCK TABLES;
+# Connection con3
+# Reaping: DROP TABLE t1, t2
+# Connection default
+# Cleanup
+#
+# Test for bug #51134 "Crash in MDL_lock::destroy on a concurrent
+# DDL workload".
+#
+drop tables if exists t1, t2, t3;
+create table t3 (i int);
+# Switching to connection 'con1'
+# Lock 't3' so upcoming RENAME is blocked.
+lock table t3 read;
+# Switching to connection 'con2'
+# Remember ID for this connection.
+# Start statement which will try to acquire two instances
+# of X metadata lock on the same object.
+# Sending:
+rename tables t1 to t2, t2 to t3;;
+# Switching to connection 'default'
+# Wait until RENAME TABLE is blocked on table 't3'.
+# Kill RENAME TABLE.
+kill query ID;
+# Switching to connection 'con2'
+# RENAME TABLE should be aborted but should not crash.
+ERROR 70100: Query execution was interrupted
+# Switching to connection 'con1'
+unlock tables;
+# Switching to connection 'default'
+drop table t3;
diff --git a/mysql-test/r/lock_sync.result b/mysql-test/r/lock_sync.result
index fc4e8c850f6..49ef3bb1b37 100644
--- a/mysql-test/r/lock_sync.result
+++ b/mysql-test/r/lock_sync.result
@@ -6,6 +6,7 @@
# statements which tried to acquire stronger write lock (TL_WRITE,
# TL_WRITE_ALLOW_READ) on this table might have led to deadlock.
drop table if exists t1;
+drop view if exists v1;
# Create auxiliary connections used through the test.
# Reset DEBUG_SYNC facility before using it.
set debug_sync= 'RESET';
@@ -14,6 +15,9 @@ set debug_sync= 'RESET';
set @old_general_log = @@global.general_log;
set @@global.general_log= OFF;
create table t1 (i int) engine=InnoDB;
+# We have to use view in order to make LOCK TABLES avoid
+# acquiring SNRW metadata lock on table.
+create view v1 as select * from t1;
insert into t1 values (1);
# Prepare user lock which will be used for resuming execution of
# the first statement after it acquires TL_WRITE_ALLOW_WRITE lock.
@@ -36,7 +40,7 @@ select count(*) > 0 from t1 as a, t1 as b for update;;
# acquiring lock for the the first instance of 't1'.
set debug_sync= 'now WAIT_FOR parked';
# Send LOCK TABLE statement which will try to get TL_WRITE lock on 't1':
-lock table t1 write;;
+lock table v1 write;;
# Switch to connection 'default'.
# Wait until this LOCK TABLES statement starts waiting for table lock.
# Allow SELECT ... FOR UPDATE to resume.
@@ -56,6 +60,9 @@ release_lock("lock_bug45143_wait")
1
# Switch to connection 'con_bug45143_1'.
# Reap INSERT statement.
+# In Statement and Mixed replication mode we get here "Unsafe
+# for binlog" warnings. In row mode there are no warnings.
+# Hide the discrepancy.
# Switch to connection 'con_bug45143_3'.
# Reap LOCK TABLES statement.
unlock tables;
@@ -63,4 +70,25 @@ unlock tables;
# Do clean-up.
set debug_sync= 'RESET';
set @@global.general_log= @old_general_log;
+drop view v1;
drop table t1;
+#
+# Bug#50821 Deadlock between LOCK TABLES and ALTER TABLE
+#
+DROP TABLE IF EXISTS t1, t2;
+CREATE TABLE t1(id INT);
+CREATE TABLE t2(id INT);
+# Connection con2
+START TRANSACTION;
+SELECT * FROM t1;
+id
+# Connection default
+# Sending:
+ALTER TABLE t1 ADD COLUMN j INT;
+# Connection con2
+# This used to cause a deadlock.
+INSERT INTO t2 SELECT * FROM t1;
+COMMIT;
+# Connection default
+# Reaping ALTER TABLE t1 ADD COLUMN j INT
+DROP TABLE t1, t2;
diff --git a/mysql-test/r/lowercase_table2.result b/mysql-test/r/lowercase_table2.result
index cf87fd1b5a4..b621a466a29 100644
--- a/mysql-test/r/lowercase_table2.result
+++ b/mysql-test/r/lowercase_table2.result
@@ -226,10 +226,9 @@ drop table t_bug44738_UPPERCASE;
create table t_bug44738_UPPERCASE (i int);
drop table t_bug44738_UPPERCASE;
# Finally, let us check that another issue which was exposed by
-# the original test case is solved. I.e. that fuse in CREATE TABLE
-# which ensures that table is not created if there is an entry for
-# it in TDC even though it was removed from disk uses normalized
-# version of the table name.
+# the original test case is solved. I.e. that the table is not
+# created if there is an entry for it in TDC even though it was
+# removed from disk.
create table t_bug44738_UPPERCASE (i int) engine = myisam;
# Load table definition in TDC.
select table_schema, table_name, table_comment from information_schema.tables
@@ -237,10 +236,13 @@ where table_schema = 'test' and table_name like 't_bug44738_%';
table_schema table_name table_comment
test t_bug44738_UPPERCASE
# Simulate manual removal of the table.
-# After manual removal of table still there should be an entry for table
-# in TDC so attempt to create table with the same name should fail.
+# Check that still there is an entry for table in TDC.
+show open tables like 't_bug44738_%';
+Database Table In_use Name_locked
+test t_bug44738_uppercase 0 0
+# So attempt to create table with the same name should fail.
create table t_bug44738_UPPERCASE (i int);
-ERROR 42S01: Table 't_bug44738_uppercase' already exists
+ERROR HY000: Can't find file: 't_bug44738_uppercase' (errno: 2)
# And should succeed after FLUSH TABLES.
flush tables;
create table t_bug44738_UPPERCASE (i int);
diff --git a/mysql-test/r/mdl_sync.result b/mysql-test/r/mdl_sync.result
new file mode 100644
index 00000000000..299df47b409
--- /dev/null
+++ b/mysql-test/r/mdl_sync.result
@@ -0,0 +1,2377 @@
+SET DEBUG_SYNC= 'RESET';
+drop table if exists t1,t2,t3;
+create table t1 (i int);
+create table t2 (i int);
+connection: default
+lock tables t2 read;
+connection: con1
+set debug_sync='mdl_upgrade_shared_lock_to_exclusive SIGNAL parked WAIT_FOR go';
+alter table t1 rename t3;
+connection: default
+set debug_sync= 'now WAIT_FOR parked';
+connection: con2
+set debug_sync='mdl_acquire_lock_wait SIGNAL go';
+drop table t1,t2;
+connection: con1
+connection: default
+unlock tables;
+connection: con2
+ERROR 42S02: Unknown table 't1'
+drop table t3;
+SET DEBUG_SYNC= 'RESET';
+#
+# Basic test coverage for type-of-operation aware metadata locks.
+#
+drop table if exists t1, t2, t3;
+set debug_sync= 'RESET';
+create table t1 (c1 int);
+#
+# A) First let us check compatibility rules between differend kinds of
+# type-of-operation aware metadata locks.
+# Of course, these rules are already covered by the tests scattered
+# across the test suite. But it still makes sense to have one place
+# which covers all of them.
+#
+# 1) Acquire S (simple shared) lock on the table (by using HANDLER):
+#
+handler t1 open;
+#
+# Switching to connection 'mdl_con1'.
+# Check that S, SH, SR and SW locks are compatible with it.
+handler t1 open t;
+handler t close;
+select column_name from information_schema.columns where
+table_schema='test' and table_name='t1';
+column_name
+c1
+select count(*) from t1;
+count(*)
+0
+insert into t1 values (1), (1);
+# Check that SNW lock is compatible with it. To do this use ALTER TABLE
+# which will fail after opening the table and thus obtaining SNW metadata
+# lock.
+alter table t1 add primary key (c1);
+ERROR 23000: Duplicate entry '1' for key 'PRIMARY'
+# Check that SNRW lock is compatible with S lock.
+lock table t1 write;
+insert into t1 values (1);
+unlock tables;
+# Check that X lock is incompatible with S lock.
+# Sending:
+rename table t1 to t2;;
+#
+# Switching to connection 'mdl_con2'.
+# Check that the above RENAME is blocked because of S lock.
+#
+# Switching to connection 'default'.
+# Unblock RENAME TABLE.
+handler t1 close;
+#
+# Switching to connection 'mdl_con1'.
+# Reaping RENAME TABLE.
+# Restore the original state of the things.
+rename table t2 to t1;
+#
+# Switching to connection 'default'.
+handler t1 open;
+#
+# Switching to connection 'mdl_con1'.
+# Check that upgrade from SNW to X is blocked by presence of S lock.
+# Sending:
+alter table t1 add column c2 int;;
+#
+# Switching to connection 'mdl_con2'.
+# Check that the above ALTER TABLE is blocked because of S lock.
+#
+# Switching to connection 'default'.
+# Unblock ALTER TABLE.
+handler t1 close;
+#
+# Switching to connection 'mdl_con1'.
+# Reaping ALTER TABLE.
+# Restore the original state of the things.
+alter table t1 drop column c2;
+#
+# Switching to connection 'default'.
+handler t1 open;
+#
+# Switching to connection 'mdl_con1'.
+# Check that upgrade from SNRW to X is blocked by presence of S lock.
+lock table t1 write;
+# Sending:
+alter table t1 add column c2 int;;
+#
+# Switching to connection 'mdl_con2'.
+# Check that the above upgrade of SNRW to X in ALTER TABLE is blocked
+# because of S lock.
+#
+# Switching to connection 'default'.
+# Unblock ALTER TABLE.
+handler t1 close;
+#
+# Switching to connection 'mdl_con1'.
+# Reaping ALTER TABLE.
+# Restore the original state of the things.
+alter table t1 drop column c2;
+unlock tables;
+#
+# Switching to connection 'default'.
+#
+# 2) Acquire SH (shared high-priority) lock on the table.
+# We have to involve DEBUG_SYNC facility for this as usually
+# such kind of locks are short-lived.
+#
+set debug_sync= 'after_open_table_mdl_shared SIGNAL locked WAIT_FOR finish';
+# Sending:
+select table_name, table_type, auto_increment, table_comment from information_schema.tables where table_schema='test' and table_name='t1';;
+#
+# Switching to connection 'mdl_con1'.
+set debug_sync= 'now WAIT_FOR locked';
+# Check that S, SH, SR and SW locks are compatible with it.
+handler t1 open;
+handler t1 close;
+select column_name from information_schema.columns where
+table_schema='test' and table_name='t1';
+column_name
+c1
+select count(*) from t1;
+count(*)
+3
+insert into t1 values (1);
+# Check that SNW lock is compatible with it. To do this use ALTER TABLE
+# which will fail after opening the table and thus obtaining SNW metadata
+# lock.
+alter table t1 add primary key (c1);
+ERROR 23000: Duplicate entry '1' for key 'PRIMARY'
+# Check that SNRW lock is compatible with SH lock.
+lock table t1 write;
+delete from t1 limit 1;
+unlock tables;
+# Check that X lock is incompatible with SH lock.
+# Sending:
+rename table t1 to t2;;
+#
+# Switching to connection 'mdl_con2'.
+# Check that the above RENAME is blocked because of SH lock.
+# Unblock RENAME TABLE.
+set debug_sync= 'now SIGNAL finish';
+#
+# Switching to connection 'default'.
+# Reaping SELECT ... FROM I_S.
+table_name table_type auto_increment table_comment
+t1 BASE TABLE NULL
+#
+# Switching to connection 'mdl_con1'.
+# Reaping RENAME TABLE.
+# Restore the original state of the things.
+rename table t2 to t1;
+#
+# Switching to connection 'default'.
+set debug_sync= 'after_open_table_mdl_shared SIGNAL locked WAIT_FOR finish';
+# Sending:
+select table_name, table_type, auto_increment, table_comment from information_schema.tables where table_schema='test' and table_name='t1';;
+#
+# Switching to connection 'mdl_con1'.
+set debug_sync= 'now WAIT_FOR locked';
+# Check that upgrade from SNW to X is blocked by presence of SH lock.
+# Sending:
+alter table t1 add column c2 int;;
+#
+# Switching to connection 'mdl_con2'.
+# Check that the above ALTER TABLE is blocked because of SH lock.
+# Unblock RENAME TABLE.
+set debug_sync= 'now SIGNAL finish';
+#
+# Switching to connection 'default'.
+# Reaping SELECT ... FROM I_S.
+table_name table_type auto_increment table_comment
+t1 BASE TABLE NULL
+#
+# Switching to connection 'mdl_con1'.
+# Reaping ALTER TABLE.
+# Restore the original state of the things.
+alter table t1 drop column c2;
+#
+# Switching to connection 'default'.
+set debug_sync= 'after_open_table_mdl_shared SIGNAL locked WAIT_FOR finish';
+select table_name, table_type, auto_increment, table_comment from information_schema.tables where table_schema='test' and table_name='t1';;
+#
+# Switching to connection 'mdl_con1'.
+set debug_sync= 'now WAIT_FOR locked';
+# Check that upgrade from SNRW to X is blocked by presence of S lock.
+lock table t1 write;
+# Sending:
+alter table t1 add column c2 int;;
+#
+# Switching to connection 'mdl_con2'.
+# Check that the above upgrade of SNRW to X in ALTER TABLE is blocked
+# because of S lock.
+# Unblock RENAME TABLE.
+set debug_sync= 'now SIGNAL finish';
+#
+# Switching to connection 'default'.
+# Reaping SELECT ... FROM I_S.
+table_name table_type auto_increment table_comment
+t1 BASE TABLE NULL
+#
+# Switching to connection 'mdl_con1'.
+# Reaping ALTER TABLE.
+# Restore the original state of the things.
+alter table t1 drop column c2;
+unlock tables;
+#
+# Switching to connection 'default'.
+#
+#
+# 3) Acquire SR lock on the table.
+#
+#
+begin;
+select count(*) from t1;
+count(*)
+3
+#
+# Switching to connection 'mdl_con1'.
+# Check that S, SH, SR and SW locks are compatible with it.
+handler t1 open;
+handler t1 close;
+select column_name from information_schema.columns where
+table_schema='test' and table_name='t1';
+column_name
+c1
+select count(*) from t1;
+count(*)
+3
+insert into t1 values (1);
+# Check that SNW lock is compatible with it. To do this use ALTER TABLE
+# which will fail after opening the table and thus obtaining SNW metadata
+# lock.
+alter table t1 add primary key (c1);
+ERROR 23000: Duplicate entry '1' for key 'PRIMARY'
+# Check that SNRW lock is not compatible with SR lock.
+# Sending:
+lock table t1 write;;
+#
+# Switching to connection 'default'.
+# Check that the above LOCK TABLES is blocked because of SR lock.
+# Unblock LOCK TABLES.
+commit;
+#
+# Switching to connection 'mdl_con1'.
+# Reaping LOCK TABLES.
+delete from t1 limit 1;
+unlock tables;
+#
+# Switching to connection 'default'.
+begin;
+select count(*) from t1;
+count(*)
+3
+#
+# Switching to connection 'mdl_con1'.
+# Check that X lock is incompatible with SR lock.
+# Sending:
+rename table t1 to t2;;
+#
+# Switching to connection 'mdl_con2'.
+# Check that the above RENAME is blocked because of SR lock.
+#
+# Switching to connection 'default'.
+# Unblock RENAME TABLE.
+commit;
+#
+# Switching to connection 'mdl_con1'.
+# Reaping RENAME TABLE.
+# Restore the original state of the things.
+rename table t2 to t1;
+#
+# Switching to connection 'default'.
+begin;
+select count(*) from t1;
+count(*)
+3
+#
+# Switching to connection 'mdl_con1'.
+# Check that upgrade from SNW to X is blocked by presence of SR lock.
+# Sending:
+alter table t1 add column c2 int;;
+#
+# Switching to connection 'mdl_con2'.
+# Check that the above ALTER TABLE is blocked because of SR lock.
+#
+# Switching to connection 'default'.
+# Unblock ALTER TABLE.
+commit;
+#
+# Switching to connection 'mdl_con1'.
+# Reaping ALTER TABLE.
+# Restore the original state of the things.
+alter table t1 drop column c2;
+#
+# There is no need to check that upgrade from SNRW to X is blocked
+# by presence of SR lock because SNRW is incompatible with SR anyway.
+#
+#
+# Switching to connection 'default'.
+#
+#
+# 4) Acquire SW lock on the table.
+#
+#
+begin;
+insert into t1 values (1);
+#
+# Switching to connection 'mdl_con1'.
+# Check that S, SH, SR and SW locks are compatible with it.
+handler t1 open;
+handler t1 close;
+select column_name from information_schema.columns where
+table_schema='test' and table_name='t1';
+column_name
+c1
+select count(*) from t1;
+count(*)
+4
+insert into t1 values (1);
+# Check that SNW lock is not compatible with SW lock.
+# Again we use ALTER TABLE which fails after opening
+# the table to avoid upgrade of SNW -> X.
+# Sending:
+alter table t1 add primary key (c1);;
+#
+# Switching to connection 'default'.
+# Check that the above ALTER TABLE is blocked because of SW lock.
+# Unblock ALTER TABLE.
+commit;
+#
+# Switching to connection 'mdl_con1'.
+# Reaping ALTER TABLE.
+ERROR 23000: Duplicate entry '1' for key 'PRIMARY'
+#
+# Switching to connection 'default'.
+begin;
+insert into t1 values (1);
+#
+# Switching to connection 'mdl_con1'.
+# Check that SNRW lock is not compatible with SW lock.
+# Sending:
+lock table t1 write;;
+#
+# Switching to connection 'default'.
+# Check that the above LOCK TABLES is blocked because of SW lock.
+# Unblock LOCK TABLES.
+commit;
+#
+# Switching to connection 'mdl_con1'.
+# Reaping LOCK TABLES.
+delete from t1 limit 2;
+unlock tables;
+#
+# Switching to connection 'default'.
+begin;
+insert into t1 values (1);
+#
+# Switching to connection 'mdl_con1'.
+# Check that X lock is incompatible with SW lock.
+# Sending:
+rename table t1 to t2;;
+#
+# Switching to connection 'mdl_con2'.
+# Check that the above RENAME is blocked because of SW lock.
+#
+# Switching to connection 'default'.
+# Unblock RENAME TABLE.
+commit;
+#
+# Switching to connection 'mdl_con1'.
+# Reaping RENAME TABLE.
+# Restore the original state of the things.
+rename table t2 to t1;
+#
+# There is no need to check that upgrade from SNW/SNRW to X is
+# blocked by presence of SW lock because SNW/SNRW is incompatible
+# with SW anyway.
+#
+#
+# Switching to connection 'default'.
+#
+#
+# 5) Acquire SNW lock on the table. We have to use DEBUG_SYNC for
+# this, to prevent SNW from being immediately upgraded to X.
+#
+set debug_sync= 'after_open_table_mdl_shared SIGNAL locked WAIT_FOR finish';
+# Sending:
+alter table t1 add primary key (c1);;
+#
+# Switching to connection 'mdl_con1'.
+set debug_sync= 'now WAIT_FOR locked';
+# Check that S, SH and SR locks are compatible with it.
+handler t1 open;
+handler t1 close;
+select column_name from information_schema.columns where
+table_schema='test' and table_name='t1';
+column_name
+c1
+select count(*) from t1;
+count(*)
+5
+# Check that SW lock is incompatible with SNW lock.
+# Sending:
+delete from t1 limit 2;;
+#
+# Switching to connection 'mdl_con2'.
+# Check that the above DELETE is blocked because of SNW lock.
+# Unblock ALTER and thus DELETE.
+set debug_sync= 'now SIGNAL finish';
+#
+# Switching to connection 'default'.
+# Reaping ALTER TABLE.
+ERROR 23000: Duplicate entry '1' for key 'PRIMARY'
+#
+# Switching to connection 'mdl_con1'.
+# Reaping DELETE.
+#
+# Switching to connection 'default'.
+set debug_sync= 'after_open_table_mdl_shared SIGNAL locked WAIT_FOR finish';
+# Sending:
+alter table t1 add primary key (c1);;
+#
+# Switching to connection 'mdl_con1'.
+set debug_sync= 'now WAIT_FOR locked';
+# Check that SNW lock is incompatible with SNW lock.
+# Sending:
+alter table t1 add primary key (c1);;
+#
+# Switching to connection 'mdl_con2'.
+# Check that the above ALTER is blocked because of SNW lock.
+# Unblock ALTERs.
+set debug_sync= 'now SIGNAL finish';
+#
+# Switching to connection 'default'.
+# Reaping first ALTER TABLE.
+ERROR 23000: Duplicate entry '1' for key 'PRIMARY'
+#
+# Switching to connection 'mdl_con1'.
+# Reaping another ALTER TABLE.
+ERROR 23000: Duplicate entry '1' for key 'PRIMARY'
+#
+# Switching to connection 'default'.
+set debug_sync= 'after_open_table_mdl_shared SIGNAL locked WAIT_FOR finish';
+# Sending:
+alter table t1 add primary key (c1);;
+#
+# Switching to connection 'mdl_con1'.
+set debug_sync= 'now WAIT_FOR locked';
+# Check that SNRW lock is incompatible with SNW lock.
+# Sending:
+lock table t1 write;;
+#
+# Switching to connection 'mdl_con2'.
+# Check that the above LOCK TABLES is blocked because of SNW lock.
+# Unblock ALTER and thus LOCK TABLES.
+set debug_sync= 'now SIGNAL finish';
+#
+# Switching to connection 'default'.
+# Reaping ALTER TABLE.
+ERROR 23000: Duplicate entry '1' for key 'PRIMARY'
+#
+# Switching to connection 'mdl_con1'.
+# Reaping LOCK TABLES
+insert into t1 values (1);
+unlock tables;
+#
+# Switching to connection 'default'.
+set debug_sync= 'after_open_table_mdl_shared SIGNAL locked WAIT_FOR finish';
+# Sending:
+alter table t1 add primary key (c1);;
+#
+# Switching to connection 'mdl_con1'.
+set debug_sync= 'now WAIT_FOR locked';
+# Check that X lock is incompatible with SNW lock.
+# Sending:
+rename table t1 to t2;;
+#
+# Switching to connection 'mdl_con2'.
+# Check that the above RENAME is blocked because of SNW lock.
+# Unblock ALTER and thus RENAME TABLE.
+set debug_sync= 'now SIGNAL finish';
+#
+# Switching to connection 'default'.
+# Reaping ALTER TABLE.
+ERROR 23000: Duplicate entry '1' for key 'PRIMARY'
+#
+# Switching to connection 'mdl_con1'.
+# Reaping RENAME TABLE
+# Revert back to original state of things.
+rename table t2 to t1;
+#
+# There is no need to check that upgrade from SNW/SNRW to X is
+# blocked by presence of another SNW lock because SNW/SNRW is
+# incompatible with SNW anyway.
+#
+# Switching to connection 'default'.
+#
+#
+# 6) Acquire SNRW lock on the table.
+#
+#
+lock table t1 write;
+#
+# Switching to connection 'mdl_con1'.
+# Check that S and SH locks are compatible with it.
+handler t1 open;
+handler t1 close;
+select column_name from information_schema.columns where
+table_schema='test' and table_name='t1';
+column_name
+c1
+# Check that SR lock is incompatible with SNRW lock.
+# Sending:
+select count(*) from t1;;
+#
+# Switching to connection 'default'.
+# Check that the above SELECT is blocked because of SNRW lock.
+# Unblock SELECT.
+unlock tables;
+#
+# Switching to connection 'mdl_con1'.
+# Reaping SELECT.
+count(*)
+4
+#
+# Switching to connection 'default'.
+lock table t1 write;
+#
+# Switching to connection 'mdl_con1'.
+# Check that SW lock is incompatible with SNRW lock.
+# Sending:
+delete from t1 limit 1;;
+#
+# Switching to connection 'default'.
+# Check that the above DELETE is blocked because of SNRW lock.
+# Unblock DELETE.
+unlock tables;
+#
+# Switching to connection 'mdl_con1'.
+# Reaping DELETE.
+#
+# Switching to connection 'default'.
+lock table t1 write;
+#
+# Switching to connection 'mdl_con1'.
+# Check that SNW lock is incompatible with SNRW lock.
+# Sending:
+alter table t1 add primary key (c1);;
+#
+# Switching to connection 'default'.
+# Check that the above ALTER is blocked because of UNWR lock.
+# Unblock ALTER.
+unlock tables;
+#
+# Switching to connection 'mdl_con1'.
+# Reaping ALTER TABLE.
+ERROR 23000: Duplicate entry '1' for key 'PRIMARY'
+#
+# Switching to connection 'default'.
+lock table t1 write;
+#
+# Switching to connection 'mdl_con1'.
+# Check that SNRW lock is incompatible with SNRW lock.
+# Sending:
+lock table t1 write;;
+#
+# Switching to connection 'default'.
+# Check that the above LOCK TABLES is blocked because of SNRW lock.
+# Unblock waiting LOCK TABLES.
+unlock tables;
+#
+# Switching to connection 'mdl_con1'.
+# Reaping LOCK TABLES
+insert into t1 values (1);
+unlock tables;
+#
+# Switching to connection 'default'.
+lock table t1 write;
+#
+# Switching to connection 'mdl_con1'.
+# Check that X lock is incompatible with SNRW lock.
+# Sending:
+rename table t1 to t2;;
+#
+# Switching to connection 'default'.
+# Check that the above RENAME is blocked because of SNRW lock.
+# Unblock RENAME TABLE
+unlock tables;
+#
+# Switching to connection 'mdl_con1'.
+# Reaping RENAME TABLE
+# Revert back to original state of things.
+rename table t2 to t1;
+#
+# There is no need to check that upgrade from SNW/SNRW to X is
+# blocked by presence of another SNRW lock because SNW/SNRW is
+# incompatible with SNRW anyway.
+#
+# Switching to connection 'default'.
+#
+#
+# 7) Now do the same round of tests for X lock. We use additional
+# table to get long-lived lock of this type.
+#
+create table t2 (c1 int);
+#
+# Switching to connection 'mdl_con2'.
+# Take a lock on t2, so RENAME TABLE t1 TO t2 will get blocked
+# after acquiring X lock on t1.
+lock tables t2 read;
+#
+# Switching to connection 'default'.
+# Sending:
+rename table t1 to t2;;
+#
+# Switching to connection 'mdl_con1'.
+# Check that RENAME has acquired X lock on t1 and is waiting for t2.
+# Check that S lock in incompatible with X lock.
+# Sending:
+handler t1 open;;
+#
+# Switching to connection 'mdl_con2'.
+# Check that the above HANDLER statement is blocked because of X lock.
+# Unblock RENAME TABLE
+unlock tables;
+#
+# Switching to connection 'default'.
+# Reaping RENAME TABLE.
+ERROR 42S01: Table 't2' already exists
+#
+# Switching to connection 'mdl_con1'.
+# Reaping HANDLER.
+handler t1 close;
+#
+# Switching to connection 'mdl_con2'.
+# Prepare for blocking RENAME TABLE.
+lock tables t2 read;
+#
+# Switching to connection 'default'.
+# Sending:
+rename table t1 to t2;;
+#
+# Switching to connection 'mdl_con1'.
+# Check that RENAME has acquired X lock on t1 and is waiting for t2.
+# Check that SH lock in incompatible with X lock.
+# Sending:
+select column_name from information_schema.columns where table_schema='test' and table_name='t1';;
+#
+# Switching to connection 'mdl_con2'.
+# Check that the above SELECT ... FROM I_S ... statement is blocked
+# because of X lock.
+# Unblock RENAME TABLE
+unlock tables;
+#
+# Switching to connection 'default'.
+# Reaping RENAME TABLE.
+ERROR 42S01: Table 't2' already exists
+#
+# Switching to connection 'mdl_con1'.
+# Reaping SELECT ... FROM I_S.
+column_name
+c1
+#
+# Switching to connection 'mdl_con2'.
+# Prepare for blocking RENAME TABLE.
+lock tables t2 read;
+#
+# Switching to connection 'default'.
+# Sending:
+rename table t1 to t2;;
+#
+# Switching to connection 'mdl_con1'.
+# Check that RENAME has acquired X lock on t1 and is waiting for t2.
+# Check that SR lock in incompatible with X lock.
+# Sending:
+select count(*) from t1;;
+#
+# Switching to connection 'mdl_con2'.
+# Check that the above SELECT statement is blocked
+# because of X lock.
+# Unblock RENAME TABLE
+unlock tables;
+#
+# Switching to connection 'default'.
+# Reaping RENAME TABLE.
+ERROR 42S01: Table 't2' already exists
+#
+# Switching to connection 'mdl_con1'.
+# Reaping SELECT.
+count(*)
+4
+#
+# Switching to connection 'mdl_con2'.
+# Prepare for blocking RENAME TABLE.
+lock tables t2 read;
+#
+# Switching to connection 'default'.
+# Sending:
+rename table t1 to t2;;
+#
+# Switching to connection 'mdl_con1'.
+# Check that RENAME has acquired X lock on t1 and is waiting for t2.
+# Check that SW lock in incompatible with X lock.
+# Sending:
+delete from t1 limit 1;;
+#
+# Switching to connection 'mdl_con2'.
+# Check that the above DELETE statement is blocked
+# because of X lock.
+# Unblock RENAME TABLE
+unlock tables;
+#
+# Switching to connection 'default'.
+# Reaping RENAME TABLE.
+ERROR 42S01: Table 't2' already exists
+#
+# Switching to connection 'mdl_con1'.
+# Reaping DELETE.
+#
+# Switching to connection 'mdl_con2'.
+# Prepare for blocking RENAME TABLE.
+lock tables t2 read;
+#
+# Switching to connection 'default'.
+# Sending:
+rename table t1 to t2;;
+#
+# Switching to connection 'mdl_con1'.
+# Check that RENAME has acquired X lock on t1 and is waiting for t2.
+# Check that SNW lock is incompatible with X lock.
+# Sending:
+alter table t1 add primary key (c1);;
+#
+# Switching to connection 'mdl_con2'.
+# Check that the above ALTER statement is blocked
+# because of X lock.
+# Unblock RENAME TABLE
+unlock tables;
+#
+# Switching to connection 'default'.
+# Reaping RENAME TABLE
+ERROR 42S01: Table 't2' already exists
+#
+# Switching to connection 'mdl_con1'.
+# Reaping ALTER.
+ERROR 23000: Duplicate entry '1' for key 'PRIMARY'
+#
+# Switching to connection 'mdl_con2'.
+# Prepare for blocking RENAME TABLE.
+lock tables t2 read;
+#
+# Switching to connection 'default'.
+# Sending:
+rename table t1 to t2;;
+#
+# Switching to connection 'mdl_con1'.
+# Check that RENAME has acquired X lock on t1 and is waiting for t2.
+# Check that SNRW lock is incompatible with X lock.
+# Sending:
+lock table t1 write;;
+#
+# Switching to connection 'mdl_con2'.
+# Check that the above LOCK TABLE statement is blocked
+# because of X lock.
+# Unblock RENAME TABLE
+unlock tables;
+#
+# Switching to connection 'default'.
+# Reaping RENAME TABLE
+ERROR 42S01: Table 't2' already exists
+#
+# Switching to connection 'mdl_con1'.
+# Reaping LOCK TABLE.
+unlock tables;
+#
+# Switching to connection 'mdl_con2'.
+# Prepare for blocking RENAME TABLE.
+lock tables t2 read;
+#
+# Switching to connection 'default'.
+# Sending:
+rename table t1 to t2;;
+#
+# Switching to connection 'mdl_con1'.
+# Check that RENAME has acquired X lock on t1 and is waiting for t2.
+# Check that X lock is incompatible with X lock.
+# Sending:
+rename table t1 to t3;;
+#
+# Switching to connection 'mdl_con2'.
+# Check that the above RENAME statement is blocked
+# because of X lock.
+# Unblock RENAME TABLE
+unlock tables;
+#
+# Switching to connection 'default'.
+# Reaping RENAME TABLE
+ERROR 42S01: Table 't2' already exists
+#
+# Switching to connection 'mdl_con1'.
+# Reaping RENAME.
+rename table t3 to t1;
+#
+# B) Now let us test compatibility in cases when both locks
+# are pending. I.e. let us test rules for priorities between
+# different types of metadata locks.
+#
+#
+# Switching to connection 'mdl_con2'.
+#
+# 1) Check compatibility for pending SNW lock.
+#
+# Acquire SW lock in order to create pending SNW lock later.
+begin;
+insert into t1 values (1);
+#
+# Switching to connection 'default'.
+# Add pending SNW lock.
+# Sending:
+alter table t1 add primary key (c1);;
+#
+# Switching to connection 'mdl_con1'.
+# Check that ALTER TABLE is waiting with pending SNW lock.
+# Check that S, SH and SR locks are compatible with pending SNW
+handler t1 open t;
+handler t close;
+select column_name from information_schema.columns where
+table_schema='test' and table_name='t1';
+column_name
+c1
+select count(*) from t1;
+count(*)
+4
+# Check that SW is incompatible with pending SNW
+# Sending:
+delete from t1 limit 1;;
+#
+# Switching to connection 'mdl_con2'.
+# Check that the above DELETE is blocked because of pending SNW lock.
+# Unblock ALTER TABLE.
+commit;
+#
+# Switching to connection 'default'.
+# Reaping ALTER.
+ERROR 23000: Duplicate entry '1' for key 'PRIMARY'
+#
+# Switching to connection 'mdl_con1'.
+# Reaping DELETE.
+#
+# We can't do similar check for SNW, SNRW and X locks because
+# they will also be blocked by active SW lock.
+#
+#
+# Switching to connection 'mdl_con2'.
+#
+# 2) Check compatibility for pending SNRW lock.
+#
+# Acquire SR lock in order to create pending SNRW lock.
+begin;
+select count(*) from t1;
+count(*)
+3
+#
+# Switching to connection 'default'.
+# Add pending SNRW lock.
+# Sending:
+lock table t1 write;;
+#
+# Switching to connection 'mdl_con1'.
+# Check that LOCK TABLE is waiting with pending SNRW lock.
+# Check that S and SH locks are compatible with pending SNRW
+handler t1 open t;
+handler t close;
+select column_name from information_schema.columns where
+table_schema='test' and table_name='t1';
+column_name
+c1
+# Check that SR is incompatible with pending SNRW
+# Sending:
+select count(*) from t1;;
+#
+# Switching to connection 'mdl_con2'.
+# Check that the above SELECT is blocked because of pending SNRW lock.
+# Unblock LOCK TABLE.
+commit;
+#
+# Switching to connection 'default'.
+# Reaping LOCK TABLE.
+unlock tables;
+#
+# Switching to connection 'mdl_con1'.
+# Reaping SELECT.
+count(*)
+3
+# Restore pending SNRW lock.
+#
+# Switching to connection 'mdl_con2'.
+begin;
+select count(*) from t1;
+count(*)
+3
+#
+# Switching to connection 'default'.
+# Sending:
+lock table t1 write;;
+#
+# Switching to connection 'mdl_con1'.
+# Check that LOCK TABLE is waiting with pending SNRW lock.
+# Check that SW is incompatible with pending SNRW
+# Sending:
+insert into t1 values (1);;
+#
+# Switching to connection 'mdl_con2'.
+# Check that the above INSERT is blocked because of pending SNRW lock.
+# Unblock LOCK TABLE.
+commit;
+#
+# Switching to connection 'default'.
+# Reaping LOCK TABLE.
+unlock tables;
+#
+# Switching to connection 'mdl_con1'.
+# Reaping INSERT.
+# Restore pending SNRW lock.
+#
+# Switching to connection 'mdl_con2'.
+begin;
+select count(*) from t1;
+count(*)
+4
+#
+# Switching to connection 'default'.
+# Sending:
+lock table t1 write;;
+#
+# Switching to connection 'mdl_con1'.
+# Check that LOCK TABLE is waiting with pending SNRW lock.
+# Check that SNW is compatible with pending SNRW
+# So ALTER TABLE statements are not starved by LOCK TABLEs.
+alter table t1 add primary key (c1);
+ERROR 23000: Duplicate entry '1' for key 'PRIMARY'
+#
+# Switching to connection 'mdl_con2'.
+# Unblock LOCK TABLE.
+commit;
+#
+# Switching to connection 'default'.
+# Reaping LOCK TABLE.
+unlock tables;
+#
+# We can't do similar check for SNRW and X locks because
+# they will also be blocked by active SR lock.
+#
+#
+# Switching to connection 'mdl_con2'.
+#
+# 3) Check compatibility for pending X lock.
+#
+# Acquire SR lock in order to create pending X lock.
+begin;
+select count(*) from t1;
+count(*)
+4
+#
+# Switching to connection 'default'.
+# Add pending X lock.
+# Sending:
+rename table t1 to t2;;
+#
+# Switching to connection 'mdl_con1'.
+# Check that RENAME TABLE is waiting with pending X lock.
+# Check that SH locks are compatible with pending X
+select column_name from information_schema.columns where
+table_schema='test' and table_name='t1';
+column_name
+c1
+# Check that S is incompatible with pending X
+# Sending:
+handler t1 open;;
+#
+# Switching to connection 'mdl_con2'.
+# Check that the above HANDLER OPEN is blocked because of pending X lock.
+# Unblock RENAME TABLE.
+commit;
+#
+# Switching to connection 'default'.
+# Reaping RENAME TABLE.
+ERROR 42S01: Table 't2' already exists
+#
+# Switching to connection 'mdl_con1'.
+# Reaping HANDLER t1 OPEN.
+handler t1 close;
+# Restore pending X lock.
+#
+# Switching to connection 'mdl_con2'.
+begin;
+select count(*) from t1;
+count(*)
+4
+#
+# Switching to connection 'default'.
+# Add pending X lock.
+# Sending:
+rename table t1 to t2;;
+#
+# Switching to connection 'mdl_con1'.
+# Check that RENAME TABLE is waiting with pending X lock.
+# Check that SR is incompatible with pending X
+# Sending:
+select count(*) from t1;;
+#
+# Switching to connection 'mdl_con2'.
+# Check that the above SELECT is blocked because of pending X lock.
+# Unblock RENAME TABLE.
+commit;
+#
+# Switching to connection 'default'.
+# Reaping RENAME TABLE.
+ERROR 42S01: Table 't2' already exists
+#
+# Switching to connection 'mdl_con1'.
+# Reaping SELECT.
+count(*)
+4
+# Restore pending X lock.
+#
+# Switching to connection 'mdl_con2'.
+begin;
+select count(*) from t1;
+count(*)
+4
+#
+# Switching to connection 'default'.
+# Add pending X lock.
+# Sending:
+rename table t1 to t2;;
+#
+# Switching to connection 'mdl_con1'.
+# Check that RENAME TABLE is waiting with pending X lock.
+# Check that SW is incompatible with pending X
+# Sending:
+delete from t1 limit 1;;
+#
+# Switching to connection 'mdl_con2'.
+# Check that the above DELETE is blocked because of pending X lock.
+# Unblock RENAME TABLE.
+commit;
+#
+# Switching to connection 'default'.
+# Reaping RENAME TABLE.
+ERROR 42S01: Table 't2' already exists
+#
+# Switching to connection 'mdl_con1'.
+# Reaping DELETE.
+# Restore pending X lock.
+#
+# Switching to connection 'mdl_con2'.
+begin;
+select count(*) from t1;
+count(*)
+3
+#
+# Switching to connection 'default'.
+# Add pending X lock.
+# Sending:
+rename table t1 to t2;;
+#
+# Switching to connection 'mdl_con1'.
+# Check that RENAME TABLE is waiting with pending X lock.
+# Check that SNW is incompatible with pending X
+# Sending:
+alter table t1 add primary key (c1);;
+#
+# Switching to connection 'mdl_con2'.
+# Check that the above ALTER TABLE is blocked because of pending X lock.
+# Unblock RENAME TABLE.
+commit;
+#
+# Switching to connection 'default'.
+# Reaping RENAME TABLE.
+ERROR 42S01: Table 't2' already exists
+#
+# Switching to connection 'mdl_con1'.
+# Reaping ALTER TABLE.
+ERROR 23000: Duplicate entry '1' for key 'PRIMARY'
+# Restore pending X lock.
+#
+# Switching to connection 'mdl_con2'.
+handler t1 open;
+#
+# Switching to connection 'default'.
+# Add pending X lock.
+# Sending:
+rename table t1 to t2;;
+#
+# Switching to connection 'mdl_con1'.
+# Check that RENAME TABLE is waiting with pending X lock.
+# Check that SNRW is incompatible with pending X
+# Sending:
+lock table t1 write;;
+#
+# Switching to connection 'mdl_con3'.
+# Check that the above LOCK TABLES is blocked because of pending X lock.
+#
+# Switching to connection 'mdl_con2'.
+# Unblock RENAME TABLE.
+handler t1 close;
+#
+# Switching to connection 'default'.
+# Reaping RENAME TABLE.
+ERROR 42S01: Table 't2' already exists
+#
+# Switching to connection 'mdl_con1'.
+# Reaping LOCK TABLES.
+unlock tables;
+#
+# Switching to connection 'default'.
+#
+#
+# C) Now let us test how type-of-operation locks are handled in
+# transactional context. Obviously we are mostly interested
+# in conflicting types of locks.
+#
+#
+# 1) Let us check how various locks used within transactional
+# context interact with active/pending SNW lock.
+#
+# We start with case when we are acquiring lock on the table
+# which was not used in the transaction before.
+begin;
+select count(*) from t1;
+count(*)
+3
+#
+# Switching to connection 'mdl_con1'.
+# Create an active SNW lock on t2.
+# We have to use DEBUG_SYNC facility as otherwise SNW lock
+# will be immediately released (or upgraded to X lock).
+insert into t2 values (1), (1);
+set debug_sync= 'after_open_table_mdl_shared SIGNAL locked WAIT_FOR finish';
+# Sending:
+alter table t2 add primary key (c1);;
+#
+# Switching to connection 'default'.
+set debug_sync= 'now WAIT_FOR locked';
+# SR lock should be acquired without any waiting.
+select count(*) from t2;
+count(*)
+2
+commit;
+# Now let us check that we will wait in case of SW lock.
+begin;
+select count(*) from t1;
+count(*)
+3
+# Sending:
+insert into t2 values (1);;
+#
+# Switching to connection 'mdl_con2'.
+# Check that the above INSERT is blocked.
+# Unblock ALTER TABLE and thus INSERT.
+set debug_sync= 'now SIGNAL finish';
+#
+# Switching to connection 'mdl_con1'.
+# Reap ALTER TABLE.
+ERROR 23000: Duplicate entry '1' for key 'PRIMARY'
+#
+# Switching to connection 'default'.
+# Reap INSERT.
+commit;
+#
+# Now let us see what happens when we are acquiring lock on the table
+# which is already used in transaction.
+#
+# *) First, case when transaction which has SR lock on the table also
+# locked in SNW mode acquires yet another SR lock and then tries
+# to acquire SW lock.
+begin;
+select count(*) from t1;
+count(*)
+3
+#
+# Switching to connection 'mdl_con1'.
+# Create an active SNW lock on t1.
+set debug_sync= 'after_open_table_mdl_shared SIGNAL locked WAIT_FOR finish';
+# Sending:
+alter table t1 add primary key (c1);;
+#
+# Switching to connection 'default'.
+set debug_sync= 'now WAIT_FOR locked';
+# We should still be able to get SR lock without waiting.
+select count(*) from t1;
+count(*)
+3
+# Since the above ALTER TABLE is not upgrading SNW lock to X by waiting
+# for SW lock we won't create deadlock.
+# So the below INSERT should not end-up with ER_LOCK_DEADLOCK error.
+# Sending:
+insert into t1 values (1);;
+#
+# Switching to connection 'mdl_con2'.
+# Check that the above INSERT is blocked.
+# Unblock ALTER TABLE and thus INSERT.
+set debug_sync= 'now SIGNAL finish';
+#
+# Switching to connection 'mdl_con1'.
+# Reap ALTER TABLE.
+ERROR 23000: Duplicate entry '1' for key 'PRIMARY'
+#
+# Switching to connection 'default'.
+# Reap INSERT.
+commit;
+#
+# **) Now test in which transaction that has SW lock on the table
+# against which there is pending SNW lock acquires SR and SW
+# locks on this table.
+#
+begin;
+insert into t1 values (1);
+#
+# Switching to connection 'mdl_con1'.
+# Create pending SNW lock on t1.
+# Sending:
+alter table t1 add primary key (c1);;
+#
+# Switching to connection 'default'.
+# Wait until ALTER TABLE starts waiting for SNW lock.
+# We should still be able to get both SW and SR locks without waiting.
+select count(*) from t1;
+count(*)
+5
+delete from t1 limit 1;
+# Unblock ALTER TABLE.
+commit;
+#
+# Switching to connection 'mdl_con1'.
+# Reap ALTER TABLE.
+ERROR 23000: Duplicate entry '1' for key 'PRIMARY'
+#
+# Switching to connection 'default'.
+#
+# 2) Now similar tests for active SNW lock which is being upgraded
+# to X lock.
+#
+# Again we start with case when we are acquiring lock on the
+# table which was not used in the transaction before.
+begin;
+select count(*) from t1;
+count(*)
+4
+#
+# Switching to connection 'mdl_con2'.
+# Start transaction which will prevent SNW -> X upgrade from
+# completing immediately.
+begin;
+select count(*) from t2;
+count(*)
+3
+#
+# Switching to connection 'mdl_con1'.
+# Create SNW lock pending upgrade to X on t2.
+# Sending:
+alter table t2 add column c2 int;;
+#
+# Switching to connection 'default'.
+# Wait until ALTER TABLE starts waiting X lock.
+# Check that attempt to acquire SR lock on t2 causes waiting.
+# Sending:
+select count(*) from t2;;
+#
+# Switching to connection 'mdl_con2'.
+# Check that the above SELECT is blocked.
+# Unblock ALTER TABLE.
+commit;
+#
+# Switching to connection 'mdl_con1'.
+# Reap ALTER TABLE.
+#
+# Switching to connection 'default'.
+# Reap SELECT.
+count(*)
+3
+commit;
+# Do similar check for SW lock.
+begin;
+select count(*) from t1;
+count(*)
+4
+#
+# Switching to connection 'mdl_con2'.
+# Start transaction which will prevent SNW -> X upgrade from
+# completing immediately.
+begin;
+select count(*) from t2;
+count(*)
+3
+#
+# Switching to connection 'mdl_con1'.
+# Create SNW lock pending upgrade to X on t2.
+# Sending:
+alter table t2 drop column c2;;
+#
+# Switching to connection 'default'.
+# Wait until ALTER TABLE starts waiting X lock.
+# Check that attempt to acquire SW lock on t2 causes waiting.
+# Sending:
+insert into t2 values (1);;
+#
+# Switching to connection 'mdl_con2'.
+# Check that the above INSERT is blocked.
+# Unblock ALTER TABLE.
+commit;
+#
+# Switching to connection 'mdl_con1'.
+# Reap ALTER TABLE.
+#
+# Switching to connection 'default'.
+# Reap INSERT.
+commit;
+#
+# Test for the case in which we are acquiring lock on the table
+# which is already used in transaction.
+#
+begin;
+select count(*) from t1;
+count(*)
+4
+#
+# Switching to connection 'mdl_con1'.
+# Create SNW lock pending upgrade to X.
+# Sending:
+alter table t1 add column c2 int;;
+#
+# Switching to connection 'default'.
+# Wait until ALTER TABLE starts waiting X lock.
+# Check that transaction is still able to acquire SR lock.
+select count(*) from t1;
+count(*)
+4
+# Waiting trying to acquire SW lock will cause deadlock and
+# therefore should cause an error.
+delete from t1 limit 1;
+ERROR 40001: Deadlock found when trying to get lock; try restarting transaction
+# Unblock ALTER TABLE.
+commit;
+#
+# Switching to connection 'mdl_con1'.
+# Reap ALTER TABLE.
+#
+# Switching to connection 'default'.
+#
+# 3) Check how various locks used within transactional context
+# interact with active/pending SNRW lock.
+#
+# Once again we start with case when we are acquiring lock on
+# the table which was not used in the transaction before.
+begin;
+select count(*) from t1;
+count(*)
+4
+#
+# Switching to connection 'mdl_con1'.
+lock table t2 write;
+#
+# Switching to connection 'default'.
+# Attempt to acquire SR should be blocked. It should
+# not cause errors as it does not creates deadlock.
+# Sending:
+select count(*) from t2;;
+#
+# Switching to connection 'mdl_con1'.
+# Check that the above SELECT is blocked
+# Unblock SELECT.
+unlock tables;
+#
+# Switching to connection 'default'.
+# Reap SELECT.
+count(*)
+4
+commit;
+# Repeat the same test for SW lock.
+begin;
+select count(*) from t1;
+count(*)
+4
+#
+# Switching to connection 'mdl_con1'.
+lock table t2 write;
+#
+# Switching to connection 'default'.
+# Again attempt to acquire SW should be blocked and should
+# not cause any errors.
+# Sending:
+delete from t2 limit 1;;
+#
+# Switching to connection 'mdl_con1'.
+# Check that the above DELETE is blocked
+# Unblock DELETE.
+unlock tables;
+#
+# Switching to connection 'default'.
+# Reap DELETE.
+commit;
+#
+# Now coverage for the case in which we are acquiring lock on
+# the table which is already used in transaction and against
+# which there is a pending SNRW lock request.
+#
+# *) Let us start with case when transaction has only a SR lock.
+#
+begin;
+select count(*) from t1;
+count(*)
+4
+#
+# Switching to connection 'mdl_con1'.
+# Sending:
+lock table t1 write;;
+#
+# Switching to connection 'default'.
+# Wait until LOCK TABLE is blocked creating pending request for X lock.
+# Check that another instance of SR lock is granted without waiting.
+select count(*) from t1;
+count(*)
+4
+# Attempt to wait for SW lock will lead to deadlock, thus
+# the below statement should end with ER_LOCK_DEADLOCK error.
+delete from t1 limit 1;
+ERROR 40001: Deadlock found when trying to get lock; try restarting transaction
+# Unblock LOCK TABLES.
+commit;
+#
+# Switching to connection 'mdl_con1'.
+# Reap LOCK TABLES.
+unlock tables;
+#
+# Switching to connection 'default'.
+#
+# **) Now case when transaction has a SW lock.
+#
+begin;
+delete from t1 limit 1;
+#
+# Switching to connection 'mdl_con1'.
+# Sending:
+lock table t1 write;;
+#
+# Switching to connection 'default'.
+# Wait until LOCK TABLE is blocked creating pending request for X lock.
+# Check that both SR and SW locks are granted without waiting
+# and errors.
+select count(*) from t1;
+count(*)
+3
+insert into t1 values (1, 1);
+# Unblock LOCK TABLES.
+commit;
+#
+# Switching to connection 'mdl_con1'.
+# Reap LOCK TABLES.
+unlock tables;
+#
+# Switching to connection 'default'.
+#
+# 4) Check how various locks used within transactional context
+# interact with active/pending X lock.
+#
+# As usual we start with case when we are acquiring lock on
+# the table which was not used in the transaction before.
+begin;
+select count(*) from t1;
+count(*)
+4
+#
+# Switching to connection 'mdl_con2'.
+# Start transaction which will prevent X lock from going away
+# immediately.
+begin;
+select count(*) from t2;
+count(*)
+3
+#
+# Switching to connection 'mdl_con1'.
+# Create pending X lock on t2.
+# Sending:
+rename table t2 to t3;;
+#
+# Switching to connection 'default'.
+# Wait until RENAME TABLE starts waiting with pending X lock.
+# Check that attempt to acquire SR lock on t2 causes waiting.
+# Sending:
+select count(*) from t2;;
+#
+# Switching to connection 'mdl_con2'.
+# Check that the above SELECT is blocked.
+# Unblock RENAME TABLE.
+commit;
+#
+# Switching to connection 'mdl_con1'.
+# Reap RENAME TABLE.
+#
+# Switching to connection 'default'.
+# Reap SELECT.
+ERROR 42S02: Table 'test.t2' doesn't exist
+commit;
+rename table t3 to t2;
+# The same test for SW lock.
+begin;
+select count(*) from t1;
+count(*)
+4
+#
+# Switching to connection 'mdl_con2'.
+# Start transaction which will prevent X lock from going away
+# immediately.
+begin;
+select count(*) from t2;
+count(*)
+3
+#
+# Switching to connection 'mdl_con1'.
+# Create pending X lock on t2.
+# Sending:
+rename table t2 to t3;;
+#
+# Switching to connection 'default'.
+# Wait until RENAME TABLE starts waiting with pending X lock.
+# Check that attempt to acquire SW lock on t2 causes waiting.
+# Sending:
+delete from t2 limit 1;;
+#
+# Switching to connection 'mdl_con2'.
+# Check that the above DELETE is blocked.
+# Unblock RENAME TABLE.
+commit;
+#
+# Switching to connection 'mdl_con1'.
+# Reap RENAME TABLE.
+#
+# Switching to connection 'default'.
+# Reap DELETE.
+ERROR 42S02: Table 'test.t2' doesn't exist
+commit;
+rename table t3 to t2;
+#
+# Coverage for the case in which we are acquiring lock on
+# the table which is already used in transaction and against
+# which there is a pending X lock request.
+#
+# *) The first case is when transaction has only a SR lock.
+#
+begin;
+select count(*) from t1;
+count(*)
+4
+#
+# Switching to connection 'mdl_con1'.
+# Sending:
+rename table t1 to t2;;
+#
+# Switching to connection 'default'.
+# Wait until RENAME TABLE is blocked creating pending request for X lock.
+# Check that another instance of SR lock is granted without waiting.
+select count(*) from t1;
+count(*)
+4
+# Attempt to wait for SW lock will lead to deadlock, thus
+# the below statement should end with ER_LOCK_DEADLOCK error.
+delete from t1 limit 1;
+ERROR 40001: Deadlock found when trying to get lock; try restarting transaction
+# Unblock RENAME TABLE.
+commit;
+#
+# Switching to connection 'mdl_con1'.
+# Reap RENAME TABLE.
+ERROR 42S01: Table 't2' already exists
+#
+# Switching to connection 'default'.
+#
+# **) The second case is when transaction has a SW lock.
+#
+begin;
+delete from t1 limit 1;
+#
+# Switching to connection 'mdl_con1'.
+# Sending:
+rename table t1 to t2;;
+#
+# Switching to connection 'default'.
+# Wait until RENAME TABLE is blocked creating pending request for X lock.
+# Check that both SR and SW locks are granted without waiting
+# and errors.
+select count(*) from t1;
+count(*)
+3
+insert into t1 values (1, 1);
+# Unblock RENAME TABLE.
+commit;
+#
+# Switching to connection 'mdl_con1'.
+# Reap RENAME TABLE.
+ERROR 42S01: Table 't2' already exists
+#
+# Switching to connection 'default'.
+# Clean-up.
+set debug_sync= 'RESET';
+drop table t1, t2;
+#
+# Additional coverage for some scenarios in which not quite
+# correct use of S metadata locks by HANDLER statement might
+# have caused deadlocks.
+#
+drop table if exists t1, t2;
+create table t1 (i int);
+create table t2 (j int);
+insert into t1 values (1);
+#
+# First, check scenario in which we upgrade SNRW lock to X lock
+# on a table while having HANDLER READ trying to acquire TL_READ
+# on the same table.
+#
+handler t1 open;
+#
+# Switching to connection 'handler_con1'.
+lock table t1 write;
+# Upgrade SNRW to X lock.
+# Sending:
+alter table t1 add column j int;;
+#
+# Switching to connection 'handler_con2'.
+# Wait until ALTER is blocked during upgrade.
+#
+# Switching to connection 'default'.
+# The below statement should not cause deadlock.
+handler t1 read first;;
+#
+# Switching to connection 'handler_con1'.
+# Reap ALTER TABLE.
+unlock tables;
+#
+# Switching to connection 'default'.
+# Reap HANDLER READ.
+i j
+1 NULL
+handler t1 close;
+#
+# Now, check scenario in which upgrade of SNRW lock to X lock
+# can be blocked by HANDLER which is open in connection currently
+# waiting to get table-lock owned by connection doing upgrade.
+#
+handler t1 open;
+#
+# Switching to connection 'handler_con1'.
+lock table t1 write, t2 read;
+#
+# Switching to connection 'default'.
+# Execute statement which will be blocked on table-level lock
+# owned by connection 'handler_con1'.
+# Sending:
+insert into t2 values (1);;
+#
+# Switching to connection 'handler_con1'.
+# Wait until INSERT is blocked on table-level lock.
+# The below statement should not cause deadlock.
+alter table t1 drop column j;
+unlock tables;
+#
+# Switching to connection 'default'.
+# Reap INSERT.
+handler t1 close;
+#
+# Then, check the scenario in which upgrade of SNRW lock to X
+# lock is blocked by HANDLER which is open in connection currently
+# waiting to get SW lock on the same table.
+#
+handler t1 open;
+#
+# Switching to connection 'handler_con1'.
+lock table t1 write;
+#
+# Switching to connection 'default'.
+# The below insert should be blocked because active SNRW lock on 't1'.
+# Sending:
+insert into t1 values (1);;
+#
+# Switching to connection 'handler_con1'.
+# Wait until INSERT is blocked because of SNRW lock.
+# The below ALTER TABLE will be blocked because of presence of HANDLER.
+# Sending:
+alter table t1 add column j int;;
+#
+# Switching to connection 'default'.
+# INSERT should be chosen as victim for resolving deadlock.
+# Reaping INSERT.
+ERROR 40001: Deadlock found when trying to get lock; try restarting transaction
+# Close HANDLER to unblock ALTER TABLE.
+handler t1 close;
+#
+# Switching to connection 'handler_con1'.
+# Reaping ALTER TABLE.
+unlock tables;
+#
+# Switching to connection 'default'.
+#
+# Finally, test in which upgrade of SNRW lock to X lock is blocked
+# by HANDLER which is open in connection currently waiting to get
+# SR lock on the table on which lock is upgraded.
+#
+handler t1 open;
+#
+# Switching to connection 'handler_con1'.
+lock table t1 write, t2 write;
+#
+# Switching to connection 'default'.
+# The below insert should be blocked because active SNRW lock on 't1'.
+# Sending:
+insert into t2 values (1);;
+#
+# Switching to connection 'handler_con1'.
+# Wait until INSERT is blocked because of SNRW lock.
+# The below ALTER TABLE will be blocked because of presence of HANDLER.
+# Sending:
+alter table t1 drop column j;;
+#
+# Switching to connection 'default'.
+# INSERT should be chosen as victim for resolving deadlock.
+# Reaping INSERT.
+ERROR 40001: Deadlock found when trying to get lock; try restarting transaction
+# Close HANDLER to unblock ALTER TABLE.
+handler t1 close;
+#
+# Switching to connection 'handler_con1'.
+# Reaping ALTER TABLE.
+unlock tables;
+#
+# Switching to connection 'default'.
+# Clean-up.
+drop tables t1, t2;
+#
+# Test coverage for basic deadlock detection in metadata
+# locking subsystem.
+#
+drop tables if exists t0, t1, t2, t3, t4, t5;
+create table t1 (i int);
+create table t2 (j int);
+create table t3 (k int);
+create table t4 (k int);
+#
+# Test for the case in which no deadlock occurs.
+#
+#
+# Switching to connection 'deadlock_con1'.
+begin;
+insert into t1 values (1);
+#
+# Switching to connection 'deadlock_con2'.
+begin;
+insert into t2 values (1);
+#
+# Switching to connection 'default'.
+# Send:
+rename table t2 to t0, t3 to t2, t0 to t3;;
+#
+# Switching to connection 'deadlock_con1'.
+# Wait until the above RENAME TABLE is blocked because it has to wait
+# for 'deadlock_con2' which holds shared metadata lock on 't2'.
+# The below statement should wait for exclusive metadata lock
+# on 't2' to go away and should not produce ER_LOCK_DEADLOCK
+# as no deadlock is possible in this situation.
+# Send:
+select * from t2;;
+#
+# Switching to connection 'deadlock_con2'.
+# Wait until the above SELECT * FROM t2 is starts waiting
+# for an exclusive metadata lock to go away.
+#
+# Unblock RENAME TABLE by releasing shared metadata lock on t2.
+commit;
+#
+# Switching to connection 'default'.
+# Reap RENAME TABLE.
+#
+# Switching to connection 'deadlock_con1'.
+# Reap SELECT.
+k
+#
+# Switching to connection 'default'.
+#
+# Let us check that in the process of waiting for conflicting lock
+# on table 't2' to go away transaction in connection 'deadlock_con1'
+# has not released metadata lock on table 't1'.
+# Send:
+rename table t1 to t0, t3 to t1, t0 to t3;;
+#
+# Switching to connection 'deadlock_con1'.
+# Wait until the above RENAME TABLE is blocked because it has to wait
+# for 'deadlock_con1' which should still hold shared metadata lock on
+# table 't1'.
+# Commit transaction to unblock RENAME TABLE.
+commit;
+#
+# Switching to connection 'default'.
+# Reap RENAME TABLE.
+#
+# Test for case when deadlock occurs and should be detected immediately.
+#
+#
+# Switching to connection 'deadlock_con1'.
+begin;
+insert into t2 values (2);
+#
+# Switching to connection 'default'.
+# Send:
+rename table t2 to t0, t1 to t2, t0 to t1;;
+#
+# Switching to connection 'deadlock_con1'.
+# Wait until the above RENAME TABLE is blocked because it has to wait
+# for 'deadlock_con1' which holds shared metadata lock on 't2'.
+#
+# The below statement should not wait as doing so will cause deadlock.
+# Instead it should fail and emit ER_LOCK_DEADLOCK statement.
+select * from t1;
+ERROR 40001: Deadlock found when trying to get lock; try restarting transaction
+#
+# Let us check that failure of the above statement has not released
+# metadata lock on table 't1', i.e. that RENAME TABLE is still blocked.
+# Commit transaction to unblock RENAME TABLE.
+commit;
+#
+# Switching to connection 'default'.
+# Reap RENAME TABLE.
+#
+# Test for the case in which deadlock also occurs but not immediately.
+#
+#
+# Switching to connection 'deadlock_con1'.
+begin;
+insert into t2 values (1);
+#
+# Switching to connection 'default'.
+lock table t1 write;
+#
+# Switching to connection 'deadlock_con1'.
+# The below SELECT statement should wait for metadata lock
+# on table 't1' and should not produce ER_LOCK_DEADLOCK
+# immediately as no deadlock is possible at the moment.
+select * from t1;;
+#
+# Switching to connection 'deadlock_con2'.
+# Wait until the above SELECT * FROM t1 is starts waiting
+# for an UNRW metadata lock to go away.
+# Send RENAME TABLE statement that will deadlock with the
+# SELECT statement and thus should abort the latter.
+rename table t1 to t0, t2 to t1, t0 to t2;;
+#
+# Switching to connection 'default'.
+# Wait till above RENAME TABLE is blocked while holding
+# pending X lock on t1.
+# Allow the above RENAME TABLE to acquire lock on t1 and
+# create pending lock on t2 thus creating deadlock.
+unlock tables;
+#
+# Switching to connection 'deadlock_con1'.
+# Since the latest RENAME TABLE entered in deadlock with SELECT
+# statement the latter should be aborted and emit ER_LOCK_DEADLOCK
+# error.
+# Reap SELECT * FROM t1.
+ERROR 40001: Deadlock found when trying to get lock; try restarting transaction
+#
+# Again let us check that failure of the SELECT statement has not
+# released metadata lock on table 't2', i.e. that the latest RENAME
+# is blocked.
+# Commit transaction to unblock this RENAME TABLE.
+commit;
+#
+# Switching to connection 'deadlock_con2'.
+# Reap RENAME TABLE ... .
+#
+# Switching to connection 'default'.
+drop tables t1, t2, t3, t4;
+#
+# Now, test case which shows that deadlock detection empiric
+# also takes into account requests for metadata lock upgrade.
+#
+create table t1 (i int);
+insert into t1 values (1);
+# Avoid race which occurs when SELECT in 'deadlock_con1' connection
+# accesses table before the above INSERT unlocks the table and thus
+# its result becomes visible to other connections.
+select * from t1;
+i
+1
+#
+# Switching to connection 'deadlock_con1'.
+begin;
+select * from t1;
+i
+1
+#
+# Switching to connection 'default'.
+# Send:
+alter table t1 add column j int, rename to t2;;
+#
+# Switching to connection 'deadlock_con1'.
+# Wait until the above ALTER TABLE ... RENAME acquires exclusive
+# metadata lock on 't2' and starts waiting for connection
+# 'deadlock_con1' which holds shared lock on 't1'.
+# The below statement should not wait as it will cause deadlock.
+# An appropriate error should be reported instead.
+select * from t2;
+ERROR 40001: Deadlock found when trying to get lock; try restarting transaction
+# Again let us check that failure of the above statement has not
+# released all metadata locks in connection 'deadlock_con1' and
+# so ALTER TABLE ... RENAME is still blocked.
+# Commit transaction to unblock ALTER TABLE ... RENAME.
+commit;
+#
+# Switching to connection 'default'.
+# Reap ALTER TABLE ... RENAME.
+drop table t2;
+#
+# Test for bug #46748 "Assertion in MDL_context::wait_for_locks()
+# on INSERT + CREATE TRIGGER".
+#
+drop tables if exists t1, t2, t3, t4, t5;
+# Let us simulate scenario in which we open some tables from extended
+# part of prelocking set but then encounter conflicting metadata lock,
+# so have to back-off and wait for it to go away.
+create table t1 (i int);
+create table t2 (j int);
+create table t3 (k int);
+create table t4 (l int);
+create trigger t1_bi before insert on t1 for each row
+insert into t2 values (new.i);
+create trigger t2_bi before insert on t2 for each row
+insert into t3 values (new.j);
+#
+# Switching to connection 'con1root'.
+lock tables t4 read;
+#
+# Switching to connection 'con2root'.
+# Send :
+rename table t3 to t5, t4 to t3;;
+#
+# Switching to connection 'default'.
+# Wait until the above RENAME TABLE adds pending requests for exclusive
+# metadata lock on its tables and blocks due to 't4' being used by LOCK
+# TABLES.
+# Send :
+insert into t1 values (1);;
+#
+# Switching to connection 'con1root'.
+# Wait until INSERT statement waits due to encountering pending
+# exclusive metadata lock on 't3'.
+unlock tables;
+#
+# Switching to connection 'con2root'.
+# Reap RENAME TABLE.
+#
+# Switching to connection 'default'.
+# Reap INSERT.
+# Clean-up.
+drop tables t1, t2, t3, t5;
+#
+# Bug#42546 - Backup: RESTORE fails, thinking it finds an existing table
+#
+DROP TABLE IF EXISTS t1;
+set @save_log_output=@@global.log_output;
+set global log_output=file;
+#
+# Test 1: CREATE TABLE
+#
+# Connection 2
+# Start insert on the not-yet existing table
+# Wait after taking the MDL lock
+SET DEBUG_SYNC= 'after_open_table_mdl_shared SIGNAL locked WAIT_FOR finish';
+INSERT INTO t1 VALUES(1,"def");
+# Connection 1
+SET DEBUG_SYNC= 'now WAIT_FOR locked';
+# Now INSERT has a MDL on the non-existent table t1.
+#
+# Continue the INSERT once CREATE waits for exclusive lock
+SET DEBUG_SYNC= 'mdl_acquire_lock_wait SIGNAL finish';
+# Try to create that table.
+CREATE TABLE t1 (c1 INT, c2 VARCHAR(100), KEY(c1));
+# Connection 2
+# Insert fails
+ERROR 42S02: Table 'test.t1' doesn't exist
+# Connection 1
+SET DEBUG_SYNC= 'RESET';
+SHOW TABLES;
+Tables_in_test
+t1
+DROP TABLE IF EXISTS t1;
+#
+# Test 2: CREATE TABLE LIKE
+#
+CREATE TABLE t2 (c1 INT, c2 VARCHAR(100), KEY(c1));
+# Connection 2
+# Start insert on the not-yet existing table
+# Wait after taking the MDL
+SET DEBUG_SYNC= 'after_open_table_mdl_shared SIGNAL locked WAIT_FOR finish';
+INSERT INTO t1 VALUES(1,"def");
+# Connection 1
+SET DEBUG_SYNC= 'now WAIT_FOR locked';
+# Now INSERT has a MDL on the non-existent table t1.
+#
+# Continue the INSERT once CREATE waits for exclusive lock
+SET DEBUG_SYNC= 'mdl_acquire_lock_wait SIGNAL finish';
+# Try to create that table.
+CREATE TABLE t1 LIKE t2;
+# Connection 2
+# Insert fails
+ERROR 42S02: Table 'test.t1' doesn't exist
+# Connection 1
+SET DEBUG_SYNC= 'RESET';
+SHOW TABLES;
+Tables_in_test
+t1
+t2
+DROP TABLE t2;
+DROP TABLE IF EXISTS t1;
+set global log_output=@save_log_output;
+#
+# Bug #46044 "MDL deadlock on LOCK TABLE + CREATE TABLE HIGH_PRIORITY
+# FOR UPDATE"
+#
+drop tables if exists t1, t2;
+create table t1 (i int);
+# Let us check that we won't deadlock if during filling
+# of I_S table we encounter conflicting metadata lock
+# which owner is in its turn waiting for our connection.
+lock tables t1 read;
+# Switching to connection 'con46044'.
+# Sending:
+create table t2 select * from t1 for update;;
+# Switching to connection 'default'.
+# Waiting until CREATE TABLE ... SELECT ... is blocked.
+# First let us check that SHOW FIELDS/DESCRIBE doesn't
+# gets blocked and emits and error.
+show fields from t2;
+ERROR HY000: Table 'test'.'t2' was skipped since its definition is being modified by concurrent DDL statement
+# Now test for I_S query which reads only .FRMs.
+#
+# Query below should only emit a warning.
+select column_name from information_schema.columns
+where table_schema='test' and table_name='t2';
+column_name
+Warnings:
+Warning 1684 Table 'test'.'t2' was skipped since its definition is being modified by concurrent DDL statement
+# Finally, test for I_S query which does full-blown table open.
+#
+# Query below should not be blocked. Warning message should be
+# stored in the 'table_comment' column.
+select table_name, table_type, auto_increment, table_comment
+from information_schema.tables where table_schema='test' and table_name='t2';
+table_name table_type auto_increment table_comment
+t2 BASE TABLE NULL Table 'test'.'t2' was skipped since its definition is being modified by concurre
+# Switching to connection 'default'.
+unlock tables;
+# Switching to connection 'con46044'.
+# Reaping CREATE TABLE ... SELECT ... .
+drop table t2;
+#
+# Let us also check that queries to I_S wait for conflicting metadata
+# locks to go away instead of skipping table with a warning in cases
+# when deadlock is not possible. This is a nice thing from compatibility
+# and ease of use points of view.
+#
+# We check same three queries to I_S in this new situation.
+# Switching to connection 'con46044_2'.
+lock tables t1 read;
+# Switching to connection 'con46044'.
+# Sending:
+create table t2 select * from t1 for update;;
+# Switching to connection 'default'.
+# Waiting until CREATE TABLE ... SELECT ... is blocked.
+# Let us check that SHOW FIELDS/DESCRIBE gets blocked.
+# Sending:
+show fields from t2;;
+# Switching to connection 'con46044_2'.
+# Wait until SHOW FIELDS gets blocked.
+unlock tables;
+# Switching to connection 'con46044'.
+# Reaping CREATE TABLE ... SELECT ... .
+# Switching to connection 'default'.
+# Reaping SHOW FIELDS ...
+Field Type Null Key Default Extra
+i int(11) YES NULL
+drop table t2;
+# Switching to connection 'con46044_2'.
+lock tables t1 read;
+# Switching to connection 'con46044'.
+# Sending:
+create table t2 select * from t1 for update;;
+# Switching to connection 'default'.
+# Waiting until CREATE TABLE ... SELECT ... is blocked.
+# Check that I_S query which reads only .FRMs gets blocked.
+# Sending:
+select column_name from information_schema.columns where table_schema='test' and table_name='t2';;
+# Switching to connection 'con46044_2'.
+# Wait until SELECT COLUMN_NAME FROM I_S.COLUMNS gets blocked.
+unlock tables;
+# Switching to connection 'con46044'.
+# Reaping CREATE TABLE ... SELECT ... .
+# Switching to connection 'default'.
+# Reaping SELECT COLUMN_NAME FROM I_S.COLUMNS
+column_name
+i
+drop table t2;
+# Switching to connection 'con46044_2'.
+lock tables t1 read;
+# Switching to connection 'con46044'.
+# Sending:
+create table t2 select * from t1 for update;;
+# Switching to connection 'default'.
+# Waiting until CREATE TABLE ... SELECT ... is blocked.
+# Finally, check that I_S query which does full-blown table open
+# also gets blocked.
+# Sending:
+select table_name, table_type, auto_increment, table_comment from information_schema.tables where table_schema='test' and table_name='t2';;
+# Switching to connection 'con46044_2'.
+# Wait until SELECT ... FROM I_S.TABLES gets blocked.
+unlock tables;
+# Switching to connection 'con46044'.
+# Reaping CREATE TABLE ... SELECT ... .
+# Switching to connection 'default'.
+# Reaping SELECT ... FROM I_S.TABLES
+table_name table_type auto_increment table_comment
+t2 BASE TABLE NULL
+drop table t2;
+# Switching to connection 'default'.
+# Clean-up.
+drop table t1;
+#
+# Test for bug #46273 "MySQL 5.4.4 new MDL: Bug#989 is not fully fixed
+# in case of ALTER".
+#
+drop table if exists t1;
+set debug_sync= 'RESET';
+create table t1 (c1 int primary key, c2 int, c3 int);
+insert into t1 values (1,1,0),(2,2,0),(3,3,0),(4,4,0),(5,5,0);
+begin;
+select * from t1 where c2 = 3;
+c1 c2 c3
+3 3 0
+#
+# Switching to connection 'con46273'.
+set debug_sync='after_lock_tables_takes_lock SIGNAL alter_table_locked WAIT_FOR alter_go';
+alter table t1 add column e int, rename to t2;;
+#
+# Switching to connection 'default'.
+set debug_sync='now WAIT_FOR alter_table_locked';
+set debug_sync='before_open_table_wait_refresh SIGNAL alter_go';
+# The below statement should get ER_LOCK_DEADLOCK error
+# (i.e. it should not allow ALTER to proceed, and then
+# fail due to 't1' changing its name to 't2').
+update t1 set c3=c3+1 where c2 = 3;
+ERROR 40001: Deadlock found when trying to get lock; try restarting transaction
+#
+# Let us check that failure of the above statement has not released
+# metadata lock on table 't1', i.e. that ALTER TABLE is still blocked.
+# Unblock ALTER TABLE by commiting transaction and thus releasing
+# metadata lock on 't1'.
+commit;
+#
+# Switching to connection 'con46273'.
+# Reap ALTER TABLE.
+#
+# Switching to connection 'default'.
+# Clean-up.
+set debug_sync= 'RESET';
+drop table t2;
+#
+# Test for bug #46673 "Deadlock between FLUSH TABLES WITH READ LOCK
+# and DML".
+#
+drop tables if exists t1;
+create table t1 (i int);
+# Switching to connection 'con46673'.
+begin;
+insert into t1 values (1);
+# Switching to connection 'default'.
+# Statement below should not get blocked. And if after some
+# changes to code it is there should not be a deadlock between
+# it and transaction from connection 'con46673'.
+flush tables with read lock;
+unlock tables;
+# Switching to connection 'con46673'.
+delete from t1 where i = 1;
+commit;
+# Switching to connection 'default'.
+# Clean-up
+drop table t1;
+#
+# Bug#48210 FLUSH TABLES WITH READ LOCK deadlocks
+# against concurrent CREATE PROCEDURE
+#
+# Test 1: CREATE PROCEDURE
+# Connection 1
+# Start CREATE PROCEDURE and open mysql.proc
+SET DEBUG_SYNC= 'after_open_table_mdl_shared SIGNAL table_opened WAIT_FOR grlwait';
+CREATE PROCEDURE p1() SELECT 1;
+# Connection 2
+SET DEBUG_SYNC= 'now WAIT_FOR table_opened';
+# Check that FLUSH must wait to get the GRL
+# and let CREATE PROCEDURE continue
+SET DEBUG_SYNC= 'wait_lock_global_read_lock SIGNAL grlwait';
+FLUSH TABLES WITH READ LOCK;
+# Connection 1
+# Connection 2
+UNLOCK TABLES;
+# Connection 1
+SET DEBUG_SYNC= 'RESET';
+# Test 2: DROP PROCEDURE
+# Start DROP PROCEDURE and open tables
+SET DEBUG_SYNC= 'after_open_table_mdl_shared SIGNAL table_opened WAIT_FOR grlwait';
+DROP PROCEDURE p1;
+# Connection 2
+SET DEBUG_SYNC= 'now WAIT_FOR table_opened';
+# Check that FLUSH must wait to get the GRL
+# and let DROP PROCEDURE continue
+SET DEBUG_SYNC= 'wait_lock_global_read_lock SIGNAL grlwait';
+FLUSH TABLES WITH READ LOCK;
+# Connection 1
+# Connection 2
+UNLOCK TABLES;
+# Connection 1
+SET DEBUG_SYNC= 'RESET';
+#
+# Bug#50786 Assertion `thd->mdl_context.trans_sentinel() == __null'
+# failed in open_ltable()
+#
+DROP TABLE IF EXISTS t1, t2;
+CREATE TABLE t1 (i INT);
+CREATE TABLE t2 (i INT);
+SET @old_general_log= @@global.general_log;
+SET @@global.general_log= 1;
+SET @old_log_output= @@global.log_output;
+SET @@global.log_output= 'TABLE';
+SET @old_sql_log_off= @@session.sql_log_off;
+SET @@session.sql_log_off= 1;
+# connection: con1
+HANDLER t1 OPEN;
+# connection: con3
+SET @@session.sql_log_off= 1;
+# connection: con2
+SET DEBUG_SYNC= 'thr_multi_lock_after_thr_lock SIGNAL parked WAIT_FOR go';
+# Sending:
+SELECT 1;
+# connection: con3
+SET DEBUG_SYNC= 'now WAIT_FOR parked';
+# connection: con1
+# Sending:
+SELECT 1;
+# connection: con3
+# Sending:
+ALTER TABLE t1 ADD COLUMN j INT;
+# connection: default
+SET DEBUG_SYNC= 'now SIGNAL go';
+# connection: con1
+# Reaping SELECT 1
+1
+1
+HANDLER t1 CLOSE;
+# connection: con2
+# Reaping SELECT 1
+1
+1
+# connection: con3
+# Reaping ALTER TABLE t1 ADD COLUMN j INT
+# connection: default
+DROP TABLE t1, t2;
+SET DEBUG_SYNC= 'RESET';
+SET @@global.general_log= @old_general_log;
+SET @@global.log_output= @old_log_output;
+SET @@session.sql_log_off= @old_sql_log_off;
+#
+# Additional coverage for bug #50913 "Deadlock between
+# open_and_lock_tables_derived and MDL". The main test
+# case is in lock_multi.test
+#
+drop table if exists t1;
+set debug_sync= 'RESET';
+create table t1 (i int) engine=InnoDB;
+# Switching to connection 'con50913_1'.
+set debug_sync= 'thr_multi_lock_after_thr_lock SIGNAL parked WAIT_FOR go';
+# Sending:
+alter table t1 add column j int;
+# Switching to connection 'default'.
+# Wait until ALTER TABLE gets blocked on a sync point after
+# acquiring thr_lock.c lock.
+set debug_sync= 'now WAIT_FOR parked';
+# The below statement should wait on MDL lock and not deadlock on
+# thr_lock.c lock.
+# Sending:
+truncate table t1;
+# Switching to connection 'con50913_2'.
+# Wait until TRUNCATE TABLE is blocked on MDL lock.
+# Unblock ALTER TABLE.
+set debug_sync= 'now SIGNAL go';
+# Switching to connection 'con50913_1'.
+# Reaping ALTER TABLE.
+# Switching to connection 'default'.
+# Reaping TRUNCATE TABLE.
+set debug_sync= 'RESET';
+drop table t1;
+#
+# Test for bug #50998 "Deadlock in MDL code during test
+# rqg_mdl_stability".
+# Also provides coverage for the case when addition of
+# waiting statement adds several loops in the waiters
+# graph and therefore several searches for deadlock
+# should be performed.
+drop table if exists t1;
+set debug_sync= 'RESET';
+create table t1 (i int);
+# Switching to connection 'con1'.
+begin;
+select * from t1;
+i
+# Switching to connection 'con2'.
+begin;
+select * from t1;
+i
+# Switching to connection 'default'.
+# Start ALTER TABLE which will acquire SNW lock and
+# table lock and get blocked on sync point.
+set debug_sync= 'thr_multi_lock_after_thr_lock SIGNAL parked WAIT_FOR go';
+# Sending:
+alter table t1 add column j int;
+# Switching to connection 'con1'.
+# Wait until ALTER TABLE gets blocked on a sync point.
+set debug_sync= 'now WAIT_FOR parked';
+# Sending:
+insert into t1 values (1);
+# Switching to connection 'con2'.
+# Sending:
+insert into t1 values (1);
+# Switching to connection 'con3'.
+# Wait until both 'con1' and 'con2' are blocked trying to acquire
+# SW lock on the table.
+# Unblock ALTER TABLE. Since it will try to upgrade SNW to X lock
+# deadlock with two loops in waiting graph will occur. Both loops
+# should be found and DML statements in both 'con1' and 'con2'
+# should be aborted with ER_LOCK_DEADLOCK errors.
+set debug_sync= 'now SIGNAL go';
+# Switching to connection 'con1'.
+# Reaping INSERT. It should end with ER_LOCK_DEADLOCK error and
+# not wait indefinitely (as it happened before the bugfix).
+ERROR 40001: Deadlock found when trying to get lock; try restarting transaction
+commit;
+# Switching to connection 'con2'.
+# Reaping INSERT.
+ERROR 40001: Deadlock found when trying to get lock; try restarting transaction
+commit;
+# Switching to connection 'default'.
+# Reap ALTER TABLE.
+set debug_sync= 'RESET';
+drop table t1;
diff --git a/mysql-test/r/merge.result b/mysql-test/r/merge.result
index 83152a0dd8d..62981adaf8a 100644
--- a/mysql-test/r/merge.result
+++ b/mysql-test/r/merge.result
@@ -578,23 +578,23 @@ select max(b) from t1 where a = 2;
max(b)
1
drop table t3,t1,t2;
-create table t1 (a int not null);
-create table t2 (a int not null);
-insert into t1 values (1);
-insert into t2 values (2);
-create temporary table t3 (a int not null) ENGINE=MERGE UNION=(t1,t2);
-select * from t3;
+CREATE TABLE t1 (c1 INT NOT NULL);
+CREATE TABLE t2 (c1 INT NOT NULL);
+INSERT INTO t1 VALUES (1);
+INSERT INTO t2 VALUES (2);
+CREATE TEMPORARY TABLE t3 (c1 INT NOT NULL) ENGINE=MRG_MYISAM UNION=(t1,t2);
+SELECT * FROM t3;
ERROR HY000: Unable to open underlying table which is differently defined or of non-MyISAM type or doesn't exist
-create temporary table t4 (a int not null);
-create temporary table t5 (a int not null);
-insert into t4 values (1);
-insert into t5 values (2);
-create temporary table t6 (a int not null) ENGINE=MERGE UNION=(t4,t5);
-select * from t6;
-a
-1
-2
-drop table t6, t3, t1, t2, t4, t5;
+CREATE TEMPORARY TABLE t4 (c1 INT NOT NULL);
+CREATE TEMPORARY TABLE t5 (c1 INT NOT NULL);
+INSERT INTO t4 VALUES (4);
+INSERT INTO t5 VALUES (5);
+CREATE TEMPORARY TABLE t6 (c1 INT NOT NULL) ENGINE=MRG_MYISAM UNION=(t4,t5);
+SELECT * FROM t6;
+c1
+4
+5
+DROP TABLE t6, t3, t1, t2, t4, t5;
create temporary table t1 (a int not null);
create temporary table t2 (a int not null);
insert into t1 values (1);
@@ -1046,18 +1046,21 @@ c1
LOCK TABLE t1 WRITE, t2 WRITE, t3 WRITE;
INSERT INTO t1 VALUES (1);
TRUNCATE TABLE t3;
-ERROR HY000: Can't execute the given command because you have active locked tables or an active transaction
SELECT * FROM t3;
c1
-1
-2
+UNLOCK TABLES;
+SELECT * FROM t1;
+c1
+SELECT * FROM t2;
+c1
#
# Truncate child table under locked tables.
+LOCK TABLE t1 WRITE, t2 WRITE, t3 WRITE;
+INSERT INTO t1 VALUES (1);
+INSERT INTO t2 VALUES (2);
TRUNCATE TABLE t1;
-ERROR HY000: Can't execute the given command because you have active locked tables or an active transaction
SELECT * FROM t3;
c1
-1
2
UNLOCK TABLES;
DROP TABLE t1, t2, t3;
@@ -1089,18 +1092,24 @@ INSERT INTO t1 VALUES (1);
CREATE TABLE t4 (c1 INT, INDEX(c1));
LOCK TABLE t4 WRITE;
TRUNCATE TABLE t3;
-ERROR HY000: Can't execute the given command because you have active locked tables or an active transaction
SELECT * FROM t3;
c1
-1
-2
+SELECT * FROM t1;
+c1
+SELECT * FROM t2;
+c1
#
# Truncate temporary child table under locked tables.
+INSERT INTO t1 VALUES (1);
+INSERT INTO t2 VALUES (2);
TRUNCATE TABLE t1;
-ERROR HY000: Can't execute the given command because you have active locked tables or an active transaction
SELECT * FROM t3;
c1
-1
+2
+SELECT * FROM t1;
+c1
+SELECT * FROM t2;
+c1
2
UNLOCK TABLES;
DROP TABLE t1, t2, t3, t4;
@@ -1149,7 +1158,8 @@ SHOW CREATE TABLE t3;
ERROR 42S02: Table 'test.t3' doesn't exist
DROP TABLE t1, t2;
#
-# CREATE ... LIKE
+# Bug#37371 "CREATE TABLE LIKE merge loses UNION parameter"
+# Demonstrate that this is no longer the case.
#
# 1. Create like.
CREATE TABLE t1 (c1 INT);
@@ -1164,26 +1174,26 @@ SHOW CREATE TABLE t4;
Table Create Table
t4 CREATE TABLE `t4` (
`c1` int(11) DEFAULT NULL
-) ENGINE=MRG_MyISAM DEFAULT CHARSET=latin1
+) ENGINE=MRG_MyISAM DEFAULT CHARSET=latin1 INSERT_METHOD=LAST UNION=(`t1`,`t2`)
INSERT INTO t4 VALUES (4);
-ERROR HY000: Table 't4' is read only
DROP TABLE t4;
#
# 1. Create like with locked tables.
LOCK TABLES t3 WRITE, t2 WRITE, t1 WRITE;
CREATE TABLE t4 LIKE t3;
+ERROR HY000: Table 't4' was not locked with LOCK TABLES
SHOW CREATE TABLE t4;
ERROR HY000: Table 't4' was not locked with LOCK TABLES
INSERT INTO t4 VALUES (4);
ERROR HY000: Table 't4' was not locked with LOCK TABLES
-UNLOCK TABLES;
+CREATE TEMPORARY TABLE t4 LIKE t3;
SHOW CREATE TABLE t4;
-Table Create Table
-t4 CREATE TABLE `t4` (
- `c1` int(11) DEFAULT NULL
-) ENGINE=MRG_MyISAM DEFAULT CHARSET=latin1
+ERROR HY000: Unable to open underlying table which is differently defined or of non-MyISAM type or doesn't exist
+INSERT INTO t4 VALUES (4);
+ERROR HY000: Unable to open underlying table which is differently defined or of non-MyISAM type or doesn't exist
+UNLOCK TABLES;
INSERT INTO t4 VALUES (4);
-ERROR HY000: Table 't4' is read only
+ERROR HY000: Unable to open underlying table which is differently defined or of non-MyISAM type or doesn't exist
DROP TABLE t4;
#
# Rename child.
@@ -1210,6 +1220,7 @@ c1
1
2
3
+4
RENAME TABLE t2 TO t5;
SELECT * FROM t3 ORDER BY c1;
ERROR HY000: Unable to open underlying table which is differently defined or of non-MyISAM type or doesn't exist
@@ -1219,6 +1230,7 @@ c1
1
2
3
+4
#
# 3. Normal rename with locked tables.
LOCK TABLES t1 WRITE, t2 WRITE, t3 WRITE;
@@ -1227,6 +1239,7 @@ c1
1
2
3
+4
RENAME TABLE t2 TO t5;
ERROR HY000: Can't execute the given command because you have active locked tables or an active transaction
SELECT * FROM t3 ORDER BY c1;
@@ -1234,6 +1247,7 @@ c1
1
2
3
+4
RENAME TABLE t5 TO t2;
ERROR HY000: Can't execute the given command because you have active locked tables or an active transaction
SELECT * FROM t3 ORDER BY c1;
@@ -1241,6 +1255,7 @@ c1
1
2
3
+4
UNLOCK TABLES;
#
# 4. Alter table rename.
@@ -1253,12 +1268,13 @@ c1
1
2
3
+4
#
# 5. Alter table rename with locked tables.
LOCK TABLES t1 WRITE, t2 WRITE, t3 WRITE;
ALTER TABLE t2 RENAME TO t5;
SELECT * FROM t3 ORDER BY c1;
-ERROR HY000: Table 't3' was not locked with LOCK TABLES
+ERROR HY000: Table 't2' was not locked with LOCK TABLES
ALTER TABLE t5 RENAME TO t2;
ERROR HY000: Table 't5' was not locked with LOCK TABLES
UNLOCK TABLES;
@@ -1268,6 +1284,7 @@ c1
1
2
3
+4
#
# Rename parent.
#
@@ -1278,6 +1295,7 @@ c1
1
2
3
+4
RENAME TABLE t3 TO t5;
ERROR HY000: Can't execute the given command because you have active locked tables or an active transaction
SELECT * FROM t3 ORDER BY c1;
@@ -1285,6 +1303,7 @@ c1
1
2
3
+4
RENAME TABLE t5 TO t3;
ERROR HY000: Can't execute the given command because you have active locked tables or an active transaction
SELECT * FROM t3 ORDER BY c1;
@@ -1292,6 +1311,7 @@ c1
1
2
3
+4
#
# 5. Alter table rename with locked tables.
ALTER TABLE t3 RENAME TO t5;
@@ -1306,6 +1326,7 @@ c1
1
2
3
+4
DROP TABLE t1, t2, t3;
#
# Drop locked tables.
@@ -1330,9 +1351,9 @@ LOCK TABLES t1 WRITE, t2 WRITE;
INSERT INTO t1 VALUES (1);
DROP TABLE t1;
SELECT * FROM t2;
-ERROR HY000: Unable to open underlying table which is differently defined or of non-MyISAM type or doesn't exist
+ERROR HY000: Table 't1' was not locked with LOCK TABLES
SELECT * FROM t1;
-ERROR 42S02: Table 'test.t1' doesn't exist
+ERROR HY000: Table 't1' was not locked with LOCK TABLES
UNLOCK TABLES;
DROP TABLE t2;
#
@@ -2256,3 +2277,332 @@ deallocate prepare stmt;
#
drop table t_parent;
set @@global.table_definition_cache=@save_table_definition_cache;
+DROP DATABASE IF EXISTS mysql_test1;
+CREATE DATABASE mysql_test1;
+CREATE TABLE t1 ... DATA DIRECTORY=... INDEX DIRECTORY=...
+CREATE TABLE mysql_test1.t2 ... DATA DIRECTORY=... INDEX DIRECTORY=...
+CREATE TABLE m1 (c1 INT) ENGINE=MRG_MYISAM UNION=(t1,mysql_test1.t2)
+INSERT_METHOD=LAST;
+INSERT INTO t1 VALUES (1);
+INSERT INTO mysql_test1.t2 VALUES (2);
+SELECT * FROM m1;
+c1
+1
+2
+DROP TABLE t1, mysql_test1.t2, m1;
+DROP DATABASE mysql_test1;
+CREATE TABLE t1 (c1 INT);
+CREATE TABLE t2 (c1 INT);
+INSERT INTO t1 (c1) VALUES (1);
+CREATE TABLE tm1 (c1 INT) ENGINE=MRG_MYISAM UNION=(t1,t2) INSERT_METHOD=FIRST;
+CREATE TABLE t3 (c1 INT);
+INSERT INTO t3 (c1) VALUES (1);
+CREATE FUNCTION f1() RETURNS INT RETURN (SELECT MAX(c1) FROM t3);
+CREATE VIEW v1 AS SELECT foo.c1 c1, f1() c2, bar.c1 c3, f1() c4
+FROM tm1 foo, tm1 bar, t3;
+SELECT * FROM v1;
+c1 c2 c3 c4
+1 1 1 1
+DROP FUNCTION f1;
+DROP VIEW v1;
+DROP TABLE tm1, t1, t2, t3;
+CREATE TEMPORARY TABLE t1 (c1 INT);
+CREATE TEMPORARY TABLE t2 (c1 INT);
+CREATE TEMPORARY TABLE tm1 (c1 INT) ENGINE=MRG_MYISAM UNION=(t1,t2)
+INSERT_METHOD=FIRST;
+CREATE FUNCTION f1() RETURNS INT RETURN (SELECT MAX(c1) FROM tm1);
+INSERT INTO tm1 (c1) VALUES (1);
+SELECT f1() FROM (SELECT 1) AS c1;
+f1()
+1
+DROP FUNCTION f1;
+DROP TABLE tm1, t1, t2;
+CREATE FUNCTION f1() RETURNS INT
+BEGIN
+CREATE TEMPORARY TABLE t1 (c1 INT);
+CREATE TEMPORARY TABLE t2 (c1 INT);
+CREATE TEMPORARY TABLE tm1 (c1 INT) ENGINE=MRG_MYISAM UNION=(t1,t2);
+INSERT INTO t1 (c1) VALUES (1);
+RETURN (SELECT MAX(c1) FROM tm1);
+END|
+SELECT f1() FROM (SELECT 1 UNION SELECT 1) c1;
+f1()
+1
+DROP FUNCTION f1;
+DROP TABLE tm1, t1, t2;
+CREATE TEMPORARY TABLE t1 (c1 INT);
+INSERT INTO t1 (c1) VALUES (1);
+CREATE TEMPORARY TABLE tm1 (c1 INT) ENGINE=MRG_MYISAM UNION=(t1);
+CREATE FUNCTION f1() RETURNS INT
+BEGIN
+CREATE TEMPORARY TABLE t2 (c1 INT);
+ALTER TEMPORARY TABLE tm1 UNION=(t1,t2);
+INSERT INTO t2 (c1) VALUES (2);
+RETURN (SELECT MAX(c1) FROM tm1);
+END|
+ERROR 0A000: ALTER VIEW is not allowed in stored procedures
+DROP TABLE tm1, t1;
+CREATE TABLE t1 (c1 INT) ENGINE=MyISAM;
+CREATE TABLE tm1 (c1 INT) ENGINE=MRG_MYISAM UNION=(t1) INSERT_METHOD=LAST;
+INSERT INTO tm1 VALUES (1);
+SELECT * FROM tm1;
+c1
+1
+DROP TABLE tm1, t1;
+CREATE FUNCTION f1() RETURNS INT
+BEGIN
+INSERT INTO tm1 VALUES (1);
+RETURN (SELECT MAX(c1) FROM tm1);
+END|
+CREATE TABLE t1 (c1 INT) ENGINE=MyISAM;
+CREATE TABLE tm1 (c1 INT) ENGINE=MRG_MYISAM UNION=(t1) INSERT_METHOD=LAST;
+SELECT f1();
+f1()
+1
+DROP FUNCTION f1;
+DROP TABLE tm1, t1;
+CREATE TABLE t1 (c1 INT) ENGINE=MyISAM;
+CREATE TABLE tm1 (c1 INT) ENGINE=MRG_MYISAM UNION=(t1) INSERT_METHOD=LAST;
+LOCK TABLE tm1 WRITE;
+INSERT INTO tm1 VALUES (1);
+SELECT * FROM tm1;
+c1
+1
+UNLOCK TABLES;
+DROP TABLE tm1, t1;
+CREATE FUNCTION f1() RETURNS INT
+BEGIN
+INSERT INTO tm1 VALUES (1);
+RETURN (SELECT MAX(c1) FROM tm1);
+END|
+CREATE TABLE t1 (c1 INT) ENGINE=MyISAM;
+CREATE TABLE tm1 (c1 INT) ENGINE=MRG_MYISAM UNION=(t1) INSERT_METHOD=LAST;
+LOCK TABLE tm1 WRITE;
+SELECT f1();
+f1()
+1
+UNLOCK TABLES;
+DROP FUNCTION f1;
+DROP TABLE tm1, t1;
+CREATE TABLE t1 (c1 INT) ENGINE=MyISAM;
+CREATE TABLE t2 (c1 INT) ENGINE=MyISAM;
+CREATE TABLE tm1 (c1 INT) ENGINE=MRG_MYISAM UNION=(t1) INSERT_METHOD=LAST;
+CREATE TRIGGER t2_ai AFTER INSERT ON t2
+FOR EACH ROW INSERT INTO tm1 VALUES(11);
+LOCK TABLE t2 WRITE;
+INSERT INTO t2 VALUES (2);
+SELECT * FROM tm1;
+c1
+11
+SELECT * FROM t2;
+c1
+2
+UNLOCK TABLES;
+DROP TRIGGER t2_ai;
+DROP TABLE tm1, t1, t2;
+CREATE TEMPORARY TABLE t1 (c1 INT) ENGINE=MyISAM;
+CREATE TEMPORARY TABLE tm1 (c1 INT) ENGINE=MRG_MYISAM UNION=(t1)
+INSERT_METHOD=LAST;
+INSERT INTO tm1 VALUES (1);
+SELECT * FROM tm1;
+c1
+1
+DROP TABLE tm1, t1;
+CREATE FUNCTION f1() RETURNS INT
+BEGIN
+INSERT INTO tm1 VALUES (1);
+RETURN (SELECT MAX(c1) FROM tm1);
+END|
+CREATE TEMPORARY TABLE t1 (c1 INT) ENGINE=MyISAM;
+CREATE TEMPORARY TABLE tm1 (c1 INT) ENGINE=MRG_MYISAM UNION=(t1)
+INSERT_METHOD=LAST;
+SELECT f1();
+f1()
+1
+DROP FUNCTION f1;
+DROP TABLE tm1, t1;
+CREATE TEMPORARY TABLE t1 (c1 INT) ENGINE=MyISAM;
+CREATE TEMPORARY TABLE tm1 (c1 INT) ENGINE=MRG_MYISAM UNION=(t1)
+INSERT_METHOD=LAST;
+CREATE TABLE t9 (c1 INT) ENGINE=MyISAM;
+LOCK TABLE t9 WRITE;
+INSERT INTO tm1 VALUES (1);
+SELECT * FROM tm1;
+c1
+1
+UNLOCK TABLES;
+DROP TABLE tm1, t1, t9;
+CREATE FUNCTION f1() RETURNS INT
+BEGIN
+INSERT INTO tm1 VALUES (1);
+RETURN (SELECT MAX(c1) FROM tm1);
+END|
+CREATE TEMPORARY TABLE t1 (c1 INT) ENGINE=MyISAM;
+CREATE TEMPORARY TABLE tm1 (c1 INT) ENGINE=MRG_MYISAM UNION=(t1)
+INSERT_METHOD=LAST;
+CREATE TABLE t9 (c1 INT) ENGINE=MyISAM;
+LOCK TABLE t9 WRITE;
+SELECT f1();
+f1()
+1
+UNLOCK TABLES;
+DROP FUNCTION f1;
+DROP TABLE tm1, t1, t9;
+CREATE TEMPORARY TABLE t1 (c1 INT) ENGINE=MyISAM;
+CREATE TEMPORARY TABLE tm1 (c1 INT) ENGINE=MRG_MYISAM UNION=(t1)
+INSERT_METHOD=LAST;
+CREATE TABLE t2 (c1 INT) ENGINE=MyISAM;
+CREATE TRIGGER t2_ai AFTER INSERT ON t2
+FOR EACH ROW INSERT INTO tm1 VALUES(11);
+LOCK TABLE t2 WRITE;
+INSERT INTO t2 VALUES (2);
+SELECT * FROM tm1;
+c1
+11
+SELECT * FROM t2;
+c1
+2
+UNLOCK TABLES;
+DROP TRIGGER t2_ai;
+DROP TABLE tm1, t1, t2;
+#
+# Don't allow an update of a MERGE child in a trigger
+# if the table's already being modified by the main
+# statement.
+#
+CREATE TABLE t1 (c1 INT) ENGINE=MyISAM;
+CREATE TABLE tm1 (c1 INT) ENGINE=MRG_MYISAM UNION=(t1)
+INSERT_METHOD=LAST;
+CREATE TRIGGER tm1_ai AFTER INSERT ON tm1
+FOR EACH ROW INSERT INTO t1 VALUES(11);
+LOCK TABLE tm1 WRITE, t1 WRITE;
+INSERT INTO tm1 VALUES (1);
+ERROR HY000: Can't update table 't1' in stored function/trigger because it is already used by statement which invoked this stored function/trigger.
+SELECT * FROM tm1;
+c1
+1
+UNLOCK TABLES;
+LOCK TABLE t1 WRITE, tm1 WRITE;
+INSERT INTO tm1 VALUES (1);
+ERROR HY000: Can't update table 't1' in stored function/trigger because it is already used by statement which invoked this stored function/trigger.
+SELECT * FROM tm1;
+c1
+1
+1
+UNLOCK TABLES;
+DROP TRIGGER tm1_ai;
+DROP TABLE tm1, t1;
+#
+# Don't select MERGE child when trying to get a prelocked table.
+#
+# Due to a limitation demonstrated by the previous test
+# we can no longer use a write-locked prelocked table.
+# The test is kept for historical purposes.
+#
+CREATE TABLE t1 (c1 INT) ENGINE=MyISAM;
+CREATE TABLE tm1 (c1 INT) ENGINE=MRG_MYISAM UNION=(t1)
+INSERT_METHOD=LAST;
+CREATE TRIGGER tm1_ai AFTER INSERT ON tm1
+FOR EACH ROW SELECT max(c1) FROM t1 INTO @var;
+LOCK TABLE tm1 WRITE, t1 WRITE;
+INSERT INTO tm1 VALUES (1);
+SELECT * FROM tm1;
+c1
+1
+UNLOCK TABLES;
+LOCK TABLE t1 WRITE, tm1 WRITE;
+INSERT INTO tm1 VALUES (1);
+SELECT * FROM tm1;
+c1
+1
+1
+UNLOCK TABLES;
+DROP TRIGGER tm1_ai;
+DROP TABLE tm1, t1;
+CREATE TABLE t1 (c1 INT) ENGINE=MyISAM;
+CREATE TABLE t2 (c1 INT) ENGINE=MyISAM;
+CREATE TABLE t3 (c1 INT) ENGINE=MyISAM;
+CREATE TABLE t4 (c1 INT) ENGINE=MyISAM;
+CREATE TABLE t5 (c1 INT) ENGINE=MyISAM;
+CREATE TABLE tm1 (c1 INT) ENGINE=MRG_MYISAM UNION=(t1,t2,t3,t4,t5)
+INSERT_METHOD=LAST;
+CREATE TRIGGER t2_au AFTER UPDATE ON t2
+FOR EACH ROW SELECT MAX(c1) FROM t1 INTO @var;
+CREATE FUNCTION f1() RETURNS INT
+RETURN (SELECT MAX(c1) FROM t4);
+LOCK TABLE tm1 WRITE, t1 WRITE, t2 WRITE, t3 WRITE, t4 WRITE, t5 WRITE;
+INSERT INTO t1 VALUES(1);
+INSERT INTO t2 VALUES(2);
+INSERT INTO t3 VALUES(3);
+INSERT INTO t4 VALUES(4);
+INSERT INTO t5 VALUES(5);
+UPDATE t2, tm1 SET t2.c1=f1();
+FLUSH TABLES;
+FLUSH TABLES;
+UNLOCK TABLES;
+SELECT * FROM tm1;
+c1
+1
+4
+3
+4
+5
+DROP TRIGGER t2_au;
+DROP FUNCTION f1;
+DROP TABLE tm1, t1, t2, t3, t4, t5;
+#
+# Bug47098 assert in MDL_context::destroy on HANDLER
+# <damaged merge table> OPEN
+#
+# Test that merge tables are closed correctly when opened using
+# HANDLER ... OPEN.
+# The general case.
+DROP TABLE IF EXISTS t1, t2, t3;
+# Connection con1.
+CREATE TABLE t1 (c1 int);
+CREATE TABLE t2 (c1 int);
+CREATE TABLE t3 (c1 int) ENGINE = MERGE UNION (t1,t2);
+START TRANSACTION;
+HANDLER t3 OPEN;
+ERROR HY000: Table storage engine for 't3' doesn't have this option
+DROP TABLE t1, t2, t3;
+# Connection default.
+# Disconnecting con1, all mdl_tickets must have been released.
+# The bug-specific case.
+# Connection con1.
+CREATE TABLE t1 (c1 int);
+CREATE TABLE t2 (c1 int);
+CREATE TABLE t3 (c1 int) ENGINE = MERGE UNION (t1,t2);
+DROP TABLE t2;
+START TRANSACTION;
+HANDLER t3 OPEN;
+ERROR HY000: Unable to open underlying table which is differently defined or of non-MyISAM type or doesn't exist
+DROP TABLE t1, t3;
+# Connection default.
+# Disconnecting con1, all mdl_tickets must have been released.
+#
+# A test case for Bug#47648 main.merge fails sporadically
+#
+# Make sure we correctly maintain lex->query_tables_last_own.
+#
+create table t1 (c1 int not null);
+create table t2 (c1 int not null);
+create table t3 (c1 int not null);
+create function f1 () returns int return (select max(c1) from t3);
+create table t4 (c1 int not null) engine=merge union=(t1,t2) insert_method=last ;
+select * from t4 where c1 < f1();
+c1
+prepare stmt from "select * from t4 where c1 < f1()";
+execute stmt;
+c1
+execute stmt;
+c1
+execute stmt;
+c1
+drop function f1;
+execute stmt;
+ERROR 42000: FUNCTION test.f1 does not exist
+execute stmt;
+ERROR 42000: FUNCTION test.f1 does not exist
+drop table t4, t3, t2, t1;
+End of 6.0 tests
diff --git a/mysql-test/r/merge_recover.result b/mysql-test/r/merge_recover.result
new file mode 100644
index 00000000000..871c12ca4c0
--- /dev/null
+++ b/mysql-test/r/merge_recover.result
@@ -0,0 +1,103 @@
+#
+# Test of MyISAM MRG tables with corrupted children.
+# Run with --myisam-recover=force option.
+#
+# Preparation: we need to make sure that the merge parent
+# is never left in the table cache when closed, since this may
+# have effect on merge children.
+# For that, we set the table cache to minimal size and populate it
+# in a concurrent connection.
+#
+# Switching to connection con1
+#
+#
+# Minimal values.
+#
+call mtr.add_suppression("Got an error from thread_id=.*ha_myisam.cc:");
+call mtr.add_suppression("MySQL thread id .*, query id .* localhost.*root Checking table");
+call mtr.add_suppression(" '\..test.t1'");
+set global table_open_cache=256;
+set global table_definition_cache=400;
+drop procedure if exists p_create;
+create procedure p_create()
+begin
+declare i int default 1;
+set @lock_table_stmt="lock table ";
+set @drop_table_stmt="drop table ";
+while i < @@global.table_definition_cache + 1 do
+set @table_name=concat("t_", i);
+set @opt_comma=if(i=1, "", ", ");
+set @lock_table_stmt=concat(@lock_table_stmt, @opt_comma,
+@table_name, " read");
+set @drop_table_stmt=concat(@drop_table_stmt, @opt_comma, @table_name);
+set @create_table_stmt=concat("create table if not exists ",
+@table_name, " (a int)");
+prepare stmt from @create_table_stmt;
+execute stmt;
+deallocate prepare stmt;
+set i= i+1;
+end while;
+end|
+call p_create();
+drop procedure p_create;
+#
+# Switching to connection 'default'
+#
+#
+# We have to disable the ps-protocol, to avoid
+# "Prepared statement needs to be re-prepared" errors
+# -- table def versions change all the time with full table cache.
+#
+drop table if exists t1, t1_mrg, t1_copy;
+#
+# Prepare a MERGE engine table, that refers to a corrupted
+# child.
+#
+create table t1 (a int, key(a)) engine=myisam;
+create table t1_mrg (a int) union (t1) engine=merge;
+#
+# Create a table with a corrupted index file:
+# save an old index file, insert more rows,
+# overwrite the new index file with the old one.
+#
+insert into t1 (a) values (1), (2), (3);
+flush table t1;
+insert into t1 (a) values (4), (5), (6);
+flush table t1;
+# check table is needed to mark the table as crashed.
+check table t1;
+Table Op Msg_type Msg_text
+test.t1 check warning Size of datafile is: 42 Should be: 21
+test.t1 check error Record-count is not ok; is 6 Should be: 3
+test.t1 check warning Found 6 key parts. Should be: 3
+test.t1 check error Corrupt
+#
+# At this point we have a merge table t1_mrg pointing to t1,
+# and t1 is corrupted, and will be auto-repaired at open.
+# Check that this doesn't lead to memory corruption.
+#
+select * from t1_mrg;
+a
+1
+2
+3
+4
+5
+6
+Warnings:
+Error 145 Table 't1' is marked as crashed and should be repaired
+Error 1194 Table 't1' is marked as crashed and should be repaired
+Error 1034 Number of rows changed from 3 to 6
+#
+# Cleanup
+#
+drop table t1, t1_mrg;
+#
+# Switching to connection con1
+#
+unlock tables;
+prepare stmt from @drop_table_stmt;
+execute stmt;
+deallocate prepare stmt;
+set @@global.table_definition_cache=default;
+set @@global.table_open_cache=default;
diff --git a/mysql-test/r/mix2_myisam.result b/mysql-test/r/mix2_myisam.result
index cabc4de8d21..99596c7774d 100644
--- a/mysql-test/r/mix2_myisam.result
+++ b/mysql-test/r/mix2_myisam.result
@@ -2063,6 +2063,7 @@ insert into t1(a) values (1),(2),(3);
commit;
set autocommit = 0;
update t1 set b = 5 where a = 2;
+commit;
create trigger t1t before insert on t1 for each row begin set NEW.b = NEW.a * 10 + 5, NEW.c = NEW.a / 10; end |
set autocommit = 0;
insert into t1(a) values (10),(20),(30),(40),(50),(60),(70),(80),(90),(100),
@@ -2105,6 +2106,7 @@ update t2 set b = b + 5 where a = 1;
update t3 set b = b + 5 where a = 1;
update t4 set b = b + 5 where a = 1;
insert into t5(a) values(20);
+commit;
set autocommit = 0;
insert into t1(a) values(7);
insert into t2(a) values(8);
diff --git a/mysql-test/r/mysqld--help-notwin.result b/mysql-test/r/mysqld--help-notwin.result
index 7b2f4e670c8..7c6a7a2491a 100644
--- a/mysql-test/r/mysqld--help-notwin.result
+++ b/mysql-test/r/mysqld--help-notwin.result
@@ -219,6 +219,9 @@ The following options may be given as the first argument:
the week.
--local-infile Enable LOAD DATA LOCAL INFILE
(Defaults to on; use --skip-local-infile to disable.)
+ --lock-wait-timeout=#
+ Timeout in seconds to wait for a lock before returning an
+ error.
-l, --log[=name] Log connections and queries to file (deprecated option,
use --general-log/--general-log-file instead).
--log-bin[=name] Log update queries in binary format. Optional (but
@@ -706,10 +709,6 @@ The following options may be given as the first argument:
--table-cache=# Deprecated; use --table-open-cache instead.
--table-definition-cache=#
The number of cached table definitions
- --table-lock-wait-timeout=#
- Timeout in seconds to wait for a table level lock before
- returning an error. Used only if the connection has
- active cursors
--table-open-cache=#
The number of cached open tables
--tc-heuristic-recover=name
@@ -826,6 +825,7 @@ lc-messages en_US
lc-messages-dir MYSQL_SHAREDIR/
lc-time-names en_US
local-infile TRUE
+lock-wait-timeout 31536000
log-bin (No default value)
log-bin-index (No default value)
log-bin-trust-function-creators FALSE
@@ -964,7 +964,6 @@ sync-relay-log-info 0
sysdate-is-now FALSE
table-cache 400
table-definition-cache 400
-table-lock-wait-timeout 50
table-open-cache 400
tc-heuristic-recover COMMIT
thread-cache-size 0
diff --git a/mysql-test/r/mysqld--help-win.result b/mysql-test/r/mysqld--help-win.result
index d6236de2389..b4896b0e002 100644
--- a/mysql-test/r/mysqld--help-win.result
+++ b/mysql-test/r/mysqld--help-win.result
@@ -218,6 +218,9 @@ The following options may be given as the first argument:
the week.
--local-infile Enable LOAD DATA LOCAL INFILE
(Defaults to on; use --skip-local-infile to disable.)
+ --lock-wait-timeout=#
+ Timeout in seconds to wait for a lock before returning an
+ error.
-l, --log[=name] Log connections and queries to file (deprecated option,
use --general-log/--general-log-file instead).
--log-bin[=name] Log update queries in binary format. Optional (but
@@ -710,10 +713,6 @@ The following options may be given as the first argument:
--table-cache=# Deprecated; use --table-open-cache instead.
--table-definition-cache=#
The number of cached table definitions
- --table-lock-wait-timeout=#
- Timeout in seconds to wait for a table level lock before
- returning an error. Used only if the connection has
- active cursors
--table-open-cache=#
The number of cached open tables
--tc-heuristic-recover=name
@@ -829,6 +828,7 @@ lc-messages en_US
lc-messages-dir MYSQL_SHAREDIR/
lc-time-names en_US
local-infile TRUE
+lock-wait-timeout 31536000
log-bin (No default value)
log-bin-index (No default value)
log-bin-trust-function-creators FALSE
@@ -970,7 +970,6 @@ sync-relay-log-info 0
sysdate-is-now FALSE
table-cache 400
table-definition-cache 400
-table-lock-wait-timeout 50
table-open-cache 400
tc-heuristic-recover COMMIT
thread-cache-size 0
diff --git a/mysql-test/r/not_embedded_server.result b/mysql-test/r/not_embedded_server.result
index 60c92bd0196..fac38624695 100644
--- a/mysql-test/r/not_embedded_server.result
+++ b/mysql-test/r/not_embedded_server.result
@@ -1,6 +1,16 @@
-select 1;
-1
-1
+call mtr.add_suppression("Can't open and lock privilege tables: Table 'host' was not locked with LOCK TABLES");
SHOW VARIABLES like 'slave_skip_errors';
Variable_name Value
slave_skip_errors OFF
+#
+# WL#4284: Transactional DDL locking
+#
+# FLUSH PRIVILEGES should not implicitly unlock locked tables.
+#
+drop table if exists t1;
+create table t1 (c1 int);
+lock tables t1 read;
+flush privileges;
+ERROR HY000: Table 'host' was not locked with LOCK TABLES
+unlock tables;
+drop table t1;
diff --git a/mysql-test/r/partition.result b/mysql-test/r/partition.result
index b72cc607fe2..e855ffb23e3 100644
--- a/mysql-test/r/partition.result
+++ b/mysql-test/r/partition.result
@@ -78,6 +78,15 @@ show indexes from t1;
Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment
t1 1 a 1 a A 1 NULL NULL YES BTREE
drop table t1;
+create table t1 (a int)
+partition by hash (a);
+create index i on t1 (a);
+insert into t1 values (1);
+insert into t1 select * from t1;
+create index i on t1 (a);
+ERROR 42000: Duplicate key name 'i'
+create index i2 on t1 (a);
+drop table t1;
CREATE TABLE t1 (a INT, FOREIGN KEY (a) REFERENCES t0 (a))
ENGINE=MyISAM
PARTITION BY HASH (a);
diff --git a/mysql-test/r/partition_column_prune.result b/mysql-test/r/partition_column_prune.result
index 82c49453d43..844429d24a6 100644
--- a/mysql-test/r/partition_column_prune.result
+++ b/mysql-test/r/partition_column_prune.result
@@ -56,11 +56,11 @@ insert into t1 values (2,5), (2,15), (2,25),
insert into t1 select * from t1;
explain partitions select * from t1 where a=2;
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p01,p02,p03,p11 ALL NULL NULL NULL NULL 13 Using where
+1 SIMPLE t1 p01,p02,p03,p11 ALL NULL NULL NULL NULL 8 Using where
explain partitions select * from t1 where a=4;
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p11,p12,p13,p21 ALL NULL NULL NULL NULL 16 Using where
+1 SIMPLE t1 p11,p12,p13,p21 ALL NULL NULL NULL NULL 14 Using where
explain partitions select * from t1 where a=2 and b < 22;
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p01,p02,p03 ALL NULL NULL NULL NULL 16 Using where
+1 SIMPLE t1 p01,p02,p03 ALL NULL NULL NULL NULL 14 Using where
drop table t1;
diff --git a/mysql-test/r/partition_innodb.result b/mysql-test/r/partition_innodb.result
index 186082c435f..d7145fcc604 100644
--- a/mysql-test/r/partition_innodb.result
+++ b/mysql-test/r/partition_innodb.result
@@ -304,47 +304,3 @@ CREATE TABLE t1 (a INT) ENGINE=InnoDB
PARTITION BY list(a) (PARTITION p1 VALUES IN (1));
CREATE INDEX i1 ON t1 (a);
DROP TABLE t1;
-#
-# Bug#47343: InnoDB fails to clean-up after lock wait timeout on
-# REORGANIZE PARTITION
-#
-CREATE TABLE t1 (
-a INT,
-b DATE NOT NULL,
-PRIMARY KEY (a, b)
-) ENGINE=InnoDB
-PARTITION BY RANGE (a) (
-PARTITION pMAX VALUES LESS THAN MAXVALUE
-) ;
-INSERT INTO t1 VALUES (1, '2001-01-01'), (2, '2002-02-02'), (3, '2003-03-03');
-START TRANSACTION;
-SELECT * FROM t1 FOR UPDATE;
-a b
-1 2001-01-01
-2 2002-02-02
-3 2003-03-03
-# Connection con1
-ALTER TABLE t1 REORGANIZE PARTITION pMAX INTO
-(PARTITION p3 VALUES LESS THAN (3),
-PARTITION pMAX VALUES LESS THAN MAXVALUE);
-ERROR HY000: Lock wait timeout exceeded; try restarting transaction
-SHOW WARNINGS;
-Level Code Message
-Error 1205 Lock wait timeout exceeded; try restarting transaction
-ALTER TABLE t1 REORGANIZE PARTITION pMAX INTO
-(PARTITION p3 VALUES LESS THAN (3),
-PARTITION pMAX VALUES LESS THAN MAXVALUE);
-ERROR HY000: Lock wait timeout exceeded; try restarting transaction
-SHOW WARNINGS;
-Level Code Message
-Error 1205 Lock wait timeout exceeded; try restarting transaction
-t1.frm
-t1.par
-# Connection default
-SELECT * FROM t1;
-a b
-1 2001-01-01
-2 2002-02-02
-3 2003-03-03
-COMMIT;
-DROP TABLE t1;
diff --git a/mysql-test/r/partition_innodb_semi_consistent.result b/mysql-test/r/partition_innodb_semi_consistent.result
index 471da4c1c2e..48a1bb3d258 100644
--- a/mysql-test/r/partition_innodb_semi_consistent.result
+++ b/mysql-test/r/partition_innodb_semi_consistent.result
@@ -102,7 +102,7 @@ a b
# Switch to connection con1
# 3. test for updated key column:
TRUNCATE t1;
-TRUNCATE t2;
+DELETE FROM t2;
INSERT INTO t1 VALUES (1,'init');
BEGIN;
UPDATE t1 SET a = 2, b = CONCAT(b, '+con1') WHERE a = 1;
diff --git a/mysql-test/r/partition_pruning.result b/mysql-test/r/partition_pruning.result
index bd81e2b5d4f..ba18f7b9685 100644
--- a/mysql-test/r/partition_pruning.result
+++ b/mysql-test/r/partition_pruning.result
@@ -2570,7 +2570,7 @@ id select_type table partitions type possible_keys key key_len ref rows Extra
explain partitions
select * from t1 X, t1 Y where X.a = Y.a and (X.a=1 or X.a=2);
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE X p1,p2 ALL a NULL NULL NULL 4 Using where
+1 SIMPLE X p1,p2 ALL a NULL NULL NULL 2 Using where
1 SIMPLE Y p1,p2 ref a a 4 test.X.a 2
drop table t1;
create table t1 (a int) partition by hash(a) partitions 20;
diff --git a/mysql-test/r/partition_sync.result b/mysql-test/r/partition_sync.result
index 31cf0569464..d48362cb57c 100644
--- a/mysql-test/r/partition_sync.result
+++ b/mysql-test/r/partition_sync.result
@@ -23,3 +23,35 @@ a
1
# Connection 1
DROP TABLE t1;
+#
+# Bug #46654 False deadlock on concurrent DML/DDL
+# with partitions, inconsistent behavior
+#
+DROP TABLE IF EXISTS tbl_with_partitions;
+CREATE TABLE tbl_with_partitions ( i INT )
+PARTITION BY HASH(i);
+INSERT INTO tbl_with_partitions VALUES (1);
+# Connection 3
+LOCK TABLE tbl_with_partitions READ;
+# Connection 1
+# Access table with disabled autocommit
+SET AUTOCOMMIT = 0;
+SELECT * FROM tbl_with_partitions;
+i
+1
+# Connection 2
+# Alter table, abort after prepare
+set session debug="+d,abort_copy_table";
+ALTER TABLE tbl_with_partitions ADD COLUMN f INT;
+ERROR HY000: Lock wait timeout exceeded; try restarting transaction
+# Connection 1
+# Try accessing the table after Alter aborted.
+# This used to give ER_LOCK_DEADLOCK.
+SELECT * FROM tbl_with_partitions;
+i
+1
+# Connection 3
+UNLOCK TABLES;
+# Connection 1
+# Cleanup
+DROP TABLE tbl_with_partitions;
diff --git a/mysql-test/r/ps.result b/mysql-test/r/ps.result
index c9628e43ddd..d7b2fa5820a 100644
--- a/mysql-test/r/ps.result
+++ b/mysql-test/r/ps.result
@@ -3152,5 +3152,29 @@ DROP PROCEDURE p1;
DROP PROCEDURE p2;
# End of WL#4435.
-
-End of 6.0 tests.
+#
+# WL#4284: Transactional DDL locking
+#
+DROP TABLE IF EXISTS t1;
+CREATE TABLE t1 (a INT);
+BEGIN;
+SELECT * FROM t1;
+a
+# Test that preparing a CREATE TABLE does not take a exclusive metdata lock.
+PREPARE stmt1 FROM "CREATE TABLE t1 AS SELECT 1";
+EXECUTE stmt1;
+ERROR 42S01: Table 't1' already exists
+DEALLOCATE PREPARE stmt1;
+DROP TABLE t1;
+#
+# WL#4284: Transactional DDL locking
+#
+# Test that metadata locks taken during prepare are released.
+#
+DROP TABLE IF EXISTS t1;
+CREATE TABLE t1 (a INT);
+BEGIN;
+PREPARE stmt1 FROM "SELECT * FROM t1";
+DROP TABLE t1;
+#
+# End of 6.0 tests.
diff --git a/mysql-test/r/ps_ddl.result b/mysql-test/r/ps_ddl.result
index 375f31ef9c4..6987694407d 100644
--- a/mysql-test/r/ps_ddl.result
+++ b/mysql-test/r/ps_ddl.result
@@ -269,8 +269,6 @@ Part 7: TABLE -> TABLE (TRIGGER dependencies) transitions
=====================================================================
# Test 7-a: dependent PROCEDURE has changed
#
-# Note, this scenario is not supported, subject of Bug#12093
-#
create table t1 (a int);
create trigger t1_ai after insert on t1 for each row
call p1(new.a);
@@ -282,10 +280,9 @@ drop procedure p1;
create procedure p1 (a int) begin end;
set @var= 2;
execute stmt using @var;
-ERROR 42000: PROCEDURE test.p1 does not exist
# Cleanup
drop procedure p1;
-call p_verify_reprepare_count(0);
+call p_verify_reprepare_count(1);
SUCCESS
# Test 7-b: dependent FUNCTION has changed
@@ -361,11 +358,13 @@ set @var=8;
# XXX: bug, the SQL statement in the trigger is still
# pointing at table 't3', since the view was expanded
# at first statement execution.
+# Since the view definition is inlined in the statement
+# at prepare, changing the view definition does not cause
+# repreparation.
# Repreparation of the main statement doesn't cause repreparation
# of trigger statements.
execute stmt using @var;
-ERROR 42S02: Table 'test.t3' doesn't exist
-call p_verify_reprepare_count(1);
+call p_verify_reprepare_count(0);
SUCCESS
#
@@ -382,6 +381,7 @@ select * from t3;
a
6
7
+8
flush table t1;
set @var=9;
execute stmt using @var;
@@ -396,6 +396,7 @@ select * from t3;
a
6
7
+8
drop view v1;
drop table t1,t2,t3;
# Test 7-d: dependent TABLE has changed
@@ -707,6 +708,9 @@ deallocate prepare stmt;
=====================================================================
Part 16: VIEW -> TEMPORARY TABLE transitions
=====================================================================
+#
+# Test 1: Merged view
+#
create table t2 (a int);
insert into t2 (a) values (1);
create view t1 as select * from t2;
@@ -720,18 +724,74 @@ SUCCESS
create temporary table t1 (a int);
execute stmt;
a
-call p_verify_reprepare_count(1);
+1
+call p_verify_reprepare_count(0);
SUCCESS
drop view t1;
execute stmt;
+ERROR 42S02: Table 'test.t1' doesn't exist
+call p_verify_reprepare_count(0);
+SUCCESS
+
+drop table t2;
+drop temporary table t1;
+deallocate prepare stmt;
+#
+# Test 2: Materialized view
+#
+create table t2 (a int);
+insert into t2 (a) values (1);
+create algorithm = temptable view t1 as select * from t2;
+prepare stmt from "select * from t1";
+execute stmt;
+a
+1
+call p_verify_reprepare_count(0);
+SUCCESS
+
+create temporary table t1 (a int);
+execute stmt;
a
+1
+call p_verify_reprepare_count(0);
+SUCCESS
+
+drop view t1;
+execute stmt;
+ERROR 42S02: Table 'test.t1' doesn't exist
call p_verify_reprepare_count(0);
SUCCESS
drop table t2;
drop temporary table t1;
deallocate prepare stmt;
+#
+# Test 3: View referencing an Information schema table
+#
+create view t1 as select table_name from information_schema.views;
+prepare stmt from "select * from t1";
+execute stmt;
+table_name
+t1
+call p_verify_reprepare_count(0);
+SUCCESS
+
+create temporary table t1 (a int);
+execute stmt;
+table_name
+t1
+call p_verify_reprepare_count(0);
+SUCCESS
+
+drop view t1;
+execute stmt;
+table_name
+call p_verify_reprepare_count(0);
+SUCCESS
+
+drop temporary table t1;
+deallocate prepare stmt;
=====================================================================
Part 17: VIEW -> VIEW (DDL) transitions
=====================================================================
@@ -1695,7 +1755,7 @@ SUCCESS
drop table t2;
create temporary table t2 (a int);
execute stmt;
-call p_verify_reprepare_count(1);
+call p_verify_reprepare_count(0);
SUCCESS
execute stmt;
@@ -1711,7 +1771,7 @@ SUCCESS
drop table t2;
execute stmt;
-call p_verify_reprepare_count(1);
+call p_verify_reprepare_count(0);
SUCCESS
drop table t2;
@@ -1755,21 +1815,21 @@ SUCCESS
drop table t1;
deallocate prepare stmt;
-# XXX: no validation of the first table in case of
-# CREATE TEMPORARY TABLE. This is a shortcoming of the current code,
-# but since validation is not strictly necessary, nothing is done
-# about it.
-# Will be fixed as part of work on Bug#21431 "Incomplete support of
-# temporary tables"
create table t1 (a int);
insert into t1 (a) values (1);
prepare stmt from "create temporary table if not exists t2 as select * from t1";
execute stmt;
drop table t2;
execute stmt;
+call p_verify_reprepare_count(0);
+SUCCESS
+
execute stmt;
Warnings:
Note 1050 Table 't2' already exists
+call p_verify_reprepare_count(1);
+SUCCESS
+
select * from t2;
a
1
@@ -1777,6 +1837,9 @@ a
execute stmt;
Warnings:
Note 1050 Table 't2' already exists
+call p_verify_reprepare_count(0);
+SUCCESS
+
select * from t2;
a
1
@@ -1790,7 +1853,7 @@ Note 1050 Table 't2' already exists
select * from t2;
a
1
-call p_verify_reprepare_count(0);
+call p_verify_reprepare_count(1);
SUCCESS
drop table t1;
diff --git a/mysql-test/r/ps_ddl1.result b/mysql-test/r/ps_ddl1.result
index e41a72ceb96..87abcd90590 100644
--- a/mysql-test/r/ps_ddl1.result
+++ b/mysql-test/r/ps_ddl1.result
@@ -460,7 +460,7 @@ create schema mysqltest;
end|
execute stmt;
ERROR 42000: PROCEDURE test.p1 does not exist
-call p_verify_reprepare_count(1);
+call p_verify_reprepare_count(0);
SUCCESS
execute stmt;
diff --git a/mysql-test/r/repair.result b/mysql-test/r/repair.result
index 5bb3dd76fed..6ab5ecb7e18 100644
--- a/mysql-test/r/repair.result
+++ b/mysql-test/r/repair.result
@@ -157,3 +157,29 @@ REPAIR TABLE tt1 USE_FRM;
Table Op Msg_type Msg_text
tt1 repair error Cannot repair temporary table from .frm file
DROP TABLE tt1;
+#
+# Bug #48248 assert in MDL_ticket::upgrade_shared_lock_to_exclusive
+#
+DROP TABLE IF EXISTS t1;
+CREATE TABLE t1(a INT);
+LOCK TABLES t1 READ;
+REPAIR TABLE t1;
+Table Op Msg_type Msg_text
+test.t1 repair Error Table 't1' was locked with a READ lock and can't be updated
+test.t1 repair status Operation failed
+UNLOCK TABLES;
+DROP TABLE t1;
+#
+# Test for bug #50784 "MDL: Assertion `m_tickets.is_empty() ||
+# m_tickets.front() == m_trans_sentinel'"
+#
+drop tables if exists t1, t2;
+create table t1 (i int);
+create table t2 (j int);
+set @@autocommit= 0;
+repair table t1, t2;
+Table Op Msg_type Msg_text
+test.t1 repair status OK
+test.t2 repair status OK
+set @@autocommit= default;
+drop tables t1, t2;
diff --git a/mysql-test/r/schema.result b/mysql-test/r/schema.result
index 402d3e1d987..2919606d74a 100644
--- a/mysql-test/r/schema.result
+++ b/mysql-test/r/schema.result
@@ -12,3 +12,39 @@ mysql
performance_schema
test
drop schema foo;
+#
+# Bug #48940 MDL deadlocks against mysql_rm_db
+#
+DROP SCHEMA IF EXISTS schema1;
+# Connection default
+CREATE SCHEMA schema1;
+CREATE TABLE schema1.t1 (a INT);
+SET autocommit= FALSE;
+INSERT INTO schema1.t1 VALUES (1);
+# Connection 2
+DROP SCHEMA schema1;
+# Connection default
+ALTER SCHEMA schema1 DEFAULT CHARACTER SET utf8;
+Got one of the listed errors
+SET autocommit= TRUE;
+# Connection 2
+# Connection default
+#
+# Bug #49988 MDL deadlocks with mysql_create_db, reload_acl_and_cache
+#
+DROP SCHEMA IF EXISTS schema1;
+# Connection default
+CREATE SCHEMA schema1;
+CREATE TABLE schema1.t1 (id INT);
+LOCK TABLE schema1.t1 WRITE;
+# Connection con2
+DROP SCHEMA schema1;
+# Connection default
+# CREATE SCHEMA used to give a deadlock.
+# Now we prohibit CREATE SCHEMA in LOCK TABLES mode.
+CREATE SCHEMA IF NOT EXISTS schema1;
+ERROR HY000: Can't execute the given command because you have active locked tables or an active transaction
+# UNLOCK TABLES so DROP SCHEMA can continue.
+UNLOCK TABLES;
+# Connection con2
+# Connection default
diff --git a/mysql-test/r/sp-error.result b/mysql-test/r/sp-error.result
index 00ae7dd4eca..4cefee95903 100644
--- a/mysql-test/r/sp-error.result
+++ b/mysql-test/r/sp-error.result
@@ -512,7 +512,7 @@ select * from t1;
end|
lock table t1 read|
alter procedure bug9566 comment 'Some comment'|
-ERROR HY000: Table 'proc' was not locked with LOCK TABLES
+ERROR HY000: Can't execute the given command because you have active locked tables or an active transaction
unlock tables|
drop procedure bug9566|
drop procedure if exists bug7299|
@@ -1687,6 +1687,17 @@ NULL
SELECT non_existent (a) FROM t1 WHERE b = 999999;
ERROR 42000: FUNCTION test.non_existent does not exist
DROP TABLE t1;
+CREATE TABLE t1 ( f2 INTEGER, f3 INTEGER );
+INSERT INTO t1 VALUES ( 1, 1 );
+CREATE FUNCTION func_1 () RETURNS INTEGER
+BEGIN
+INSERT INTO t1 SELECT * FROM t1 ;
+RETURN 1 ;
+END|
+INSERT INTO t1 SELECT * FROM (SELECT 2 AS f1, 2 AS f2) AS A WHERE func_1() = 5;
+ERROR HY000: Can't update table 't1' in stored function/trigger because it is already used by statement which invoked this stored function/trigger.
+DROP FUNCTION func_1;
+DROP TABLE t1;
#
# Bug #47788: Crash in TABLE_LIST::hide_view_error on UPDATE + VIEW +
# SP + MERGE + ALTER
diff --git a/mysql-test/r/sp-lock.result b/mysql-test/r/sp-lock.result
new file mode 100644
index 00000000000..e9087f61807
--- /dev/null
+++ b/mysql-test/r/sp-lock.result
@@ -0,0 +1,697 @@
+#
+# Test coverage for changes performed by the fix
+# for Bug#30977 "Concurrent statement using stored function
+# and DROP FUNCTION breaks SBR.
+#
+#
+# 1) Verify that the preceding transaction is
+# (implicitly) committed before CREATE/ALTER/DROP
+# PROCEDURE. Note, that this is already tested
+# in implicit_commit.test, but here we use an alternative
+# approach.
+#
+# Start a transaction, create a savepoint,
+# then call a DDL operation on a procedure, and then check
+# that the savepoint is no longer present.
+drop table if exists t1;
+drop procedure if exists p1;
+drop procedure if exists p2;
+drop procedure if exists p3;
+drop procedure if exists p4;
+drop function if exists f1;
+create table t1 (a int);
+#
+# Test 'CREATE PROCEDURE'.
+#
+begin;
+savepoint sv;
+create procedure p1() begin end;
+rollback to savepoint sv;
+ERROR 42000: SAVEPOINT sv does not exist
+#
+# Test 'ALTER PROCEDURE'.
+#
+begin;
+savepoint sv;
+alter procedure p1 comment 'changed comment';
+rollback to savepoint sv;
+ERROR 42000: SAVEPOINT sv does not exist
+#
+# Test 'DROP PROCEDURE'.
+#
+begin;
+savepoint sv;
+drop procedure p1;
+rollback to savepoint sv;
+ERROR 42000: SAVEPOINT sv does not exist
+#
+# Test 'CREATE FUNCTION'.
+#
+begin;
+savepoint sv;
+create function f1() returns int return 1;
+rollback to savepoint sv;
+ERROR 42000: SAVEPOINT sv does not exist
+#
+# Test 'ALTER FUNCTION'.
+#
+begin;
+savepoint sv;
+alter function f1 comment 'new comment';
+rollback to savepoint sv;
+ERROR 42000: SAVEPOINT sv does not exist
+#
+# Test 'DROP FUNCTION'.
+#
+begin;
+savepoint sv;
+drop function f1;
+rollback to savepoint sv;
+ERROR 42000: SAVEPOINT sv does not exist
+#
+# 2) Verify that procedure DDL operations fail
+# under lock tables.
+#
+# Auxiliary routines to test ALTER.
+create procedure p1() begin end;
+create function f1() returns int return 1;
+lock table t1 write;
+create procedure p2() begin end;
+ERROR HY000: Can't execute the given command because you have active locked tables or an active transaction
+alter procedure p1 comment 'changed comment';
+ERROR HY000: Can't execute the given command because you have active locked tables or an active transaction
+drop procedure p1;
+ERROR HY000: Can't execute the given command because you have active locked tables or an active transaction
+create function f2() returns int return 1;
+ERROR HY000: Can't execute the given command because you have active locked tables or an active transaction
+alter function f1 comment 'changed comment';
+ERROR HY000: Can't execute the given command because you have active locked tables or an active transaction
+lock table t1 read;
+create procedure p2() begin end;
+ERROR HY000: Can't execute the given command because you have active locked tables or an active transaction
+alter procedure p1 comment 'changed comment';
+ERROR HY000: Can't execute the given command because you have active locked tables or an active transaction
+drop procedure p1;
+ERROR HY000: Can't execute the given command because you have active locked tables or an active transaction
+create function f2() returns int return 1;
+ERROR HY000: Can't execute the given command because you have active locked tables or an active transaction
+alter function f1 comment 'changed comment';
+ERROR HY000: Can't execute the given command because you have active locked tables or an active transaction
+unlock tables;
+#
+# Even if we locked a temporary table.
+# Todo: this is a restriction we could possibly lift.
+#
+drop table t1;
+create temporary table t1 (a int);
+lock table t1 read;
+create procedure p2() begin end;
+ERROR HY000: Can't execute the given command because you have active locked tables or an active transaction
+alter procedure p1 comment 'changed comment';
+ERROR HY000: Can't execute the given command because you have active locked tables or an active transaction
+drop procedure p1;
+ERROR HY000: Can't execute the given command because you have active locked tables or an active transaction
+create function f2() returns int return 1;
+ERROR HY000: Can't execute the given command because you have active locked tables or an active transaction
+alter function f1 comment 'changed comment';
+ERROR HY000: Can't execute the given command because you have active locked tables or an active transaction
+unlock tables;
+drop function f1;
+drop procedure p1;
+drop temporary table t1;
+#
+# 3) Verify that CREATE/ALTER/DROP routine grab an
+# exclusive lock.
+#
+# For that, start a transaction, use a routine. In a concurrent
+# connection, try to drop or alter the routine. It should place
+# a pending or exclusive lock and block. In another concurrnet
+# connection, try to use the routine.
+# That should block on the pending exclusive lock.
+#
+# Establish helper connections.
+#
+# Test DROP PROCEDURE.
+#
+# --> connection default
+create procedure p1() begin end;
+create function f1() returns int
+begin
+call p1();
+return 1;
+end|
+begin;
+select f1();
+f1()
+1
+# --> connection con1
+# Sending 'drop procedure p1'...
+drop procedure p1;
+# --> connection con2
+# Waitng for 'drop procedure t1' to get blocked on MDL lock...
+# Demonstrate that there is a pending exclusive lock.
+# Sending 'select f1()'...
+select f1();
+# --> connection con3
+# Waitng for 'select f1()' to get blocked by a pending MDL lock...
+# --> connection default
+commit;
+# --> connection con1
+# Reaping 'drop procedure p1'...
+# --> connection con2
+# Reaping 'select f1()'
+ERROR 42000: PROCEDURE test.p1 does not exist
+# --> connection default
+#
+# Test CREATE PROCEDURE.
+#
+create procedure p1() begin end;
+begin;
+select f1();
+f1()
+1
+# --> connection con1
+# Sending 'create procedure p1'...
+create procedure p1() begin end;
+# --> connection con2
+# Waitng for 'create procedure t1' to get blocked on MDL lock...
+# Demonstrate that there is a pending exclusive lock.
+# Sending 'select f1()'...
+select f1();
+# --> connection con3
+# Waitng for 'select f1()' to get blocked by a pending MDL lock...
+# --> connection default
+commit;
+# --> connection con1
+# Reaping 'create procedure p1'...
+ERROR 42000: PROCEDURE p1 already exists
+# --> connection con2
+# Reaping 'select f1()'
+f1()
+1
+#
+# Test ALTER PROCEDURE.
+#
+begin;
+select f1();
+f1()
+1
+# --> connection con1
+# Sending 'alter procedure p1'...
+alter procedure p1 contains sql;
+# --> connection con2
+# Waitng for 'alter procedure t1' to get blocked on MDL lock...
+# Demonstrate that there is a pending exclusive lock.
+# Sending 'select f1()'...
+select f1();
+# --> connection con3
+# Waitng for 'select f1()' to get blocked by a pending MDL lock...
+# --> connection default
+commit;
+# --> connection con1
+# Reaping 'alter procedure p1'...
+# --> connection con2
+# Reaping 'select f1()'
+f1()
+1
+# --> connection default
+#
+# Test DROP FUNCTION.
+#
+begin;
+select f1();
+f1()
+1
+# --> connection con1
+# Sending 'drop function f1'...
+drop function f1;
+# --> connection con2
+# Waitng for 'drop function f1' to get blocked on MDL lock...
+# Demonstrate that there is a pending exclusive lock.
+# Sending 'select f1()'...
+select f1();
+# --> connection con3
+# Waitng for 'select f1()' to get blocked by a pending MDL lock...
+# --> connection default
+commit;
+# --> connection con1
+# Reaping 'drop function f1'...
+# --> connection con2
+# Reaping 'select f1()'
+ERROR 42000: FUNCTION test.f1 does not exist
+# --> connection default
+#
+# Test CREATE FUNCTION.
+#
+create function f1() returns int return 1;
+begin;
+select f1();
+f1()
+1
+# --> connection con1
+# Sending 'create function f1'...
+create function f1() returns int return 2;
+# --> connection con2
+# Waitng for 'create function f1' to get blocked on MDL lock...
+# Demonstrate that there is a pending exclusive lock.
+# Sending 'select f1()'...
+select f1();
+# --> connection con3
+# Waitng for 'select f1()' to get blocked by a pending MDL lock...
+# --> connection default
+commit;
+# --> connection con1
+# Reaping 'create function f1'...
+ERROR 42000: FUNCTION f1 already exists
+# --> connection con2
+# Reaping 'select f1()'
+f1()
+1
+# --> connection default
+#
+# Test ALTER FUNCTION.
+#
+begin;
+select f1();
+f1()
+1
+# --> connection con1
+# Sending 'alter function f1'...
+alter function f1 contains sql;
+# --> connection con2
+# Waitng for 'alter function f1' to get blocked on MDL lock...
+# Demonstrate that there is a pending exclusive lock.
+# Sending 'select f1()'...
+select f1();
+# --> connection con3
+# Waitng for 'select f1()' to get blocked by a pending MDL lock...
+# --> connection default
+commit;
+# --> connection con1
+# Reaping 'alter function f1'...
+# --> connection con2
+# Reaping 'select f1()'
+f1()
+1
+# --> connection default
+drop function f1;
+drop procedure p1;
+#
+# 4) MDL lock should not be taken for
+# unrolled CALL statements.
+# The primary goal of metadata locks is a consistent binary log.
+# When a call statement is unrolled, it doesn't get to the
+# binary log, instead the statements that are contained
+# in the procedure body do. This can nest to any level.
+#
+create procedure p1() begin end;
+create procedure p2() begin end;
+create table t1 (a int);
+create procedure p3()
+begin
+call p1();
+call p1();
+call p2();
+end|
+create procedure p4()
+begin
+call p1();
+call p1();
+call p2();
+call p2();
+call p3();
+end|
+begin;
+select * from t1;
+a
+savepoint sv;
+call p4();
+# Prepared statement should not add any locks either.
+prepare stmt from "call p4()";
+execute stmt;
+execute stmt;
+# --> connection con1
+drop procedure p1;
+drop procedure p2;
+drop procedure p3;
+drop procedure p4;
+# --> connection default
+# This is to verify there was no implicit commit.
+rollback to savepoint sv;
+call p4();
+ERROR 42000: PROCEDURE test.p4 does not exist
+commit;
+drop table t1;
+#
+# 5) Locks should be taken on routines
+# used indirectly by views or triggers.
+#
+#
+# A function is used from a trigger.
+#
+create function f1() returns int return 1;
+create table t1 (a int);
+create table t2 (a int, b int);
+create trigger t1_ai after insert on t1 for each row
+insert into t2 (a, b) values (new.a, f1());
+begin;
+insert into t1 (a) values (1);
+# --> connection con1
+# Sending 'drop function f1'
+drop function f1;
+# --> connection con2
+# Waitng for 'drop function f1' to get blocked on MDL lock...
+# --> connnection default
+commit;
+# --> connection con1
+# Reaping 'drop function f1'...
+# --> connection default
+#
+# A function is used from a view.
+#
+create function f1() returns int return 1;
+create view v1 as select f1() as a;
+begin;
+select * from v1;
+a
+1
+# --> connection con1
+# Sending 'drop function f1'
+drop function f1;
+# --> connection con2
+# Waitng for 'drop function f1' to get blocked on MDL lock...
+# --> connnection default
+commit;
+# --> connection con1
+# Reaping 'drop function f1'...
+# --> connection default
+#
+# A procedure is used from a function.
+#
+create function f1() returns int
+begin
+declare v_out int;
+call p1(v_out);
+return v_out;
+end|
+create procedure p1(out v_out int) set v_out=3;
+begin;
+select * from v1;
+a
+3
+# --> connection con1
+# Sending 'drop procedure p1'
+drop procedure p1;
+# --> connection con2
+# Waitng for 'drop procedure p1' to get blocked on MDL lock...
+# --> connnection default
+commit;
+# --> connection con1
+# Reaping 'drop procedure p1'...
+# --> connection default
+#
+# Deep nesting: a function is used from a procedure used
+# from a function used from a view used in a trigger.
+#
+create function f2() returns int return 4;
+create procedure p1(out v_out int) set v_out=f2();
+drop trigger t1_ai;
+create trigger t1_ai after insert on t1 for each row
+insert into t2 (a, b) values (new.a, (select max(a) from v1));
+begin;
+insert into t1 (a) values (3);
+# --> connection con1
+# Sending 'drop function f2'
+drop function f2;
+# --> connection con2
+# Waitng for 'drop function f2' to get blocked on MDL lock...
+# --> connnection default
+commit;
+# --> connection con1
+# Reaping 'drop function f2'...
+# --> connection default
+drop view v1;
+drop function f1;
+drop procedure p1;
+drop table t1, t2;
+#
+# 6) Check that ER_LOCK_DEADLOCK is reported if
+# acquisition of a shared lock fails during a transaction or
+# we need to back off to flush the sp cache.
+#
+# Sic: now this situation does not require a back off since we
+# flush the cache on the fly.
+#
+create function f1() returns int return 7;
+create table t1 (a int);
+begin;
+select * from t1;
+a
+select f1();
+f1()
+7
+commit;
+drop table t1;
+drop function f1;
+#
+# 7) Demonstrate that under LOCK TABLES we accumulate locks
+# on stored routines, and release metadata locks in
+# ROLLBACK TO SAVEPOINT. That is done only for those stored
+# routines that are not part of LOCK TABLES prelocking list.
+# Those stored routines that are part of LOCK TABLES
+# prelocking list are implicitly locked when entering
+# LOCK TABLES, and ROLLBACK TO SAVEPOINT has no effect on
+# them.
+#
+create function f1() returns varchar(20) return "f1()";
+create function f2() returns varchar(20) return "f2()";
+create view v1 as select f1() as a;
+set @@session.autocommit=0;
+lock table v1 read;
+select * from v1;
+a
+f1()
+savepoint sv;
+select f2();
+f2()
+f2()
+# --> connection con1
+# Sending 'drop function f1'...
+drop function f1;
+# --> connection con2
+# Waitng for 'drop function f1' to get blocked on MDL lock...
+# Sending 'drop function f2'...
+drop function f2;
+# --> connection default
+# Waitng for 'drop function f2' to get blocked on MDL lock...
+rollback to savepoint sv;
+# --> connection con2
+# Reaping 'drop function f2'...
+# --> connection default
+unlock tables;
+# --> connection con1
+# Reaping 'drop function f1'...
+# --> connection default
+drop function f1;
+ERROR 42000: FUNCTION test.f1 does not exist
+drop function f2;
+ERROR 42000: FUNCTION test.f2 does not exist
+drop view v1;
+set @@session.autocommit=default;
+#
+# 8) Check the situation when we're preparing or executing a
+# prepared statement, and as part of that try to flush the
+# session sp cache. However, one of the procedures that
+# needs a flush is in use. Verify that there is no infinite
+# reprepare loop and no crash.
+#
+create function f1() returns int return 1;
+#
+# We just mention p1() in the body of f2() to make
+# sure that p1() metadata is validated when validating
+# 'select f2()'.
+# Recursion is not allowed in stored functions, so
+# an attempt to just invoke p1() from f2() which is in turn
+# called from p1() would have given a run-time error.
+#
+create function f2() returns int
+begin
+if @var is null then
+call p1();
+end if;
+return 1;
+end|
+create procedure p1()
+begin
+select f1() into @var;
+execute stmt;
+end|
+# --> connection con2
+prepare stmt from "select f2()";
+# --> connection default
+begin;
+select f1();
+f1()
+1
+# --> connection con1
+# Sending 'alter function f1 ...'...
+alter function f1 comment "comment";
+# --> connection con2
+# Waitng for 'alter function f1 ...' to get blocked on MDL lock...
+# Sending 'call p1()'...
+call p1();
+# Waitng for 'call p1()' to get blocked on MDL lock on f1...
+# Let 'alter function f1 ...' go through...
+commit;
+# --> connection con1
+# Reaping 'alter function f1 ...'
+# --> connection con2
+# Reaping 'call p1()'...
+f2()
+1
+deallocate prepare stmt;
+# --> connection default
+drop function f1;
+drop function f2;
+drop procedure p1;
+#
+# 9) Check the situation when a stored function is invoked
+# from a stored procedure, and recursively invokes the
+# stored procedure that is in use. But for the second
+# invocation, a cache flush is requested. We can't
+# flush the procedure that's in use, and are forced
+# to use an old version. It is not a violation of
+# consistency, since we unroll top-level calls.
+# Just verify the code works.
+#
+create function f1() returns int return 1;
+begin;
+select f1();
+f1()
+1
+# --> connection con1
+# Sending 'alter function f1 ...'...
+alter function f1 comment "comment";
+# --> connection con2
+# Waitng for 'alter function f1 ...' to get blocked on MDL lock...
+#
+# We just mention p1() in the body of f2() to make
+# sure that p1() is prelocked for f2().
+# Recursion is not allowed in stored functions, so
+# an attempt to just invoke p1() from f2() which is in turn
+# called from p1() would have given a run-time error.
+#
+create function f2() returns int
+begin
+if @var is null then
+call p1();
+end if;
+return 1;
+end|
+create procedure p1()
+begin
+select f1() into @var;
+select f2() into @var;
+end|
+# Sending 'call p1()'...
+call p1();
+# Waitng for 'call p1()' to get blocked on MDL lock on f1...
+# Let 'alter function f1 ...' go through...
+commit;
+# --> connection con1
+# Reaping 'alter function f1 ...'
+# --> connection con2
+# Reaping 'call p1()'...
+# --> connection default
+drop function f1;
+drop function f2;
+drop procedure p1;
+#
+# 10) A select from information_schema.routines now
+# flushes the stored routines caches. Test that this
+# does not remove from the cache a stored routine
+# that is already prelocked.
+#
+create function f1() returns int return get_lock("30977", 100000);
+create function f2() returns int return 2;
+create function f3() returns varchar(255)
+begin
+declare res varchar(255);
+declare c cursor for select routine_name from
+information_schema.routines where routine_name='f1';
+select f1() into @var;
+open c;
+fetch c into res;
+close c;
+select f2() into @var;
+return res;
+end|
+# --> connection con1
+select get_lock("30977", 0);
+get_lock("30977", 0)
+1
+# --> connection default
+# Sending 'select f3()'...
+select f3();
+# --> connection con1
+# Waitng for 'select f3()' to get blocked on the user level lock...
+# Do something to change the cache version.
+create function f4() returns int return 4;
+drop function f4;
+select release_lock("30977");
+release_lock("30977")
+1
+# --> connection default
+# Reaping 'select f3()'...
+# Routine 'f2()' should exist and get executed successfully.
+f3()
+f1
+select @var;
+@var
+2
+drop function f1;
+drop function f2;
+drop function f3;
+# 11) Check the situation when the connection is flushing the
+# SP cache which contains a procedure that is being executed.
+#
+# Function f1() calls p1(). Procedure p1() has a DROP
+# VIEW statement, which, we know, invalidates the routines cache.
+# During cache flush p1() must not be flushed since it's in
+# use.
+#
+create function f1() returns int
+begin
+call p1();
+return 1;
+end|
+create procedure p1()
+begin
+create view v1 as select 1;
+drop view v1;
+select f1() into @var;
+set @exec_count=@exec_count+1;
+end|
+set @exec_count=0;
+call p1();
+ERROR HY000: Recursive limit 0 (as set by the max_sp_recursion_depth variable) was exceeded for routine p1
+select @exec_count;
+@exec_count
+0
+set @@session.max_sp_recursion_depth=5;
+set @exec_count=0;
+call p1();
+ERROR HY000: Explicit or implicit commit is not allowed in stored function or trigger.
+select @exec_count;
+@exec_count
+0
+drop procedure p1;
+drop function f1;
+set @@session.max_sp_recursion_depth=default;
+# --> connection con1
+# --> connection con2
+# --> connection con3
+# --> connection default
+#
+# End of 5.5 tests
+#
diff --git a/mysql-test/r/sp-threads.result b/mysql-test/r/sp-threads.result
index 953830ecc87..a14d099c673 100644
--- a/mysql-test/r/sp-threads.result
+++ b/mysql-test/r/sp-threads.result
@@ -35,7 +35,7 @@ call bug9486();
show processlist;
Id User Host db Command Time State Info
# root localhost test Sleep # NULL
-# root localhost test Query # Locked update t1, t2 set val= 1 where id1=id2
+# root localhost test Query # Waiting for table update t1, t2 set val= 1 where id1=id2
# root localhost test Query # NULL show processlist
# root localhost test Sleep # NULL
unlock tables;
diff --git a/mysql-test/r/sp.result b/mysql-test/r/sp.result
index 29af7a51283..c9e622a540d 100644
--- a/mysql-test/r/sp.result
+++ b/mysql-test/r/sp.result
@@ -1083,11 +1083,9 @@ select f0()|
f0()
100
select * from v0|
-f0()
-100
+ERROR HY000: Table 'v0' was not locked with LOCK TABLES
select *, f0() from v0, (select 123) as d1|
-f0() 123 f0()
-100 123 100
+ERROR HY000: Table 'v0' was not locked with LOCK TABLES
select id, f3() from t1|
ERROR HY000: Table 't1' was not locked with LOCK TABLES
select f4()|
@@ -7149,3 +7147,62 @@ SELECT routine_comment FROM information_schema.routines WHERE routine_name = "p1
routine_comment
12345678901234567890123456789012345678901234567890123456789012345678901234567890
DROP PROCEDURE p1;
+#
+# Bug #47313 assert in check_key_in_view during CALL procedure
+#
+DROP TABLE IF EXISTS t1;
+DROP VIEW IF EXISTS t1, t2_unrelated;
+DROP PROCEDURE IF EXISTS p1;
+CREATE PROCEDURE p1(IN x INT) INSERT INTO t1 VALUES (x);
+CREATE VIEW t1 AS SELECT 10 AS f1;
+# t1 refers to the view
+CALL p1(1);
+ERROR HY000: The target table t1 of the INSERT is not insertable-into
+CREATE TEMPORARY TABLE t1 (f1 INT);
+# t1 still refers to the view since it was inlined
+CALL p1(2);
+ERROR HY000: The target table t1 of the INSERT is not insertable-into
+DROP VIEW t1;
+# t1 now refers to the temporary table
+CALL p1(3);
+# Check which values were inserted into the temp table.
+SELECT * FROM t1;
+f1
+3
+DROP TEMPORARY TABLE t1;
+DROP PROCEDURE p1;
+# Now test what happens if the sp cache is invalidated.
+CREATE PROCEDURE p1(IN x INT) INSERT INTO t1 VALUES (x);
+CREATE VIEW t1 AS SELECT 10 AS f1;
+CREATE VIEW v2_unrelated AS SELECT 1 AS r1;
+# Load the procedure into the sp cache
+CALL p1(4);
+ERROR HY000: The target table t1 of the INSERT is not insertable-into
+CREATE TEMPORARY TABLE t1 (f1 int);
+ALTER VIEW v2_unrelated AS SELECT 2 AS r1;
+# Alter view causes the sp cache to be invalidated.
+# Now t1 refers to the temporary table, not the view.
+CALL p1(5);
+# Check which values were inserted into the temp table.
+SELECT * FROM t1;
+f1
+5
+DROP TEMPORARY TABLE t1;
+DROP VIEW t1, v2_unrelated;
+DROP PROCEDURE p1;
+CREATE PROCEDURE p1(IN x INT) INSERT INTO t1 VALUES (x);
+CREATE TEMPORARY TABLE t1 (f1 INT);
+# t1 refers to the temporary table
+CALL p1(6);
+CREATE VIEW t1 AS SELECT 10 AS f1;
+# Create view causes the sp cache to be invalidated.
+# t1 still refers to the temporary table since it shadows the view.
+CALL p1(7);
+DROP VIEW t1;
+# Check which values were inserted into the temp table.
+SELECT * FROM t1;
+f1
+6
+7
+DROP TEMPORARY TABLE t1;
+DROP PROCEDURE p1;
diff --git a/mysql-test/r/trigger.result b/mysql-test/r/trigger.result
index 47b50b233b3..5c63604a325 100644
--- a/mysql-test/r/trigger.result
+++ b/mysql-test/r/trigger.result
@@ -2162,3 +2162,23 @@ Warning 1265 Data truncated for column 'trg2' at row 1
DROP TRIGGER trg1;
DROP TRIGGER trg2;
DROP TABLE t1;
+#
+# Bug #46747 "Crash in MDL_ticket::upgrade_shared_lock_to_exclusive
+# on TRIGGER + TEMP table".
+#
+drop trigger if exists t1_bi;
+drop temporary table if exists t1;
+drop table if exists t1;
+create table t1 (i int);
+create trigger t1_bi before insert on t1 for each row set @a:=1;
+# Create temporary table which shadows base table with trigger.
+create temporary table t1 (j int);
+# Dropping of trigger should succeed.
+drop trigger t1_bi;
+select trigger_name from information_schema.triggers
+where event_object_schema = 'test' and event_object_table = 't1';
+trigger_name
+# Clean-up.
+drop temporary table t1;
+drop table t1;
+End of 6.0 tests.
diff --git a/mysql-test/r/truncate.result b/mysql-test/r/truncate.result
index b194f9b7dc6..8f237c81e75 100644
--- a/mysql-test/r/truncate.result
+++ b/mysql-test/r/truncate.result
@@ -1,4 +1,4 @@
-drop table if exists t1;
+drop table if exists t1, t2;
create table t1 (a integer, b integer,c1 CHAR(10));
insert into t1 (a) values (1),(2);
truncate table t1;
@@ -60,3 +60,102 @@ truncate table v1;
ERROR 42S02: Table 'test.v1' doesn't exist
drop view v1;
drop table t1;
+#
+# Bug#20667 - Truncate table fails for a write locked table
+#
+CREATE TABLE t1 (c1 INT);
+LOCK TABLE t1 WRITE;
+INSERT INTO t1 VALUES (1);
+SELECT * FROM t1;
+c1
+1
+TRUNCATE TABLE t1;
+SELECT * FROM t1;
+c1
+UNLOCK TABLES;
+LOCK TABLE t1 READ;
+TRUNCATE TABLE t1;
+ERROR HY000: Table 't1' was locked with a READ lock and can't be updated
+UNLOCK TABLES;
+CREATE TABLE t2 (c1 INT);
+LOCK TABLE t2 WRITE;
+TRUNCATE TABLE t1;
+ERROR HY000: Table 't1' was not locked with LOCK TABLES
+UNLOCK TABLES;
+CREATE VIEW v1 AS SELECT t1.c1 FROM t1,t2 WHERE t1.c1 = t2.c1;
+INSERT INTO t1 VALUES (1), (2), (3);
+INSERT INTO t2 VALUES (1), (3), (4);
+SELECT * FROM v1;
+c1
+1
+3
+TRUNCATE v1;
+ERROR 42S02: Table 'test.v1' doesn't exist
+SELECT * FROM v1;
+c1
+1
+3
+LOCK TABLE t1 WRITE;
+SELECT * FROM v1;
+ERROR HY000: Table 'v1' was not locked with LOCK TABLES
+TRUNCATE v1;
+ERROR 42S02: Table 'test.v1' doesn't exist
+SELECT * FROM v1;
+ERROR HY000: Table 'v1' was not locked with LOCK TABLES
+UNLOCK TABLES;
+LOCK TABLE t1 WRITE, t2 WRITE;
+SELECT * FROM v1;
+ERROR HY000: Table 'v1' was not locked with LOCK TABLES
+TRUNCATE v1;
+ERROR 42S02: Table 'test.v1' doesn't exist
+SELECT * FROM v1;
+ERROR HY000: Table 'v1' was not locked with LOCK TABLES
+UNLOCK TABLES;
+LOCK TABLE v1 WRITE;
+SELECT * FROM v1;
+c1
+1
+3
+TRUNCATE v1;
+ERROR 42S02: Table 'test.v1' doesn't exist
+SELECT * FROM v1;
+c1
+1
+3
+UNLOCK TABLES;
+LOCK TABLE t1 WRITE, t2 WRITE, v1 WRITE;
+SELECT * FROM v1;
+c1
+1
+3
+TRUNCATE v1;
+ERROR 42S02: Table 'test.v1' doesn't exist
+SELECT * FROM v1;
+c1
+1
+3
+UNLOCK TABLES;
+DROP VIEW v1;
+DROP TABLE t1, t2;
+CREATE PROCEDURE p1() SET @a = 5;
+TRUNCATE p1;
+ERROR 42S02: Table 'test.p1' doesn't exist
+SHOW CREATE PROCEDURE p1;
+Procedure sql_mode Create Procedure character_set_client collation_connection Database Collation
+p1 CREATE DEFINER=`root`@`localhost` PROCEDURE `p1`()
+SET @a = 5 latin1 latin1_swedish_ci latin1_swedish_ci
+DROP PROCEDURE p1;
+#
+# Bug#46452 Crash in MDL, HANDLER OPEN + TRUNCATE TABLE
+#
+DROP TABLE IF EXISTS t1;
+CREATE TABLE t1 AS SELECT 1 AS f1;
+HANDLER t1 OPEN;
+# Here comes the crash.
+TRUNCATE t1;
+# Currently TRUNCATE, just like other DDL, implicitly closes
+# open HANDLER table.
+HANDLER t1 READ FIRST;
+ERROR 42S02: Unknown table 't1' in HANDLER
+DROP TABLE t1;
+# End of 6.0 tests
diff --git a/mysql-test/r/truncate_coverage.result b/mysql-test/r/truncate_coverage.result
new file mode 100644
index 00000000000..7a5021f55e2
--- /dev/null
+++ b/mysql-test/r/truncate_coverage.result
@@ -0,0 +1,73 @@
+SET DEBUG_SYNC='RESET';
+DROP TABLE IF EXISTS t1;
+#
+# Bug#20667 - Truncate table fails for a write locked table
+#
+CREATE TABLE t1 (c1 INT);
+INSERT INTO t1 VALUES (1);
+#
+# connection con1
+HANDLER t1 OPEN;
+#
+# connection default
+LOCK TABLE t1 WRITE;
+SET DEBUG_SYNC='mdl_upgrade_shared_lock_to_exclusive SIGNAL waiting';
+TRUNCATE TABLE t1;
+#
+# connection con2
+SET DEBUG_SYNC='now WAIT_FOR waiting';
+KILL QUERY @id;
+#
+# connection con1
+# Release shared metadata lock by closing HANDLER.
+HANDLER t1 CLOSE;
+#
+# connection default
+ERROR 70100: Query execution was interrupted
+UNLOCK TABLES;
+DROP TABLE t1;
+SET DEBUG_SYNC='RESET';
+CREATE TABLE t1 (c1 INT);
+INSERT INTO t1 VALUES (1);
+#
+# connection con1
+HANDLER t1 OPEN;
+#
+# connection default
+LOCK TABLE t1 WRITE;
+SET DEBUG_SYNC='mdl_upgrade_shared_lock_to_exclusive SIGNAL waiting';
+TRUNCATE TABLE t1;
+#
+# connection con2
+SET DEBUG_SYNC='now WAIT_FOR waiting';
+#
+# connection con1
+HANDLER t1 CLOSE;
+#
+# connection default
+ERROR 42S02: Table 'test.t1' doesn't exist
+UNLOCK TABLES;
+DROP TABLE t1;
+ERROR 42S02: Unknown table 't1'
+SET DEBUG_SYNC='RESET';
+CREATE TABLE t1 (c1 INT);
+INSERT INTO t1 VALUES (1);
+#
+# connection con1
+START TRANSACTION;
+INSERT INTO t1 VALUES (2);
+#
+# connection default
+SET DEBUG_SYNC='mdl_acquire_lock_wait SIGNAL waiting';
+TRUNCATE TABLE t1;
+#
+# connection con1
+SET DEBUG_SYNC='now WAIT_FOR waiting';
+KILL QUERY @id;
+COMMIT;
+#
+# connection default
+ERROR 70100: Query execution was interrupted
+UNLOCK TABLES;
+DROP TABLE t1;
+SET DEBUG_SYNC='RESET';
diff --git a/mysql-test/r/variables.result b/mysql-test/r/variables.result
index a8437961117..3251e9738a5 100644
--- a/mysql-test/r/variables.result
+++ b/mysql-test/r/variables.result
@@ -1066,11 +1066,9 @@ set global default_storage_engine =@my_storage_engine;
set global thread_cache_size =@my_thread_cache_size;
set global max_allowed_packet =@my_max_allowed_packet;
set global join_buffer_size =@my_join_buffer_size;
-show global variables where Variable_name='table_definition_cache' or
-Variable_name='table_lock_wait_timeout';
+show global variables where Variable_name='table_definition_cache';
Variable_name Value
table_definition_cache #
-table_lock_wait_timeout #
# --
# -- Bug#34820: log_output can be set to illegal value.
diff --git a/mysql-test/r/view.result b/mysql-test/r/view.result
index a54db7240a4..4c0acc2eb6a 100644
--- a/mysql-test/r/view.result
+++ b/mysql-test/r/view.result
@@ -1102,10 +1102,8 @@ select * from v1;
a
select * from t2;
ERROR HY000: Table 't2' was not locked with LOCK TABLES
-drop view v1;
-drop table t1, t2;
-ERROR HY000: Table 't1' was locked with a READ lock and can't be updated
unlock tables;
+drop view v1;
drop table t1, t2;
create table t1 (a int);
create view v1 as select * from t1 where a < 2 with check option;
@@ -1957,15 +1955,15 @@ CHECK TABLE v1, v2, v3, v4, v5, v6;
Table Op Msg_type Msg_text
test.v1 check Error FUNCTION test.f1 does not exist
test.v1 check Error View 'test.v1' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them
-test.v1 check error Corrupt
+test.v1 check status Operation failed
test.v2 check status OK
test.v3 check Error FUNCTION test.f1 does not exist
test.v3 check Error View 'test.v3' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them
-test.v3 check error Corrupt
+test.v3 check status Operation failed
test.v4 check status OK
test.v5 check Error FUNCTION test.f1 does not exist
test.v5 check Error View 'test.v5' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them
-test.v5 check error Corrupt
+test.v5 check status Operation failed
test.v6 check status OK
create function f1 () returns int return (select max(col1) from t1);
DROP TABLE t1;
@@ -3974,3 +3972,35 @@ create view v_9801 as
select sum(s1) from t_9801 group by s1 with rollup with check option;
ERROR HY000: CHECK OPTION on non-updatable view 'test.v_9801'
drop table t_9801;
+#
+# Bug #47335 assert in get_table_share
+#
+DROP TABLE IF EXISTS t1;
+DROP VIEW IF EXISTS v1;
+CREATE TEMPORARY TABLE t1 (id INT);
+ALTER VIEW t1 AS SELECT 1 AS f1;
+ERROR 42S02: Table 'test.t1' doesn't exist
+DROP TABLE t1;
+CREATE VIEW v1 AS SELECT 1 AS f1;
+CREATE TEMPORARY TABLE v1 (id INT);
+ALTER VIEW v1 AS SELECT 2 AS f1;
+DROP TABLE v1;
+SELECT * FROM v1;
+f1
+2
+DROP VIEW v1;
+#
+# Bug #47635 assert in start_waiting_global_read_lock
+# during CREATE VIEW
+#
+DROP TABLE IF EXISTS t1, t2;
+DROP VIEW IF EXISTS t2;
+CREATE TABLE t1 (f1 integer);
+CREATE TEMPORARY TABLE IF NOT EXISTS t1 (f1 integer);
+CREATE TEMPORARY TABLE t2 (f1 integer);
+DROP TABLE t1;
+FLUSH TABLES WITH READ LOCK;
+CREATE VIEW t2 AS SELECT * FROM t1;
+ERROR HY000: Can't execute the query because you have a conflicting read lock
+UNLOCK TABLES;
+DROP TABLE t1, t2;
diff --git a/mysql-test/r/view_grant.result b/mysql-test/r/view_grant.result
index 65fbf2d87b6..0c74d8ed91b 100644
--- a/mysql-test/r/view_grant.result
+++ b/mysql-test/r/view_grant.result
@@ -779,9 +779,9 @@ GRANT CREATE VIEW ON db26813.v2 TO u26813@localhost;
GRANT DROP, CREATE VIEW ON db26813.v3 TO u26813@localhost;
GRANT SELECT ON db26813.t1 TO u26813@localhost;
ALTER VIEW v1 AS SELECT f2 FROM t1;
-ERROR 42000: Access denied; you need (at least one of) the SUPER privilege(s) for this operation
+ERROR 42000: CREATE VIEW command denied to user 'u26813'@'localhost' for table 'v1'
ALTER VIEW v2 AS SELECT f2 FROM t1;
-ERROR 42000: Access denied; you need (at least one of) the SUPER privilege(s) for this operation
+ERROR 42000: DROP command denied to user 'u26813'@'localhost' for table 'v2'
ALTER VIEW v3 AS SELECT f2 FROM t1;
ERROR 42000: Access denied; you need (at least one of) the SUPER privilege(s) for this operation
SHOW CREATE VIEW v3;
diff --git a/mysql-test/suite/binlog/r/binlog_row_drop_tbl.result b/mysql-test/suite/binlog/r/binlog_row_drop_tbl.result
new file mode 100644
index 00000000000..8b32e9e5a45
--- /dev/null
+++ b/mysql-test/suite/binlog/r/binlog_row_drop_tbl.result
@@ -0,0 +1,16 @@
+DROP TABLE IF EXISTS t1;
+RESET MASTER;
+CREATE TABLE t1 (a INT);
+SET AUTOCOMMIT=OFF;
+BEGIN;
+INSERT INTO t1 VALUES(1);
+DROP TABLE t1;;
+COMMIT;
+show binlog events from <binlog_start>;
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Query # # use `test`; CREATE TABLE t1 (a INT)
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Table_map # # table_id: # (test.t1)
+master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
+master-bin.000001 # Query # # COMMIT
+master-bin.000001 # Query # # use `test`; DROP TABLE t1
diff --git a/mysql-test/suite/binlog/r/binlog_row_mix_innodb_myisam.result b/mysql-test/suite/binlog/r/binlog_row_mix_innodb_myisam.result
index d59e84c1e1e..a4db4d65b07 100644
--- a/mysql-test/suite/binlog/r/binlog_row_mix_innodb_myisam.result
+++ b/mysql-test/suite/binlog/r/binlog_row_mix_innodb_myisam.result
@@ -241,6 +241,7 @@ select (@after:=unix_timestamp())*0;
select (@after-@before) >= 2;
(@after-@before) >= 2
1
+commit;
drop table t1,t2;
commit;
begin;
diff --git a/mysql-test/suite/binlog/r/binlog_stm_drop_tbl.result b/mysql-test/suite/binlog/r/binlog_stm_drop_tbl.result
new file mode 100644
index 00000000000..260092e5561
--- /dev/null
+++ b/mysql-test/suite/binlog/r/binlog_stm_drop_tbl.result
@@ -0,0 +1,15 @@
+DROP TABLE IF EXISTS t1;
+RESET MASTER;
+CREATE TABLE t1 (a INT);
+SET AUTOCOMMIT=OFF;
+BEGIN;
+INSERT INTO t1 VALUES(1);
+DROP TABLE t1;;
+COMMIT;
+show binlog events from <binlog_start>;
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Query # # use `test`; CREATE TABLE t1 (a INT)
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Query # # use `test`; INSERT INTO t1 VALUES(1)
+master-bin.000001 # Query # # COMMIT
+master-bin.000001 # Query # # use `test`; DROP TABLE t1
diff --git a/mysql-test/suite/binlog/r/binlog_stm_mix_innodb_myisam.result b/mysql-test/suite/binlog/r/binlog_stm_mix_innodb_myisam.result
index 3cdefeac59b..fab65bfb973 100644
--- a/mysql-test/suite/binlog/r/binlog_stm_mix_innodb_myisam.result
+++ b/mysql-test/suite/binlog/r/binlog_stm_mix_innodb_myisam.result
@@ -229,6 +229,7 @@ select (@after:=unix_timestamp())*0;
select (@after-@before) >= 2;
(@after-@before) >= 2
1
+commit;
drop table t1,t2;
commit;
begin;
diff --git a/mysql-test/suite/binlog/t/binlog_row_drop_tbl.test b/mysql-test/suite/binlog/t/binlog_row_drop_tbl.test
new file mode 100644
index 00000000000..06854900612
--- /dev/null
+++ b/mysql-test/suite/binlog/t/binlog_row_drop_tbl.test
@@ -0,0 +1,5 @@
+# This is a wrapper for drop_table.test so that the same test case can be used
+# For both statement and row based bin logs
+
+-- source include/have_binlog_format_row.inc
+-- source extra/binlog_tests/drop_table.test
diff --git a/mysql-test/suite/binlog/t/binlog_stm_drop_tbl.test b/mysql-test/suite/binlog/t/binlog_stm_drop_tbl.test
new file mode 100644
index 00000000000..f2b07bb69f6
--- /dev/null
+++ b/mysql-test/suite/binlog/t/binlog_stm_drop_tbl.test
@@ -0,0 +1,5 @@
+# This is a wrapper for drop_table.test so that the same test case can be used
+# For both statement and row based bin logs
+
+-- source include/have_binlog_format_mixed_or_statement.inc
+-- source extra/binlog_tests/drop_table.test
diff --git a/mysql-test/suite/binlog/t/binlog_stm_row.test b/mysql-test/suite/binlog/t/binlog_stm_row.test
index 71444a04c6f..8ac1bb1acbe 100644
--- a/mysql-test/suite/binlog/t/binlog_stm_row.test
+++ b/mysql-test/suite/binlog/t/binlog_stm_row.test
@@ -60,7 +60,7 @@ let $wait_condition=
--echo # con1
let $wait_condition=
SELECT COUNT(*) = 1 FROM information_schema.processlist WHERE
- state = "Locked" and info = "INSERT INTO t2 VALUES (3)";
+ state = "Table lock" and info = "INSERT INTO t2 VALUES (3)";
--source include/wait_condition.inc
SELECT RELEASE_LOCK('Bug#34306');
--connection con2
diff --git a/mysql-test/suite/funcs_1/datadict/processlist_val.inc b/mysql-test/suite/funcs_1/datadict/processlist_val.inc
index c34fb626bcd..9c6bd585fde 100644
--- a/mysql-test/suite/funcs_1/datadict/processlist_val.inc
+++ b/mysql-test/suite/funcs_1/datadict/processlist_val.inc
@@ -367,13 +367,13 @@ echo
;
connection default;
echo
-# Poll till INFO is no more NULL and State = 'Locked'.
+# Poll till INFO is no more NULL and State = 'Waiting for table'.
;
let $wait_condition= SELECT COUNT(*) FROM INFORMATION_SCHEMA.PROCESSLIST
- WHERE INFO IS NOT NULL AND STATE = 'Locked';
+ WHERE INFO IS NOT NULL AND STATE = 'Waiting for table';
--source include/wait_condition.inc
#
-# Expect to see the state 'Locked' for the third connection because the SELECT
+# Expect to see the state 'Waiting for table' for the third connection because the SELECT
# collides with the WRITE TABLE LOCK.
--replace_column 1 <ID> 3 <HOST_NAME> 6 <TIME>
SELECT * FROM INFORMATION_SCHEMA.PROCESSLIST;
@@ -422,10 +422,10 @@ echo
;
connection default;
echo
-# Poll till INFO is no more NULL and State = 'Locked'.
+# Poll till INFO is no more NULL and State = 'Waiting for table'.
;
let $wait_condition= SELECT COUNT(*) FROM INFORMATION_SCHEMA.PROCESSLIST
- WHERE INFO IS NOT NULL AND STATE = 'Locked';
+ WHERE INFO IS NOT NULL AND STATE = 'Waiting for table';
--source include/wait_condition.inc
echo
# Expect result:
diff --git a/mysql-test/suite/funcs_1/r/processlist_val_no_prot.result b/mysql-test/suite/funcs_1/r/processlist_val_no_prot.result
index b0cae801fd6..5f79fd04a90 100644
--- a/mysql-test/suite/funcs_1/r/processlist_val_no_prot.result
+++ b/mysql-test/suite/funcs_1/r/processlist_val_no_prot.result
@@ -193,11 +193,11 @@ LOCK TABLE test.t1 WRITE;
SELECT COUNT(*) FROM test.t1;
# ----- switch to connection default (user = root) -----
-# Poll till INFO is no more NULL and State = 'Locked'.
+# Poll till INFO is no more NULL and State = 'Waiting for table'.
SELECT * FROM INFORMATION_SCHEMA.PROCESSLIST;
ID USER HOST DB COMMAND TIME STATE INFO
-<ID> test_user <HOST_NAME> information_schema Query <TIME> Locked SELECT COUNT(*) FROM test.t1
+<ID> test_user <HOST_NAME> information_schema Query <TIME> Waiting for table SELECT COUNT(*) FROM test.t1
<ID> test_user <HOST_NAME> information_schema Sleep <TIME> NULL
<ID> root <HOST_NAME> information_schema Query <TIME> executing SELECT * FROM INFORMATION_SCHEMA.PROCESSLIST
UNLOCK TABLES;
@@ -221,7 +221,7 @@ LOCK TABLE test.t1 WRITE;
SELECT count(*),'BEGIN-This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.-END' AS "Long string" FROM test.t1;
# ----- switch to connection default (user = root) -----
-# Poll till INFO is no more NULL and State = 'Locked'.
+# Poll till INFO is no more NULL and State = 'Waiting for table'.
# Expect result:
# Statement Content of INFO
diff --git a/mysql-test/suite/funcs_1/r/processlist_val_ps.result b/mysql-test/suite/funcs_1/r/processlist_val_ps.result
index 4e4cfa57e36..bb8e25c87ab 100644
--- a/mysql-test/suite/funcs_1/r/processlist_val_ps.result
+++ b/mysql-test/suite/funcs_1/r/processlist_val_ps.result
@@ -193,11 +193,11 @@ LOCK TABLE test.t1 WRITE;
SELECT COUNT(*) FROM test.t1;
# ----- switch to connection default (user = root) -----
-# Poll till INFO is no more NULL and State = 'Locked'.
+# Poll till INFO is no more NULL and State = 'Waiting for table'.
SELECT * FROM INFORMATION_SCHEMA.PROCESSLIST;
ID USER HOST DB COMMAND TIME STATE INFO
-<ID> test_user <HOST_NAME> information_schema Query <TIME> Locked SELECT COUNT(*) FROM test.t1
+<ID> test_user <HOST_NAME> information_schema Query <TIME> Waiting for table SELECT COUNT(*) FROM test.t1
<ID> test_user <HOST_NAME> information_schema Sleep <TIME> NULL
<ID> root <HOST_NAME> information_schema Execute <TIME> executing SELECT * FROM INFORMATION_SCHEMA.PROCESSLIST
UNLOCK TABLES;
@@ -221,7 +221,7 @@ LOCK TABLE test.t1 WRITE;
SELECT count(*),'BEGIN-This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.-END' AS "Long string" FROM test.t1;
# ----- switch to connection default (user = root) -----
-# Poll till INFO is no more NULL and State = 'Locked'.
+# Poll till INFO is no more NULL and State = 'Waiting for table'.
# Expect result:
# Statement Content of INFO
diff --git a/mysql-test/suite/ndb/r/ndb_index_ordered.result b/mysql-test/suite/ndb/r/ndb_index_ordered.result
index a29b5343d7c..c99db354314 100644
--- a/mysql-test/suite/ndb/r/ndb_index_ordered.result
+++ b/mysql-test/suite/ndb/r/ndb_index_ordered.result
@@ -637,21 +637,6 @@ select count(*)- 4 from t1 use index (v) where v > 0000965.00042;
count(*)- 4
0
drop table t1;
-create table t1(a int primary key, b int not null, index(b));
-insert into t1 values (1,1), (2,2);
-set autocommit=0;
-begin;
-select count(*) from t1;
-count(*)
-2
-ALTER TABLE t1 ADD COLUMN c int;
-select a from t1 where b = 2;
-a
-2
-show tables;
-Tables_in_test
-t1
-drop table t1;
create table t1 (a int, c varchar(10),
primary key using hash (a), index(c)) engine=ndb;
insert into t1 (a, c) values (1,'aaa'),(3,'bbb');
diff --git a/mysql-test/suite/ndb/t/disabled.def b/mysql-test/suite/ndb/t/disabled.def
index 65b6b9ed135..4c5c792f4ef 100644
--- a/mysql-test/suite/ndb/t/disabled.def
+++ b/mysql-test/suite/ndb/t/disabled.def
@@ -15,3 +15,4 @@ ndb_condition_pushdown : Bug#49746 2010-02-08 alik ndb_condition_pushdown fai
# the below testcase have been reworked to avoid the bug, test contains comment, keep bug open
+ndb_alter_table3 : Bug#45621 2009-06-10 alik A few test files are disabled due to WL#4284
diff --git a/mysql-test/suite/ndb/t/ndb_index_ordered.test b/mysql-test/suite/ndb/t/ndb_index_ordered.test
index 782f17ca5b2..c8dfc1de59f 100644
--- a/mysql-test/suite/ndb/t/ndb_index_ordered.test
+++ b/mysql-test/suite/ndb/t/ndb_index_ordered.test
@@ -333,21 +333,29 @@ select count(*)- 4 from t1 use index (v) where v > 0000965.00042;
drop table t1;
+#
+# Disabled due to WL#4284
+#
+# Needs to be reworked. It's not possible anymore to do a non-fast alter table
+# on a table that is being used by a pending transaction (transaction holds a
+# metadata lock on the table).
+#
# bug#7798
-create table t1(a int primary key, b int not null, index(b));
-insert into t1 values (1,1), (2,2);
-connect (con1,localhost,root,,test);
-connect (con2,localhost,root,,test);
-connection con1;
-set autocommit=0;
-begin;
-select count(*) from t1;
-connection con2;
-ALTER TABLE t1 ADD COLUMN c int;
-connection con1;
-select a from t1 where b = 2;
-show tables;
-drop table t1;
+# create table t1(a int primary key, b int not null, c int, index(b));
+# insert into t1 values (1,1,1), (2,2,2);
+# connect (con1,localhost,root,,test);
+# connect (con2,localhost,root,,test);
+# connection con1;
+# set autocommit=0;
+# begin;
+# select count(*) from t1;
+# connection con2;
+# ALTER TABLE t1 ADD COLUMN c int
+# connection con1;
+# select a from t1 where b = 2;
+# show tables;
+# drop table t1;
+#
# mysqld 5.0.13 crash, no bug#
create table t1 (a int, c varchar(10),
diff --git a/mysql-test/suite/parts/r/partition_special_innodb.result b/mysql-test/suite/parts/r/partition_special_innodb.result
index 26c1ac9356c..a9c5b2e766e 100644
--- a/mysql-test/suite/parts/r/partition_special_innodb.result
+++ b/mysql-test/suite/parts/r/partition_special_innodb.result
@@ -212,11 +212,7 @@ SET autocommit=OFF;
START TRANSACTION;
INSERT INTO t1 VALUES (NULL, 'first row t2');
SET autocommit=OFF;
+SET SESSION lock_wait_timeout= 1;
ALTER TABLE t1 AUTO_INCREMENT = 10;
ERROR HY000: Lock wait timeout exceeded; try restarting transaction
-INSERT INTO t1 VALUES (NULL, 'second row t2');
-SELECT a,b FROM t1 ORDER BY a;
-a b
-1 first row t2
-2 second row t2
DROP TABLE t1;
diff --git a/mysql-test/suite/parts/t/partition_special_innodb.test b/mysql-test/suite/parts/t/partition_special_innodb.test
index eac19f6d588..833e489558e 100644
--- a/mysql-test/suite/parts/t/partition_special_innodb.test
+++ b/mysql-test/suite/parts/t/partition_special_innodb.test
@@ -68,12 +68,10 @@ INSERT INTO t1 VALUES (NULL, 'first row t2');
--connection con2
SET autocommit=OFF;
+SET SESSION lock_wait_timeout= 1;
--error ER_LOCK_WAIT_TIMEOUT
ALTER TABLE t1 AUTO_INCREMENT = 10;
---connection con1
-INSERT INTO t1 VALUES (NULL, 'second row t2');
-SELECT a,b FROM t1 ORDER BY a;
--disconnect con2
--disconnect con1
--connection default
diff --git a/mysql-test/suite/rpl/r/rpl_mixed_row_innodb.result b/mysql-test/suite/rpl/r/rpl_mixed_row_innodb.result
index a4894631087..68b981ad70f 100644
--- a/mysql-test/suite/rpl/r/rpl_mixed_row_innodb.result
+++ b/mysql-test/suite/rpl/r/rpl_mixed_row_innodb.result
@@ -82,3 +82,48 @@ FLUSH LOGS;
FLUSH LOGS;
DROP DATABASE mysqltest1;
End of 5.1 tests
+#
+# Bug#39675 rename tables on innodb tables with pending
+# transactions causes slave data issue.
+#
+DROP TABLE IF EXISTS t1;
+DROP TABLE IF EXISTS t2;
+DROP TABLE IF EXISTS t3;
+CREATE TABLE t1 (
+id INT PRIMARY KEY auto_increment,
+b INT DEFAULT NULL
+) ENGINE=InnoDB;
+CREATE TABLE t2 (
+id INT PRIMARY KEY auto_increment,
+b INT DEFAULT NULL
+) ENGINE=InnoDB;
+INSERT INTO t1 (b) VALUES (1),(2),(3);
+BEGIN;
+INSERT INTO t1(b) VALUES (4);
+-------- switch to master1 --------
+RENAME TABLE t1 TO t3, t2 TO t1;;
+-------- switch to master --------
+COMMIT;
+-------- switch to master1 --------
+-------- switch to master --------
+SELECT * FROM t1;
+id b
+SELECT * FROM t3;
+id b
+1 1
+2 2
+3 3
+4 4
+-------- switch to slave --------
+SELECT * FROM t1;
+id b
+SELECT * FROM t3;
+id b
+1 1
+2 2
+3 3
+4 4
+-------- switch to master --------
+DROP TABLE t1;
+DROP TABLE t3;
+End of 6.0 tests
diff --git a/mysql-test/suite/rpl/r/rpl_sp.result b/mysql-test/suite/rpl/r/rpl_sp.result
index 21910302f3a..7f810c5c128 100644
--- a/mysql-test/suite/rpl/r/rpl_sp.result
+++ b/mysql-test/suite/rpl/r/rpl_sp.result
@@ -1187,4 +1187,47 @@ drop procedure mysqltestbug36570_p1;
drop procedure ` mysqltestbug36570_p2`;
drop function mysqltestbug36570_f1;
End of 5.0 tests
-End of 5.1 tests
+# End of 5.1 tests
+#
+# Test Bug#30977 Concurrent statement using stored
+# function and DROP FUNCTION breaks SBR.
+#
+# Demonstrate that stored function DDL can not go through,
+# or, worse yet, make its way into the binary log, while
+# the stored function is in use.
+# For that, try to insert a result of a stored function
+# into a table. Block the insert in the beginning, waiting
+# on a table lock. While insert is blocked, attempt to
+# drop the routine. Verify that this attempt
+# blocks and waits for INSERT to complete. Commit and
+# reap the chain of events. Master and slave must contain
+# identical data. Statements in the binrary log must be
+# consistent with data in the table.
+#
+# --> connection default
+drop table if exists t1, t2;
+drop function if exists t1;
+create table t1 (a int);
+create table t2 (a int) as select 1 as a;
+create function f1() returns int deterministic return (select max(a) from t2);
+lock table t2 write;
+# --> connection master
+# Sending 'insert into t1 (a) values (f1())'...
+insert into t1 (a) values (f1());
+# Waitng for 'insert into t1 ...' to get blocked on table lock...
+# Sending 'drop function f1'. It will abort the table lock wait.
+drop function f1;
+# --> connection default
+# Now let's let 'insert' go through...
+unlock tables;
+# --> connection con1
+# Reaping 'insert into t1 (a) values (f1())'...
+ERROR 42000: FUNCTION test.f1 does not exist
+select * from t1;
+a
+select * from t1;
+a
+drop table t1, t2;
+drop function f1;
+ERROR 42000: FUNCTION test.f1 does not exist
+# End of 5.5 tests.
diff --git a/mysql-test/suite/rpl/r/rpl_stm_innodb.result b/mysql-test/suite/rpl/r/rpl_stm_innodb.result
index 457ad3340b4..c2cce22e3ee 100644
--- a/mysql-test/suite/rpl/r/rpl_stm_innodb.result
+++ b/mysql-test/suite/rpl/r/rpl_stm_innodb.result
@@ -82,3 +82,48 @@ FLUSH LOGS;
FLUSH LOGS;
DROP DATABASE mysqltest1;
End of 5.1 tests
+#
+# Bug#39675 rename tables on innodb tables with pending
+# transactions causes slave data issue.
+#
+DROP TABLE IF EXISTS t1;
+DROP TABLE IF EXISTS t2;
+DROP TABLE IF EXISTS t3;
+CREATE TABLE t1 (
+id INT PRIMARY KEY auto_increment,
+b INT DEFAULT NULL
+) ENGINE=InnoDB;
+CREATE TABLE t2 (
+id INT PRIMARY KEY auto_increment,
+b INT DEFAULT NULL
+) ENGINE=InnoDB;
+INSERT INTO t1 (b) VALUES (1),(2),(3);
+BEGIN;
+INSERT INTO t1(b) VALUES (4);
+-------- switch to master1 --------
+RENAME TABLE t1 TO t3, t2 TO t1;;
+-------- switch to master --------
+COMMIT;
+-------- switch to master1 --------
+-------- switch to master --------
+SELECT * FROM t1;
+id b
+SELECT * FROM t3;
+id b
+1 1
+2 2
+3 3
+4 4
+-------- switch to slave --------
+SELECT * FROM t1;
+id b
+SELECT * FROM t3;
+id b
+1 1
+2 2
+3 3
+4 4
+-------- switch to master --------
+DROP TABLE t1;
+DROP TABLE t3;
+End of 6.0 tests
diff --git a/mysql-test/suite/rpl/r/rpl_stm_loadfile.result b/mysql-test/suite/rpl/r/rpl_stm_loadfile.result
index 1dd0805f4d3..3551e38d5ef 100644
--- a/mysql-test/suite/rpl/r/rpl_stm_loadfile.result
+++ b/mysql-test/suite/rpl/r/rpl_stm_loadfile.result
@@ -17,6 +17,8 @@ INSERT INTO test.t1 VALUES(2,'test');
UPDATE test.t1 SET blob_column=LOAD_FILE('../../std_data/words2.dat') WHERE a=2;
end|
CALL test.p1();
+Warnings:
+Note 1592 Unsafe statement binlogged in statement format since BINLOG_FORMAT = STATEMENT. Reason for unsafeness: Statement uses a system function whose value may differ on slave.
SELECT * FROM test.t1 ORDER BY blob_column;
a blob_column
1 abase
diff --git a/mysql-test/suite/rpl/r/rpl_trigger.result b/mysql-test/suite/rpl/r/rpl_trigger.result
index 3d7757613a7..01d886c4709 100644
--- a/mysql-test/suite/rpl/r/rpl_trigger.result
+++ b/mysql-test/suite/rpl/r/rpl_trigger.result
@@ -893,8 +893,6 @@ s
@
root@localhost
DROP TRIGGER trg1;
-Warnings:
-Warning 1454 No definer attribute for trigger 'test'.'trg1'. The trigger will be activated under the authorization of the invoker, which may have insufficient privileges. Please recreate the trigger.
DROP TABLE t1;
DROP TABLE t2;
STOP SLAVE;
diff --git a/mysql-test/suite/rpl/r/rpl_view_multi.result b/mysql-test/suite/rpl/r/rpl_view_multi.result
new file mode 100644
index 00000000000..b3f10584a24
--- /dev/null
+++ b/mysql-test/suite/rpl/r/rpl_view_multi.result
@@ -0,0 +1,90 @@
+stop slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+reset master;
+reset slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+start slave;
+#
+# Bug #25144 "replication / binlog with view breaks".
+# Statements that used views didn't ensure that view were not modified
+# during their execution. Indeed this led to incorrect binary log with
+# statement based logging and as result to broken replication.
+#
+drop tables if exists t1, t2;
+drop view if exists v1;
+# Syncing slave with master and switching to connection 'slave'
+# Switching to connection 'master'
+create table t1 (i int);
+create table t2 (i int);
+create view v1 as select * from t1;
+# First we try to concurrently execute statement that uses view
+# and statement that drops it. We use "user" locks as means to
+# suspend execution of first statement once it opens our view.
+select get_lock("lock_bg25144", 1);
+get_lock("lock_bg25144", 1)
+1
+# Switching to connection 'master1'
+insert into v1 values (get_lock("lock_bg25144", 100));
+# Switching to connection 'master2'
+drop view v1;
+# Switching to connection 'master'
+select release_lock("lock_bg25144");
+release_lock("lock_bg25144")
+1
+# Switching to connection 'master1'
+select release_lock("lock_bg25144");
+release_lock("lock_bg25144")
+1
+# Switching to connection 'master2'
+# Switching to connection 'master'
+# Check that insertion through view did happen.
+select * from t1;
+i
+1
+# Syncing slave with master and switching to connection 'slave'
+# Check that slave was able to replicate this sequence
+# which means that we got correct binlog order.
+select * from t1;
+i
+1
+# Switching to connection 'master'
+# Now we will repeat the test by trying concurrently execute
+# statement that uses a view and statement that alters it.
+create view v1 as select * from t1;
+select get_lock("lock_bg25144", 1);
+get_lock("lock_bg25144", 1)
+1
+# Switching to connection 'master1'
+insert into v1 values (get_lock("lock_bg25144", 100));
+# Switching to connection 'master2'
+alter view v1 as select * from t2;
+# Switching to connection 'master'
+select release_lock("lock_bg25144");
+release_lock("lock_bg25144")
+1
+# Switching to connection 'master1'
+select release_lock("lock_bg25144");
+release_lock("lock_bg25144")
+1
+# Switching to connection 'master2'
+# Switching to connection 'master'
+# Second insertion should go to t1 as well.
+select * from t1;
+i
+1
+1
+select * from t2;
+i
+# Syncing slave with master and switching to connection 'slave'
+# Now let us check that statements were logged in proper order
+# So we have same result on slave.
+select * from t1;
+i
+1
+1
+select * from t2;
+i
+# Switching to connection 'master'
+drop table t1, t2;
+drop view v1;
+# Syncing slave with master and switching to connection 'slave'
diff --git a/mysql-test/suite/rpl/t/disabled.def b/mysql-test/suite/rpl/t/disabled.def
index a5017b1a02c..873b8c314e8 100644
--- a/mysql-test/suite/rpl/t/disabled.def
+++ b/mysql-test/suite/rpl/t/disabled.def
@@ -12,3 +12,5 @@
rpl_row_create_table : Bug#45576 2009-12-01 joro rpl_row_create_table fails on PB2
rpl_spec_variables : BUG#47661 2009-10-27 jasonh rpl_spec_variables fails on PB2 hpux
+rpl_failed_optimize : WL#4284: Can't optimize table used by a pending transaction (there is metadata lock on the table).
+rpl_read_only : WL#4284: Setting Read only won't succeed until all metadata locks are released.
diff --git a/mysql-test/suite/rpl/t/rpl_killed_ddl.test b/mysql-test/suite/rpl/t/rpl_killed_ddl.test
index 61b882efcf3..22bf194cc08 100644
--- a/mysql-test/suite/rpl/t/rpl_killed_ddl.test
+++ b/mysql-test/suite/rpl/t/rpl_killed_ddl.test
@@ -139,7 +139,8 @@ disable_warnings;
######## DATABASE ########
-let $diff_statement= SHOW DATABASES LIKE 'd%';
+let $diff_statement= SELECT schema_name FROM information_schema.schemata
+ WHERE schema_name LIKE 'd%' ORDER BY schema_name;
send CREATE DATABASE d2;
source include/kill_query_and_diff_master_slave.inc;
@@ -158,7 +159,9 @@ source include/kill_query_and_diff_master_slave.inc;
######## EVENT ########
-let $diff_statement= SELECT event_name, event_body, execute_at FROM information_schema.events where event_name like 'e%';
+let $diff_statement= SELECT event_name, event_body, execute_at
+ FROM information_schema.events where event_name like 'e%'
+ ORDER BY event_name;
send CREATE EVENT e2
ON SCHEDULE AT CURRENT_TIMESTAMP + INTERVAL 1 DAY
diff --git a/mysql-test/suite/rpl/t/rpl_sp.test b/mysql-test/suite/rpl/t/rpl_sp.test
index 96a41d9a9ad..362bfa17ef3 100644
--- a/mysql-test/suite/rpl/t/rpl_sp.test
+++ b/mysql-test/suite/rpl/t/rpl_sp.test
@@ -621,7 +621,66 @@ drop procedure mysqltestbug36570_p1;
drop procedure ` mysqltestbug36570_p2`;
drop function mysqltestbug36570_f1;
--echo End of 5.0 tests
---echo End of 5.1 tests
+--echo # End of 5.1 tests
+--echo #
+--echo # Test Bug#30977 Concurrent statement using stored
+--echo # function and DROP FUNCTION breaks SBR.
+--echo #
+--echo # Demonstrate that stored function DDL can not go through,
+--echo # or, worse yet, make its way into the binary log, while
+--echo # the stored function is in use.
+--echo # For that, try to insert a result of a stored function
+--echo # into a table. Block the insert in the beginning, waiting
+--echo # on a table lock. While insert is blocked, attempt to
+--echo # drop the routine. Verify that this attempt
+--echo # blocks and waits for INSERT to complete. Commit and
+--echo # reap the chain of events. Master and slave must contain
+--echo # identical data. Statements in the binrary log must be
+--echo # consistent with data in the table.
+--echo #
+--echo # --> connection default
+connection default;
+--disable_warnings
+drop table if exists t1, t2;
+drop function if exists t1;
+--enable_warnings
+create table t1 (a int);
+create table t2 (a int) as select 1 as a;
+create function f1() returns int deterministic return (select max(a) from t2);
+lock table t2 write;
+--echo # --> connection master
+connection master;
+--echo # Sending 'insert into t1 (a) values (f1())'...
+--send insert into t1 (a) values (f1())
+connection master1;
+--echo # Waitng for 'insert into t1 ...' to get blocked on table lock...
+let $wait_condition=select count(*)=1 from information_schema.processlist
+where state='Waiting for table' and info='insert into t1 (a) values (f1())';
+--source include/wait_condition.inc
+--echo # Sending 'drop function f1'. It will abort the table lock wait.
+drop function f1;
+--echo # --> connection default
+connection default;
+--echo # Now let's let 'insert' go through...
+unlock tables;
+--echo # --> connection con1
+connection master;
+--echo # Reaping 'insert into t1 (a) values (f1())'...
+--error ER_SP_DOES_NOT_EXIST
+--reap
+connection master;
+select * from t1;
+sync_slave_with_master;
+connection slave;
+select * from t1;
+# Cleanup
+connection master;
+drop table t1, t2;
+--error ER_SP_DOES_NOT_EXIST
+drop function f1;
+
+--echo # End of 5.5 tests.
+
# Cleanup
sync_slave_with_master;
diff --git a/mysql-test/suite/rpl/t/rpl_view_multi.test b/mysql-test/suite/rpl/t/rpl_view_multi.test
new file mode 100644
index 00000000000..90942f00ba7
--- /dev/null
+++ b/mysql-test/suite/rpl/t/rpl_view_multi.test
@@ -0,0 +1,145 @@
+#
+# This file contains test cases for bugs which involve views, several
+# concurren connections and manifest themselves as wrong binary log
+# sequence which results in broken replication. In principle we are
+# mostly interested in SBR here but this test will also work with RBR.
+#
+--source include/master-slave.inc
+
+--echo #
+--echo # Bug #25144 "replication / binlog with view breaks".
+--echo # Statements that used views didn't ensure that view were not modified
+--echo # during their execution. Indeed this led to incorrect binary log with
+--echo # statement based logging and as result to broken replication.
+--echo #
+#
+# Suppress "unsafe" warnings.
+#
+disable_query_log;
+call mtr.add_suppression("Unsafe statement binlogged in statement format since BINLOG_FORMAT = STATEMENT");
+enable_query_log;
+
+
+--disable_warnings
+drop tables if exists t1, t2;
+drop view if exists v1;
+--enable_warnings
+--echo # Syncing slave with master and switching to connection 'slave'
+--sync_slave_with_master
+
+connect (master2,127.0.0.1,root,,test,$MASTER_MYPORT,);
+
+--echo # Switching to connection 'master'
+connection master;
+create table t1 (i int);
+create table t2 (i int);
+create view v1 as select * from t1;
+
+--echo # First we try to concurrently execute statement that uses view
+--echo # and statement that drops it. We use "user" locks as means to
+--echo # suspend execution of first statement once it opens our view.
+select get_lock("lock_bg25144", 1);
+
+--echo # Switching to connection 'master1'
+connection master1;
+--send insert into v1 values (get_lock("lock_bg25144", 100))
+
+--echo # Switching to connection 'master2'
+connection master2;
+let $wait_condition=
+ select count(*) = 1 from information_schema.processlist
+ where state = "User lock" and info like "insert into v1 %lock_bg25144%";
+--source include/wait_condition.inc
+--send drop view v1
+
+--echo # Switching to connection 'master'
+connection master;
+let $wait_condition=
+ select count(*) = 1 from information_schema.processlist
+ where state = "Waiting for table" and info = "drop view v1";
+--source include/wait_condition.inc
+
+select release_lock("lock_bg25144");
+
+--echo # Switching to connection 'master1'
+connection master1;
+--disable_warnings
+--reap
+--enable_warnings
+select release_lock("lock_bg25144");
+
+--echo # Switching to connection 'master2'
+connection master2;
+--reap
+
+--echo # Switching to connection 'master'
+connection master;
+--echo # Check that insertion through view did happen.
+select * from t1;
+--echo # Syncing slave with master and switching to connection 'slave'
+--sync_slave_with_master
+--echo # Check that slave was able to replicate this sequence
+--echo # which means that we got correct binlog order.
+select * from t1;
+
+--echo # Switching to connection 'master'
+connection master;
+--echo # Now we will repeat the test by trying concurrently execute
+--echo # statement that uses a view and statement that alters it.
+create view v1 as select * from t1;
+
+select get_lock("lock_bg25144", 1);
+
+--echo # Switching to connection 'master1'
+connection master1;
+--send insert into v1 values (get_lock("lock_bg25144", 100))
+
+--echo # Switching to connection 'master2'
+connection master2;
+let $wait_condition=
+ select count(*) = 1 from information_schema.processlist
+ where state = "User lock" and info like "insert into v1 %lock_bg25144%";
+--source include/wait_condition.inc
+--send alter view v1 as select * from t2
+
+--echo # Switching to connection 'master'
+connection master;
+let $wait_condition=
+ select count(*) = 1 from information_schema.processlist
+ where state = "Waiting for table" and
+ info = "alter view v1 as select * from t2";
+--source include/wait_condition.inc
+
+select release_lock("lock_bg25144");
+
+--echo # Switching to connection 'master1'
+connection master1;
+--disable_warnings
+--reap
+--enable_warnings
+select release_lock("lock_bg25144");
+
+--echo # Switching to connection 'master2'
+connection master2;
+--reap
+
+--echo # Switching to connection 'master'
+connection master;
+
+--echo # Second insertion should go to t1 as well.
+select * from t1;
+select * from t2;
+
+--echo # Syncing slave with master and switching to connection 'slave'
+--sync_slave_with_master
+--echo # Now let us check that statements were logged in proper order
+--echo # So we have same result on slave.
+select * from t1;
+select * from t2;
+
+--echo # Switching to connection 'master'
+connection master;
+drop table t1, t2;
+drop view v1;
+--echo # Syncing slave with master and switching to connection 'slave'
+--sync_slave_with_master
diff --git a/mysql-test/suite/rpl_ndb/r/rpl_ndb_binlog_format_errors.result b/mysql-test/suite/rpl_ndb/r/rpl_ndb_binlog_format_errors.result
index 35f54455179..ecf2159e5db 100644
--- a/mysql-test/suite/rpl_ndb/r/rpl_ndb_binlog_format_errors.result
+++ b/mysql-test/suite/rpl_ndb/r/rpl_ndb_binlog_format_errors.result
@@ -43,11 +43,11 @@ SELECT * FROM t /* Should be empty */;
a
* Modify both row-only and stmt-only table
CREATE TRIGGER trig_2 AFTER INSERT ON t_stmt FOR EACH ROW BEGIN INSERT INTO t_row VALUES(1); END;
+ERROR HY000: Cannot execute statement: binlogging impossible since BINLOG_FORMAT = ROW and at least one table uses a storage engine limited to statement-logging.
INSERT INTO t_stmt VALUES (1);
-ERROR HY000: Cannot execute statement: binlogging impossible since both row-incapable engines and statement-incapable engines are involved.
+ERROR HY000: Cannot execute statement: binlogging impossible since BINLOG_FORMAT = ROW and at least one table uses a storage engine limited to statement-logging.
SELECT * FROM t_stmt /* should be empty */;
a
-DROP TRIGGER trig_2;
* Stmt-only table and binlog_format=row
INSERT INTO t_stmt VALUES (1);
ERROR HY000: Cannot execute statement: binlogging impossible since BINLOG_FORMAT = ROW and at least one table uses a storage engine limited to statement-logging.
diff --git a/mysql-test/suite/rpl_ndb/t/rpl_ndb_binlog_format_errors.test b/mysql-test/suite/rpl_ndb/t/rpl_ndb_binlog_format_errors.test
index 5bf3d39750b..ddad6519b5f 100644
--- a/mysql-test/suite/rpl_ndb/t/rpl_ndb_binlog_format_errors.test
+++ b/mysql-test/suite/rpl_ndb/t/rpl_ndb_binlog_format_errors.test
@@ -97,11 +97,11 @@ SELECT * FROM t_self_logging /* Should be empty */;
SELECT * FROM t /* Should be empty */;
--echo * Modify both row-only and stmt-only table
+--error ER_BINLOG_ROW_MODE_AND_STMT_ENGINE
--eval CREATE TRIGGER trig_2 AFTER INSERT ON t_stmt FOR EACH ROW BEGIN INSERT INTO t_row VALUES(1); END
---error ER_BINLOG_ROW_ENGINE_AND_STMT_ENGINE
+--error ER_BINLOG_ROW_MODE_AND_STMT_ENGINE
INSERT INTO t_stmt VALUES (1);
SELECT * FROM t_stmt /* should be empty */;
-DROP TRIGGER trig_2;
--echo * Stmt-only table and binlog_format=row
--error ER_BINLOG_ROW_MODE_AND_STMT_ENGINE
diff --git a/mysql-test/suite/sys_vars/r/autocommit_func.result b/mysql-test/suite/sys_vars/r/autocommit_func.result
index 8fe7c0bc90e..13115ca81ef 100644
--- a/mysql-test/suite/sys_vars/r/autocommit_func.result
+++ b/mysql-test/suite/sys_vars/r/autocommit_func.result
@@ -103,6 +103,8 @@ id name
2 Record_2
4 Record_4
5 Record_5
+## Commit changes
+COMMIT;
## Dropping table t1 ##
DROP table t1;
## Disconnecting both connections ##
diff --git a/mysql-test/suite/sys_vars/r/concurrent_insert_func.result b/mysql-test/suite/sys_vars/r/concurrent_insert_func.result
index de4ddbb5a04..0b5b342e134 100644
--- a/mysql-test/suite/sys_vars/r/concurrent_insert_func.result
+++ b/mysql-test/suite/sys_vars/r/concurrent_insert_func.result
@@ -37,9 +37,9 @@ INSERT INTO t1(name) VALUES('Record_7');
connection default;
## show processlist info and state ##
SELECT state,info FROM INFORMATION_SCHEMA.PROCESSLIST
-WHERE state= "Locked" AND info LIKE "INSERT INTO t1%";
+WHERE state= "Table lock" AND info LIKE "INSERT INTO t1%";
state info
-Locked INSERT INTO t1(name) VALUES('Record_7')
+Table lock INSERT INTO t1(name) VALUES('Record_7')
## table contents befor UNLOCK ##
SELECT * FROM t1;
name
diff --git a/mysql-test/suite/sys_vars/r/delayed_insert_limit_func.result b/mysql-test/suite/sys_vars/r/delayed_insert_limit_func.result
index 10d9f0d71c3..eeb7a28c816 100644
--- a/mysql-test/suite/sys_vars/r/delayed_insert_limit_func.result
+++ b/mysql-test/suite/sys_vars/r/delayed_insert_limit_func.result
@@ -4,6 +4,7 @@ Creating connection con0
Creating connection con1
SET @global_delayed_insert_limit = @@GLOBAL.delayed_insert_limit;
CREATE TABLE t1 (a VARCHAR(100),b VARCHAR(100),c VARCHAR(100));
+CREATE VIEW v1 as select * from t1;
'#--------------------FN_DYNVARS_25_01-------------------------#'
SET GLOBAL delayed_insert_limit = 14;
INSERT INTO t1 VALUES('1','1','1');
@@ -12,7 +13,7 @@ INSERT INTO t1 VALUES('3','1','1');
INSERT INTO t1 VALUES('4','1','1');
INSERT INTO t1 VALUES('5','1','1');
INSERT INTO t1 VALUES('6','1','1');
-LOCK TABLE t1 WRITE;
+LOCK TABLE v1 WRITE;
** Connection con1 **
INSERT DELAYED INTO t1 VALUES('7','1','1');
INSERT DELAYED INTO t1 VALUES('8','1','1');
@@ -70,8 +71,10 @@ SELECT COUNT(*) FROM t1;
COUNT(*)
43
DROP TABLE t1;
+DROP VIEW v1;
'#--------------------FN_DYNVARS_25_02-------------------------#'
CREATE TABLE t1 (a VARCHAR(100));
+CREATE VIEW v1 AS SELECT * FROM t1;
SET GLOBAL delayed_insert_limit = 20;
INSERT INTO t1 VALUES('1');
INSERT INTO t1 VALUES('2');
@@ -79,7 +82,7 @@ INSERT INTO t1 VALUES('3');
INSERT INTO t1 VALUES('4');
INSERT INTO t1 VALUES('5');
INSERT INTO t1 VALUES('6');
-LOCK TABLE t1 WRITE;
+LOCK TABLE v1 WRITE;
** Connection con1 **
Asynchronous execute
INSERT DELAYED INTO t1 VALUES('7');
@@ -116,5 +119,6 @@ COUNT(*) BETWEEN 6 AND 22
1
** Connection default**
DROP TABLE t1;
+DROP VIEW v1;
SET @@GLOBAL.delayed_insert_limit = @global_delayed_insert_limit;
Disconnecting from con1, con0
diff --git a/mysql-test/suite/sys_vars/r/lock_wait_timeout_basic.result b/mysql-test/suite/sys_vars/r/lock_wait_timeout_basic.result
new file mode 100644
index 00000000000..6d1e8d3bb59
--- /dev/null
+++ b/mysql-test/suite/sys_vars/r/lock_wait_timeout_basic.result
@@ -0,0 +1,177 @@
+SET @start_global_value = @@global.lock_wait_timeout;
+SELECT @start_global_value;
+@start_global_value
+31536000
+SET @start_session_value = @@session.lock_wait_timeout;
+SELECT @start_session_value;
+@start_session_value
+31536000
+'#--------------------FN_DYNVARS_002_01-------------------------#'
+SET @@global.lock_wait_timeout = 100;
+SET @@global.lock_wait_timeout = DEFAULT;
+SELECT @@global.lock_wait_timeout;
+@@global.lock_wait_timeout
+31536000
+SET @@session.lock_wait_timeout = 200;
+SET @@session.lock_wait_timeout = DEFAULT;
+SELECT @@session.lock_wait_timeout;
+@@session.lock_wait_timeout
+31536000
+'#--------------------FN_DYNVARS_002_02-------------------------#'
+SET @@global.lock_wait_timeout = @start_global_value;
+SELECT @@global.lock_wait_timeout = 31536000;
+@@global.lock_wait_timeout = 31536000
+1
+SET @@session.lock_wait_timeout = @start_session_value;
+SELECT @@session.lock_wait_timeout = 31536000;
+@@session.lock_wait_timeout = 31536000
+1
+'#--------------------FN_DYNVARS_002_03-------------------------#'
+SET @@global.lock_wait_timeout = 1;
+SELECT @@global.lock_wait_timeout;
+@@global.lock_wait_timeout
+1
+SET @@global.lock_wait_timeout = 60020;
+SELECT @@global.lock_wait_timeout;
+@@global.lock_wait_timeout
+60020
+SET @@global.lock_wait_timeout = 65535;
+SELECT @@global.lock_wait_timeout;
+@@global.lock_wait_timeout
+65535
+'#--------------------FN_DYNVARS_002_04-------------------------#'
+SET @@session.lock_wait_timeout = 1;
+SELECT @@session.lock_wait_timeout;
+@@session.lock_wait_timeout
+1
+SET @@session.lock_wait_timeout = 50050;
+SELECT @@session.lock_wait_timeout;
+@@session.lock_wait_timeout
+50050
+SET @@session.lock_wait_timeout = 65535;
+SELECT @@session.lock_wait_timeout;
+@@session.lock_wait_timeout
+65535
+'#------------------FN_DYNVARS_002_05-----------------------#'
+SET @@global.lock_wait_timeout = 0;
+Warnings:
+Warning 1292 Truncated incorrect lock_wait_timeout value: '0'
+SELECT @@global.lock_wait_timeout;
+@@global.lock_wait_timeout
+1
+SET @@global.lock_wait_timeout = -1024;
+Warnings:
+Warning 1292 Truncated incorrect lock_wait_timeout value: '-1024'
+SELECT @@global.lock_wait_timeout;
+@@global.lock_wait_timeout
+1
+SET @@global.lock_wait_timeout = 31536001;
+Warnings:
+Warning 1292 Truncated incorrect lock_wait_timeout value: '31536001'
+SELECT @@global.lock_wait_timeout;
+@@global.lock_wait_timeout
+31536000
+SET @@global.lock_wait_timeout = ON;
+ERROR 42000: Incorrect argument type to variable 'lock_wait_timeout'
+SELECT @@global.lock_wait_timeout;
+@@global.lock_wait_timeout
+31536000
+SET @@global.lock_wait_timeout = OFF;
+ERROR 42000: Incorrect argument type to variable 'lock_wait_timeout'
+SELECT @@global.lock_wait_timeout;
+@@global.lock_wait_timeout
+31536000
+SET @@global.lock_wait_timeout = test;
+ERROR 42000: Incorrect argument type to variable 'lock_wait_timeout'
+SELECT @@global.lock_wait_timeout;
+@@global.lock_wait_timeout
+31536000
+SET @@session.lock_wait_timeout = 0;
+Warnings:
+Warning 1292 Truncated incorrect lock_wait_timeout value: '0'
+SELECT @@session.lock_wait_timeout;
+@@session.lock_wait_timeout
+1
+SET @@session.lock_wait_timeout = -2;
+Warnings:
+Warning 1292 Truncated incorrect lock_wait_timeout value: '-2'
+SELECT @@session.lock_wait_timeout;
+@@session.lock_wait_timeout
+1
+SET @@session.lock_wait_timeout = 31537000;
+Warnings:
+Warning 1292 Truncated incorrect lock_wait_timeout value: '31537000'
+SELECT @@session.lock_wait_timeout;
+@@session.lock_wait_timeout
+31536000
+SET @@session.lock_wait_timeout = ON;
+ERROR 42000: Incorrect argument type to variable 'lock_wait_timeout'
+SELECT @@session.lock_wait_timeout;
+@@session.lock_wait_timeout
+31536000
+SET @@session.lock_wait_timeout = OFF;
+ERROR 42000: Incorrect argument type to variable 'lock_wait_timeout'
+SELECT @@session.lock_wait_timeout;
+@@session.lock_wait_timeout
+31536000
+SET @@session.lock_wait_timeout = test;
+ERROR 42000: Incorrect argument type to variable 'lock_wait_timeout'
+SELECT @@session.lock_wait_timeout;
+@@session.lock_wait_timeout
+31536000
+'#------------------FN_DYNVARS_002_06-----------------------#'
+SELECT @@global.lock_wait_timeout = VARIABLE_VALUE
+FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES
+WHERE VARIABLE_NAME='lock_wait_timeout';
+@@global.lock_wait_timeout = VARIABLE_VALUE
+1
+'#------------------FN_DYNVARS_002_07-----------------------#'
+SELECT @@session.lock_wait_timeout = VARIABLE_VALUE
+FROM INFORMATION_SCHEMA.SESSION_VARIABLES
+WHERE VARIABLE_NAME='lock_wait_timeout';
+@@session.lock_wait_timeout = VARIABLE_VALUE
+1
+'#------------------FN_DYNVARS_002_08-----------------------#'
+SET @@global.lock_wait_timeout = TRUE;
+SELECT @@global.lock_wait_timeout;
+@@global.lock_wait_timeout
+1
+SET @@global.lock_wait_timeout = FALSE;
+Warnings:
+Warning 1292 Truncated incorrect lock_wait_timeout value: '0'
+SELECT @@global.lock_wait_timeout;
+@@global.lock_wait_timeout
+1
+'#---------------------FN_DYNVARS_001_09----------------------#'
+SET @@global.lock_wait_timeout = 10;
+SET @@session.lock_wait_timeout = 11;
+SELECT @@lock_wait_timeout = @@global.lock_wait_timeout;
+@@lock_wait_timeout = @@global.lock_wait_timeout
+0
+'#---------------------FN_DYNVARS_001_10----------------------#'
+SET @@lock_wait_timeout = 100;
+SELECT @@lock_wait_timeout = @@local.lock_wait_timeout;
+@@lock_wait_timeout = @@local.lock_wait_timeout
+1
+SELECT @@local.lock_wait_timeout = @@session.lock_wait_timeout;
+@@local.lock_wait_timeout = @@session.lock_wait_timeout
+1
+'#---------------------FN_DYNVARS_001_11----------------------#'
+SET lock_wait_timeout = 1;
+SELECT @@lock_wait_timeout;
+@@lock_wait_timeout
+1
+SELECT local.lock_wait_timeout;
+ERROR 42S02: Unknown table 'local' in field list
+SELECT session.lock_wait_timeout;
+ERROR 42S02: Unknown table 'session' in field list
+SELECT lock_wait_timeout = @@session.lock_wait_timeout;
+ERROR 42S22: Unknown column 'lock_wait_timeout' in 'field list'
+SET @@global.lock_wait_timeout = @start_global_value;
+SELECT @@global.lock_wait_timeout;
+@@global.lock_wait_timeout
+31536000
+SET @@session.lock_wait_timeout = @start_session_value;
+SELECT @@session.lock_wait_timeout;
+@@session.lock_wait_timeout
+31536000
diff --git a/mysql-test/suite/sys_vars/r/query_cache_wlock_invalidate_func.result b/mysql-test/suite/sys_vars/r/query_cache_wlock_invalidate_func.result
index 6b90b61a035..abb8fdcd2a0 100644
--- a/mysql-test/suite/sys_vars/r/query_cache_wlock_invalidate_func.result
+++ b/mysql-test/suite/sys_vars/r/query_cache_wlock_invalidate_func.result
@@ -11,6 +11,7 @@ CREATE TABLE t1(id int, value varchar(10));
INSERT INTO t1 VALUES(1, 'val1');
INSERT INTO t1 VALUES(2, 'val2');
INSERT INTO t1 VALUES(3, 'val3');
+CREATE VIEW v1 AS SELECT * FROM t1;
SET GLOBAL query_cache_size = 131072;
FLUSHING CACHE
SET GLOBAL query_cache_size = 0;
@@ -32,11 +33,11 @@ SHOW STATUS LIKE 'Qcache_queries_in_cache';
Variable_name Value
Qcache_queries_in_cache 1
1 Expected
-LOCK TABLE t1 WRITE;
+LOCK TABLE v1 WRITE;
UNLOCK TABLES;
SHOW STATUS LIKE 'Qcache_queries_in_cache';
Variable_name Value
-Qcache_queries_in_cache 0
+Qcache_queries_in_cache 1
0 Expected
'#----------------------------FN_DYNVARS_136_02-----------------------#'
SELECT * FROM t1;
@@ -48,12 +49,13 @@ id value
2 val2
3 val3
** Connection con0 **
-LOCK TABLE t1 WRITE;
+LOCK TABLE v1 WRITE;
** Connection con1 **
** Asynchronous Execution **
SELECT * FROM t1;
** Connection con0 **
wait until table is locked
+Timeout in wait_condition.inc for SELECT count(*) > 0 FROM information_schema.processlist WHERE state= 'Table lock'
UNLOCK TABLES;
** Connection con1 **
** Asynchronous Result **
@@ -77,7 +79,7 @@ SHOW STATUS LIKE 'Qcache_queries_in_cache';
Variable_name Value
Qcache_queries_in_cache 1
1 Expected
-LOCK TABLE t1 WRITE;
+LOCK TABLE v1 WRITE;
UNLOCK TABLES;
SHOW STATUS LIKE 'Qcache_queries_in_cache';
Variable_name Value
@@ -100,7 +102,7 @@ id value
2 val2
3 val3
** Connection con0 **
-LOCK TABLE t1 WRITE;
+LOCK TABLE v1 WRITE;
** Connection con1 **
** Should not be blocked **
SELECT * FROM t1;
@@ -163,3 +165,4 @@ SET @@GLOBAL.query_cache_type = @old_cache_type;
** Connection default **
Disconnecting Connections con0, con1
DROP TABLE t1;
+DROP VIEW v1;
diff --git a/mysql-test/suite/sys_vars/r/sql_low_priority_updates_func.result b/mysql-test/suite/sys_vars/r/sql_low_priority_updates_func.result
index 584ca4c6f8f..fe76c2c4b96 100644
--- a/mysql-test/suite/sys_vars/r/sql_low_priority_updates_func.result
+++ b/mysql-test/suite/sys_vars/r/sql_low_priority_updates_func.result
@@ -6,6 +6,7 @@
SET @global_low_priority_updates = @@GLOBAL.low_priority_updates;
SET @session_low_priority_updates = @@SESSION.low_priority_updates;
CREATE TABLE t1 (a varchar(100));
+create view v1 as select * from t1;
'#--------------------FN_DYNVARS_160_01-------------------------#'
** Connection con0 **
SET SESSION low_priority_updates = ON;
@@ -19,7 +20,7 @@ INSERT INTO t1 VALUES('3');
INSERT INTO t1 VALUES('4');
INSERT INTO t1 VALUES('5');
INSERT INTO t1 VALUES('6');
-LOCK TABLE t1 WRITE;
+LOCK TABLE v1 WRITE;
** Connection con1 **
** Asynchronous Execution **
UPDATE t1 SET a = CONCAT(a,"-updated");|
@@ -55,7 +56,7 @@ INSERT INTO t1 VALUES('3');
INSERT INTO t1 VALUES('4');
INSERT INTO t1 VALUES('5');
INSERT INTO t1 VALUES('6');
-LOCK TABLE t1 WRITE;
+LOCK TABLE v1 WRITE;
** Connection con1 **
** Asynchronous Execution **
UPDATE t1 SET a = CONCAT(a,"-updated");|
@@ -107,6 +108,7 @@ SELECT @@SESSION.low_priority_updates;
Disconnecting Connections con_int1, con_int2
** Connection default **
Disconnecting Connections con0, con1
+drop view v1;
DROP TABLE t1;
SET @@GLOBAL.low_priority_updates = @global_low_priority_updates;
SET @@SESSION.low_priority_updates = @session_low_priority_updates;
diff --git a/mysql-test/suite/sys_vars/r/table_lock_wait_timeout_basic.result b/mysql-test/suite/sys_vars/r/table_lock_wait_timeout_basic.result
deleted file mode 100644
index 68c36242cc1..00000000000
--- a/mysql-test/suite/sys_vars/r/table_lock_wait_timeout_basic.result
+++ /dev/null
@@ -1,98 +0,0 @@
-SET @start_value = @@global.table_lock_wait_timeout;
-SELECT @start_value;
-@start_value
-50
-'#--------------------FN_DYNVARS_001_01------------------------#'
-SET @@global.table_lock_wait_timeout = 99;
-SET @@global.table_lock_wait_timeout = DeFAULT;
-SELECT @@global.table_lock_wait_timeout;
-@@global.table_lock_wait_timeout
-50
-'#---------------------FN_DYNVARS_001_02-------------------------#'
-SET @@global.table_lock_wait_timeout =Default;
-SELECT @@global.table_lock_wait_timeout = 50;
-@@global.table_lock_wait_timeout = 50
-1
-'#--------------------FN_DYNVARS_001_03------------------------#'
-SET @@global.table_lock_wait_timeout = 8;
-SELECT @@global.table_lock_wait_timeout ;
-@@global.table_lock_wait_timeout
-8
-SET @@global.table_lock_wait_timeout = 1;
-SELECT @@global.table_lock_wait_timeout ;
-@@global.table_lock_wait_timeout
-1
-SET @@global.table_lock_wait_timeout = 1073741824;
-SELECT @@global.table_lock_wait_timeout ;
-@@global.table_lock_wait_timeout
-1073741824
-SET @@global.table_lock_wait_timeout = 18000;
-SELECT @@global.table_lock_wait_timeout ;
-@@global.table_lock_wait_timeout
-18000
-SET @@global.table_lock_wait_timeout = 65535;
-SELECT @@global.table_lock_wait_timeout ;
-@@global.table_lock_wait_timeout
-65535
-'#--------------------FN_DYNVARS_001_04-------------------------#'
-SET @@global.table_lock_wait_timeout = -1;
-Warnings:
-Warning 1292 Truncated incorrect table_lock_wait_timeout value: '-1'
-SET @@global.table_lock_wait_timeout= 100000000000;
-Warnings:
-Warning 1292 Truncated incorrect table_lock_wait_timeout value: '100000000000'
-SET @@global.table_lock_wait_timeout= -1024;
-Warnings:
-Warning 1292 Truncated incorrect table_lock_wait_timeout value: '-1024'
-SET @@global.table_lock_wait_timeout= 0;
-Warnings:
-Warning 1292 Truncated incorrect table_lock_wait_timeout value: '0'
-SET @@global.table_lock_wait_timeout= 10000.01;
-ERROR 42000: Incorrect argument type to variable 'table_lock_wait_timeout'
-SET @@global.table_lock_wait_timeout= ON;
-ERROR 42000: Incorrect argument type to variable 'table_lock_wait_timeout'
-SET @@global.table_lock_wait_timeout= 'test';
-ERROR 42000: Incorrect argument type to variable 'table_lock_wait_timeout'
-SET @@global.table_lock_wait_timeout= '';
-ERROR 42000: Incorrect argument type to variable 'table_lock_wait_timeout'
-'#-------------------FN_DYNVARS_001_05----------------------------#'
-SET @@session.table_lock_wait_timeout= 0;
-ERROR HY000: Variable 'table_lock_wait_timeout' is a GLOBAL variable and should be set with SET GLOBAL
-SELECT @@table_lock_wait_timeout;
-@@table_lock_wait_timeout
-1
-'#----------------------FN_DYNVARS_001_06------------------------#'
-SELECT @@global.table_lock_wait_timeout= VARIABLE_VALUE
-FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES
-WHERE VARIABLE_NAME='table_lock_wait_timeout';
-@@global.table_lock_wait_timeout= VARIABLE_VALUE
-1
-'#---------------------FN_DYNVARS_001_09----------------------#'
-SET @@global.table_lock_wait_timeout= TRUE;
-SELECT @@global.table_lock_wait_timeout;
-@@global.table_lock_wait_timeout
-1
-SET @@global.table_lock_wait_timeout= FALSE;
-Warnings:
-Warning 1292 Truncated incorrect table_lock_wait_timeout value: '0'
-SELECT @@global.table_lock_wait_timeout;
-@@global.table_lock_wait_timeout
-1
-'#---------------------FN_DYNVARS_001_10----------------------#'
-SET @@global.table_lock_wait_timeout= 10;
-SELECT @@table_lock_wait_timeout= @@global.table_lock_wait_timeout;
-@@table_lock_wait_timeout= @@global.table_lock_wait_timeout
-1
-'#---------------------FN_DYNVARS_001_11----------------------#'
-SET table_lock_wait_timeout= 8;
-ERROR HY000: Variable 'table_lock_wait_timeout' is a GLOBAL variable and should be set with SET GLOBAL
-SET global.table_lock_wait_timeout= 10;
-ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'table_lock_wait_timeout= 10' at line 1
-SELECT global.table_lock_wait_timeout;
-ERROR 42S02: Unknown table 'global' in field list
-SELECT table_lock_wait_timeout= @@session.table_lock_wait_timeout;
-ERROR 42S22: Unknown column 'table_lock_wait_timeout' in 'field list'
-SET @@global.table_lock_wait_timeout= @start_value;
-SELECT @@global.table_lock_wait_timeout;
-@@global.table_lock_wait_timeout
-50
diff --git a/mysql-test/suite/sys_vars/t/autocommit_func.test b/mysql-test/suite/sys_vars/t/autocommit_func.test
index 06193448588..10c763ca58e 100644
--- a/mysql-test/suite/sys_vars/t/autocommit_func.test
+++ b/mysql-test/suite/sys_vars/t/autocommit_func.test
@@ -152,6 +152,10 @@ SELECT * from t1;
CONNECTION test_con2;
SELECT * from t1;
+--echo ## Commit changes
+CONNECTION test_con1;
+COMMIT;
+
--echo ## Dropping table t1 ##
DROP table t1;
diff --git a/mysql-test/suite/sys_vars/t/concurrent_insert_func.test b/mysql-test/suite/sys_vars/t/concurrent_insert_func.test
index 1a600ffd7f6..018247df3ff 100644
--- a/mysql-test/suite/sys_vars/t/concurrent_insert_func.test
+++ b/mysql-test/suite/sys_vars/t/concurrent_insert_func.test
@@ -98,12 +98,12 @@ INSERT INTO t1(name) VALUES('Record_7');
connection default;
# wait until INSERT will be locked (low performance)
let $wait_condition= SELECT COUNT(*) = 1 FROM INFORMATION_SCHEMA.PROCESSLIST
- WHERE state= "Locked" AND info LIKE "INSERT INTO t1%";
+ WHERE state= "Table lock" AND info LIKE "INSERT INTO t1%";
--source include/wait_condition.inc
--echo ## show processlist info and state ##
SELECT state,info FROM INFORMATION_SCHEMA.PROCESSLIST
-WHERE state= "Locked" AND info LIKE "INSERT INTO t1%";
+WHERE state= "Table lock" AND info LIKE "INSERT INTO t1%";
--echo ## table contents befor UNLOCK ##
SELECT * FROM t1;
UNLOCK TABLES;
diff --git a/mysql-test/suite/sys_vars/t/delayed_insert_limit_func.test b/mysql-test/suite/sys_vars/t/delayed_insert_limit_func.test
index abe41f021a6..60092dbb8e8 100644
--- a/mysql-test/suite/sys_vars/t/delayed_insert_limit_func.test
+++ b/mysql-test/suite/sys_vars/t/delayed_insert_limit_func.test
@@ -46,6 +46,7 @@ SET @global_delayed_insert_limit = @@GLOBAL.delayed_insert_limit;
#
CREATE TABLE t1 (a VARCHAR(100),b VARCHAR(100),c VARCHAR(100));
+CREATE VIEW v1 as select * from t1;
--echo '#--------------------FN_DYNVARS_25_01-------------------------#'
@@ -60,7 +61,7 @@ INSERT INTO t1 VALUES('4','1','1');
INSERT INTO t1 VALUES('5','1','1');
INSERT INTO t1 VALUES('6','1','1');
-LOCK TABLE t1 WRITE;
+LOCK TABLE v1 WRITE;
--echo ** Connection con1 **
connection con1;
@@ -122,7 +123,7 @@ connection default;
--echo ** Wait till con0 is blocked **
let $wait_condition=
SELECT COUNT(*) = 1 FROM information_schema.processlist
- WHERE state = 'Locked' AND info = '$my_select';
+ WHERE state = 'Table lock' AND info = '$my_select';
--source include/wait_condition.inc
UNLOCK TABLES;
@@ -153,6 +154,7 @@ let $wait_condition= SELECT count(*) = 43 FROM t1;
SELECT COUNT(*) FROM t1;
DROP TABLE t1;
+DROP VIEW v1;
--echo '#--------------------FN_DYNVARS_25_02-------------------------#'
@@ -160,6 +162,7 @@ DROP TABLE t1;
# delayed_insert_limit is bigger than the number of inserted rows
CREATE TABLE t1 (a VARCHAR(100));
+CREATE VIEW v1 AS SELECT * FROM t1;
SET GLOBAL delayed_insert_limit = 20;
@@ -170,7 +173,7 @@ INSERT INTO t1 VALUES('4');
INSERT INTO t1 VALUES('5');
INSERT INTO t1 VALUES('6');
-LOCK TABLE t1 WRITE;
+LOCK TABLE v1 WRITE;
--echo ** Connection con1 **
connection con1;
@@ -216,7 +219,7 @@ connection default;
--echo ** Wait till con0 is blocked **
let $wait_condition=
SELECT COUNT(*) = 1 FROM information_schema.processlist
- WHERE state = 'Locked' AND info = '$my_select';
+ WHERE state = 'Table lock' AND info = '$my_select';
--source include/wait_condition.inc
UNLOCK TABLES;
@@ -242,6 +245,7 @@ eval $my_select;
--echo ** Connection default**
connection default;
DROP TABLE t1;
+DROP VIEW v1;
SET @@GLOBAL.delayed_insert_limit = @global_delayed_insert_limit;
--echo Disconnecting from con1, con0
diff --git a/mysql-test/suite/sys_vars/t/lock_wait_timeout_basic.test b/mysql-test/suite/sys_vars/t/lock_wait_timeout_basic.test
new file mode 100644
index 00000000000..770bda0e053
--- /dev/null
+++ b/mysql-test/suite/sys_vars/t/lock_wait_timeout_basic.test
@@ -0,0 +1,213 @@
+############## mysql-test\t\lock_wait_timeout_basic.test #######################
+# #
+# Variable Name: lock_wait_timeout #
+# Scope: GLOBAL & SESSION #
+# Access Type: Dynamic #
+# Data Type: Numeric #
+# Default Value: 1 #
+# Range: 1 - 31536000 #
+# #
+# #
+# Creation Date: 2010-02-08 #
+# Author: Jon Olav Hauglid #
+# #
+# Description: Test Cases of Dynamic System Variable "lock_wait_timeout" #
+# that checks behavior of this variable in the following ways #
+# * Default Value #
+# * Valid & Invalid values #
+# * Scope & Access method #
+# * Data Integrity #
+# #
+# Reference: http://dev.mysql.com/doc/refman/5.5/en/ #
+# server-system-variables.html#option_mysqld_lock-wait-timeout #
+# #
+################################################################################
+
+--source include/load_sysvars.inc
+
+#####################################################################
+# START OF lock_wait_timeout TESTS #
+#####################################################################
+
+#############################################################
+# Save initial value #
+#############################################################
+
+SET @start_global_value = @@global.lock_wait_timeout;
+SELECT @start_global_value;
+SET @start_session_value = @@session.lock_wait_timeout;
+SELECT @start_session_value;
+
+
+--echo '#--------------------FN_DYNVARS_002_01-------------------------#'
+#####################################################################
+# Display the DEFAULT value of lock_wait_timeout #
+#####################################################################
+
+SET @@global.lock_wait_timeout = 100;
+SET @@global.lock_wait_timeout = DEFAULT;
+SELECT @@global.lock_wait_timeout;
+
+SET @@session.lock_wait_timeout = 200;
+SET @@session.lock_wait_timeout = DEFAULT;
+SELECT @@session.lock_wait_timeout;
+
+
+--echo '#--------------------FN_DYNVARS_002_02-------------------------#'
+#####################################################################
+# Check the DEFAULT value of lock_wait_timeout #
+#####################################################################
+
+SET @@global.lock_wait_timeout = @start_global_value;
+SELECT @@global.lock_wait_timeout = 31536000;
+SET @@session.lock_wait_timeout = @start_session_value;
+SELECT @@session.lock_wait_timeout = 31536000;
+
+
+--echo '#--------------------FN_DYNVARS_002_03-------------------------#'
+###############################################################################
+# Change the value of lock_wait_timeout to a valid value for GLOBAL Scope #
+###############################################################################
+
+SET @@global.lock_wait_timeout = 1;
+SELECT @@global.lock_wait_timeout;
+SET @@global.lock_wait_timeout = 60020;
+SELECT @@global.lock_wait_timeout;
+SET @@global.lock_wait_timeout = 65535;
+SELECT @@global.lock_wait_timeout;
+
+
+--echo '#--------------------FN_DYNVARS_002_04-------------------------#'
+###############################################################################
+# Change the value of lock_wait_timeout to a valid value for SESSION Scope #
+###############################################################################
+
+SET @@session.lock_wait_timeout = 1;
+SELECT @@session.lock_wait_timeout;
+SET @@session.lock_wait_timeout = 50050;
+SELECT @@session.lock_wait_timeout;
+SET @@session.lock_wait_timeout = 65535;
+SELECT @@session.lock_wait_timeout;
+
+
+--echo '#------------------FN_DYNVARS_002_05-----------------------#'
+#################################################################
+# Change the value of lock_wait_timeout to an invalid value #
+#################################################################
+# for global scope
+SET @@global.lock_wait_timeout = 0;
+SELECT @@global.lock_wait_timeout;
+SET @@global.lock_wait_timeout = -1024;
+SELECT @@global.lock_wait_timeout;
+SET @@global.lock_wait_timeout = 31536001;
+SELECT @@global.lock_wait_timeout;
+--Error ER_WRONG_TYPE_FOR_VAR
+SET @@global.lock_wait_timeout = ON;
+SELECT @@global.lock_wait_timeout;
+--Error ER_WRONG_TYPE_FOR_VAR
+SET @@global.lock_wait_timeout = OFF;
+SELECT @@global.lock_wait_timeout;
+--Error ER_WRONG_TYPE_FOR_VAR
+SET @@global.lock_wait_timeout = test;
+SELECT @@global.lock_wait_timeout;
+# for session scope
+SET @@session.lock_wait_timeout = 0;
+SELECT @@session.lock_wait_timeout;
+SET @@session.lock_wait_timeout = -2;
+SELECT @@session.lock_wait_timeout;
+SET @@session.lock_wait_timeout = 31537000;
+SELECT @@session.lock_wait_timeout;
+
+--Error ER_WRONG_TYPE_FOR_VAR
+SET @@session.lock_wait_timeout = ON;
+SELECT @@session.lock_wait_timeout;
+--Error ER_WRONG_TYPE_FOR_VAR
+SET @@session.lock_wait_timeout = OFF;
+SELECT @@session.lock_wait_timeout;
+--Error ER_WRONG_TYPE_FOR_VAR
+SET @@session.lock_wait_timeout = test;
+SELECT @@session.lock_wait_timeout;
+
+
+
+--echo '#------------------FN_DYNVARS_002_06-----------------------#'
+####################################################################
+# Check if the value in GLOBAL Table matches value in variable #
+####################################################################
+
+SELECT @@global.lock_wait_timeout = VARIABLE_VALUE
+FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES
+WHERE VARIABLE_NAME='lock_wait_timeout';
+
+
+--echo '#------------------FN_DYNVARS_002_07-----------------------#'
+####################################################################
+# Check if the value in SESSION Table matches value in variable #
+####################################################################
+
+SELECT @@session.lock_wait_timeout = VARIABLE_VALUE
+FROM INFORMATION_SCHEMA.SESSION_VARIABLES
+WHERE VARIABLE_NAME='lock_wait_timeout';
+
+
+--echo '#------------------FN_DYNVARS_002_08-----------------------#'
+####################################################################
+# Check if TRUE and FALSE values can be used on variable #
+####################################################################
+
+SET @@global.lock_wait_timeout = TRUE;
+SELECT @@global.lock_wait_timeout;
+SET @@global.lock_wait_timeout = FALSE;
+SELECT @@global.lock_wait_timeout;
+
+
+--echo '#---------------------FN_DYNVARS_001_09----------------------#'
+###############################################################################
+# Check if global and session variables are independant of each other #
+###############################################################################
+
+SET @@global.lock_wait_timeout = 10;
+SET @@session.lock_wait_timeout = 11;
+SELECT @@lock_wait_timeout = @@global.lock_wait_timeout;
+
+
+--echo '#---------------------FN_DYNVARS_001_10----------------------#'
+##############################################################################
+# Check if accessing variable with SESSION,LOCAL and without SCOPE points #
+# to same session variable #
+##############################################################################
+
+SET @@lock_wait_timeout = 100;
+SELECT @@lock_wait_timeout = @@local.lock_wait_timeout;
+SELECT @@local.lock_wait_timeout = @@session.lock_wait_timeout;
+
+
+--echo '#---------------------FN_DYNVARS_001_11----------------------#'
+###############################################################################
+# Check if lock_wait_timeout can be accessed with and without @@ sign #
+###############################################################################
+
+SET lock_wait_timeout = 1;
+SELECT @@lock_wait_timeout;
+--Error ER_UNKNOWN_TABLE
+SELECT local.lock_wait_timeout;
+--Error ER_UNKNOWN_TABLE
+SELECT session.lock_wait_timeout;
+--Error ER_BAD_FIELD_ERROR
+SELECT lock_wait_timeout = @@session.lock_wait_timeout;
+
+
+####################################
+# Restore initial value #
+####################################
+
+SET @@global.lock_wait_timeout = @start_global_value;
+SELECT @@global.lock_wait_timeout;
+SET @@session.lock_wait_timeout = @start_session_value;
+SELECT @@session.lock_wait_timeout;
+
+
+###################################################
+# END OF lock_wait_timeout TESTS #
+###################################################
+
diff --git a/mysql-test/suite/sys_vars/t/query_cache_wlock_invalidate_func.test b/mysql-test/suite/sys_vars/t/query_cache_wlock_invalidate_func.test
index e5ced59d175..a72d73105a6 100644
--- a/mysql-test/suite/sys_vars/t/query_cache_wlock_invalidate_func.test
+++ b/mysql-test/suite/sys_vars/t/query_cache_wlock_invalidate_func.test
@@ -60,6 +60,8 @@ INSERT INTO t1 VALUES(1, 'val1');
INSERT INTO t1 VALUES(2, 'val2');
INSERT INTO t1 VALUES(3, 'val3');
+CREATE VIEW v1 AS SELECT * FROM t1;
+
#
# Clearing the query cache and setting up cache size
#
@@ -99,7 +101,7 @@ SELECT * FROM t1;
SHOW STATUS LIKE 'Qcache_queries_in_cache';
--echo 1 Expected
-LOCK TABLE t1 WRITE;
+LOCK TABLE v1 WRITE;
UNLOCK TABLES;
@@ -127,7 +129,7 @@ SELECT * FROM t1;
--echo ** Connection con0 **
connection con0;
-LOCK TABLE t1 WRITE;
+LOCK TABLE v1 WRITE;
--echo ** Connection con1 **
connection con1;
@@ -139,7 +141,7 @@ send SELECT * FROM t1;
connection con0;
--echo wait until table is locked
-let $wait_condition= SELECT count(*) > 0 FROM information_schema.processlist WHERE state= 'Locked';
+let $wait_condition= SELECT count(*) > 0 FROM information_schema.processlist WHERE state= 'Table lock';
--source include/wait_condition.inc
UNLOCK TABLES;
@@ -175,7 +177,7 @@ SELECT * FROM t1;
SHOW STATUS LIKE 'Qcache_queries_in_cache';
--echo 1 Expected
-LOCK TABLE t1 WRITE;
+LOCK TABLE v1 WRITE;
UNLOCK TABLES;
@@ -199,7 +201,7 @@ SELECT * FROM t1;
--echo ** Connection con0 **
connection con0;
-LOCK TABLE t1 WRITE;
+LOCK TABLE v1 WRITE;
--echo ** Connection con1 **
connection con1;
@@ -281,6 +283,7 @@ disconnect con0;
disconnect con1;
DROP TABLE t1;
+DROP VIEW v1;
--enable_ps_protocol
diff --git a/mysql-test/suite/sys_vars/t/rpl_semi_sync_master_enabled_basic.test b/mysql-test/suite/sys_vars/t/rpl_semi_sync_master_enabled_basic.test
index 749695e035c..43954d6441d 100644
--- a/mysql-test/suite/sys_vars/t/rpl_semi_sync_master_enabled_basic.test
+++ b/mysql-test/suite/sys_vars/t/rpl_semi_sync_master_enabled_basic.test
@@ -5,6 +5,7 @@
# 2010-01-21 OBN - Added
#
#
+source include/not_embedded.inc;
source include/have_semisync_plugin.inc;
# The following is to prevent a mis-match on windows that has the name of of the lib ending with 'dll'
--replace_regex /\.dll/.so/
diff --git a/mysql-test/suite/sys_vars/t/rpl_semi_sync_master_timeout_basic.test b/mysql-test/suite/sys_vars/t/rpl_semi_sync_master_timeout_basic.test
index 16389c23d54..0d085412a00 100644
--- a/mysql-test/suite/sys_vars/t/rpl_semi_sync_master_timeout_basic.test
+++ b/mysql-test/suite/sys_vars/t/rpl_semi_sync_master_timeout_basic.test
@@ -4,6 +4,7 @@
#
# 2010-01-21 OBN - Added
#
+source include/not_embedded.inc;
source include/have_semisync_plugin.inc;
# The following is to prevent a mis-match on windows that has the name of of the lib ending with 'dll'
--replace_regex /\.dll/.so/
diff --git a/mysql-test/suite/sys_vars/t/rpl_semi_sync_master_trace_level_basic.test b/mysql-test/suite/sys_vars/t/rpl_semi_sync_master_trace_level_basic.test
index c23aa1da688..c3f538f8dba 100644
--- a/mysql-test/suite/sys_vars/t/rpl_semi_sync_master_trace_level_basic.test
+++ b/mysql-test/suite/sys_vars/t/rpl_semi_sync_master_trace_level_basic.test
@@ -4,6 +4,7 @@
#
# 2010-01-21 OBN - Added
#
+source include/not_embedded.inc;
source include/have_semisync_plugin.inc;
# The following is to prevent a mis-match on windows that has the name of of the lib ending with 'dll'
--replace_regex /\.dll/.so/
diff --git a/mysql-test/suite/sys_vars/t/rpl_semi_sync_master_wait_no_slave_basic.test b/mysql-test/suite/sys_vars/t/rpl_semi_sync_master_wait_no_slave_basic.test
index 9686a0e0d9a..1db772dec61 100644
--- a/mysql-test/suite/sys_vars/t/rpl_semi_sync_master_wait_no_slave_basic.test
+++ b/mysql-test/suite/sys_vars/t/rpl_semi_sync_master_wait_no_slave_basic.test
@@ -5,6 +5,7 @@
# 2010-01-21 OBN - Added
#
#
+source include/not_embedded.inc;
source include/have_semisync_plugin.inc;
# The following is to prevent a mis-match on windows that has the name of of the lib ending with 'dll'
--replace_regex /\.dll/.so/
diff --git a/mysql-test/suite/sys_vars/t/rpl_semi_sync_slave_enabled_basic.test b/mysql-test/suite/sys_vars/t/rpl_semi_sync_slave_enabled_basic.test
index 0bb16cfd38e..565139456db 100644
--- a/mysql-test/suite/sys_vars/t/rpl_semi_sync_slave_enabled_basic.test
+++ b/mysql-test/suite/sys_vars/t/rpl_semi_sync_slave_enabled_basic.test
@@ -5,6 +5,7 @@
# 2010-01-21 OBN - Added
#
#
+source include/not_embedded.inc;
source include/have_semisync_plugin.inc;
# The following is to prevent a mis-match on windows that has the name of of the lib ending with 'dll'
--replace_regex /\.dll/.so/
diff --git a/mysql-test/suite/sys_vars/t/rpl_semi_sync_slave_trace_level_basic.test b/mysql-test/suite/sys_vars/t/rpl_semi_sync_slave_trace_level_basic.test
index 2bdf09f2a7f..ac88593f02f 100644
--- a/mysql-test/suite/sys_vars/t/rpl_semi_sync_slave_trace_level_basic.test
+++ b/mysql-test/suite/sys_vars/t/rpl_semi_sync_slave_trace_level_basic.test
@@ -4,6 +4,7 @@
#
# 2010-01-21 OBN - Added
#
+source include/not_embedded.inc;
source include/have_semisync_plugin.inc;
# The following is to prevent a mis-match on windows that has the name of of the lib ending with 'dll'
--replace_regex /\.dll/.so/
diff --git a/mysql-test/suite/sys_vars/t/sql_low_priority_updates_func.test b/mysql-test/suite/sys_vars/t/sql_low_priority_updates_func.test
index 2ef6e34b0b3..87813a958e0 100644
--- a/mysql-test/suite/sys_vars/t/sql_low_priority_updates_func.test
+++ b/mysql-test/suite/sys_vars/t/sql_low_priority_updates_func.test
@@ -46,6 +46,7 @@ SET @session_low_priority_updates = @@SESSION.low_priority_updates;
#
CREATE TABLE t1 (a varchar(100));
+create view v1 as select * from t1;
--echo '#--------------------FN_DYNVARS_160_01-------------------------#'
#
@@ -69,7 +70,7 @@ INSERT INTO t1 VALUES('4');
INSERT INTO t1 VALUES('5');
INSERT INTO t1 VALUES('6');
-LOCK TABLE t1 WRITE;
+LOCK TABLE v1 WRITE;
--echo ** Connection con1 **
connection con1;
@@ -85,7 +86,7 @@ delimiter ;|
--echo ** Connection con0 **
connection con0;
-let $wait_condition = SELECT COUNT(*) > 0 FROM information_schema.processlist WHERE state='Locked' AND info LIKE 'UPDATE t1 SET a = CONCAT(a,"-updated")';
+let $wait_condition = SELECT COUNT(*) > 0 FROM information_schema.processlist WHERE state='Table lock' AND info LIKE 'UPDATE t1 SET a = CONCAT(a,"-updated")';
--source include/wait_condition.inc
--echo ** Asynchronous Execution **
@@ -101,7 +102,7 @@ delimiter ;|
--echo ** Connection default **
connection default;
-let $wait_condition= SELECT count(*) = 2 FROM information_schema.processlist WHERE state LIKE 'Locked';
+let $wait_condition= SELECT count(*) = 2 FROM information_schema.processlist WHERE state LIKE 'Table lock';
--source include/wait_condition.inc
UNLOCK TABLES;
@@ -139,7 +140,7 @@ INSERT INTO t1 VALUES('4');
INSERT INTO t1 VALUES('5');
INSERT INTO t1 VALUES('6');
-LOCK TABLE t1 WRITE;
+LOCK TABLE v1 WRITE;
--echo ** Connection con1 **
connection con1;
@@ -155,7 +156,7 @@ delimiter ;|
--echo ** Connection con0 **
connection con0;
-let $wait_condition = SELECT COUNT(*) > 0 FROM information_schema.processlist WHERE state='Locked' AND info LIKE 'UPDATE t1 SET a = CONCAT(a,"-updated")';
+let $wait_condition = SELECT COUNT(*) > 0 FROM information_schema.processlist WHERE state='Table lock' AND info LIKE 'UPDATE t1 SET a = CONCAT(a,"-updated")';
--source include/wait_condition.inc
--echo ** Asynchronous Execution **
@@ -171,7 +172,7 @@ delimiter ;|
--echo ** Connection default **
connection default;
-let $wait_condition= SELECT count(*) = 2 FROM information_schema.processlist WHERE state LIKE 'Locked';
+let $wait_condition= SELECT count(*) = 2 FROM information_schema.processlist WHERE state LIKE 'Table lock';
--source include/wait_condition.inc
UNLOCK TABLES;
@@ -238,6 +239,7 @@ connection default;
disconnect con0;
disconnect con1;
+drop view v1;
DROP TABLE t1;
SET @@GLOBAL.low_priority_updates = @global_low_priority_updates;
diff --git a/mysql-test/suite/sys_vars/t/table_lock_wait_timeout_basic.test b/mysql-test/suite/sys_vars/t/table_lock_wait_timeout_basic.test
deleted file mode 100644
index f33e5660c5d..00000000000
--- a/mysql-test/suite/sys_vars/t/table_lock_wait_timeout_basic.test
+++ /dev/null
@@ -1,171 +0,0 @@
-############## mysql-test\t\table_lock_wait_timeout_basic.test ################
-# #
-# Variable Name: table_lock_wait _timeout #
-# Scope: GLOBAL #
-# Access Type: Dynamic #
-# Data Type: numeric #
-# Default Value: 50 #
-# Range: 1-1073741824 #
-# #
-# #
-# Creation Date: 2008-02-14 #
-# Author: Salman #
-# #
-# Description: Test Cases of Dynamic System Variable table_lock_wait_timeout #
-# that checks the behavior of this variable in the following ways#
-# * Default Value #
-# * Valid & Invalid values #
-# * Scope & Access method #
-# * Data Integrity #
-# #
-# Reference: http://dev.mysql.com/doc/refman/5.1/en/ #
-# server-system-variables.html#option_mysqld_table_lock_wait_timeout #
-# #
-###############################################################################
-
---source include/load_sysvars.inc
-########################################################################
-# START OF table_lock_wait_timeout TESTS #
-########################################################################
-
-
-##########################################################################
-# Saving initial value of table_lock_wait_timeout in a temporary variable#
-##########################################################################
-
-SET @start_value = @@global.table_lock_wait_timeout;
-SELECT @start_value;
-
-
---echo '#--------------------FN_DYNVARS_001_01------------------------#'
-########################################################################
-# Display the DEFAULT value of table_lock_wait_timeout #
-########################################################################
-
-SET @@global.table_lock_wait_timeout = 99;
-SET @@global.table_lock_wait_timeout = DeFAULT;
-SELECT @@global.table_lock_wait_timeout;
-
-
---echo '#---------------------FN_DYNVARS_001_02-------------------------#'
-###############################################
-# Verify default value of variable #
-###############################################
-
-SET @@global.table_lock_wait_timeout =Default;
-SELECT @@global.table_lock_wait_timeout = 50;
-
---echo '#--------------------FN_DYNVARS_001_03------------------------#'
-########################################################################
-# Change the value of table_lock_wait_timeout to a valid value #
-########################################################################
-
-
-SET @@global.table_lock_wait_timeout = 8;
-SELECT @@global.table_lock_wait_timeout ;
-
-SET @@global.table_lock_wait_timeout = 1;
-SELECT @@global.table_lock_wait_timeout ;
-SET @@global.table_lock_wait_timeout = 1073741824;
-SELECT @@global.table_lock_wait_timeout ;
-SET @@global.table_lock_wait_timeout = 18000;
-SELECT @@global.table_lock_wait_timeout ;
-SET @@global.table_lock_wait_timeout = 65535;
-SELECT @@global.table_lock_wait_timeout ;
-
-
-
---echo '#--------------------FN_DYNVARS_001_04-------------------------#'
-#########################################################################
-# Change the value of table_lock_wait_timeout to invalid value #
-#########################################################################
-
-SET @@global.table_lock_wait_timeout = -1;
-
-SET @@global.table_lock_wait_timeout= 100000000000;
-
-SET @@global.table_lock_wait_timeout= -1024;
-
-SET @@global.table_lock_wait_timeout= 0;
-
---Error ER_WRONG_TYPE_FOR_VAR
-SET @@global.table_lock_wait_timeout= 10000.01;
-
---Error ER_WRONG_TYPE_FOR_VAR
-SET @@global.table_lock_wait_timeout= ON;
---Error ER_WRONG_TYPE_FOR_VAR
-SET @@global.table_lock_wait_timeout= 'test';
-
---Error ER_WRONG_TYPE_FOR_VAR
-SET @@global.table_lock_wait_timeout= '';
-
-
---echo '#-------------------FN_DYNVARS_001_05----------------------------#'
-###########################################################################
-# Test if accessing session table_lock_wait_timeout gives error #
-###########################################################################
-
---Error ER_GLOBAL_VARIABLE
-SET @@session.table_lock_wait_timeout= 0;
-SELECT @@table_lock_wait_timeout;
-
-
---echo '#----------------------FN_DYNVARS_001_06------------------------#'
-##############################################################################
-# Check if the value in GLOBAL & SESSION Tables matches values in variable #
-##############################################################################
-
-SELECT @@global.table_lock_wait_timeout= VARIABLE_VALUE
-FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES
-WHERE VARIABLE_NAME='table_lock_wait_timeout';
-
-
---echo '#---------------------FN_DYNVARS_001_09----------------------#'
-###################################################################
-# Check if TRUE and FALSE values can be used on variable #
-###################################################################
-
-SET @@global.table_lock_wait_timeout= TRUE;
-SELECT @@global.table_lock_wait_timeout;
-
-SET @@global.table_lock_wait_timeout= FALSE;
-SELECT @@global.table_lock_wait_timeout;
-
-
---echo '#---------------------FN_DYNVARS_001_10----------------------#'
-###############################################################################
-# Check if accessing variable without SCOPE points to same global variable #
-###############################################################################
-
-SET @@global.table_lock_wait_timeout= 10;
-SELECT @@table_lock_wait_timeout= @@global.table_lock_wait_timeout;
-
-
---echo '#---------------------FN_DYNVARS_001_11----------------------#'
-###############################################################################
-# Check if table_lock_wait_timeout can be accessed with and without @@ sign #
-###############################################################################
-
---Error ER_GLOBAL_VARIABLE
-SET table_lock_wait_timeout= 8;
---Error ER_PARSE_ERROR
-SET global.table_lock_wait_timeout= 10;
---Error ER_UNKNOWN_TABLE
-SELECT global.table_lock_wait_timeout;
---Error ER_BAD_FIELD_ERROR
-SELECT table_lock_wait_timeout= @@session.table_lock_wait_timeout;
-
-
-##############################
-# Restore initial value #
-##############################
-
-SET @@global.table_lock_wait_timeout= @start_value;
-SELECT @@global.table_lock_wait_timeout;
-
-
-########################################################################
-# END OF table_lock_wait_timeout TESTS #
-########################################################################
-
-
diff --git a/mysql-test/t/create.test b/mysql-test/t/create.test
index 6c4048a7739..e0a6fde1381 100644
--- a/mysql-test/t/create.test
+++ b/mysql-test/t/create.test
@@ -683,8 +683,8 @@ drop table t1;
# Error during open_and_lock_tables() of tables
--error ER_NO_SUCH_TABLE
create table t1 select * from t2;
-# Rather special error which also caught during open tables pahse
---error ER_UPDATE_TABLE_USED
+# A special case which is also caught during open tables pahse
+--error ER_NO_SUCH_TABLE
create table t1 select * from t1;
# Error which happens before select_create::prepare()
--error ER_CANT_AGGREGATE_2COLLATIONS
@@ -706,6 +706,10 @@ create table t1 (i int);
create table t1 select 1 as i;
create table if not exists t1 select 1 as i;
select * from t1;
+# Error which is detected after successfull table open.
+--error ER_UPDATE_TABLE_USED
+create table if not exists t1 select * from t1;
+select * from t1;
# Error before select_create::prepare()
--error ER_CANT_AGGREGATE_2COLLATIONS
create table t1 select coalesce('a' collate latin1_swedish_ci,'b' collate latin1_bin);
@@ -1634,3 +1638,33 @@ END ;|
DROP TABLE t1;
DROP TABLE B;
+
+
+--echo #
+--echo # Bug #47107 assert in notify_shared_lock on incorrect
+--echo # CREATE TABLE , HANDLER
+--echo #
+
+--disable_warnings
+DROP TABLE IF EXISTS t1;
+--enable_warnings
+
+CREATE TABLE t1(f1 integer);
+
+--echo # The following CREATE TABLEs before gave an assert.
+
+HANDLER t1 OPEN AS A;
+--error ER_TABLE_EXISTS_ERROR
+CREATE TABLE t1 SELECT 1 AS f2;
+
+HANDLER t1 OPEN AS A;
+--error ER_TABLE_EXISTS_ERROR
+CREATE TABLE t1(f1 integer);
+
+CREATE TABLE t2(f1 integer);
+HANDLER t1 OPEN AS A;
+--error ER_TABLE_EXISTS_ERROR
+CREATE TABLE t1 LIKE t2;
+
+DROP TABLE t2;
+DROP TABLE t1;
diff --git a/mysql-test/t/debug_sync.test b/mysql-test/t/debug_sync.test
index 514e471b603..ebeeec61632 100644
--- a/mysql-test/t/debug_sync.test
+++ b/mysql-test/t/debug_sync.test
@@ -390,7 +390,7 @@ DROP TABLE IF EXISTS t1;
#
# Test.
CREATE TABLE t1 (c1 INT);
-LOCK TABLE t1 WRITE;
+LOCK TABLE t1 READ;
--echo connection con1
connect (con1,localhost,root,,);
# Retain action after use. First used by general_log.
diff --git a/mysql-test/t/delayed.test b/mysql-test/t/delayed.test
index d1e9bc154f5..142f1b241d6 100644
--- a/mysql-test/t/delayed.test
+++ b/mysql-test/t/delayed.test
@@ -307,7 +307,7 @@ connection update;
connection default;
let $wait_condition=
select count(*) = 1 from information_schema.processlist
- where command = "Delayed insert" and state = "upgrading lock";
+ where command = "Delayed insert" and state = "Table lock";
--source include/wait_condition.inc
connect (select,localhost,root,,);
--echo connection: select
diff --git a/mysql-test/t/disabled.def b/mysql-test/t/disabled.def
index 97237d5da73..3b34ef368e1 100644
--- a/mysql-test/t/disabled.def
+++ b/mysql-test/t/disabled.def
@@ -10,7 +10,8 @@
#
##############################################################################
kill : Bug#37780 2008-12-03 HHunger need some changes to be robust enough for pushbuild.
-query_cache_28249 : Bug#43861 2009-03-25 main.query_cache_28249 fails sporadicallyr
+query_cache_28249 : Bug#43861 2009-03-25 main.query_cache_28249 fails sporadically
+sp_sync : Bug#48157 2010-02-06 5.5-m3 demands a differnt solution
innodb-autoinc : Bug#49267 2009-12-02 test fails on windows because of different case mode
innodb : Bug#49396 2009-12-03 test fails in embedded mode
plugin_load : Bug#42144 2009-12-21 alik plugin_load fails
diff --git a/mysql-test/t/drop.test b/mysql-test/t/drop.test
index 4aeb7165bcb..5ef4a28b202 100644
--- a/mysql-test/t/drop.test
+++ b/mysql-test/t/drop.test
@@ -100,8 +100,8 @@ drop database if exists mysqltest;
drop table if exists t1;
--enable_warnings
create table t1 (i int);
-lock tables t1 read;
create database mysqltest;
+lock tables t1 read;
connect (addconroot1, localhost, root,,);
--send drop table t1
connect (addconroot2, localhost, root,,);
diff --git a/mysql-test/t/drop_debug.test b/mysql-test/t/drop_debug.test
index 97ee5847d0a..63c85d9246b 100644
--- a/mysql-test/t/drop_debug.test
+++ b/mysql-test/t/drop_debug.test
@@ -17,11 +17,14 @@ DROP DATABASE IF EXISTS mysql_test;
--echo
CREATE DATABASE mysql_test;
CREATE TABLE mysql_test.t1(a INT);
+CREATE TABLE mysql_test.t2(b INT);
+CREATE TABLE mysql_test.t3(c INT);
--echo
SET SESSION DEBUG = "+d,bug43138";
--echo
+--sorted_result
DROP DATABASE mysql_test;
--echo
diff --git a/mysql-test/t/flush.test b/mysql-test/t/flush.test
index f27d4cf2fad..d41ac3100b0 100644
--- a/mysql-test/t/flush.test
+++ b/mysql-test/t/flush.test
@@ -68,10 +68,13 @@ drop table t1;
create table t1 (c1 int);
lock table t1 write;
# Cannot get the global read lock with write locked tables.
---error 1192
+--error ER_LOCK_OR_ACTIVE_TRANSACTION
flush tables with read lock;
lock table t1 read;
-# Can get the global read lock with read locked tables.
+# Cannot get the global read lock with read locked tables.
+--error ER_LOCK_OR_ACTIVE_TRANSACTION
+flush tables with read lock;
+unlock tables;
flush tables with read lock;
--error 1223
lock table t1 write;
@@ -84,12 +87,12 @@ create table t2 (c1 int);
create table t3 (c1 int);
lock table t1 read, t2 read, t3 write;
# Cannot get the global read lock with write locked tables.
---error 1192
+--error ER_LOCK_OR_ACTIVE_TRANSACTION
flush tables with read lock;
lock table t1 read, t2 read, t3 read;
-# Can get the global read lock with read locked tables.
+# Cannot get the global read lock with read locked tables.
+--error ER_LOCK_OR_ACTIVE_TRANSACTION
flush tables with read lock;
-# Release all table locks and the global read lock.
unlock tables;
drop table t1, t2, t3;
@@ -157,6 +160,7 @@ flush tables with read lock;
unlock tables;
lock tables t1 read;
+--error ER_LOCK_OR_ACTIVE_TRANSACTION
flush tables with read lock;
unlock tables;
@@ -199,3 +203,24 @@ set global general_log= @old_general_log;
set global read_only= @old_read_only;
--echo End of 5.1 tests
+
+
+--echo #
+--echo # Additional test for bug #51136 "Crash in pthread_rwlock_rdlock
+--echo # on TEMPORARY + HANDLER + LOCK + SP".
+--echo # Also see the main test for this bug in include/handler.inc.
+--echo #
+--disable_warnings
+drop tables if exists t1, t2;
+--enable_warnings
+create table t1 (i int);
+create temporary table t2 (j int);
+flush tables with read lock;
+lock table t2 read;
+--echo # This commit should not release any MDL locks.
+commit;
+--echo # The below statement crashed before the bug fix as it
+--echo # has attempted to release global shared metadata lock
+--echo # which was already released by commit.
+unlock tables;
+drop tables t1, t2;
diff --git a/mysql-test/t/flush_block_commit.test b/mysql-test/t/flush_block_commit.test
index 74892def63f..0b3bede1684 100644
--- a/mysql-test/t/flush_block_commit.test
+++ b/mysql-test/t/flush_block_commit.test
@@ -6,7 +6,7 @@
# And it requires InnoDB
--source include/have_innodb.inc
-# Save the initial number of concurrent sessions
+--echo # Save the initial number of concurrent sessions
--source include/count_sessions.inc
--echo # Establish connection con1 (user=root)
@@ -30,18 +30,24 @@ INSERT INTO t1 VALUES(1);
--echo # Switch to connection con2
connection con2;
FLUSH TABLES WITH READ LOCK;
-SELECT * FROM t1;
--echo # Switch to connection con1
connection con1;
-send COMMIT; # blocked by con2
-sleep 1;
+--echo # Sending:
+--send COMMIT
--echo # Switch to connection con2
connection con2;
-SELECT * FROM t1; # verify con1 was blocked and data did not move
+--echo # Wait until COMMIT gets blocked.
+let $wait_condition=
+ select count(*) = 1 from information_schema.processlist
+ where state = "Waiting for release of readlock" and info = "COMMIT";
+--source include/wait_condition.inc
+--echo # Verify that 'con1' was blocked and data did not move.
+SELECT * FROM t1;
UNLOCK TABLES;
--echo # Switch to connection con1
connection con1;
-reap;
+--echo # Reaping COMMIT
+--reap
# No deadlock ?
@@ -63,6 +69,7 @@ COMMIT; # should not be blocked by con3
--echo # Switch to connection con2
connection con2;
reap;
+COMMIT;
--echo # Switch to connection con3
connection con3;
reap;
@@ -79,8 +86,6 @@ connection con1;
BEGIN;
INSERT INTO t1 VALUES(10);
FLUSH TABLES WITH READ LOCK;
-COMMIT;
-UNLOCK TABLES;
--echo # Switch to connection con2
connection con2;
FLUSH TABLES WITH READ LOCK; # bug caused hang here
@@ -91,19 +96,21 @@ UNLOCK TABLES;
BEGIN;
SELECT * FROM t1;
SHOW CREATE DATABASE test;
-
-DROP TABLE t1;
+COMMIT;
-# Cleanup
+--echo # Cleanup
--echo # Switch to connection default and close connections con1, con2, con3
connection default;
disconnect con1;
disconnect con2;
disconnect con3;
-# End of 4.1 tests
+--echo # We commit open transactions when we disconnect: only then we can
+--echo # drop the table.
+DROP TABLE t1;
+--echo # End of 4.1 tests
-# Wait till all disconnects are completed
+--echo # Wait till all disconnects are completed
--source include/wait_until_count_sessions.inc
diff --git a/mysql-test/t/flush_block_commit_notembedded.test b/mysql-test/t/flush_block_commit_notembedded.test
index aea38250218..d7ffbd475b4 100644
--- a/mysql-test/t/flush_block_commit_notembedded.test
+++ b/mysql-test/t/flush_block_commit_notembedded.test
@@ -9,7 +9,7 @@
--source include/have_log_bin.inc
--source include/have_innodb.inc
-# Save the initial number of concurrent sessions
+--echo # Save the initial number of concurrent sessions
--source include/count_sessions.inc
@@ -24,14 +24,14 @@ connection con1;
CREATE TABLE t1 (a INT) ENGINE=innodb;
RESET MASTER;
SET AUTOCOMMIT=0;
-INSERT t1 VALUES (1);
+SELECT 1;
--echo # Switch to connection con2
connection con2;
FLUSH TABLES WITH READ LOCK;
SHOW MASTER STATUS;
--echo # Switch to connection con1
connection con1;
-send COMMIT;
+send INSERT INTO t1 VALUES (1);
--echo # Switch to connection con2
connection con2;
sleep 1;
@@ -43,11 +43,30 @@ reap;
DROP TABLE t1;
SET AUTOCOMMIT=1;
+# GLR blocks new transactions
+create table t1 (a int) engine=innodb;
+connection con1;
+flush tables with read lock;
+connection con2;
+begin;
+--send insert into t1 values (1);
+connection con1;
+let $wait_condition=
+ select count(*) = 1 from information_schema.processlist
+ where state = "Waiting for release of readlock" and
+ info = "insert into t1 values (1)";
+--source include/wait_condition.inc
+unlock tables;
+connection con2;
+--reap
+commit;
+drop table t1;
+
--echo # Switch to connection default and close connections con1 and con2
connection default;
disconnect con1;
disconnect con2;
-# Wait till all disconnects are completed
+--echo # Wait till all disconnects are completed
--source include/wait_until_count_sessions.inc
diff --git a/mysql-test/t/flush_table.test b/mysql-test/t/flush_table.test
index 50e7e91419a..e4fc1b0c39f 100644
--- a/mysql-test/t/flush_table.test
+++ b/mysql-test/t/flush_table.test
@@ -15,30 +15,21 @@ insert into t1 values(0);
# Test for with read lock + flush
lock table t1 read;
+--error ER_TABLE_NOT_LOCKED_FOR_WRITE
flush table t1;
-check table t1;
unlock tables;
-# Test for with 2 read lock in different thread + flush
+# Test for with write lock + flush
-lock table t1 read;
-connect (locker,localhost,root,,test);
-connection locker;
-lock table t1 read;
-connection default;
-send flush table t1;
-connection locker;
---sleep 2
-select * from t1;
-unlock tables;
-connection default;
-reap;
-select * from t1;
+lock table t1 write;
+flush table t1;
+check table t1;
unlock tables;
# Test for with a write lock and a waiting read lock + flush
lock table t1 write;
+connect (locker,localhost,root,,test);
connection locker;
send lock table t1 read;
connection default;
@@ -51,9 +42,9 @@ reap;
unlock tables;
connection default;
-# Test for with a read lock and a waiting write lock + flush
+# Test for with a write lock and a waiting write lock + flush
-lock table t1 read;
+lock table t1 write;
connection locker;
send lock table t1 write;
connection default;
diff --git a/mysql-test/t/implicit_commit.test b/mysql-test/t/implicit_commit.test
new file mode 100644
index 00000000000..d8ffd6e9452
--- /dev/null
+++ b/mysql-test/t/implicit_commit.test
@@ -0,0 +1,1162 @@
+source include/have_innodb.inc;
+source include/not_embedded.inc;
+
+SET GLOBAL EVENT_SCHEDULER = OFF;
+SET BINLOG_FORMAT = STATEMENT;
+
+LET $OLD_DB= `SELECT DATABASE()`;
+
+CREATE DATABASE db1;
+USE db1;
+CREATE TABLE t1 (a INT, KEY a(a)) ENGINE=INNODB;
+INSERT INTO t1 VALUES (1),(2),(3),(4),(5);
+CREATE TABLE t3 (a INT) ENGINE=MyISAM;
+INSERT INTO t3 SELECT * FROM t1;
+CREATE TABLE trans (a INT) ENGINE=INNODB;
+
+DELIMITER |;
+
+CREATE PROCEDURE test_if_commit()
+BEGIN
+ ROLLBACK;
+ SELECT IF (COUNT(*) > 0, "YES", "NO") AS "IMPLICIT COMMIT" FROM trans;
+ DELETE FROM trans;
+ COMMIT;
+END|
+
+DELIMITER ;|
+
+SET AUTOCOMMIT = FALSE;
+
+--echo #
+--echo # SQLCOM_SELECT
+--echo #
+
+let $statement=
+ select 1 as res from t1 where (1) in (select * from t1);
+source include/implicit_commit_helper.inc;
+
+--echo #
+--echo # SQLCOM_CREATE_TABLE LIKE
+--echo #
+
+let $statement=
+ create table t2 like t1;
+source include/implicit_commit_helper.inc;
+
+--echo #
+--echo # SQLCOM_SHOW_CREATE
+--echo #
+
+let $statement=
+ show create table t2;
+source include/implicit_commit_helper.inc;
+
+--echo #
+--echo # SQLCOM_DROP_TABLE
+--echo #
+
+let $statement=
+ drop table t2;
+source include/implicit_commit_helper.inc;
+
+--echo #
+--echo # SQLCOM_CREATE_TABLE TEMPORARY
+--echo #
+
+let $statement=
+ create temporary table t2 as select * from t1;
+source include/implicit_commit_helper.inc;
+
+--echo #
+--echo # SQLCOM_DROP_TABLE TEMPORARY
+--echo #
+
+let $statement=
+ drop temporary table t2;
+source include/implicit_commit_helper.inc;
+
+--echo #
+--echo # SQLCOM_CREATE_TABLE
+--echo #
+
+let $statement=
+ create table t2 as select * from t1;
+source include/implicit_commit_helper.inc;
+
+--echo #
+--echo # SQLCOM_UPDATE
+--echo #
+
+let $statement=
+ update t2 set a=a+1 where (1) in (select * from t1);
+source include/implicit_commit_helper.inc;
+
+--echo #
+--echo # SQLCOM_INSERT
+--echo #
+
+let $statement=
+ insert into t2 set a=((1) in (select * from t1));
+source include/implicit_commit_helper.inc;
+
+--echo #
+--echo # SQLCOM_INSERT_SELECT
+--echo #
+
+let $statement=
+ insert into t2 select * from t1;
+source include/implicit_commit_helper.inc;
+
+--echo #
+--echo # SQLCOM_REPLACE
+--echo #
+
+let $statement=
+ replace t2 set a=((1) in (select * from t1));
+source include/implicit_commit_helper.inc;
+
+--echo #
+--echo # SQLCOM_REPLACE_SELECT
+--echo #
+
+let $statement=
+ replace t2 select * from t1;
+source include/implicit_commit_helper.inc;
+
+--echo #
+--echo # SQLCOM_DELETE
+--echo #
+
+let $statement=
+ delete from t2 where (1) in (select * from t1);
+source include/implicit_commit_helper.inc;
+
+--echo #
+--echo # SQLCOM_DELETE_MULTI
+--echo #
+
+let $statement=
+ delete t2, t3 from t2, t3 where (1) in (select * from t1);
+source include/implicit_commit_helper.inc;
+
+--echo #
+--echo # SQLCOM_UPDATE_MULTI
+--echo #
+
+select * from t2;
+let $statement=
+ update t2, t3 set t3.a=t2.a, t2.a=null where (1) in (select * from t1);
+source include/implicit_commit_helper.inc;
+
+--echo #
+--echo # SQLCOM_LOAD
+--echo #
+
+create table t4 (a varchar(100));
+
+let $statement=
+ load data infile '../../std_data/words.dat' into table t4;
+source include/implicit_commit_helper.inc;
+
+drop table t4;
+
+--echo #
+--echo # SQLCOM_SHOW_DATABASES
+--echo #
+
+let $statement=
+ show databases where (1) in (select * from t1);
+source include/implicit_commit_helper.inc;
+
+--echo #
+--echo # SQLCOM_SHOW_TABLES
+--echo #
+
+let $statement=
+ show tables where (1) in (select * from t1);
+source include/implicit_commit_helper.inc;
+
+--echo #
+--echo # SQLCOM_SHOW_FIELDS
+--echo #
+
+let $statement=
+ show fields from t1 where (1) in (select * from t1);
+source include/implicit_commit_helper.inc;
+
+--echo #
+--echo # SQLCOM_SHOW_KEYS
+--echo #
+
+let $statement=
+ show keys from t1 where (1) in (select * from t1);
+source include/implicit_commit_helper.inc;
+
+--echo #
+--echo # SQLCOM_SHOW_VARIABLES
+--echo #
+
+let $statement=
+ show variables where (1) in (select * from t1);
+source include/implicit_commit_helper.inc;
+
+--echo #
+--echo # SQLCOM_SHOW_STATUS
+--echo #
+
+let $statement=
+ show status where (1) in (select * from t1);
+source include/implicit_commit_helper.inc;
+
+--echo #
+--echo # SQLCOM_SHOW_ENGINE_MUTEX
+--echo #
+
+let $statement=
+ show engine all mutex;
+source include/implicit_commit_helper.inc;
+
+--echo #
+--echo # SQLCOM_SHOW_PROCESSLIST
+--echo #
+
+let $statement=
+ show processlist;
+source include/implicit_commit_helper.inc;
+
+--echo #
+--echo # SQLCOM_SHOW_ENGINE_LOGS
+--echo #
+
+let $statement=
+ show engine all logs;
+source include/implicit_commit_helper.inc;
+
+--echo #
+--echo # SQLCOM_SHOW_ENGINE_STATUS
+--echo #
+
+let $statement=
+ show engine all status;
+source include/implicit_commit_helper.inc;
+
+--echo #
+--echo # SQLCOM_SHOW_CHARSETS
+--echo #
+
+let $statement=
+ show charset where (1) in (select * from t1);
+source include/implicit_commit_helper.inc;
+
+--echo #
+--echo # SQLCOM_SHOW_COLLATIONS
+--echo #
+
+let $statement=
+ show collation where (1) in (select * from t1);
+source include/implicit_commit_helper.inc;
+
+--echo #
+--echo # SQLCOM_SHOW_TABLE_STATUS
+--echo #
+
+let $statement=
+ show table status where (1) in (select * from t1);
+source include/implicit_commit_helper.inc;
+
+--echo #
+--echo # SQLCOM_SHOW_TRIGGERS
+--echo #
+
+let $statement=
+ show triggers where (1) in (select * from t1);
+source include/implicit_commit_helper.inc;
+
+--echo #
+--echo # SQLCOM_SHOW_OPEN_TABLES
+--echo #
+
+let $statement=
+ show open tables where (1) in (select * from t1);
+source include/implicit_commit_helper.inc;
+
+--echo #
+--echo # SQLCOM_SHOW_STATUS_PROC
+--echo #
+
+let $statement=
+ show procedure status where (1) in (select * from t1);
+source include/implicit_commit_helper.inc;
+
+--echo #
+--echo # SQLCOM_SHOW_STATUS_FUNC
+--echo #
+
+let $statement=
+ show function status where (1) in (select * from t1);
+source include/implicit_commit_helper.inc;
+
+--echo #
+--echo # SQLCOM_SET_OPTION
+--echo #
+
+let $statement=
+ set @a=((1) in (select * from t1));
+source include/implicit_commit_helper.inc;
+
+--echo #
+--echo # SQLCOM_DO
+--echo #
+
+let $statement=
+ do ((1) in (select * from t1));
+source include/implicit_commit_helper.inc;
+
+--echo #
+--echo # SQLCOM_CALL
+--echo #
+
+create procedure p1(a int) begin end;
+
+let $statement=
+ call p1((1) in (select * from t1));
+source include/implicit_commit_helper.inc;
+
+drop procedure p1;
+
+--echo #
+--echo # SQLCOM_CREATE_VIEW
+--echo #
+
+let $statement=
+ create view v1 as select * from t1;
+source include/implicit_commit_helper.inc;
+
+--echo #
+--echo # SQLCOM_ALTER_VIEW
+--echo #
+
+let $statement=
+ alter view v1 as select 2;
+source include/implicit_commit_helper.inc;
+
+--echo #
+--echo # SQLCOM_DROP_VIEW
+--echo #
+
+let $statement=
+ drop view v1;
+source include/implicit_commit_helper.inc;
+
+--echo #
+--echo # SQLCOM_CREATE_INDEX
+--echo #
+
+let $statement=
+ create index idx1 on t1(a);
+source include/implicit_commit_helper.inc;
+
+--echo #
+--echo # SQLCOM_DROP_INDEX
+--echo #
+
+let $statement=
+ drop index idx1 on t1;
+source include/implicit_commit_helper.inc;
+
+--echo #
+--echo # SQLCOM_ALTER_TABLE
+--echo #
+
+let $statement=
+ alter table t1 add column b int;
+source include/implicit_commit_helper.inc;
+
+let $statement=
+ alter table t1 change b c int;
+source include/implicit_commit_helper.inc;
+
+let $statement=
+ alter table t1 drop column c;
+source include/implicit_commit_helper.inc;
+
+--echo #
+--echo # SQLCOM_ALTER_TABLE TEMPORARY
+--echo #
+
+create temporary table t4 (a int);
+
+let $statement=
+ alter table t1 add column b int;
+source include/implicit_commit_helper.inc;
+
+let $statement=
+ alter table t1 change b c int;
+source include/implicit_commit_helper.inc;
+
+let $statement=
+ alter table t1 drop column c;
+source include/implicit_commit_helper.inc;
+
+drop table t4;
+
+--echo #
+--echo # SQLCOM_TRUNCATE
+--echo #
+
+insert into t2 select * from t1;
+let $statement=
+ truncate table t2;
+source include/implicit_commit_helper.inc;
+insert into t2 select * from t1;
+
+--echo #
+--echo # SQLCOM_TRUNCATE TEMPORARY
+--echo #
+
+create temporary table t4 as select * from t1;
+let $statement=
+ truncate table t4;
+source include/implicit_commit_helper.inc;
+drop temporary table t4;
+
+--echo #
+--echo # SQLCOM_SHOW_MASTER_STAT
+--echo #
+
+let $statement=
+ show master status;
+source include/implicit_commit_helper.inc;
+
+--echo #
+--echo # SQLCOM_SHOW_SLAVE_STAT
+--echo #
+
+let $statement=
+ show slave status;
+source include/implicit_commit_helper.inc;
+
+--echo #
+--echo # SQLCOM_GRANT
+--echo #
+
+let $statement=
+ grant all on test.t1 to mysqltest_2@localhost with grant option;
+source include/implicit_commit_helper.inc;
+
+--echo #
+--echo # SQLCOM_REVOKE
+--echo #
+let $statement=
+ revoke select on test.t1 from mysqltest_2@localhost;
+source include/implicit_commit_helper.inc;
+
+--echo #
+--echo # SQLCOM_REVOKE_ALL
+--echo #
+
+let $statement=
+ revoke all on test.t1 from mysqltest_2@localhost;
+source include/implicit_commit_helper.inc;
+
+drop user mysqltest_2@localhost;
+
+--echo #
+--echo # SQLCOM_SHOW_GRANTS
+--echo #
+
+let $statement=
+ show grants;
+source include/implicit_commit_helper.inc;
+
+let $statement=
+ show grants for current_user();
+source include/implicit_commit_helper.inc;
+
+--echo #
+--echo # SQLCOM_LOCK_TABLES
+--echo #
+
+let $statement=
+ lock tables t1 write, trans write;
+source include/implicit_commit_helper.inc;
+
+--echo #
+--echo # SQLCOM_UNLOCK_TABLES
+--echo #
+
+let $statement=
+ unlock tables;
+source include/implicit_commit_helper.inc;
+
+#
+# Missing test for lock tables transactional.
+#
+
+--echo #
+--echo # SQLCOM_CREATE_DB
+--echo #
+
+let $statement=
+ create database db2;
+source include/implicit_commit_helper.inc;
+
+--echo #
+--echo # SQLCOM_CHANGE_DB
+--echo #
+
+create table db2.t1 (a int);
+insert into db2.t1 values (1);
+commit;
+
+let $statement=
+ use db2;
+source include/implicit_commit_helper.inc;
+
+--echo #
+--echo # SQLCOM_SHOW_CREATE_DB
+--echo #
+
+let $statement=
+ show create database db2;
+source include/implicit_commit_helper.inc;
+
+--echo #
+--echo # SQLCOM_ALTER_DB
+--echo #
+
+#let $statement=
+# alter database db2 character set koi8r;
+#source include/implicit_commit_helper.inc;
+
+#let $statement=
+# alter database db2 collate cp1251_general_cs;
+#source include/implicit_commit_helper.inc;
+
+--echo #
+--echo # SQLCOM_ALTER_DB_UPGRADE
+--echo #
+
+#let $statement=
+# alter database `#mysql50#db3` upgrade data directory name;
+#source include/implicit_commit_helper.inc;
+
+--echo #
+--echo # SQLCOM_DROP_DB
+--echo #
+
+use db1;
+
+let $statement=
+ drop database db2;
+source include/implicit_commit_helper.inc;
+
+--echo #
+--echo # SQLCOM_REPAIR
+--echo #
+
+let $statement=
+ repair table t2;
+source include/implicit_commit_helper.inc;
+
+let $statement=
+ repair table t2 use_frm;
+source include/implicit_commit_helper.inc;
+
+--echo #
+--echo # SQLCOM_OPTIMIZE
+--echo #
+
+let $statement=
+ optimize table t1;
+source include/implicit_commit_helper.inc;
+
+--echo #
+--echo # SQLCOM_CHECK
+--echo #
+
+let $statement=
+ check table t1;
+source include/implicit_commit_helper.inc;
+
+let $statement=
+ check table t1 extended;
+source include/implicit_commit_helper.inc;
+
+--echo #
+--echo # SQLCOM_ASSIGN_TO_KEYCACHE
+--echo #
+
+set global keycache.key_buffer_size=128*1024;
+
+let $statement=
+ cache index t3 in keycache;
+source include/implicit_commit_helper.inc;
+
+set global keycache.key_buffer_size=0;
+
+--echo #
+--echo # SQLCOM_PRELOAD_KEYS
+--echo #
+
+let $statement=
+ load index into cache t3;
+source include/implicit_commit_helper.inc;
+
+--echo #
+--echo # SQLCOM_FLUSH
+--echo #
+
+let $statement=
+ flush local privileges;
+source include/implicit_commit_helper.inc;
+
+let $statement=
+ flush privileges;
+source include/implicit_commit_helper.inc;
+
+--echo #
+--echo # SQLCOM_KILL
+--echo #
+
+--echo #
+--echo # SQLCOM_ANALYZE
+--echo #
+
+let $statement=
+ analyze table t1;
+source include/implicit_commit_helper.inc;
+
+--echo #
+--echo # SQLCOM_ROLLBACK
+--echo #
+
+let $statement=
+ rollback;
+source include/implicit_commit_helper.inc;
+
+--echo #
+--echo # SQLCOM_ROLLBACK_TO_SAVEPOINT
+--echo #
+
+
+--echo #
+--echo # SQLCOM_COMMIT
+--echo #
+
+let $statement=
+ commit;
+source include/implicit_commit_helper.inc;
+
+--echo #
+--echo # SQLCOM_SAVEPOINT
+--echo #
+
+let $statement=
+ savepoint sp1;
+source include/implicit_commit_helper.inc;
+
+--echo #
+--echo # SQLCOM_RELEASE_SAVEPOINT
+--echo #
+
+--echo #
+--echo # SQLCOM_SLAVE_START
+--echo #
+
+--echo #
+--echo # SQLCOM_SLAVE_STOP
+--echo #
+
+--echo #
+--echo # SQLCOM_BEGIN
+--echo #
+
+let $statement=
+ begin;
+source include/implicit_commit_helper.inc;
+
+--echo #
+--echo # SQLCOM_CHANGE_MASTER
+--echo #
+
+--echo #
+--echo # SQLCOM_RENAME_TABLE
+--echo #
+
+let $statement=
+ rename table t3 to t4;
+source include/implicit_commit_helper.inc;
+
+let $statement=
+ rename table t4 to t3;
+source include/implicit_commit_helper.inc;
+
+--echo #
+--echo # SQLCOM_RESET
+--echo #
+
+--echo #
+--echo # SQLCOM_PURGE
+--echo #
+
+--echo #
+--echo # SQLCOM_PURGE_BEFORE
+--echo #
+
+--echo #
+--echo # SQLCOM_SHOW_BINLOGS
+--echo #
+
+--echo #
+--echo # SQLCOM_HA_OPEN
+--echo #
+
+let $statement=
+ handler t1 open as ha1;
+source include/implicit_commit_helper.inc;
+
+--echo #
+--echo # SQLCOM_HA_READ
+--echo #
+
+let $statement=
+ handler ha1 read a first;
+source include/implicit_commit_helper.inc;
+
+--echo #
+--echo # SQLCOM_HA_CLOSE
+--echo #
+
+let $statement=
+ handler ha1 close;
+source include/implicit_commit_helper.inc;
+
+--echo #
+--echo # SQLCOM_SHOW_SLAVE_HOSTS
+--echo #
+
+let $statement=
+ show slave hosts;
+source include/implicit_commit_helper.inc;
+
+--echo #
+--echo # SQLCOM_SHOW_BINLOG_EVENTS
+--echo #
+
+let $statement=
+ show binlog events;
+source include/implicit_commit_helper.inc;
+
+--echo #
+--echo # SQLCOM_SHOW_NEW_MASTER
+--echo #
+
+--echo #
+--echo # SQLCOM_SHOW_WARNS
+--echo #
+
+let $statement=
+ show warnings;
+source include/implicit_commit_helper.inc;
+
+--echo #
+--echo # SQLCOM_EMPTY_QUERY
+--echo #
+
+--echo #
+--echo # SQLCOM_SHOW_ERRORS
+--echo #
+
+let $statement=
+ show errors;
+source include/implicit_commit_helper.inc;
+
+--echo #
+--echo # SQLCOM_SHOW_STORAGE_ENGINES
+--echo #
+
+let $statement=
+ show engines;
+source include/implicit_commit_helper.inc;
+
+--echo #
+--echo # SQLCOM_SHOW_PRIVILEGES
+--echo #
+
+let $statement=
+ show privileges;
+source include/implicit_commit_helper.inc;
+
+--echo #
+--echo # SQLCOM_HELP
+--echo #
+
+let $statement=
+ help 'foo';
+source include/implicit_commit_helper.inc;
+
+--echo #
+--echo # SQLCOM_CREATE_USER
+--echo #
+
+let $statement=
+ create user trxusr1;
+source include/implicit_commit_helper.inc;
+
+--echo #
+--echo # SQLCOM_RENAME_USER
+--echo #
+
+let $statement=
+ rename user 'trxusr1' to 'trxusr2';
+source include/implicit_commit_helper.inc;
+
+--echo #
+--echo # SQLCOM_DROP_USER
+--echo #
+
+let $statement=
+ drop user trxusr2;
+source include/implicit_commit_helper.inc;
+
+--echo #
+--echo # SQLCOM_CHECKSUM
+--echo #
+
+let $statement=
+ checksum table t1;
+source include/implicit_commit_helper.inc;
+
+--echo #
+--echo # SQLCOM_CREATE_PROCEDURE
+--echo #
+
+let $statement=
+ create procedure p1(a int) begin end;
+source include/implicit_commit_helper.inc;
+
+--echo #
+--echo # SQLCOM_ALTER_PROCEDURE
+--echo #
+
+let $statement=
+ alter procedure p1 comment 'foobar';
+source include/implicit_commit_helper.inc;
+
+--echo #
+--echo # SQLCOM_SHOW_CREATE_PROC
+--echo #
+
+let $statement=
+ show create procedure p1;
+source include/implicit_commit_helper.inc;
+
+--echo #
+--echo # SQLCOM_SHOW_STATUS_PROC
+--echo #
+
+let $statement=
+ show procedure status;
+source include/implicit_commit_helper.inc;
+
+--echo #
+--echo # SQLCOM_SHOW_PROC_CODE
+--echo #
+
+#
+# Available only on servers with debugging support.
+#
+
+--disable_abort_on_error
+let $statement=
+ show procedure code p1;
+source include/implicit_commit_helper.inc;
+--enable_abort_on_error
+
+--echo #
+--echo # SQLCOM_DROP_PROCEDURE
+--echo #
+
+let $statement=
+ drop procedure p1;
+source include/implicit_commit_helper.inc;
+
+--echo #
+--echo # SQLCOM_CREATE_FUNCTION
+--echo #
+
+--echo #
+--echo # SQLCOM_DROP_FUNCTION
+--echo #
+
+--echo #
+--echo # SQLCOM_CREATE_SPFUNCTION
+--echo #
+
+let $statement=
+ create function f1() returns int return 69;
+source include/implicit_commit_helper.inc;
+
+--echo #
+--echo # SQLCOM_ALTER_FUNCTION
+--echo #
+
+let $statement=
+ alter function f1 comment 'comment';
+source include/implicit_commit_helper.inc;
+
+--echo #
+--echo # SQLCOM_SHOW_CREATE_FUNC
+--echo #
+
+let $statement=
+ show create function f1;
+source include/implicit_commit_helper.inc;
+
+--echo #
+--echo # SQLCOM_SHOW_STATUS_FUNC
+--echo #
+
+let $statement=
+ show function status like '%f%';
+source include/implicit_commit_helper.inc;
+
+--echo #
+--echo # SQLCOM_SHOW_FUNC_CODE
+--echo #
+
+#
+# Available only on servers with debugging support.
+#
+
+--disable_abort_on_error
+let $statement=
+ show function code f1;
+source include/implicit_commit_helper.inc;
+--enable_abort_on_error
+
+--echo #
+--echo # SQLCOM_PREPARE
+--echo #
+
+let $statement=
+ prepare stmt1 from "insert into t1 values (5)";
+source include/implicit_commit_helper.inc;
+
+--echo #
+--echo # SQLCOM_EXECUTE
+--echo #
+
+let $statement=
+ execute stmt1;
+source include/implicit_commit_helper.inc;
+
+--echo #
+--echo # SQLCOM_DEALLOCATE_PREPARE
+--echo #
+
+let $statement=
+ deallocate prepare stmt1;
+source include/implicit_commit_helper.inc;
+
+--echo #
+--echo # SQLCOM_CREATE_TRIGGER
+--echo #
+
+let $statement=
+ create trigger trg1 before insert on t1 for each row set @a:=1;
+source include/implicit_commit_helper.inc;
+
+--echo #
+--echo # SQLCOM_SHOW_CREATE_TRIGGER
+--echo #
+
+let $statement=
+ show create trigger trg1;
+source include/implicit_commit_helper.inc;
+
+--echo #
+--echo # SQLCOM_DROP_TRIGGER
+--echo #
+
+let $statement=
+ drop trigger trg1;
+source include/implicit_commit_helper.inc;
+
+--echo #
+--echo # SQLCOM_XA_START
+--echo #
+
+--echo #
+--echo # SQLCOM_XA_END
+--echo #
+
+--echo #
+--echo # SQLCOM_XA_PREPARE
+--echo #
+
+--echo #
+--echo # SQLCOM_XA_COMMIT
+--echo #
+
+--echo #
+--echo # SQLCOM_XA_ROLLBACK
+--echo #
+
+--echo #
+--echo # SQLCOM_XA_RECOVER
+--echo #
+
+--echo #
+--echo # SQLCOM_ALTER_TABLESPACE
+--echo #
+
+--echo #
+--echo # SQLCOM_INSTALL_PLUGIN
+--echo #
+
+--echo #
+--echo # SQLCOM_SHOW_PLUGINS
+--echo #
+
+--echo #
+--echo # SQLCOM_UNINSTALL_PLUGIN
+--echo #
+
+--echo #
+--echo # SQLCOM_SHOW_AUTHORS
+--echo #
+
+let $statement=
+ show authors;
+source include/implicit_commit_helper.inc;
+
+--echo #
+--echo # SQLCOM_BINLOG_BASE64_EVENT
+--echo #
+
+--echo #
+--echo # SQLCOM_SHOW_CONTRIBUTORS
+--echo #
+
+let $statement=
+ show contributors;
+source include/implicit_commit_helper.inc;
+
+--echo #
+--echo # SQLCOM_CREATE_SERVER
+--echo #
+
+--echo #
+--echo # SQLCOM_ALTER_SERVER
+--echo #
+
+--echo #
+--echo # SQLCOM_DROP_SERVER
+--echo #
+
+--echo #
+--echo # SQLCOM_CREATE_EVENT
+--echo #
+
+let $statement=
+ create event ev1 on schedule every 1 second do insert into t1 values (6);
+source include/implicit_commit_helper.inc;
+
+--echo #
+--echo # SQLCOM_ALTER_EVENT
+--echo #
+
+let $statement=
+ alter event ev1 rename to ev2 disable;
+source include/implicit_commit_helper.inc;
+
+--echo #
+--echo # SQLCOM_SHOW_CREATE_EVENT
+--echo #
+
+let $statement=
+ show create event ev2;
+source include/implicit_commit_helper.inc;
+
+--echo #
+--echo # SQLCOM_SHOW_EVENTS
+--echo #
+
+let $statement=
+ show events;
+source include/implicit_commit_helper.inc;
+
+--echo #
+--echo # SQLCOM_DROP_EVENT
+--echo #
+
+let $statement=
+ drop event ev2;
+source include/implicit_commit_helper.inc;
+
+--echo #
+--echo # SQLCOM_BACKUP
+--echo #
+
+#create database backup_db;
+#
+#let $statement=
+# backup database db1 to 'backup_db1.ba';
+#source include/implicit_commit_helper.inc;
+
+--echo #
+--echo # SQLCOM_SHOW_ARCHIVE
+--echo #
+
+#
+# --error ER_NOT_ALLOWED_COMMAND
+#
+#let $statement=
+# show backup 'backup_db1.ba';
+#source include/implicit_commit_helper.inc;
+#
+
+--echo #
+--echo # SQLCOM_RESTORE
+--echo #
+
+#let $statement=
+# restore from 'backup_db1.ba';
+#source include/implicit_commit_helper.inc;
+
+#--remove_file $MYSQLTEST_VARDIR/master-data/backup_db1.ba
+#
+#drop database backup_db;
+
+--echo #
+--echo # SQLCOM_BACKUP_TEST
+--echo #
+
+# BACKUP_TEST
+
+--echo #
+--echo # SQLCOM_SHOW_PROFILE
+--echo #
+
+let $statement=
+ show profile memory;
+source include/implicit_commit_helper.inc;
+
+--echo #
+--echo # SQLCOM_SHOW_PROFILES
+--echo #
+
+let $statement=
+ show profiles;
+source include/implicit_commit_helper.inc;
+
+DROP TABLE t1;
+DROP TABLE t2;
+DROP TABLE t3;
+eval USE $OLD_DB;
+DROP DATABASE db1;
+
+--echo End of tests
diff --git a/mysql-test/t/information_schema.test b/mysql-test/t/information_schema.test
index cec93aeb0cb..456cacf2fe1 100644
--- a/mysql-test/t/information_schema.test
+++ b/mysql-test/t/information_schema.test
@@ -544,6 +544,7 @@ AND table_name not like 'ndb%' AND table_name not like 'innodb_%'
GROUP BY TABLE_SCHEMA;
+
#
# TRIGGERS table test
#
@@ -914,8 +915,8 @@ DROP PROCEDURE p1;
DROP USER mysql_bug20230@localhost;
#
-# Bug#2123 query with a simple non-correlated subquery over
-# INFORMARTION_SCHEMA.TABLES
+# Bug#21231 query with a simple non-correlated subquery over
+# INFORMARTION_SCHEMA.TABLES
#
SELECT MAX(table_name) FROM information_schema.tables WHERE table_schema IN ('mysql', 'INFORMATION_SCHEMA', 'test');
@@ -1418,9 +1419,66 @@ DROP DATABASE db1;
--echo End of 5.1 tests.
+--echo #
+--echo # Additional test for WL#3726 "DDL locking for all metadata objects"
+--echo # To avoid possible deadlocks process of filling of I_S tables should
+--echo # use high-priority metadata lock requests when opening tables.
+--echo # Below we just test that we really use high-priority lock request
+--echo # since reproducing a deadlock will require much more complex test.
+--echo #
+--disable_warnings
+drop tables if exists t1, t2, t3;
+--enable_warnings
+create table t1 (i int);
+create table t2 (j int primary key auto_increment);
+connect (con3726_1,localhost,root,,test);
+--echo # Switching to connection 'con3726_1'
+connection con3726_1;
+lock table t2 read;
+connect (con3726_2,localhost,root,,test);
+--echo # Switching to connection 'con3726_2'
+connection con3726_2;
+--echo # RENAME below will be blocked by 'lock table t2 read' above but
+--echo # will add two pending requests for exclusive metadata locks.
+--send rename table t2 to t3
+--echo # Switching to connection 'default'
+connection default;
+let $wait_condition=
+ select count(*) = 1 from information_schema.processlist
+ where state = "Waiting for table" and info like "rename table t2 to t3";
+--source include/wait_condition.inc
+--echo # These statements should not be blocked by pending lock requests
+select table_name, column_name, data_type from information_schema.columns
+ where table_schema = 'test' and table_name in ('t1', 't2');
+select table_name, auto_increment from information_schema.tables
+ where table_schema = 'test' and table_name in ('t1', 't2');
+--echo # Switching to connection 'con3726_1'
+connection con3726_1;
+unlock tables;
+--echo # Switching to connection 'con3726_2'
+connection con3726_2;
+--reap
+--echo # Switching to connection 'default'
+connection default;
+disconnect con3726_1;
+disconnect con3726_2;
+drop tables t1, t3;
+
+#
+# Bug#39270 I_S optimization algorithm does not work properly in some cases
+#
+EXPLAIN SELECT * FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE;
+EXPLAIN SELECT * FROM INFORMATION_SCHEMA.PARTITIONS WHERE TABLE_NAME='t1';
+EXPLAIN SELECT * FROM INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS
+ WHERE CONSTRAINT_SCHEMA='test';
+EXPLAIN SELECT * FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS
+ WHERE TABLE_NAME='t1' and TABLE_SCHEMA='test';
+EXPLAIN SELECT * FROM INFORMATION_SCHEMA.TRIGGERS
+ WHERE EVENT_OBJECT_SCHEMA='test';
+
#
# Bug#24062 Incorrect error msg after execute DROP TABLE IF EXISTS on information_schema
-#
+#
--error ER_DBACCESS_DENIED_ERROR
create table information_schema.t1 (f1 INT);
--error ER_DBACCESS_DENIED_ERROR
@@ -1456,27 +1514,18 @@ DROP TABLE t1, information_schema.tables;
LOCK TABLES t1 READ, information_schema.tables READ;
DROP TABLE t1;
-#
-# Bug#39270 I_S optimization algorithm does not work properly in some cases
-#
-EXPLAIN SELECT * FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE;
-EXPLAIN SELECT * FROM INFORMATION_SCHEMA.PARTITIONS WHERE TABLE_NAME='t1';
-EXPLAIN SELECT * FROM INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS
- WHERE CONSTRAINT_SCHEMA='test';
-EXPLAIN SELECT * FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS
- WHERE TABLE_NAME='t1' and TABLE_SCHEMA='test';
-EXPLAIN SELECT * FROM INFORMATION_SCHEMA.TRIGGERS
- WHERE EVENT_OBJECT_SCHEMA='test';
+# Wait till all disconnects are completed
+--source include/wait_until_count_sessions.inc
#
-# Bug #43834 Assertion in Natural_join_column::db_name() on an I_S query
+# Bug #43834 Assertion in Natural_join_column::db_name() on an I_S query
#
+
SELECT *
-FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE
-LEFT JOIN INFORMATION_SCHEMA.COLUMNS
-USING (TABLE_SCHEMA, TABLE_NAME, COLUMN_NAME)
-WHERE COLUMNS.TABLE_SCHEMA = 'test'
-AND COLUMNS.TABLE_NAME = 't1';
+FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE
+LEFT JOIN INFORMATION_SCHEMA.COLUMNS
+USING (TABLE_SCHEMA, TABLE_NAME, COLUMN_NAME)
+WHERE COLUMNS.TABLE_SCHEMA = 'test'
+AND COLUMNS.TABLE_NAME = 't1';
+
-# Wait till all disconnects are completed
---source include/wait_until_count_sessions.inc
diff --git a/mysql-test/t/innodb-lock.test b/mysql-test/t/innodb-lock.test
index eacf7e562be..d2f630ccaba 100644
--- a/mysql-test/t/innodb-lock.test
+++ b/mysql-test/t/innodb-lock.test
@@ -56,9 +56,12 @@ commit;
drop table t1;
-#
-# Try with old lock method (where LOCK TABLE is ignored by InnoDB)
-#
+--echo #
+--echo # Old lock method (where LOCK TABLE was ignored by InnoDB) no longer
+--echo # works due to fix for bugs #46272 "MySQL 5.4.4, new MDL: unnecessary
+--echo # deadlock" and bug #37346 "innodb does not detect deadlock between
+--echo # update and alter table".
+--echo #
set @@innodb_table_locks=0;
@@ -67,36 +70,38 @@ insert into t1 values(0, 0),(1,1),(2,2);
commit;
SELECT * from t1 where id = 0 FOR UPDATE;
+--echo # Connection 'con2'.
connection con2;
set autocommit=0;
set @@innodb_table_locks=0;
-# The following statement should work becase innodb doesn't check table locks
-lock table t1 write;
+--echo # The following statement should block because SQL-level lock
+--echo # is taken on t1 which will wait until concurrent transaction
+--echo # is commited.
+--echo # Sending:
+--send lock table t1 write;
+--echo # Connection 'con1'.
connection con1;
+--echo # Wait until LOCK TABLE is blocked on SQL-level lock.
+let $wait_condition=
+ select count(*) = 1 from information_schema.processlist
+ where state = "Waiting for table" and info = "lock table t1 write";
+--source include/wait_condition.inc
+--echo # We should be able to do UPDATEs and SELECTs within transaction.
+update t1 set x=1 where id = 0;
+select * from t1;
+--echo # Unblock LOCK TABLE.
+commit;
-# This will be locked by MySQL
---send
-update t1 set x=10 where id = 2;
---sleep 2
-
+--echo # Connection 'con2'.
connection con2;
-
-# Note that we will get a deadlock if we try to select any rows marked
-# for update by con1 !
-
-SELECT * from t1 where id = 2;
-UPDATE t1 set x=3 where id = 2;
-commit;
-SELECT * from t1;
-commit;
+--echo # Reap LOCK TABLE.
+--reap
unlock tables;
+--echo # Connection 'con1'.
connection con1;
-reap;
-commit;
-select * from t1;
drop table t1;
# End of 4.1 tests
diff --git a/mysql-test/t/innodb.test b/mysql-test/t/innodb.test
index 075058d42c2..c4380ff8f43 100644
--- a/mysql-test/t/innodb.test
+++ b/mysql-test/t/innodb.test
@@ -1854,16 +1854,15 @@ connect (b,localhost,root,,);
connection a;
create table t1(a int not null, b int, c int, d int, primary key(a)) engine=innodb;
insert into t1(a) values (1),(2),(3);
+delimiter |;
+create trigger t1t before insert on t1 for each row begin set NEW.b = NEW.a * 10 + 5, NEW.c = NEW.a / 10; end |
+delimiter ;|
commit;
connection b;
set autocommit = 0;
update t1 set b = 5 where a = 2;
connection a;
-delimiter |;
-create trigger t1t before insert on t1 for each row begin set NEW.b = NEW.a * 10 + 5, NEW.c = NEW.a / 10; end |
-delimiter ;|
set autocommit = 0;
-connection a;
insert into t1(a) values (10),(20),(30),(40),(50),(60),(70),(80),(90),(100),
(11),(21),(31),(41),(51),(61),(71),(81),(91),(101),
(12),(22),(32),(42),(52),(62),(72),(82),(92),(102),
@@ -1927,6 +1926,9 @@ insert into t2(a) values(8);
delete from t2 where a = 3;
update t4 set b = b + 1 where a = 3;
commit;
+connection a;
+commit;
+connection b;
drop trigger t1t;
drop trigger t2t;
drop trigger t3t;
diff --git a/mysql-test/t/innodb_mysql_lock-master.opt b/mysql-test/t/innodb_mysql_lock-master.opt
new file mode 100644
index 00000000000..0041949b829
--- /dev/null
+++ b/mysql-test/t/innodb_mysql_lock-master.opt
@@ -0,0 +1 @@
+--innodb_lock_wait_timeout=300
diff --git a/mysql-test/t/innodb_mysql_lock.test b/mysql-test/t/innodb_mysql_lock.test
new file mode 100644
index 00000000000..6469ef2d229
--- /dev/null
+++ b/mysql-test/t/innodb_mysql_lock.test
@@ -0,0 +1,175 @@
+-- source include/have_innodb.inc
+
+# Save the initial number of concurrent sessions.
+--source include/count_sessions.inc
+
+--echo #
+--echo # Bug #22876 Four-way deadlock
+--echo #
+
+--disable_warnings
+DROP TABLE IF EXISTS t1;
+--enable_warnings
+
+connect (con1,localhost,root,,);
+connect (con2,localhost,root,,);
+connect (con3,localhost,root,,);
+
+--echo # Connection 1
+connection con1;
+set @@autocommit=0;
+CREATE TABLE t1(s1 INT UNIQUE) ENGINE=innodb;
+INSERT INTO t1 VALUES (1);
+
+--echo # Connection 2
+connection con2;
+set @@autocommit=0;
+INSERT INTO t1 VALUES (2);
+--send INSERT INTO t1 VALUES (1)
+
+--echo # Connection 3
+connection con3;
+set @@autocommit=0;
+--send DROP TABLE t1
+
+--echo # Connection 1
+connection con1;
+let $wait_condition=
+ SELECT COUNT(*) = 1 FROM information_schema.processlist
+ WHERE info = "INSERT INTO t1 VALUES (1)" and
+ state = "update";
+--source include/wait_condition.inc
+let $wait_condition=
+ SELECT COUNT(*) = 1 FROM information_schema.processlist
+ WHERE info = "DROP TABLE t1" and
+ state = "Waiting for table";
+--source include/wait_condition.inc
+--echo # Connection 1 is now holding the lock.
+--echo # Issuing insert from connection 1 while connection 2&3
+--echo # is waiting for the lock should give a deadlock error.
+--error ER_LOCK_DEADLOCK
+INSERT INTO t1 VALUES (2);
+
+--echo # Cleanup
+connection con2;
+--reap
+commit;
+set @@autocommit=1;
+connection con1;
+commit;
+set @@autocommit=1;
+connection con3;
+--reap
+set @@autocommit=1;
+connection default;
+
+disconnect con1;
+disconnect con3;
+
+
+--echo #
+--echo # Test for bug #37346 "innodb does not detect deadlock between update
+--echo # and alter table".
+--echo #
+--disable_warnings
+drop table if exists t1;
+--enable_warnings
+create table t1 (c1 int primary key, c2 int, c3 int) engine=InnoDB;
+insert into t1 values (1,1,0),(2,2,0),(3,3,0),(4,4,0),(5,5,0);
+begin;
+--echo # Run statement which acquires X-lock on one of table's rows.
+update t1 set c3=c3+1 where c2=3;
+
+--echo #
+--echo # Switching to connection 'con37346'.
+connect (con37346,localhost,root,,test,,);
+connection con37346;
+--echo # The below ALTER TABLE statement should wait till transaction
+--echo # in connection 'default' is complete and then succeed.
+--echo # It should not deadlock or fail with ER_LOCK_DEADLOCK error.
+--echo # Sending:
+--send alter table t1 add column c4 int;
+
+--echo #
+--echo # Switching to connection 'default'.
+connection default;
+--echo # Wait until the above ALTER TABLE gets blocked because this
+--echo # connection holds SW metadata lock on table to be altered.
+let $wait_condition=
+ select count(*) = 1 from information_schema.processlist
+ where state = "Waiting for table" and info = "alter table t1 add column c4 int";
+--source include/wait_condition.inc
+
+--echo # The below statement should succeed. It should not
+--echo # deadlock or end with ER_LOCK_DEADLOCK error.
+update t1 set c3=c3+1 where c2=4;
+
+--echo # Unblock ALTER TABLE by committing transaction.
+commit;
+
+--echo #
+--echo # Switching to connection 'con37346'.
+connection con37346;
+--echo # Reaping ALTER TABLE.
+--reap
+
+--echo #
+--echo # Switching to connection 'default'.
+connection default;
+disconnect con37346;
+drop table t1;
+
+
+--echo #
+--echo # Bug #42147 Concurrent DML and LOCK TABLE ... READ for InnoDB
+--echo # table cause warnings in errlog
+--echo #
+
+--echo #
+--echo # Note that this test for now relies on a global suppression of
+--echo # the warning "Found lock of type 6 that is write and read locked"
+--echo # This suppression rule can be removed once Bug#42147 is properly
+--echo # fixed. See bug page for more info.
+--echo #
+
+--disable_warnings
+DROP TABLE IF EXISTS t1;
+--enable_warnings
+
+CREATE TABLE t1 (i INT) engine= innodb;
+
+--echo # Connection 2
+--echo # Get user-level lock
+connection con2;
+SELECT get_lock('bug42147_lock', 60);
+
+--echo # Connection 1
+connection default;
+--send INSERT INTO t1 SELECT get_lock('bug42147_lock', 60)
+
+--echo # Connection 2
+connection con2;
+let $wait_condition=
+ SELECT COUNT(*) > 0 FROM information_schema.processlist
+ WHERE state = 'User lock'
+ AND info = 'INSERT INTO t1 SELECT get_lock(\'bug42147_lock\', 60)';
+--source include/wait_condition.inc
+LOCK TABLES t1 READ;
+SELECT release_lock('bug42147_lock');
+
+--echo # Connection 1
+connection default;
+--reap
+
+--echo # Connection 2
+connection con2;
+UNLOCK TABLES;
+
+--echo # Connection 1
+connection default;
+disconnect con2;
+DROP TABLE t1;
+
+# Check that all connections opened by test cases in this file are really
+# gone so execution of other tests won't be affected by their presence.
+--source include/wait_until_count_sessions.inc
diff --git a/mysql-test/t/innodb_mysql_sync.test b/mysql-test/t/innodb_mysql_sync.test
new file mode 100644
index 00000000000..3f061e30293
--- /dev/null
+++ b/mysql-test/t/innodb_mysql_sync.test
@@ -0,0 +1,48 @@
+#
+# Test file for InnoDB tests that require the debug sync facility
+#
+--source include/have_innodb.inc
+--source include/have_debug_sync.inc
+# Save the initial number of concurrent sessions.
+--source include/count_sessions.inc
+
+
+--echo #
+--echo # Bug 42074 concurrent optimize table and
+--echo # alter table = Assertion failed: thd->is_error()
+--echo #
+
+--disable_warnings
+DROP TABLE IF EXISTS t1;
+--enable_warnings
+
+--echo # Create InnoDB table
+CREATE TABLE t1 (id INT) engine=innodb;
+connect (con2, localhost, root);
+
+--echo # Connection 1
+--echo # Start optimizing table
+connection default;
+SET DEBUG_SYNC='ha_admin_try_alter SIGNAL optimize_started WAIT_FOR table_altered';
+--send OPTIMIZE TABLE t1
+
+--echo # Connection 2
+--echo # Change table to engine=memory
+connection con2;
+SET DEBUG_SYNC='now WAIT_FOR optimize_started';
+ALTER TABLE t1 engine=memory;
+SET DEBUG_SYNC='now SIGNAL table_altered';
+
+--echo # Connection 1
+--echo # Complete optimization
+connection default;
+--reap
+
+disconnect con2;
+DROP TABLE t1;
+SET DEBUG_SYNC='RESET';
+
+
+# Check that all connections opened by test cases in this file are really
+# gone so execution of other tests won't be affected by their presence.
+--source include/wait_until_count_sessions.inc
diff --git a/mysql-test/t/insert_notembedded.test b/mysql-test/t/insert_notembedded.test
index 2950acff3cc..510dc56e8f7 100644
--- a/mysql-test/t/insert_notembedded.test
+++ b/mysql-test/t/insert_notembedded.test
@@ -174,7 +174,7 @@ connection default;
# we must wait till the insert opens and locks the table
let $wait_condition=
select count(*) = 1 from information_schema.processlist
- where state = "Locked" and id = $ID;
+ where state = "Table lock" and id = $ID;
--source include/wait_condition.inc
connect (select,localhost,root,,);
--echo connection: select
diff --git a/mysql-test/t/kill.test b/mysql-test/t/kill.test
index 02b033df2e5..b91feb3a1d5 100644
--- a/mysql-test/t/kill.test
+++ b/mysql-test/t/kill.test
@@ -329,6 +329,243 @@ KILL CONNECTION_ID();
SELECT 1;
--connection default
+--echo #
+--echo # Additional test for WL#3726 "DDL locking for all metadata objects"
+--echo # Check that DDL and DML statements waiting for metadata locks can
+--echo # be killed. Note that we don't cover all situations here since it
+--echo # can be tricky to write test case for some of them (e.g. REPAIR or
+--echo # ALTER and other statements under LOCK TABLES).
+--echo #
+--disable_warnings
+drop tables if exists t1, t2, t3;
+--enable_warnings
+
+create table t1 (i int primary key);
+connect (blocker, localhost, root, , );
+connect (dml, localhost, root, , );
+connect (ddl, localhost, root, , );
+
+--echo # Test for RENAME TABLE
+--echo # Switching to connection 'blocker'
+connection blocker;
+lock table t1 read;
+--echo # Switching to connection 'ddl'
+connection ddl;
+let $ID= `select connection_id()`;
+--send rename table t1 to t2
+--echo # Switching to connection 'default'
+connection default;
+let $wait_condition=
+ select count(*) = 1 from information_schema.processlist
+ where state = "Waiting for table" and info = "rename table t1 to t2";
+--source include/wait_condition.inc
+--replace_result $ID ID
+eval kill query $ID;
+--echo # Switching to connection 'ddl'
+connection ddl;
+--error ER_QUERY_INTERRUPTED
+--reap
+
+--echo # Test for DROP TABLE
+--send drop table t1
+--echo # Switching to connection 'default'
+connection default;
+let $wait_condition=
+ select count(*) = 1 from information_schema.processlist
+ where state = "Waiting for table" and
+ info = "drop table t1";
+--source include/wait_condition.inc
+--replace_result $ID ID
+eval kill query $ID;
+--echo # Switching to connection 'ddl'
+connection ddl;
+--error ER_QUERY_INTERRUPTED
+--reap
+
+--echo # Test for CREATE TRIGGER
+--send create trigger t1_bi before insert on t1 for each row set @a:=1
+--echo # Switching to connection 'default'
+connection default;
+let $wait_condition=
+ select count(*) = 1 from information_schema.processlist
+ where state = "Waiting for table" and
+ info = "create trigger t1_bi before insert on t1 for each row set @a:=1";
+--source include/wait_condition.inc
+--replace_result $ID ID
+eval kill query $ID;
+--echo # Switching to connection 'ddl'
+connection ddl;
+--error ER_QUERY_INTERRUPTED
+--reap
+
+--echo #
+--echo # Tests for various kinds of ALTER TABLE
+--echo #
+--echo # Full-blown ALTER which should copy table
+--send alter table t1 add column j int
+--echo # Switching to connection 'default'
+connection default;
+let $wait_condition=
+ select count(*) = 1 from information_schema.processlist
+ where state = "Waiting for table" and
+ info = "alter table t1 add column j int";
+--source include/wait_condition.inc
+--replace_result $ID ID
+eval kill query $ID;
+--echo # Switching to connection 'ddl'
+connection ddl;
+--error ER_QUERY_INTERRUPTED
+--reap
+
+--echo # Two kinds of simple ALTER
+--send alter table t1 rename to t2
+--echo # Switching to connection 'default'
+connection default;
+let $wait_condition=
+ select count(*) = 1 from information_schema.processlist
+ where state = "Waiting for table" and
+ info = "alter table t1 rename to t2";
+--source include/wait_condition.inc
+--replace_result $ID ID
+eval kill query $ID;
+--echo # Switching to connection 'ddl'
+connection ddl;
+--error ER_QUERY_INTERRUPTED
+--reap
+--send alter table t1 disable keys
+--echo # Switching to connection 'default'
+connection default;
+let $wait_condition=
+ select count(*) = 1 from information_schema.processlist
+ where state = "Waiting for table" and
+ info = "alter table t1 disable keys";
+--source include/wait_condition.inc
+--replace_result $ID ID
+eval kill query $ID;
+--echo # Switching to connection 'ddl'
+connection ddl;
+--error ER_QUERY_INTERRUPTED
+--reap
+--echo # Fast ALTER
+--send alter table t1 alter column i set default 100
+--echo # Switching to connection 'default'
+connection default;
+let $wait_condition=
+ select count(*) = 1 from information_schema.processlist
+ where state = "Waiting for table" and
+ info = "alter table t1 alter column i set default 100";
+--source include/wait_condition.inc
+--replace_result $ID ID
+eval kill query $ID;
+--echo # Switching to connection 'ddl'
+connection ddl;
+--error ER_QUERY_INTERRUPTED
+--reap
+--echo # Special case which is triggered only for MERGE tables.
+--echo # Switching to connection 'blocker'
+connection blocker;
+unlock tables;
+create table t2 (i int primary key) engine=merge union=(t1);
+lock tables t2 read;
+--echo # Switching to connection 'ddl'
+connection ddl;
+--send alter table t2 alter column i set default 100
+--echo # Switching to connection 'default'
+connection default;
+let $wait_condition=
+ select count(*) = 1 from information_schema.processlist
+ where state = "Waiting for table" and
+ info = "alter table t2 alter column i set default 100";
+--source include/wait_condition.inc
+--replace_result $ID ID
+eval kill query $ID;
+--echo # Switching to connection 'ddl'
+connection ddl;
+--error ER_QUERY_INTERRUPTED
+--reap
+
+--echo # Test for DML waiting for meta-data lock
+--echo # Switching to connection 'blocker'
+connection blocker;
+unlock tables;
+drop table t2;
+create table t2 (k int);
+lock tables t1 read;
+--echo # Switching to connection 'ddl'
+connection ddl;
+# Let us add pending exclusive metadata lock on t2
+--send rename tables t1 to t3, t2 to t1
+--echo # Switching to connection 'dml'
+connection dml;
+let $wait_condition=
+ select count(*) = 1 from information_schema.processlist
+ where state = "Waiting for table" and
+ info = "rename tables t1 to t3, t2 to t1";
+--source include/wait_condition.inc
+let $ID2= `select connection_id()`;
+--send insert into t2 values (1)
+--echo # Switching to connection 'default'
+connection default;
+let $wait_condition=
+ select count(*) = 1 from information_schema.processlist
+ where state = "Waiting for table" and
+ info = "insert into t2 values (1)";
+--source include/wait_condition.inc
+--replace_result $ID2 ID2
+eval kill query $ID2;
+--echo # Switching to connection 'dml'
+connection dml;
+--error ER_QUERY_INTERRUPTED
+--reap
+--echo # Switching to connection 'blocker'
+connection blocker;
+unlock tables;
+--echo # Switching to connection 'ddl'
+connection ddl;
+--reap
+
+--echo # Test for DML waiting for tables to be flushed
+--echo # Switching to connection 'blocker'
+connection blocker;
+lock tables t1 read;
+--echo # Switching to connection 'ddl'
+connection ddl;
+--echo # Let us mark locked table t1 as old
+--send flush tables
+--echo # Switching to connection 'dml'
+connection dml;
+let $wait_condition=
+ select count(*) = 1 from information_schema.processlist
+ where state = "Flushing tables" and
+ info = "flush tables";
+--source include/wait_condition.inc
+--send select * from t1
+--echo # Switching to connection 'default'
+connection default;
+let $wait_condition=
+ select count(*) = 1 from information_schema.processlist
+ where state = "Waiting for table" and
+ info = "select * from t1";
+--source include/wait_condition.inc
+--replace_result $ID2 ID2
+eval kill query $ID2;
+--echo # Switching to connection 'dml'
+connection dml;
+--error ER_QUERY_INTERRUPTED
+--reap
+--echo # Switching to connection 'blocker'
+connection blocker;
+unlock tables;
+--echo # Switching to connection 'ddl'
+connection ddl;
+--reap
+
+--echo # Cleanup.
+--echo # Switching to connection 'default'
+connection default;
+drop table t3;
+drop table t1;
+
###########################################################################
# Restore global concurrent_insert value. Keep in the end of the test file.
diff --git a/mysql-test/t/lock.test b/mysql-test/t/lock.test
index 04994e3e48f..eda3e8451dd 100644
--- a/mysql-test/t/lock.test
+++ b/mysql-test/t/lock.test
@@ -2,8 +2,11 @@
# Testing of table locking
#
+# Save the initial number of concurrent sessions.
+--source include/count_sessions.inc
+
--disable_warnings
-drop table if exists t1,t2;
+drop table if exists t1,t2,t3;
--enable_warnings
CREATE TABLE t1 ( `id` int(11) NOT NULL default '0', `id2` int(11) NOT NULL default '0', `id3` int(11) NOT NULL default '0', `dummy1` char(30) default NULL, PRIMARY KEY (`id`,`id2`), KEY `index_id3` (`id3`)) ENGINE=MyISAM;
insert into t1 (id,id2) values (1,1),(1,2),(1,3);
@@ -178,6 +181,7 @@ select * from t2;
--error ER_TABLE_NOT_LOCKED
select * from t3;
select * from v_bug5719;
+--error ER_LOCK_OR_ACTIVE_TRANSACTION
drop view v_bug5719;
--echo
--echo sic: did not left LOCK TABLES mode automatically
@@ -185,7 +189,7 @@ drop view v_bug5719;
--error ER_TABLE_NOT_LOCKED
select * from t1;
unlock tables;
-create view v_bug5719 as select * from t1;
+create or replace view v_bug5719 as select * from t1;
lock tables v_bug5719 write;
select * from v_bug5719;
--echo
@@ -198,6 +202,12 @@ select * from t1;
select * from t2;
--error ER_TABLE_NOT_LOCKED
select * from t3;
+--echo Dropping of implicitly locked table is disallowed.
+--error ER_TABLE_NOT_LOCKED_FOR_WRITE
+drop table t1;
+unlock tables;
+--echo Now let us also lock table explicitly and drop it.
+lock tables t1 write, v_bug5719 write;
drop table t1;
--echo
--echo sic: left LOCK TABLES mode
@@ -251,3 +261,324 @@ UNLOCK TABLES;
DROP TABLE t1,t2;
--echo End of 5.1 tests.
+
+--echo #
+--echo # Ensure that FLUSH TABLES doesn't substitute a base locked table
+--echo # with a temporary one.
+--echo #
+
+--disable_warnings
+drop table if exists t1, t2;
+--enable_warnings
+create table t1 (a int);
+create table t2 (a int);
+lock table t1 write, t2 write;
+create temporary table t1 (a int);
+flush table t1;
+drop temporary table t1;
+select * from t1;
+unlock tables;
+drop table t1, t2;
+
+--echo #
+--echo # Ensure that REPAIR .. USE_FRM works under LOCK TABLES.
+--echo #
+
+--disable_warnings
+drop table if exists t1, t2;
+--enable_warnings
+create table t1 (a int);
+create table t2 (a int);
+lock table t1 write, t2 write;
+repair table t1 use_frm;
+repair table t1 use_frm;
+select * from t1;
+select * from t2;
+repair table t2 use_frm;
+repair table t2 use_frm;
+select * from t1;
+unlock tables;
+drop table t1, t2;
+
+--echo #
+--echo # Ensure that mi_copy_status is called for two instances
+--echo # of the same table when it is reopened after a flush.
+--echo #
+--disable_warnings
+drop table if exists t1;
+drop view if exists v1;
+--enable_warnings
+create table t1 (c1 int);
+create view v1 as select * from t1;
+lock tables t1 write, v1 write;
+flush table t1;
+insert into t1 values (33);
+flush table t1;
+select * from t1;
+unlock tables;
+drop table t1;
+drop view v1;
+
+--echo #
+--echo # WL#4284: Transactional DDL locking
+--echo #
+
+--disable_warnings
+drop table if exists t1;
+--enable_warnings
+create table t1 (a int);
+connect(con1,localhost,root,,);
+set autocommit= 0;
+insert into t1 values (1);
+lock table t1 write;
+--echo # Disconnect
+--echo # Ensure that metadata locks will be released if there is an open
+--echo # transaction (autocommit=off) in conjunction with lock tables.
+disconnect con1;
+connection default;
+drop table t1;
+
+--echo # Same problem but now for BEGIN
+
+--disable_warnings
+drop table if exists t1;
+--enable_warnings
+create table t1 (a int);
+connect(con1,localhost,root,,);
+begin;
+insert into t1 values (1);
+--echo # Disconnect
+--echo # Ensure that metadata locks held by the transaction are released.
+disconnect con1;
+connection default;
+drop table t1;
+
+
+--echo #
+--echo # Coverage for situations when we try to execute DDL on tables
+--echo # which are locked by LOCK TABLES only implicitly.
+--echo #
+--disable_warnings
+drop tables if exists t1, t2;
+drop view if exists v1;
+drop function if exists f1;
+--enable_warnings
+create table t1 (i int);
+create table t2 (j int);
+--echo #
+--echo # Try to perform DDL on table which is locked through view.
+create view v1 as select * from t2;
+lock tables t1 write, v1 write;
+--error ER_TABLE_NOT_LOCKED_FOR_WRITE
+flush table t2;
+--error ER_TABLE_NOT_LOCKED_FOR_WRITE
+drop table t2;
+--error ER_TABLE_NOT_LOCKED_FOR_WRITE
+alter table t2 add column k int;
+--error ER_TABLE_NOT_LOCKED_FOR_WRITE
+create trigger t2_bi before insert on t2 for each row set @a:=1;
+--echo # Repair produces error as part of its result set.
+repair table t2;
+unlock tables;
+drop view v1;
+--echo #
+--echo # Now, try DDL on table which is locked through routine.
+delimiter |;
+create function f1 () returns int
+begin
+ insert into t2 values (1);
+ return 0;
+end|
+delimiter ;|
+create view v1 as select f1() from t1;
+lock tables v1 read;
+--error ER_TABLE_NOT_LOCKED_FOR_WRITE
+flush table t2;
+--error ER_TABLE_NOT_LOCKED_FOR_WRITE
+drop table t2;
+--error ER_TABLE_NOT_LOCKED_FOR_WRITE
+alter table t2 add column k int;
+--error ER_TABLE_NOT_LOCKED_FOR_WRITE
+create trigger t2_bi before insert on t2 for each row set @a:=1;
+--echo # Repair produces error as part of its result set.
+repair table t2;
+unlock tables;
+drop view v1;
+drop function f1;
+--echo #
+--echo # Finally, try DDL on table which is locked thanks to trigger.
+create trigger t1_ai after insert on t1 for each row insert into t2 values (1);
+lock tables t1 write;
+--error ER_TABLE_NOT_LOCKED_FOR_WRITE
+flush table t2;
+--error ER_TABLE_NOT_LOCKED_FOR_WRITE
+drop table t2;
+--error ER_TABLE_NOT_LOCKED_FOR_WRITE
+alter table t2 add column k int;
+--error ER_TABLE_NOT_LOCKED_FOR_WRITE
+create trigger t2_bi before insert on t2 for each row set @a:=1;
+--echo # Repair produces error as part of its result set.
+repair table t2;
+unlock tables;
+drop trigger t1_ai;
+drop tables t1, t2;
+
+
+--echo #
+--echo # Bug#45035 " Altering table under LOCK TABLES results in
+--echo # "Error 1213 Deadlock found..."
+--echo #
+--echo # When reopening tables under LOCK TABLES after ALTER TABLE,
+--echo # 6.0 used to be taking thr_lock locks one by one, and
+--echo # that would lead to a lock conflict.
+--echo # Check that taking all locks at once works.
+--echo #
+--disable_warnings
+drop table if exists t1;
+--enable_warnings
+create table t1 (i int);
+lock tables t1 write, t1 as a read, t1 as b read;
+alter table t1 add column j int;
+unlock tables;
+drop table t1;
+create temporary table t1 (i int);
+--echo #
+--echo # This is just for test coverage purposes,
+--echo # when this is allowed, remove the --error.
+--echo #
+--error ER_CANT_REOPEN_TABLE
+lock tables t1 write, t1 as a read, t1 as b read;
+alter table t1 add column j int;
+unlock tables;
+drop table t1;
+--echo #
+--echo # Separate case for partitioned tables is important
+--echo # because each partition has an own thr_lock object.
+--echo #
+create table t1 (i int) partition by list (i)
+ (partition p0 values in (1),
+ partition p1 values in (2,3),
+ partition p2 values in (4,5));
+lock tables t1 write, t1 as a read, t1 as b read;
+alter table t1 add column j int;
+unlock tables;
+drop table t1;
+
+
+--echo #
+--echo # Bug #43272 HANDLER SQL command does not work under LOCK TABLES
+--echo #
+
+--disable_warnings
+DROP TABLE IF EXISTS t1;
+--enable_warnings
+
+CREATE TABLE t1 (a INT);
+LOCK TABLE t1 WRITE;
+
+--echo # HANDLER commands are not allowed in LOCK TABLES mode
+--error ER_LOCK_OR_ACTIVE_TRANSACTION
+HANDLER t1 OPEN;
+--error ER_LOCK_OR_ACTIVE_TRANSACTION
+HANDLER t1 READ FIRST;
+--error ER_LOCK_OR_ACTIVE_TRANSACTION
+HANDLER t1 CLOSE;
+
+UNLOCK TABLES;
+DROP TABLE t1;
+
+
+--echo #
+--echo # Bug#45066 FLUSH TABLES WITH READ LOCK deadlocks against
+--echo # LOCK TABLE
+--echo #
+
+--disable_warnings
+DROP TABLE IF EXISTS t1;
+--enable_warnings
+
+CREATE TABLE t1(a INT);
+
+LOCK TABLE t1 READ;
+--error ER_TABLE_NOT_LOCKED_FOR_WRITE
+FLUSH TABLES;
+
+LOCK TABLE t1 WRITE;
+FLUSH TABLES;
+
+--echo #
+--echo # If you allow the next combination, you reintroduce bug Bug#45066
+--echo #
+LOCK TABLE t1 READ;
+--error ER_LOCK_OR_ACTIVE_TRANSACTION
+FLUSH TABLES WITH READ LOCK;
+
+LOCK TABLE t1 WRITE;
+--error ER_LOCK_OR_ACTIVE_TRANSACTION
+FLUSH TABLES WITH READ LOCK;
+
+UNLOCK TABLES;
+DROP TABLE t1;
+
+
+--echo #
+--echo # Simplified test for bug #48538 "Assertion in thr_lock() on LOAD DATA
+--echo # CONCURRENT INFILE".
+--echo #
+
+--disable_warnings
+DROP TABLE IF EXISTS t1;
+--enable_warnings
+
+CREATE TABLE t1 (f1 INT, f2 INT) ENGINE = MEMORY;
+CREATE TRIGGER t1_ai AFTER INSERT ON t1 FOR EACH ROW
+ UPDATE LOW_PRIORITY t1 SET f2 = 7;
+
+--echo # Statement below should fail with ER_CANT_UPDATE_USED_TABLE_IN_SF_OR_TRG
+--echo # error instead of failing on assertion in table-level locking subsystem.
+--error ER_CANT_UPDATE_USED_TABLE_IN_SF_OR_TRG
+INSERT INTO t1(f1) VALUES(0);
+
+DROP TABLE t1;
+
+
+--echo #
+--echo # Bug#43685 Lock table affects other non-related tables
+--echo #
+
+--disable_warnings
+DROP TABLE IF EXISTS t1, t2;
+--enable_warnings
+
+connect (con2, localhost, root);
+CREATE TABLE t1 (id INT);
+CREATE TABLE t2 (id INT);
+
+--echo # Connection default
+connection default;
+LOCK TABLE t1 WRITE;
+ANALYZE TABLE t1;
+
+--echo # Connection con2
+connection con2;
+LOCK TABLE t2 WRITE;
+--echo # This used to hang until the first connection
+--echo # unlocked t1.
+FLUSH TABLE t2;
+
+UNLOCK TABLES;
+
+--echo # Connection default
+connection default;
+UNLOCK TABLES;
+DROP TABLE t1, t2;
+disconnect con2;
+
+
+--echo #
+--echo # End of 6.0 tests.
+--echo #
+
+# Check that all connections opened by test cases in this file are really
+# gone so execution of other tests won't be affected by their presence.
+--source include/wait_until_count_sessions.inc
diff --git a/mysql-test/t/lock_multi.test b/mysql-test/t/lock_multi.test
index 5670276ee2e..c34dcb05dd4 100644
--- a/mysql-test/t/lock_multi.test
+++ b/mysql-test/t/lock_multi.test
@@ -8,31 +8,44 @@ drop table if exists t1,t2;
# Test to see if select will get the lock ahead of low priority update
connect (locker,localhost,root,,);
+connect (locker2,localhost,root,,);
connect (reader,localhost,root,,);
connect (writer,localhost,root,,);
connection locker;
create table t1(n int);
insert into t1 values (1);
-lock tables t1 write;
+connection locker2;
+select get_lock("mysqltest_lock", 100);
+connection locker;
+send
+update t1 set n = 2 and get_lock('mysqltest_lock', 100);
connection writer;
+# Wait till above update gets blocked on a user lock.
+let $wait_condition=
+ select count(*) = 1 from information_schema.processlist
+ where state = "User lock" and info = "update t1 set n = 2 and get_lock('mysqltest_lock', 100)";
+--source include/wait_condition.inc
send
update low_priority t1 set n = 4;
connection reader;
# Sleep a bit till the update of connection writer is in work and hangs
let $wait_condition=
select count(*) = 1 from information_schema.processlist
- where state = "Locked" and info = "update low_priority t1 set n = 4";
+ where state = "Table lock" and info = "update low_priority t1 set n = 4";
--source include/wait_condition.inc
send
select n from t1;
-connection locker;
+connection locker2;
# Sleep a bit till the select of connection reader is in work and hangs
let $wait_condition=
select count(*) = 1 from information_schema.processlist
- where state = "Locked" and info = "select n from t1";
+ where state = "Table lock" and info = "select n from t1";
--source include/wait_condition.inc
-unlock tables;
+select release_lock("mysqltest_lock");
+connection locker;
+reap;
+select release_lock("mysqltest_lock");
connection writer;
reap;
connection reader;
@@ -42,19 +55,31 @@ drop table t1;
connection locker;
create table t1(n int);
insert into t1 values (1);
-lock tables t1 read;
+connection locker2;
+select get_lock("mysqltest_lock", 100);
+connection locker;
+send
+select n from t1 where get_lock('mysqltest_lock', 100);
connection writer;
+# Wait till above select gets blocked on a user lock.
+let $wait_condition=
+ select count(*) = 1 from information_schema.processlist
+ where state = "User lock" and info = "select n from t1 where get_lock('mysqltest_lock', 100)";
+--source include/wait_condition.inc
send
update low_priority t1 set n = 4;
connection reader;
# Sleep a bit till the update of connection writer is in work and hangs
let $wait_condition=
select count(*) = 1 from information_schema.processlist
- where state = "Locked" and info = "update low_priority t1 set n = 4";
+ where state = "Table lock" and info = "update low_priority t1 set n = 4";
--source include/wait_condition.inc
select n from t1;
+connection locker2;
+select release_lock("mysqltest_lock");
connection locker;
-unlock tables;
+reap;
+select release_lock("mysqltest_lock");
connection writer;
reap;
drop table t1;
@@ -95,9 +120,10 @@ insert t1 select * from t2;
connection locker;
let $wait_condition=
select count(*) = 1 from information_schema.processlist
- where state = "Locked" and info = "insert t1 select * from t2";
+ where state = "Waiting for table" and info = "insert t1 select * from t2";
--source include/wait_condition.inc
drop table t2;
+unlock tables;
connection reader;
--error ER_NO_SUCH_TABLE
reap;
@@ -119,9 +145,10 @@ connection locker;
# Sleep a bit till the insert of connection reader is in work and hangs
let $wait_condition=
select count(*) = 1 from information_schema.processlist
- where state = "Locked" and info = "insert t1 select * from t2";
+ where state = "Waiting for table" and info = "insert t1 select * from t2";
--source include/wait_condition.inc
drop table t2;
+unlock tables;
connection reader;
--error ER_NO_SUCH_TABLE
reap;
@@ -163,8 +190,8 @@ SELECT user.Select_priv FROM user, db WHERE user.user = db.user LIMIT 1;
connection locker;
# Sleep a bit till the select of connection reader is in work and hangs
let $wait_condition=
- select count(*) = 1 from information_schema.processlist
- where state = "Waiting for table" and info =
+ SELECT COUNT(*) = 1 FROM information_schema.processlist
+ WHERE state = "Waiting for table" AND info =
"SELECT user.Select_priv FROM user, db WHERE user.user = db.user LIMIT 1";
--source include/wait_condition.inc
# Make test case independent from earlier grants.
@@ -196,9 +223,10 @@ connection writer;
# Sleep a bit till the flush of connection locker is in work and hangs
let $wait_condition=
select count(*) = 1 from information_schema.processlist
- where state = "Flushing tables" and info = "FLUSH TABLES WITH READ LOCK";
+ where state = "Waiting for table" and info = "FLUSH TABLES WITH READ LOCK";
--source include/wait_condition.inc
# This must not block.
+--error ER_TABLE_NOT_LOCKED
CREATE TABLE t2 (c1 int);
UNLOCK TABLES;
#
@@ -208,7 +236,7 @@ reap;
UNLOCK TABLES;
#
connection default;
-DROP TABLE t1, t2;
+DROP TABLE t1;
#
# Test if CREATE TABLE SELECT with LOCK TABLE deadlocks.
#
@@ -226,7 +254,7 @@ connection writer;
# Sleep a bit till the flush of connection locker is in work and hangs
let $wait_condition=
select count(*) = 1 from information_schema.processlist
- where state = "Flushing tables" and info = "FLUSH TABLES WITH READ LOCK";
+ where state = "Waiting for table" and info = "FLUSH TABLES WITH READ LOCK";
--source include/wait_condition.inc
--error ER_TABLE_NOT_LOCKED
CREATE TABLE t2 AS SELECT * FROM t1;
@@ -298,7 +326,7 @@ connection reader;
# Wait till connection writer is blocked
let $wait_condition=
select count(*) = 1 from information_schema.processlist
- where state = "Locked" and info = "alter table t1 auto_increment=0";
+ where state = "Waiting for table" and info = "alter table t1 auto_increment=0";
--source include/wait_condition.inc
send
alter table t1 auto_increment=0;
@@ -306,7 +334,7 @@ connection locker;
# Wait till connection reader is blocked
let $wait_condition=
select count(*) = 2 from information_schema.processlist
- where state = "Locked" and info = "alter table t1 auto_increment=0";
+ where state = "Waiting for table" and info = "alter table t1 auto_increment=0";
--source include/wait_condition.inc
unlock tables;
connection writer;
@@ -337,10 +365,10 @@ connection con2;
send flush tables with read lock;
connection con5;
--echo # con5
-let $show_statement= SHOW PROCESSLIST;
-let $field= State;
-let $condition= = 'Flushing tables';
---source include/wait_show_condition.inc
+let $wait_condition=
+ select count(*) = 1 from information_schema.processlist
+ where state = "Waiting for table" and info = "flush tables with read lock";
+--source include/wait_condition.inc
--echo # global read lock is taken
connection con3;
--echo # con3
@@ -461,16 +489,16 @@ update t1 set i= 10;
connection reader;
let $wait_condition=
select count(*) = 1 from information_schema.processlist
- where state = "Locked" and info = "update t1 set i= 10";
+ where state = "Table lock" and info = "update t1 set i= 10";
--source include/wait_condition.inc
send
select * from t1;
connection default;
let $wait_condition=
select count(*) = 1 from information_schema.processlist
- where state = "Locked" and info = "select * from t1";
+ where state = "Table lock" and info = "select * from t1";
--source include/wait_condition.inc
-let $ID= `select id from information_schema.processlist where state = "Locked" and info = "update t1 set i= 10"`;
+let $ID= `select id from information_schema.processlist where state = "Table lock" and info = "update t1 set i= 10"`;
--replace_result $ID ID
eval kill query $ID;
connection reader;
@@ -501,6 +529,7 @@ drop table t1;
# Disconnect sessions used in many subtests above
disconnect locker;
+disconnect locker2;
disconnect reader;
disconnect writer;
@@ -528,7 +557,7 @@ connection default;
--echo connection: default
let $wait_condition=
select count(*) = 1 from information_schema.processlist
- where state = "Flushing tables";
+ where state = "Waiting for table";
--source include/wait_condition.inc
alter table t1 add column j int;
connect (insert,localhost,root,,test,,);
@@ -536,7 +565,7 @@ connection insert;
--echo connection: insert
let $wait_condition=
select count(*) = 1 from information_schema.processlist
- where state = "Flushing tables";
+ where state = "Waiting for table";
--source include/wait_condition.inc
--send insert into t1 values (1,2);
--echo connection: default
@@ -586,18 +615,14 @@ connection default;
--echo connection: default
let $wait_condition=
select count(*) = 1 from information_schema.processlist
- where state = "Flushing tables";
+ where state = "Waiting for table";
--source include/wait_condition.inc
flush tables;
let $wait_condition=
select count(*) = 1 from information_schema.processlist
- where state = "Flushing tables";
+ where state = "Waiting for table";
--source include/wait_condition.inc
unlock tables;
-let $wait_condition=
- select count(*) = 0 from information_schema.processlist
- where state = "Flushing tables";
---source include/wait_condition.inc
connection flush;
--reap
connection default;
@@ -617,11 +642,11 @@ lock tables t1 read;
let $tlwa= `show status like 'Table_locks_waited'`;
connect (waiter,localhost,root,,);
connection waiter;
---send insert into t1 values(1);
+send insert into t1 values(1);
connection default;
let $wait_condition=
select count(*) = 1 from information_schema.processlist
- where state = "Locked" and info = "insert into t1 values(1)";
+ where state = "Table lock" and info = "insert into t1 values(1)";
--source include/wait_condition.inc
let $tlwb= `show status like 'Table_locks_waited'`;
unlock tables;
@@ -658,21 +683,414 @@ connection default;
--echo connection: default
let $wait_condition=
select count(*) = 1 from information_schema.processlist
- where state = "Flushing tables";
+ where state = "Waiting for table";
--source include/wait_condition.inc
flush tables;
let $wait_condition=
select count(*) = 1 from information_schema.processlist
- where state = "Flushing tables";
+ where state = "Waiting for table";
--source include/wait_condition.inc
drop table t1;
-let $wait_condition=
- select count(*) = 0 from information_schema.processlist
- where state = "Flushing tables";
---source include/wait_condition.inc
connection flush;
--reap
connection default;
disconnect flush;
+
+
+--echo #
+--echo # Test for bug #46272 "MySQL 5.4.4, new MDL: unnecessary deadlock".
+--echo #
+--disable_warnings
+drop table if exists t1;
+--enable_warnings
+create table t1 (c1 int primary key, c2 int, c3 int);
+insert into t1 values (1,1,0),(2,2,0),(3,3,0),(4,4,0),(5,5,0);
+begin;
+update t1 set c3=c3+1 where c2=3;
+
+--echo #
+--echo # Switching to connection 'con46272'.
+connect (con46272,localhost,root,,test,,);
+connection con46272;
+--echo # The below ALTER TABLE statement should wait till transaction
+--echo # in connection 'default' is complete and then succeed.
+--echo # It should not deadlock or fail with ER_LOCK_DEADLOCK error.
+--echo # Sending:
+--send alter table t1 add column c4 int;
+
+--echo #
+--echo # Switching to connection 'default'.
+connection default;
+--echo # Wait until the above ALTER TABLE gets blocked because this
+--echo # connection holds SW metadata lock on table to be altered.
+let $wait_condition=
+ select count(*) = 1 from information_schema.processlist
+ where state = "Waiting for table" and info = "alter table t1 add column c4 int";
+--source include/wait_condition.inc
+
+--echo # The below statement should succeed. It should not
+--echo # deadlock or end with ER_LOCK_DEADLOCK error.
+update t1 set c3=c3+1 where c2=4;
+
+--echo # Unblock ALTER TABLE by committing transaction.
+commit;
+
+--echo #
+--echo # Switching to connection 'con46272'.
+connection con46272;
+--echo # Reaping ALTER TABLE.
+--reap
+
+--echo #
+--echo # Switching to connection 'default'.
+connection default;
+disconnect con46272;
+drop table t1;
+
+
+--echo #
+--echo # Bug#47249 assert in MDL_global_lock::is_lock_type_compatible
+--echo #
+
+--disable_warnings
+DROP TABLE IF EXISTS t1;
+DROP VIEW IF EXISTS v1;
+--enable_warnings
+
+--echo #
+--echo # Test 1: LOCK TABLES v1 WRITE, t1 READ;
+--echo #
+--echo # Thanks to the fact that we no longer allow DDL on tables
+--echo # which are locked for write implicitly, the exact scenario
+--echo # in which assert was failing is no longer repeatable.
+
+CREATE TABLE t1 ( f1 integer );
+CREATE VIEW v1 AS SELECT f1 FROM t1 ;
+
+LOCK TABLES v1 WRITE, t1 READ;
+--error ER_TABLE_NOT_LOCKED_FOR_WRITE
+FLUSH TABLE t1;
+UNLOCK TABLES;
+
+# Cleanup
+DROP TABLE t1;
+DROP VIEW v1;
+
+--echo #
+--echo # Test 2: LOCK TABLES t1 WRITE, v1 READ;
+--echo #
+
+CREATE TABLE t1 ( f1 integer );
+CREATE VIEW v1 AS SELECT f1 FROM t1 ;
+
+--echo # Connection 2
+connect (con2,localhost,root);
+LOCK TABLES t1 WRITE, v1 READ;
+FLUSH TABLE t1;
+disconnect con2;
+--source include/wait_until_disconnected.inc
+
+--echo # Connection 1
+connection default;
+LOCK TABLES t1 WRITE;
+FLUSH TABLE t1; # Assertion happened here
+
+# Cleanup
+DROP TABLE t1;
+DROP VIEW v1;
+
+
+--echo #
+--echo # Test for bug #50913 "Deadlock between open_and_lock_tables_derived
+--echo # and MDL". Also see additional coverage in mdl_sync.test.
+--echo #
+--disable_warnings
+drop table if exists t1;
+drop view if exists v1;
+--enable_warnings
+connect (con50913,localhost,root);
+connection default;
+create table t1 (i int);
+create view v1 as select i from t1;
+begin;
+select * from t1;
+
+--echo # Switching to connection 'con50913'.
+connection con50913;
+--echo # Sending:
+--send alter table t1 add column j int
+
+--echo # Switching to connection 'default'.
+connection default;
+--echo # Wait until ALTER TABLE gets blocked.
+let $wait_condition=
+ select count(*) = 1 from information_schema.processlist
+ where state = "Waiting for table" and info = "alter table t1 add column j int";
+--source include/wait_condition.inc
+--echo # The below statement should try to acquire SW lock on 't1'
+--echo # and therefore should get ER_LOCK_DEADLOCK error. Before
+--echo # bug fix it acquired SR lock and hung on thr_lock.c lock.
+--error ER_LOCK_DEADLOCK
+delete a from t1 as a where i = 1;
+--echo # Unblock ALTER TABLE.
+commit;
+
+--echo # Switching to connection 'con50913'.
+connection con50913;
+--echo # Reaping ALTER TABLE;
+--reap
+
+--echo # Switching to connection 'default'.
+connection default;
+begin;
+select * from v1;
+
+--echo # Switching to connection 'con50913'.
+connection con50913;
+--echo # Sending:
+--send alter table t1 drop column j
+
+--echo # Switching to connection 'default'.
+connection default;
+--echo # Wait until ALTER TABLE gets blocked.
+let $wait_condition=
+ select count(*) = 1 from information_schema.processlist
+ where state = "Waiting for table" and info = "alter table t1 drop column j";
+--source include/wait_condition.inc
+--echo # The below statement should try to acquire SW lock on 't1'
+--echo # and therefore should get ER_LOCK_DEADLOCK error. Before
+--echo # bug fix it acquired SR lock and hung on thr_lock.c lock.
+--error ER_LOCK_DEADLOCK
+insert into v1 values (1);
+--echo # Unblock ALTER TABLE.
+commit;
+
+--echo # Switching to connection 'con50913'.
+connection con50913;
+--echo # Reaping ALTER TABLE;
+--reap
+
+--echo # Switching to connection 'default'.
+connection default;
+disconnect con50913;
+drop view v1;
+drop table t1;
+
+
+--echo #
+--echo # Bug#45225 Locking: hang if drop table with no timeout
+--echo #
+--echo # These tests also provide function coverage for the
+--echo # lock_wait_timeout server variable.
+--echo #
+
+--disable_warnings
+DROP TABLE IF EXISTS t1;
+--enable_warnings
+
+CREATE TABLE t1 (id int);
+
+connect(con2, localhost, root,,);
+SET SESSION lock_wait_timeout= 1;
+
+--echo #
+--echo # Test 1: acquire exclusive lock
+--echo #
+
+--echo # Connection default
+connection default;
+START TRANSACTION;
+INSERT INTO t1 VALUES (1);
+
+--echo # Connection 2
+connection con2;
+--error ER_LOCK_WAIT_TIMEOUT
+DROP TABLE t1;
+
+--echo # Connection default
+connection default;
+COMMIT;
+
+--echo #
+--echo # Test 2: upgrade shared lock
+--echo #
+
+--echo # Connection default
+connection default;
+START TRANSACTION;
+SELECT * FROM t1;
+
+--echo # Connection 2
+connection con2;
+--error ER_LOCK_WAIT_TIMEOUT
+ALTER TABLE t1 RENAME TO t2;
+
+--echo # Connection default
+connection default;
+COMMIT;
+
+--echo #
+--echo # Test 3: acquire shared lock
+--echo #
+
+--echo # Connection default
+connection default;
+LOCK TABLE t1 WRITE;
+
+--echo # Connection 2
+connection con2;
+--error ER_LOCK_WAIT_TIMEOUT
+INSERT INTO t1(id) VALUES (2);
+
+--echo # Connection default
+connection default;
+UNLOCK TABLES;
+
+--echo #
+--echo # Test 4: table level locks
+--echo #
+
+--echo # Connection default
+connection default;
+LOCK TABLE t1 READ;
+
+--echo # Connection 2
+connection con2;
+--error ER_LOCK_WAIT_TIMEOUT
+INSERT INTO t1(id) VALUES(4);
+
+--echo # Connection default
+connection default;
+UNLOCK TABLES;
+
+--echo #
+--echo # Test 5: Waiting on Table Definition Cache (TDC)
+--echo #
+
+connect(con3, localhost, root);
+
+--echo # Connection default
+connection default;
+LOCK TABLE t1 READ;
+
+--echo # Connection con3
+connection con3;
+--echo # Sending:
+--send FLUSH TABLES
+
+--echo # Connection con2
+connection con2;
+let $wait_condition=
+ SELECT COUNT(*) = 1 FROM information_schema.processlist
+ WHERE state = "Flushing tables" AND info = "FLUSH TABLES";
+--source include/wait_condition.inc
+--error ER_LOCK_WAIT_TIMEOUT
+SELECT * FROM t1;
+
+--echo # Connection default
+connection default;
+UNLOCK TABLES;
+
+--echo # Connection con3
+connection con3;
+--echo # Reaping: FLUSH TABLES
+--reap
+
+--echo #
+--echo # Test 6: Timeouts in I_S queries
+--echo #
+
+--echo # Connection default
+connection default;
+CREATE TABLE t2 (id INT);
+LOCK TABLE t2 WRITE;
+
+--echo # Connection con3
+connection con3;
+--echo # Sending:
+--send DROP TABLE t1, t2
+
+--echo # Connection con2
+connection con2;
+let $wait_condition=
+ SELECT COUNT(*) = 1 FROM information_schema.processlist
+ WHERE state = "Waiting for table" AND info = "DROP TABLE t1, t2";
+--source include/wait_condition.inc
+# Note: This query causes two timeouts.
+# 1: try_acquire_high_prio_shared_mdl_lock on t1
+# 2: recover_from_failed_open on t1
+SELECT table_name, table_comment FROM information_schema.tables
+ WHERE table_schema= 'test' AND table_name= 't1';
+
+--echo # Connection default
+connection default;
+UNLOCK TABLES;
+
+--echo # Connection con3
+connection con3;
+--echo # Reaping: DROP TABLE t1, t2
+--reap
+
+--echo # Connection default
+connection default;
+--echo # Cleanup
+disconnect con2;
+disconnect con3;
+
+
+--echo #
+--echo # Test for bug #51134 "Crash in MDL_lock::destroy on a concurrent
+--echo # DDL workload".
+--echo #
+--disable_warnings
+drop tables if exists t1, t2, t3;
+--enable_warnings
+connect (con1, localhost, root, , );
+connect (con2, localhost, root, , );
+connection default;
+create table t3 (i int);
+
+--echo # Switching to connection 'con1'
+connection con1;
+--echo # Lock 't3' so upcoming RENAME is blocked.
+lock table t3 read;
+
+--echo # Switching to connection 'con2'
+connection con2;
+--echo # Remember ID for this connection.
+let $ID= `select connection_id()`;
+--echo # Start statement which will try to acquire two instances
+--echo # of X metadata lock on the same object.
+--echo # Sending:
+--send rename tables t1 to t2, t2 to t3;
+
+--echo # Switching to connection 'default'
+connection default;
+--echo # Wait until RENAME TABLE is blocked on table 't3'.
+let $wait_condition=
+ select count(*) = 1 from information_schema.processlist
+ where state = "Waiting for table" and info = "rename tables t1 to t2, t2 to t3";
+--source include/wait_condition.inc
+--echo # Kill RENAME TABLE.
+--replace_result $ID ID
+eval kill query $ID;
+
+--echo # Switching to connection 'con2'
+connection con2;
+--echo # RENAME TABLE should be aborted but should not crash.
+--error ER_QUERY_INTERRUPTED
+--reap
+
+--echo # Switching to connection 'con1'
+connection con1;
+unlock tables;
+
+--echo # Switching to connection 'default'
+connection default;
+disconnect con1;
+disconnect con2;
+drop table t3;
+
+
# Wait till all disconnects are completed
--source include/wait_until_count_sessions.inc
diff --git a/mysql-test/t/lock_sync.test b/mysql-test/t/lock_sync.test
index 73289685114..97388e9c176 100644
--- a/mysql-test/t/lock_sync.test
+++ b/mysql-test/t/lock_sync.test
@@ -4,6 +4,10 @@
--source include/have_debug_sync.inc
# We need InnoDB to be able use TL_WRITE_ALLOW_WRITE type of locks in our tests.
--source include/have_innodb.inc
+# The test for Bug#50821 requires binary logging turned on.
+# With binary logging on, sub-queries in DML statements acquire
+# TL_READ_NO_INSERT which was needed to reproduce this deadlock bug.
+--source include/have_log_bin.inc
# Until bug#41971 'Thread state on embedded server is always "Writing to net"'
# is fixed this test can't be run on embedded version of server.
--source include/not_embedded.inc
@@ -19,8 +23,16 @@
--echo # (TL_WRITE_ALLOW_WRITE) on several instances of the same table and
--echo # statements which tried to acquire stronger write lock (TL_WRITE,
--echo # TL_WRITE_ALLOW_READ) on this table might have led to deadlock.
+#
+# Suppress warnings for INSERTs that use get_lock().
+#
+disable_query_log;
+call mtr.add_suppression("Unsafe statement binlogged in statement format since BINLOG_FORMAT = STATEMENT");
+enable_query_log;
+
--disable_warnings
drop table if exists t1;
+drop view if exists v1;
--enable_warnings
--echo # Create auxiliary connections used through the test.
connect (con_bug45143_1,localhost,root,,test,,);
@@ -35,6 +47,9 @@ set @old_general_log = @@global.general_log;
set @@global.general_log= OFF;
create table t1 (i int) engine=InnoDB;
+--echo # We have to use view in order to make LOCK TABLES avoid
+--echo # acquiring SNRW metadata lock on table.
+create view v1 as select * from t1;
insert into t1 values (1);
--echo # Prepare user lock which will be used for resuming execution of
--echo # the first statement after it acquires TL_WRITE_ALLOW_WRITE lock.
@@ -65,14 +80,14 @@ connection con_bug45143_3;
--echo # acquiring lock for the the first instance of 't1'.
set debug_sync= 'now WAIT_FOR parked';
--echo # Send LOCK TABLE statement which will try to get TL_WRITE lock on 't1':
---send lock table t1 write;
+--send lock table v1 write;
--echo # Switch to connection 'default'.
connection default;
--echo # Wait until this LOCK TABLES statement starts waiting for table lock.
let $wait_condition= select count(*)= 1 from information_schema.processlist
- where state= 'Locked' and
- info='lock table t1 write';
+ where state= 'Table lock' and
+ info='lock table v1 write';
--source include/wait_condition.inc
--echo # Allow SELECT ... FOR UPDATE to resume.
--echo # Since it already has TL_WRITE_ALLOW_WRITE lock on the first instance
@@ -94,7 +109,13 @@ select release_lock("lock_bug45143_wait");
--echo # Switch to connection 'con_bug45143_1'.
connection con_bug45143_1;
--echo # Reap INSERT statement.
+--echo # In Statement and Mixed replication mode we get here "Unsafe
+--echo # for binlog" warnings. In row mode there are no warnings.
+--echo # Hide the discrepancy.
+--disable_warnings
--reap
+--enable_warnings
+
--echo # Switch to connection 'con_bug45143_3'.
connection con_bug45143_3;
@@ -110,9 +131,53 @@ disconnect con_bug45143_2;
disconnect con_bug45143_3;
set debug_sync= 'RESET';
set @@global.general_log= @old_general_log;
+drop view v1;
drop table t1;
+--echo #
+--echo # Bug#50821 Deadlock between LOCK TABLES and ALTER TABLE
+--echo #
+
+--disable_warnings
+DROP TABLE IF EXISTS t1, t2;
+--enable_warnings
+
+CREATE TABLE t1(id INT);
+CREATE TABLE t2(id INT);
+
+--echo # Connection con2
+connect (con2, localhost, root);
+START TRANSACTION;
+SELECT * FROM t1;
+
+--echo # Connection default
+connection default;
+--echo # Sending:
+--send ALTER TABLE t1 ADD COLUMN j INT
+
+--echo # Connection con2
+connection con2;
+let $wait_condition=
+ SELECT COUNT(*) = 1 FROM information_schema.processlist
+ WHERE state = "Waiting for table"
+ AND info = "ALTER TABLE t1 ADD COLUMN j INT";
+--source include/wait_condition.inc
+
+--echo # This used to cause a deadlock.
+INSERT INTO t2 SELECT * FROM t1;
+
+COMMIT;
+
+--echo # Connection default
+connection default;
+--echo # Reaping ALTER TABLE t1 ADD COLUMN j INT
+--reap
+
+DROP TABLE t1, t2;
+disconnect con2;
+
+
# Check that all connections opened by test cases in this file are really
# gone so execution of other tests won't be affected by their presence.
--source include/wait_until_count_sessions.inc
diff --git a/mysql-test/t/lowercase_table2.test b/mysql-test/t/lowercase_table2.test
index 92add60616a..b8c7f532cde 100644
--- a/mysql-test/t/lowercase_table2.test
+++ b/mysql-test/t/lowercase_table2.test
@@ -201,10 +201,9 @@ create table t_bug44738_UPPERCASE (i int);
drop table t_bug44738_UPPERCASE;
--echo # Finally, let us check that another issue which was exposed by
---echo # the original test case is solved. I.e. that fuse in CREATE TABLE
---echo # which ensures that table is not created if there is an entry for
---echo # it in TDC even though it was removed from disk uses normalized
---echo # version of the table name.
+--echo # the original test case is solved. I.e. that the table is not
+--echo # created if there is an entry for it in TDC even though it was
+--echo # removed from disk.
create table t_bug44738_UPPERCASE (i int) engine = myisam;
--echo # Load table definition in TDC.
select table_schema, table_name, table_comment from information_schema.tables
@@ -214,9 +213,10 @@ let $MYSQLD_DATADIR= `select @@datadir`;
--remove_file $MYSQLD_DATADIR/test/t_bug44738_UPPERCASE.frm
--remove_file $MYSQLD_DATADIR/test/t_bug44738_UPPERCASE.MYD
--remove_file $MYSQLD_DATADIR/test/t_bug44738_UPPERCASE.MYI
---echo # After manual removal of table still there should be an entry for table
---echo # in TDC so attempt to create table with the same name should fail.
---error ER_TABLE_EXISTS_ERROR
+--echo # Check that still there is an entry for table in TDC.
+show open tables like 't_bug44738_%';
+--echo # So attempt to create table with the same name should fail.
+--error ER_FILE_NOT_FOUND
create table t_bug44738_UPPERCASE (i int);
--echo # And should succeed after FLUSH TABLES.
flush tables;
diff --git a/mysql-test/t/mdl_sync.test b/mysql-test/t/mdl_sync.test
new file mode 100644
index 00000000000..b9a9241ce32
--- /dev/null
+++ b/mysql-test/t/mdl_sync.test
@@ -0,0 +1,3468 @@
+#
+# We need the Debug Sync Facility.
+#
+--source include/have_debug_sync.inc
+
+# We need InnoDB tables for some of the tests.
+--source include/have_innodb.inc
+
+# Save the initial number of concurrent sessions.
+--source include/count_sessions.inc
+
+
+# Clean up resources used in this test case.
+--disable_warnings
+SET DEBUG_SYNC= 'RESET';
+--enable_warnings
+
+#
+# Test the case of when a exclusive lock request waits for a
+# shared lock being upgraded to a exclusive lock.
+#
+
+connect (con1,localhost,root,,test,,);
+connect (con2,localhost,root,,test,,);
+connect (con3,localhost,root,,test,,);
+
+connection default;
+
+--disable_warnings
+drop table if exists t1,t2,t3;
+--enable_warnings
+
+create table t1 (i int);
+create table t2 (i int);
+
+--echo connection: default
+lock tables t2 read;
+
+connection con1;
+--echo connection: con1
+set debug_sync='mdl_upgrade_shared_lock_to_exclusive SIGNAL parked WAIT_FOR go';
+--send alter table t1 rename t3
+
+connection default;
+--echo connection: default
+set debug_sync= 'now WAIT_FOR parked';
+
+connection con2;
+--echo connection: con2
+set debug_sync='mdl_acquire_lock_wait SIGNAL go';
+--send drop table t1,t2
+
+connection con1;
+--echo connection: con1
+--reap
+
+connection default;
+--echo connection: default
+unlock tables;
+
+connection con2;
+--echo connection: con2
+--error ER_BAD_TABLE_ERROR
+--reap
+
+connection default;
+drop table t3;
+
+disconnect con1;
+disconnect con2;
+disconnect con3;
+
+# Clean up resources used in this test case.
+--disable_warnings
+SET DEBUG_SYNC= 'RESET';
+--enable_warnings
+
+
+--echo #
+--echo # Basic test coverage for type-of-operation aware metadata locks.
+--echo #
+--disable_warnings
+drop table if exists t1, t2, t3;
+--enable_warnings
+connect(mdl_con1,localhost,root,,);
+connect(mdl_con2,localhost,root,,);
+connect(mdl_con3,localhost,root,,);
+connection default;
+set debug_sync= 'RESET';
+create table t1 (c1 int);
+
+--echo #
+--echo # A) First let us check compatibility rules between differend kinds of
+--echo # type-of-operation aware metadata locks.
+--echo # Of course, these rules are already covered by the tests scattered
+--echo # across the test suite. But it still makes sense to have one place
+--echo # which covers all of them.
+--echo #
+
+--echo # 1) Acquire S (simple shared) lock on the table (by using HANDLER):
+--echo #
+handler t1 open;
+--echo #
+--echo # Switching to connection 'mdl_con1'.
+connection mdl_con1;
+--echo # Check that S, SH, SR and SW locks are compatible with it.
+handler t1 open t;
+handler t close;
+select column_name from information_schema.columns where
+ table_schema='test' and table_name='t1';
+select count(*) from t1;
+insert into t1 values (1), (1);
+--echo # Check that SNW lock is compatible with it. To do this use ALTER TABLE
+--echo # which will fail after opening the table and thus obtaining SNW metadata
+--echo # lock.
+--error ER_DUP_ENTRY
+alter table t1 add primary key (c1);
+--echo # Check that SNRW lock is compatible with S lock.
+lock table t1 write;
+insert into t1 values (1);
+unlock tables;
+--echo # Check that X lock is incompatible with S lock.
+--echo # Sending:
+--send rename table t1 to t2;
+--echo #
+--echo # Switching to connection 'mdl_con2'.
+connection mdl_con2;
+--echo # Check that the above RENAME is blocked because of S lock.
+let $wait_condition=
+ select count(*) = 1 from information_schema.processlist
+ where state = "Waiting for table" and info = "rename table t1 to t2";
+--source include/wait_condition.inc
+--echo #
+--echo # Switching to connection 'default'.
+connection default;
+--echo # Unblock RENAME TABLE.
+handler t1 close;
+--echo #
+--echo # Switching to connection 'mdl_con1'.
+connection mdl_con1;
+--echo # Reaping RENAME TABLE.
+--reap
+--echo # Restore the original state of the things.
+rename table t2 to t1;
+--echo #
+--echo # Switching to connection 'default'.
+connection default;
+handler t1 open;
+--echo #
+--echo # Switching to connection 'mdl_con1'.
+connection mdl_con1;
+--echo # Check that upgrade from SNW to X is blocked by presence of S lock.
+--echo # Sending:
+--send alter table t1 add column c2 int;
+--echo #
+--echo # Switching to connection 'mdl_con2'.
+connection mdl_con2;
+--echo # Check that the above ALTER TABLE is blocked because of S lock.
+let $wait_condition=
+ select count(*) = 1 from information_schema.processlist
+ where state = "Waiting for table" and info = "alter table t1 add column c2 int";
+--source include/wait_condition.inc
+--echo #
+--echo # Switching to connection 'default'.
+connection default;
+--echo # Unblock ALTER TABLE.
+handler t1 close;
+--echo #
+--echo # Switching to connection 'mdl_con1'.
+connection mdl_con1;
+--echo # Reaping ALTER TABLE.
+--reap
+--echo # Restore the original state of the things.
+alter table t1 drop column c2;
+--echo #
+--echo # Switching to connection 'default'.
+connection default;
+handler t1 open;
+--echo #
+--echo # Switching to connection 'mdl_con1'.
+connection mdl_con1;
+--echo # Check that upgrade from SNRW to X is blocked by presence of S lock.
+lock table t1 write;
+--echo # Sending:
+--send alter table t1 add column c2 int;
+--echo #
+--echo # Switching to connection 'mdl_con2'.
+connection mdl_con2;
+--echo # Check that the above upgrade of SNRW to X in ALTER TABLE is blocked
+--echo # because of S lock.
+let $wait_condition=
+ select count(*) = 1 from information_schema.processlist
+ where state = "Waiting for table" and info = "alter table t1 add column c2 int";
+--source include/wait_condition.inc
+--echo #
+--echo # Switching to connection 'default'.
+connection default;
+--echo # Unblock ALTER TABLE.
+handler t1 close;
+--echo #
+--echo # Switching to connection 'mdl_con1'.
+connection mdl_con1;
+--echo # Reaping ALTER TABLE.
+--reap
+--echo # Restore the original state of the things.
+alter table t1 drop column c2;
+unlock tables;
+--echo #
+--echo # Switching to connection 'default'.
+connection default;
+--echo #
+--echo # 2) Acquire SH (shared high-priority) lock on the table.
+--echo # We have to involve DEBUG_SYNC facility for this as usually
+--echo # such kind of locks are short-lived.
+--echo #
+set debug_sync= 'after_open_table_mdl_shared SIGNAL locked WAIT_FOR finish';
+--echo # Sending:
+--send select table_name, table_type, auto_increment, table_comment from information_schema.tables where table_schema='test' and table_name='t1';
+--echo #
+--echo # Switching to connection 'mdl_con1'.
+connection mdl_con1;
+set debug_sync= 'now WAIT_FOR locked';
+--echo # Check that S, SH, SR and SW locks are compatible with it.
+handler t1 open;
+handler t1 close;
+select column_name from information_schema.columns where
+ table_schema='test' and table_name='t1';
+select count(*) from t1;
+insert into t1 values (1);
+--echo # Check that SNW lock is compatible with it. To do this use ALTER TABLE
+--echo # which will fail after opening the table and thus obtaining SNW metadata
+--echo # lock.
+--error ER_DUP_ENTRY
+alter table t1 add primary key (c1);
+--echo # Check that SNRW lock is compatible with SH lock.
+lock table t1 write;
+delete from t1 limit 1;
+unlock tables;
+--echo # Check that X lock is incompatible with SH lock.
+--echo # Sending:
+--send rename table t1 to t2;
+--echo #
+--echo # Switching to connection 'mdl_con2'.
+connection mdl_con2;
+--echo # Check that the above RENAME is blocked because of SH lock.
+let $wait_condition=
+ select count(*) = 1 from information_schema.processlist
+ where state = "Waiting for table" and info = "rename table t1 to t2";
+--source include/wait_condition.inc
+--echo # Unblock RENAME TABLE.
+set debug_sync= 'now SIGNAL finish';
+--echo #
+--echo # Switching to connection 'default'.
+connection default;
+--echo # Reaping SELECT ... FROM I_S.
+--reap
+--echo #
+--echo # Switching to connection 'mdl_con1'.
+connection mdl_con1;
+--echo # Reaping RENAME TABLE.
+--reap
+--echo # Restore the original state of the things.
+rename table t2 to t1;
+--echo #
+--echo # Switching to connection 'default'.
+connection default;
+set debug_sync= 'after_open_table_mdl_shared SIGNAL locked WAIT_FOR finish';
+--echo # Sending:
+--send select table_name, table_type, auto_increment, table_comment from information_schema.tables where table_schema='test' and table_name='t1';
+--echo #
+--echo # Switching to connection 'mdl_con1'.
+connection mdl_con1;
+set debug_sync= 'now WAIT_FOR locked';
+--echo # Check that upgrade from SNW to X is blocked by presence of SH lock.
+--echo # Sending:
+--send alter table t1 add column c2 int;
+--echo #
+--echo # Switching to connection 'mdl_con2'.
+connection mdl_con2;
+--echo # Check that the above ALTER TABLE is blocked because of SH lock.
+let $wait_condition=
+ select count(*) = 1 from information_schema.processlist
+ where state = "Waiting for table" and info = "alter table t1 add column c2 int";
+--source include/wait_condition.inc
+--echo # Unblock RENAME TABLE.
+set debug_sync= 'now SIGNAL finish';
+--echo #
+--echo # Switching to connection 'default'.
+connection default;
+--echo # Reaping SELECT ... FROM I_S.
+--reap
+--echo #
+--echo # Switching to connection 'mdl_con1'.
+connection mdl_con1;
+--echo # Reaping ALTER TABLE.
+--reap
+--echo # Restore the original state of the things.
+alter table t1 drop column c2;
+--echo #
+--echo # Switching to connection 'default'.
+connection default;
+set debug_sync= 'after_open_table_mdl_shared SIGNAL locked WAIT_FOR finish';
+--send select table_name, table_type, auto_increment, table_comment from information_schema.tables where table_schema='test' and table_name='t1';
+--echo #
+--echo # Switching to connection 'mdl_con1'.
+connection mdl_con1;
+set debug_sync= 'now WAIT_FOR locked';
+--echo # Check that upgrade from SNRW to X is blocked by presence of S lock.
+lock table t1 write;
+--echo # Sending:
+--send alter table t1 add column c2 int;
+--echo #
+--echo # Switching to connection 'mdl_con2'.
+connection mdl_con2;
+--echo # Check that the above upgrade of SNRW to X in ALTER TABLE is blocked
+--echo # because of S lock.
+let $wait_condition=
+ select count(*) = 1 from information_schema.processlist
+ where state = "Waiting for table" and info = "alter table t1 add column c2 int";
+--source include/wait_condition.inc
+--echo # Unblock RENAME TABLE.
+set debug_sync= 'now SIGNAL finish';
+--echo #
+--echo # Switching to connection 'default'.
+connection default;
+--echo # Reaping SELECT ... FROM I_S.
+--reap
+--echo #
+--echo # Switching to connection 'mdl_con1'.
+connection mdl_con1;
+--echo # Reaping ALTER TABLE.
+--reap
+--echo # Restore the original state of the things.
+alter table t1 drop column c2;
+unlock tables;
+--echo #
+--echo # Switching to connection 'default'.
+connection default;
+--echo #
+--echo #
+--echo # 3) Acquire SR lock on the table.
+--echo #
+--echo #
+begin;
+select count(*) from t1;
+--echo #
+--echo # Switching to connection 'mdl_con1'.
+connection mdl_con1;
+--echo # Check that S, SH, SR and SW locks are compatible with it.
+handler t1 open;
+handler t1 close;
+select column_name from information_schema.columns where
+ table_schema='test' and table_name='t1';
+select count(*) from t1;
+insert into t1 values (1);
+--echo # Check that SNW lock is compatible with it. To do this use ALTER TABLE
+--echo # which will fail after opening the table and thus obtaining SNW metadata
+--echo # lock.
+--error ER_DUP_ENTRY
+alter table t1 add primary key (c1);
+--echo # Check that SNRW lock is not compatible with SR lock.
+--echo # Sending:
+--send lock table t1 write;
+--echo #
+--echo # Switching to connection 'default'.
+connection default;
+--echo # Check that the above LOCK TABLES is blocked because of SR lock.
+let $wait_condition=
+ select count(*) = 1 from information_schema.processlist
+ where state = "Waiting for table" and info = "lock table t1 write";
+--source include/wait_condition.inc
+--echo # Unblock LOCK TABLES.
+commit;
+--echo #
+--echo # Switching to connection 'mdl_con1'.
+connection mdl_con1;
+--echo # Reaping LOCK TABLES.
+--reap
+delete from t1 limit 1;
+unlock tables;
+--echo #
+--echo # Switching to connection 'default'.
+connection default;
+begin;
+select count(*) from t1;
+--echo #
+--echo # Switching to connection 'mdl_con1'.
+connection mdl_con1;
+--echo # Check that X lock is incompatible with SR lock.
+--echo # Sending:
+--send rename table t1 to t2;
+--echo #
+--echo # Switching to connection 'mdl_con2'.
+connection mdl_con2;
+--echo # Check that the above RENAME is blocked because of SR lock.
+let $wait_condition=
+ select count(*) = 1 from information_schema.processlist
+ where state = "Waiting for table" and info = "rename table t1 to t2";
+--source include/wait_condition.inc
+--echo #
+--echo # Switching to connection 'default'.
+connection default;
+--echo # Unblock RENAME TABLE.
+commit;
+--echo #
+--echo # Switching to connection 'mdl_con1'.
+connection mdl_con1;
+--echo # Reaping RENAME TABLE.
+--reap
+--echo # Restore the original state of the things.
+rename table t2 to t1;
+--echo #
+--echo # Switching to connection 'default'.
+connection default;
+begin;
+select count(*) from t1;
+--echo #
+--echo # Switching to connection 'mdl_con1'.
+connection mdl_con1;
+--echo # Check that upgrade from SNW to X is blocked by presence of SR lock.
+--echo # Sending:
+--send alter table t1 add column c2 int;
+--echo #
+--echo # Switching to connection 'mdl_con2'.
+connection mdl_con2;
+--echo # Check that the above ALTER TABLE is blocked because of SR lock.
+let $wait_condition=
+ select count(*) = 1 from information_schema.processlist
+ where state = "Waiting for table" and info = "alter table t1 add column c2 int";
+--source include/wait_condition.inc
+--echo #
+--echo # Switching to connection 'default'.
+connection default;
+--echo # Unblock ALTER TABLE.
+commit;
+--echo #
+--echo # Switching to connection 'mdl_con1'.
+connection mdl_con1;
+--echo # Reaping ALTER TABLE.
+--reap
+--echo # Restore the original state of the things.
+alter table t1 drop column c2;
+--echo #
+--echo # There is no need to check that upgrade from SNRW to X is blocked
+--echo # by presence of SR lock because SNRW is incompatible with SR anyway.
+--echo #
+--echo #
+--echo # Switching to connection 'default'.
+connection default;
+--echo #
+--echo #
+--echo # 4) Acquire SW lock on the table.
+--echo #
+--echo #
+begin;
+insert into t1 values (1);
+--echo #
+--echo # Switching to connection 'mdl_con1'.
+connection mdl_con1;
+--echo # Check that S, SH, SR and SW locks are compatible with it.
+handler t1 open;
+handler t1 close;
+select column_name from information_schema.columns where
+ table_schema='test' and table_name='t1';
+select count(*) from t1;
+insert into t1 values (1);
+--echo # Check that SNW lock is not compatible with SW lock.
+--echo # Again we use ALTER TABLE which fails after opening
+--echo # the table to avoid upgrade of SNW -> X.
+--echo # Sending:
+--send alter table t1 add primary key (c1);
+--echo #
+--echo # Switching to connection 'default'.
+connection default;
+--echo # Check that the above ALTER TABLE is blocked because of SW lock.
+let $wait_condition=
+ select count(*) = 1 from information_schema.processlist
+ where state = "Waiting for table" and info = "alter table t1 add primary key (c1)";
+--source include/wait_condition.inc
+--echo # Unblock ALTER TABLE.
+commit;
+--echo #
+--echo # Switching to connection 'mdl_con1'.
+connection mdl_con1;
+--echo # Reaping ALTER TABLE.
+--error ER_DUP_ENTRY
+--reap
+--echo #
+--echo # Switching to connection 'default'.
+connection default;
+begin;
+insert into t1 values (1);
+--echo #
+--echo # Switching to connection 'mdl_con1'.
+connection mdl_con1;
+--echo # Check that SNRW lock is not compatible with SW lock.
+--echo # Sending:
+--send lock table t1 write;
+--echo #
+--echo # Switching to connection 'default'.
+connection default;
+--echo # Check that the above LOCK TABLES is blocked because of SW lock.
+let $wait_condition=
+ select count(*) = 1 from information_schema.processlist
+ where state = "Waiting for table" and info = "lock table t1 write";
+--source include/wait_condition.inc
+--echo # Unblock LOCK TABLES.
+commit;
+--echo #
+--echo # Switching to connection 'mdl_con1'.
+connection mdl_con1;
+--echo # Reaping LOCK TABLES.
+--reap
+delete from t1 limit 2;
+unlock tables;
+--echo #
+--echo # Switching to connection 'default'.
+connection default;
+begin;
+insert into t1 values (1);
+--echo #
+--echo # Switching to connection 'mdl_con1'.
+connection mdl_con1;
+--echo # Check that X lock is incompatible with SW lock.
+--echo # Sending:
+--send rename table t1 to t2;
+--echo #
+--echo # Switching to connection 'mdl_con2'.
+connection mdl_con2;
+--echo # Check that the above RENAME is blocked because of SW lock.
+let $wait_condition=
+ select count(*) = 1 from information_schema.processlist
+ where state = "Waiting for table" and info = "rename table t1 to t2";
+--source include/wait_condition.inc
+--echo #
+--echo # Switching to connection 'default'.
+connection default;
+--echo # Unblock RENAME TABLE.
+commit;
+--echo #
+--echo # Switching to connection 'mdl_con1'.
+connection mdl_con1;
+--echo # Reaping RENAME TABLE.
+--reap
+--echo # Restore the original state of the things.
+rename table t2 to t1;
+--echo #
+--echo # There is no need to check that upgrade from SNW/SNRW to X is
+--echo # blocked by presence of SW lock because SNW/SNRW is incompatible
+--echo # with SW anyway.
+--echo #
+--echo #
+--echo # Switching to connection 'default'.
+connection default;
+--echo #
+--echo #
+--echo # 5) Acquire SNW lock on the table. We have to use DEBUG_SYNC for
+--echo # this, to prevent SNW from being immediately upgraded to X.
+--echo #
+set debug_sync= 'after_open_table_mdl_shared SIGNAL locked WAIT_FOR finish';
+--echo # Sending:
+--send alter table t1 add primary key (c1);
+--echo #
+--echo # Switching to connection 'mdl_con1'.
+connection mdl_con1;
+set debug_sync= 'now WAIT_FOR locked';
+--echo # Check that S, SH and SR locks are compatible with it.
+handler t1 open;
+handler t1 close;
+select column_name from information_schema.columns where
+ table_schema='test' and table_name='t1';
+select count(*) from t1;
+--echo # Check that SW lock is incompatible with SNW lock.
+--echo # Sending:
+--send delete from t1 limit 2;
+--echo #
+--echo # Switching to connection 'mdl_con2'.
+connection mdl_con2;
+--echo # Check that the above DELETE is blocked because of SNW lock.
+let $wait_condition=
+ select count(*) = 1 from information_schema.processlist
+ where state = "Waiting for table" and info = "delete from t1 limit 2";
+--source include/wait_condition.inc
+--echo # Unblock ALTER and thus DELETE.
+set debug_sync= 'now SIGNAL finish';
+--echo #
+--echo # Switching to connection 'default'.
+connection default;
+--echo # Reaping ALTER TABLE.
+--error ER_DUP_ENTRY
+--reap
+--echo #
+--echo # Switching to connection 'mdl_con1'.
+connection mdl_con1;
+--echo # Reaping DELETE.
+--reap
+--echo #
+--echo # Switching to connection 'default'.
+connection default;
+set debug_sync= 'after_open_table_mdl_shared SIGNAL locked WAIT_FOR finish';
+--echo # Sending:
+--send alter table t1 add primary key (c1);
+--echo #
+--echo # Switching to connection 'mdl_con1'.
+connection mdl_con1;
+set debug_sync= 'now WAIT_FOR locked';
+--echo # Check that SNW lock is incompatible with SNW lock.
+--echo # Sending:
+--send alter table t1 add primary key (c1);
+--echo #
+--echo # Switching to connection 'mdl_con2'.
+connection mdl_con2;
+--echo # Check that the above ALTER is blocked because of SNW lock.
+let $wait_condition=
+ select count(*) = 1 from information_schema.processlist
+ where state = "Waiting for table" and info = "alter table t1 add primary key (c1)";
+--source include/wait_condition.inc
+--echo # Unblock ALTERs.
+set debug_sync= 'now SIGNAL finish';
+--echo #
+--echo # Switching to connection 'default'.
+connection default;
+--echo # Reaping first ALTER TABLE.
+--error ER_DUP_ENTRY
+--reap
+--echo #
+--echo # Switching to connection 'mdl_con1'.
+connection mdl_con1;
+--echo # Reaping another ALTER TABLE.
+--error ER_DUP_ENTRY
+--reap
+--echo #
+--echo # Switching to connection 'default'.
+connection default;
+set debug_sync= 'after_open_table_mdl_shared SIGNAL locked WAIT_FOR finish';
+--echo # Sending:
+--send alter table t1 add primary key (c1);
+--echo #
+--echo # Switching to connection 'mdl_con1'.
+connection mdl_con1;
+set debug_sync= 'now WAIT_FOR locked';
+--echo # Check that SNRW lock is incompatible with SNW lock.
+--echo # Sending:
+--send lock table t1 write;
+--echo #
+--echo # Switching to connection 'mdl_con2'.
+connection mdl_con2;
+--echo # Check that the above LOCK TABLES is blocked because of SNW lock.
+let $wait_condition=
+ select count(*) = 1 from information_schema.processlist
+ where state = "Waiting for table" and info = "lock table t1 write";
+--source include/wait_condition.inc
+--echo # Unblock ALTER and thus LOCK TABLES.
+set debug_sync= 'now SIGNAL finish';
+--echo #
+--echo # Switching to connection 'default'.
+connection default;
+--echo # Reaping ALTER TABLE.
+--error ER_DUP_ENTRY
+--reap
+--echo #
+--echo # Switching to connection 'mdl_con1'.
+connection mdl_con1;
+--echo # Reaping LOCK TABLES
+--reap
+insert into t1 values (1);
+unlock tables;
+--echo #
+--echo # Switching to connection 'default'.
+connection default;
+set debug_sync= 'after_open_table_mdl_shared SIGNAL locked WAIT_FOR finish';
+--echo # Sending:
+--send alter table t1 add primary key (c1);
+--echo #
+--echo # Switching to connection 'mdl_con1'.
+connection mdl_con1;
+set debug_sync= 'now WAIT_FOR locked';
+--echo # Check that X lock is incompatible with SNW lock.
+--echo # Sending:
+--send rename table t1 to t2;
+--echo #
+--echo # Switching to connection 'mdl_con2'.
+connection mdl_con2;
+--echo # Check that the above RENAME is blocked because of SNW lock.
+let $wait_condition=
+ select count(*) = 1 from information_schema.processlist
+ where state = "Waiting for table" and info = "rename table t1 to t2";
+--source include/wait_condition.inc
+--echo # Unblock ALTER and thus RENAME TABLE.
+set debug_sync= 'now SIGNAL finish';
+--echo #
+--echo # Switching to connection 'default'.
+connection default;
+--echo # Reaping ALTER TABLE.
+--error ER_DUP_ENTRY
+--reap
+--echo #
+--echo # Switching to connection 'mdl_con1'.
+connection mdl_con1;
+--echo # Reaping RENAME TABLE
+--reap
+--echo # Revert back to original state of things.
+rename table t2 to t1;
+--echo #
+--echo # There is no need to check that upgrade from SNW/SNRW to X is
+--echo # blocked by presence of another SNW lock because SNW/SNRW is
+--echo # incompatible with SNW anyway.
+--echo #
+--echo # Switching to connection 'default'.
+connection default;
+--echo #
+--echo #
+--echo # 6) Acquire SNRW lock on the table.
+--echo #
+--echo #
+lock table t1 write;
+--echo #
+--echo # Switching to connection 'mdl_con1'.
+connection mdl_con1;
+--echo # Check that S and SH locks are compatible with it.
+handler t1 open;
+handler t1 close;
+select column_name from information_schema.columns where
+ table_schema='test' and table_name='t1';
+--echo # Check that SR lock is incompatible with SNRW lock.
+--echo # Sending:
+--send select count(*) from t1;
+--echo #
+--echo # Switching to connection 'default'.
+connection default;
+--echo # Check that the above SELECT is blocked because of SNRW lock.
+let $wait_condition=
+ select count(*) = 1 from information_schema.processlist
+ where state = "Waiting for table" and info = "select count(*) from t1";
+--source include/wait_condition.inc
+--echo # Unblock SELECT.
+unlock tables;
+--echo #
+--echo # Switching to connection 'mdl_con1'.
+connection mdl_con1;
+--echo # Reaping SELECT.
+--reap
+--echo #
+--echo # Switching to connection 'default'.
+connection default;
+lock table t1 write;
+--echo #
+--echo # Switching to connection 'mdl_con1'.
+connection mdl_con1;
+--echo # Check that SW lock is incompatible with SNRW lock.
+--echo # Sending:
+--send delete from t1 limit 1;
+--echo #
+--echo # Switching to connection 'default'.
+connection default;
+--echo # Check that the above DELETE is blocked because of SNRW lock.
+let $wait_condition=
+ select count(*) = 1 from information_schema.processlist
+ where state = "Waiting for table" and info = "delete from t1 limit 1";
+--source include/wait_condition.inc
+--echo # Unblock DELETE.
+unlock tables;
+--echo #
+--echo # Switching to connection 'mdl_con1'.
+connection mdl_con1;
+--echo # Reaping DELETE.
+--reap
+--echo #
+--echo # Switching to connection 'default'.
+connection default;
+lock table t1 write;
+--echo #
+--echo # Switching to connection 'mdl_con1'.
+connection mdl_con1;
+--echo # Check that SNW lock is incompatible with SNRW lock.
+--echo # Sending:
+--send alter table t1 add primary key (c1);
+--echo #
+--echo # Switching to connection 'default'.
+connection default;
+--echo # Check that the above ALTER is blocked because of UNWR lock.
+let $wait_condition=
+ select count(*) = 1 from information_schema.processlist
+ where state = "Waiting for table" and info = "alter table t1 add primary key (c1)";
+--source include/wait_condition.inc
+--echo # Unblock ALTER.
+unlock tables;
+--echo #
+--echo # Switching to connection 'mdl_con1'.
+connection mdl_con1;
+--echo # Reaping ALTER TABLE.
+--error ER_DUP_ENTRY
+--reap
+--echo #
+--echo # Switching to connection 'default'.
+connection default;
+lock table t1 write;
+--echo #
+--echo # Switching to connection 'mdl_con1'.
+connection mdl_con1;
+--echo # Check that SNRW lock is incompatible with SNRW lock.
+--echo # Sending:
+--send lock table t1 write;
+--echo #
+--echo # Switching to connection 'default'.
+connection default;
+--echo # Check that the above LOCK TABLES is blocked because of SNRW lock.
+let $wait_condition=
+ select count(*) = 1 from information_schema.processlist
+ where state = "Waiting for table" and info = "lock table t1 write";
+--source include/wait_condition.inc
+--echo # Unblock waiting LOCK TABLES.
+unlock tables;
+--echo #
+--echo # Switching to connection 'mdl_con1'.
+connection mdl_con1;
+--echo # Reaping LOCK TABLES
+--reap
+insert into t1 values (1);
+unlock tables;
+--echo #
+--echo # Switching to connection 'default'.
+connection default;
+lock table t1 write;
+--echo #
+--echo # Switching to connection 'mdl_con1'.
+connection mdl_con1;
+--echo # Check that X lock is incompatible with SNRW lock.
+--echo # Sending:
+--send rename table t1 to t2;
+--echo #
+--echo # Switching to connection 'default'.
+connection default;
+--echo # Check that the above RENAME is blocked because of SNRW lock.
+let $wait_condition=
+ select count(*) = 1 from information_schema.processlist
+ where state = "Waiting for table" and info = "rename table t1 to t2";
+--source include/wait_condition.inc
+--echo # Unblock RENAME TABLE
+unlock tables;
+--echo #
+--echo # Switching to connection 'mdl_con1'.
+connection mdl_con1;
+--echo # Reaping RENAME TABLE
+--reap
+--echo # Revert back to original state of things.
+rename table t2 to t1;
+--echo #
+--echo # There is no need to check that upgrade from SNW/SNRW to X is
+--echo # blocked by presence of another SNRW lock because SNW/SNRW is
+--echo # incompatible with SNRW anyway.
+--echo #
+--echo # Switching to connection 'default'.
+connection default;
+--echo #
+--echo #
+--echo # 7) Now do the same round of tests for X lock. We use additional
+--echo # table to get long-lived lock of this type.
+--echo #
+create table t2 (c1 int);
+--echo #
+--echo # Switching to connection 'mdl_con2'.
+connection mdl_con2;
+--echo # Take a lock on t2, so RENAME TABLE t1 TO t2 will get blocked
+--echo # after acquiring X lock on t1.
+lock tables t2 read;
+--echo #
+--echo # Switching to connection 'default'.
+connection default;
+--echo # Sending:
+--send rename table t1 to t2;
+--echo #
+--echo # Switching to connection 'mdl_con1'.
+connection mdl_con1;
+--echo # Check that RENAME has acquired X lock on t1 and is waiting for t2.
+let $wait_condition=
+select count(*) = 1 from information_schema.processlist
+where state = "Waiting for table" and info = "rename table t1 to t2";
+--source include/wait_condition.inc
+--echo # Check that S lock in incompatible with X lock.
+--echo # Sending:
+--send handler t1 open;
+--echo #
+--echo # Switching to connection 'mdl_con2'.
+connection mdl_con2;
+--echo # Check that the above HANDLER statement is blocked because of X lock.
+let $wait_condition=
+select count(*) = 1 from information_schema.processlist
+where state = "Waiting for table" and info = "handler t1 open";
+--source include/wait_condition.inc
+--echo # Unblock RENAME TABLE
+unlock tables;
+--echo #
+--echo # Switching to connection 'default'.
+connection default;
+--echo # Reaping RENAME TABLE.
+--error ER_TABLE_EXISTS_ERROR
+--reap
+--echo #
+--echo # Switching to connection 'mdl_con1'.
+connection mdl_con1;
+--echo # Reaping HANDLER.
+--reap
+handler t1 close;
+--echo #
+--echo # Switching to connection 'mdl_con2'.
+connection mdl_con2;
+--echo # Prepare for blocking RENAME TABLE.
+lock tables t2 read;
+--echo #
+--echo # Switching to connection 'default'.
+connection default;
+--echo # Sending:
+--send rename table t1 to t2;
+--echo #
+--echo # Switching to connection 'mdl_con1'.
+connection mdl_con1;
+--echo # Check that RENAME has acquired X lock on t1 and is waiting for t2.
+let $wait_condition=
+select count(*) = 1 from information_schema.processlist
+where state = "Waiting for table" and info = "rename table t1 to t2";
+--source include/wait_condition.inc
+--echo # Check that SH lock in incompatible with X lock.
+--echo # Sending:
+--send select column_name from information_schema.columns where table_schema='test' and table_name='t1';
+--echo #
+--echo # Switching to connection 'mdl_con2'.
+connection mdl_con2;
+--echo # Check that the above SELECT ... FROM I_S ... statement is blocked
+--echo # because of X lock.
+let $wait_condition=
+select count(*) = 1 from information_schema.processlist
+where state = "Waiting for table" and info like "select column_name from information_schema.columns%";
+--source include/wait_condition.inc
+--echo # Unblock RENAME TABLE
+unlock tables;
+--echo #
+--echo # Switching to connection 'default'.
+connection default;
+--echo # Reaping RENAME TABLE.
+--error ER_TABLE_EXISTS_ERROR
+--reap
+--echo #
+--echo # Switching to connection 'mdl_con1'.
+connection mdl_con1;
+--echo # Reaping SELECT ... FROM I_S.
+--reap
+--echo #
+--echo # Switching to connection 'mdl_con2'.
+connection mdl_con2;
+--echo # Prepare for blocking RENAME TABLE.
+lock tables t2 read;
+--echo #
+--echo # Switching to connection 'default'.
+connection default;
+--echo # Sending:
+--send rename table t1 to t2;
+--echo #
+--echo # Switching to connection 'mdl_con1'.
+connection mdl_con1;
+--echo # Check that RENAME has acquired X lock on t1 and is waiting for t2.
+let $wait_condition=
+select count(*) = 1 from information_schema.processlist
+where state = "Waiting for table" and info = "rename table t1 to t2";
+--source include/wait_condition.inc
+--echo # Check that SR lock in incompatible with X lock.
+--echo # Sending:
+--send select count(*) from t1;
+--echo #
+--echo # Switching to connection 'mdl_con2'.
+connection mdl_con2;
+--echo # Check that the above SELECT statement is blocked
+--echo # because of X lock.
+let $wait_condition=
+select count(*) = 1 from information_schema.processlist
+where state = "Waiting for table" and info = "select count(*) from t1";
+--source include/wait_condition.inc
+--echo # Unblock RENAME TABLE
+unlock tables;
+--echo #
+--echo # Switching to connection 'default'.
+connection default;
+--echo # Reaping RENAME TABLE.
+--error ER_TABLE_EXISTS_ERROR
+--reap
+--echo #
+--echo # Switching to connection 'mdl_con1'.
+connection mdl_con1;
+--echo # Reaping SELECT.
+--reap
+--echo #
+--echo # Switching to connection 'mdl_con2'.
+connection mdl_con2;
+--echo # Prepare for blocking RENAME TABLE.
+lock tables t2 read;
+--echo #
+--echo # Switching to connection 'default'.
+connection default;
+--echo # Sending:
+--send rename table t1 to t2;
+--echo #
+--echo # Switching to connection 'mdl_con1'.
+connection mdl_con1;
+--echo # Check that RENAME has acquired X lock on t1 and is waiting for t2.
+let $wait_condition=
+select count(*) = 1 from information_schema.processlist
+where state = "Waiting for table" and info = "rename table t1 to t2";
+--source include/wait_condition.inc
+--echo # Check that SW lock in incompatible with X lock.
+--echo # Sending:
+--send delete from t1 limit 1;
+--echo #
+--echo # Switching to connection 'mdl_con2'.
+connection mdl_con2;
+--echo # Check that the above DELETE statement is blocked
+--echo # because of X lock.
+let $wait_condition=
+select count(*) = 1 from information_schema.processlist
+where state = "Waiting for table" and info = "delete from t1 limit 1";
+--source include/wait_condition.inc
+--echo # Unblock RENAME TABLE
+unlock tables;
+--echo #
+--echo # Switching to connection 'default'.
+connection default;
+--echo # Reaping RENAME TABLE.
+--error ER_TABLE_EXISTS_ERROR
+--reap
+--echo #
+--echo # Switching to connection 'mdl_con1'.
+connection mdl_con1;
+--echo # Reaping DELETE.
+--reap
+--echo #
+--echo # Switching to connection 'mdl_con2'.
+connection mdl_con2;
+--echo # Prepare for blocking RENAME TABLE.
+lock tables t2 read;
+--echo #
+--echo # Switching to connection 'default'.
+connection default;
+--echo # Sending:
+--send rename table t1 to t2;
+--echo #
+--echo # Switching to connection 'mdl_con1'.
+connection mdl_con1;
+--echo # Check that RENAME has acquired X lock on t1 and is waiting for t2.
+let $wait_condition=
+select count(*) = 1 from information_schema.processlist
+where state = "Waiting for table" and info = "rename table t1 to t2";
+--source include/wait_condition.inc
+--echo # Check that SNW lock is incompatible with X lock.
+--echo # Sending:
+--send alter table t1 add primary key (c1);
+--echo #
+--echo # Switching to connection 'mdl_con2'.
+connection mdl_con2;
+--echo # Check that the above ALTER statement is blocked
+--echo # because of X lock.
+let $wait_condition=
+select count(*) = 1 from information_schema.processlist
+where state = "Waiting for table" and info = "alter table t1 add primary key (c1)";
+--source include/wait_condition.inc
+--echo # Unblock RENAME TABLE
+unlock tables;
+--echo #
+--echo # Switching to connection 'default'.
+connection default;
+--echo # Reaping RENAME TABLE
+--error ER_TABLE_EXISTS_ERROR
+--reap
+--echo #
+--echo # Switching to connection 'mdl_con1'.
+connection mdl_con1;
+--echo # Reaping ALTER.
+--error ER_DUP_ENTRY
+--reap
+--echo #
+--echo # Switching to connection 'mdl_con2'.
+connection mdl_con2;
+--echo # Prepare for blocking RENAME TABLE.
+lock tables t2 read;
+--echo #
+--echo # Switching to connection 'default'.
+connection default;
+--echo # Sending:
+--send rename table t1 to t2;
+--echo #
+--echo # Switching to connection 'mdl_con1'.
+connection mdl_con1;
+--echo # Check that RENAME has acquired X lock on t1 and is waiting for t2.
+let $wait_condition=
+select count(*) = 1 from information_schema.processlist
+where state = "Waiting for table" and info = "rename table t1 to t2";
+--source include/wait_condition.inc
+--echo # Check that SNRW lock is incompatible with X lock.
+--echo # Sending:
+--send lock table t1 write;
+--echo #
+--echo # Switching to connection 'mdl_con2'.
+connection mdl_con2;
+--echo # Check that the above LOCK TABLE statement is blocked
+--echo # because of X lock.
+let $wait_condition=
+select count(*) = 1 from information_schema.processlist
+where state = "Waiting for table" and info = "lock table t1 write";
+--source include/wait_condition.inc
+--echo # Unblock RENAME TABLE
+unlock tables;
+--echo #
+--echo # Switching to connection 'default'.
+connection default;
+--echo # Reaping RENAME TABLE
+--error ER_TABLE_EXISTS_ERROR
+--reap
+--echo #
+--echo # Switching to connection 'mdl_con1'.
+connection mdl_con1;
+--echo # Reaping LOCK TABLE.
+--reap
+unlock tables;
+--echo #
+--echo # Switching to connection 'mdl_con2'.
+connection mdl_con2;
+--echo # Prepare for blocking RENAME TABLE.
+lock tables t2 read;
+--echo #
+--echo # Switching to connection 'default'.
+connection default;
+--echo # Sending:
+--send rename table t1 to t2;
+--echo #
+--echo # Switching to connection 'mdl_con1'.
+connection mdl_con1;
+--echo # Check that RENAME has acquired X lock on t1 and is waiting for t2.
+let $wait_condition=
+select count(*) = 1 from information_schema.processlist
+where state = "Waiting for table" and info = "rename table t1 to t2";
+--source include/wait_condition.inc
+--echo # Check that X lock is incompatible with X lock.
+--echo # Sending:
+--send rename table t1 to t3;
+--echo #
+--echo # Switching to connection 'mdl_con2'.
+connection mdl_con2;
+--echo # Check that the above RENAME statement is blocked
+--echo # because of X lock.
+let $wait_condition=
+select count(*) = 1 from information_schema.processlist
+where state = "Waiting for table" and info = "rename table t1 to t3";
+--source include/wait_condition.inc
+--echo # Unblock RENAME TABLE
+unlock tables;
+--echo #
+--echo # Switching to connection 'default'.
+connection default;
+--echo # Reaping RENAME TABLE
+--error ER_TABLE_EXISTS_ERROR
+--reap
+--echo #
+--echo # Switching to connection 'mdl_con1'.
+connection mdl_con1;
+--echo # Reaping RENAME.
+--reap
+rename table t3 to t1;
+
+--echo #
+--echo # B) Now let us test compatibility in cases when both locks
+--echo # are pending. I.e. let us test rules for priorities between
+--echo # different types of metadata locks.
+--echo #
+
+--echo #
+--echo # Switching to connection 'mdl_con2'.
+connection mdl_con2;
+--echo #
+--echo # 1) Check compatibility for pending SNW lock.
+--echo #
+--echo # Acquire SW lock in order to create pending SNW lock later.
+begin;
+insert into t1 values (1);
+--echo #
+--echo # Switching to connection 'default'.
+connection default;
+--echo # Add pending SNW lock.
+--echo # Sending:
+--send alter table t1 add primary key (c1);
+--echo #
+--echo # Switching to connection 'mdl_con1'.
+connection mdl_con1;
+--echo # Check that ALTER TABLE is waiting with pending SNW lock.
+let $wait_condition=
+select count(*) = 1 from information_schema.processlist
+where state = "Waiting for table" and info = "alter table t1 add primary key (c1)";
+--source include/wait_condition.inc
+--echo # Check that S, SH and SR locks are compatible with pending SNW
+handler t1 open t;
+handler t close;
+select column_name from information_schema.columns where
+ table_schema='test' and table_name='t1';
+select count(*) from t1;
+--echo # Check that SW is incompatible with pending SNW
+--echo # Sending:
+--send delete from t1 limit 1;
+--echo #
+--echo # Switching to connection 'mdl_con2'.
+connection mdl_con2;
+--echo # Check that the above DELETE is blocked because of pending SNW lock.
+let $wait_condition=
+select count(*) = 1 from information_schema.processlist
+where state = "Waiting for table" and info = "delete from t1 limit 1";
+--source include/wait_condition.inc
+--echo # Unblock ALTER TABLE.
+commit;
+--echo #
+--echo # Switching to connection 'default'.
+connection default;
+--echo # Reaping ALTER.
+--error ER_DUP_ENTRY
+--reap
+--echo #
+--echo # Switching to connection 'mdl_con1'.
+connection mdl_con1;
+--echo # Reaping DELETE.
+--reap
+--echo #
+--echo # We can't do similar check for SNW, SNRW and X locks because
+--echo # they will also be blocked by active SW lock.
+--echo #
+--echo #
+--echo # Switching to connection 'mdl_con2'.
+connection mdl_con2;
+--echo #
+--echo # 2) Check compatibility for pending SNRW lock.
+--echo #
+--echo # Acquire SR lock in order to create pending SNRW lock.
+begin;
+select count(*) from t1;
+--echo #
+--echo # Switching to connection 'default'.
+connection default;
+--echo # Add pending SNRW lock.
+--echo # Sending:
+--send lock table t1 write;
+--echo #
+--echo # Switching to connection 'mdl_con1'.
+connection mdl_con1;
+--echo # Check that LOCK TABLE is waiting with pending SNRW lock.
+let $wait_condition=
+select count(*) = 1 from information_schema.processlist
+where state = "Waiting for table" and info = "lock table t1 write";
+--source include/wait_condition.inc
+--echo # Check that S and SH locks are compatible with pending SNRW
+handler t1 open t;
+handler t close;
+select column_name from information_schema.columns where
+ table_schema='test' and table_name='t1';
+--echo # Check that SR is incompatible with pending SNRW
+--echo # Sending:
+--send select count(*) from t1;
+--echo #
+--echo # Switching to connection 'mdl_con2'.
+connection mdl_con2;
+--echo # Check that the above SELECT is blocked because of pending SNRW lock.
+let $wait_condition=
+select count(*) = 1 from information_schema.processlist
+where state = "Waiting for table" and info = "select count(*) from t1";
+--source include/wait_condition.inc
+--echo # Unblock LOCK TABLE.
+commit;
+--echo #
+--echo # Switching to connection 'default'.
+connection default;
+--echo # Reaping LOCK TABLE.
+--reap
+unlock tables;
+--echo #
+--echo # Switching to connection 'mdl_con1'.
+connection mdl_con1;
+--echo # Reaping SELECT.
+--reap
+--echo # Restore pending SNRW lock.
+--echo #
+--echo # Switching to connection 'mdl_con2'.
+connection mdl_con2;
+begin;
+select count(*) from t1;
+--echo #
+--echo # Switching to connection 'default'.
+connection default;
+--echo # Sending:
+--send lock table t1 write;
+--echo #
+--echo # Switching to connection 'mdl_con1'.
+connection mdl_con1;
+--echo # Check that LOCK TABLE is waiting with pending SNRW lock.
+let $wait_condition=
+select count(*) = 1 from information_schema.processlist
+where state = "Waiting for table" and info = "lock table t1 write";
+--source include/wait_condition.inc
+--echo # Check that SW is incompatible with pending SNRW
+--echo # Sending:
+--send insert into t1 values (1);
+--echo #
+--echo # Switching to connection 'mdl_con2'.
+connection mdl_con2;
+--echo # Check that the above INSERT is blocked because of pending SNRW lock.
+let $wait_condition=
+select count(*) = 1 from information_schema.processlist
+where state = "Waiting for table" and info = "insert into t1 values (1)";
+--source include/wait_condition.inc
+--echo # Unblock LOCK TABLE.
+commit;
+--echo #
+--echo # Switching to connection 'default'.
+connection default;
+--echo # Reaping LOCK TABLE.
+--reap
+unlock tables;
+--echo #
+--echo # Switching to connection 'mdl_con1'.
+connection mdl_con1;
+--echo # Reaping INSERT.
+--reap
+--echo # Restore pending SNRW lock.
+--echo #
+--echo # Switching to connection 'mdl_con2'.
+connection mdl_con2;
+begin;
+select count(*) from t1;
+--echo #
+--echo # Switching to connection 'default'.
+connection default;
+--echo # Sending:
+--send lock table t1 write;
+--echo #
+--echo # Switching to connection 'mdl_con1'.
+connection mdl_con1;
+--echo # Check that LOCK TABLE is waiting with pending SNRW lock.
+let $wait_condition=
+select count(*) = 1 from information_schema.processlist
+where state = "Waiting for table" and info = "lock table t1 write";
+--source include/wait_condition.inc
+--echo # Check that SNW is compatible with pending SNRW
+--echo # So ALTER TABLE statements are not starved by LOCK TABLEs.
+--error ER_DUP_ENTRY
+alter table t1 add primary key (c1);
+--echo #
+--echo # Switching to connection 'mdl_con2'.
+connection mdl_con2;
+--echo # Unblock LOCK TABLE.
+commit;
+--echo #
+--echo # Switching to connection 'default'.
+connection default;
+--echo # Reaping LOCK TABLE.
+--reap
+unlock tables;
+--echo #
+--echo # We can't do similar check for SNRW and X locks because
+--echo # they will also be blocked by active SR lock.
+--echo #
+--echo #
+--echo # Switching to connection 'mdl_con2'.
+connection mdl_con2;
+--echo #
+--echo # 3) Check compatibility for pending X lock.
+--echo #
+--echo # Acquire SR lock in order to create pending X lock.
+begin;
+select count(*) from t1;
+--echo #
+--echo # Switching to connection 'default'.
+connection default;
+--echo # Add pending X lock.
+--echo # Sending:
+--send rename table t1 to t2;
+--echo #
+--echo # Switching to connection 'mdl_con1'.
+connection mdl_con1;
+--echo # Check that RENAME TABLE is waiting with pending X lock.
+let $wait_condition=
+select count(*) = 1 from information_schema.processlist
+where state = "Waiting for table" and info = "rename table t1 to t2";
+--source include/wait_condition.inc
+--echo # Check that SH locks are compatible with pending X
+select column_name from information_schema.columns where
+ table_schema='test' and table_name='t1';
+--echo # Check that S is incompatible with pending X
+--echo # Sending:
+--send handler t1 open;
+--echo #
+--echo # Switching to connection 'mdl_con2'.
+connection mdl_con2;
+--echo # Check that the above HANDLER OPEN is blocked because of pending X lock.
+let $wait_condition=
+select count(*) = 1 from information_schema.processlist
+where state = "Waiting for table" and info = "handler t1 open";
+--source include/wait_condition.inc
+--echo # Unblock RENAME TABLE.
+commit;
+--echo #
+--echo # Switching to connection 'default'.
+connection default;
+--echo # Reaping RENAME TABLE.
+--error ER_TABLE_EXISTS_ERROR
+--reap
+--echo #
+--echo # Switching to connection 'mdl_con1'.
+connection mdl_con1;
+--echo # Reaping HANDLER t1 OPEN.
+--reap
+handler t1 close;
+--echo # Restore pending X lock.
+--echo #
+--echo # Switching to connection 'mdl_con2'.
+connection mdl_con2;
+begin;
+select count(*) from t1;
+--echo #
+--echo # Switching to connection 'default'.
+connection default;
+--echo # Add pending X lock.
+--echo # Sending:
+--send rename table t1 to t2;
+--echo #
+--echo # Switching to connection 'mdl_con1'.
+connection mdl_con1;
+--echo # Check that RENAME TABLE is waiting with pending X lock.
+let $wait_condition=
+select count(*) = 1 from information_schema.processlist
+where state = "Waiting for table" and info = "rename table t1 to t2";
+--source include/wait_condition.inc
+--echo # Check that SR is incompatible with pending X
+--echo # Sending:
+--send select count(*) from t1;
+--echo #
+--echo # Switching to connection 'mdl_con2'.
+connection mdl_con2;
+--echo # Check that the above SELECT is blocked because of pending X lock.
+let $wait_condition=
+select count(*) = 1 from information_schema.processlist
+where state = "Waiting for table" and info = "select count(*) from t1";
+--source include/wait_condition.inc
+--echo # Unblock RENAME TABLE.
+commit;
+--echo #
+--echo # Switching to connection 'default'.
+connection default;
+--echo # Reaping RENAME TABLE.
+--error ER_TABLE_EXISTS_ERROR
+--reap
+--echo #
+--echo # Switching to connection 'mdl_con1'.
+connection mdl_con1;
+--echo # Reaping SELECT.
+--reap
+--echo # Restore pending X lock.
+--echo #
+--echo # Switching to connection 'mdl_con2'.
+connection mdl_con2;
+begin;
+select count(*) from t1;
+--echo #
+--echo # Switching to connection 'default'.
+connection default;
+--echo # Add pending X lock.
+--echo # Sending:
+--send rename table t1 to t2;
+--echo #
+--echo # Switching to connection 'mdl_con1'.
+connection mdl_con1;
+--echo # Check that RENAME TABLE is waiting with pending X lock.
+let $wait_condition=
+select count(*) = 1 from information_schema.processlist
+where state = "Waiting for table" and info = "rename table t1 to t2";
+--source include/wait_condition.inc
+--echo # Check that SW is incompatible with pending X
+--echo # Sending:
+--send delete from t1 limit 1;
+--echo #
+--echo # Switching to connection 'mdl_con2'.
+connection mdl_con2;
+--echo # Check that the above DELETE is blocked because of pending X lock.
+let $wait_condition=
+select count(*) = 1 from information_schema.processlist
+where state = "Waiting for table" and info = "delete from t1 limit 1";
+--source include/wait_condition.inc
+--echo # Unblock RENAME TABLE.
+commit;
+--echo #
+--echo # Switching to connection 'default'.
+connection default;
+--echo # Reaping RENAME TABLE.
+--error ER_TABLE_EXISTS_ERROR
+--reap
+--echo #
+--echo # Switching to connection 'mdl_con1'.
+connection mdl_con1;
+--echo # Reaping DELETE.
+--reap
+--echo # Restore pending X lock.
+--echo #
+--echo # Switching to connection 'mdl_con2'.
+connection mdl_con2;
+begin;
+select count(*) from t1;
+--echo #
+--echo # Switching to connection 'default'.
+connection default;
+--echo # Add pending X lock.
+--echo # Sending:
+--send rename table t1 to t2;
+--echo #
+--echo # Switching to connection 'mdl_con1'.
+connection mdl_con1;
+--echo # Check that RENAME TABLE is waiting with pending X lock.
+let $wait_condition=
+select count(*) = 1 from information_schema.processlist
+where state = "Waiting for table" and info = "rename table t1 to t2";
+--source include/wait_condition.inc
+--echo # Check that SNW is incompatible with pending X
+--echo # Sending:
+--send alter table t1 add primary key (c1);
+--echo #
+--echo # Switching to connection 'mdl_con2'.
+connection mdl_con2;
+--echo # Check that the above ALTER TABLE is blocked because of pending X lock.
+let $wait_condition=
+select count(*) = 1 from information_schema.processlist
+where state = "Waiting for table" and info = "alter table t1 add primary key (c1)";
+--source include/wait_condition.inc
+--echo # Unblock RENAME TABLE.
+commit;
+--echo #
+--echo # Switching to connection 'default'.
+connection default;
+--echo # Reaping RENAME TABLE.
+--error ER_TABLE_EXISTS_ERROR
+--reap
+--echo #
+--echo # Switching to connection 'mdl_con1'.
+connection mdl_con1;
+--echo # Reaping ALTER TABLE.
+--error ER_DUP_ENTRY
+--reap
+--echo # Restore pending X lock.
+--echo #
+--echo # Switching to connection 'mdl_con2'.
+connection mdl_con2;
+handler t1 open;
+--echo #
+--echo # Switching to connection 'default'.
+connection default;
+--echo # Add pending X lock.
+--echo # Sending:
+--send rename table t1 to t2;
+--echo #
+--echo # Switching to connection 'mdl_con1'.
+connection mdl_con1;
+--echo # Check that RENAME TABLE is waiting with pending X lock.
+let $wait_condition=
+select count(*) = 1 from information_schema.processlist
+where state = "Waiting for table" and info = "rename table t1 to t2";
+--source include/wait_condition.inc
+--echo # Check that SNRW is incompatible with pending X
+--echo # Sending:
+--send lock table t1 write;
+--echo #
+--echo # Switching to connection 'mdl_con3'.
+connection mdl_con3;
+--echo # Check that the above LOCK TABLES is blocked because of pending X lock.
+let $wait_condition=
+select count(*) = 1 from information_schema.processlist
+where state = "Waiting for table" and info = "lock table t1 write";
+--source include/wait_condition.inc
+--echo #
+--echo # Switching to connection 'mdl_con2'.
+connection mdl_con2;
+--echo # Unblock RENAME TABLE.
+handler t1 close;
+--echo #
+--echo # Switching to connection 'default'.
+connection default;
+--echo # Reaping RENAME TABLE.
+--error ER_TABLE_EXISTS_ERROR
+--reap
+--echo #
+--echo # Switching to connection 'mdl_con1'.
+connection mdl_con1;
+--echo # Reaping LOCK TABLES.
+--reap
+unlock tables;
+--echo #
+--echo # Switching to connection 'default'.
+connection default;
+
+--echo #
+--echo #
+--echo # C) Now let us test how type-of-operation locks are handled in
+--echo # transactional context. Obviously we are mostly interested
+--echo # in conflicting types of locks.
+--echo #
+
+--echo #
+--echo # 1) Let us check how various locks used within transactional
+--echo # context interact with active/pending SNW lock.
+--echo #
+--echo # We start with case when we are acquiring lock on the table
+--echo # which was not used in the transaction before.
+begin;
+select count(*) from t1;
+--echo #
+--echo # Switching to connection 'mdl_con1'.
+connection mdl_con1;
+--echo # Create an active SNW lock on t2.
+--echo # We have to use DEBUG_SYNC facility as otherwise SNW lock
+--echo # will be immediately released (or upgraded to X lock).
+insert into t2 values (1), (1);
+set debug_sync= 'after_open_table_mdl_shared SIGNAL locked WAIT_FOR finish';
+--echo # Sending:
+--send alter table t2 add primary key (c1);
+--echo #
+--echo # Switching to connection 'default'.
+connection default;
+set debug_sync= 'now WAIT_FOR locked';
+--echo # SR lock should be acquired without any waiting.
+select count(*) from t2;
+commit;
+--echo # Now let us check that we will wait in case of SW lock.
+begin;
+select count(*) from t1;
+--echo # Sending:
+--send insert into t2 values (1);
+--echo #
+--echo # Switching to connection 'mdl_con2'.
+connection mdl_con2;
+--echo # Check that the above INSERT is blocked.
+let $wait_condition=
+select count(*) = 1 from information_schema.processlist
+where state = "Waiting for table" and info = "insert into t2 values (1)";
+--source include/wait_condition.inc
+--echo # Unblock ALTER TABLE and thus INSERT.
+set debug_sync= 'now SIGNAL finish';
+--echo #
+--echo # Switching to connection 'mdl_con1'.
+connection mdl_con1;
+--echo # Reap ALTER TABLE.
+--error ER_DUP_ENTRY
+--reap
+--echo #
+--echo # Switching to connection 'default'.
+connection default;
+--echo # Reap INSERT.
+--reap
+commit;
+--echo #
+--echo # Now let us see what happens when we are acquiring lock on the table
+--echo # which is already used in transaction.
+--echo #
+--echo # *) First, case when transaction which has SR lock on the table also
+--echo # locked in SNW mode acquires yet another SR lock and then tries
+--echo # to acquire SW lock.
+begin;
+select count(*) from t1;
+--echo #
+--echo # Switching to connection 'mdl_con1'.
+connection mdl_con1;
+--echo # Create an active SNW lock on t1.
+set debug_sync= 'after_open_table_mdl_shared SIGNAL locked WAIT_FOR finish';
+--echo # Sending:
+--send alter table t1 add primary key (c1);
+--echo #
+--echo # Switching to connection 'default'.
+connection default;
+set debug_sync= 'now WAIT_FOR locked';
+--echo # We should still be able to get SR lock without waiting.
+select count(*) from t1;
+--echo # Since the above ALTER TABLE is not upgrading SNW lock to X by waiting
+--echo # for SW lock we won't create deadlock.
+--echo # So the below INSERT should not end-up with ER_LOCK_DEADLOCK error.
+--echo # Sending:
+--send insert into t1 values (1);
+--echo #
+--echo # Switching to connection 'mdl_con2'.
+connection mdl_con2;
+--echo # Check that the above INSERT is blocked.
+let $wait_condition=
+select count(*) = 1 from information_schema.processlist
+where state = "Waiting for table" and info = "insert into t1 values (1)";
+--source include/wait_condition.inc
+--echo # Unblock ALTER TABLE and thus INSERT.
+set debug_sync= 'now SIGNAL finish';
+--echo #
+--echo # Switching to connection 'mdl_con1'.
+connection mdl_con1;
+--echo # Reap ALTER TABLE.
+--error ER_DUP_ENTRY
+--reap
+--echo #
+--echo # Switching to connection 'default'.
+connection default;
+--echo # Reap INSERT.
+--reap
+commit;
+--echo #
+--echo # **) Now test in which transaction that has SW lock on the table
+--echo # against which there is pending SNW lock acquires SR and SW
+--echo # locks on this table.
+--echo #
+begin;
+insert into t1 values (1);
+--echo #
+--echo # Switching to connection 'mdl_con1'.
+connection mdl_con1;
+--echo # Create pending SNW lock on t1.
+--echo # Sending:
+--send alter table t1 add primary key (c1);
+--echo #
+--echo # Switching to connection 'default'.
+connection default;
+--echo # Wait until ALTER TABLE starts waiting for SNW lock.
+let $wait_condition=
+select count(*) = 1 from information_schema.processlist
+where state = "Waiting for table" and info = "alter table t1 add primary key (c1)";
+--source include/wait_condition.inc
+--echo # We should still be able to get both SW and SR locks without waiting.
+select count(*) from t1;
+delete from t1 limit 1;
+--echo # Unblock ALTER TABLE.
+commit;
+--echo #
+--echo # Switching to connection 'mdl_con1'.
+connection mdl_con1;
+--echo # Reap ALTER TABLE.
+--error ER_DUP_ENTRY
+--reap
+--echo #
+--echo # Switching to connection 'default'.
+connection default;
+--echo #
+--echo # 2) Now similar tests for active SNW lock which is being upgraded
+--echo # to X lock.
+--echo #
+--echo # Again we start with case when we are acquiring lock on the
+--echo # table which was not used in the transaction before.
+begin;
+select count(*) from t1;
+--echo #
+--echo # Switching to connection 'mdl_con2'.
+connection mdl_con2;
+--echo # Start transaction which will prevent SNW -> X upgrade from
+--echo # completing immediately.
+begin;
+select count(*) from t2;
+--echo #
+--echo # Switching to connection 'mdl_con1'.
+connection mdl_con1;
+--echo # Create SNW lock pending upgrade to X on t2.
+--echo # Sending:
+--send alter table t2 add column c2 int;
+--echo #
+--echo # Switching to connection 'default'.
+connection default;
+--echo # Wait until ALTER TABLE starts waiting X lock.
+let $wait_condition=
+select count(*) = 1 from information_schema.processlist
+where state = "Waiting for table" and info = "alter table t2 add column c2 int";
+--source include/wait_condition.inc
+--echo # Check that attempt to acquire SR lock on t2 causes waiting.
+--echo # Sending:
+--send select count(*) from t2;
+--echo #
+--echo # Switching to connection 'mdl_con2'.
+connection mdl_con2;
+--echo # Check that the above SELECT is blocked.
+let $wait_condition=
+select count(*) = 1 from information_schema.processlist
+where state = "Waiting for table" and info = "select count(*) from t2";
+--source include/wait_condition.inc
+--echo # Unblock ALTER TABLE.
+commit;
+--echo #
+--echo # Switching to connection 'mdl_con1'.
+connection mdl_con1;
+--echo # Reap ALTER TABLE.
+--reap
+--echo #
+--echo # Switching to connection 'default'.
+connection default;
+--echo # Reap SELECT.
+--reap
+commit;
+--echo # Do similar check for SW lock.
+begin;
+select count(*) from t1;
+--echo #
+--echo # Switching to connection 'mdl_con2'.
+connection mdl_con2;
+--echo # Start transaction which will prevent SNW -> X upgrade from
+--echo # completing immediately.
+begin;
+select count(*) from t2;
+--echo #
+--echo # Switching to connection 'mdl_con1'.
+connection mdl_con1;
+--echo # Create SNW lock pending upgrade to X on t2.
+--echo # Sending:
+--send alter table t2 drop column c2;
+--echo #
+--echo # Switching to connection 'default'.
+connection default;
+--echo # Wait until ALTER TABLE starts waiting X lock.
+let $wait_condition=
+select count(*) = 1 from information_schema.processlist
+where state = "Waiting for table" and info = "alter table t2 drop column c2";
+--source include/wait_condition.inc
+--echo # Check that attempt to acquire SW lock on t2 causes waiting.
+--echo # Sending:
+--send insert into t2 values (1);
+--echo #
+--echo # Switching to connection 'mdl_con2'.
+connection mdl_con2;
+--echo # Check that the above INSERT is blocked.
+let $wait_condition=
+select count(*) = 1 from information_schema.processlist
+where state = "Waiting for table" and info = "insert into t2 values (1)";
+--source include/wait_condition.inc
+--echo # Unblock ALTER TABLE.
+commit;
+--echo #
+--echo # Switching to connection 'mdl_con1'.
+connection mdl_con1;
+--echo # Reap ALTER TABLE.
+--reap
+--echo #
+--echo # Switching to connection 'default'.
+connection default;
+--echo # Reap INSERT.
+--reap
+commit;
+--echo #
+--echo # Test for the case in which we are acquiring lock on the table
+--echo # which is already used in transaction.
+--echo #
+begin;
+select count(*) from t1;
+--echo #
+--echo # Switching to connection 'mdl_con1'.
+connection mdl_con1;
+--echo # Create SNW lock pending upgrade to X.
+--echo # Sending:
+--send alter table t1 add column c2 int;
+--echo #
+--echo # Switching to connection 'default'.
+connection default;
+--echo # Wait until ALTER TABLE starts waiting X lock.
+let $wait_condition=
+select count(*) = 1 from information_schema.processlist
+where state = "Waiting for table" and info = "alter table t1 add column c2 int";
+--source include/wait_condition.inc
+--echo # Check that transaction is still able to acquire SR lock.
+select count(*) from t1;
+--echo # Waiting trying to acquire SW lock will cause deadlock and
+--echo # therefore should cause an error.
+--error ER_LOCK_DEADLOCK
+delete from t1 limit 1;
+--echo # Unblock ALTER TABLE.
+commit;
+--echo #
+--echo # Switching to connection 'mdl_con1'.
+connection mdl_con1;
+--echo # Reap ALTER TABLE.
+--reap
+--echo #
+--echo # Switching to connection 'default'.
+connection default;
+--echo #
+--echo # 3) Check how various locks used within transactional context
+--echo # interact with active/pending SNRW lock.
+--echo #
+--echo # Once again we start with case when we are acquiring lock on
+--echo # the table which was not used in the transaction before.
+begin;
+select count(*) from t1;
+--echo #
+--echo # Switching to connection 'mdl_con1'.
+connection mdl_con1;
+lock table t2 write;
+--echo #
+--echo # Switching to connection 'default'.
+connection default;
+--echo # Attempt to acquire SR should be blocked. It should
+--echo # not cause errors as it does not creates deadlock.
+--echo # Sending:
+--send select count(*) from t2;
+--echo #
+--echo # Switching to connection 'mdl_con1'.
+connection mdl_con1;
+--echo # Check that the above SELECT is blocked
+let $wait_condition=
+select count(*) = 1 from information_schema.processlist
+where state = "Waiting for table" and info = "select count(*) from t2";
+--source include/wait_condition.inc
+--echo # Unblock SELECT.
+unlock tables;
+--echo #
+--echo # Switching to connection 'default'.
+connection default;
+--echo # Reap SELECT.
+--reap
+commit;
+--echo # Repeat the same test for SW lock.
+begin;
+select count(*) from t1;
+--echo #
+--echo # Switching to connection 'mdl_con1'.
+connection mdl_con1;
+lock table t2 write;
+--echo #
+--echo # Switching to connection 'default'.
+connection default;
+--echo # Again attempt to acquire SW should be blocked and should
+--echo # not cause any errors.
+--echo # Sending:
+--send delete from t2 limit 1;
+--echo #
+--echo # Switching to connection 'mdl_con1'.
+connection mdl_con1;
+--echo # Check that the above DELETE is blocked
+let $wait_condition=
+select count(*) = 1 from information_schema.processlist
+where state = "Waiting for table" and info = "delete from t2 limit 1";
+--source include/wait_condition.inc
+--echo # Unblock DELETE.
+unlock tables;
+--echo #
+--echo # Switching to connection 'default'.
+connection default;
+--echo # Reap DELETE.
+--reap
+commit;
+--echo #
+--echo # Now coverage for the case in which we are acquiring lock on
+--echo # the table which is already used in transaction and against
+--echo # which there is a pending SNRW lock request.
+--echo #
+--echo # *) Let us start with case when transaction has only a SR lock.
+--echo #
+begin;
+select count(*) from t1;
+--echo #
+--echo # Switching to connection 'mdl_con1'.
+connection mdl_con1;
+--echo # Sending:
+--send lock table t1 write;
+--echo #
+--echo # Switching to connection 'default'.
+connection default;
+--echo # Wait until LOCK TABLE is blocked creating pending request for X lock.
+let $wait_condition=
+select count(*) = 1 from information_schema.processlist
+where state = "Waiting for table" and info = "lock table t1 write";
+--source include/wait_condition.inc
+--echo # Check that another instance of SR lock is granted without waiting.
+select count(*) from t1;
+--echo # Attempt to wait for SW lock will lead to deadlock, thus
+--echo # the below statement should end with ER_LOCK_DEADLOCK error.
+--error ER_LOCK_DEADLOCK
+delete from t1 limit 1;
+--echo # Unblock LOCK TABLES.
+commit;
+--echo #
+--echo # Switching to connection 'mdl_con1'.
+connection mdl_con1;
+--echo # Reap LOCK TABLES.
+--reap
+unlock tables;
+--echo #
+--echo # Switching to connection 'default'.
+connection default;
+--echo #
+--echo # **) Now case when transaction has a SW lock.
+--echo #
+begin;
+delete from t1 limit 1;
+--echo #
+--echo # Switching to connection 'mdl_con1'.
+connection mdl_con1;
+--echo # Sending:
+--send lock table t1 write;
+--echo #
+--echo # Switching to connection 'default'.
+connection default;
+--echo # Wait until LOCK TABLE is blocked creating pending request for X lock.
+let $wait_condition=
+select count(*) = 1 from information_schema.processlist
+where state = "Waiting for table" and info = "lock table t1 write";
+--source include/wait_condition.inc
+--echo # Check that both SR and SW locks are granted without waiting
+--echo # and errors.
+select count(*) from t1;
+insert into t1 values (1, 1);
+--echo # Unblock LOCK TABLES.
+commit;
+--echo #
+--echo # Switching to connection 'mdl_con1'.
+connection mdl_con1;
+--echo # Reap LOCK TABLES.
+--reap
+unlock tables;
+--echo #
+--echo # Switching to connection 'default'.
+connection default;
+--echo #
+--echo # 4) Check how various locks used within transactional context
+--echo # interact with active/pending X lock.
+--echo #
+--echo # As usual we start with case when we are acquiring lock on
+--echo # the table which was not used in the transaction before.
+begin;
+select count(*) from t1;
+--echo #
+--echo # Switching to connection 'mdl_con2'.
+connection mdl_con2;
+--echo # Start transaction which will prevent X lock from going away
+--echo # immediately.
+begin;
+select count(*) from t2;
+--echo #
+--echo # Switching to connection 'mdl_con1'.
+connection mdl_con1;
+--echo # Create pending X lock on t2.
+--echo # Sending:
+--send rename table t2 to t3;
+--echo #
+--echo # Switching to connection 'default'.
+connection default;
+--echo # Wait until RENAME TABLE starts waiting with pending X lock.
+let $wait_condition=
+select count(*) = 1 from information_schema.processlist
+where state = "Waiting for table" and info = "rename table t2 to t3";
+--source include/wait_condition.inc
+--echo # Check that attempt to acquire SR lock on t2 causes waiting.
+--echo # Sending:
+--send select count(*) from t2;
+--echo #
+--echo # Switching to connection 'mdl_con2'.
+connection mdl_con2;
+--echo # Check that the above SELECT is blocked.
+let $wait_condition=
+select count(*) = 1 from information_schema.processlist
+where state = "Waiting for table" and info = "select count(*) from t2";
+--source include/wait_condition.inc
+--echo # Unblock RENAME TABLE.
+commit;
+--echo #
+--echo # Switching to connection 'mdl_con1'.
+connection mdl_con1;
+--echo # Reap RENAME TABLE.
+--reap
+--echo #
+--echo # Switching to connection 'default'.
+connection default;
+--echo # Reap SELECT.
+--error ER_NO_SUCH_TABLE
+--reap
+commit;
+rename table t3 to t2;
+--echo # The same test for SW lock.
+begin;
+select count(*) from t1;
+--echo #
+--echo # Switching to connection 'mdl_con2'.
+connection mdl_con2;
+--echo # Start transaction which will prevent X lock from going away
+--echo # immediately.
+begin;
+select count(*) from t2;
+--echo #
+--echo # Switching to connection 'mdl_con1'.
+connection mdl_con1;
+--echo # Create pending X lock on t2.
+--echo # Sending:
+--send rename table t2 to t3;
+--echo #
+--echo # Switching to connection 'default'.
+connection default;
+--echo # Wait until RENAME TABLE starts waiting with pending X lock.
+let $wait_condition=
+select count(*) = 1 from information_schema.processlist
+where state = "Waiting for table" and info = "rename table t2 to t3";
+--source include/wait_condition.inc
+--echo # Check that attempt to acquire SW lock on t2 causes waiting.
+--echo # Sending:
+--send delete from t2 limit 1;
+--echo #
+--echo # Switching to connection 'mdl_con2'.
+connection mdl_con2;
+--echo # Check that the above DELETE is blocked.
+let $wait_condition=
+select count(*) = 1 from information_schema.processlist
+where state = "Waiting for table" and info = "delete from t2 limit 1";
+--source include/wait_condition.inc
+--echo # Unblock RENAME TABLE.
+commit;
+--echo #
+--echo # Switching to connection 'mdl_con1'.
+connection mdl_con1;
+--echo # Reap RENAME TABLE.
+--reap
+--echo #
+--echo # Switching to connection 'default'.
+connection default;
+--echo # Reap DELETE.
+--error ER_NO_SUCH_TABLE
+--reap
+commit;
+rename table t3 to t2;
+--echo #
+--echo # Coverage for the case in which we are acquiring lock on
+--echo # the table which is already used in transaction and against
+--echo # which there is a pending X lock request.
+--echo #
+--echo # *) The first case is when transaction has only a SR lock.
+--echo #
+begin;
+select count(*) from t1;
+--echo #
+--echo # Switching to connection 'mdl_con1'.
+connection mdl_con1;
+--echo # Sending:
+--send rename table t1 to t2;
+--echo #
+--echo # Switching to connection 'default'.
+connection default;
+--echo # Wait until RENAME TABLE is blocked creating pending request for X lock.
+let $wait_condition=
+select count(*) = 1 from information_schema.processlist
+where state = "Waiting for table" and info = "rename table t1 to t2";
+--source include/wait_condition.inc
+--echo # Check that another instance of SR lock is granted without waiting.
+select count(*) from t1;
+--echo # Attempt to wait for SW lock will lead to deadlock, thus
+--echo # the below statement should end with ER_LOCK_DEADLOCK error.
+--error ER_LOCK_DEADLOCK
+delete from t1 limit 1;
+--echo # Unblock RENAME TABLE.
+commit;
+--echo #
+--echo # Switching to connection 'mdl_con1'.
+connection mdl_con1;
+--echo # Reap RENAME TABLE.
+--error ER_TABLE_EXISTS_ERROR
+--reap
+--echo #
+--echo # Switching to connection 'default'.
+connection default;
+--echo #
+--echo # **) The second case is when transaction has a SW lock.
+--echo #
+begin;
+delete from t1 limit 1;
+--echo #
+--echo # Switching to connection 'mdl_con1'.
+connection mdl_con1;
+--echo # Sending:
+--send rename table t1 to t2;
+--echo #
+--echo # Switching to connection 'default'.
+connection default;
+--echo # Wait until RENAME TABLE is blocked creating pending request for X lock.
+let $wait_condition=
+select count(*) = 1 from information_schema.processlist
+where state = "Waiting for table" and info = "rename table t1 to t2";
+--source include/wait_condition.inc
+--echo # Check that both SR and SW locks are granted without waiting
+--echo # and errors.
+select count(*) from t1;
+insert into t1 values (1, 1);
+--echo # Unblock RENAME TABLE.
+commit;
+--echo #
+--echo # Switching to connection 'mdl_con1'.
+connection mdl_con1;
+--echo # Reap RENAME TABLE.
+--error ER_TABLE_EXISTS_ERROR
+--reap
+--echo #
+--echo # Switching to connection 'default'.
+connection default;
+
+--echo # Clean-up.
+disconnect mdl_con1;
+disconnect mdl_con2;
+disconnect mdl_con3;
+set debug_sync= 'RESET';
+drop table t1, t2;
+
+
+--echo #
+--echo # Additional coverage for some scenarios in which not quite
+--echo # correct use of S metadata locks by HANDLER statement might
+--echo # have caused deadlocks.
+--echo #
+--disable_warnings
+drop table if exists t1, t2;
+--enable_warnings
+connect(handler_con1,localhost,root,,);
+connect(handler_con2,localhost,root,,);
+connection default;
+create table t1 (i int);
+create table t2 (j int);
+insert into t1 values (1);
+
+--echo #
+--echo # First, check scenario in which we upgrade SNRW lock to X lock
+--echo # on a table while having HANDLER READ trying to acquire TL_READ
+--echo # on the same table.
+--echo #
+handler t1 open;
+--echo #
+--echo # Switching to connection 'handler_con1'.
+connection handler_con1;
+lock table t1 write;
+--echo # Upgrade SNRW to X lock.
+--echo # Sending:
+--send alter table t1 add column j int;
+--echo #
+--echo # Switching to connection 'handler_con2'.
+connection handler_con2;
+--echo # Wait until ALTER is blocked during upgrade.
+let $wait_condition=
+ select count(*) = 1 from information_schema.processlist
+ where state = "Waiting for table" and info = "alter table t1 add column j int";
+--source include/wait_condition.inc
+--echo #
+--echo # Switching to connection 'default'.
+connection default;
+--echo # The below statement should not cause deadlock.
+--send handler t1 read first;
+--echo #
+--echo # Switching to connection 'handler_con1'.
+connection handler_con1;
+--echo # Reap ALTER TABLE.
+--reap
+unlock tables;
+--echo #
+--echo # Switching to connection 'default'.
+connection default;
+--echo # Reap HANDLER READ.
+--reap
+handler t1 close;
+
+--echo #
+--echo # Now, check scenario in which upgrade of SNRW lock to X lock
+--echo # can be blocked by HANDLER which is open in connection currently
+--echo # waiting to get table-lock owned by connection doing upgrade.
+--echo #
+handler t1 open;
+--echo #
+--echo # Switching to connection 'handler_con1'.
+connection handler_con1;
+lock table t1 write, t2 read;
+--echo #
+--echo # Switching to connection 'default'.
+connection default;
+--echo # Execute statement which will be blocked on table-level lock
+--echo # owned by connection 'handler_con1'.
+--echo # Sending:
+--send insert into t2 values (1);
+--echo #
+--echo # Switching to connection 'handler_con1'.
+connection handler_con1;
+--echo # Wait until INSERT is blocked on table-level lock.
+let $wait_condition=
+ select count(*) = 1 from information_schema.processlist
+ where state = "Table lock" and info = "insert into t2 values (1)";
+--source include/wait_condition.inc
+--echo # The below statement should not cause deadlock.
+alter table t1 drop column j;
+unlock tables;
+--echo #
+--echo # Switching to connection 'default'.
+connection default;
+--echo # Reap INSERT.
+--reap
+handler t1 close;
+
+--echo #
+--echo # Then, check the scenario in which upgrade of SNRW lock to X
+--echo # lock is blocked by HANDLER which is open in connection currently
+--echo # waiting to get SW lock on the same table.
+--echo #
+handler t1 open;
+--echo #
+--echo # Switching to connection 'handler_con1'.
+connection handler_con1;
+lock table t1 write;
+--echo #
+--echo # Switching to connection 'default'.
+connection default;
+--echo # The below insert should be blocked because active SNRW lock on 't1'.
+--echo # Sending:
+--send insert into t1 values (1);
+--echo #
+--echo # Switching to connection 'handler_con1'.
+connection handler_con1;
+--echo # Wait until INSERT is blocked because of SNRW lock.
+let $wait_condition=
+ select count(*) = 1 from information_schema.processlist
+ where state = "Waiting for table" and info = "insert into t1 values (1)";
+--source include/wait_condition.inc
+--echo # The below ALTER TABLE will be blocked because of presence of HANDLER.
+--echo # Sending:
+--send alter table t1 add column j int;
+--echo #
+--echo # Switching to connection 'default'.
+connection default;
+--echo # INSERT should be chosen as victim for resolving deadlock.
+--echo # Reaping INSERT.
+--error ER_LOCK_DEADLOCK
+--reap
+--echo # Close HANDLER to unblock ALTER TABLE.
+handler t1 close;
+--echo #
+--echo # Switching to connection 'handler_con1'.
+connection handler_con1;
+--echo # Reaping ALTER TABLE.
+--reap
+unlock tables;
+--echo #
+--echo # Switching to connection 'default'.
+connection default;
+
+--echo #
+--echo # Finally, test in which upgrade of SNRW lock to X lock is blocked
+--echo # by HANDLER which is open in connection currently waiting to get
+--echo # SR lock on the table on which lock is upgraded.
+--echo #
+handler t1 open;
+--echo #
+--echo # Switching to connection 'handler_con1'.
+connection handler_con1;
+lock table t1 write, t2 write;
+--echo #
+--echo # Switching to connection 'default'.
+connection default;
+--echo # The below insert should be blocked because active SNRW lock on 't1'.
+--echo # Sending:
+--send insert into t2 values (1);
+--echo #
+--echo # Switching to connection 'handler_con1'.
+connection handler_con1;
+--echo # Wait until INSERT is blocked because of SNRW lock.
+let $wait_condition=
+ select count(*) = 1 from information_schema.processlist
+ where state = "Waiting for table" and info = "insert into t2 values (1)";
+--source include/wait_condition.inc
+--echo # The below ALTER TABLE will be blocked because of presence of HANDLER.
+--echo # Sending:
+--send alter table t1 drop column j;
+--echo #
+--echo # Switching to connection 'default'.
+connection default;
+--echo # INSERT should be chosen as victim for resolving deadlock.
+--echo # Reaping INSERT.
+--error ER_LOCK_DEADLOCK
+--reap
+--echo # Close HANDLER to unblock ALTER TABLE.
+handler t1 close;
+--echo #
+--echo # Switching to connection 'handler_con1'.
+connection handler_con1;
+--echo # Reaping ALTER TABLE.
+--reap
+unlock tables;
+--echo #
+--echo # Switching to connection 'default'.
+connection default;
+
+--echo # Clean-up.
+disconnect handler_con1;
+disconnect handler_con2;
+drop tables t1, t2;
+
+
+--echo #
+--echo # Test coverage for basic deadlock detection in metadata
+--echo # locking subsystem.
+--echo #
+--disable_warnings
+drop tables if exists t0, t1, t2, t3, t4, t5;
+--enable_warnings
+
+connect(deadlock_con1,localhost,root,,);
+connect(deadlock_con2,localhost,root,,);
+connect(deadlock_con3,localhost,root,,);
+connection default;
+create table t1 (i int);
+create table t2 (j int);
+create table t3 (k int);
+create table t4 (k int);
+
+--echo #
+--echo # Test for the case in which no deadlock occurs.
+--echo #
+
+--echo #
+--echo # Switching to connection 'deadlock_con1'.
+connection deadlock_con1;
+begin;
+insert into t1 values (1);
+
+--echo #
+--echo # Switching to connection 'deadlock_con2'.
+connection deadlock_con2;
+begin;
+insert into t2 values (1);
+
+--echo #
+--echo # Switching to connection 'default'.
+connection default;
+--echo # Send:
+--send rename table t2 to t0, t3 to t2, t0 to t3;
+
+--echo #
+--echo # Switching to connection 'deadlock_con1'.
+connection deadlock_con1;
+--echo # Wait until the above RENAME TABLE is blocked because it has to wait
+--echo # for 'deadlock_con2' which holds shared metadata lock on 't2'.
+let $wait_condition=
+ select count(*) = 1 from information_schema.processlist
+ where state = "Waiting for table" and info = "rename table t2 to t0, t3 to t2, t0 to t3";
+--source include/wait_condition.inc
+--echo # The below statement should wait for exclusive metadata lock
+--echo # on 't2' to go away and should not produce ER_LOCK_DEADLOCK
+--echo # as no deadlock is possible in this situation.
+--echo # Send:
+--send select * from t2;
+
+--echo #
+--echo # Switching to connection 'deadlock_con2'.
+connection deadlock_con2;
+--echo # Wait until the above SELECT * FROM t2 is starts waiting
+--echo # for an exclusive metadata lock to go away.
+let $wait_condition=
+ select count(*) = 1 from information_schema.processlist
+ where state = "Waiting for table" and info = "select * from t2";
+--source include/wait_condition.inc
+--echo #
+--echo # Unblock RENAME TABLE by releasing shared metadata lock on t2.
+commit;
+
+--echo #
+--echo # Switching to connection 'default'.
+connection default;
+--echo # Reap RENAME TABLE.
+--reap
+
+--echo #
+--echo # Switching to connection 'deadlock_con1'.
+connection deadlock_con1;
+--echo # Reap SELECT.
+--reap
+
+--echo #
+--echo # Switching to connection 'default'.
+connection default;
+--echo #
+--echo # Let us check that in the process of waiting for conflicting lock
+--echo # on table 't2' to go away transaction in connection 'deadlock_con1'
+--echo # has not released metadata lock on table 't1'.
+--echo # Send:
+--send rename table t1 to t0, t3 to t1, t0 to t3;
+
+--echo #
+--echo # Switching to connection 'deadlock_con1'.
+connection deadlock_con1;
+--echo # Wait until the above RENAME TABLE is blocked because it has to wait
+--echo # for 'deadlock_con1' which should still hold shared metadata lock on
+--echo # table 't1'.
+let $wait_condition=
+ select count(*) = 1 from information_schema.processlist
+ where state = "Waiting for table" and info = "rename table t1 to t0, t3 to t1, t0 to t3";
+--source include/wait_condition.inc
+--echo # Commit transaction to unblock RENAME TABLE.
+commit;
+
+--echo #
+--echo # Switching to connection 'default'.
+connection default;
+--echo # Reap RENAME TABLE.
+--reap
+
+--echo #
+--echo # Test for case when deadlock occurs and should be detected immediately.
+--echo #
+
+--echo #
+--echo # Switching to connection 'deadlock_con1'.
+connection deadlock_con1;
+begin;
+insert into t2 values (2);
+
+--echo #
+--echo # Switching to connection 'default'.
+connection default;
+--echo # Send:
+--send rename table t2 to t0, t1 to t2, t0 to t1;
+
+--echo #
+--echo # Switching to connection 'deadlock_con1'.
+connection deadlock_con1;
+--echo # Wait until the above RENAME TABLE is blocked because it has to wait
+--echo # for 'deadlock_con1' which holds shared metadata lock on 't2'.
+let $wait_condition=
+ select count(*) = 1 from information_schema.processlist
+ where state = "Waiting for table" and info = "rename table t2 to t0, t1 to t2, t0 to t1";
+--source include/wait_condition.inc
+--echo #
+--echo # The below statement should not wait as doing so will cause deadlock.
+--echo # Instead it should fail and emit ER_LOCK_DEADLOCK statement.
+--error ER_LOCK_DEADLOCK
+select * from t1;
+
+--echo #
+--echo # Let us check that failure of the above statement has not released
+--echo # metadata lock on table 't1', i.e. that RENAME TABLE is still blocked.
+let $wait_condition=
+ select count(*) = 1 from information_schema.processlist
+ where state = "Waiting for table" and info = "rename table t2 to t0, t1 to t2, t0 to t1";
+--source include/wait_condition.inc
+--echo # Commit transaction to unblock RENAME TABLE.
+commit;
+
+--echo #
+--echo # Switching to connection 'default'.
+connection default;
+--echo # Reap RENAME TABLE.
+--reap
+
+--echo #
+--echo # Test for the case in which deadlock also occurs but not immediately.
+--echo #
+
+--echo #
+--echo # Switching to connection 'deadlock_con1'.
+connection deadlock_con1;
+begin;
+insert into t2 values (1);
+
+--echo #
+--echo # Switching to connection 'default'.
+connection default;
+lock table t1 write;
+
+--echo #
+--echo # Switching to connection 'deadlock_con1'.
+connection deadlock_con1;
+--echo # The below SELECT statement should wait for metadata lock
+--echo # on table 't1' and should not produce ER_LOCK_DEADLOCK
+--echo # immediately as no deadlock is possible at the moment.
+--send select * from t1;
+
+--echo #
+--echo # Switching to connection 'deadlock_con2'.
+connection deadlock_con2;
+--echo # Wait until the above SELECT * FROM t1 is starts waiting
+--echo # for an UNRW metadata lock to go away.
+let $wait_condition=
+ select count(*) = 1 from information_schema.processlist
+ where state = "Waiting for table" and info = "select * from t1";
+--source include/wait_condition.inc
+
+--echo # Send RENAME TABLE statement that will deadlock with the
+--echo # SELECT statement and thus should abort the latter.
+--send rename table t1 to t0, t2 to t1, t0 to t2;
+
+--echo #
+--echo # Switching to connection 'default'.
+connection default;
+--echo # Wait till above RENAME TABLE is blocked while holding
+--echo # pending X lock on t1.
+let $wait_condition=
+ select count(*) = 1 from information_schema.processlist
+ where state = "Waiting for table" and info = "rename table t1 to t0, t2 to t1, t0 to t2";
+--source include/wait_condition.inc
+--echo # Allow the above RENAME TABLE to acquire lock on t1 and
+--echo # create pending lock on t2 thus creating deadlock.
+unlock tables;
+
+--echo #
+--echo # Switching to connection 'deadlock_con1'.
+connection deadlock_con1;
+--echo # Since the latest RENAME TABLE entered in deadlock with SELECT
+--echo # statement the latter should be aborted and emit ER_LOCK_DEADLOCK
+--echo # error.
+--echo # Reap SELECT * FROM t1.
+--error ER_LOCK_DEADLOCK
+--reap
+
+--echo #
+--echo # Again let us check that failure of the SELECT statement has not
+--echo # released metadata lock on table 't2', i.e. that the latest RENAME
+--echo # is blocked.
+let $wait_condition=
+ select count(*) = 1 from information_schema.processlist
+ where state = "Waiting for table" and info = "rename table t1 to t0, t2 to t1, t0 to t2";
+--source include/wait_condition.inc
+--echo # Commit transaction to unblock this RENAME TABLE.
+commit;
+
+--echo #
+--echo # Switching to connection 'deadlock_con2'.
+connection deadlock_con2;
+--echo # Reap RENAME TABLE ... .
+--reap;
+
+--echo #
+--echo # Switching to connection 'default'.
+connection default;
+
+drop tables t1, t2, t3, t4;
+
+--echo #
+--echo # Now, test case which shows that deadlock detection empiric
+--echo # also takes into account requests for metadata lock upgrade.
+--echo #
+create table t1 (i int);
+insert into t1 values (1);
+--echo # Avoid race which occurs when SELECT in 'deadlock_con1' connection
+--echo # accesses table before the above INSERT unlocks the table and thus
+--echo # its result becomes visible to other connections.
+select * from t1;
+
+--echo #
+--echo # Switching to connection 'deadlock_con1'.
+connection deadlock_con1;
+begin;
+select * from t1;
+
+--echo #
+--echo # Switching to connection 'default'.
+connection default;
+--echo # Send:
+--send alter table t1 add column j int, rename to t2;
+
+--echo #
+--echo # Switching to connection 'deadlock_con1'.
+connection deadlock_con1;
+--echo # Wait until the above ALTER TABLE ... RENAME acquires exclusive
+--echo # metadata lock on 't2' and starts waiting for connection
+--echo # 'deadlock_con1' which holds shared lock on 't1'.
+let $wait_condition=
+ select count(*) = 1 from information_schema.processlist
+ where state = "Waiting for table" and info = "alter table t1 add column j int, rename to t2";
+--source include/wait_condition.inc
+
+--echo # The below statement should not wait as it will cause deadlock.
+--echo # An appropriate error should be reported instead.
+--error ER_LOCK_DEADLOCK
+select * from t2;
+
+--echo # Again let us check that failure of the above statement has not
+--echo # released all metadata locks in connection 'deadlock_con1' and
+--echo # so ALTER TABLE ... RENAME is still blocked.
+let $wait_condition=
+ select count(*) = 1 from information_schema.processlist
+ where state = "Waiting for table" and info = "alter table t1 add column j int, rename to t2";
+--source include/wait_condition.inc
+
+--echo # Commit transaction to unblock ALTER TABLE ... RENAME.
+commit;
+
+--echo #
+--echo # Switching to connection 'default'.
+connection default;
+--echo # Reap ALTER TABLE ... RENAME.
+--reap
+
+drop table t2;
+
+disconnect deadlock_con1;
+disconnect deadlock_con2;
+disconnect deadlock_con3;
+
+
+--echo #
+--echo # Test for bug #46748 "Assertion in MDL_context::wait_for_locks()
+--echo # on INSERT + CREATE TRIGGER".
+--echo #
+--disable_warnings
+drop tables if exists t1, t2, t3, t4, t5;
+--enable_warnings
+--echo # Let us simulate scenario in which we open some tables from extended
+--echo # part of prelocking set but then encounter conflicting metadata lock,
+--echo # so have to back-off and wait for it to go away.
+connect (con1root,localhost,root,,test,,);
+connect (con2root,localhost,root,,test,,);
+connection default;
+create table t1 (i int);
+create table t2 (j int);
+create table t3 (k int);
+create table t4 (l int);
+create trigger t1_bi before insert on t1 for each row
+ insert into t2 values (new.i);
+create trigger t2_bi before insert on t2 for each row
+ insert into t3 values (new.j);
+--echo #
+--echo # Switching to connection 'con1root'.
+connection con1root;
+lock tables t4 read;
+--echo #
+--echo # Switching to connection 'con2root'.
+connection con2root;
+--echo # Send :
+--send rename table t3 to t5, t4 to t3;
+--echo #
+--echo # Switching to connection 'default'.
+connection default;
+--echo # Wait until the above RENAME TABLE adds pending requests for exclusive
+--echo # metadata lock on its tables and blocks due to 't4' being used by LOCK
+--echo # TABLES.
+let $wait_condition= select count(*)= 1 from information_schema.processlist
+ where state= 'Waiting for table' and
+ info='rename table t3 to t5, t4 to t3';
+--source include/wait_condition.inc
+--echo # Send :
+--send insert into t1 values (1);
+--echo #
+--echo # Switching to connection 'con1root'.
+connection con1root;
+--echo # Wait until INSERT statement waits due to encountering pending
+--echo # exclusive metadata lock on 't3'.
+let $wait_condition= select count(*)= 1 from information_schema.processlist
+ where state= 'Waiting for table' and
+ info='insert into t1 values (1)';
+--source include/wait_condition.inc
+unlock tables;
+--echo #
+--echo # Switching to connection 'con2root'.
+connection con2root;
+--echo # Reap RENAME TABLE.
+--reap
+--echo #
+--echo # Switching to connection 'default'.
+connection default;
+--echo # Reap INSERT.
+--reap
+--echo # Clean-up.
+disconnect con1root;
+disconnect con2root;
+drop tables t1, t2, t3, t5;
+
+
+--echo #
+--echo # Bug#42546 - Backup: RESTORE fails, thinking it finds an existing table
+--echo #
+
+--disable_warnings
+DROP TABLE IF EXISTS t1;
+--enable_warnings
+set @save_log_output=@@global.log_output;
+set global log_output=file;
+
+connect(con2, localhost, root,,);
+
+--echo #
+--echo # Test 1: CREATE TABLE
+--echo #
+
+--echo # Connection 2
+connection con2;
+--echo # Start insert on the not-yet existing table
+--echo # Wait after taking the MDL lock
+SET DEBUG_SYNC= 'after_open_table_mdl_shared SIGNAL locked WAIT_FOR finish';
+--send INSERT INTO t1 VALUES(1,"def")
+
+--echo # Connection 1
+connection default;
+SET DEBUG_SYNC= 'now WAIT_FOR locked';
+--echo # Now INSERT has a MDL on the non-existent table t1.
+
+--echo #
+--echo # Continue the INSERT once CREATE waits for exclusive lock
+SET DEBUG_SYNC= 'mdl_acquire_lock_wait SIGNAL finish';
+--echo # Try to create that table.
+--send CREATE TABLE t1 (c1 INT, c2 VARCHAR(100), KEY(c1))
+
+--echo # Connection 2
+--echo # Insert fails
+connection con2;
+--error ER_NO_SUCH_TABLE
+--reap
+
+--echo # Connection 1
+connection default;
+--reap;
+SET DEBUG_SYNC= 'RESET';
+SHOW TABLES;
+
+--disable_warnings
+DROP TABLE IF EXISTS t1;
+--enable_warnings
+
+--echo #
+--echo # Test 2: CREATE TABLE LIKE
+--echo #
+
+CREATE TABLE t2 (c1 INT, c2 VARCHAR(100), KEY(c1));
+
+--echo # Connection 2
+connection con2;
+--echo # Start insert on the not-yet existing table
+--echo # Wait after taking the MDL
+SET DEBUG_SYNC= 'after_open_table_mdl_shared SIGNAL locked WAIT_FOR finish';
+--send INSERT INTO t1 VALUES(1,"def")
+
+--echo # Connection 1
+connection default;
+SET DEBUG_SYNC= 'now WAIT_FOR locked';
+--echo # Now INSERT has a MDL on the non-existent table t1.
+
+--echo #
+--echo # Continue the INSERT once CREATE waits for exclusive lock
+SET DEBUG_SYNC= 'mdl_acquire_lock_wait SIGNAL finish';
+--echo # Try to create that table.
+--send CREATE TABLE t1 LIKE t2
+
+--echo # Connection 2
+--echo # Insert fails
+connection con2;
+--error ER_NO_SUCH_TABLE
+--reap
+
+--echo # Connection 1
+connection default;
+--reap
+SET DEBUG_SYNC= 'RESET';
+SHOW TABLES;
+
+DROP TABLE t2;
+disconnect con2;
+--disable_warnings
+DROP TABLE IF EXISTS t1;
+--enable_warnings
+
+set global log_output=@save_log_output;
+
+
+--echo #
+--echo # Bug #46044 "MDL deadlock on LOCK TABLE + CREATE TABLE HIGH_PRIORITY
+--echo # FOR UPDATE"
+--echo #
+--disable_warnings
+drop tables if exists t1, t2;
+--enable_warnings
+connect (con46044, localhost, root,,);
+connect (con46044_2, localhost, root,,);
+connection default;
+create table t1 (i int);
+
+--echo # Let us check that we won't deadlock if during filling
+--echo # of I_S table we encounter conflicting metadata lock
+--echo # which owner is in its turn waiting for our connection.
+lock tables t1 read;
+
+--echo # Switching to connection 'con46044'.
+connection con46044;
+--echo # Sending:
+--send create table t2 select * from t1 for update;
+
+--echo # Switching to connection 'default'.
+connection default;
+--echo # Waiting until CREATE TABLE ... SELECT ... is blocked.
+let $wait_condition=
+ select count(*) = 1 from information_schema.processlist
+ where state = "Table lock" and info = "create table t2 select * from t1 for update";
+--source include/wait_condition.inc
+
+--echo # First let us check that SHOW FIELDS/DESCRIBE doesn't
+--echo # gets blocked and emits and error.
+--error ER_WARN_I_S_SKIPPED_TABLE
+show fields from t2;
+
+--echo # Now test for I_S query which reads only .FRMs.
+--echo #
+--echo # Query below should only emit a warning.
+select column_name from information_schema.columns
+ where table_schema='test' and table_name='t2';
+
+--echo # Finally, test for I_S query which does full-blown table open.
+--echo #
+--echo # Query below should not be blocked. Warning message should be
+--echo # stored in the 'table_comment' column.
+select table_name, table_type, auto_increment, table_comment
+ from information_schema.tables where table_schema='test' and table_name='t2';
+
+--echo # Switching to connection 'default'.
+connection default;
+unlock tables;
+
+--echo # Switching to connection 'con46044'.
+connection con46044;
+--echo # Reaping CREATE TABLE ... SELECT ... .
+--reap
+drop table t2;
+
+--echo #
+--echo # Let us also check that queries to I_S wait for conflicting metadata
+--echo # locks to go away instead of skipping table with a warning in cases
+--echo # when deadlock is not possible. This is a nice thing from compatibility
+--echo # and ease of use points of view.
+--echo #
+--echo # We check same three queries to I_S in this new situation.
+
+--echo # Switching to connection 'con46044_2'.
+connection con46044_2;
+lock tables t1 read;
+
+--echo # Switching to connection 'con46044'.
+connection con46044;
+--echo # Sending:
+--send create table t2 select * from t1 for update;
+
+--echo # Switching to connection 'default'.
+connection default;
+--echo # Waiting until CREATE TABLE ... SELECT ... is blocked.
+let $wait_condition=
+ select count(*) = 1 from information_schema.processlist
+ where state = "Table lock" and info = "create table t2 select * from t1 for update";
+--source include/wait_condition.inc
+
+--echo # Let us check that SHOW FIELDS/DESCRIBE gets blocked.
+--echo # Sending:
+--send show fields from t2;
+
+--echo # Switching to connection 'con46044_2'.
+connection con46044_2;
+--echo # Wait until SHOW FIELDS gets blocked.
+let $wait_condition=
+ select count(*) = 1 from information_schema.processlist
+ where state = "Waiting for table" and info = "show fields from t2";
+--source include/wait_condition.inc
+
+unlock tables;
+
+--echo # Switching to connection 'con46044'.
+connection con46044;
+--echo # Reaping CREATE TABLE ... SELECT ... .
+--reap
+
+--echo # Switching to connection 'default'.
+connection default;
+--echo # Reaping SHOW FIELDS ...
+--reap
+drop table t2;
+
+--echo # Switching to connection 'con46044_2'.
+connection con46044_2;
+lock tables t1 read;
+
+--echo # Switching to connection 'con46044'.
+connection con46044;
+--echo # Sending:
+--send create table t2 select * from t1 for update;
+
+--echo # Switching to connection 'default'.
+connection default;
+--echo # Waiting until CREATE TABLE ... SELECT ... is blocked.
+let $wait_condition=
+ select count(*) = 1 from information_schema.processlist
+ where state = "Table lock" and info = "create table t2 select * from t1 for update";
+--source include/wait_condition.inc
+
+--echo # Check that I_S query which reads only .FRMs gets blocked.
+--echo # Sending:
+--send select column_name from information_schema.columns where table_schema='test' and table_name='t2';
+
+--echo # Switching to connection 'con46044_2'.
+connection con46044_2;
+--echo # Wait until SELECT COLUMN_NAME FROM I_S.COLUMNS gets blocked.
+let $wait_condition=
+ select count(*) = 1 from information_schema.processlist
+ where state = "Waiting for table" and
+ info like "select column_name from information_schema.columns%";
+--source include/wait_condition.inc
+
+unlock tables;
+
+--echo # Switching to connection 'con46044'.
+connection con46044;
+--echo # Reaping CREATE TABLE ... SELECT ... .
+--reap
+
+--echo # Switching to connection 'default'.
+connection default;
+--echo # Reaping SELECT COLUMN_NAME FROM I_S.COLUMNS
+--reap
+drop table t2;
+
+--echo # Switching to connection 'con46044_2'.
+connection con46044_2;
+lock tables t1 read;
+
+--echo # Switching to connection 'con46044'.
+connection con46044;
+--echo # Sending:
+--send create table t2 select * from t1 for update;
+
+--echo # Switching to connection 'default'.
+connection default;
+--echo # Waiting until CREATE TABLE ... SELECT ... is blocked.
+let $wait_condition=
+ select count(*) = 1 from information_schema.processlist
+ where state = "Table lock" and info = "create table t2 select * from t1 for update";
+--source include/wait_condition.inc
+
+--echo # Finally, check that I_S query which does full-blown table open
+--echo # also gets blocked.
+--echo # Sending:
+--send select table_name, table_type, auto_increment, table_comment from information_schema.tables where table_schema='test' and table_name='t2';
+
+--echo # Switching to connection 'con46044_2'.
+connection con46044_2;
+--echo # Wait until SELECT ... FROM I_S.TABLES gets blocked.
+let $wait_condition=
+ select count(*) = 1 from information_schema.processlist
+ where state = "Waiting for table" and
+ info like "select table_name, table_type, auto_increment, table_comment from information_schema.tables%";
+--source include/wait_condition.inc
+
+unlock tables;
+
+--echo # Switching to connection 'con46044'.
+connection con46044;
+--echo # Reaping CREATE TABLE ... SELECT ... .
+--reap
+
+--echo # Switching to connection 'default'.
+connection default;
+--echo # Reaping SELECT ... FROM I_S.TABLES
+--reap
+drop table t2;
+
+--echo # Switching to connection 'default'.
+connection default;
+--echo # Clean-up.
+disconnect con46044;
+disconnect con46044_2;
+drop table t1;
+
+
+--echo #
+--echo # Test for bug #46273 "MySQL 5.4.4 new MDL: Bug#989 is not fully fixed
+--echo # in case of ALTER".
+--echo #
+--disable_warnings
+drop table if exists t1;
+--enable_warnings
+set debug_sync= 'RESET';
+connect (con46273,localhost,root,,test,,);
+connection default;
+create table t1 (c1 int primary key, c2 int, c3 int);
+insert into t1 values (1,1,0),(2,2,0),(3,3,0),(4,4,0),(5,5,0);
+
+begin;
+select * from t1 where c2 = 3;
+
+--echo #
+--echo # Switching to connection 'con46273'.
+connection con46273;
+set debug_sync='after_lock_tables_takes_lock SIGNAL alter_table_locked WAIT_FOR alter_go';
+--send alter table t1 add column e int, rename to t2;
+
+--echo #
+--echo # Switching to connection 'default'.
+connection default;
+set debug_sync='now WAIT_FOR alter_table_locked';
+set debug_sync='before_open_table_wait_refresh SIGNAL alter_go';
+--echo # The below statement should get ER_LOCK_DEADLOCK error
+--echo # (i.e. it should not allow ALTER to proceed, and then
+--echo # fail due to 't1' changing its name to 't2').
+--error ER_LOCK_DEADLOCK
+update t1 set c3=c3+1 where c2 = 3;
+
+--echo #
+--echo # Let us check that failure of the above statement has not released
+--echo # metadata lock on table 't1', i.e. that ALTER TABLE is still blocked.
+let $wait_condition=
+ select count(*) = 1 from information_schema.processlist
+ where state = "Waiting for table" and info = "alter table t1 add column e int, rename to t2";
+--source include/wait_condition.inc
+
+--echo # Unblock ALTER TABLE by commiting transaction and thus releasing
+--echo # metadata lock on 't1'.
+commit;
+
+--echo #
+--echo # Switching to connection 'con46273'.
+connection con46273;
+--echo # Reap ALTER TABLE.
+--reap
+
+--echo #
+--echo # Switching to connection 'default'.
+connection default;
+disconnect con46273;
+--echo # Clean-up.
+set debug_sync= 'RESET';
+drop table t2;
+
+
+--echo #
+--echo # Test for bug #46673 "Deadlock between FLUSH TABLES WITH READ LOCK
+--echo # and DML".
+--echo #
+--disable_warnings
+drop tables if exists t1;
+--enable_warnings
+connect (con46673, localhost, root,,);
+connection default;
+create table t1 (i int);
+
+--echo # Switching to connection 'con46673'.
+connection con46673;
+begin;
+insert into t1 values (1);
+
+--echo # Switching to connection 'default'.
+connection default;
+--echo # Statement below should not get blocked. And if after some
+--echo # changes to code it is there should not be a deadlock between
+--echo # it and transaction from connection 'con46673'.
+flush tables with read lock;
+unlock tables;
+
+--echo # Switching to connection 'con46673'.
+connection con46673;
+delete from t1 where i = 1;
+commit;
+
+--echo # Switching to connection 'default'.
+connection default;
+--echo # Clean-up
+disconnect con46673;
+drop table t1;
+
+
+--echo #
+--echo # Bug#48210 FLUSH TABLES WITH READ LOCK deadlocks
+--echo # against concurrent CREATE PROCEDURE
+--echo #
+
+connect (con2, localhost, root);
+
+--echo # Test 1: CREATE PROCEDURE
+
+--echo # Connection 1
+connection default;
+--echo # Start CREATE PROCEDURE and open mysql.proc
+SET DEBUG_SYNC= 'after_open_table_mdl_shared SIGNAL table_opened WAIT_FOR grlwait';
+--send CREATE PROCEDURE p1() SELECT 1
+
+--echo # Connection 2
+connection con2;
+SET DEBUG_SYNC= 'now WAIT_FOR table_opened';
+--echo # Check that FLUSH must wait to get the GRL
+--echo # and let CREATE PROCEDURE continue
+SET DEBUG_SYNC= 'wait_lock_global_read_lock SIGNAL grlwait';
+--send FLUSH TABLES WITH READ LOCK
+
+--echo # Connection 1
+connection default;
+--reap
+
+--echo # Connection 2
+connection con2;
+--reap
+UNLOCK TABLES;
+
+--echo # Connection 1
+connection default;
+SET DEBUG_SYNC= 'RESET';
+
+--echo # Test 2: DROP PROCEDURE
+
+connection default;
+--echo # Start DROP PROCEDURE and open tables
+SET DEBUG_SYNC= 'after_open_table_mdl_shared SIGNAL table_opened WAIT_FOR grlwait';
+--send DROP PROCEDURE p1
+
+--echo # Connection 2
+connection con2;
+SET DEBUG_SYNC= 'now WAIT_FOR table_opened';
+--echo # Check that FLUSH must wait to get the GRL
+--echo # and let DROP PROCEDURE continue
+SET DEBUG_SYNC= 'wait_lock_global_read_lock SIGNAL grlwait';
+--send FLUSH TABLES WITH READ LOCK
+
+--echo # Connection 1
+connection default;
+--reap
+
+--echo # Connection 2
+connection con2;
+--reap
+UNLOCK TABLES;
+
+--echo # Connection 1
+connection default;
+SET DEBUG_SYNC= 'RESET';
+
+disconnect con2;
+
+
+--echo #
+--echo # Bug#50786 Assertion `thd->mdl_context.trans_sentinel() == __null'
+--echo # failed in open_ltable()
+--echo #
+
+--disable_warnings
+DROP TABLE IF EXISTS t1, t2;
+--enable_warnings
+
+connect (con1,localhost,root);
+connect (con2,localhost,root);
+connect (con3,localhost,root);
+connection default;
+
+CREATE TABLE t1 (i INT);
+CREATE TABLE t2 (i INT);
+
+SET @old_general_log= @@global.general_log;
+SET @@global.general_log= 1;
+
+SET @old_log_output= @@global.log_output;
+SET @@global.log_output= 'TABLE';
+
+SET @old_sql_log_off= @@session.sql_log_off;
+SET @@session.sql_log_off= 1;
+
+--echo # connection: con1
+connection con1;
+HANDLER t1 OPEN;
+
+--echo # connection: con3
+connection con3;
+SET @@session.sql_log_off= 1;
+
+--echo # connection: con2
+connection con2;
+SET DEBUG_SYNC= 'thr_multi_lock_after_thr_lock SIGNAL parked WAIT_FOR go';
+
+# The below statement will block on the debug sync point
+# after it gets write lock on mysql.general_log table.
+--echo # Sending:
+--send SELECT 1
+
+--echo # connection: con3
+connection con3;
+SET DEBUG_SYNC= 'now WAIT_FOR parked';
+
+--echo # connection: con1
+connection con1;
+# This statement will block in open_ltable() when
+# trying to write into mysql.general_log.
+--echo # Sending:
+--send SELECT 1
+
+--echo # connection: con3
+connection con3;
+let $wait_condition=
+ SELECT COUNT(*) = 1 FROM information_schema.processlist
+ WHERE state = "Table lock" and info = "SELECT 1";
+--source include/wait_condition.inc
+# The ALTER below will try to abort the statement in connection con1,
+# since the latter waits on a table-level lock while having a HANDLER
+# open. This will cause mysql_lock_tables() in con1 fail which before
+# triggered the assert.
+--echo # Sending:
+--send ALTER TABLE t1 ADD COLUMN j INT
+
+--echo # connection: default
+connection default;
+let $wait_condition=
+ SELECT COUNT(*) = 1 FROM information_schema.processlist
+ WHERE state = "Waiting for table"
+ AND info = "ALTER TABLE t1 ADD COLUMN j INT";
+--source include/wait_condition.inc
+SET DEBUG_SYNC= 'now SIGNAL go';
+
+--echo # connection: con1
+connection con1;
+--echo # Reaping SELECT 1
+--reap
+HANDLER t1 CLOSE;
+
+--echo # connection: con2
+connection con2;
+--echo # Reaping SELECT 1
+--reap
+
+--echo # connection: con3
+connection con3;
+--echo # Reaping ALTER TABLE t1 ADD COLUMN j INT
+--reap
+
+--echo # connection: default
+connection default;
+DROP TABLE t1, t2;
+SET DEBUG_SYNC= 'RESET';
+disconnect con1;
+disconnect con2;
+disconnect con3;
+SET @@global.general_log= @old_general_log;
+SET @@global.log_output= @old_log_output;
+SET @@session.sql_log_off= @old_sql_log_off;
+
+
+--echo #
+--echo # Additional coverage for bug #50913 "Deadlock between
+--echo # open_and_lock_tables_derived and MDL". The main test
+--echo # case is in lock_multi.test
+--echo #
+--disable_warnings
+drop table if exists t1;
+--enable_warnings
+set debug_sync= 'RESET';
+connect (con50913_1,localhost,root);
+connect (con50913_2,localhost,root);
+connection default;
+create table t1 (i int) engine=InnoDB;
+
+--echo # Switching to connection 'con50913_1'.
+connection con50913_1;
+set debug_sync= 'thr_multi_lock_after_thr_lock SIGNAL parked WAIT_FOR go';
+--echo # Sending:
+--send alter table t1 add column j int
+
+--echo # Switching to connection 'default'.
+connection default;
+--echo # Wait until ALTER TABLE gets blocked on a sync point after
+--echo # acquiring thr_lock.c lock.
+set debug_sync= 'now WAIT_FOR parked';
+--echo # The below statement should wait on MDL lock and not deadlock on
+--echo # thr_lock.c lock.
+--echo # Sending:
+--send truncate table t1
+
+--echo # Switching to connection 'con50913_2'.
+connection con50913_2;
+--echo # Wait until TRUNCATE TABLE is blocked on MDL lock.
+let $wait_condition=
+ select count(*) = 1 from information_schema.processlist
+ where state = "Waiting for table" and info = "truncate table t1";
+--source include/wait_condition.inc
+--echo # Unblock ALTER TABLE.
+set debug_sync= 'now SIGNAL go';
+
+--echo # Switching to connection 'con50913_1'.
+connection con50913_1;
+--echo # Reaping ALTER TABLE.
+--reap
+
+--echo # Switching to connection 'default'.
+connection default;
+--echo # Reaping TRUNCATE TABLE.
+--reap
+disconnect con50913_1;
+disconnect con50913_2;
+set debug_sync= 'RESET';
+drop table t1;
+
+
+--echo #
+--echo # Test for bug #50998 "Deadlock in MDL code during test
+--echo # rqg_mdl_stability".
+--echo # Also provides coverage for the case when addition of
+--echo # waiting statement adds several loops in the waiters
+--echo # graph and therefore several searches for deadlock
+--echo # should be performed.
+--disable_warnings
+drop table if exists t1;
+--enable_warnings
+set debug_sync= 'RESET';
+connect (con1,localhost,root);
+connect (con2,localhost,root);
+connect (con3,localhost,root);
+connection default;
+create table t1 (i int);
+
+--echo # Switching to connection 'con1'.
+connection con1;
+begin;
+select * from t1;
+
+--echo # Switching to connection 'con2'.
+connection con2;
+begin;
+select * from t1;
+
+--echo # Switching to connection 'default'.
+connection default;
+--echo # Start ALTER TABLE which will acquire SNW lock and
+--echo # table lock and get blocked on sync point.
+set debug_sync= 'thr_multi_lock_after_thr_lock SIGNAL parked WAIT_FOR go';
+--echo # Sending:
+--send alter table t1 add column j int
+
+--echo # Switching to connection 'con1'.
+connection con1;
+--echo # Wait until ALTER TABLE gets blocked on a sync point.
+set debug_sync= 'now WAIT_FOR parked';
+--echo # Sending:
+--send insert into t1 values (1)
+
+--echo # Switching to connection 'con2'.
+connection con2;
+--echo # Sending:
+--send insert into t1 values (1)
+
+--echo # Switching to connection 'con3'.
+connection con3;
+--echo # Wait until both 'con1' and 'con2' are blocked trying to acquire
+--echo # SW lock on the table.
+let $wait_condition=
+ select count(*) = 2 from information_schema.processlist
+ where state = "Waiting for table" and info = "insert into t1 values (1)";
+--source include/wait_condition.inc
+--echo # Unblock ALTER TABLE. Since it will try to upgrade SNW to X lock
+--echo # deadlock with two loops in waiting graph will occur. Both loops
+--echo # should be found and DML statements in both 'con1' and 'con2'
+--echo # should be aborted with ER_LOCK_DEADLOCK errors.
+set debug_sync= 'now SIGNAL go';
+
+--echo # Switching to connection 'con1'.
+connection con1;
+--echo # Reaping INSERT. It should end with ER_LOCK_DEADLOCK error and
+--echo # not wait indefinitely (as it happened before the bugfix).
+--error ER_LOCK_DEADLOCK
+--reap
+commit;
+
+--echo # Switching to connection 'con2'.
+connection con2;
+--echo # Reaping INSERT.
+--error ER_LOCK_DEADLOCK
+--reap
+commit;
+
+--echo # Switching to connection 'default'.
+connection default;
+--echo # Reap ALTER TABLE.
+--reap
+
+disconnect con1;
+disconnect con2;
+disconnect con3;
+connection default;
+set debug_sync= 'RESET';
+drop table t1;
+
+
+# Check that all connections opened by test cases in this file are really
+# gone so execution of other tests won't be affected by their presence.
+--source include/wait_until_count_sessions.inc
diff --git a/mysql-test/t/merge-big.test b/mysql-test/t/merge-big.test
index b687973c9d1..33bd93791f1 100644
--- a/mysql-test/t/merge-big.test
+++ b/mysql-test/t/merge-big.test
@@ -51,7 +51,7 @@ connection default;
#--sleep 8
#SELECT ID,STATE,INFO FROM INFORMATION_SCHEMA.PROCESSLIST;
let $wait_condition= SELECT 1 FROM INFORMATION_SCHEMA.PROCESSLIST
- WHERE ID = $con1_id AND STATE = 'Locked';
+ WHERE ID = $con1_id AND STATE = 'Table lock';
--source include/wait_condition.inc
#SELECT NOW();
--echo # Kick INSERT out of thr_multi_lock().
@@ -61,7 +61,7 @@ FLUSH TABLES;
#--sleep 8
#SELECT ID,STATE,INFO FROM INFORMATION_SCHEMA.PROCESSLIST;
let $wait_condition= SELECT 1 FROM INFORMATION_SCHEMA.PROCESSLIST
- WHERE ID = $con1_id AND STATE = 'Waiting for table';
+ WHERE ID = $con1_id AND STATE = 'Table lock';
--source include/wait_condition.inc
#SELECT NOW();
--echo # Unlock and close table and wait for con1 to close too.
diff --git a/mysql-test/t/merge.test b/mysql-test/t/merge.test
index 63ad5a1e97c..f0d8960322e 100644
--- a/mysql-test/t/merge.test
+++ b/mysql-test/t/merge.test
@@ -216,20 +216,20 @@ drop table t3,t1,t2;
#
# temporary merge tables
#
-create table t1 (a int not null);
-create table t2 (a int not null);
-insert into t1 values (1);
-insert into t2 values (2);
-create temporary table t3 (a int not null) ENGINE=MERGE UNION=(t1,t2);
+CREATE TABLE t1 (c1 INT NOT NULL);
+CREATE TABLE t2 (c1 INT NOT NULL);
+INSERT INTO t1 VALUES (1);
+INSERT INTO t2 VALUES (2);
+CREATE TEMPORARY TABLE t3 (c1 INT NOT NULL) ENGINE=MRG_MYISAM UNION=(t1,t2);
--error ER_WRONG_MRG_TABLE
-select * from t3;
-create temporary table t4 (a int not null);
-create temporary table t5 (a int not null);
-insert into t4 values (1);
-insert into t5 values (2);
-create temporary table t6 (a int not null) ENGINE=MERGE UNION=(t4,t5);
-select * from t6;
-drop table t6, t3, t1, t2, t4, t5;
+SELECT * FROM t3;
+CREATE TEMPORARY TABLE t4 (c1 INT NOT NULL);
+CREATE TEMPORARY TABLE t5 (c1 INT NOT NULL);
+INSERT INTO t4 VALUES (4);
+INSERT INTO t5 VALUES (5);
+CREATE TEMPORARY TABLE t6 (c1 INT NOT NULL) ENGINE=MRG_MYISAM UNION=(t4,t5);
+SELECT * FROM t6;
+DROP TABLE t6, t3, t1, t2, t4, t5;
#
# Bug#19627 - temporary merge table locking
# MERGE table and its children must match in temporary type.
@@ -556,7 +556,7 @@ CREATE TABLE t1(a INT);
SELECT * FROM tm1;
CHECK TABLE tm1;
CREATE TABLE t2(a BLOB);
---error 1168
+--error ER_WRONG_MRG_TABLE
SELECT * FROM tm1;
CHECK TABLE tm1;
ALTER TABLE t2 MODIFY a INT;
@@ -675,12 +675,16 @@ SELECT * FROM t3;
--echo # Truncate MERGE table under locked tables.
LOCK TABLE t1 WRITE, t2 WRITE, t3 WRITE;
INSERT INTO t1 VALUES (1);
---error ER_LOCK_OR_ACTIVE_TRANSACTION
TRUNCATE TABLE t3;
SELECT * FROM t3;
+UNLOCK TABLES;
+SELECT * FROM t1;
+SELECT * FROM t2;
--echo #
--echo # Truncate child table under locked tables.
---error ER_LOCK_OR_ACTIVE_TRANSACTION
+LOCK TABLE t1 WRITE, t2 WRITE, t3 WRITE;
+INSERT INTO t1 VALUES (1);
+INSERT INTO t2 VALUES (2);
TRUNCATE TABLE t1;
SELECT * FROM t3;
UNLOCK TABLES;
@@ -706,14 +710,18 @@ SELECT * FROM t3;
INSERT INTO t1 VALUES (1);
CREATE TABLE t4 (c1 INT, INDEX(c1));
LOCK TABLE t4 WRITE;
---error ER_LOCK_OR_ACTIVE_TRANSACTION
TRUNCATE TABLE t3;
SELECT * FROM t3;
+SELECT * FROM t1;
+SELECT * FROM t2;
--echo #
--echo # Truncate temporary child table under locked tables.
---error ER_LOCK_OR_ACTIVE_TRANSACTION
+INSERT INTO t1 VALUES (1);
+INSERT INTO t2 VALUES (2);
TRUNCATE TABLE t1;
SELECT * FROM t3;
+SELECT * FROM t1;
+SELECT * FROM t2;
UNLOCK TABLES;
DROP TABLE t1, t2, t3, t4;
@@ -846,7 +854,8 @@ SHOW CREATE TABLE t3;
DROP TABLE t1, t2;
#
--echo #
---echo # CREATE ... LIKE
+--echo # Bug#37371 "CREATE TABLE LIKE merge loses UNION parameter"
+--echo # Demonstrate that this is no longer the case.
--echo #
--echo # 1. Create like.
CREATE TABLE t1 (c1 INT);
@@ -858,20 +867,24 @@ INSERT INTO t2 VALUES (2);
INSERT INTO t3 VALUES (3);
CREATE TABLE t4 LIKE t3;
SHOW CREATE TABLE t4;
---error ER_OPEN_AS_READONLY
INSERT INTO t4 VALUES (4);
DROP TABLE t4;
--echo #
--echo # 1. Create like with locked tables.
LOCK TABLES t3 WRITE, t2 WRITE, t1 WRITE;
+--error ER_TABLE_NOT_LOCKED
CREATE TABLE t4 LIKE t3;
--error ER_TABLE_NOT_LOCKED
SHOW CREATE TABLE t4;
--error ER_TABLE_NOT_LOCKED
INSERT INTO t4 VALUES (4);
-UNLOCK TABLES;
+CREATE TEMPORARY TABLE t4 LIKE t3;
+--error ER_WRONG_MRG_TABLE
SHOW CREATE TABLE t4;
---error ER_OPEN_AS_READONLY
+--error ER_WRONG_MRG_TABLE
+INSERT INTO t4 VALUES (4);
+UNLOCK TABLES;
+--error ER_WRONG_MRG_TABLE
INSERT INTO t4 VALUES (4);
DROP TABLE t4;
#
@@ -969,9 +982,9 @@ CREATE TABLE t2 (c1 INT, INDEX(c1)) ENGINE=MRG_MYISAM UNION=(t1)
LOCK TABLES t1 WRITE, t2 WRITE;
INSERT INTO t1 VALUES (1);
DROP TABLE t1;
---error 1168
+--error ER_TABLE_NOT_LOCKED
SELECT * FROM t2;
---error ER_NO_SUCH_TABLE
+--error ER_TABLE_NOT_LOCKED
SELECT * FROM t1;
UNLOCK TABLES;
DROP TABLE t2;
@@ -1407,6 +1420,7 @@ FLUSH TABLES m1, t1;
UNLOCK TABLES;
DROP TABLE t1, m1;
+
#
# Bug#35068 - Assertion fails when reading from i_s.tables
# and there is incorrect merge table
@@ -1694,3 +1708,386 @@ while ($1)
--enable_query_log
drop table t_parent;
set @@global.table_definition_cache=@save_table_definition_cache;
+
+#
+# WL#4144 - Lock MERGE engine children
+#
+# Test DATA/INDEX DIRECTORY
+#
+--disable_warnings
+DROP DATABASE IF EXISTS mysql_test1;
+--enable_warnings
+CREATE DATABASE mysql_test1;
+--disable_query_log
+# data/index directory don't work in HAVE_purify builds. Disable
+# build-dependent warnings.
+--disable_warnings
+--echo CREATE TABLE t1 ... DATA DIRECTORY=... INDEX DIRECTORY=...
+eval CREATE TABLE t1 (c1 INT)
+ DATA DIRECTORY='$MYSQLTEST_VARDIR/tmp'
+ INDEX DIRECTORY='$MYSQLTEST_VARDIR/tmp';
+--echo CREATE TABLE mysql_test1.t2 ... DATA DIRECTORY=... INDEX DIRECTORY=...
+eval CREATE TABLE mysql_test1.t2 (c1 INT)
+ DATA DIRECTORY='$MYSQLTEST_VARDIR/tmp'
+ INDEX DIRECTORY='$MYSQLTEST_VARDIR/tmp';
+--enable_query_log
+--enable_warnings
+CREATE TABLE m1 (c1 INT) ENGINE=MRG_MYISAM UNION=(t1,mysql_test1.t2)
+ INSERT_METHOD=LAST;
+INSERT INTO t1 VALUES (1);
+INSERT INTO mysql_test1.t2 VALUES (2);
+SELECT * FROM m1;
+#--copy_file $MYSQLTEST_VARDIR/master-data/test/m1.MRG /tmp/mysql-test-m1.MRG
+DROP TABLE t1, mysql_test1.t2, m1;
+DROP DATABASE mysql_test1;
+#
+# Review detected Crash #1. Detaching main tables while in sub statement.
+#
+CREATE TABLE t1 (c1 INT);
+CREATE TABLE t2 (c1 INT);
+INSERT INTO t1 (c1) VALUES (1);
+CREATE TABLE tm1 (c1 INT) ENGINE=MRG_MYISAM UNION=(t1,t2) INSERT_METHOD=FIRST;
+CREATE TABLE t3 (c1 INT);
+INSERT INTO t3 (c1) VALUES (1);
+CREATE FUNCTION f1() RETURNS INT RETURN (SELECT MAX(c1) FROM t3);
+CREATE VIEW v1 AS SELECT foo.c1 c1, f1() c2, bar.c1 c3, f1() c4
+ FROM tm1 foo, tm1 bar, t3;
+SELECT * FROM v1;
+DROP FUNCTION f1;
+DROP VIEW v1;
+DROP TABLE tm1, t1, t2, t3;
+#
+# Review detected Crash #2. Trying to attach temporary table twice.
+#
+CREATE TEMPORARY TABLE t1 (c1 INT);
+CREATE TEMPORARY TABLE t2 (c1 INT);
+CREATE TEMPORARY TABLE tm1 (c1 INT) ENGINE=MRG_MYISAM UNION=(t1,t2)
+ INSERT_METHOD=FIRST;
+CREATE FUNCTION f1() RETURNS INT RETURN (SELECT MAX(c1) FROM tm1);
+INSERT INTO tm1 (c1) VALUES (1);
+SELECT f1() FROM (SELECT 1) AS c1;
+DROP FUNCTION f1;
+DROP TABLE tm1, t1, t2;
+#
+# Review suggested test. DDL in a stored function.
+#
+DELIMITER |;
+CREATE FUNCTION f1() RETURNS INT
+BEGIN
+ CREATE TEMPORARY TABLE t1 (c1 INT);
+ CREATE TEMPORARY TABLE t2 (c1 INT);
+ CREATE TEMPORARY TABLE tm1 (c1 INT) ENGINE=MRG_MYISAM UNION=(t1,t2);
+ INSERT INTO t1 (c1) VALUES (1);
+ RETURN (SELECT MAX(c1) FROM tm1);
+END|
+DELIMITER ;|
+SELECT f1() FROM (SELECT 1 UNION SELECT 1) c1;
+DROP FUNCTION f1;
+DROP TABLE tm1, t1, t2;
+#
+CREATE TEMPORARY TABLE t1 (c1 INT);
+INSERT INTO t1 (c1) VALUES (1);
+CREATE TEMPORARY TABLE tm1 (c1 INT) ENGINE=MRG_MYISAM UNION=(t1);
+DELIMITER |;
+--error ER_SP_BADSTATEMENT
+CREATE FUNCTION f1() RETURNS INT
+BEGIN
+ CREATE TEMPORARY TABLE t2 (c1 INT);
+ ALTER TEMPORARY TABLE tm1 UNION=(t1,t2);
+ INSERT INTO t2 (c1) VALUES (2);
+ RETURN (SELECT MAX(c1) FROM tm1);
+END|
+DELIMITER ;|
+DROP TABLE tm1, t1;
+#
+# Base table. No LOCK TABLES, no functions/triggers.
+#
+CREATE TABLE t1 (c1 INT) ENGINE=MyISAM;
+CREATE TABLE tm1 (c1 INT) ENGINE=MRG_MYISAM UNION=(t1) INSERT_METHOD=LAST;
+INSERT INTO tm1 VALUES (1);
+SELECT * FROM tm1;
+DROP TABLE tm1, t1;
+#
+# Base table. No LOCK TABLES, sub-statement that is run inside a function.
+#
+DELIMITER |;
+CREATE FUNCTION f1() RETURNS INT
+BEGIN
+ INSERT INTO tm1 VALUES (1);
+ RETURN (SELECT MAX(c1) FROM tm1);
+END|
+DELIMITER ;|
+CREATE TABLE t1 (c1 INT) ENGINE=MyISAM;
+CREATE TABLE tm1 (c1 INT) ENGINE=MRG_MYISAM UNION=(t1) INSERT_METHOD=LAST;
+SELECT f1();
+DROP FUNCTION f1;
+DROP TABLE tm1, t1;
+#
+# Base table. LOCK TABLES, no functions/triggers.
+#
+CREATE TABLE t1 (c1 INT) ENGINE=MyISAM;
+CREATE TABLE tm1 (c1 INT) ENGINE=MRG_MYISAM UNION=(t1) INSERT_METHOD=LAST;
+LOCK TABLE tm1 WRITE;
+INSERT INTO tm1 VALUES (1);
+SELECT * FROM tm1;
+UNLOCK TABLES;
+DROP TABLE tm1, t1;
+#
+# Base table. LOCK TABLES, sub-statement that is run inside a function.
+#
+DELIMITER |;
+CREATE FUNCTION f1() RETURNS INT
+BEGIN
+ INSERT INTO tm1 VALUES (1);
+ RETURN (SELECT MAX(c1) FROM tm1);
+END|
+DELIMITER ;|
+CREATE TABLE t1 (c1 INT) ENGINE=MyISAM;
+CREATE TABLE tm1 (c1 INT) ENGINE=MRG_MYISAM UNION=(t1) INSERT_METHOD=LAST;
+LOCK TABLE tm1 WRITE;
+SELECT f1();
+UNLOCK TABLES;
+DROP FUNCTION f1;
+DROP TABLE tm1, t1;
+#
+# Base table. LOCK TABLES statement that locks a table that has a trigger
+# that inserts into a merge table, so an attempt is made to lock tables
+# of a sub-statement.
+#
+CREATE TABLE t1 (c1 INT) ENGINE=MyISAM;
+CREATE TABLE t2 (c1 INT) ENGINE=MyISAM;
+CREATE TABLE tm1 (c1 INT) ENGINE=MRG_MYISAM UNION=(t1) INSERT_METHOD=LAST;
+CREATE TRIGGER t2_ai AFTER INSERT ON t2
+ FOR EACH ROW INSERT INTO tm1 VALUES(11);
+LOCK TABLE t2 WRITE;
+INSERT INTO t2 VALUES (2);
+SELECT * FROM tm1;
+SELECT * FROM t2;
+UNLOCK TABLES;
+DROP TRIGGER t2_ai;
+DROP TABLE tm1, t1, t2;
+#
+# Temporary. No LOCK TABLES, no functions/triggers.
+#
+CREATE TEMPORARY TABLE t1 (c1 INT) ENGINE=MyISAM;
+CREATE TEMPORARY TABLE tm1 (c1 INT) ENGINE=MRG_MYISAM UNION=(t1)
+ INSERT_METHOD=LAST;
+INSERT INTO tm1 VALUES (1);
+SELECT * FROM tm1;
+DROP TABLE tm1, t1;
+#
+# Temporary. No LOCK TABLES, sub-statement that is run inside a function.
+#
+DELIMITER |;
+CREATE FUNCTION f1() RETURNS INT
+BEGIN
+ INSERT INTO tm1 VALUES (1);
+ RETURN (SELECT MAX(c1) FROM tm1);
+END|
+DELIMITER ;|
+CREATE TEMPORARY TABLE t1 (c1 INT) ENGINE=MyISAM;
+CREATE TEMPORARY TABLE tm1 (c1 INT) ENGINE=MRG_MYISAM UNION=(t1)
+ INSERT_METHOD=LAST;
+SELECT f1();
+DROP FUNCTION f1;
+DROP TABLE tm1, t1;
+#
+# Temporary. LOCK TABLES, no functions/triggers.
+#
+CREATE TEMPORARY TABLE t1 (c1 INT) ENGINE=MyISAM;
+CREATE TEMPORARY TABLE tm1 (c1 INT) ENGINE=MRG_MYISAM UNION=(t1)
+ INSERT_METHOD=LAST;
+CREATE TABLE t9 (c1 INT) ENGINE=MyISAM;
+LOCK TABLE t9 WRITE;
+INSERT INTO tm1 VALUES (1);
+SELECT * FROM tm1;
+UNLOCK TABLES;
+DROP TABLE tm1, t1, t9;
+#
+# Temporary. LOCK TABLES, sub-statement that is run inside a function.
+#
+DELIMITER |;
+CREATE FUNCTION f1() RETURNS INT
+BEGIN
+ INSERT INTO tm1 VALUES (1);
+ RETURN (SELECT MAX(c1) FROM tm1);
+END|
+DELIMITER ;|
+CREATE TEMPORARY TABLE t1 (c1 INT) ENGINE=MyISAM;
+CREATE TEMPORARY TABLE tm1 (c1 INT) ENGINE=MRG_MYISAM UNION=(t1)
+ INSERT_METHOD=LAST;
+CREATE TABLE t9 (c1 INT) ENGINE=MyISAM;
+LOCK TABLE t9 WRITE;
+SELECT f1();
+UNLOCK TABLES;
+DROP FUNCTION f1;
+DROP TABLE tm1, t1, t9;
+#
+# Temporary. LOCK TABLES statement that locks a table that has a trigger
+# that inserts into a merge table, so an attempt is made to lock tables
+# of a sub-statement.
+#
+CREATE TEMPORARY TABLE t1 (c1 INT) ENGINE=MyISAM;
+CREATE TEMPORARY TABLE tm1 (c1 INT) ENGINE=MRG_MYISAM UNION=(t1)
+ INSERT_METHOD=LAST;
+CREATE TABLE t2 (c1 INT) ENGINE=MyISAM;
+CREATE TRIGGER t2_ai AFTER INSERT ON t2
+ FOR EACH ROW INSERT INTO tm1 VALUES(11);
+LOCK TABLE t2 WRITE;
+INSERT INTO t2 VALUES (2);
+SELECT * FROM tm1;
+SELECT * FROM t2;
+UNLOCK TABLES;
+DROP TRIGGER t2_ai;
+DROP TABLE tm1, t1, t2;
+--echo #
+--echo # Don't allow an update of a MERGE child in a trigger
+--echo # if the table's already being modified by the main
+--echo # statement.
+--echo #
+CREATE TABLE t1 (c1 INT) ENGINE=MyISAM;
+CREATE TABLE tm1 (c1 INT) ENGINE=MRG_MYISAM UNION=(t1)
+ INSERT_METHOD=LAST;
+CREATE TRIGGER tm1_ai AFTER INSERT ON tm1
+ FOR EACH ROW INSERT INTO t1 VALUES(11);
+LOCK TABLE tm1 WRITE, t1 WRITE;
+--error ER_CANT_UPDATE_USED_TABLE_IN_SF_OR_TRG
+INSERT INTO tm1 VALUES (1);
+SELECT * FROM tm1;
+UNLOCK TABLES;
+LOCK TABLE t1 WRITE, tm1 WRITE;
+--error ER_CANT_UPDATE_USED_TABLE_IN_SF_OR_TRG
+INSERT INTO tm1 VALUES (1);
+SELECT * FROM tm1;
+UNLOCK TABLES;
+DROP TRIGGER tm1_ai;
+DROP TABLE tm1, t1;
+
+--echo #
+--echo # Don't select MERGE child when trying to get a prelocked table.
+--echo #
+--echo # Due to a limitation demonstrated by the previous test
+--echo # we can no longer use a write-locked prelocked table.
+--echo # The test is kept for historical purposes.
+--echo #
+CREATE TABLE t1 (c1 INT) ENGINE=MyISAM;
+CREATE TABLE tm1 (c1 INT) ENGINE=MRG_MYISAM UNION=(t1)
+ INSERT_METHOD=LAST;
+CREATE TRIGGER tm1_ai AFTER INSERT ON tm1
+ FOR EACH ROW SELECT max(c1) FROM t1 INTO @var;
+LOCK TABLE tm1 WRITE, t1 WRITE;
+INSERT INTO tm1 VALUES (1);
+SELECT * FROM tm1;
+UNLOCK TABLES;
+LOCK TABLE t1 WRITE, tm1 WRITE;
+INSERT INTO tm1 VALUES (1);
+SELECT * FROM tm1;
+UNLOCK TABLES;
+DROP TRIGGER tm1_ai;
+DROP TABLE tm1, t1;
+
+# Don't resurrect chopped off prelocked tables.
+# The problem is not visible by test results; only by debugging.
+#
+CREATE TABLE t1 (c1 INT) ENGINE=MyISAM;
+CREATE TABLE t2 (c1 INT) ENGINE=MyISAM;
+CREATE TABLE t3 (c1 INT) ENGINE=MyISAM;
+CREATE TABLE t4 (c1 INT) ENGINE=MyISAM;
+CREATE TABLE t5 (c1 INT) ENGINE=MyISAM;
+CREATE TABLE tm1 (c1 INT) ENGINE=MRG_MYISAM UNION=(t1,t2,t3,t4,t5)
+ INSERT_METHOD=LAST;
+CREATE TRIGGER t2_au AFTER UPDATE ON t2
+ FOR EACH ROW SELECT MAX(c1) FROM t1 INTO @var;
+CREATE FUNCTION f1() RETURNS INT
+ RETURN (SELECT MAX(c1) FROM t4);
+LOCK TABLE tm1 WRITE, t1 WRITE, t2 WRITE, t3 WRITE, t4 WRITE, t5 WRITE;
+INSERT INTO t1 VALUES(1);
+INSERT INTO t2 VALUES(2);
+INSERT INTO t3 VALUES(3);
+INSERT INTO t4 VALUES(4);
+INSERT INTO t5 VALUES(5);
+ connect (con1,localhost,root,,);
+ send UPDATE t2, tm1 SET t2.c1=f1();
+connection default;
+# Force reopen in other thread.
+#sleep 1;
+FLUSH TABLES;
+#sleep 1;
+FLUSH TABLES;
+#sleep 1;
+UNLOCK TABLES;
+ connection con1;
+ reap;
+ disconnect con1;
+connection default;
+SELECT * FROM tm1;
+DROP TRIGGER t2_au;
+DROP FUNCTION f1;
+DROP TABLE tm1, t1, t2, t3, t4, t5;
+
+--echo #
+--echo # Bug47098 assert in MDL_context::destroy on HANDLER
+--echo # <damaged merge table> OPEN
+--echo #
+--echo # Test that merge tables are closed correctly when opened using
+--echo # HANDLER ... OPEN.
+--echo # The general case.
+--disable_warnings
+DROP TABLE IF EXISTS t1, t2, t3;
+--enable_warnings
+--echo # Connection con1.
+connect (con1,localhost,root,,);
+CREATE TABLE t1 (c1 int);
+CREATE TABLE t2 (c1 int);
+CREATE TABLE t3 (c1 int) ENGINE = MERGE UNION (t1,t2);
+START TRANSACTION;
+--error ER_ILLEGAL_HA
+HANDLER t3 OPEN;
+DROP TABLE t1, t2, t3;
+--echo # Connection default.
+connection default;
+--echo # Disconnecting con1, all mdl_tickets must have been released.
+disconnect con1;
+--echo # The bug-specific case.
+--echo # Connection con1.
+connect (con1,localhost,root,,);
+CREATE TABLE t1 (c1 int);
+CREATE TABLE t2 (c1 int);
+CREATE TABLE t3 (c1 int) ENGINE = MERGE UNION (t1,t2);
+DROP TABLE t2;
+START TRANSACTION;
+--error ER_WRONG_MRG_TABLE
+HANDLER t3 OPEN;
+DROP TABLE t1, t3;
+--echo # Connection default.
+connection default;
+--echo # Disconnecting con1, all mdl_tickets must have been released.
+disconnect con1;
+
+--echo #
+--echo # A test case for Bug#47648 main.merge fails sporadically
+--echo #
+--echo # Make sure we correctly maintain lex->query_tables_last_own.
+--echo #
+create table t1 (c1 int not null);
+create table t2 (c1 int not null);
+create table t3 (c1 int not null);
+
+create function f1 () returns int return (select max(c1) from t3);
+
+create table t4 (c1 int not null) engine=merge union=(t1,t2) insert_method=last ;
+
+select * from t4 where c1 < f1();
+prepare stmt from "select * from t4 where c1 < f1()";
+execute stmt;
+execute stmt;
+execute stmt;
+drop function f1;
+--error ER_SP_DOES_NOT_EXIST
+execute stmt;
+--error ER_SP_DOES_NOT_EXIST
+execute stmt;
+drop table t4, t3, t2, t1;
+
+--echo End of 6.0 tests
+
diff --git a/mysql-test/t/merge_recover-master.opt b/mysql-test/t/merge_recover-master.opt
new file mode 100644
index 00000000000..875a25ad513
--- /dev/null
+++ b/mysql-test/t/merge_recover-master.opt
@@ -0,0 +1 @@
+--myisam-recover=force
diff --git a/mysql-test/t/merge_recover.test b/mysql-test/t/merge_recover.test
new file mode 100644
index 00000000000..f2cb204eeb6
--- /dev/null
+++ b/mysql-test/t/merge_recover.test
@@ -0,0 +1,113 @@
+--echo #
+--echo # Test of MyISAM MRG tables with corrupted children.
+--echo # Run with --myisam-recover=force option.
+--echo #
+--echo # Preparation: we need to make sure that the merge parent
+--echo # is never left in the table cache when closed, since this may
+--echo # have effect on merge children.
+--echo # For that, we set the table cache to minimal size and populate it
+--echo # in a concurrent connection.
+connect(con1,localhost,root,,test,,);
+--echo #
+--echo # Switching to connection con1
+--echo #
+connection con1;
+--echo #
+--echo # Minimal values.
+--echo #
+
+call mtr.add_suppression("Got an error from thread_id=.*ha_myisam.cc:");
+call mtr.add_suppression("MySQL thread id .*, query id .* localhost.*root Checking table");
+call mtr.add_suppression(" '\..test.t1'");
+
+set global table_open_cache=256;
+set global table_definition_cache=400;
+--disable_warnings
+drop procedure if exists p_create;
+--enable_warnings
+delimiter |;
+create procedure p_create()
+begin
+ declare i int default 1;
+ set @lock_table_stmt="lock table ";
+ set @drop_table_stmt="drop table ";
+ while i < @@global.table_definition_cache + 1 do
+ set @table_name=concat("t_", i);
+ set @opt_comma=if(i=1, "", ", ");
+ set @lock_table_stmt=concat(@lock_table_stmt, @opt_comma,
+ @table_name, " read");
+ set @drop_table_stmt=concat(@drop_table_stmt, @opt_comma, @table_name);
+ set @create_table_stmt=concat("create table if not exists ",
+ @table_name, " (a int)");
+ prepare stmt from @create_table_stmt;
+ execute stmt;
+ deallocate prepare stmt;
+ set i= i+1;
+ end while;
+end|
+delimiter ;|
+call p_create();
+drop procedure p_create;
+--disable_query_log
+let $lock=`select @lock_table_stmt`;
+eval $lock;
+--enable_query_log
+--echo #
+--echo # Switching to connection 'default'
+--echo #
+connection default;
+--echo #
+--echo # We have to disable the ps-protocol, to avoid
+--echo # "Prepared statement needs to be re-prepared" errors
+--echo # -- table def versions change all the time with full table cache.
+--echo #
+--disable_ps_protocol
+--disable_warnings
+drop table if exists t1, t1_mrg, t1_copy;
+--enable_warnings
+let $MYSQLD_DATADIR=`select @@datadir`;
+--echo #
+--echo # Prepare a MERGE engine table, that refers to a corrupted
+--echo # child.
+--echo #
+create table t1 (a int, key(a)) engine=myisam;
+create table t1_mrg (a int) union (t1) engine=merge;
+--echo #
+--echo # Create a table with a corrupted index file:
+--echo # save an old index file, insert more rows,
+--echo # overwrite the new index file with the old one.
+--echo #
+insert into t1 (a) values (1), (2), (3);
+flush table t1;
+--copy_file $MYSQLD_DATADIR/test/t1.MYI $MYSQLD_DATADIR/test/t1_copy.MYI
+insert into t1 (a) values (4), (5), (6);
+flush table t1;
+--remove_file $MYSQLD_DATADIR/test/t1.MYI
+--copy_file $MYSQLD_DATADIR/test/t1_copy.MYI $MYSQLD_DATADIR/test/t1.MYI
+--remove_file $MYSQLD_DATADIR/test/t1_copy.MYI
+--echo # check table is needed to mark the table as crashed.
+check table t1;
+--echo #
+--echo # At this point we have a merge table t1_mrg pointing to t1,
+--echo # and t1 is corrupted, and will be auto-repaired at open.
+--echo # Check that this doesn't lead to memory corruption.
+--echo #
+--replace_regex /'.*[\/\\]/'/
+select * from t1_mrg;
+--echo #
+--echo # Cleanup
+--echo #
+drop table t1, t1_mrg;
+--echo #
+--echo # Switching to connection con1
+--echo #
+connection con1;
+unlock tables;
+prepare stmt from @drop_table_stmt;
+execute stmt;
+deallocate prepare stmt;
+set @@global.table_definition_cache=default;
+set @@global.table_open_cache=default;
+disconnect con1;
+connection default;
+--enable_ps_protocol
diff --git a/mysql-test/t/multi_update.test b/mysql-test/t/multi_update.test
index fc37fd6a27d..68b44a33428 100644
--- a/mysql-test/t/multi_update.test
+++ b/mysql-test/t/multi_update.test
@@ -474,7 +474,8 @@ drop table t1,t2;
#
# Test alter table and a concurrent multi update
-# (This will force update to reopen tables)
+# (Before we have introduced data-lock-aware metadata locks
+# this test case forced update to reopen tables).
#
create table t1 (a int, b int);
@@ -494,9 +495,9 @@ send alter table t1 add column c int default 100 after a;
connect (updater,localhost,root,,test);
connection updater;
# Wait till "alter table t1 ..." of session changer is in work.
-# = There is one session is in state "Locked".
+# = There is one session waiting.
let $wait_condition= select count(*)= 1 from information_schema.processlist
- where state= 'Locked';
+ where state= 'Waiting for table';
--source include/wait_condition.inc
send update t1, v1 set t1.b=t1.a+t1.b+v1.b where t1.a=v1.a;
@@ -505,9 +506,9 @@ connection locker;
# - "alter table t1 ..." of session changer and
# - "update t1, v1 ..." of session updater
# are in work.
-# = There are two session is in state "Locked".
+# = There are two session waiting.
let $wait_condition= select count(*)= 2 from information_schema.processlist
- where state= 'Locked';
+ where state= 'Waiting for table';
--source include/wait_condition.inc
unlock tables;
diff --git a/mysql-test/t/not_embedded_server.test b/mysql-test/t/not_embedded_server.test
index fa2b659ec57..917d5871682 100644
--- a/mysql-test/t/not_embedded_server.test
+++ b/mysql-test/t/not_embedded_server.test
@@ -4,12 +4,6 @@
-- source include/not_embedded.inc
-#
-# Produce output
-#
-
-select 1;
-
# The following fails sporadically because 'check-testcase' runs
# queries before this test and there is no way to guarantee that any
# previous process finishes. The purpose of the test is not clearly
@@ -36,6 +30,8 @@ select 1;
#execute stmt1;
#deallocate prepare stmt1;
+call mtr.add_suppression("Can't open and lock privilege tables: Table 'host' was not locked with LOCK TABLES");
+
#
# Bug#43835: SHOW VARIABLES does not include 0 for slave_skip_errors
#
@@ -43,3 +39,18 @@ select 1;
SHOW VARIABLES like 'slave_skip_errors';
# End of 5.1 tests
+
+--echo #
+--echo # WL#4284: Transactional DDL locking
+--echo #
+--echo # FLUSH PRIVILEGES should not implicitly unlock locked tables.
+--echo #
+--disable_warnings
+drop table if exists t1;
+--enable_warnings
+create table t1 (c1 int);
+lock tables t1 read;
+--error ER_TABLE_NOT_LOCKED
+flush privileges;
+unlock tables;
+drop table t1;
diff --git a/mysql-test/t/partition.test b/mysql-test/t/partition.test
index 1904b4cb805..18b7e0d343b 100644
--- a/mysql-test/t/partition.test
+++ b/mysql-test/t/partition.test
@@ -95,6 +95,19 @@ show indexes from t1;
drop table t1;
#
+# Bug#40181: hang if create index
+#
+create table t1 (a int)
+partition by hash (a);
+create index i on t1 (a);
+insert into t1 values (1);
+insert into t1 select * from t1;
+--error ER_DUP_KEYNAME
+create index i on t1 (a);
+create index i2 on t1 (a);
+drop table t1;
+
+#
# Bug#36001: Partitions: spelling and using some error messages
#
--error ER_FOREIGN_KEY_ON_PARTITIONED
diff --git a/mysql-test/t/partition_innodb-master.opt b/mysql-test/t/partition_innodb-master.opt
deleted file mode 100644
index 462f8fbe828..00000000000
--- a/mysql-test/t/partition_innodb-master.opt
+++ /dev/null
@@ -1 +0,0 @@
---innodb_lock_wait_timeout=1
diff --git a/mysql-test/t/partition_innodb.test b/mysql-test/t/partition_innodb.test
index a910bbb001e..a2764766c4e 100644
--- a/mysql-test/t/partition_innodb.test
+++ b/mysql-test/t/partition_innodb.test
@@ -350,6 +350,7 @@ DROP TABLE t1;
# Before the fix it should show extra file like #sql-2405_2.par
--list_files $MYSQLD_DATADIR/test/ *
+--disable_parsing
--echo #
--echo # Bug#47343: InnoDB fails to clean-up after lock wait timeout on
--echo # REORGANIZE PARTITION
@@ -390,3 +391,4 @@ connection default;
SELECT * FROM t1;
COMMIT;
DROP TABLE t1;
+--enable_parsing
diff --git a/mysql-test/t/partition_innodb_semi_consistent.test b/mysql-test/t/partition_innodb_semi_consistent.test
index 6a6a7cf958e..2bf879603a4 100644
--- a/mysql-test/t/partition_innodb_semi_consistent.test
+++ b/mysql-test/t/partition_innodb_semi_consistent.test
@@ -157,7 +157,7 @@ connection con1;
--echo # 3. test for updated key column:
TRUNCATE t1;
-TRUNCATE t2;
+DELETE FROM t2;
INSERT INTO t1 VALUES (1,'init');
diff --git a/mysql-test/t/partition_sync.test b/mysql-test/t/partition_sync.test
index a732b35b8b9..85eb33ebb6b 100644
--- a/mysql-test/t/partition_sync.test
+++ b/mysql-test/t/partition_sync.test
@@ -1,4 +1,5 @@
--source include/have_partition.inc
+--source include/have_debug.inc
# Save the initial number of concurrent sessions.
--source include/count_sessions.inc
@@ -36,6 +37,57 @@ disconnect con1;
DROP TABLE t1;
+--echo #
+--echo # Bug #46654 False deadlock on concurrent DML/DDL
+--echo # with partitions, inconsistent behavior
+--echo #
+
+--disable_warnings
+DROP TABLE IF EXISTS tbl_with_partitions;
+--enable_warnings
+
+CREATE TABLE tbl_with_partitions ( i INT )
+ PARTITION BY HASH(i);
+INSERT INTO tbl_with_partitions VALUES (1);
+
+connect(con2,localhost,root);
+connect(con3,localhost,root);
+
+--echo # Connection 3
+connection con3;
+LOCK TABLE tbl_with_partitions READ;
+
+--echo # Connection 1
+--echo # Access table with disabled autocommit
+connection default;
+SET AUTOCOMMIT = 0;
+SELECT * FROM tbl_with_partitions;
+
+--echo # Connection 2
+--echo # Alter table, abort after prepare
+connection con2;
+set session debug="+d,abort_copy_table";
+--error ER_LOCK_WAIT_TIMEOUT
+ALTER TABLE tbl_with_partitions ADD COLUMN f INT;
+
+--echo # Connection 1
+--echo # Try accessing the table after Alter aborted.
+--echo # This used to give ER_LOCK_DEADLOCK.
+connection default;
+SELECT * FROM tbl_with_partitions;
+
+--echo # Connection 3
+connection con3;
+UNLOCK TABLES;
+
+--echo # Connection 1
+--echo # Cleanup
+connection default;
+disconnect con2;
+disconnect con3;
+DROP TABLE tbl_with_partitions;
+
+
# Check that all connections opened by test cases in this file are really
# gone so execution of other tests won't be affected by their presence.
--source include/wait_until_count_sessions.inc
diff --git a/mysql-test/t/ps.test b/mysql-test/t/ps.test
index 6b12832b17b..dcea4d9828b 100644
--- a/mysql-test/t/ps.test
+++ b/mysql-test/t/ps.test
@@ -3267,7 +3267,44 @@ DROP PROCEDURE p2;
###########################################################################
---echo
---echo End of 6.0 tests.
+
+--echo #
+--echo # WL#4284: Transactional DDL locking
+--echo #
+
+--disable_warnings
+DROP TABLE IF EXISTS t1;
+--enable_warnings
+CREATE TABLE t1 (a INT);
+BEGIN;
+SELECT * FROM t1;
+--echo # Test that preparing a CREATE TABLE does not take a exclusive metdata lock.
+PREPARE stmt1 FROM "CREATE TABLE t1 AS SELECT 1";
+--error ER_TABLE_EXISTS_ERROR
+EXECUTE stmt1;
+DEALLOCATE PREPARE stmt1;
+DROP TABLE t1;
+
+--echo #
+--echo # WL#4284: Transactional DDL locking
+--echo #
+--echo # Test that metadata locks taken during prepare are released.
+--echo #
+
+connect(con1,localhost,root,,);
+connection default;
+--disable_warnings
+DROP TABLE IF EXISTS t1;
+--enable_warnings
+CREATE TABLE t1 (a INT);
+connection con1;
+BEGIN;
+PREPARE stmt1 FROM "SELECT * FROM t1";
+connection default;
+DROP TABLE t1;
+disconnect con1;
+
+--echo #
+--echo # End of 6.0 tests.
###########################################################################
diff --git a/mysql-test/t/ps_ddl.test b/mysql-test/t/ps_ddl.test
index 1543c757908..3803a0daf52 100644
--- a/mysql-test/t/ps_ddl.test
+++ b/mysql-test/t/ps_ddl.test
@@ -278,8 +278,6 @@ deallocate prepare stmt;
--echo # Test 7-a: dependent PROCEDURE has changed
--echo #
---echo # Note, this scenario is not supported, subject of Bug#12093
---echo #
create table t1 (a int);
create trigger t1_ai after insert on t1 for each row
@@ -291,11 +289,10 @@ execute stmt using @var;
drop procedure p1;
create procedure p1 (a int) begin end;
set @var= 2;
---error ER_SP_DOES_NOT_EXIST
execute stmt using @var;
--echo # Cleanup
drop procedure p1;
-call p_verify_reprepare_count(0);
+call p_verify_reprepare_count(1);
--echo # Test 7-b: dependent FUNCTION has changed
--echo #
@@ -355,11 +352,13 @@ set @var=8;
--echo # XXX: bug, the SQL statement in the trigger is still
--echo # pointing at table 't3', since the view was expanded
--echo # at first statement execution.
+--echo # Since the view definition is inlined in the statement
+--echo # at prepare, changing the view definition does not cause
+--echo # repreparation.
--echo # Repreparation of the main statement doesn't cause repreparation
--echo # of trigger statements.
---error ER_NO_SUCH_TABLE
execute stmt using @var;
-call p_verify_reprepare_count(1);
+call p_verify_reprepare_count(0);
--echo #
--echo # Sic: the insert went into t3, even though the view now
--echo # points at t2. This is because neither the merged view
@@ -642,6 +641,9 @@ deallocate prepare stmt;
--echo Part 16: VIEW -> TEMPORARY TABLE transitions
--echo =====================================================================
+--echo #
+--echo # Test 1: Merged view
+--echo #
create table t2 (a int);
insert into t2 (a) values (1);
create view t1 as select * from t2;
@@ -651,9 +653,39 @@ execute stmt;
call p_verify_reprepare_count(0);
create temporary table t1 (a int);
+# t1 still refers to the view - no reprepare has been done.
execute stmt;
-call p_verify_reprepare_count(1);
+call p_verify_reprepare_count(0);
+
+drop view t1;
+# t1 still refers to the, now deleted, view - no reprepare has been done.
+--error ER_NO_SUCH_TABLE
+execute stmt;
+call p_verify_reprepare_count(0);
+
+drop table t2;
+drop temporary table t1;
+deallocate prepare stmt;
+
+--echo #
+--echo # Test 2: Materialized view
+--echo #
+create table t2 (a int);
+insert into t2 (a) values (1);
+create algorithm = temptable view t1 as select * from t2;
+
+prepare stmt from "select * from t1";
+execute stmt;
+call p_verify_reprepare_count(0);
+
+create temporary table t1 (a int);
+# t1 still refers to the view - no reprepare has been done.
+execute stmt;
+call p_verify_reprepare_count(0);
+
drop view t1;
+# t1 still refers to the, now deleted, view - no reprepare has been done.
+--error ER_NO_SUCH_TABLE
execute stmt;
call p_verify_reprepare_count(0);
@@ -661,6 +693,28 @@ drop table t2;
drop temporary table t1;
deallocate prepare stmt;
+--echo #
+--echo # Test 3: View referencing an Information schema table
+--echo #
+create view t1 as select table_name from information_schema.views;
+
+prepare stmt from "select * from t1";
+execute stmt;
+call p_verify_reprepare_count(0);
+
+create temporary table t1 (a int);
+# t1 has been substituted with a reference to the IS table
+execute stmt;
+call p_verify_reprepare_count(0);
+
+drop view t1;
+# Since the IS table has been substituted in, the statement still works
+execute stmt;
+call p_verify_reprepare_count(0);
+
+drop temporary table t1;
+deallocate prepare stmt;
+
--echo =====================================================================
--echo Part 17: VIEW -> VIEW (DDL) transitions
--echo =====================================================================
@@ -1447,7 +1501,7 @@ drop table t2;
create temporary table t2 (a int);
# Temporary table and base table are not in the same name space.
execute stmt;
-call p_verify_reprepare_count(1);
+call p_verify_reprepare_count(0);
--error ER_TABLE_EXISTS_ERROR
execute stmt;
call p_verify_reprepare_count(1);
@@ -1457,7 +1511,7 @@ execute stmt;
call p_verify_reprepare_count(0);
drop table t2;
execute stmt;
-call p_verify_reprepare_count(1);
+call p_verify_reprepare_count(0);
drop table t2;
# View with name of table to be created exists
# Attention:
@@ -1494,27 +1548,24 @@ execute stmt;
call p_verify_reprepare_count(0);
drop table t1;
deallocate prepare stmt;
---echo # XXX: no validation of the first table in case of
---echo # CREATE TEMPORARY TABLE. This is a shortcoming of the current code,
---echo # but since validation is not strictly necessary, nothing is done
---echo # about it.
---echo # Will be fixed as part of work on Bug#21431 "Incomplete support of
---echo # temporary tables"
create table t1 (a int);
insert into t1 (a) values (1);
prepare stmt from "create temporary table if not exists t2 as select * from t1";
execute stmt;
drop table t2;
execute stmt;
+call p_verify_reprepare_count(0);
execute stmt;
+call p_verify_reprepare_count(1);
select * from t2;
execute stmt;
+call p_verify_reprepare_count(0);
select * from t2;
drop table t2;
create temporary table t2 (a varchar(10));
execute stmt;
select * from t2;
-call p_verify_reprepare_count(0);
+call p_verify_reprepare_count(1);
drop table t1;
create table t1 (x int);
execute stmt;
diff --git a/mysql-test/t/ps_ddl1.test b/mysql-test/t/ps_ddl1.test
index 379ed576b5f..0145d445a14 100644
--- a/mysql-test/t/ps_ddl1.test
+++ b/mysql-test/t/ps_ddl1.test
@@ -363,7 +363,7 @@ end|
delimiter ;|
--error ER_SP_DOES_NOT_EXIST
execute stmt;
-call p_verify_reprepare_count(1);
+call p_verify_reprepare_count(0);
--error ER_SP_DOES_NOT_EXIST
execute stmt;
call p_verify_reprepare_count(0);
diff --git a/mysql-test/t/query_cache_28249.test b/mysql-test/t/query_cache_28249.test
index 390a1ce6e3d..c95d7553988 100644
--- a/mysql-test/t/query_cache_28249.test
+++ b/mysql-test/t/query_cache_28249.test
@@ -58,18 +58,18 @@ connection user3;
# Typical information_schema.processlist content after sufficient sleep time
# ID USER COMMAND TIME STATE INFO
# ....
-# 2 root Query 5 Locked SELECT *, (SELECT COUNT(*) FROM t2) FROM t1
+# 2 root Query 5 Table lock SELECT *, (SELECT COUNT(*) FROM t2) FROM t1
# ....
# XXXXXX XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
# The values marked with 'X' must be reached.
--echo # Poll till the select of connection user1 is blocked by the write lock on t1.
let $wait_condition= SELECT COUNT(*) = 1 FROM information_schema.processlist
-WHERE state = 'Locked'
+WHERE state = 'Table lock'
AND info = '$select_for_qc';
--source include/wait_condition.inc
eval
SELECT user,command,state,info FROM information_schema.processlist
-WHERE state = 'Locked'
+WHERE state = 'Table lock'
AND info = '$select_for_qc';
INSERT INTO t1 VALUES (4);
diff --git a/mysql-test/t/read_only_innodb.test b/mysql-test/t/read_only_innodb.test
index f8c25fdee1d..9e001f2b997 100644
--- a/mysql-test/t/read_only_innodb.test
+++ b/mysql-test/t/read_only_innodb.test
@@ -33,7 +33,7 @@ set global read_only=1;
connection con1;
select @@global.read_only;
select * from table_11733 ;
--- error ER_OPTION_PREVENTS_STATEMENT
+--error ER_OPTION_PREVENTS_STATEMENT
COMMIT;
connection default;
diff --git a/mysql-test/t/repair.test b/mysql-test/t/repair.test
index eb2ca7992a6..3c55f06ff4c 100644
--- a/mysql-test/t/repair.test
+++ b/mysql-test/t/repair.test
@@ -158,3 +158,33 @@ CREATE TEMPORARY TABLE tt1 (c1 INT);
REPAIR TABLE tt1 USE_FRM;
DROP TABLE tt1;
+
+--echo #
+--echo # Bug #48248 assert in MDL_ticket::upgrade_shared_lock_to_exclusive
+--echo #
+
+--disable_warnings
+DROP TABLE IF EXISTS t1;
+--enable_warnings
+
+CREATE TABLE t1(a INT);
+LOCK TABLES t1 READ;
+REPAIR TABLE t1;
+
+UNLOCK TABLES;
+DROP TABLE t1;
+
+
+--echo #
+--echo # Test for bug #50784 "MDL: Assertion `m_tickets.is_empty() ||
+--echo # m_tickets.front() == m_trans_sentinel'"
+--echo #
+--disable_warnings
+drop tables if exists t1, t2;
+--enable_warnings
+create table t1 (i int);
+create table t2 (j int);
+set @@autocommit= 0;
+repair table t1, t2;
+set @@autocommit= default;
+drop tables t1, t2;
diff --git a/mysql-test/t/schema.test b/mysql-test/t/schema.test
index a08d9b38935..f106b9e4865 100644
--- a/mysql-test/t/schema.test
+++ b/mysql-test/t/schema.test
@@ -4,6 +4,9 @@
# Drop mysqltest1 database, as it can left from the previous tests.
#
+# Save the initial number of concurrent sessions.
+--source include/count_sessions.inc
+
--disable_warnings
drop database if exists mysqltest1;
--enable_warnings
@@ -12,3 +15,93 @@ create schema foo;
show create schema foo;
show schemas;
drop schema foo;
+
+
+--echo #
+--echo # Bug #48940 MDL deadlocks against mysql_rm_db
+--echo #
+
+--disable_warnings
+DROP SCHEMA IF EXISTS schema1;
+--enable_warnings
+
+connect(con2, localhost, root);
+
+--echo # Connection default
+connection default;
+
+CREATE SCHEMA schema1;
+CREATE TABLE schema1.t1 (a INT);
+
+SET autocommit= FALSE;
+INSERT INTO schema1.t1 VALUES (1);
+
+--echo # Connection 2
+connection con2;
+--send DROP SCHEMA schema1
+
+--echo # Connection default
+connection default;
+let $wait_condition= SELECT COUNT(*)= 1 FROM information_schema.processlist
+ WHERE state= 'Waiting for table'
+ AND info='DROP SCHEMA schema1';
+--source include/wait_condition.inc
+# Listing the error twice to prevent result diffences based on filename
+--error 1,1
+ALTER SCHEMA schema1 DEFAULT CHARACTER SET utf8;
+SET autocommit= TRUE;
+
+--echo # Connection 2
+connection con2;
+--reap
+
+--echo # Connection default
+connection default;
+disconnect con2;
+
+
+--echo #
+--echo # Bug #49988 MDL deadlocks with mysql_create_db, reload_acl_and_cache
+--echo #
+
+--disable_warnings
+DROP SCHEMA IF EXISTS schema1;
+--enable_warnings
+
+connect (con2, localhost, root);
+
+--echo # Connection default
+connection default;
+CREATE SCHEMA schema1;
+CREATE TABLE schema1.t1 (id INT);
+LOCK TABLE schema1.t1 WRITE;
+
+--echo # Connection con2
+connection con2;
+--send DROP SCHEMA schema1
+
+--echo # Connection default
+connection default;
+let $wait_condition=SELECT COUNT(*)=1 FROM information_schema.processlist
+ WHERE state='Waiting for table' and info='DROP SCHEMA schema1';
+--source include/wait_condition.inc
+
+--echo # CREATE SCHEMA used to give a deadlock.
+--echo # Now we prohibit CREATE SCHEMA in LOCK TABLES mode.
+--error ER_LOCK_OR_ACTIVE_TRANSACTION
+CREATE SCHEMA IF NOT EXISTS schema1;
+
+--echo # UNLOCK TABLES so DROP SCHEMA can continue.
+UNLOCK TABLES;
+
+--echo # Connection con2
+connection con2;
+--reap
+
+--echo # Connection default
+connection default;
+disconnect con2;
+
+# Check that all connections opened by test cases in this file are really
+# gone so execution of other tests won't be affected by their presence.
+--source include/wait_until_count_sessions.inc
diff --git a/mysql-test/t/sp-error.test b/mysql-test/t/sp-error.test
index e33adf56284..c8b2595e23d 100644
--- a/mysql-test/t/sp-error.test
+++ b/mysql-test/t/sp-error.test
@@ -723,7 +723,7 @@ lock table t1 read|
# This should fail since we forgot to lock mysql.proc for writing
# explicitly, and we can't open mysql.proc for _writing_ if there
# are locked tables.
---error 1100
+--error ER_LOCK_OR_ACTIVE_TRANSACTION
alter procedure bug9566 comment 'Some comment'|
unlock tables|
# This should succeed
@@ -2490,6 +2490,35 @@ SELECT AVG (a) FROM t1 WHERE b = 999999;
SELECT non_existent (a) FROM t1 WHERE b = 999999;
DROP TABLE t1;
+
+#
+# Bug #46374 crash, INSERT INTO t1 uses function, function modifies t1
+#
+CREATE TABLE t1 ( f2 INTEGER, f3 INTEGER );
+INSERT INTO t1 VALUES ( 1, 1 );
+
+delimiter |;
+
+CREATE FUNCTION func_1 () RETURNS INTEGER
+BEGIN
+ INSERT INTO t1 SELECT * FROM t1 ;
+ RETURN 1 ;
+END|
+
+delimiter ;|
+
+# The bug caused the following INSERT statement to trigger
+# an assertion. Error 1442 is the correct response
+#
+--error 1442
+INSERT INTO t1 SELECT * FROM (SELECT 2 AS f1, 2 AS f2) AS A WHERE func_1() = 5;
+
+# Cleanup
+DROP FUNCTION func_1;
+DROP TABLE t1;
+
+
+
--echo #
--echo # Bug #47788: Crash in TABLE_LIST::hide_view_error on UPDATE + VIEW +
--echo # SP + MERGE + ALTER
@@ -2513,3 +2542,4 @@ DROP VIEW v1;
DROP TABLE t1;
--echo End of 5.1 tests
+
diff --git a/mysql-test/t/sp-lock.test b/mysql-test/t/sp-lock.test
new file mode 100644
index 00000000000..0b31eabb0f1
--- /dev/null
+++ b/mysql-test/t/sp-lock.test
@@ -0,0 +1,898 @@
+# Copyright (C) 2009 Sun Microsystems, Inc
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+#
+# Metadata lock handling for stored procedures and
+# functions.
+#
+--echo #
+--echo # Test coverage for changes performed by the fix
+--echo # for Bug#30977 "Concurrent statement using stored function
+--echo # and DROP FUNCTION breaks SBR.
+--echo #
+
+--echo #
+--echo # 1) Verify that the preceding transaction is
+--echo # (implicitly) committed before CREATE/ALTER/DROP
+--echo # PROCEDURE. Note, that this is already tested
+--echo # in implicit_commit.test, but here we use an alternative
+--echo # approach.
+--echo #
+
+--echo # Start a transaction, create a savepoint,
+--echo # then call a DDL operation on a procedure, and then check
+--echo # that the savepoint is no longer present.
+
+--disable_warnings
+drop table if exists t1;
+drop procedure if exists p1;
+drop procedure if exists p2;
+drop procedure if exists p3;
+drop procedure if exists p4;
+drop function if exists f1;
+--enable_warnings
+create table t1 (a int);
+--echo #
+--echo # Test 'CREATE PROCEDURE'.
+--echo #
+begin;
+savepoint sv;
+create procedure p1() begin end;
+--error ER_SP_DOES_NOT_EXIST
+rollback to savepoint sv;
+--echo #
+--echo # Test 'ALTER PROCEDURE'.
+--echo #
+begin;
+savepoint sv;
+alter procedure p1 comment 'changed comment';
+--error ER_SP_DOES_NOT_EXIST
+rollback to savepoint sv;
+--echo #
+--echo # Test 'DROP PROCEDURE'.
+--echo #
+begin;
+savepoint sv;
+drop procedure p1;
+--error ER_SP_DOES_NOT_EXIST
+rollback to savepoint sv;
+--echo #
+--echo # Test 'CREATE FUNCTION'.
+--echo #
+begin;
+savepoint sv;
+create function f1() returns int return 1;
+--error ER_SP_DOES_NOT_EXIST
+rollback to savepoint sv;
+--echo #
+--echo # Test 'ALTER FUNCTION'.
+--echo #
+begin;
+savepoint sv;
+alter function f1 comment 'new comment';
+--error ER_SP_DOES_NOT_EXIST
+rollback to savepoint sv;
+--echo #
+--echo # Test 'DROP FUNCTION'.
+--echo #
+begin;
+savepoint sv;
+drop function f1;
+--error ER_SP_DOES_NOT_EXIST
+rollback to savepoint sv;
+
+--echo #
+--echo # 2) Verify that procedure DDL operations fail
+--echo # under lock tables.
+--echo #
+--echo # Auxiliary routines to test ALTER.
+create procedure p1() begin end;
+create function f1() returns int return 1;
+
+lock table t1 write;
+--error ER_LOCK_OR_ACTIVE_TRANSACTION
+create procedure p2() begin end;
+--error ER_LOCK_OR_ACTIVE_TRANSACTION
+alter procedure p1 comment 'changed comment';
+--error ER_LOCK_OR_ACTIVE_TRANSACTION
+drop procedure p1;
+--error ER_LOCK_OR_ACTIVE_TRANSACTION
+create function f2() returns int return 1;
+--error ER_LOCK_OR_ACTIVE_TRANSACTION
+alter function f1 comment 'changed comment';
+lock table t1 read;
+--error ER_LOCK_OR_ACTIVE_TRANSACTION
+create procedure p2() begin end;
+--error ER_LOCK_OR_ACTIVE_TRANSACTION
+alter procedure p1 comment 'changed comment';
+--error ER_LOCK_OR_ACTIVE_TRANSACTION
+drop procedure p1;
+--error ER_LOCK_OR_ACTIVE_TRANSACTION
+create function f2() returns int return 1;
+--error ER_LOCK_OR_ACTIVE_TRANSACTION
+alter function f1 comment 'changed comment';
+unlock tables;
+--echo #
+--echo # Even if we locked a temporary table.
+--echo # Todo: this is a restriction we could possibly lift.
+--echo #
+drop table t1;
+create temporary table t1 (a int);
+lock table t1 read;
+--error ER_LOCK_OR_ACTIVE_TRANSACTION
+create procedure p2() begin end;
+--error ER_LOCK_OR_ACTIVE_TRANSACTION
+alter procedure p1 comment 'changed comment';
+--error ER_LOCK_OR_ACTIVE_TRANSACTION
+drop procedure p1;
+--error ER_LOCK_OR_ACTIVE_TRANSACTION
+create function f2() returns int return 1;
+--error ER_LOCK_OR_ACTIVE_TRANSACTION
+alter function f1 comment 'changed comment';
+unlock tables;
+
+drop function f1;
+drop procedure p1;
+drop temporary table t1;
+
+--echo #
+--echo # 3) Verify that CREATE/ALTER/DROP routine grab an
+--echo # exclusive lock.
+--echo #
+--echo # For that, start a transaction, use a routine. In a concurrent
+--echo # connection, try to drop or alter the routine. It should place
+--echo # a pending or exclusive lock and block. In another concurrnet
+--echo # connection, try to use the routine.
+--echo # That should block on the pending exclusive lock.
+--echo #
+--echo # Establish helper connections.
+connect(con1, localhost, root,,);
+connect(con2, localhost, root,,);
+connect(con3, localhost, root,,);
+
+--echo #
+--echo # Test DROP PROCEDURE.
+--echo #
+--echo # --> connection default
+connection default;
+create procedure p1() begin end;
+delimiter |;
+create function f1() returns int
+begin
+ call p1();
+ return 1;
+end|
+delimiter ;|
+begin;
+select f1();
+--echo # --> connection con1
+connection con1;
+--echo # Sending 'drop procedure p1'...
+send drop procedure p1;
+--echo # --> connection con2
+connection con2;
+--echo # Waitng for 'drop procedure t1' to get blocked on MDL lock...
+let $wait_condition=select count(*)=1 from information_schema.processlist
+where state='Waiting for table' and info='drop procedure p1';
+--source include/wait_condition.inc
+--echo # Demonstrate that there is a pending exclusive lock.
+--echo # Sending 'select f1()'...
+send select f1();
+--echo # --> connection con3
+connection con3;
+--echo # Waitng for 'select f1()' to get blocked by a pending MDL lock...
+let $wait_condition=select count(*)=1 from information_schema.processlist
+where state='Waiting for table' and info='select f1()';
+--echo # --> connection default
+connection default;
+commit;
+--echo # --> connection con1
+connection con1;
+--echo # Reaping 'drop procedure p1'...
+reap;
+--echo # --> connection con2
+connection con2;
+--echo # Reaping 'select f1()'
+--error ER_SP_DOES_NOT_EXIST
+reap;
+--echo # --> connection default
+connection default;
+
+--echo #
+--echo # Test CREATE PROCEDURE.
+--echo #
+create procedure p1() begin end;
+begin;
+select f1();
+--echo # --> connection con1
+connection con1;
+--echo # Sending 'create procedure p1'...
+send create procedure p1() begin end;
+--echo # --> connection con2
+connection con2;
+--echo # Waitng for 'create procedure t1' to get blocked on MDL lock...
+let $wait_condition=select count(*)=1 from information_schema.processlist
+where state='Waiting for table' and info='create procedure p1() begin end';
+--source include/wait_condition.inc
+--echo # Demonstrate that there is a pending exclusive lock.
+--echo # Sending 'select f1()'...
+send select f1();
+--echo # --> connection con3
+connection con3;
+--echo # Waitng for 'select f1()' to get blocked by a pending MDL lock...
+let $wait_condition=select count(*)=1 from information_schema.processlist
+where state='Waiting for table' and info='select f1()';
+--echo # --> connection default
+connection default;
+commit;
+--echo # --> connection con1
+connection con1;
+--echo # Reaping 'create procedure p1'...
+--error ER_SP_ALREADY_EXISTS
+reap;
+--echo # --> connection con2
+connection con2;
+--echo # Reaping 'select f1()'
+reap;
+connection default;
+
+--echo #
+--echo # Test ALTER PROCEDURE.
+--echo #
+begin;
+select f1();
+--echo # --> connection con1
+connection con1;
+--echo # Sending 'alter procedure p1'...
+send alter procedure p1 contains sql;
+--echo # --> connection con2
+connection con2;
+--echo # Waitng for 'alter procedure t1' to get blocked on MDL lock...
+let $wait_condition=select count(*)=1 from information_schema.processlist
+where state='Waiting for table' and info='alter procedure p1 contains sql';
+--source include/wait_condition.inc
+--echo # Demonstrate that there is a pending exclusive lock.
+--echo # Sending 'select f1()'...
+send select f1();
+--echo # --> connection con3
+connection con3;
+--echo # Waitng for 'select f1()' to get blocked by a pending MDL lock...
+let $wait_condition=select count(*)=1 from information_schema.processlist
+where state='Waiting for table' and info='select f1()';
+--echo # --> connection default
+connection default;
+commit;
+--echo # --> connection con1
+connection con1;
+--echo # Reaping 'alter procedure p1'...
+reap;
+--echo # --> connection con2
+connection con2;
+--echo # Reaping 'select f1()'
+reap;
+--echo # --> connection default
+connection default;
+
+--echo #
+--echo # Test DROP FUNCTION.
+--echo #
+begin;
+select f1();
+--echo # --> connection con1
+connection con1;
+--echo # Sending 'drop function f1'...
+send drop function f1;
+--echo # --> connection con2
+connection con2;
+--echo # Waitng for 'drop function f1' to get blocked on MDL lock...
+let $wait_condition=select count(*)=1 from information_schema.processlist
+where state='Waiting for table' and info='drop function f1';
+--source include/wait_condition.inc
+--echo # Demonstrate that there is a pending exclusive lock.
+--echo # Sending 'select f1()'...
+send select f1();
+--echo # --> connection con3
+connection con3;
+--echo # Waitng for 'select f1()' to get blocked by a pending MDL lock...
+let $wait_condition=select count(*)=1 from information_schema.processlist
+where state='Waiting for table' and info='select f1()';
+--echo # --> connection default
+connection default;
+commit;
+--echo # --> connection con1
+connection con1;
+--echo # Reaping 'drop function f1'...
+reap;
+--echo # --> connection con2
+connection con2;
+--echo # Reaping 'select f1()'
+--error ER_SP_DOES_NOT_EXIST
+reap;
+--echo # --> connection default
+connection default;
+
+--echo #
+--echo # Test CREATE FUNCTION.
+--echo #
+create function f1() returns int return 1;
+begin;
+select f1();
+--echo # --> connection con1
+connection con1;
+--echo # Sending 'create function f1'...
+send create function f1() returns int return 2;
+--echo # --> connection con2
+connection con2;
+--echo # Waitng for 'create function f1' to get blocked on MDL lock...
+let $wait_condition=select count(*)=1 from information_schema.processlist
+where state='Waiting for table' and info='create function f1() returns int return 2';
+--source include/wait_condition.inc
+--echo # Demonstrate that there is a pending exclusive lock.
+--echo # Sending 'select f1()'...
+send select f1();
+--echo # --> connection con3
+connection con3;
+--echo # Waitng for 'select f1()' to get blocked by a pending MDL lock...
+let $wait_condition=select count(*)=1 from information_schema.processlist
+where state='Waiting for table' and info='select f1()';
+--echo # --> connection default
+connection default;
+commit;
+--echo # --> connection con1
+connection con1;
+--echo # Reaping 'create function f1'...
+--error ER_SP_ALREADY_EXISTS
+reap;
+--echo # --> connection con2
+connection con2;
+--echo # Reaping 'select f1()'
+reap;
+--echo # --> connection default
+connection default;
+
+--echo #
+--echo # Test ALTER FUNCTION.
+--echo #
+begin;
+select f1();
+--echo # --> connection con1
+connection con1;
+--echo # Sending 'alter function f1'...
+send alter function f1 contains sql;
+--echo # --> connection con2
+connection con2;
+--echo # Waitng for 'alter function f1' to get blocked on MDL lock...
+let $wait_condition=select count(*)=1 from information_schema.processlist
+where state='Waiting for table' and info='alter function f1 contains sql';
+--source include/wait_condition.inc
+--echo # Demonstrate that there is a pending exclusive lock.
+--echo # Sending 'select f1()'...
+send select f1();
+--echo # --> connection con3
+connection con3;
+--echo # Waitng for 'select f1()' to get blocked by a pending MDL lock...
+let $wait_condition=select count(*)=1 from information_schema.processlist
+where state='Waiting for table' and info='select f1()';
+--echo # --> connection default
+connection default;
+commit;
+--echo # --> connection con1
+connection con1;
+--echo # Reaping 'alter function f1'...
+reap;
+--echo # --> connection con2
+connection con2;
+--echo # Reaping 'select f1()'
+reap;
+--echo # --> connection default
+connection default;
+drop function f1;
+drop procedure p1;
+
+--echo #
+--echo # 4) MDL lock should not be taken for
+--echo # unrolled CALL statements.
+--echo # The primary goal of metadata locks is a consistent binary log.
+--echo # When a call statement is unrolled, it doesn't get to the
+--echo # binary log, instead the statements that are contained
+--echo # in the procedure body do. This can nest to any level.
+--echo #
+create procedure p1() begin end;
+create procedure p2() begin end;
+create table t1 (a int);
+delimiter |;
+create procedure p3()
+begin
+ call p1();
+ call p1();
+ call p2();
+end|
+create procedure p4()
+begin
+ call p1();
+ call p1();
+ call p2();
+ call p2();
+ call p3();
+end|
+delimiter ;|
+begin;
+select * from t1;
+savepoint sv;
+call p4();
+--echo # Prepared statement should not add any locks either.
+prepare stmt from "call p4()";
+execute stmt;
+execute stmt;
+--echo # --> connection con1
+connection con1;
+drop procedure p1;
+drop procedure p2;
+drop procedure p3;
+drop procedure p4;
+--echo # --> connection default
+connection default;
+--echo # This is to verify there was no implicit commit.
+rollback to savepoint sv;
+--error ER_SP_DOES_NOT_EXIST
+call p4();
+commit;
+drop table t1;
+
+--echo #
+--echo # 5) Locks should be taken on routines
+--echo # used indirectly by views or triggers.
+--echo #
+--echo #
+--echo # A function is used from a trigger.
+--echo #
+create function f1() returns int return 1;
+create table t1 (a int);
+create table t2 (a int, b int);
+create trigger t1_ai after insert on t1 for each row
+ insert into t2 (a, b) values (new.a, f1());
+begin;
+insert into t1 (a) values (1);
+--echo # --> connection con1
+connection con1;
+--echo # Sending 'drop function f1'
+send drop function f1;
+--echo # --> connection con2
+connection con2;
+--echo # Waitng for 'drop function f1' to get blocked on MDL lock...
+let $wait_condition=select count(*)=1 from information_schema.processlist
+where state='Waiting for table' and info='drop function f1';
+--source include/wait_condition.inc
+--echo # --> connnection default
+connection default;
+commit;
+--echo # --> connection con1
+connection con1;
+--echo # Reaping 'drop function f1'...
+reap;
+--echo # --> connection default
+connection default;
+--echo #
+--echo # A function is used from a view.
+--echo #
+create function f1() returns int return 1;
+create view v1 as select f1() as a;
+begin;
+select * from v1;
+--echo # --> connection con1
+connection con1;
+--echo # Sending 'drop function f1'
+send drop function f1;
+--echo # --> connection con2
+connection con2;
+--echo # Waitng for 'drop function f1' to get blocked on MDL lock...
+let $wait_condition=select count(*)=1 from information_schema.processlist
+where state='Waiting for table' and info='drop function f1';
+--source include/wait_condition.inc
+--echo # --> connnection default
+connection default;
+commit;
+--echo # --> connection con1
+connection con1;
+--echo # Reaping 'drop function f1'...
+reap;
+--echo # --> connection default
+connection default;
+--echo #
+--echo # A procedure is used from a function.
+--echo #
+delimiter |;
+create function f1() returns int
+begin
+ declare v_out int;
+ call p1(v_out);
+ return v_out;
+end|
+delimiter ;|
+create procedure p1(out v_out int) set v_out=3;
+begin;
+select * from v1;
+--echo # --> connection con1
+connection con1;
+--echo # Sending 'drop procedure p1'
+send drop procedure p1;
+--echo # --> connection con2
+connection con2;
+--echo # Waitng for 'drop procedure p1' to get blocked on MDL lock...
+let $wait_condition=select count(*)=1 from information_schema.processlist
+where state='Waiting for table' and info='drop procedure p1';
+--source include/wait_condition.inc
+--echo # --> connnection default
+connection default;
+commit;
+--echo # --> connection con1
+connection con1;
+--echo # Reaping 'drop procedure p1'...
+reap;
+--echo # --> connection default
+connection default;
+
+--echo #
+--echo # Deep nesting: a function is used from a procedure used
+--echo # from a function used from a view used in a trigger.
+--echo #
+create function f2() returns int return 4;
+create procedure p1(out v_out int) set v_out=f2();
+drop trigger t1_ai;
+create trigger t1_ai after insert on t1 for each row
+ insert into t2 (a, b) values (new.a, (select max(a) from v1));
+begin;
+insert into t1 (a) values (3);
+--echo # --> connection con1
+connection con1;
+--echo # Sending 'drop function f2'
+send drop function f2;
+--echo # --> connection con2
+connection con2;
+--echo # Waitng for 'drop function f2' to get blocked on MDL lock...
+let $wait_condition=select count(*)=1 from information_schema.processlist
+where state='Waiting for table' and info='drop function f2';
+--source include/wait_condition.inc
+--echo # --> connnection default
+connection default;
+commit;
+--echo # --> connection con1
+connection con1;
+--echo # Reaping 'drop function f2'...
+reap;
+--echo # --> connection default
+connection default;
+
+drop view v1;
+drop function f1;
+drop procedure p1;
+drop table t1, t2;
+
+--echo #
+--echo # 6) Check that ER_LOCK_DEADLOCK is reported if
+--echo # acquisition of a shared lock fails during a transaction or
+--echo # we need to back off to flush the sp cache.
+--echo #
+--echo # Sic: now this situation does not require a back off since we
+--echo # flush the cache on the fly.
+--echo #
+create function f1() returns int return 7;
+create table t1 (a int);
+begin;
+select * from t1;
+# Used to have a back-off here, with optional ER_LOCK_DEADLOCK
+#--error ER_LOCK_DEADLOCK
+select f1();
+commit;
+drop table t1;
+drop function f1;
+
+--echo #
+--echo # 7) Demonstrate that under LOCK TABLES we accumulate locks
+--echo # on stored routines, and release metadata locks in
+--echo # ROLLBACK TO SAVEPOINT. That is done only for those stored
+--echo # routines that are not part of LOCK TABLES prelocking list.
+--echo # Those stored routines that are part of LOCK TABLES
+--echo # prelocking list are implicitly locked when entering
+--echo # LOCK TABLES, and ROLLBACK TO SAVEPOINT has no effect on
+--echo # them.
+--echo #
+create function f1() returns varchar(20) return "f1()";
+create function f2() returns varchar(20) return "f2()";
+create view v1 as select f1() as a;
+set @@session.autocommit=0;
+lock table v1 read;
+select * from v1;
+savepoint sv;
+select f2();
+--echo # --> connection con1
+connection con1;
+--echo # Sending 'drop function f1'...
+send drop function f1;
+--echo # --> connection con2
+connection con2;
+--echo # Waitng for 'drop function f1' to get blocked on MDL lock...
+let $wait_condition=select count(*)=1 from information_schema.processlist
+where state='Waiting for table' and info='drop function f1';
+--source include/wait_condition.inc
+--echo # Sending 'drop function f2'...
+send drop function f2;
+--echo # --> connection default
+connection default;
+--echo # Waitng for 'drop function f2' to get blocked on MDL lock...
+let $wait_condition=select count(*)=1 from information_schema.processlist
+where state='Waiting for table' and info='drop function f2';
+--source include/wait_condition.inc
+rollback to savepoint sv;
+--echo # --> connection con2
+connection con2;
+--echo # Reaping 'drop function f2'...
+reap;
+--echo # --> connection default
+connection default;
+unlock tables;
+--echo # --> connection con1
+connection con1;
+--echo # Reaping 'drop function f1'...
+reap;
+--echo # --> connection default
+connection default;
+--error ER_SP_DOES_NOT_EXIST
+drop function f1;
+--error ER_SP_DOES_NOT_EXIST
+drop function f2;
+drop view v1;
+set @@session.autocommit=default;
+
+--echo #
+--echo # 8) Check the situation when we're preparing or executing a
+--echo # prepared statement, and as part of that try to flush the
+--echo # session sp cache. However, one of the procedures that
+--echo # needs a flush is in use. Verify that there is no infinite
+--echo # reprepare loop and no crash.
+--echo #
+create function f1() returns int return 1;
+delimiter |;
+--echo #
+--echo # We just mention p1() in the body of f2() to make
+--echo # sure that p1() metadata is validated when validating
+--echo # 'select f2()'.
+--echo # Recursion is not allowed in stored functions, so
+--echo # an attempt to just invoke p1() from f2() which is in turn
+--echo # called from p1() would have given a run-time error.
+--echo #
+create function f2() returns int
+begin
+ if @var is null then
+ call p1();
+ end if;
+ return 1;
+end|
+create procedure p1()
+begin
+ select f1() into @var;
+ execute stmt;
+end|
+delimiter ;|
+--echo # --> connection con2
+connection con2;
+prepare stmt from "select f2()";
+--echo # --> connection default
+connection default;
+begin;
+select f1();
+--echo # --> connection con1
+connection con1;
+--echo # Sending 'alter function f1 ...'...
+send alter function f1 comment "comment";
+--echo # --> connection con2
+connection con2;
+--echo # Waitng for 'alter function f1 ...' to get blocked on MDL lock...
+let $wait_condition=select count(*)=1 from information_schema.processlist
+where state='Waiting for table' and info like 'alter function f1 comment%';
+--source include/wait_condition.inc
+--echo # Sending 'call p1()'...
+send call p1();
+connection default;
+--echo # Waitng for 'call p1()' to get blocked on MDL lock on f1...
+let $wait_condition=select count(*)=1 from information_schema.processlist
+where state='Waiting for table' and info='select f1() into @var';
+--source include/wait_condition.inc
+--echo # Let 'alter function f1 ...' go through...
+commit;
+--echo # --> connection con1
+connection con1;
+--echo # Reaping 'alter function f1 ...'
+reap;
+--echo # --> connection con2
+connection con2;
+--echo # Reaping 'call p1()'...
+reap;
+deallocate prepare stmt;
+--echo # --> connection default
+connection default;
+drop function f1;
+drop function f2;
+drop procedure p1;
+
+--echo #
+--echo # 9) Check the situation when a stored function is invoked
+--echo # from a stored procedure, and recursively invokes the
+--echo # stored procedure that is in use. But for the second
+--echo # invocation, a cache flush is requested. We can't
+--echo # flush the procedure that's in use, and are forced
+--echo # to use an old version. It is not a violation of
+--echo # consistency, since we unroll top-level calls.
+--echo # Just verify the code works.
+--echo #
+create function f1() returns int return 1;
+begin;
+select f1();
+--echo # --> connection con1
+connection con1;
+--echo # Sending 'alter function f1 ...'...
+send alter function f1 comment "comment";
+--echo # --> connection con2
+connection con2;
+--echo # Waitng for 'alter function f1 ...' to get blocked on MDL lock...
+let $wait_condition=select count(*)=1 from information_schema.processlist
+where state='Waiting for table' and info like 'alter function f1 comment%';
+--source include/wait_condition.inc
+delimiter |;
+--echo #
+--echo # We just mention p1() in the body of f2() to make
+--echo # sure that p1() is prelocked for f2().
+--echo # Recursion is not allowed in stored functions, so
+--echo # an attempt to just invoke p1() from f2() which is in turn
+--echo # called from p1() would have given a run-time error.
+--echo #
+create function f2() returns int
+begin
+ if @var is null then
+ call p1();
+ end if;
+ return 1;
+end|
+create procedure p1()
+begin
+ select f1() into @var;
+ select f2() into @var;
+end|
+delimiter ;|
+--echo # Sending 'call p1()'...
+send call p1();
+connection default;
+--echo # Waitng for 'call p1()' to get blocked on MDL lock on f1...
+let $wait_condition=select count(*)=1 from information_schema.processlist
+where state='Waiting for table' and info='select f1() into @var';
+--source include/wait_condition.inc
+--echo # Let 'alter function f1 ...' go through...
+commit;
+--echo # --> connection con1
+connection con1;
+--echo # Reaping 'alter function f1 ...'
+reap;
+--echo # --> connection con2
+connection con2;
+--echo # Reaping 'call p1()'...
+reap;
+--echo # --> connection default
+connection default;
+drop function f1;
+drop function f2;
+drop procedure p1;
+
+--echo #
+--echo # 10) A select from information_schema.routines now
+--echo # flushes the stored routines caches. Test that this
+--echo # does not remove from the cache a stored routine
+--echo # that is already prelocked.
+--echo #
+create function f1() returns int return get_lock("30977", 100000);
+create function f2() returns int return 2;
+delimiter |;
+create function f3() returns varchar(255)
+begin
+ declare res varchar(255);
+ declare c cursor for select routine_name from
+ information_schema.routines where routine_name='f1';
+ select f1() into @var;
+ open c;
+ fetch c into res;
+ close c;
+ select f2() into @var;
+ return res;
+end|
+delimiter ;|
+--echo # --> connection con1
+connection con1;
+select get_lock("30977", 0);
+--echo # --> connection default
+connection default;
+--echo # Sending 'select f3()'...
+send select f3();
+--echo # --> connection con1
+connection con1;
+--echo # Waitng for 'select f3()' to get blocked on the user level lock...
+let $wait_condition=select count(*)=1 from information_schema.processlist
+where state='User lock' and info='select f1() into @var';
+--source include/wait_condition.inc
+--echo # Do something to change the cache version.
+create function f4() returns int return 4;
+drop function f4;
+select release_lock("30977");
+--echo # --> connection default
+connection default;
+--echo # Reaping 'select f3()'...
+--echo # Routine 'f2()' should exist and get executed successfully.
+reap;
+select @var;
+drop function f1;
+drop function f2;
+drop function f3;
+
+
+--echo # 11) Check the situation when the connection is flushing the
+--echo # SP cache which contains a procedure that is being executed.
+--echo #
+--echo # Function f1() calls p1(). Procedure p1() has a DROP
+--echo # VIEW statement, which, we know, invalidates the routines cache.
+--echo # During cache flush p1() must not be flushed since it's in
+--echo # use.
+--echo #
+delimiter |;
+create function f1() returns int
+begin
+ call p1();
+ return 1;
+end|
+create procedure p1()
+begin
+ create view v1 as select 1;
+ drop view v1;
+ select f1() into @var;
+ set @exec_count=@exec_count+1;
+end|
+delimiter ;|
+set @exec_count=0;
+--error ER_SP_RECURSION_LIMIT
+call p1();
+select @exec_count;
+set @@session.max_sp_recursion_depth=5;
+set @exec_count=0;
+--error ER_COMMIT_NOT_ALLOWED_IN_SF_OR_TRG
+call p1();
+select @exec_count;
+drop procedure p1;
+drop function f1;
+set @@session.max_sp_recursion_depth=default;
+
+--echo # --> connection con1
+connection con1;
+disconnect con1;
+--source include/wait_until_disconnected.inc
+--echo # --> connection con2
+connection con2;
+disconnect con2;
+--source include/wait_until_disconnected.inc
+--echo # --> connection con3
+connection con3;
+disconnect con3;
+--source include/wait_until_disconnected.inc
+--echo # --> connection default
+connection default;
+--echo #
+--echo # End of 5.5 tests
+--echo #
diff --git a/mysql-test/t/sp.test b/mysql-test/t/sp.test
index 8ec551227eb..b4727ad3df7 100644
--- a/mysql-test/t/sp.test
+++ b/mysql-test/t/sp.test
@@ -1308,9 +1308,11 @@ select f3()|
select id, f3() from t1 as t11 order by id|
# Degenerate cases work too :)
select f0()|
+# But these should not (particularly views should be locked explicitly).
+--error ER_TABLE_NOT_LOCKED
select * from v0|
+--error ER_TABLE_NOT_LOCKED
select *, f0() from v0, (select 123) as d1|
-# But these should not !
--error ER_TABLE_NOT_LOCKED
select id, f3() from t1|
--error ER_TABLE_NOT_LOCKED
@@ -8516,3 +8518,84 @@ SELECT routine_comment FROM information_schema.routines WHERE routine_name = "p1
DROP PROCEDURE p1;
+
+--echo #
+--echo # Bug #47313 assert in check_key_in_view during CALL procedure
+--echo #
+
+--disable_warnings
+DROP TABLE IF EXISTS t1;
+DROP VIEW IF EXISTS t1, t2_unrelated;
+DROP PROCEDURE IF EXISTS p1;
+--enable_warnings
+
+CREATE PROCEDURE p1(IN x INT) INSERT INTO t1 VALUES (x);
+CREATE VIEW t1 AS SELECT 10 AS f1;
+
+--echo # t1 refers to the view
+--error ER_NON_INSERTABLE_TABLE
+CALL p1(1);
+
+CREATE TEMPORARY TABLE t1 (f1 INT);
+
+--echo # t1 still refers to the view since it was inlined
+--error ER_NON_INSERTABLE_TABLE
+CALL p1(2);
+
+DROP VIEW t1;
+
+--echo # t1 now refers to the temporary table
+CALL p1(3);
+
+--echo # Check which values were inserted into the temp table.
+SELECT * FROM t1;
+
+DROP TEMPORARY TABLE t1;
+DROP PROCEDURE p1;
+
+--echo # Now test what happens if the sp cache is invalidated.
+
+CREATE PROCEDURE p1(IN x INT) INSERT INTO t1 VALUES (x);
+CREATE VIEW t1 AS SELECT 10 AS f1;
+CREATE VIEW v2_unrelated AS SELECT 1 AS r1;
+
+--echo # Load the procedure into the sp cache
+--error ER_NON_INSERTABLE_TABLE
+CALL p1(4);
+
+CREATE TEMPORARY TABLE t1 (f1 int);
+
+ALTER VIEW v2_unrelated AS SELECT 2 AS r1;
+
+--echo # Alter view causes the sp cache to be invalidated.
+--echo # Now t1 refers to the temporary table, not the view.
+CALL p1(5);
+
+--echo # Check which values were inserted into the temp table.
+SELECT * FROM t1;
+
+DROP TEMPORARY TABLE t1;
+DROP VIEW t1, v2_unrelated;
+DROP PROCEDURE p1;
+
+CREATE PROCEDURE p1(IN x INT) INSERT INTO t1 VALUES (x);
+CREATE TEMPORARY TABLE t1 (f1 INT);
+
+--echo # t1 refers to the temporary table
+CALL p1(6);
+
+CREATE VIEW t1 AS SELECT 10 AS f1;
+
+--echo # Create view causes the sp cache to be invalidated.
+--echo # t1 still refers to the temporary table since it shadows the view.
+CALL p1(7);
+
+DROP VIEW t1;
+
+--echo # Check which values were inserted into the temp table.
+SELECT * FROM t1;
+
+DROP TEMPORARY TABLE t1;
+DROP PROCEDURE p1;
+
+
diff --git a/mysql-test/t/sp_notembedded.test b/mysql-test/t/sp_notembedded.test
index f593e184ad2..f7984952e33 100644
--- a/mysql-test/t/sp_notembedded.test
+++ b/mysql-test/t/sp_notembedded.test
@@ -322,7 +322,7 @@ set session low_priority_updates=on;
connection rl_wait;
let $wait_condition=
select count(*) = 1 from information_schema.processlist
- where state = "Locked" and
+ where state = "Table lock" and
info = "update t1 set value='updated' where value='old'";
--source include/wait_condition.inc
diff --git a/mysql-test/t/sp_sync.test b/mysql-test/t/sp_sync.test
index f9dae17b039..519a9211206 100644
--- a/mysql-test/t/sp_sync.test
+++ b/mysql-test/t/sp_sync.test
@@ -34,7 +34,7 @@ SET DEBUG_SYNC = 'multi_update_reopen_tables SIGNAL parked WAIT_FOR go';
connection con1;
let $wait_condition= SELECT 1 FROM information_schema.processlist WHERE ID = $ID AND
-state = "Locked";
+state = "Waiting for table";
--source include/wait_condition.inc
DROP TABLE t1, t2;
SET DEBUG_SYNC = 'now WAIT_FOR parked';
diff --git a/mysql-test/t/status.test b/mysql-test/t/status.test
index f951218f5c8..cca54f6c762 100644
--- a/mysql-test/t/status.test
+++ b/mysql-test/t/status.test
@@ -58,7 +58,7 @@ let $ID= `select connection_id()`;
connection con2;
--echo # Switched to connection: con2
# wait for the other query to start executing
-let $wait_condition= select 1 from INFORMATION_SCHEMA.PROCESSLIST where ID = $ID and STATE = "Locked";
+let $wait_condition= select 1 from INFORMATION_SCHEMA.PROCESSLIST where ID = $ID and STATE = "Table lock";
--source include/wait_condition.inc
unlock tables;
diff --git a/mysql-test/t/trigger.test b/mysql-test/t/trigger.test
index f3b9d6bb91e..7ff61bd96e1 100644
--- a/mysql-test/t/trigger.test
+++ b/mysql-test/t/trigger.test
@@ -2489,3 +2489,28 @@ DROP TRIGGER trg1;
DROP TRIGGER trg2;
DROP TABLE t1;
+
+--echo #
+--echo # Bug #46747 "Crash in MDL_ticket::upgrade_shared_lock_to_exclusive
+--echo # on TRIGGER + TEMP table".
+--echo #
+
+--disable_warnings
+drop trigger if exists t1_bi;
+drop temporary table if exists t1;
+drop table if exists t1;
+--enable_warnings
+
+create table t1 (i int);
+create trigger t1_bi before insert on t1 for each row set @a:=1;
+--echo # Create temporary table which shadows base table with trigger.
+create temporary table t1 (j int);
+--echo # Dropping of trigger should succeed.
+drop trigger t1_bi;
+select trigger_name from information_schema.triggers
+ where event_object_schema = 'test' and event_object_table = 't1';
+--echo # Clean-up.
+drop temporary table t1;
+drop table t1;
+
+--echo End of 6.0 tests.
diff --git a/mysql-test/t/trigger_notembedded.test b/mysql-test/t/trigger_notembedded.test
index 7a7e6c6bc85..8a570a7e87d 100644
--- a/mysql-test/t/trigger_notembedded.test
+++ b/mysql-test/t/trigger_notembedded.test
@@ -896,7 +896,7 @@ connection default;
--echo connection: default
let $wait_condition=
select count(*) = 1 from information_schema.processlist
- where state = "Flushing tables";
+ where state = "Waiting for table";
--source include/wait_condition.inc
create trigger t1_bi before insert on t1 for each row begin end;
unlock tables;
diff --git a/mysql-test/t/truncate.test b/mysql-test/t/truncate.test
index ba5364bd324..cdfa448f78a 100644
--- a/mysql-test/t/truncate.test
+++ b/mysql-test/t/truncate.test
@@ -2,7 +2,7 @@
# Test of truncate
#
--disable_warnings
-drop table if exists t1;
+drop table if exists t1, t2;
--enable_warnings
create table t1 (a integer, b integer,c1 CHAR(10));
@@ -69,3 +69,97 @@ drop table t1;
# End of 5.0 tests
+--echo #
+--echo # Bug#20667 - Truncate table fails for a write locked table
+--echo #
+CREATE TABLE t1 (c1 INT);
+LOCK TABLE t1 WRITE;
+INSERT INTO t1 VALUES (1);
+SELECT * FROM t1;
+TRUNCATE TABLE t1;
+SELECT * FROM t1;
+UNLOCK TABLES;
+#
+LOCK TABLE t1 READ;
+--error ER_TABLE_NOT_LOCKED_FOR_WRITE
+TRUNCATE TABLE t1;
+UNLOCK TABLES;
+#
+CREATE TABLE t2 (c1 INT);
+LOCK TABLE t2 WRITE;
+--error ER_TABLE_NOT_LOCKED
+TRUNCATE TABLE t1;
+UNLOCK TABLES;
+#
+CREATE VIEW v1 AS SELECT t1.c1 FROM t1,t2 WHERE t1.c1 = t2.c1;
+INSERT INTO t1 VALUES (1), (2), (3);
+INSERT INTO t2 VALUES (1), (3), (4);
+SELECT * FROM v1;
+--error ER_NO_SUCH_TABLE
+TRUNCATE v1;
+SELECT * FROM v1;
+#
+LOCK TABLE t1 WRITE;
+--error ER_TABLE_NOT_LOCKED
+SELECT * FROM v1;
+--error ER_NO_SUCH_TABLE
+TRUNCATE v1;
+--error ER_TABLE_NOT_LOCKED
+SELECT * FROM v1;
+UNLOCK TABLES;
+#
+LOCK TABLE t1 WRITE, t2 WRITE;
+--error ER_TABLE_NOT_LOCKED
+SELECT * FROM v1;
+--error ER_NO_SUCH_TABLE
+TRUNCATE v1;
+--error ER_TABLE_NOT_LOCKED
+SELECT * FROM v1;
+UNLOCK TABLES;
+#
+LOCK TABLE v1 WRITE;
+SELECT * FROM v1;
+--error ER_NO_SUCH_TABLE
+TRUNCATE v1;
+SELECT * FROM v1;
+UNLOCK TABLES;
+#
+LOCK TABLE t1 WRITE, t2 WRITE, v1 WRITE;
+SELECT * FROM v1;
+--error ER_NO_SUCH_TABLE
+TRUNCATE v1;
+SELECT * FROM v1;
+UNLOCK TABLES;
+#
+DROP VIEW v1;
+DROP TABLE t1, t2;
+#
+CREATE PROCEDURE p1() SET @a = 5;
+--error ER_NO_SUCH_TABLE
+TRUNCATE p1;
+SHOW CREATE PROCEDURE p1;
+DROP PROCEDURE p1;
+
+--echo #
+--echo # Bug#46452 Crash in MDL, HANDLER OPEN + TRUNCATE TABLE
+--echo #
+--disable_warnings
+DROP TABLE IF EXISTS t1;
+--enable_warnings
+
+CREATE TABLE t1 AS SELECT 1 AS f1;
+
+HANDLER t1 OPEN;
+--echo # Here comes the crash.
+TRUNCATE t1;
+
+--echo # Currently TRUNCATE, just like other DDL, implicitly closes
+--echo # open HANDLER table.
+--error ER_UNKNOWN_TABLE
+HANDLER t1 READ FIRST;
+
+# Cleanup
+DROP TABLE t1;
+
+--echo # End of 6.0 tests
+
diff --git a/mysql-test/t/truncate_coverage.test b/mysql-test/t/truncate_coverage.test
new file mode 100644
index 00000000000..b7c08b03c8b
--- /dev/null
+++ b/mysql-test/t/truncate_coverage.test
@@ -0,0 +1,164 @@
+#
+# Code coverage testing of TRUNCATE TABLE.
+#
+# Ingo Struewing, 2009-07-20
+#
+
+--source include/have_debug_sync.inc
+SET DEBUG_SYNC='RESET';
+
+--let $MYSQLD_DATADIR= `SELECT @@datadir`
+
+--disable_warnings
+DROP TABLE IF EXISTS t1;
+--enable_warnings
+
+--echo #
+--echo # Bug#20667 - Truncate table fails for a write locked table
+--echo #
+########
+# Attack wait_while_table_is_used(). Kill query while trying to
+# upgrade MDL.
+#
+CREATE TABLE t1 (c1 INT);
+INSERT INTO t1 VALUES (1);
+#
+# Acquire a shared metadata lock on table by opening HANDLER for it and wait.
+# TRUNCATE shall block on this metadata lock.
+# We can't use normal DML as such statements would also block LOCK TABLES.
+#
+--echo #
+--echo # connection con1
+--connect (con1, localhost, root,,)
+HANDLER t1 OPEN;
+#
+# Get connection id of default connection.
+# Lock the table and start TRUNCATE, which will block on MDL upgrade.
+#
+--echo #
+--echo # connection default
+--connection default
+let $ID= `SELECT @id := CONNECTION_ID()`;
+LOCK TABLE t1 WRITE;
+SET DEBUG_SYNC='mdl_upgrade_shared_lock_to_exclusive SIGNAL waiting';
+send TRUNCATE TABLE t1;
+#
+# Get the default connection ID into a variable in an invisible statement.
+# Kill the TRUNCATE query. This shall result in an error return
+# from wait_while_table_is_used().
+#
+--echo #
+--echo # connection con2
+--connect (con2, localhost, root,,)
+SET DEBUG_SYNC='now WAIT_FOR waiting';
+let $invisible_assignment_in_select = `SELECT @id := $ID`;
+KILL QUERY @id;
+--disconnect con2
+--echo #
+--echo # connection con1
+--connection con1
+--echo # Release shared metadata lock by closing HANDLER.
+HANDLER t1 CLOSE;
+--disconnect con1
+--echo #
+--echo # connection default
+--connection default
+--error ER_QUERY_INTERRUPTED
+reap;
+UNLOCK TABLES;
+DROP TABLE t1;
+SET DEBUG_SYNC='RESET';
+########
+# Attack reopen_tables(). Remove form file.
+#
+CREATE TABLE t1 (c1 INT);
+INSERT INTO t1 VALUES (1);
+#
+# Acquire a shared metadata lock on table by opening HANDLER for it and wait.
+# TRUNCATE shall block on this metadata lock.
+# We can't use normal DML as such statements would also block LOCK TABLES.
+#
+--echo #
+--echo # connection con1
+--connect (con1, localhost, root,,)
+HANDLER t1 OPEN;
+#
+# Lock the table and start TRUNCATE, which will block on MDL upgrade.
+#
+--echo #
+--echo # connection default
+--connection default
+LOCK TABLE t1 WRITE;
+SET DEBUG_SYNC='mdl_upgrade_shared_lock_to_exclusive SIGNAL waiting';
+send TRUNCATE TABLE t1;
+#
+# Remove datafile.
+# Commit to let TRUNCATE continue.
+#
+--echo #
+--echo # connection con2
+--connect (con2, localhost, root,,)
+SET DEBUG_SYNC='now WAIT_FOR waiting';
+--remove_file $MYSQLD_DATADIR/test/t1.frm
+--disconnect con2
+--echo #
+--echo # connection con1
+--connection con1
+HANDLER t1 CLOSE;
+--disconnect con1
+--echo #
+--echo # connection default
+--connection default
+--error ER_NO_SUCH_TABLE
+reap;
+UNLOCK TABLES;
+--error ER_BAD_TABLE_ERROR
+DROP TABLE t1;
+SET DEBUG_SYNC='RESET';
+########
+# Attack acquire_exclusive_locks(). Hold a global read lock.
+# Non-LOCK TABLE case.
+#
+CREATE TABLE t1 (c1 INT);
+INSERT INTO t1 VALUES (1);
+#
+# Start a transaction and execute a DML in it. Since 5.4.4 this leaves
+# a shared meta data lock (MDL) behind. TRUNCATE shall block on it.
+#
+--echo #
+--echo # connection con1
+--connect (con1, localhost, root,,)
+START TRANSACTION;
+INSERT INTO t1 VALUES (2);
+#
+# Get connection id of default connection.
+# Start TRUNCATE, which will block on acquire_exclusive_locks().
+#
+--echo #
+--echo # connection default
+--connection default
+let $ID= `SELECT @id := CONNECTION_ID()`;
+SET DEBUG_SYNC='mdl_acquire_lock_wait SIGNAL waiting';
+send TRUNCATE TABLE t1;
+#
+# Get the default connection ID into a variable in an invisible statement.
+# Kill the TRUNCATE query. This shall result in an error return
+# from wait_while_table_is_used().
+#
+--echo #
+--echo # connection con1
+--connection con1
+SET DEBUG_SYNC='now WAIT_FOR waiting';
+let $invisible_assignment_in_select = `SELECT @id := $ID`;
+KILL QUERY @id;
+COMMIT;
+--disconnect con1
+--echo #
+--echo # connection default
+--connection default
+--error ER_QUERY_INTERRUPTED
+reap;
+UNLOCK TABLES;
+DROP TABLE t1;
+SET DEBUG_SYNC='RESET';
+
diff --git a/mysql-test/t/variables.test b/mysql-test/t/variables.test
index d4b88fc6f9c..8b58b8f2e68 100644
--- a/mysql-test/t/variables.test
+++ b/mysql-test/t/variables.test
@@ -830,8 +830,8 @@ set global join_buffer_size =@my_join_buffer_size;
# Bug#28580 Repeatation of status variables
#
--replace_column 2 #
-show global variables where Variable_name='table_definition_cache' or
-Variable_name='table_lock_wait_timeout';
+show global variables where Variable_name='table_definition_cache';
+# Note: table_lock_wait_timeout no longer exists. See bug#45225.
###########################################################################
diff --git a/mysql-test/t/view.test b/mysql-test/t/view.test
index 4515f26bc52..8297013611f 100644
--- a/mysql-test/t/view.test
+++ b/mysql-test/t/view.test
@@ -1,3 +1,4 @@
+
--disable_warnings
drop table if exists t1,t2,t3,t4,t9,`t1a``b`,v1,v2,v3,v4,v5,v6;
drop view if exists t1,t2,`t1a``b`,v1,v2,v3,v4,v5,v6;
@@ -1016,10 +1017,8 @@ lock tables t1 read, v1 read;
select * from v1;
-- error ER_TABLE_NOT_LOCKED
select * from t2;
-drop view v1;
---error ER_TABLE_NOT_LOCKED_FOR_WRITE
-drop table t1, t2;
unlock tables;
+drop view v1;
drop table t1, t2;
#
@@ -3934,3 +3933,45 @@ create view v_9801 as
drop table t_9801;
+--echo #
+--echo # Bug #47335 assert in get_table_share
+--echo #
+
+--disable_warnings
+DROP TABLE IF EXISTS t1;
+DROP VIEW IF EXISTS v1;
+--enable_warnings
+
+CREATE TEMPORARY TABLE t1 (id INT);
+--error ER_NO_SUCH_TABLE
+ALTER VIEW t1 AS SELECT 1 AS f1;
+DROP TABLE t1;
+
+CREATE VIEW v1 AS SELECT 1 AS f1;
+CREATE TEMPORARY TABLE v1 (id INT);
+ALTER VIEW v1 AS SELECT 2 AS f1;
+DROP TABLE v1;
+SELECT * FROM v1;
+DROP VIEW v1;
+
+
+--echo #
+--echo # Bug #47635 assert in start_waiting_global_read_lock
+--echo # during CREATE VIEW
+--echo #
+
+--disable_warnings
+DROP TABLE IF EXISTS t1, t2;
+DROP VIEW IF EXISTS t2;
+--enable_warnings
+
+CREATE TABLE t1 (f1 integer);
+CREATE TEMPORARY TABLE IF NOT EXISTS t1 (f1 integer);
+CREATE TEMPORARY TABLE t2 (f1 integer);
+DROP TABLE t1;
+FLUSH TABLES WITH READ LOCK;
+--error ER_CANT_UPDATE_WITH_READLOCK
+CREATE VIEW t2 AS SELECT * FROM t1;
+
+UNLOCK TABLES;
+DROP TABLE t1, t2;
diff --git a/mysql-test/t/view_grant.test b/mysql-test/t/view_grant.test
index f01edb1e499..d94bcfc29ed 100644
--- a/mysql-test/t/view_grant.test
+++ b/mysql-test/t/view_grant.test
@@ -1047,9 +1047,9 @@ GRANT SELECT ON db26813.t1 TO u26813@localhost;
connect (u1,localhost,u26813,,db26813);
connection u1;
---error ER_SPECIFIC_ACCESS_DENIED_ERROR
+--error ER_TABLEACCESS_DENIED_ERROR
ALTER VIEW v1 AS SELECT f2 FROM t1;
---error ER_SPECIFIC_ACCESS_DENIED_ERROR
+--error ER_TABLEACCESS_DENIED_ERROR
ALTER VIEW v2 AS SELECT f2 FROM t1;
--error ER_SPECIFIC_ACCESS_DENIED_ERROR
ALTER VIEW v3 AS SELECT f2 FROM t1;
diff --git a/mysql-test/t/xa.test b/mysql-test/t/xa.test
index f84d822170f..0f705ae20c6 100644
--- a/mysql-test/t/xa.test
+++ b/mysql-test/t/xa.test
@@ -76,9 +76,10 @@ xa rollback 'testa','testb';
xa start 'zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz';
select * from t1;
-drop table t1;
disconnect con1;
+connection default;
+drop table t1;
#
# Bug#28323: Server crashed in xid cache operations