config root man

Current Path : /home/usr.opt/mysql57/mysql-test/t/

FreeBSD hs32.drive.ne.jp 9.1-RELEASE FreeBSD 9.1-RELEASE #1: Wed Jan 14 12:18:08 JST 2015 root@hs32.drive.ne.jp:/sys/amd64/compile/hs32 amd64
Upload File :
Current File : //home/usr.opt/mysql57/mysql-test/t/lock_multi.test

# This tests Bug#16986 Deadlock condition with MyISAM tables
# All tests are required to run with Myisam.
# Hence MTR starts mysqld with MyISAM as default

--source include/force_myisam_default.inc
--source include/have_myisam.inc

# Save the initial number of concurrent sessions
--source include/count_sessions.inc

--disable_warnings
drop table if exists t1,t2;
--enable_warnings

# 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);
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 = "Waiting for table level lock" and
        info = "update low_priority t1 set n = 4";
--source include/wait_condition.inc
send
select n from t1;
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 = "Waiting for table level lock" and
        info = "select n from t1";
--source include/wait_condition.inc
select release_lock("mysqltest_lock");
connection locker;
reap;
select release_lock("mysqltest_lock");
connection writer;
reap;
connection reader;
reap;
drop table t1;

connection locker;
create table t1(n int);
insert into t1 values (1);
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 = "Waiting for table level 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;
reap;
select release_lock("mysqltest_lock");
connection writer;
reap;
drop table t1;


--echo #
--echo # Test locking in multi-update statements.
--echo #

--echo # 
--echo # Multi-update should not be blocked by THR_LOCK locks acquired
--echo # on table which is not updated.
--echo # 
--enable_connect_log
connection locker;
create table t1 (a int, b int);
create table t2 (c int, d int);
insert into t1 values(1,1);
insert into t1 values(2,2);
insert into t2 values(1,2);
connection locker2;
select get_lock("mysqltest_lock", 100);
connection locker;
--echo # Sending:
--send select a from t1 where get_lock('mysqltest_lock', 100)
connection writer;
--echo # 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 a from t1 where get_lock('mysqltest_lock', 100)";
--source include/wait_condition.inc
update t1,t2 set c=a where b=d;
connection reader;
select c from t2;
connection locker2;
select release_lock("mysqltest_lock");
connection locker;
--echo # Reap select.
--reap
select release_lock("mysqltest_lock");

--echo #
--echo # Indeed it should be blocked by THR_LOCK locks on table
--echo # which is updated.
--echo #
connection locker2;
select get_lock("mysqltest_lock", 100);
connection locker;
--echo # Sending:
--send select c from t2 where get_lock('mysqltest_lock', 100)
connection writer;
--echo # 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 c from t2 where get_lock('mysqltest_lock', 100)";
--source include/wait_condition.inc
--echo # Sending:
--send update t1,t2 set c=a where b=d;
connection default;
--echo # Wait till multi-update is blocked on THR_LOCK lock
let $wait_condition=
  select count(*) = 1 from information_schema.processlist
  where state = "Waiting for table level lock" and
        info = "update t1,t2 set c=a where b=d";
connection locker2;
select release_lock("mysqltest_lock");
connection locker;
--echo # Reap select.
--reap
select release_lock("mysqltest_lock");
connection writer;
--echo # Reap multi-update.
--reap

--echo #
--echo # OTOH multi-update will be blocked by concurrent LOCK TABLES READ
--echo # on any table in the join. This is because multi-update acquires
--echo # SW metadata locks on all tables in the join which conflicts with
--echo # SRO metadata lock acquired by LOCK TABLES READ.
--echo #

connection locker;
lock table t1 read;
connection writer;
--echo # Sending:
--send update t1,t2 set c=a where b=d;
connection default;
--echo # Wait till multi-update is blocked on THR_LOCK lock
let $wait_condition=
  select count(*) = 1 from information_schema.processlist
  where state = "Waiting for table metadata lock" and
        info = "update t1,t2 set c=a where b=d";
connection locker;
unlock tables;
connection writer;
--echo # Reap multi-update.
--reap

connection locker;
lock table t2 read;
connection writer;
--echo # Sending:
--send update t1,t2 set c=a where b=d;
connection default;
--echo # Wait till multi-update is blocked on THR_LOCK lock
let $wait_condition=
  select count(*) = 1 from information_schema.processlist
  where state = "Waiting for table metadata lock" and
        info = "update t1,t2 set c=a where b=d";
connection locker;
unlock tables;
connection writer;
--echo # Reap multi-update.
--reap

--echo #
--echo # Still if multi-update is executed under LOCK TABLES
--echo # it will be compatible with LOCK TABLES READ on the
--echo # table from its join which is only read.
--echo #
--echo # Main difference here is that LOCK TABLES preannounces
--echo # locks which will be requested by multi-update.
--echo #
connection locker;
lock table t1 read;
connection writer;
lock tables t1 read, t2 write;
update t1,t2 set c=a where b=d;
unlock tables;
connection locker;
unlock tables;

connection default;
drop table t1;
drop table t2;
--disable_connect_log


#
# Test problem when using locks on many tables and dropping a table that
# is to-be-locked by another thread
#
#
connection locker;
create table t1 (a int);
create table t2 (a int);
lock table t1 write, t2 write;
connection reader;
send
insert t1 select * from t2;
connection locker;
let $wait_condition=
  select count(*) = 1 from information_schema.processlist
  where state = "Waiting for table metadata lock" 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;
connection locker;
drop table t1;

#
# Same test as above, but with the dropped table locked twice
#

connection locker;
create table t1 (a int);
create table t2 (a int);
lock table t1 write, t2 write, t1 as t1_2 write, t2 as t2_2 write;
connection reader;
send
insert t1 select * from t2;
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 = "Waiting for table metadata lock" 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;
connection locker;
drop table t1;


--echo End of 4.1 tests

#
# Bug#9998 MySQL client hangs on USE "database"
#
create table t1(a int);
lock tables t1 write;
connection reader;
show columns from t1;
connection locker;
unlock tables;
drop table t1;

#
# Bug#16986 Deadlock condition with MyISAM tables
#

# Need a matching user in mysql.user for multi-table select
--source include/add_anonymous_users.inc

connection locker;
USE mysql;
LOCK TABLES columns_priv WRITE, db WRITE, user WRITE;
FLUSH TABLES;
#
connection reader;
USE mysql;
# Note:  This must be a multi-table select, otherwise the deadlock will not occur
send
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 metadata lock" 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.
--replace_result "Table is already up to date" "OK"
OPTIMIZE TABLES columns_priv, db, user;
UNLOCK TABLES;
#
connection reader;
reap;
USE test;
#
connection locker;
use test;
#
connection default;
#
# Test if CREATE TABLE with LOCK TABLE deadlocks.
#
connection writer;
CREATE TABLE t1 (c1 int);
LOCK TABLE t1 WRITE;
#
# This waits until t1 is unlocked.
connection locker;
send
FLUSH TABLES WITH READ LOCK;
#
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 = "Waiting for global read lock" 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;
#
# This awakes now.
connection locker;
reap;
UNLOCK TABLES;
#
connection default;
DROP TABLE t1;
#
# Test if CREATE TABLE SELECT with LOCK TABLE deadlocks.
#
connection writer;
CREATE TABLE t1 (c1 int);
LOCK TABLE t1 WRITE;
#
# This waits until t1 is unlocked.
connection locker;
send
FLUSH TABLES WITH READ LOCK;
#
# This must not block.
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 = "Waiting for global read lock" and
        info = "FLUSH TABLES WITH READ LOCK";
--source include/wait_condition.inc
--error ER_TABLE_NOT_LOCKED
CREATE TABLE t2 AS SELECT * FROM t1;
UNLOCK TABLES;
#
# This awakes now.
connection locker;
reap;
UNLOCK TABLES;
#
connection default;
DROP TABLE t1;

--source include/delete_anonymous_users.inc

#
# Bug#19815 CREATE/RENAME/DROP DATABASE can deadlock on a global read lock
#
connect (con1,localhost,root,,);
connect (con2,localhost,root,,);
#
connection con1;
CREATE DATABASE mysqltest_1;
FLUSH TABLES WITH READ LOCK;
#
# With bug in place: acquire LOCK_mysql_create_table and
# wait in wait_if_global_read_lock().
connection con2;
send
DROP DATABASE mysqltest_1;
#
# With bug in place: try to acquire LOCK_mysql_create_table...
# When fixed: Reject dropping db because of the read lock.
connection con1;
# Wait a bit so that the session con2 is in state
# "Waiting for global read lock"
let $wait_condition=
  select count(*) = 1 from information_schema.processlist
  where state = "Waiting for global read lock"
  and info = "DROP DATABASE mysqltest_1";
--source include/wait_condition.inc
--error ER_CANT_UPDATE_WITH_READLOCK
DROP DATABASE mysqltest_1;
UNLOCK TABLES;
#
connection con2;
reap;
#
connection default;
disconnect con1;
disconnect con2;
# This must have been dropped by connection 2 already,
# which waited until the global read lock was released.
--error ER_DB_DROP_EXISTS
DROP DATABASE mysqltest_1;

#
# Bug#17264 MySQL Server freeze
#
connection locker;
# Disable warnings to allow test to run also without InnoDB
--disable_warnings
create table t1 (f1 int(12) unsigned not null auto_increment, primary key(f1)) engine=innodb;
--enable_warnings
lock tables t1 write;
connection writer;
send
alter table t1 auto_increment=0;
connection reader;
# Wait till connection writer is blocked
let $wait_condition=
  select count(*) = 1 from information_schema.processlist
  where state = "Waiting for table metadata lock" and
        info = "alter table t1 auto_increment=0";
--source include/wait_condition.inc
send
alter table t1 auto_increment=0;
connection locker;
# Wait till connection reader is blocked
let $wait_condition=
  select count(*) = 2 from information_schema.processlist
  where state = "Waiting for table metadata lock" and
        info = "alter table t1 auto_increment=0";
--source include/wait_condition.inc
unlock tables;
connection writer;
reap;
connection reader;
reap;
connection locker;
drop table t1;

#
# Bug#43230: SELECT ... FOR UPDATE can hang with FLUSH TABLES WITH READ LOCK indefinitely
#

connect (con1,localhost,root,,);
connect (con2,localhost,root,,);
connect (con3,localhost,root,,);
connect (con4,localhost,root,,);
connect (con5,localhost,root,,);

create table t1 (a int);
create table t2 like t1;

connection con1;
--echo # con1
lock tables t1 write;
connection con2;
--echo # con2
send flush tables with read lock;
connection con5;
--echo # con5
let $wait_condition=
  select count(*) = 1 from information_schema.processlist
  where state = "Waiting for global read lock" and
        info = "flush tables with read lock";
--source include/wait_condition.inc
--echo # global read lock is taken
connection con3;
--echo # con3
send select * from t2 for update;
connection con5;
let $wait_condition=
  select count(*) = 1 from information_schema.processlist
  where state = "Waiting for global read lock" and
        info = "select * from t2 for update";
--source include/wait_condition.inc
--echo # waiting for release of read lock
connection con4;
--echo # con4
--echo # would hang and later cause a deadlock
flush tables t2;
connection con1;
--echo # clean up
unlock tables;
connection con2;
--reap
unlock tables;
connection con3;
--reap
connection default;
disconnect con5;
disconnect con4;
disconnect con3;
disconnect con2;
disconnect con1;

drop table t1,t2;

--echo #
--echo # Lightweight version:
--echo # Ensure that the wait for a GRL is done before opening tables.
--echo #

connect (con1,localhost,root,,);
connect (con2,localhost,root,,);

create table t1 (a int);
create table t2 like t1;

--echo #
--echo # UPDATE
--echo #

connection default;
--echo # default
flush tables with read lock;
connection con1;
--echo # con1
send update t2 set a = 1;
connection default;
--echo # default
let $wait_condition=
  select count(*) = 1 from information_schema.processlist
  where state = "Waiting for global read lock" and
        info = "update t2 set a = 1";
--source include/wait_condition.inc
--echo # statement is waiting for release of read lock
connection con2;
--echo # con2
flush table t2;
connection default;
--echo # default
unlock tables;
connection con1;
--echo # con1
--reap

--echo #
--echo # LOCK TABLES .. WRITE
--echo #

connection default;
--echo # default
flush tables with read lock;
connection con1;
--echo # con1
send lock tables t2 write;
connection default;
--echo # default
let $wait_condition=
  select count(*) = 1 from information_schema.processlist
  where state = "Waiting for global read lock" and
        info = "lock tables t2 write";
--source include/wait_condition.inc
--echo # statement is waiting for release of read lock
connection con2;
--echo # con2
flush table t2;
connection default;
--echo # default
unlock tables;
connection con1;
--echo # con1
--reap
unlock tables;

connection default;
disconnect con2;
disconnect con1;

drop table t1,t2;


--echo End of 5.0 tests


#
# Bug#21281 Pending write lock is incorrectly removed when its
#           statement being KILLed
#
create table t1 (i int);
insert into t1 values (1);
select get_lock('mysqltest_lock', 100);
connection locker;
send select * from t1 where get_lock('mysqltest_lock', 100);
connection writer;
let $wait_condition=
  select count(*) = 1 from information_schema.processlist
  where state = "User lock" and
        info = "select * from t1 where get_lock('mysqltest_lock', 100)";
--source include/wait_condition.inc
send
update t1 set i= 10;
connection reader;
let $wait_condition=
  select count(*) = 1 from information_schema.processlist
  where state = "Waiting for table level 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 = "Waiting for table level lock" and
        info = "select * from t1";
--source include/wait_condition.inc
let $ID= `select id from information_schema.processlist
          where state = "Waiting for table level lock" and
                info = "update t1 set i= 10"`;
--replace_result $ID ID
eval kill query $ID;
connection reader;
--reap
connection writer;
--error ER_QUERY_INTERRUPTED
--reap
connection default;
select release_lock('mysqltest_lock');
connection locker;
--reap
select release_lock('mysqltest_lock');
connection default;
drop table t1;

#
# Bug#25856 HANDLER table OPEN in one connection lock DROP TABLE in another one
#
--disable_warnings
drop table if exists t1;
--enable_warnings
create table t1 (a int) ENGINE=MEMORY;
--echo --> client 2
connection locker;
--error ER_ILLEGAL_HA
handler t1 open;
--echo --> client 1
connection default;
drop table t1;


# Disconnect sessions used in many subtests above
disconnect locker;
disconnect locker2;
disconnect reader;
disconnect writer;


#
# Bug#32395 Alter table under a impending global read lock causes a server crash
#

#
# Test ALTER TABLE under LOCK TABLES and FLUSH TABLES WITH READ LOCK
#

--disable_warnings
drop table if exists t1;
--enable_warnings
create table t1 (i int);
connect (flush,localhost,root,,test,,);
connection default;
--echo connection: default
lock tables t1 write;
connection flush;
--echo connection: flush
--send flush tables with read lock;
connection default;
--echo connection: default
let $wait_condition=
  select count(*) = 1 from information_schema.processlist
  where state = "Waiting for global read lock" and
        info = "flush tables with read lock";
--source include/wait_condition.inc
alter table t1 add column j int;
connect (insert,localhost,root,,test,,);
connection insert;
--echo connection: insert
let $wait_condition=
  select count(*) = 1 from information_schema.processlist
  where state = "Waiting for global read lock" and
        info = "flush tables with read lock";
--source include/wait_condition.inc
--send insert into t1 values (1,2);
--echo connection: default
connection default;
let $wait_condition=
  select count(*) = 1 from information_schema.processlist
  where state = "Waiting for global read lock" and
        info = "insert into t1 values (1,2)";
--source include/wait_condition.inc
unlock tables;
connection flush;
--echo connection: flush
--reap
let $wait_condition=
  select count(*) = 1 from information_schema.processlist
  where state = "Waiting for global read lock" and
        info = "insert into t1 values (1,2)";
--source include/wait_condition.inc
select * from t1;
unlock tables;
connection insert;
--reap
connection default;
let $wait_condition=
  select count(*) = 1 from t1;
--source include/wait_condition.inc
select * from t1;
drop table t1;
disconnect flush;
disconnect insert;

#
# Test that FLUSH TABLES under LOCK TABLES protects write locked tables
# from a impending FLUSH TABLES WITH READ LOCK
#

--disable_warnings
drop table if exists t1;
--enable_warnings
create table t1 (i int);
connect (flush,localhost,root,,test,,);
connection default;
--echo connection: default
lock tables t1 write;
connection flush;
--echo connection: flush
--send flush tables with read lock;
connection default;
--echo connection: default
let $wait_condition=
  select count(*) = 1 from information_schema.processlist
  where state = "Waiting for global read lock";
--source include/wait_condition.inc
flush tables;
let $wait_condition=
  select count(*) = 1 from information_schema.processlist
  where state = "Waiting for global read lock";
--source include/wait_condition.inc
unlock tables;
connection flush;
--reap
connection default;
disconnect flush;
drop table t1;

#
# Bug#30331 Table_locks_waited shows inaccurate values
#

--disable_warnings
drop table if exists t1,t2;
--enable_warnings
create table t1 (a int);
insert into t1 values (1);
connect (blocker,localhost,root,,);
connection blocker;
select get_lock('mysqltest_lock', 100);
connection default;
flush status;
send select * from t1 where get_lock('mysqltest_lock', 100);
connect (waiter,localhost,root,,);
connection waiter;
let $wait_condition=
  select count(*) = 1 from information_schema.processlist
  where state = "User lock" and
        info = "select * from t1 where get_lock('mysqltest_lock', 100)";
--source include/wait_condition.inc

let $tlwa= `show status like 'Table_locks_waited'`;
send update t1 set a= 2;
connection blocker;
let $wait_condition=
  select count(*) = 1 from information_schema.processlist
  where state = "Waiting for table level lock" and
        info = "update t1 set a= 2";
--source include/wait_condition.inc
let $tlwb= `show status like 'Table_locks_waited'`;
select release_lock('mysqltest_lock');
connection waiter;
--reap
connection default;
--reap
select release_lock('mysqltest_lock');
drop table t1;
disconnect blocker;
disconnect waiter;
--disable_query_log
eval SET @tlwa= SUBSTRING_INDEX('$tlwa', '	', -1);
eval SET @tlwb= SUBSTRING_INDEX('$tlwb', '	', -1);
--enable_query_log
select @tlwa < @tlwb;

--echo End of 5.1 tests

#
# Test that DROP TABLES does not wait for a impending FLUSH TABLES
# WITH READ LOCK
#

--disable_warnings
drop table if exists t1;
--enable_warnings
create table t1 (i int);
connect (flush,localhost,root,,test,,);
connection default;
--echo connection: default
lock tables t1 write;
connection flush;
--echo connection: flush
--send flush tables with read lock;
connection default;
--echo connection: default
let $wait_condition=
  select count(*) = 1 from information_schema.processlist
  where state = "Waiting for global read lock";
--source include/wait_condition.inc
flush tables;
let $wait_condition=
  select count(*) = 1 from information_schema.processlist
  where state = "Waiting for global read lock";
--source include/wait_condition.inc
drop table t1;
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 metadata lock" 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 ;

--echo # Connection 2
connect (con2,localhost,root);
LOCK TABLES v1 WRITE, t1 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

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 metadata lock" 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 metadata lock" 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 = "Waiting for table flush" 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 metadata lock" 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 metadata lock" 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;


--echo # 
--echo # Test for the bug where upgradable metadata locks was acquired
--echo # even if the table to altered was temporary.
--echo # Bug found while working on the related bug #51240.
--echo #

--disable_warnings
DROP TABLE IF EXISTS t1;
--enable_warnings

CREATE TABLE t1 (id INT);
LOCK TABLE t1 WRITE;

--echo # Connection con1
connect (con1, localhost, root);
CREATE TEMPORARY TABLE t1 (id INT);
# This alter should not block and timeout.
ALTER TABLE t1 ADD COLUMN j INT;

--echo # Connection default
connection default;
disconnect con1;
UNLOCK TABLES;
DROP TABLE t1;


--echo #
--echo # Test coverage for LOCK TABLES ... READ/WRITE
--echo #
--echo # Of course this functionality is well-covered by tests all
--echo # around the test suite. Still it is nice to have formal
--echo # coverage for LOCK TABLES in one place.
--echo # 

--enable_connect_log
--echo # We are going to check behavior for both InnoDB and MyISAM
--echo # tables.
CREATE TABLE t1 (i INT) ENGINE=MyISAM;
CREATE TABLE t2 (i INT) ENGINE=InnoDB;
INSERT INTO t1 VALUES (1);
INSERT INTO t2 VALUES (1);
CREATE VIEW v1 AS SELECT * FROM t1;
CREATE VIEW v2 AS SELECT * FROM t2;
CREATE TABLE t3 (j INT);
CREATE TABLE t4 (j INT);
CREATE VIEW v3 AS SELECT * FROM t3 WHERE (SELECT COUNT(*) FROM t1);
CREATE VIEW v4 AS SELECT * FROM t4 WHERE (SELECT COUNT(*) FROM t2);
CREATE TABLE t5 (k INT);
CREATE TABLE t6 (k INT);
CREATE TRIGGER bi_t5 BEFORE INSERT ON t5 FOR EACH ROW SET @a:= (SELECT COUNT(*) FROM t1);
CREATE TRIGGER bi_t6 BEFORE INSERT ON t6 FOR EACH ROW SET @a:= (SELECT COUNT(*) FROM t2);
CREATE TABLE t7 (z INT);
CREATE TABLE t8 (z INT);
CREATE TRIGGER bi_t7 BEFORE INSERT ON t7 FOR EACH ROW INSERT INTO t1 VALUES (1);
CREATE TRIGGER bi_t8 BEFORE INSERT ON t8 FOR EACH ROW INSERT INTO t2 VALUES (1);

--echo #
--echo # 1) LOCK TABLES READ explicitly locking table
--echo #
--echo # 1.a) Allows concurrent reads
LOCK TABLE t1 READ, t2 READ;
connect (con1, localhost, root);
SELECT * FROM t1;
SELECT * FROM t2;
connection default;
UNLOCK TABLES;

--echo #
--echo # 1.b) Is allowed concurrently to reads
SELECT GET_LOCK('mysqltest_lock', 100);

connection con1;
--echo # Start read by sending SELECT:
--send SELECT GET_LOCK('mysqltest_lock', 100) FROM t1, t2;

connect (con2, localhost, root);
--echo # Wait until SELECT gets read lock and starts waiting for user lock
let $wait_condition=
  select count(*) = 1 from information_schema.processlist
  where state = "User lock" and
        info = "SELECT GET_LOCK('mysqltest_lock', 100) FROM t1, t2";
--source include/wait_condition.inc
--echo # LOCK TABLES should not be blocked.
LOCK TABLES t1 READ, t2 READ;
UNLOCK TABLES;

connection default;
--echo # Unblock SELECT.
SELECT RELEASE_LOCK('mysqltest_lock');

connection con1;
--echo # Reaping SELECT
--reap
SELECT RELEASE_LOCK('mysqltest_lock');

--echo #
--echo # 1.c) Blocks concurrent modifications to table
connection default;

LOCK TABLE t1 READ, t2 READ;

connection con1;
--echo # Sending:
--send INSERT INTO t1 VALUES (1)

connection default;
--echo # Wait until INSERT gets blocked
let $wait_condition=
  select count(*) = 1 from information_schema.processlist
  where state = "Waiting for table metadata lock" and
        info = "INSERT INTO t1 VALUES (1)";
--source include/wait_condition.inc

connection con2;
--echo # Sending:
--send INSERT INTO t2 VALUES (1)

connection default;
--echo # Wait until INSERT gets blocked
let $wait_condition=
  select count(*) = 1 from information_schema.processlist
  where state = "Waiting for table metadata lock" and
        info = "INSERT INTO t2 VALUES (1)";
--source include/wait_condition.inc

--echo # Unblock INSERTs
UNLOCK TABLES;

connection con1;
--echo # Reap INSERT
--reap

connection con2;
--echo # Reap INSERT
--reap

connection default;
--echo # Revert effects from INSERTs
DELETE FROM t1 LIMIT 1;
DELETE FROM t2 LIMIT 1;

--echo #
--echo # 1.d) Is blocked by concurrent table modifications
SELECT GET_LOCK('mysqltest_lock', 100);

connection con1;
--echo # Sending:
--send INSERT INTO t1 VALUES (GET_LOCK('mysqltest_lock', 100));

connection con2;
--echo # Wait until INSERT gets SW MDL lock and starts waiting for user lock
let $wait_condition=
  select count(*) = 1 from information_schema.processlist
  where state = "User lock" and
        info = "INSERT INTO t1 VALUES (GET_LOCK('mysqltest_lock', 100))";
--source include/wait_condition.inc

--echo # Sending:
--send LOCK TABLES t1 READ;

connection default;
--echo # Wait until LOCK TABLES READ is blocked due to INSERT
let $wait_condition=
  select count(*) = 1 from information_schema.processlist
  where state = "Waiting for table metadata lock" and
        info = "LOCK TABLES t1 READ";
--source include/wait_condition.inc

--echo # Unblock INSERT.
SELECT RELEASE_LOCK('mysqltest_lock');

connection con1;
--echo # Reaping INSERT
--reap
SELECT RELEASE_LOCK('mysqltest_lock');

connection con2;
--echo # Reaping LOCK TABLES READ
--reap
UNLOCK TABLES;

connection default;

SELECT GET_LOCK('mysqltest_lock', 100);

--echo # 
--echo # The below part of test also covers scenario in which bug #42147
--echo # "Concurrent DML and LOCK TABLE ... READ for InnoDB table cause
--echo # warnings in errlog" occurred.
--echo #
connection con1;
--echo # Sending:
--send INSERT INTO t2 VALUES (GET_LOCK('mysqltest_lock', 100));

connection con2;
--echo # Wait until INSERT gets SW MDL lock and starts waiting for user lock
let $wait_condition=
  select count(*) = 1 from information_schema.processlist
  where state = "User lock" and
        info = "INSERT INTO t2 VALUES (GET_LOCK('mysqltest_lock', 100))";
--source include/wait_condition.inc

--echo # Sending:
--send LOCK TABLES t2 READ;

connection default;
--echo # Wait until LOCK TABLES READ is blocked due to INSERT
let $wait_condition=
  select count(*) = 1 from information_schema.processlist
  where state = "Waiting for table metadata lock" and
        info = "LOCK TABLES t2 READ";
--source include/wait_condition.inc

--echo # Unblock INSERT.
SELECT RELEASE_LOCK('mysqltest_lock');

connection con1;
--echo # Reaping INSERT
--reap
SELECT RELEASE_LOCK('mysqltest_lock');

connection con2;
--echo # Reaping LOCK TABLES READ
--reap
UNLOCK TABLES;

connection default;
--echo # Revert effects from INSERTs
DELETE FROM t1 LIMIT 1;
DELETE FROM t2 LIMIT 1;

--echo #
--echo # 1.e) LOCK TABLES READ which explicitly locks table is not blocked
--echo #      by concurrent transactions which read table.
BEGIN;
SELECT * FROM t1;

connection con1;
LOCK TABLES t1 READ;
UNLOCK TABLES;

connection default;
COMMIT;

BEGIN;
SELECT * FROM t2;

connection con1;
LOCK TABLES t2 READ;
UNLOCK TABLES;

connection default;
COMMIT;

--echo #
--echo # 1.f) LOCK TABLES READ which explicitly locks table is blocked
--echo #      by concurrent transactions which modify table.
BEGIN;
INSERT INTO t1 VALUES (1);

connection con1;
--echo # Sending:
--send LOCK TABLES t1 READ;

connection default;
--echo # Wait until LOCK TABLES READ is blocked due concurrent transaction
let $wait_condition=
  select count(*) = 1 from information_schema.processlist
  where state = "Waiting for table metadata lock" and
        info = "LOCK TABLES t1 READ";
--source include/wait_condition.inc
--echo # Unblock LOCK TABLES READ
COMMIT;

connection con1;
--echo # Reap LOCK TABLES READ
--reap
UNLOCK TABLES;

connection default;
BEGIN;
INSERT INTO t2 VALUES (1);

connection con1;
--echo # Sending:
--send LOCK TABLES t2 READ;

connection default;
--echo # Wait until LOCK TABLES READ is blocked due concurrent transaction
let $wait_condition=
  select count(*) = 1 from information_schema.processlist
  where state = "Waiting for table metadata lock" and
        info = "LOCK TABLES t2 READ";
--source include/wait_condition.inc
--echo # Unblock LOCK TABLES READ
COMMIT;

connection con1;
--echo # Reap LOCK TABLES READ
--reap
UNLOCK TABLES;

connection default;
--echo # Revert effects from INSERTs
DELETE FROM t1 LIMIT 1;
DELETE FROM t2 LIMIT 1;

--echo #
--echo # 1.g) LOCK TABLES READ which explicitly locks table is compatible
--echo #      with itself.
LOCK TABLES t1 READ, t2 READ;

connection con1;
LOCK TABLES t1 READ, t2 READ;
UNLOCK TABLES;

connection default;
UNLOCK TABLES;

--echo #
--echo # 1.h) LOCK TABLES READ which explicitly locks table is not compatible
--echo #      with LOCK TABLE WRITE.
LOCK TABLES t1 READ;

connection con1;
--echo # Sending:
--send LOCK TABLES t1 WRITE;

connection default;
--echo # Wait until LOCK TABLES WRITE is blocked
let $wait_condition=
  select count(*) = 1 from information_schema.processlist
  where state = "Waiting for table metadata lock" and
        info = "LOCK TABLES t1 WRITE";
--source include/wait_condition.inc
--echo # Unblock LOCK TABLES WRITE
UNLOCK TABLES;

connection con1;
--echo # Reap LOCK TABLES WRITE
--reap
UNLOCK TABLES;

connection default;
LOCK TABLES t2 READ;

connection con1;
--echo # Sending:
--send LOCK TABLES t2 WRITE;

connection default;
--echo # Wait until LOCK TABLES WRITE is blocked
let $wait_condition=
  select count(*) = 1 from information_schema.processlist
  where state = "Waiting for table metadata lock" and
        info = "LOCK TABLES t2 WRITE";
--source include/wait_condition.inc
--echo # Unblock LOCK TABLES WRITE
UNLOCK TABLES;

connection con1;
--echo # Reap LOCK TABLES WRITE
--reap
UNLOCK TABLES;

connection default;
LOCK TABLES t1 WRITE;

connection con1;
--echo # Sending:
--send LOCK TABLES t1 READ;

connection default;
--echo # Wait until LOCK TABLES READ is blocked
let $wait_condition=
  select count(*) = 1 from information_schema.processlist
  where state = "Waiting for table metadata lock" and
        info = "LOCK TABLES t1 READ";
--source include/wait_condition.inc
--echo # Unblock LOCK TABLES READ
UNLOCK TABLES;

connection con1;
--echo # Reap LOCK TABLES READ
--reap
UNLOCK TABLES;

connection default;
LOCK TABLES t2 WRITE;

connection con1;
--echo # Sending:
--send LOCK TABLES t2 READ;

connection default;
--echo # Wait until LOCK TABLES READ is blocked
let $wait_condition=
  select count(*) = 1 from information_schema.processlist
  where state = "Waiting for table metadata lock" and
        info = "LOCK TABLES t2 READ";
--source include/wait_condition.inc
--echo # Unblock LOCK TABLES READ
UNLOCK TABLES;

connection con1;
--echo # Reap LOCK TABLES READ
--reap
UNLOCK TABLES;


--echo #
--echo # 2) LOCK TABLES WRITE explicitly locking table
--echo #
--echo # 2.a) Doesn't allow concurrent reads
connection default;
LOCK TABLE t1 WRITE;

connection con1;
--echo # Sending:
--send SELECT * FROM t1;

connection default;
--echo # Wait until SELECT gets blocked 
let $wait_condition=
  select count(*) = 1 from information_schema.processlist
  where state = "Waiting for table metadata lock" and
        info = "SELECT * FROM t1";
--source include/wait_condition.inc
--echo # Unblock SELECT
UNLOCK TABLES;

connection con1;
--echo # Reaping SELECT
--reap

connection default;
LOCK TABLE t2 WRITE;

connection con1;
--echo # Sending:
--send SELECT * FROM t2;

connection default;
--echo # Wait until SELECT gets blocked 
let $wait_condition=
  select count(*) = 1 from information_schema.processlist
  where state = "Waiting for table metadata lock" and
        info = "SELECT * FROM t2";
--source include/wait_condition.inc
--echo # Unblock SELECT
UNLOCK TABLES;

connection con1;
--echo # Reaping SELECT
--reap

connection default;
--echo #
--echo # 2.b) Is not allowed concurrently to reads
SELECT GET_LOCK('mysqltest_lock', 100);

connection con1;
--echo # Start read by sending SELECT:
--send SELECT GET_LOCK('mysqltest_lock', 100) FROM t1;

connection con2;
--echo # Wait until SELECT gets read lock and starts waiting for user lock
let $wait_condition=
  select count(*) = 1 from information_schema.processlist
  where state = "User lock" and
        info = "SELECT GET_LOCK('mysqltest_lock', 100) FROM t1";
--source include/wait_condition.inc
--echo # Sending:
--send LOCK TABLES t1 WRITE;

connection default;
let $wait_condition=
  select count(*) = 1 from information_schema.processlist
  where state = "Waiting for table metadata lock" and
        info = "LOCK TABLES t1 WRITE";
--source include/wait_condition.inc
UNLOCK TABLES;

--echo # Unblock SELECT.
SELECT RELEASE_LOCK('mysqltest_lock');

connection con1;
--echo # Reaping SELECT
--reap
SELECT RELEASE_LOCK('mysqltest_lock');

connection con2;
--echo # Reaping LOCK TABLE WRITE
--reap
UNLOCK TABLES;

connection default;
SELECT GET_LOCK('mysqltest_lock', 100);

connection con1;
--echo # Start read by sending SELECT:
--send SELECT GET_LOCK('mysqltest_lock', 100) FROM t2;

connection con2;
--echo # Wait until SELECT gets read lock and starts waiting for user lock
let $wait_condition=
  select count(*) = 1 from information_schema.processlist
  where state = "User lock" and
        info = "SELECT GET_LOCK('mysqltest_lock', 100) FROM t2";
--source include/wait_condition.inc
--echo # Sending:
--send LOCK TABLES t2 WRITE;

connection default;
let $wait_condition=
  select count(*) = 1 from information_schema.processlist
  where state = "Waiting for table metadata lock" and
        info = "LOCK TABLES t2 WRITE";
--source include/wait_condition.inc
UNLOCK TABLES;

--echo # Unblock SELECT.
SELECT RELEASE_LOCK('mysqltest_lock');

connection con1;
--echo # Reaping SELECT
--reap
SELECT RELEASE_LOCK('mysqltest_lock');

connection con2;
--echo # Reaping LOCK TABLE WRITE
--reap
UNLOCK TABLES;


--echo #
--echo # 2.c) Blocks concurrent modifications to table
connection default;
LOCK TABLE t1 WRITE, t2 WRITE;

connection con1;
--echo # Sending:
--send INSERT INTO t1 VALUES (1)

connection default;
--echo # Wait until INSERT gets blocked
let $wait_condition=
  select count(*) = 1 from information_schema.processlist
  where state = "Waiting for table metadata lock" and
        info = "INSERT INTO t1 VALUES (1)";
--source include/wait_condition.inc

connection con2;
--echo # Sending:
--send INSERT INTO t2 VALUES (1)

connection default;
--echo # Wait until INSERT gets blocked
let $wait_condition=
  select count(*) = 1 from information_schema.processlist
  where state = "Waiting for table metadata lock" and
        info = "INSERT INTO t2 VALUES (1)";
--source include/wait_condition.inc

--echo # Unblock INSERTs
UNLOCK TABLES;

connection con1;
--echo # Reap INSERT
--reap

connection con2;
--echo # Reap INSERT
--reap

connection default;
--echo # Revert effects from INSERTs
DELETE FROM t1 LIMIT 1;
DELETE FROM t2 LIMIT 1;

--echo #
--echo # 2.d) Is blocked by concurrent table modifications
SELECT GET_LOCK('mysqltest_lock', 100);

connection con1;
--echo # Sending:
--send INSERT INTO t1 VALUES (GET_LOCK('mysqltest_lock', 100));

connection con2;
--echo # Wait until INSERT gets SW MDL lock and starts waiting for user lock
let $wait_condition=
  select count(*) = 1 from information_schema.processlist
  where state = "User lock" and
        info = "INSERT INTO t1 VALUES (GET_LOCK('mysqltest_lock', 100))";
--source include/wait_condition.inc

--echo # Sending:
--send LOCK TABLES t1 WRITE;

connection default;
--echo # Wait until LOCK TABLES WRITE is blocked due to INSERT
let $wait_condition=
  select count(*) = 1 from information_schema.processlist
  where state = "Waiting for table metadata lock" and
        info = "LOCK TABLES t1 WRITE";
--source include/wait_condition.inc

--echo # Unblock INSERT.
SELECT RELEASE_LOCK('mysqltest_lock');

connection con1;
--echo # Reaping INSERT
--reap
SELECT RELEASE_LOCK('mysqltest_lock');

connection con2;
--echo # Reaping LOCK TABLES WRITE
--reap
UNLOCK TABLES;

connection default;

SELECT GET_LOCK('mysqltest_lock', 100);

connection con1;
--echo # Sending:
--send INSERT INTO t2 VALUES (GET_LOCK('mysqltest_lock', 100));

connection con2;
--echo # Wait until INSERT gets SW MDL lock and starts waiting for user lock
let $wait_condition=
  select count(*) = 1 from information_schema.processlist
  where state = "User lock" and
        info = "INSERT INTO t2 VALUES (GET_LOCK('mysqltest_lock', 100))";
--source include/wait_condition.inc

--echo # Sending:
--send LOCK TABLES t2 WRITE;

connection default;
--echo # Wait until LOCK TABLES WRITE is blocked due to INSERT
let $wait_condition=
  select count(*) = 1 from information_schema.processlist
  where state = "Waiting for table metadata lock" and
        info = "LOCK TABLES t2 WRITE";
--source include/wait_condition.inc

--echo # Unblock INSERT.
SELECT RELEASE_LOCK('mysqltest_lock');

connection con1;
--echo # Reaping INSERT
--reap
SELECT RELEASE_LOCK('mysqltest_lock');

connection con2;
--echo # Reaping LOCK TABLES WRITE
--reap
UNLOCK TABLES;

connection default;
--echo # Revert effects from INSERTs
DELETE FROM t1 LIMIT 1;
DELETE FROM t2 LIMIT 1;

--echo #
--echo # 2.e) LOCK TABLES WRITE which explicitly locks table is blocked
--echo #      by concurrent transactions which read table.
BEGIN;
SELECT * FROM t1;

connection con1;
--echo # Sending:
--send LOCK TABLES t1 WRITE;

connection default;
--echo # Wait until LOCK TABLES WRITE is blocked due concurrent transaction
let $wait_condition=
  select count(*) = 1 from information_schema.processlist
  where state = "Waiting for table metadata lock" and
        info = "LOCK TABLES t1 WRITE";
--source include/wait_condition.inc
--echo # Unblock LOCK TABLES WRITE
COMMIT;

connection con1;
--echo # Reap LOCK TABLES WRITE
--reap
UNLOCK TABLES;

connection default;
BEGIN;
SELECT * FROM t2;

connection con1;
--echo # Sending:
--send LOCK TABLES t2 WRITE;

connection default;
--echo # Wait until LOCK TABLES WRITE is blocked due concurrent transaction
let $wait_condition=
  select count(*) = 1 from information_schema.processlist
  where state = "Waiting for table metadata lock" and
        info = "LOCK TABLES t2 WRITE";
--source include/wait_condition.inc
--echo # Unblock LOCK TABLES WRITE
COMMIT;

connection con1;
--echo # Reap LOCK TABLES WRITE
--reap
UNLOCK TABLES;

connection default;
--echo #
--echo # 2.f) LOCK TABLES WRITE which explicitly locks table is blocked
--echo #      by concurrent transactions which modify table.
BEGIN;
INSERT INTO t1 VALUES (1);

connection con1;
--echo # Sending:
--send LOCK TABLES t1 WRITE;

connection default;
--echo # Wait until LOCK TABLES WRITE is blocked due concurrent transaction
let $wait_condition=
  select count(*) = 1 from information_schema.processlist
  where state = "Waiting for table metadata lock" and
        info = "LOCK TABLES t1 WRITE";
--source include/wait_condition.inc
--echo # Unblock LOCK TABLES WRITE
COMMIT;

connection con1;
--echo # Reap LOCK TABLES WRITE
--reap
UNLOCK TABLES;

connection default;
BEGIN;
INSERT INTO t2 VALUES (1);

connection con1;
--echo # Sending:
--send LOCK TABLES t2 WRITE;

connection default;
--echo # Wait until LOCK TABLES WRITE is blocked due concurrent transaction
let $wait_condition=
  select count(*) = 1 from information_schema.processlist
  where state = "Waiting for table metadata lock" and
        info = "LOCK TABLES t2 WRITE";
--source include/wait_condition.inc
--echo # Unblock LOCK TABLES WRITE
COMMIT;

connection con1;
--echo # Reap LOCK TABLES WRITE
--reap
UNLOCK TABLES;

connection default;
--echo # Revert effects from INSERTs
DELETE FROM t1 LIMIT 1;
DELETE FROM t2 LIMIT 1;

--echo #
--echo # 2.g) LOCK TABLES WRITE which explicitly locks table is not compatible
--echo #      with itself.
LOCK TABLES t1 WRITE;

connection con1;
--echo # Sending:
--send LOCK TABLES t1 WRITE;

connection default;
--echo # Wait until LOCK TABLES WRITE is blocked
let $wait_condition=
  select count(*) = 1 from information_schema.processlist
  where state = "Waiting for table metadata lock" and
        info = "LOCK TABLES t1 WRITE";
--source include/wait_condition.inc
--echo # Unblock LOCK TABLES WRITE
UNLOCK TABLES;

connection con1;
--echo # Reap LOCK TABLES WRITE
--reap
UNLOCK TABLES;

connection default;
LOCK TABLES t2 WRITE;

connection con1;
--echo # Sending:
--send LOCK TABLES t2 WRITE;

connection default;
--echo # Wait until LOCK TABLES WRITE is blocked
let $wait_condition=
  select count(*) = 1 from information_schema.processlist
  where state = "Waiting for table metadata lock" and
        info = "LOCK TABLES t2 WRITE";
--source include/wait_condition.inc
--echo # Unblock LOCK TABLES WRITE
UNLOCK TABLES;

connection con1;
--echo # Reap LOCK TABLES WRITE
--reap
UNLOCK TABLES;


--echo #
--echo # 3) LOCK TABLES which locks table for read through view.
--echo #    Case of main table in mergeable view.
--echo #
--echo # 3.a) Allows concurrent reads
connection default;
LOCK TABLE v1 READ, v2 READ;
connection con1;
SELECT * FROM t1;
SELECT * FROM t2;
connection default;
UNLOCK TABLES;

--echo #
--echo # 3.b) Is allowed concurrently to reads
SELECT GET_LOCK('mysqltest_lock', 100);

connection con1;
--echo # Start read by sending SELECT:
--send SELECT GET_LOCK('mysqltest_lock', 100) FROM t1, t2;

connection con2;
--echo # Wait until SELECT gets read lock and starts waiting for user lock
let $wait_condition=
  select count(*) = 1 from information_schema.processlist
  where state = "User lock" and
        info = "SELECT GET_LOCK('mysqltest_lock', 100) FROM t1, t2";
--source include/wait_condition.inc
--echo # LOCK TABLES should not be blocked.
LOCK TABLES v1 READ, v2 READ;
UNLOCK TABLES;

connection default;
--echo # Unblock SELECT.
SELECT RELEASE_LOCK('mysqltest_lock');

connection con1;
--echo # Reaping SELECT
--reap
SELECT RELEASE_LOCK('mysqltest_lock');

--echo #
--echo # 3.c) Blocks concurrent modifications to table
connection default;

LOCK TABLE v1 READ, v2 READ;

connection con1;
--echo # Sending:
--send INSERT INTO t1 VALUES (1)

connection default;
--echo # Wait until INSERT gets blocked
let $wait_condition=
  select count(*) = 1 from information_schema.processlist
  where state = "Waiting for table metadata lock" and
        info = "INSERT INTO t1 VALUES (1)";
--source include/wait_condition.inc

connection con2;
--echo # Sending:
--send INSERT INTO t2 VALUES (1)

connection default;
--echo # Wait until INSERT gets blocked
let $wait_condition=
  select count(*) = 1 from information_schema.processlist
  where state = "Waiting for table metadata lock" and
        info = "INSERT INTO t2 VALUES (1)";
--source include/wait_condition.inc

--echo # Unblock INSERTs
UNLOCK TABLES;

connection con1;
--echo # Reap INSERT
--reap

connection con2;
--echo # Reap INSERT
--reap

connection default;
--echo # Revert effects from INSERTs
DELETE FROM t1 LIMIT 1;
DELETE FROM t2 LIMIT 1;

--echo #
--echo # 3.d) Is blocked by concurrent table modifications
SELECT GET_LOCK('mysqltest_lock', 100);

connection con1;
--echo # Sending:
--send INSERT INTO t1 VALUES (GET_LOCK('mysqltest_lock', 100));

connection con2;
--echo # Wait until INSERT gets SW MDL lock and starts waiting for user lock
let $wait_condition=
  select count(*) = 1 from information_schema.processlist
  where state = "User lock" and
        info = "INSERT INTO t1 VALUES (GET_LOCK('mysqltest_lock', 100))";
--source include/wait_condition.inc

--echo # Sending:
--send LOCK TABLES v1 READ;

connection default;
--echo # Wait until LOCK TABLES READ is blocked due to INSERT
let $wait_condition=
  select count(*) = 1 from information_schema.processlist
  where state = "Waiting for table metadata lock" and
        info = "LOCK TABLES v1 READ";
--source include/wait_condition.inc

--echo # Unblock INSERT.
SELECT RELEASE_LOCK('mysqltest_lock');

connection con1;
--echo # Reaping INSERT
--reap
SELECT RELEASE_LOCK('mysqltest_lock');

connection con2;
--echo # Reaping LOCK TABLES READ
--reap
UNLOCK TABLES;

connection default;

SELECT GET_LOCK('mysqltest_lock', 100);

connection con1;
--echo # Sending:
--send INSERT INTO t2 VALUES (GET_LOCK('mysqltest_lock', 100));

connection con2;
--echo # Wait until INSERT gets SW MDL lock and starts waiting for user lock
let $wait_condition=
  select count(*) = 1 from information_schema.processlist
  where state = "User lock" and
        info = "INSERT INTO t2 VALUES (GET_LOCK('mysqltest_lock', 100))";
--source include/wait_condition.inc

--echo # Sending:
--send LOCK TABLES v2 READ;

connection default;
--echo # Wait until LOCK TABLES READ is blocked due to INSERT
let $wait_condition=
  select count(*) = 1 from information_schema.processlist
  where state = "Waiting for table metadata lock" and
        info = "LOCK TABLES v2 READ";
--source include/wait_condition.inc

--echo # Unblock INSERT.
SELECT RELEASE_LOCK('mysqltest_lock');

connection con1;
--echo # Reaping INSERT
--reap
SELECT RELEASE_LOCK('mysqltest_lock');

connection con2;
--echo # Reaping LOCK TABLES READ
--reap
UNLOCK TABLES;

connection default;
--echo # Revert effects from INSERTs
DELETE FROM t1 LIMIT 1;
DELETE FROM t2 LIMIT 1;

--echo #
--echo # 3.e) LOCK TABLES which locks table for read through view is not blocked
--echo #      by concurrent transactions which read table.
BEGIN;
SELECT * FROM t1;

connection con1;
LOCK TABLES v1 READ;
UNLOCK TABLES;

connection default;
COMMIT;

BEGIN;
SELECT * FROM t2;

connection con1;
LOCK TABLES v2 READ;
UNLOCK TABLES;

connection default;
COMMIT;

--echo #
--echo # 3.f) LOCK TABLES which locks table for read through view is blocked
--echo #      by concurrent transactions which modify table.
BEGIN;
INSERT INTO t1 VALUES (1);

connection con1;
--echo # Sending:
--send LOCK TABLES v1 READ;

connection default;
--echo # Wait until LOCK TABLES READ is blocked due concurrent transaction
let $wait_condition=
  select count(*) = 1 from information_schema.processlist
  where state = "Waiting for table metadata lock" and
        info = "LOCK TABLES v1 READ";
--source include/wait_condition.inc
--echo # Unblock LOCK TABLES READ
COMMIT;

connection con1;
--echo # Reap LOCK TABLES READ
--reap
UNLOCK TABLES;

connection default;
BEGIN;
INSERT INTO t2 VALUES (1);

connection con1;
--echo # Sending:
--send LOCK TABLES v2 READ;

connection default;
--echo # Wait until LOCK TABLES READ is blocked due concurrent transaction
let $wait_condition=
  select count(*) = 1 from information_schema.processlist
  where state = "Waiting for table metadata lock" and
        info = "LOCK TABLES v2 READ";
--source include/wait_condition.inc
--echo # Unblock LOCK TABLES READ
COMMIT;

connection con1;
--echo # Reap LOCK TABLES READ
--reap
UNLOCK TABLES;

connection default;
--echo # Revert effects from INSERTs
DELETE FROM t1 LIMIT 1;
DELETE FROM t2 LIMIT 1;

--echo #
--echo # 3.g) LOCK TABLES READ which locks table for read through view is
--echo #      compatible with explicit LOCK TABLES READ on the same table.
LOCK TABLES t1 READ, t2 READ;

connection con1;
LOCK TABLES v1 READ, v2 READ;
UNLOCK TABLES;

connection default;
UNLOCK TABLES;

--echo #
--echo # 3.h) LOCK TABLES READ which locks table for read through view is
--echo #      not compatible with explicit LOCK TABLES WRITE on the same table.
LOCK TABLES v1 READ;

connection con1;
--echo # Sending:
--send LOCK TABLES t1 WRITE;

connection default;
--echo # Wait until LOCK TABLES WRITE is blocked
let $wait_condition=
  select count(*) = 1 from information_schema.processlist
  where state = "Waiting for table metadata lock" and
        info = "LOCK TABLES t1 WRITE";
--source include/wait_condition.inc
--echo # Unblock LOCK TABLES WRITE
UNLOCK TABLES;

connection con1;
--echo # Reap LOCK TABLES WRITE
--reap
UNLOCK TABLES;

connection default;
LOCK TABLES v2 READ;

connection con1;
--echo # Sending:
--send LOCK TABLES t2 WRITE;

connection default;
--echo # Wait until LOCK TABLES WRITE is blocked
let $wait_condition=
  select count(*) = 1 from information_schema.processlist
  where state = "Waiting for table metadata lock" and
        info = "LOCK TABLES t2 WRITE";
--source include/wait_condition.inc
--echo # Unblock LOCK TABLES WRITE
UNLOCK TABLES;

connection con1;
--echo # Reap LOCK TABLES WRITE
--reap
UNLOCK TABLES;

connection default;
LOCK TABLES t1 WRITE;

connection con1;
--echo # Sending:
--send LOCK TABLES v1 READ;

connection default;
--echo # Wait until LOCK TABLES READ is blocked
let $wait_condition=
  select count(*) = 1 from information_schema.processlist
  where state = "Waiting for table metadata lock" and
        info = "LOCK TABLES v1 READ";
--source include/wait_condition.inc
--echo # Unblock LOCK TABLES READ
UNLOCK TABLES;

connection con1;
--echo # Reap LOCK TABLES READ
--reap
UNLOCK TABLES;

connection default;
LOCK TABLES t2 WRITE;

connection con1;
--echo # Sending:
--send LOCK TABLES v2 READ;

connection default;
--echo # Wait until LOCK TABLES READ is blocked
let $wait_condition=
  select count(*) = 1 from information_schema.processlist
  where state = "Waiting for table metadata lock" and
        info = "LOCK TABLES v2 READ";
--source include/wait_condition.inc
--echo # Unblock LOCK TABLES READ
UNLOCK TABLES;

connection con1;
--echo # Reap LOCK TABLES READ
--reap
UNLOCK TABLES;


--echo #
--echo # 4) LOCK TABLES which locks table for read through mergeable view.
--echo #    Case of table not from the main join. Such table will be locked
--echo #    for read even though view is locked for write.
--echo # 4.a) Allows concurrent reads
connection default;
LOCK TABLES v3 WRITE, v4 WRITE;
connection con1;
SELECT * FROM t1;
SELECT * FROM t2;
connection default;
UNLOCK TABLES;

--echo #
--echo # 4.b) Is allowed concurrently to reads
SELECT GET_LOCK('mysqltest_lock', 100);

connection con1;
--echo # Start read by sending SELECT:
--send SELECT GET_LOCK('mysqltest_lock', 100) FROM t1, t2;

connection con2;
--echo # Wait until SELECT gets read lock and starts waiting for user lock
let $wait_condition=
  select count(*) = 1 from information_schema.processlist
  where state = "User lock" and
        info = "SELECT GET_LOCK('mysqltest_lock', 100) FROM t1, t2";
--source include/wait_condition.inc
--echo # LOCK TABLES should not be blocked.
LOCK TABLES v3 WRITE, v4 WRITE;
UNLOCK TABLES;

connection default;
--echo # Unblock SELECT.
SELECT RELEASE_LOCK('mysqltest_lock');

connection con1;
--echo # Reaping SELECT
--reap
SELECT RELEASE_LOCK('mysqltest_lock');

--echo #
--echo # 4.c) Blocks concurrent modifications to table
connection default;

LOCK TABLES v3 WRITE, v4 WRITE;

connection con1;
--echo # Sending:
--send INSERT INTO t1 VALUES (1)

connection default;
--echo # Wait until INSERT gets blocked
let $wait_condition=
  select count(*) = 1 from information_schema.processlist
  where state = "Waiting for table metadata lock" and
        info = "INSERT INTO t1 VALUES (1)";
--source include/wait_condition.inc

connection con2;
--echo # Sending:
--send INSERT INTO t2 VALUES (1)

connection default;
--echo # Wait until INSERT gets blocked
let $wait_condition=
  select count(*) = 1 from information_schema.processlist
  where state = "Waiting for table metadata lock" and
        info = "INSERT INTO t2 VALUES (1)";
--source include/wait_condition.inc

--echo # Unblock INSERTs
UNLOCK TABLES;

connection con1;
--echo # Reap INSERT
--reap

connection con2;
--echo # Reap INSERT
--reap

connection default;
--echo # Revert effects from INSERTs
DELETE FROM t1 LIMIT 1;
DELETE FROM t2 LIMIT 1;

--echo #
--echo # 4.d) Is blocked by concurrent table modifications
SELECT GET_LOCK('mysqltest_lock', 100);

connection con1;
--echo # Sending:
--send INSERT INTO t1 VALUES (GET_LOCK('mysqltest_lock', 100));

connection con2;
--echo # Wait until INSERT gets SW MDL lock and starts waiting for user lock
let $wait_condition=
  select count(*) = 1 from information_schema.processlist
  where state = "User lock" and
        info = "INSERT INTO t1 VALUES (GET_LOCK('mysqltest_lock', 100))";
--source include/wait_condition.inc

--echo # Sending:
--send LOCK TABLES v3 WRITE;

connection default;
--echo # Wait until LOCK TABLES is blocked due to INSERT
let $wait_condition=
  select count(*) = 1 from information_schema.processlist
  where state = "Waiting for table metadata lock" and
        info = "LOCK TABLES v3 WRITE";
--source include/wait_condition.inc

--echo # Unblock INSERT.
SELECT RELEASE_LOCK('mysqltest_lock');

connection con1;
--echo # Reaping INSERT
--reap
SELECT RELEASE_LOCK('mysqltest_lock');

connection con2;
--echo # Reaping LOCK TABLES
--reap
UNLOCK TABLES;

connection default;

SELECT GET_LOCK('mysqltest_lock', 100);

connection con1;
--echo # Sending:
--send INSERT INTO t2 VALUES (GET_LOCK('mysqltest_lock', 100));

connection con2;
--echo # Wait until INSERT gets SW MDL lock and starts waiting for user lock
let $wait_condition=
  select count(*) = 1 from information_schema.processlist
  where state = "User lock" and
        info = "INSERT INTO t2 VALUES (GET_LOCK('mysqltest_lock', 100))";
--source include/wait_condition.inc

--echo # Sending:
--send LOCK TABLES v4 WRITE;

connection default;
--echo # Wait until LOCK TABLES is blocked due to INSERT
let $wait_condition=
  select count(*) = 1 from information_schema.processlist
  where state = "Waiting for table metadata lock" and
        info = "LOCK TABLES v4 WRITE";
--source include/wait_condition.inc

--echo # Unblock INSERT.
SELECT RELEASE_LOCK('mysqltest_lock');

connection con1;
--echo # Reaping INSERT
--reap
SELECT RELEASE_LOCK('mysqltest_lock');

connection con2;
--echo # Reaping LOCK TABLES
--reap
UNLOCK TABLES;

connection default;
--echo # Revert effects from INSERTs
DELETE FROM t1 LIMIT 1;
DELETE FROM t2 LIMIT 1;

--echo #
--echo # 4.e) LOCK TABLES which locks table for read through view is not blocked
--echo #      by concurrent transactions which read table.
BEGIN;
SELECT * FROM t1;

connection con1;
LOCK TABLES v3 WRITE;
UNLOCK TABLES;

connection default;
COMMIT;

BEGIN;
SELECT * FROM t2;

connection con1;
LOCK TABLES v4 WRITE;
UNLOCK TABLES;

connection default;
COMMIT;

--echo #
--echo # 4.f) LOCK TABLES which locks table for read through view is blocked
--echo #      by concurrent transactions which modify table.
BEGIN;
INSERT INTO t1 VALUES (1);

connection con1;
--echo # Sending:
--send LOCK TABLES v3 WRITE;

connection default;
--echo # Wait until LOCK TABLES is blocked due concurrent transaction
let $wait_condition=
  select count(*) = 1 from information_schema.processlist
  where state = "Waiting for table metadata lock" and
        info = "LOCK TABLES v3 WRITE";
--source include/wait_condition.inc
--echo # Unblock LOCK TABLES
COMMIT;

connection con1;
--echo # Reap LOCK TABLES
--reap
UNLOCK TABLES;

connection default;
BEGIN;
INSERT INTO t2 VALUES (1);

connection con1;
--echo # Sending:
--send LOCK TABLES v4 WRITE;

connection default;
--echo # Wait until LOCK TABLES is blocked due concurrent transaction
let $wait_condition=
  select count(*) = 1 from information_schema.processlist
  where state = "Waiting for table metadata lock" and
        info = "LOCK TABLES v4 WRITE";
--source include/wait_condition.inc
--echo # Unblock LOCK TABLES
COMMIT;

connection con1;
--echo # Reap LOCK TABLES
--reap
UNLOCK TABLES;

connection default;
--echo # Revert effects from INSERTs
DELETE FROM t1 LIMIT 1;
DELETE FROM t2 LIMIT 1;

--echo #
--echo # 4.g) LOCK TABLES which locks table for read through view is
--echo #      compatible with explicit LOCK TABLES READ on the same table.
LOCK TABLES t1 READ, t2 READ;

connection con1;
LOCK TABLES v3 WRITE, v4 WRITE;
UNLOCK TABLES;

connection default;
UNLOCK TABLES;

--echo #
--echo # 4.h) LOCK TABLES which locks table for read through view is
--echo #      not compatible with explicit LOCK TABLES WRITE on the same table.
LOCK TABLES v3 WRITE;

connection con1;
--echo # Sending:
--send LOCK TABLES t1 WRITE;

connection default;
--echo # Wait until LOCK TABLES WRITE is blocked
let $wait_condition=
  select count(*) = 1 from information_schema.processlist
  where state = "Waiting for table metadata lock" and
        info = "LOCK TABLES t1 WRITE";
--source include/wait_condition.inc
--echo # Unblock LOCK TABLES WRITE
UNLOCK TABLES;

connection con1;
--echo # Reap LOCK TABLES WRITE
--reap
UNLOCK TABLES;

connection default;
LOCK TABLES v4 WRITE;

connection con1;
--echo # Sending:
--send LOCK TABLES t2 WRITE;

connection default;
--echo # Wait until LOCK TABLES WRITE is blocked
let $wait_condition=
  select count(*) = 1 from information_schema.processlist
  where state = "Waiting for table metadata lock" and
        info = "LOCK TABLES t2 WRITE";
--source include/wait_condition.inc
--echo # Unblock LOCK TABLES WRITE
UNLOCK TABLES;

connection con1;
--echo # Reap LOCK TABLES WRITE
--reap
UNLOCK TABLES;

connection default;
LOCK TABLES t1 WRITE;

connection con1;
--echo # Sending:
--send LOCK TABLES v3 WRITE;

connection default;
--echo # Wait until LOCK TABLES is blocked
let $wait_condition=
  select count(*) = 1 from information_schema.processlist
  where state = "Waiting for table metadata lock" and
        info = "LOCK TABLES v3 WRITE";
--source include/wait_condition.inc
--echo # Unblock LOCK TABLES
UNLOCK TABLES;

connection con1;
--echo # Reap LOCK TABLES
--reap
UNLOCK TABLES;

connection default;
LOCK TABLES t2 WRITE;

connection con1;
--echo # Sending:
--send LOCK TABLES v4 WRITE;

connection default;
--echo # Wait until LOCK TABLES WRITE is blocked
let $wait_condition=
  select count(*) = 1 from information_schema.processlist
  where state = "Waiting for table metadata lock" and
        info = "LOCK TABLES v4 WRITE";
--source include/wait_condition.inc
--echo # Unblock LOCK TABLES
UNLOCK TABLES;

connection con1;
--echo # Reap LOCK TABLES
--reap
UNLOCK TABLES;


--echo #
--echo # 5) LOCK TABLES which locks tables for write through view
--echo #
--echo # 5.a) Doesn't allow concurrent reads
connection default;
LOCK TABLE v1 WRITE;

connection con1;
--echo # Sending:
--send SELECT * FROM t1;

connection default;
--echo # Wait until SELECT gets blocked 
let $wait_condition=
  select count(*) = 1 from information_schema.processlist
  where state = "Waiting for table metadata lock" and
        info = "SELECT * FROM t1";
--source include/wait_condition.inc
--echo # Unblock SELECT
UNLOCK TABLES;

connection con1;
--echo # Reaping SELECT
--reap

connection default;
LOCK TABLE v2 WRITE;

connection con1;
--echo # Sending:
--send SELECT * FROM t2;

connection default;
--echo # Wait until SELECT gets blocked 
let $wait_condition=
  select count(*) = 1 from information_schema.processlist
  where state = "Waiting for table metadata lock" and
        info = "SELECT * FROM t2";
--source include/wait_condition.inc
--echo # Unblock SELECT
UNLOCK TABLES;

connection con1;
--echo # Reaping SELECT
--reap

connection default;
--echo #
--echo # 5.b) Is not allowed concurrently to reads
SELECT GET_LOCK('mysqltest_lock', 100);

connection con1;
--echo # Start read by sending SELECT:
--send SELECT GET_LOCK('mysqltest_lock', 100) FROM t1;

connection con2;
--echo # Wait until SELECT gets read lock and starts waiting for user lock
let $wait_condition=
  select count(*) = 1 from information_schema.processlist
  where state = "User lock" and
        info = "SELECT GET_LOCK('mysqltest_lock', 100) FROM t1";
--source include/wait_condition.inc
--echo # Sending:
--send LOCK TABLES v1 WRITE;

connection default;
let $wait_condition=
  select count(*) = 1 from information_schema.processlist
  where state = "Waiting for table metadata lock" and
        info = "LOCK TABLES v1 WRITE";
--source include/wait_condition.inc
UNLOCK TABLES;

--echo # Unblock SELECT.
SELECT RELEASE_LOCK('mysqltest_lock');

connection con1;
--echo # Reaping SELECT
--reap
SELECT RELEASE_LOCK('mysqltest_lock');

connection con2;
--echo # Reaping LOCK TABLE WRITE
--reap
UNLOCK TABLES;

connection default;
SELECT GET_LOCK('mysqltest_lock', 100);

connection con1;
--echo # Start read by sending SELECT:
--send SELECT GET_LOCK('mysqltest_lock', 100) FROM t2;

connection con2;
--echo # Wait until SELECT gets read lock and starts waiting for user lock
let $wait_condition=
  select count(*) = 1 from information_schema.processlist
  where state = "User lock" and
        info = "SELECT GET_LOCK('mysqltest_lock', 100) FROM t2";
--source include/wait_condition.inc
--echo # Sending:
--send LOCK TABLES v2 WRITE;

connection default;
let $wait_condition=
  select count(*) = 1 from information_schema.processlist
  where state = "Waiting for table metadata lock" and
        info = "LOCK TABLES v2 WRITE";
--source include/wait_condition.inc
UNLOCK TABLES;

--echo # Unblock SELECT.
SELECT RELEASE_LOCK('mysqltest_lock');

connection con1;
--echo # Reaping SELECT
--reap
SELECT RELEASE_LOCK('mysqltest_lock');

connection con2;
--echo # Reaping LOCK TABLE WRITE
--reap
UNLOCK TABLES;


--echo #
--echo # 5.c) Blocks concurrent modifications to table
connection default;
LOCK TABLE v1 WRITE, v2 WRITE;

connection con1;
--echo # Sending:
--send INSERT INTO t1 VALUES (1)

connection default;
--echo # Wait until INSERT gets blocked
let $wait_condition=
  select count(*) = 1 from information_schema.processlist
  where state = "Waiting for table metadata lock" and
        info = "INSERT INTO t1 VALUES (1)";
--source include/wait_condition.inc

connection con2;
--echo # Sending:
--send INSERT INTO t2 VALUES (1)

connection default;
--echo # Wait until INSERT gets blocked
let $wait_condition=
  select count(*) = 1 from information_schema.processlist
  where state = "Waiting for table metadata lock" and
        info = "INSERT INTO t2 VALUES (1)";
--source include/wait_condition.inc

--echo # Unblock INSERTs
UNLOCK TABLES;

connection con1;
--echo # Reap INSERT
--reap

connection con2;
--echo # Reap INSERT
--reap

connection default;
--echo # Revert effects from INSERTs
DELETE FROM t1 LIMIT 1;
DELETE FROM t2 LIMIT 1;

--echo #
--echo # 5.d) Is blocked by concurrent table modifications
SELECT GET_LOCK('mysqltest_lock', 100);

connection con1;
--echo # Sending:
--send INSERT INTO t1 VALUES (GET_LOCK('mysqltest_lock', 100));

connection con2;
--echo # Wait until INSERT gets SW MDL lock and starts waiting for user lock
let $wait_condition=
  select count(*) = 1 from information_schema.processlist
  where state = "User lock" and
        info = "INSERT INTO t1 VALUES (GET_LOCK('mysqltest_lock', 100))";
--source include/wait_condition.inc

--echo # Sending:
--send LOCK TABLES v1 WRITE;

connection default;
--echo # Wait until LOCK TABLES WRITE is blocked due to INSERT
let $wait_condition=
  select count(*) = 1 from information_schema.processlist
  where state = "Waiting for table metadata lock" and
        info = "LOCK TABLES v1 WRITE";
--source include/wait_condition.inc

--echo # Unblock INSERT.
SELECT RELEASE_LOCK('mysqltest_lock');

connection con1;
--echo # Reaping INSERT
--reap
SELECT RELEASE_LOCK('mysqltest_lock');

connection con2;
--echo # Reaping LOCK TABLES WRITE
--reap
UNLOCK TABLES;

connection default;

SELECT GET_LOCK('mysqltest_lock', 100);

connection con1;
--echo # Sending:
--send INSERT INTO t2 VALUES (GET_LOCK('mysqltest_lock', 100));

connection con2;
--echo # Wait until INSERT gets SW MDL lock and starts waiting for user lock
let $wait_condition=
  select count(*) = 1 from information_schema.processlist
  where state = "User lock" and
        info = "INSERT INTO t2 VALUES (GET_LOCK('mysqltest_lock', 100))";
--source include/wait_condition.inc

--echo # Sending:
--send LOCK TABLES v2 WRITE;

connection default;
--echo # Wait until LOCK TABLES WRITE is blocked due to INSERT
let $wait_condition=
  select count(*) = 1 from information_schema.processlist
  where state = "Waiting for table metadata lock" and
        info = "LOCK TABLES v2 WRITE";
--source include/wait_condition.inc

--echo # Unblock INSERT.
SELECT RELEASE_LOCK('mysqltest_lock');

connection con1;
--echo # Reaping INSERT
--reap
SELECT RELEASE_LOCK('mysqltest_lock');

connection con2;
--echo # Reaping LOCK TABLES WRITE
--reap
UNLOCK TABLES;

connection default;
--echo # Revert effects from INSERTs
DELETE FROM t1 LIMIT 1;
DELETE FROM t2 LIMIT 1;

--echo #
--echo # 5.e) LOCK TABLES which locks table for write through view is blocked
--echo #      by concurrent transactions which read table.
BEGIN;
SELECT * FROM t1;

connection con1;
--echo # Sending:
--send LOCK TABLES v1 WRITE;

connection default;
--echo # Wait until LOCK TABLES WRITE is blocked due concurrent transaction
let $wait_condition=
  select count(*) = 1 from information_schema.processlist
  where state = "Waiting for table metadata lock" and
        info = "LOCK TABLES v1 WRITE";
--source include/wait_condition.inc
--echo # Unblock LOCK TABLES WRITE
COMMIT;

connection con1;
--echo # Reap LOCK TABLES WRITE
--reap
UNLOCK TABLES;

connection default;
BEGIN;
SELECT * FROM t2;

connection con1;
--echo # Sending:
--send LOCK TABLES v2 WRITE;

connection default;
--echo # Wait until LOCK TABLES WRITE is blocked due concurrent transaction
let $wait_condition=
  select count(*) = 1 from information_schema.processlist
  where state = "Waiting for table metadata lock" and
        info = "LOCK TABLES v2 WRITE";
--source include/wait_condition.inc
--echo # Unblock LOCK TABLES WRITE
COMMIT;

connection con1;
--echo # Reap LOCK TABLES WRITE
--reap
UNLOCK TABLES;

connection default;
--echo #
--echo # 5.f) LOCK TABLES which locks table for write through view is blocked
--echo #      by concurrent transactions which modify table.
BEGIN;
INSERT INTO t1 VALUES (1);

connection con1;
--echo # Sending:
--send LOCK TABLES v1 WRITE;

connection default;
--echo # Wait until LOCK TABLES WRITE is blocked due concurrent transaction
let $wait_condition=
  select count(*) = 1 from information_schema.processlist
  where state = "Waiting for table metadata lock" and
        info = "LOCK TABLES v1 WRITE";
--source include/wait_condition.inc
--echo # Unblock LOCK TABLES WRITE
COMMIT;

connection con1;
--echo # Reap LOCK TABLES WRITE
--reap
UNLOCK TABLES;

connection default;
BEGIN;
INSERT INTO t2 VALUES (1);

connection con1;
--echo # Sending:
--send LOCK TABLES v2 WRITE;

connection default;
--echo # Wait until LOCK TABLES WRITE is blocked due concurrent transaction
let $wait_condition=
  select count(*) = 1 from information_schema.processlist
  where state = "Waiting for table metadata lock" and
        info = "LOCK TABLES v2 WRITE";
--source include/wait_condition.inc
--echo # Unblock LOCK TABLES WRITE
COMMIT;

connection con1;
--echo # Reap LOCK TABLES WRITE
--reap
UNLOCK TABLES;

connection default;
--echo # Revert effects from INSERTs
DELETE FROM t1 LIMIT 1;
DELETE FROM t2 LIMIT 1;

--echo #
--echo # 5.g) LOCK TABLES which locks table for write through view is not
--echo #      compatible with LOCK TABLE WRITE.
LOCK TABLES v1 WRITE;

connection con1;
--echo # Sending:
--send LOCK TABLES t1 WRITE;

connection default;
--echo # Wait until LOCK TABLES WRITE is blocked
let $wait_condition=
  select count(*) = 1 from information_schema.processlist
  where state = "Waiting for table metadata lock" and
        info = "LOCK TABLES t1 WRITE";
--source include/wait_condition.inc
--echo # Unblock LOCK TABLES WRITE
UNLOCK TABLES;

connection con1;
--echo # Reap LOCK TABLES WRITE
--reap
UNLOCK TABLES;

connection default;
LOCK TABLES v2 WRITE;

connection con1;
--echo # Sending:
--send LOCK TABLES t2 WRITE;

connection default;
--echo # Wait until LOCK TABLES WRITE is blocked
let $wait_condition=
  select count(*) = 1 from information_schema.processlist
  where state = "Waiting for table metadata lock" and
        info = "LOCK TABLES t2 WRITE";
--source include/wait_condition.inc
--echo # Unblock LOCK TABLES WRITE
UNLOCK TABLES;

connection con1;
--echo # Reap LOCK TABLES WRITE
--reap
UNLOCK TABLES;


--echo #
--echo # 6) LOCK TABLES which locks table for read through trigger.
--echo #
--echo # 6.a) Allows concurrent reads
connection default;
LOCK TABLES t5 WRITE, t6 WRITE;
connection con1;
SELECT * FROM t1;
SELECT * FROM t2;
connection default;
UNLOCK TABLES;

--echo #
--echo # 6.b) Is allowed concurrently to reads
SELECT GET_LOCK('mysqltest_lock', 100);

connection con1;
--echo # Start read by sending SELECT:
--send SELECT GET_LOCK('mysqltest_lock', 100) FROM t1, t2;

connection con2;
--echo # Wait until SELECT gets read lock and starts waiting for user lock
let $wait_condition=
  select count(*) = 1 from information_schema.processlist
  where state = "User lock" and
        info = "SELECT GET_LOCK('mysqltest_lock', 100) FROM t1, t2";
--source include/wait_condition.inc
--echo # LOCK TABLES should not be blocked.
LOCK TABLES v3 WRITE, t6 WRITE;
UNLOCK TABLES;

connection default;
--echo # Unblock SELECT.
SELECT RELEASE_LOCK('mysqltest_lock');

connection con1;
--echo # Reaping SELECT
--reap
SELECT RELEASE_LOCK('mysqltest_lock');

--echo #
--echo # 6.c) Blocks concurrent modifications to table
connection default;

LOCK TABLES t5 WRITE, t6 WRITE;

connection con1;
--echo # Sending:
--send INSERT INTO t1 VALUES (1)

connection default;
--echo # Wait until INSERT gets blocked
let $wait_condition=
  select count(*) = 1 from information_schema.processlist
  where state = "Waiting for table metadata lock" and
        info = "INSERT INTO t1 VALUES (1)";
--source include/wait_condition.inc

connection con2;
--echo # Sending:
--send INSERT INTO t2 VALUES (1)

connection default;
--echo # Wait until INSERT gets blocked
let $wait_condition=
  select count(*) = 1 from information_schema.processlist
  where state = "Waiting for table metadata lock" and
        info = "INSERT INTO t2 VALUES (1)";
--source include/wait_condition.inc

--echo # Unblock INSERTs
UNLOCK TABLES;

connection con1;
--echo # Reap INSERT
--reap

connection con2;
--echo # Reap INSERT
--reap

connection default;
--echo # Revert effects from INSERTs
DELETE FROM t1 LIMIT 1;
DELETE FROM t2 LIMIT 1;

--echo #
--echo # 6.d) Is blocked by concurrent table modifications
SELECT GET_LOCK('mysqltest_lock', 100);

connection con1;
--echo # Sending:
--send INSERT INTO t1 VALUES (GET_LOCK('mysqltest_lock', 100));

connection con2;
--echo # Wait until INSERT gets SW MDL lock and starts waiting for user lock
let $wait_condition=
  select count(*) = 1 from information_schema.processlist
  where state = "User lock" and
        info = "INSERT INTO t1 VALUES (GET_LOCK('mysqltest_lock', 100))";
--source include/wait_condition.inc

--echo # Sending:
--send LOCK TABLES t5 WRITE;

connection default;
--echo # Wait until LOCK TABLES is blocked due to INSERT
let $wait_condition=
  select count(*) = 1 from information_schema.processlist
  where state = "Waiting for table metadata lock" and
        info = "LOCK TABLES t5 WRITE";
--source include/wait_condition.inc

--echo # Unblock INSERT.
SELECT RELEASE_LOCK('mysqltest_lock');

connection con1;
--echo # Reaping INSERT
--reap
SELECT RELEASE_LOCK('mysqltest_lock');

connection con2;
--echo # Reaping LOCK TABLES
--reap
UNLOCK TABLES;

connection default;

SELECT GET_LOCK('mysqltest_lock', 100);

connection con1;
--echo # Sending:
--send INSERT INTO t2 VALUES (GET_LOCK('mysqltest_lock', 100));

connection con2;
--echo # Wait until INSERT gets SW MDL lock and starts waiting for user lock
let $wait_condition=
  select count(*) = 1 from information_schema.processlist
  where state = "User lock" and
        info = "INSERT INTO t2 VALUES (GET_LOCK('mysqltest_lock', 100))";
--source include/wait_condition.inc

--echo # Sending:
--send LOCK TABLES t6 WRITE;

connection default;
--echo # Wait until LOCK TABLES is blocked due to INSERT
let $wait_condition=
  select count(*) = 1 from information_schema.processlist
  where state = "Waiting for table metadata lock" and
        info = "LOCK TABLES t6 WRITE";
--source include/wait_condition.inc

--echo # Unblock INSERT.
SELECT RELEASE_LOCK('mysqltest_lock');

connection con1;
--echo # Reaping INSERT
--reap
SELECT RELEASE_LOCK('mysqltest_lock');

connection con2;
--echo # Reaping LOCK TABLES
--reap
UNLOCK TABLES;

connection default;
--echo # Revert effects from INSERTs
DELETE FROM t1 LIMIT 1;
DELETE FROM t2 LIMIT 1;

--echo #
--echo # 6.e) LOCK TABLES which locks table for read through trigger is not
--echo #      blocked by concurrent transactions which read table.
BEGIN;
SELECT * FROM t1;

connection con1;
LOCK TABLES t5 WRITE;
UNLOCK TABLES;

connection default;
COMMIT;

BEGIN;
SELECT * FROM t2;

connection con1;
LOCK TABLES t6 WRITE;
UNLOCK TABLES;

connection default;
COMMIT;

--echo #
--echo # 6.f) LOCK TABLES which locks table for read through trigger is
--echo #      blocked by concurrent transactions which modify table.
BEGIN;
INSERT INTO t1 VALUES (1);

connection con1;
--echo # Sending:
--send LOCK TABLES t5 WRITE;

connection default;
--echo # Wait until LOCK TABLES is blocked due concurrent transaction
let $wait_condition=
  select count(*) = 1 from information_schema.processlist
  where state = "Waiting for table metadata lock" and
        info = "LOCK TABLES t5 WRITE";
--source include/wait_condition.inc
--echo # Unblock LOCK TABLES
COMMIT;

connection con1;
--echo # Reap LOCK TABLES
--reap
UNLOCK TABLES;

connection default;
BEGIN;
INSERT INTO t2 VALUES (1);

connection con1;
--echo # Sending:
--send LOCK TABLES t6 WRITE;

connection default;
--echo # Wait until LOCK TABLES is blocked due concurrent transaction
let $wait_condition=
  select count(*) = 1 from information_schema.processlist
  where state = "Waiting for table metadata lock" and
        info = "LOCK TABLES t6 WRITE";
--source include/wait_condition.inc
--echo # Unblock LOCK TABLES
COMMIT;

connection con1;
--echo # Reap LOCK TABLES
--reap
UNLOCK TABLES;

connection default;
--echo # Revert effects from INSERTs
DELETE FROM t1 LIMIT 1;
DELETE FROM t2 LIMIT 1;

--echo #
--echo # 6.g) LOCK TABLES which locks table for read through trigger is
--echo #      compatible with explicit LOCK TABLES READ on the same table.
LOCK TABLES t1 READ, t2 READ;

connection con1;
LOCK TABLES t5 WRITE, t6 WRITE;
UNLOCK TABLES;

connection default;
UNLOCK TABLES;

--echo #
--echo # 6.h) LOCK TABLES which locks table for read through trigger is
--echo #      not compatible with explicit LOCK TABLES WRITE on the same table.
LOCK TABLES t5 WRITE;

connection con1;
--echo # Sending:
--send LOCK TABLES t1 WRITE;

connection default;
--echo # Wait until LOCK TABLES WRITE is blocked
let $wait_condition=
  select count(*) = 1 from information_schema.processlist
  where state = "Waiting for table metadata lock" and
        info = "LOCK TABLES t1 WRITE";
--source include/wait_condition.inc
--echo # Unblock LOCK TABLES WRITE
UNLOCK TABLES;

connection con1;
--echo # Reap LOCK TABLES WRITE
--reap
UNLOCK TABLES;

connection default;
LOCK TABLES t6 WRITE;

connection con1;
--echo # Sending:
--send LOCK TABLES t2 WRITE;

connection default;
--echo # Wait until LOCK TABLES WRITE is blocked
let $wait_condition=
  select count(*) = 1 from information_schema.processlist
  where state = "Waiting for table metadata lock" and
        info = "LOCK TABLES t2 WRITE";
--source include/wait_condition.inc
--echo # Unblock LOCK TABLES WRITE
UNLOCK TABLES;

connection con1;
--echo # Reap LOCK TABLES WRITE
--reap
UNLOCK TABLES;

connection default;
LOCK TABLES t1 WRITE;

connection con1;
--echo # Sending:
--send LOCK TABLES t5 WRITE;

connection default;
--echo # Wait until LOCK TABLES is blocked
let $wait_condition=
  select count(*) = 1 from information_schema.processlist
  where state = "Waiting for table metadata lock" and
        info = "LOCK TABLES t5 WRITE";
--source include/wait_condition.inc
--echo # Unblock LOCK TABLES
UNLOCK TABLES;

connection con1;
--echo # Reap LOCK TABLES
--reap
UNLOCK TABLES;

connection default;
LOCK TABLES t2 WRITE;

connection con1;
--echo # Sending:
--send LOCK TABLES t6 WRITE;

connection default;
--echo # Wait until LOCK TABLES WRITE is blocked
let $wait_condition=
  select count(*) = 1 from information_schema.processlist
  where state = "Waiting for table metadata lock" and
        info = "LOCK TABLES t6 WRITE";
--source include/wait_condition.inc
--echo # Unblock LOCK TABLES
UNLOCK TABLES;

connection con1;
--echo # Reap LOCK TABLES
--reap
UNLOCK TABLES;


--echo #
--echo # 7) LOCK TABLES which locks tables for write through trigger
--echo #
--echo # 7.a) Doesn't allow concurrent reads
connection default;
LOCK TABLE t7 WRITE;

connection con1;
--echo # Sending:
--send SELECT * FROM t1;

connection default;
--echo # Wait until SELECT gets blocked 
let $wait_condition=
  select count(*) = 1 from information_schema.processlist
  where state = "Waiting for table metadata lock" and
        info = "SELECT * FROM t1";
--source include/wait_condition.inc
--echo # Unblock SELECT
UNLOCK TABLES;

connection con1;
--echo # Reaping SELECT
--reap

connection default;
LOCK TABLE t8 WRITE;

connection con1;
--echo # Sending:
--send SELECT * FROM t2;

connection default;
--echo # Wait until SELECT gets blocked 
let $wait_condition=
  select count(*) = 1 from information_schema.processlist
  where state = "Waiting for table metadata lock" and
        info = "SELECT * FROM t2";
--source include/wait_condition.inc
--echo # Unblock SELECT
UNLOCK TABLES;

connection con1;
--echo # Reaping SELECT
--reap

connection default;
--echo #
--echo # 7.b) Is not allowed concurrently to reads
SELECT GET_LOCK('mysqltest_lock', 100);

connection con1;
--echo # Start read by sending SELECT:
--send SELECT GET_LOCK('mysqltest_lock', 100) FROM t1;

connection con2;
--echo # Wait until SELECT gets read lock and starts waiting for user lock
let $wait_condition=
  select count(*) = 1 from information_schema.processlist
  where state = "User lock" and
        info = "SELECT GET_LOCK('mysqltest_lock', 100) FROM t1";
--source include/wait_condition.inc
--echo # Sending:
--send LOCK TABLES t7 WRITE;

connection default;
let $wait_condition=
  select count(*) = 1 from information_schema.processlist
  where state = "Waiting for table metadata lock" and
        info = "LOCK TABLES t7 WRITE";
--source include/wait_condition.inc
UNLOCK TABLES;

--echo # Unblock SELECT.
SELECT RELEASE_LOCK('mysqltest_lock');

connection con1;
--echo # Reaping SELECT
--reap
SELECT RELEASE_LOCK('mysqltest_lock');

connection con2;
--echo # Reaping LOCK TABLE WRITE
--reap
UNLOCK TABLES;

connection default;
SELECT GET_LOCK('mysqltest_lock', 100);

connection con1;
--echo # Start read by sending SELECT:
--send SELECT GET_LOCK('mysqltest_lock', 100) FROM t2;

connection con2;
--echo # Wait until SELECT gets read lock and starts waiting for user lock
let $wait_condition=
  select count(*) = 1 from information_schema.processlist
  where state = "User lock" and
        info = "SELECT GET_LOCK('mysqltest_lock', 100) FROM t2";
--source include/wait_condition.inc
--echo # Sending:
--send LOCK TABLES t8 WRITE;

connection default;
let $wait_condition=
  select count(*) = 1 from information_schema.processlist
  where state = "Waiting for table metadata lock" and
        info = "LOCK TABLES t8 WRITE";
--source include/wait_condition.inc
UNLOCK TABLES;

--echo # Unblock SELECT.
SELECT RELEASE_LOCK('mysqltest_lock');

connection con1;
--echo # Reaping SELECT
--reap
SELECT RELEASE_LOCK('mysqltest_lock');

connection con2;
--echo # Reaping LOCK TABLE WRITE
--reap
UNLOCK TABLES;


--echo #
--echo # 7.c) Blocks concurrent modifications to table
connection default;
LOCK TABLE t7 WRITE, t8 WRITE;

connection con1;
--echo # Sending:
--send INSERT INTO t1 VALUES (1)

connection default;
--echo # Wait until INSERT gets blocked
let $wait_condition=
  select count(*) = 1 from information_schema.processlist
  where state = "Waiting for table metadata lock" and
        info = "INSERT INTO t1 VALUES (1)";
--source include/wait_condition.inc

connection con2;
--echo # Sending:
--send INSERT INTO t2 VALUES (1)

connection default;
--echo # Wait until INSERT gets blocked
let $wait_condition=
  select count(*) = 1 from information_schema.processlist
  where state = "Waiting for table metadata lock" and
        info = "INSERT INTO t2 VALUES (1)";
--source include/wait_condition.inc

--echo # Unblock INSERTs
UNLOCK TABLES;

connection con1;
--echo # Reap INSERT
--reap

connection con2;
--echo # Reap INSERT
--reap

connection default;
--echo # Revert effects from INSERTs
DELETE FROM t1 LIMIT 1;
DELETE FROM t2 LIMIT 1;

--echo #
--echo # 7.d) Is blocked by concurrent table modifications
SELECT GET_LOCK('mysqltest_lock', 100);

connection con1;
--echo # Sending:
--send INSERT INTO t1 VALUES (GET_LOCK('mysqltest_lock', 100));

connection con2;
--echo # Wait until INSERT gets SW MDL lock and starts waiting for user lock
let $wait_condition=
  select count(*) = 1 from information_schema.processlist
  where state = "User lock" and
        info = "INSERT INTO t1 VALUES (GET_LOCK('mysqltest_lock', 100))";
--source include/wait_condition.inc

--echo # Sending:
--send LOCK TABLES t7 WRITE;

connection default;
--echo # Wait until LOCK TABLES WRITE is blocked due to INSERT
let $wait_condition=
  select count(*) = 1 from information_schema.processlist
  where state = "Waiting for table metadata lock" and
        info = "LOCK TABLES t7 WRITE";
--source include/wait_condition.inc

--echo # Unblock INSERT.
SELECT RELEASE_LOCK('mysqltest_lock');

connection con1;
--echo # Reaping INSERT
--reap
SELECT RELEASE_LOCK('mysqltest_lock');

connection con2;
--echo # Reaping LOCK TABLES WRITE
--reap
UNLOCK TABLES;

connection default;

SELECT GET_LOCK('mysqltest_lock', 100);

connection con1;
--echo # Sending:
--send INSERT INTO t2 VALUES (GET_LOCK('mysqltest_lock', 100));

connection con2;
--echo # Wait until INSERT gets SW MDL lock and starts waiting for user lock
let $wait_condition=
  select count(*) = 1 from information_schema.processlist
  where state = "User lock" and
        info = "INSERT INTO t2 VALUES (GET_LOCK('mysqltest_lock', 100))";
--source include/wait_condition.inc

--echo # Sending:
--send LOCK TABLES t8 WRITE;

connection default;
--echo # Wait until LOCK TABLES WRITE is blocked due to INSERT
let $wait_condition=
  select count(*) = 1 from information_schema.processlist
  where state = "Waiting for table metadata lock" and
        info = "LOCK TABLES t8 WRITE";
--source include/wait_condition.inc

--echo # Unblock INSERT.
SELECT RELEASE_LOCK('mysqltest_lock');

connection con1;
--echo # Reaping INSERT
--reap
SELECT RELEASE_LOCK('mysqltest_lock');

connection con2;
--echo # Reaping LOCK TABLES WRITE
--reap
UNLOCK TABLES;

connection default;
--echo # Revert effects from INSERTs
DELETE FROM t1 LIMIT 1;
DELETE FROM t2 LIMIT 1;

--echo #
--echo # 7.e) LOCK TABLES which locks table for write through trigger is blocked
--echo #      by concurrent transactions which read table.
BEGIN;
SELECT * FROM t1;

connection con1;
--echo # Sending:
--send LOCK TABLES t7 WRITE;

connection default;
--echo # Wait until LOCK TABLES WRITE is blocked due concurrent transaction
let $wait_condition=
  select count(*) = 1 from information_schema.processlist
  where state = "Waiting for table metadata lock" and
        info = "LOCK TABLES t7 WRITE";
--source include/wait_condition.inc
--echo # Unblock LOCK TABLES WRITE
COMMIT;

connection con1;
--echo # Reap LOCK TABLES WRITE
--reap
UNLOCK TABLES;

connection default;
BEGIN;
SELECT * FROM t2;

connection con1;
--echo # Sending:
--send LOCK TABLES t8 WRITE;

connection default;
--echo # Wait until LOCK TABLES WRITE is blocked due concurrent transaction
let $wait_condition=
  select count(*) = 1 from information_schema.processlist
  where state = "Waiting for table metadata lock" and
        info = "LOCK TABLES t8 WRITE";
--source include/wait_condition.inc
--echo # Unblock LOCK TABLES WRITE
COMMIT;

connection con1;
--echo # Reap LOCK TABLES WRITE
--reap
UNLOCK TABLES;

connection default;
--echo #
--echo # 7.f) LOCK TABLES which locks table for write through trigger is blocked
--echo #      by concurrent transactions which modify table.
BEGIN;
INSERT INTO t1 VALUES (1);

connection con1;
--echo # Sending:
--send LOCK TABLES t7 WRITE;

connection default;
--echo # Wait until LOCK TABLES WRITE is blocked due concurrent transaction
let $wait_condition=
  select count(*) = 1 from information_schema.processlist
  where state = "Waiting for table metadata lock" and
        info = "LOCK TABLES t7 WRITE";
--source include/wait_condition.inc
--echo # Unblock LOCK TABLES WRITE
COMMIT;

connection con1;
--echo # Reap LOCK TABLES WRITE
--reap
UNLOCK TABLES;

connection default;
BEGIN;
INSERT INTO t2 VALUES (1);

connection con1;
--echo # Sending:
--send LOCK TABLES t8 WRITE;

connection default;
--echo # Wait until LOCK TABLES WRITE is blocked due concurrent transaction
let $wait_condition=
  select count(*) = 1 from information_schema.processlist
  where state = "Waiting for table metadata lock" and
        info = "LOCK TABLES t8 WRITE";
--source include/wait_condition.inc
--echo # Unblock LOCK TABLES WRITE
COMMIT;

connection con1;
--echo # Reap LOCK TABLES WRITE
--reap
UNLOCK TABLES;

connection default;
--echo # Revert effects from INSERTs
DELETE FROM t1 LIMIT 1;
DELETE FROM t2 LIMIT 1;

--echo #
--echo # 7.g) LOCK TABLES which locks table for write through trigger is not
--echo #      compatible with LOCK TABLE WRITE.
LOCK TABLES t7 WRITE;

connection con1;
--echo # Sending:
--send LOCK TABLES t1 WRITE;

connection default;
--echo # Wait until LOCK TABLES WRITE is blocked
let $wait_condition=
  select count(*) = 1 from information_schema.processlist
  where state = "Waiting for table metadata lock" and
        info = "LOCK TABLES t1 WRITE";
--source include/wait_condition.inc
--echo # Unblock LOCK TABLES WRITE
UNLOCK TABLES;

connection con1;
--echo # Reap LOCK TABLES WRITE
--reap
UNLOCK TABLES;

connection default;
LOCK TABLES t8 WRITE;

connection con1;
--echo # Sending:
--send LOCK TABLES t2 WRITE;

connection default;
--echo # Wait until LOCK TABLES WRITE is blocked
let $wait_condition=
  select count(*) = 1 from information_schema.processlist
  where state = "Waiting for table metadata lock" and
        info = "LOCK TABLES t2 WRITE";
--source include/wait_condition.inc
--echo # Unblock LOCK TABLES WRITE
UNLOCK TABLES;

connection con1;
--echo # Reap LOCK TABLES WRITE
--reap
UNLOCK TABLES;
disconnect con1;
disconnect con2;
connection default;

DROP VIEW v1, v2, v3, v4;
DROP TABLES t1, t2, t3, t4, t5, t6, t7, t8;
--disable_connect_log


--echo #
--echo # Test coverage for LOCK TABLES ... READ LOCAL
--echo #
--enable_connect_log
SET @old_concurrent_insert= @@global.concurrent_insert;
SET @@global.concurrent_insert= 1;
CREATE TABLE t1 (i INT) ENGINE=MyISAM;
CREATE TABLE t2 (i INT) ENGINE=InnoDB;
CREATE VIEW v1 AS SELECT * FROM t1;
CREATE VIEW v2 AS (SELECT * FROM t1) UNION (SELECT * FROM t1);
CREATE VIEW v3 AS SELECT * FROM t2;

--echo #
--echo # 1) READ LOCAL is fully supported for MyISAM.
--echo #    Concurrent inserts are allowed.
--echo #
LOCK TABLE t1 READ LOCAL;

connect (con1, localhost, root);
INSERT INTO t1 VALUES (1);

--echo #
--echo #   Concurrent updates are blocked.
--echo #
--echo # Sending:
--send UPDATE t1 SET i= 2

connection default;
--echo # Wait until UPDATE is blocked.
let $wait_condition=
  select count(*) = 1 from information_schema.processlist
  where state = "Waiting for table level lock" and
        info = "UPDATE t1 SET i= 2";
--source include/wait_condition.inc
UNLOCK TABLES;

connection con1;
--echo # Reaping UPDATE.
--reap

--echo # 
--echo # 2) READ LOCAL works even for mergeable views on
--echo #    top of MyISAM tables.
--echo #
connection default;
LOCK TABLE v1 READ LOCAL;

connection con1;
INSERT INTO v1 VALUES (1);
INSERT INTO t1 VALUES (3);

--echo #   Concurrent updates are blocked.
--echo # Sending:
--send UPDATE t1 SET i= 2

connection default;
--echo # Wait until UPDATE is blocked.
let $wait_condition=
  select count(*) = 1 from information_schema.processlist
  where state = "Waiting for table level lock" and
        info = "UPDATE t1 SET i= 2";
--source include/wait_condition.inc
UNLOCK TABLES;
connection con1;
--echo # Reaping UPDATE.
--reap

--echo #
--echo # 3) READ LOCAL doesn't work for non-mergeable views on
--echo #    top of MyISAM tables.
--echo #
connection default;
LOCK TABLE v2 READ LOCAL;

connection con1;
--echo # Sending:
--send INSERT INTO t1 VALUES (1)

connection default;
--echo # Wait until INSERT is blocked.
let $wait_condition=
  select count(*) = 1 from information_schema.processlist
  where state = "Waiting for table metadata lock" and
        info = "INSERT INTO t1 VALUES (1)";
--source include/wait_condition.inc
UNLOCK TABLES;
connection con1;
--echo # Reaping INSERT.
--reap

connection default;
LOCK TABLE v2 READ LOCAL;

connection con1;
--echo # Sending:
--send UPDATE t1 SET i= 2;

connection default;
--echo # Wait until UPDATE is blocked.
let $wait_condition=
  select count(*) = 1 from information_schema.processlist
  where state = "Waiting for table metadata lock" and
        info = "UPDATE t1 SET i= 2";
--source include/wait_condition.inc
UNLOCK TABLES;
connection con1;
--echo # Reaping UPDATE.
--reap

--echo #
--echo # 4) READ LOCAL locks are upgraded to simple READ locks
--echo #    for InnoDB tables. So they block both concurrent inserts
--echo #    and updates.
--echo #
connection default;
LOCK TABLE t2 READ LOCAL;

connection con1;
--echo # Sending:
--send INSERT INTO t2 VALUES (1)

connection default;
--echo # Wait until INSERT is blocked.
let $wait_condition=
  select count(*) = 1 from information_schema.processlist
  where state = "Waiting for table metadata lock" and
        info = "INSERT INTO t2 VALUES (1)";
--source include/wait_condition.inc
UNLOCK TABLES;
connection con1;
--echo # Reaping INSERT.
--reap

connection default;
LOCK TABLE t2 READ LOCAL;

connection con1;
--echo # Sending:
--send UPDATE t2 SET i= 2;

connection default;
--echo # Wait until UPDATE is blocked.
let $wait_condition=
  select count(*) = 1 from information_schema.processlist
  where state = "Waiting for table metadata lock" and
        info = "UPDATE t2 SET i= 2";
--source include/wait_condition.inc
UNLOCK TABLES;
connection con1;
--echo # Reaping UPDATE.
--reap

--echo #
--echo # 5) For mergeable views on top of InnoDB tables READ LOCAL locks are
--echo #    upgraded to simple READ locks as well.
--echo #
connection default;
LOCK TABLE v3 READ LOCAL;

connection con1;
--echo # Sending:
--send INSERT INTO t2 VALUES (1)

connection default;
--echo # Wait until INSERT is blocked.
let $wait_condition=
  select count(*) = 1 from information_schema.processlist
  where state = "Waiting for table metadata lock" and
        info = "INSERT INTO t2 VALUES (1)";
--source include/wait_condition.inc
UNLOCK TABLES;
connection con1;
--echo # Reaping INSERT.
--reap

connection default;
LOCK TABLE v3 READ LOCAL;

connection con1;
--echo # Sending:
--send UPDATE t2 SET i= 2;

connection default;
--echo # Wait until UPDATE is blocked.
let $wait_condition=
  select count(*) = 1 from information_schema.processlist
  where state = "Waiting for table metadata lock" and
        info = "UPDATE t2 SET i= 2";
--source include/wait_condition.inc
UNLOCK TABLES;
connection con1;
--echo # Reaping UPDATE.
--reap

connection default;
disconnect con1;
DROP VIEW v1, v2, v3;
DROP TABLES t1, t2;
SET @@global.concurrent_insert= @old_concurrent_insert;
--disable_connect_log


--echo #
--echo # Test coverage for interaction between LOCK TABLE ... READ and
--echo # concurrent DML which uses LOW_PRIORITY and HIGH_PRIORITY clauses/
--echo # concurrent DML which is executed in @@low_priority_updates=1 mode.
--echo #
--enable_connect_log
--echo # We will use MyISAM to avoid row-locks.
CREATE TABLE t1 (i INT) ENGINE=MyISAM;
CREATE VIEW v1 AS SELECT * FROM t1;
CREATE TABLE t2 (j INT);
CREATE TRIGGER t2_ai AFTER INSERT ON t2 FOR EACH ROW
  INSERT LOW_PRIORITY INTO t1 VALUES (2);
CREATE TABLE t3 (k INT);
CREATE TRIGGER t3_ai AFTER INSERT ON t3 FOR EACH ROW
  INSERT INTO t1 VALUES (2);
CREATE TABLE tm (i INT) ENGINE=MERGE UNION=(t1);

--echo #
--echo # 1) Let us check that DML operations with LOW_PRIORITY clauses have
--echo #    lower priority than pending LOCK TABLE ... READ, thus can't starve
--echo #    it out.
--echo #
--echo # Acquire SW lock on the table, to create pending LOCK TABLE ... READ.
BEGIN;
INSERT INTO t1 VALUES (1);

connect (blocker, localhost, root);
--echo # Sending:
--send LOCK TABLE t1 READ;

connection default;
--echo # Wait until LOCK TABLE READ gets blocked
let $wait_condition=
  select count(*) = 1 from information_schema.processlist
  where state = "Waiting for table metadata lock" and
        info = "LOCK TABLE t1 READ";
--source include/wait_condition.inc

connect (con_insert, localhost, root);
--echo # INSERT HIGH_PRIORITY should not get blocked
INSERT HIGH_PRIORITY INTO t1 VALUES (1);

--echo # Sending:
--send INSERT LOW_PRIORITY INTO t1 VALUES (1);

connection default;
--echo # Check that INSERT is blocked
let $wait_condition=
  select count(*) = 1 from information_schema.processlist
  where state = "Waiting for table metadata lock" and
        info = "INSERT LOW_PRIORITY INTO t1 VALUES (1)";
--source include/wait_condition.inc

connect (con_replace, localhost, root);
--echo # Sending:
--send REPLACE LOW_PRIORITY INTO t1 VALUES (1);

connection default;
--echo # Check that REPLACE is blocked
let $wait_condition=
  select count(*) = 1 from information_schema.processlist
  where state = "Waiting for table metadata lock" and
        info = "REPLACE LOW_PRIORITY INTO t1 VALUES (1)";
--source include/wait_condition.inc

connect (con_update, localhost, root);
--echo # Sending:
--send UPDATE LOW_PRIORITY t1 SET i= 1;

connection default;
--echo # Check that UPDATE is blocked
let $wait_condition=
  select count(*) = 1 from information_schema.processlist
  where state = "Waiting for table metadata lock" and
        info = "UPDATE LOW_PRIORITY t1 SET i= 1";
--source include/wait_condition.inc

connect (con_update_multi, localhost, root);
--echo # Sending:
--send UPDATE LOW_PRIORITY t1 AS a, t1 AS b SET a.i= 1;

connection default;
--echo # Check that multi-UPDATE is blocked
let $wait_condition=
  select count(*) = 1 from information_schema.processlist
  where state = "Waiting for table metadata lock" and
        info = "UPDATE LOW_PRIORITY t1 AS a, t1 AS b SET a.i= 1";
--source include/wait_condition.inc

connect (con_delete, localhost, root);
--echo # Sending:
--send DELETE LOW_PRIORITY FROM t1 LIMIT 1;

connection default;
--echo # Check that DELETE is blocked
let $wait_condition=
  select count(*) = 1 from information_schema.processlist
  where state = "Waiting for table metadata lock" and
        info = "DELETE LOW_PRIORITY FROM t1 LIMIT 1";
--source include/wait_condition.inc

connect (con_delete_multi, localhost, root);
--echo # Sending:
--send DELETE LOW_PRIORITY FROM a USING t1 AS a, t1 AS b;

connection default;
--echo # Check that multi-DELETE is blocked
let $wait_condition=
  select count(*) = 1 from information_schema.processlist
  where state = "Waiting for table metadata lock" and
        info = "DELETE LOW_PRIORITY FROM a USING t1 AS a, t1 AS b";
--source include/wait_condition.inc

connect (con_load, localhost, root);
--echo # Sending:
--send LOAD DATA LOW_PRIORITY INFILE '../../std_data/rpl_loaddata.dat' INTO TABLE t1 (@dummy,i);

connection default;
--echo # Check that LOAD DATA is blocked
let $wait_condition=
  select count(*) = 1 from information_schema.processlist
  where state = "Waiting for table metadata lock" and
        info = "LOAD DATA LOW_PRIORITY INFILE '../../std_data/rpl_loaddata.dat' INTO TABLE t1 (@dummy,i)";
--source include/wait_condition.inc

--echo #
--echo # This should work even for views.
--echo #
connect (con_view, localhost, root);
--echo # Sending:
--send DELETE LOW_PRIORITY FROM v1;

connection default;
--echo # Check that DELETE is blocked
let $wait_condition=
  select count(*) = 1 from information_schema.processlist
  where state = "Waiting for table metadata lock" and
        info = "DELETE LOW_PRIORITY FROM v1";
--source include/wait_condition.inc

--echo #
--echo # And when LOW_PRIORITY clause is used in trigger.
--echo # 
connect (con_trigger, localhost, root);
--echo # Sending:
--send INSERT INTO t2 VALUES (1);

connection default;
--echo # Check that INSERT in trigger is blocked
let $wait_condition=
  select count(*) = 1 from information_schema.processlist
  where state = "Waiting for table metadata lock" and
        info = "INSERT INTO t2 VALUES (1)";
--source include/wait_condition.inc

--echo #
--echo # And for MERGE tables
--echo #
connect (con_merge, localhost, root);
--echo # Sending:
--send DELETE LOW_PRIORITY FROM tm LIMIT 1;

connection default;
--echo # Check that DELETE from MERGE table is blocked
let $wait_condition=
  select count(*) = 1 from information_schema.processlist
  where state = "Waiting for table metadata lock" and
        info = "DELETE LOW_PRIORITY FROM tm LIMIT 1";
--source include/wait_condition.inc

--echo # Unblock LOCK TABLE .. READ
COMMIT;

connection blocker;
--echo # Reaping LOCK TABLE .. READ
--reap
UNLOCK TABLES;

--echo # Reap all DML statements.
connection con_insert;
--reap
connection con_replace;
--reap
connection con_update;
--reap
connection con_update_multi;
--reap
connection con_delete;
--reap
connection con_delete_multi;
--reap
connection con_load;
--reap
connection con_view;
--reap
connection con_trigger;
--reap
connection con_merge;
--reap
connection default;

--echo #
--echo # 2) Let us check that DML operations have lower priority than pending
--echo #    LOCK TABLE ... READ when @@low_priority_updates mode is on.
--echo #
--echo # Acquire SW lock on the table, to create pending LOCK TABLE ... READ.
BEGIN;
INSERT INTO t1 VALUES (0);

connection blocker;
--echo # Sending:
--send LOCK TABLE t1 READ;

connection default;
--echo # Wait until LOCK TABLE READ gets blocked
let $wait_condition=
  select count(*) = 1 from information_schema.processlist
  where state = "Waiting for table metadata lock" and
        info = "LOCK TABLE t1 READ";
--source include/wait_condition.inc

connection con_insert;
SET @@session.low_priority_updates= 1;
--echo # INSERT HIGH_PRIORITY still should not get blocked
INSERT HIGH_PRIORITY INTO t1 VALUES (1);

--echo # Sending:
--send INSERT INTO t1 VALUES (1);

connection default;
--echo # Check that INSERT is blocked
let $wait_condition=
  select count(*) = 1 from information_schema.processlist
  where state = "Waiting for table metadata lock" and
        info = "INSERT INTO t1 VALUES (1)";
--source include/wait_condition.inc

connection con_replace;
SET @@session.low_priority_updates= 1;
--echo # Sending:
--send REPLACE INTO t1 VALUES (1);

connection default;
--echo # Check that REPLACE is blocked
let $wait_condition=
  select count(*) = 1 from information_schema.processlist
  where state = "Waiting for table metadata lock" and
        info = "REPLACE INTO t1 VALUES (1)";
--source include/wait_condition.inc

connection con_update;
SET @@session.low_priority_updates= 1;
--echo # Sending:
--send UPDATE t1 SET i= 1;

connection default;
--echo # Check that UPDATE is blocked
let $wait_condition=
  select count(*) = 1 from information_schema.processlist
  where state = "Waiting for table metadata lock" and
        info = "UPDATE t1 SET i= 1";
--source include/wait_condition.inc

connection con_update_multi;
SET @@session.low_priority_updates= 1;
--echo # Sending:
--send UPDATE t1 AS a, t1 AS b SET a.i= 1;

connection default;
--echo # Check that multi-UPDATE is blocked
let $wait_condition=
  select count(*) = 1 from information_schema.processlist
  where state = "Waiting for table metadata lock" and
        info = "UPDATE t1 AS a, t1 AS b SET a.i= 1";
--source include/wait_condition.inc

connection con_delete;
SET @@session.low_priority_updates= 1;
--echo # Sending:
--send DELETE FROM t1 LIMIT 1;

connection default;
--echo # Check that DELETE is blocked
let $wait_condition=
  select count(*) = 1 from information_schema.processlist
  where state = "Waiting for table metadata lock" and
        info = "DELETE FROM t1 LIMIT 1";
--source include/wait_condition.inc

connection con_delete_multi;
SET @@session.low_priority_updates= 1;
--echo # Sending:
--send DELETE FROM a USING t1 AS a, t1 AS b;

connection default;
--echo # Check that multi-DELETE is blocked
let $wait_condition=
  select count(*) = 1 from information_schema.processlist
  where state = "Waiting for table metadata lock" and
        info = "DELETE FROM a USING t1 AS a, t1 AS b";
--source include/wait_condition.inc

connection con_load;
SET @@session.low_priority_updates= 1;
--echo # Sending:
--send LOAD DATA INFILE '../../std_data/rpl_loaddata.dat' INTO TABLE t1 (@dummy,i);

connection default;
--echo # Check that LOAD DATA is blocked
let $wait_condition=
  select count(*) = 1 from information_schema.processlist
  where state = "Waiting for table metadata lock" and
        info = "LOAD DATA INFILE '../../std_data/rpl_loaddata.dat' INTO TABLE t1 (@dummy,i)";
--source include/wait_condition.inc

connection con_view;
SET @@session.low_priority_updates= 1;
--echo # Sending:
--send DELETE FROM v1;

connection default;
--echo # Check that DELETE is blocked
let $wait_condition=
  select count(*) = 1 from information_schema.processlist
  where state = "Waiting for table metadata lock" and
        info = "DELETE FROM v1";
--source include/wait_condition.inc

--echo #
--echo # And when table used in trigger.
--echo # 
connection con_trigger;
SET @@session.low_priority_updates= 1;
--echo # Sending:
--send INSERT INTO t3 VALUES (1);

connection default;
--echo # Check that INSERT in trigger is blocked
let $wait_condition=
  select count(*) = 1 from information_schema.processlist
  where state = "Waiting for table metadata lock" and
        info = "INSERT INTO t3 VALUES (1)";
--source include/wait_condition.inc

--echo #
--echo # And for MERGE tables
--echo #
connection con_merge;
SET @@session.low_priority_updates= 1;
--echo # Sending:
--send DELETE FROM tm LIMIT 1;

connection default;
--echo # Check that DELETE from MERGE table is blocked
let $wait_condition=
  select count(*) = 1 from information_schema.processlist
  where state = "Waiting for table metadata lock" and
        info = "DELETE FROM tm LIMIT 1";
--source include/wait_condition.inc

--echo # Unblock LOCK TABLE .. READ
COMMIT;

connection blocker;
--echo # Reaping LOCK TABLE .. READ
--reap
UNLOCK TABLES;

--echo # Reap all DML statements.
connection con_insert;
--reap
connection con_replace;
--reap
connection con_update;
--reap
connection con_update_multi;
--reap
connection con_delete;
--reap
connection con_delete_multi;
--reap
connection con_load;
--reap
connection con_view;
--reap
connection con_trigger;
--reap
connection con_merge;
--reap

connection default;
disconnect blocker;
disconnect con_insert;
disconnect con_replace;
disconnect con_update;
disconnect con_update_multi;
disconnect con_delete;
disconnect con_delete_multi;
disconnect con_load;
disconnect con_view;
disconnect con_trigger;
disconnect con_merge;

DROP VIEW v1;
DROP TABLES tm, t2, t3, t1;
--disable_connect_log


--echo #
--echo # Test for bug #11764618 "DEADLOCK WHEN DDL UNDER LOCK TABLES
--echo #                         WRITE, READ + PREPARE".
--echo #
--enable_connect_log
connect (con1,localhost,root,,test,,);
connect (con2,localhost,root,,test,,);
connect (con3,localhost,root,,test,,);
connection default;

create table t1(i int);
create table t2(i int);
create table t3(i int);
create table t4(i int);

lock tables t1 write, t3 read;

connection con1;
begin;
select count(*) from t4;
--echo # Sending:
--send insert into t3 values (1);

connection con2;
--echo # Wait until 'con1' acquires SR metadata lock on 't4'
--echo # and blocks on 't3'. Before WL#6671 waiting has happened
--echo # on THR_LOCK lock which led to deadlock.
let $wait_condition=
  select count(*) = 1 from information_schema.processlist
  where state = "Waiting for table metadata lock" and
        info = "insert into t3 values (1)";
--source include/wait_condition.inc

--echo # Sending:
--send rename table t2 to t0, t4 to t2, t0 to t4;

connection con3;
--echo # Wait until RENAME acquires X metadata lock on 't2'
--echo # and blocks on 't4'.
let $wait_condition=
  select count(*) = 1 from information_schema.processlist
  where state = "Waiting for table metadata lock" and
        info = "rename table t2 to t0, t4 to t2, t0 to t4";
--source include/wait_condition.inc

--echo # Sending:
--send prepare stmt1 from 'select * from t1, t2';

connection default;
--echo # Wait until PREPARE acquires S metadata lock on 't1'
--echo # and blocks on 't2'.
let $wait_condition=
  select count(*) = 1 from information_schema.processlist
  where state = "Waiting for table metadata lock" and
        info = "PREPARE stmt1 FROM ...";
--source include/wait_condition.inc

--echo # This ALTER TABLE upgrades SNRW lock on t1 to X lock.
--echo # In the past this caused deadlock.
alter table t1 add column j int;

unlock tables;

connection con1;
--echo # Reap INSERT
--reap
commit;

connection con2;
--echo # Reap RENAME
--reap

connection con3;
--echo # Reap PREPARE
--reap

connection default;
disconnect con1;
disconnect con2;
disconnect con3;
drop tables t1, t2, t3, t4;

--disable_connect_log


# Wait till all disconnects are completed
--source include/wait_until_count_sessions.inc

Man Man