mirror of
https://github.com/MariaDB/server.git
synced 2025-07-30 16:24:05 +03:00
BUG#18326: Do not lock table for writing during prepare of statement
During statement prepare phase the tables were locked as if the statement is being executed, however this is not necessary. The solution is to not lock tables on statement prepare phase. Opening tables is enough to prevent DDL on them, and during statement prepare we do not access nor modify any data.
This commit is contained in:
@ -2488,3 +2488,40 @@ execute stmt2 using @to_format, @dec;
|
||||
format(?, ?)
|
||||
10,000.00
|
||||
deallocate prepare stmt2;
|
||||
DROP TABLE IF EXISTS t1, t2;
|
||||
CREATE TABLE t1 (i INT);
|
||||
INSERT INTO t1 VALUES (1);
|
||||
CREATE TABLE t2 (i INT);
|
||||
INSERT INTO t2 VALUES (2);
|
||||
LOCK TABLE t1 READ, t2 WRITE;
|
||||
PREPARE stmt1 FROM "SELECT i FROM t1";
|
||||
PREPARE stmt2 FROM "INSERT INTO t2 (i) VALUES (3)";
|
||||
EXECUTE stmt1;
|
||||
i
|
||||
1
|
||||
EXECUTE stmt2;
|
||||
SELECT * FROM t2;
|
||||
i
|
||||
2
|
||||
UNLOCK TABLES;
|
||||
SELECT * FROM t2;
|
||||
i
|
||||
2
|
||||
3
|
||||
ALTER TABLE t1 ADD COLUMN j INT;
|
||||
ALTER TABLE t2 ADD COLUMN j INT;
|
||||
INSERT INTO t1 VALUES (4, 5);
|
||||
INSERT INTO t2 VALUES (4, 5);
|
||||
EXECUTE stmt1;
|
||||
i
|
||||
1
|
||||
4
|
||||
EXECUTE stmt2;
|
||||
SELECT * FROM t2;
|
||||
i j
|
||||
2 NULL
|
||||
3 NULL
|
||||
4 5
|
||||
3 NULL
|
||||
DROP TABLE t1, t2;
|
||||
End of 5.1 tests.
|
||||
|
@ -2516,3 +2516,60 @@ set @to_format="10000";
|
||||
execute stmt2 using @to_format, @dec;
|
||||
deallocate prepare stmt2;
|
||||
|
||||
|
||||
#
|
||||
# BUG#18326: Do not lock table for writing during prepare of statement
|
||||
#
|
||||
--disable_warnings
|
||||
DROP TABLE IF EXISTS t1, t2;
|
||||
--enable_warnings
|
||||
|
||||
CREATE TABLE t1 (i INT);
|
||||
INSERT INTO t1 VALUES (1);
|
||||
CREATE TABLE t2 (i INT);
|
||||
INSERT INTO t2 VALUES (2);
|
||||
|
||||
LOCK TABLE t1 READ, t2 WRITE;
|
||||
|
||||
connect (conn1, localhost, root, , );
|
||||
|
||||
# Prepare never acquires the lock, and thus should not block.
|
||||
PREPARE stmt1 FROM "SELECT i FROM t1";
|
||||
PREPARE stmt2 FROM "INSERT INTO t2 (i) VALUES (3)";
|
||||
|
||||
# This should not block because READ lock on t1 is shared.
|
||||
EXECUTE stmt1;
|
||||
|
||||
# This should block because WRITE lock on t2 is exclusive.
|
||||
send EXECUTE stmt2;
|
||||
|
||||
connection default;
|
||||
|
||||
SELECT * FROM t2;
|
||||
UNLOCK TABLES;
|
||||
let $wait_condition= SELECT COUNT(*) = 2 FROM t2;
|
||||
--source include/wait_condition.inc
|
||||
SELECT * FROM t2;
|
||||
|
||||
# DDL and DML works even if some client have a prepared statement
|
||||
# referencing the table.
|
||||
ALTER TABLE t1 ADD COLUMN j INT;
|
||||
ALTER TABLE t2 ADD COLUMN j INT;
|
||||
INSERT INTO t1 VALUES (4, 5);
|
||||
INSERT INTO t2 VALUES (4, 5);
|
||||
|
||||
connection conn1;
|
||||
|
||||
reap;
|
||||
EXECUTE stmt1;
|
||||
EXECUTE stmt2;
|
||||
SELECT * FROM t2;
|
||||
|
||||
disconnect conn1;
|
||||
|
||||
connection default;
|
||||
|
||||
DROP TABLE t1, t2;
|
||||
|
||||
|
||||
--echo End of 5.1 tests.
|
||||
|
Reference in New Issue
Block a user