1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
|
DROP DATABASE IF EXISTS mysqltest;
DROP TABLE IF EXISTS t1, t2, t3, t4, v1;
DROP VIEW IF EXISTS t1, t2, t3, t4, v1;
DROP PROCEDURE IF EXISTS lock_t1_excl;
DROP PROCEDURE IF EXISTS count_t2;
DROP PROCEDURE IF EXISTS update_t2;
DROP TRIGGER IF EXISTS t1_ai;
#
# WL3561 - transactional LOCK TABLE - Syntax tests
# ================================================
CREATE TABLE t1 (c1 INT ) ENGINE=MyISAM;
CREATE TABLE t2 (c2 INT ) ENGINE=MyISAM;
CREATE TABLE t3 (c3 INT ) ENGINE=MyISAM;
#
# Valid syntax for non-transactional locks.
LOCK TABLE t1 READ, t2 WRITE;
UNLOCK TABLES;
LOCK TABLE t1 READ LOCAL, t2 LOW_PRIORITY WRITE;
UNLOCK TABLES;
#
# Valid syntax for transactional locks.
LOCK TABLE t1 IN SHARE MODE, t2 IN EXCLUSIVE MODE;
Warnings:
Warning 1613 Converted to non-transactional lock on 't1'
Warning 1613 Converted to non-transactional lock on 't2'
UNLOCK TABLES;
#
# Valid syntax for aliases with and without 'AS'.
LOCK TABLE t1 AS a1 READ, t2 a2 WRITE;
UNLOCK TABLES;
LOCK TABLE t1 AS a1 IN SHARE MODE, t2 a2 IN EXCLUSIVE MODE;
Warnings:
Warning 1613 Converted to non-transactional lock on 'a1'
Warning 1613 Converted to non-transactional lock on 'a2'
UNLOCK TABLES;
#
# Transactional locks taken on a view.
CREATE VIEW v1 AS SELECT * FROM t1, t2 WHERE t1.c1 = t2.c2;
LOCK TABLE v1 IN SHARE MODE;
Warnings:
Warning 1613 Converted to non-transactional lock on 't1'
Warning 1613 Converted to non-transactional lock on 't2'
LOCK TABLE v1 IN EXCLUSIVE MODE;
Warnings:
Warning 1613 Converted to non-transactional lock on 'v1'
DROP VIEW v1;
#
# Locking INFORMATION_SCHEMA fails on missing privileges.
LOCK TABLE information_schema.tables IN SHARE MODE;
ERROR 42000: Access denied for user 'root'@'localhost' to database 'information_schema'
LOCK TABLE information_schema.tables IN EXCLUSIVE MODE;
ERROR 42000: Access denied for user 'root'@'localhost' to database 'information_schema'
LOCK TABLE information_schema.tables READ;
ERROR 42000: Access denied for user 'root'@'localhost' to database 'information_schema'
LOCK TABLE information_schema.tables WRITE;
ERROR 42000: Access denied for user 'root'@'localhost' to database 'information_schema'
#
# The new keywords EXCLUSIVE and NOWAIT are not reserved words.
CREATE TABLE t4 (exclusive INT, nowait INT) ENGINE=MyISAM;
LOCK TABLE t4 WRITE;
DROP TABLE t4;
#
# Syntax errors for misspelled modes or left out symbols.
##-------------------------------------------------------
LOCK TABLE t1 IN SHARED MODE;
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'SHARED MODE' at line 1
LOCK TABLE t1 SHARE MODE;
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'MODE' at line 1
LOCK TABLE t1 IN SHARE;
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '' at line 1
LOCK TABLE t1 IN MODE;
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'MODE' at line 1
LOCK TABLE t1 READ NOWAIT, t2 WRITE NOWAIT;
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'NOWAIT, t2 WRITE NOWAIT' at line 1
LOCK TABLE t1 READ NOWAIT, t2 IN EXCLUSIVE MODE NOWAIT;
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'NOWAIT, t2 IN EXCLUSIVE MODE NOWAIT' at line 1
LOCK TABLE t1 IN SHARE MODE NOWAIT, t2 WRITE NOWAIT;
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'NOWAIT' at line 1
LOCK TABLE t1 IN SHARED MODE NOWAIT;
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'SHARED MODE NOWAIT' at line 1
LOCK TABLE t1 SHARE MODE NOWAIT;
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'MODE NOWAIT' at line 1
LOCK TABLE t1 IN SHARE NOWAIT;
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'NOWAIT' at line 1
LOCK TABLE t1 IN MODE NOWAIT;
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'MODE NOWAIT' at line 1
##----------------------
## End of syntax errors.
#
#
# WL3561 - transactional LOCK TABLE - Lock method conversion
# ==========================================================
#
# Implicit lock method conversion due to mix in statement.
LOCK TABLE t1 READ, t2 IN EXCLUSIVE MODE;
Warnings:
Warning 1613 Converted to non-transactional lock on 't2'
UNLOCK TABLES;
# Lock t1 share (converted to read), t2 write.
LOCK TABLE t1 IN SHARE MODE, t2 WRITE;
Warnings:
Warning 1613 Converted to non-transactional lock on 't1'
# Show t1 is read locked, t2 write locked.
INSERT INTO t1 SELECT * FROM t2;
ERROR HY000: Table 't1' was locked with a READ lock and can't be updated
INSERT INTO t2 SELECT * FROM t1;
#
# Implicit lock method conversion due to existing non-transact. locks.
# Implicitly unlock existing non-transactional locks and take new ones.
# Lock t1 exclusive (converted to write), t2 share (converted to read).
LOCK TABLE t1 IN EXCLUSIVE MODE, t2 IN SHARE MODE;
Warnings:
Warning 1613 Converted to non-transactional lock on 't1'
Warning 1613 Converted to non-transactional lock on 't2'
# Show t1 is write locked, t2 read locked.
INSERT INTO t1 SELECT * FROM t2;
INSERT INTO t2 SELECT * FROM t1;
ERROR HY000: Table 't2' was locked with a READ lock and can't be updated
UNLOCK TABLES;
#
# Reject lock method conversion in strict mode.
# Set strict mode.
SET @wl3561_save_sql_mode= @@SQL_MODE;
SET @@SQL_MODE= 'STRICT_ALL_TABLES';
# Try mixed mode locks.
LOCK TABLE t1 READ, t2 IN EXCLUSIVE MODE;
ERROR HY000: Cannot convert to non-transactional lock in strict mode on 't2'
LOCK TABLE t1 IN SHARE MODE, t2 WRITE;
ERROR HY000: Cannot convert to non-transactional lock in strict mode on 't1'
# Lock non-transactional.
LOCK TABLE t1 READ, t2 WRITE;
# Try transactional locks on top of the existing non-transactional locks.
LOCK TABLE t1 IN SHARE MODE, t2 IN EXCLUSIVE MODE;
ERROR HY000: Cannot convert to non-transactional lock in strict mode on 't1'
## Error is reported on first table only. Show both errors:
SHOW WARNINGS;
Level Code Message
Error 1614 Cannot convert to non-transactional lock in strict mode on 't1'
Error 1614 Cannot convert to non-transactional lock in strict mode on 't2'
UNLOCK TABLES;
SET @@SQL_MODE= @wl3561_save_sql_mode;
#
# Reject lock method conversion in an active transaction.
# Start transaction.
START TRANSACTION;
# Try mixed mode locks.
LOCK TABLE t1 READ, t2 IN EXCLUSIVE MODE;
ERROR HY000: Cannot convert to non-transactional lock in an active transaction on 't2'
LOCK TABLE t1 IN SHARE MODE, t2 WRITE;
ERROR HY000: Cannot convert to non-transactional lock in an active transaction on 't1'
COMMIT;
#
# Implicit lock method conversion for non-transactional storage engine.
# Create a non-transactional table.
CREATE TABLE t4 (c4 INT) ENGINE= MyISAM;
# Request a transactional lock, which is converted to non-transactional.
LOCK TABLE t4 IN SHARE MODE;
Warnings:
Warning 1613 Converted to non-transactional lock on 't4'
# Try a conflict with the existing non-transactional lock.
INSERT INTO t4 VALUES(444);
ERROR HY000: Table 't4' was locked with a READ lock and can't be updated
UNLOCK TABLES;
# Set strict mode.
SET @@SQL_MODE= 'STRICT_ALL_TABLES';
# Try a transactional lock, which would need a conversion.
LOCK TABLE t4 IN SHARE MODE;
ERROR HY000: Cannot convert to non-transactional lock in strict mode on 't4'
SET @@SQL_MODE= @wl3561_save_sql_mode;
#
# View with transactional and non-transactional storage engine.
CREATE VIEW v1 AS SELECT * FROM t3, t4 WHERE t3.c3 = t4.c4;
# Request a share lock on the view, which is converted to read locks.
LOCK TABLE v1 IN SHARE MODE;
Warnings:
Warning 1613 Converted to non-transactional lock on 't3'
Warning 1613 Converted to non-transactional lock on 't4'
# Show that read locks on the base tables prohibit writing ...
INSERT INTO t3 SELECT * FROM t4;
ERROR HY000: Table 't3' was locked with a READ lock and can't be updated
INSERT INTO t4 SELECT * FROM t3;
ERROR HY000: Table 't4' was locked with a READ lock and can't be updated
# ... but allow reading.
SELECT COUNT(*) FROM t3, t4 WHERE t3.c3 = t4.c4;
COUNT(*)
0
SELECT COUNT(*) FROM v1;
COUNT(*)
0
## Report conversion on view due to existing non-transactional locks.
LOCK TABLE v1 IN EXCLUSIVE MODE;
Warnings:
Warning 1613 Converted to non-transactional lock on 'v1'
INSERT INTO t3 VALUES(333);
INSERT INTO t4 VALUES(444);
INSERT INTO t1 VALUES(111);
ERROR HY000: Table 't1' was not locked with LOCK TABLES
UNLOCK TABLES;
## Now report conversion on base table again.
LOCK TABLE v1 IN EXCLUSIVE MODE;
Warnings:
Warning 1613 Converted to non-transactional lock on 't3'
Warning 1613 Converted to non-transactional lock on 't4'
INSERT INTO t3 VALUES(333);
INSERT INTO t4 VALUES(444);
INSERT INTO t1 VALUES(111);
ERROR HY000: Table 't1' was not locked with LOCK TABLES
UNLOCK TABLES;
DROP VIEW v1;
TRUNCATE t4;
#
# Insufficient privileges do not unlock tables nor end transactions.
# Prepare database, tables and an user with insufficient privileges.
# Make a new connection with this user.
CREATE DATABASE mysqltest;
CREATE TABLE mysqltest.t5 (c5 INT) ENGINE=MyISAM;
CREATE TABLE mysqltest.t6 (c6 INT) ENGINE=MyISAM;
CREATE USER mysqltest_1@localhost;
GRANT SELECT, INSERT ON mysqltest.* TO mysqltest_1@localhost;
# connection conn1.
# Show sufficient privileges to lock tables in the test database.
LOCK TABLE t1 READ, t2 WRITE;
# Show insufficient privileges in the mysqltest database.
LOCK TABLE mysqltest.t5 READ, mysqltest.t6 WRITE;
ERROR 42000: Access denied for user 'mysqltest_1'@'localhost' to database 'mysqltest'
# Show that the locks in 'test' still exist.
INSERT INTO t1 SELECT * FROM t2;
ERROR HY000: Table 't1' was locked with a READ lock and can't be updated
INSERT INTO t2 SELECT * FROM t1;
# Unlock tables.
UNLOCK TABLES;
# Start transaction.
START TRANSACTION;
# Insert a value.
INSERT INTO t1 VALUES(111);
# Try a lock that fails on privileges.
LOCK TABLE mysqltest.t5 READ;
ERROR 42000: Access denied for user 'mysqltest_1'@'localhost' to database 'mysqltest'
# Rollback transaction.
ROLLBACK;
Warnings:
Warning 1196 Some non-transactional changed tables couldn't be rolled back
# Show that the inserted value has gone.
SELECT * FROM t1;
c1
111
# Drop the connection with the unprivileged user.
# connection default.
#
# Sufficient privileges do unlock tables and end transactions.
# Grant sufficient privileges to the user.
# Make a new connection with this user.
GRANT SELECT, INSERT, LOCK TABLES ON mysqltest.* TO mysqltest_1@localhost;
# connection conn1.
# Lock tables in the test database.
LOCK TABLE t1 READ, t2 WRITE;
# Lock tables in the mysqltest database.
LOCK TABLE mysqltest.t5 READ, mysqltest.t6 WRITE;
# Show that the locks in 'test' have been replaced ...
INSERT INTO t1 SELECT * FROM t2;
ERROR HY000: Table 't1' was not locked with LOCK TABLES
INSERT INTO t2 SELECT * FROM t1;
ERROR HY000: Table 't2' was not locked with LOCK TABLES
# ... by the locks in 'mysqltest'.
INSERT INTO mysqltest.t5 SELECT * FROM mysqltest.t6;
ERROR HY000: Table 't5' was locked with a READ lock and can't be updated
INSERT INTO mysqltest.t6 SELECT * FROM mysqltest.t5;
# Unlock tables.
UNLOCK TABLES;
# Start transaction.
START TRANSACTION;
# Insert a value.
INSERT INTO t1 VALUES(111);
# Take a new lock.
LOCK TABLE mysqltest.t5 READ;
# Rollback transaction.
ROLLBACK;
UNLOCK TABLES;
# Show that the inserted value had been committed.
SELECT * FROM t1;
c1
111
111
TRUNCATE t1;
# connection default.
UNLOCK TABLES;
DROP USER mysqltest_1@localhost;
DROP DATABASE mysqltest;
DROP TABLE t1, t2, t3, t4;
#
# WL3594 - transactional LOCK TABLE Testing - Functional tests
# ============================================================
# Prepare tables and connections.
# Set AUTOCOMMIT= 0 in each connection.
SET AUTOCOMMIT= 0;
CREATE TABLE t1 (c1 INT) ENGINE=MyISAM;
CREATE TABLE t2 (c2 INT) ENGINE=MyISAM;
# connection conn1.
SET AUTOCOMMIT= 0;
# connection conn2.
SET AUTOCOMMIT= 0;
# connection default.
#
# Normal WRITE locks go before readers (autocommit).
# Set AUTOCOMMIT= 1.
SET AUTOCOMMIT= 1;
# Insert a value.
INSERT INTO t1 VALUES(111);
# Take a non-transactional lock.
LOCK TABLE t1 READ;
# connection conn1.
# Set AUTOCOMMIT= 1.
SET AUTOCOMMIT= 1;
# Take a non-transactional WRITE lock,
# which waits in background until first read lock is released.
LOCK TABLE t1 WRITE;
# connection default.
# Wait for the helper thread to sit on its lock.
# connection conn2.
# Set AUTOCOMMIT= 1.
SET AUTOCOMMIT= 1;
# Take a non-transactional READ lock,
# which waits in background until the WRITE lock is released.
LOCK TABLE t1 READ;
# connection default.
# Wait for the helper threads to sit on their locks.
# Unlock this connections non-transactional lock.
UNLOCK TABLES;
# connection conn1.
# Now the WRITE lock is taken.
# Insert a value.
INSERT INTO t1 VALUES(1111);
# Unlock table.
UNLOCK TABLES;
# connection conn2.
# Now the READ lock is taken.
# Select from the table.
SELECT * FROM t1;
c1
111
1111
# Unlock table.
UNLOCK TABLES;
# connection default.
TRUNCATE t1;
#
# LOW_PRIORITY WRITE locks wait for readers (autocommit).
# Insert a value.
INSERT INTO t1 VALUES(111);
# Take a non-transactional lock.
LOCK TABLE t1 READ;
# connection conn1.
# Take a non-transactional LOW_PRIORITY WRITE lock,
# which waits in background until all read locks are released.
LOCK TABLE t1 LOW_PRIORITY WRITE;
# connection default.
# Wait for the helper thread to sit on its lock.
# connection conn2.
# Take a non-transactional READ lock,
# which goes before the LOW_PRIORITY WRITE lock.
LOCK TABLE t1 READ;
# The READ lock could be taken immediately.
# Select from the table.
SELECT * FROM t1;
c1
111
# Unlock table.
UNLOCK TABLES;
SET AUTOCOMMIT= 0;
# connection default.
# Unlock this connections non-transactional lock.
UNLOCK TABLES;
# connection conn1.
# Now the LOW_PRIORITY WRITE lock is taken.
# Insert a value.
INSERT INTO t1 VALUES(1111);
# Unlock table.
UNLOCK TABLES;
SET AUTOCOMMIT= 0;
# connection default.
TRUNCATE t1;
SET AUTOCOMMIT= 0;
COMMIT;
#
# LOCK TABLE is prohibited in stored procedure.
CREATE PROCEDURE lock_t1_excl()
LOCK TABLE t1 IN EXCLUSIVE MODE;
ERROR 0A000: LOCK is not allowed in stored procedures
#
# LOCK TABLE is prohibited in trigger.
CREATE TRIGGER t1_ai AFTER INSERT ON t1 FOR EACH ROW
LOCK TABLE t2 IN EXCLUSIVE MODE;
ERROR 0A000: LOCK is not allowed in stored procedures
## Cleanup.
SET AUTOCOMMIT= 1;
UNLOCK TABLES;
DROP TABLE t1, t2;
|