~drizzle-trunk/drizzle/development

1 by brian
clean slate
1
# include/locktrans.inc
2
#
3
# Transactional LOCK TABLE tests
4
5
# eval SET SESSION STORAGE_ENGINE = $engine_type;
6
7
--disable_warnings
8
DROP DATABASE  IF EXISTS mysqltest;
9
DROP TABLE     IF EXISTS t1, t2, t3, t4, v1;
10
DROP VIEW      IF EXISTS t1, t2, t3, t4, v1;
11
DROP PROCEDURE IF EXISTS lock_t1_excl;
12
DROP PROCEDURE IF EXISTS count_t2;
13
DROP PROCEDURE IF EXISTS update_t2;
14
DROP TRIGGER   IF EXISTS t1_ai;
15
--enable_warnings
16
17
--echo #
18
--echo # WL3561 - transactional LOCK TABLE - Syntax tests
19
--echo # ================================================
20
#
21
eval CREATE TABLE t1 (c1 INT ) ENGINE=$engine_type;
22
eval CREATE TABLE t2 (c2 INT ) ENGINE=$engine_type;
23
eval CREATE TABLE t3 (c3 INT ) ENGINE=$engine_type;
24
#
25
--echo #
26
--echo # Valid syntax for non-transactional locks.
27
LOCK TABLE t1 READ, t2 WRITE;
28
UNLOCK TABLES;
29
LOCK TABLE t1 READ LOCAL, t2 LOW_PRIORITY WRITE;
30
UNLOCK TABLES;
31
#
32
--echo #
33
--echo # Valid syntax for transactional locks.
34
LOCK TABLE t1 IN SHARE MODE, t2 IN EXCLUSIVE MODE;
35
UNLOCK TABLES;
36
#
37
if ($nowait_support)
38
{
39
--echo #
40
--echo # Valid syntax for transactional locks with NOWAIT option.
41
--echo ## In the preliminary reference implementation we expect these errors:
42
--echo ## NOWAIT+SHARE="timed out", NOWAIT+EXCLUSIVE="not supported".
43
--echo ## Statements abort on first error.
44
--error ER_LOCK_WAIT_TIMEOUT
45
LOCK TABLE t1 IN SHARE MODE NOWAIT, t2 IN EXCLUSIVE MODE NOWAIT;
46
--error ER_UNSUPPORTED_EXTENSION
47
LOCK TABLE t1 IN EXCLUSIVE MODE NOWAIT, t2 IN SHARE MODE NOWAIT;
48
--error ER_LOCK_WAIT_TIMEOUT
49
LOCK TABLE t1 IN EXCLUSIVE MODE, t2 IN SHARE MODE NOWAIT;
50
}
51
#
52
--echo #
53
--echo # Valid syntax for aliases with and without 'AS'.
54
LOCK TABLE t1 AS a1 READ, t2 a2 WRITE;
55
UNLOCK TABLES;
56
LOCK TABLE t1 AS a1 IN SHARE MODE, t2 a2 IN EXCLUSIVE MODE;
57
UNLOCK TABLES;
58
#
59
--echo #
60
--echo # Transactional locks taken on a view.
61
CREATE VIEW v1 AS SELECT * FROM t1, t2 WHERE t1.c1 = t2.c2;
62
LOCK TABLE v1 IN SHARE MODE;
63
LOCK TABLE v1 IN EXCLUSIVE MODE;
64
DROP VIEW v1;
65
#
66
--echo #
67
--echo # Locking INFORMATION_SCHEMA fails on missing privileges.
68
--error ER_DBACCESS_DENIED_ERROR
69
LOCK TABLE information_schema.tables IN SHARE MODE;
70
--error ER_DBACCESS_DENIED_ERROR
71
LOCK TABLE information_schema.tables IN EXCLUSIVE MODE;
72
--error ER_DBACCESS_DENIED_ERROR
73
LOCK TABLE information_schema.tables READ;
74
--error ER_DBACCESS_DENIED_ERROR
75
LOCK TABLE information_schema.tables WRITE;
76
#
77
--echo #
78
--echo # The new keywords EXCLUSIVE and NOWAIT are not reserved words.
79
eval CREATE TABLE t4 (exclusive INT, nowait INT) ENGINE=$engine_type;
80
LOCK TABLE t4 WRITE;
81
DROP TABLE t4;
82
#
83
--echo #
84
--echo # Syntax errors for misspelled modes or left out symbols.
85
--echo ##-------------------------------------------------------
86
--error ER_PARSE_ERROR
87
LOCK TABLE t1 IN SHARED MODE;
88
--error ER_PARSE_ERROR
89
LOCK TABLE t1 SHARE MODE;
90
--error ER_PARSE_ERROR
91
LOCK TABLE t1 IN SHARE;
92
--error ER_PARSE_ERROR
93
LOCK TABLE t1 IN MODE;
94
--error ER_PARSE_ERROR
95
LOCK TABLE t1 READ NOWAIT, t2 WRITE NOWAIT;
96
--error ER_PARSE_ERROR
97
LOCK TABLE t1 READ NOWAIT, t2 IN EXCLUSIVE MODE NOWAIT;
98
--error ER_PARSE_ERROR
99
LOCK TABLE t1 IN SHARE MODE NOWAIT, t2 WRITE NOWAIT;
100
--error ER_PARSE_ERROR
101
LOCK TABLE t1 IN SHARED MODE NOWAIT;
102
--error ER_PARSE_ERROR
103
LOCK TABLE t1 SHARE MODE NOWAIT;
104
--error ER_PARSE_ERROR
105
LOCK TABLE t1 IN SHARE NOWAIT;
106
--error ER_PARSE_ERROR
107
LOCK TABLE t1 IN MODE NOWAIT;
108
--echo ##----------------------
109
--echo ## End of syntax errors.
110
#
111
--echo #
112
--echo #
113
--echo # WL3561 - transactional LOCK TABLE - Lock method conversion
114
--echo # ==========================================================
115
--echo #
116
--echo # Implicit lock method conversion due to mix in statement.
117
LOCK TABLE t1 READ, t2 IN EXCLUSIVE MODE;
118
UNLOCK TABLES;
119
--echo # Lock t1 share (converted to read), t2 write.
120
LOCK TABLE t1 IN SHARE MODE, t2 WRITE;
121
--echo # Show t1 is read locked, t2 write locked.
122
--error ER_TABLE_NOT_LOCKED_FOR_WRITE
123
INSERT INTO t1 SELECT * FROM t2;
124
INSERT INTO t2 SELECT * FROM t1;
125
#
126
--echo #
127
--echo # Implicit lock method conversion due to existing non-transact. locks.
128
--echo # Implicitly unlock existing non-transactional locks and take new ones.
129
--echo # Lock t1 exclusive (converted to write), t2 share (converted to read).
130
LOCK TABLE t1 IN EXCLUSIVE MODE, t2 IN SHARE MODE;
131
--echo # Show t1 is write locked, t2 read locked.
132
INSERT INTO t1 SELECT * FROM t2;
133
--error ER_TABLE_NOT_LOCKED_FOR_WRITE
134
INSERT INTO t2 SELECT * FROM t1;
135
UNLOCK TABLES;
136
#
137
--echo #
138
--echo # Reject lock method conversion in strict mode.
139
--echo # Set strict mode.
140
SET @wl3561_save_sql_mode= @@SQL_MODE;
141
SET @@SQL_MODE= 'STRICT_ALL_TABLES';
142
--echo # Try mixed mode locks.
143
--error ER_NO_AUTO_CONVERT_LOCK_STRICT
144
LOCK TABLE t1 READ, t2 IN EXCLUSIVE MODE;
145
--error ER_NO_AUTO_CONVERT_LOCK_STRICT
146
LOCK TABLE t1 IN SHARE MODE, t2 WRITE;
147
--echo # Lock non-transactional.
148
LOCK TABLE t1 READ, t2 WRITE;
149
--echo # Try transactional locks on top of the existing non-transactional locks.
150
--error ER_NO_AUTO_CONVERT_LOCK_STRICT
151
LOCK TABLE t1 IN SHARE MODE, t2 IN EXCLUSIVE MODE;
152
--echo ## Error is reported on first table only. Show both errors:
153
SHOW WARNINGS;
154
UNLOCK TABLES;
155
SET @@SQL_MODE= @wl3561_save_sql_mode;
156
#
157
--echo #
158
--echo # Reject lock method conversion in an active transaction.
159
--echo # Start transaction.
160
START TRANSACTION;
161
--echo # Try mixed mode locks.
162
--error ER_NO_AUTO_CONVERT_LOCK_TRANSACTION
163
LOCK TABLE t1 READ, t2 IN EXCLUSIVE MODE;
164
--error ER_NO_AUTO_CONVERT_LOCK_TRANSACTION
165
LOCK TABLE t1 IN SHARE MODE, t2 WRITE;
166
COMMIT;
167
#
168
--echo #
169
--echo # Implicit lock method conversion for non-transactional storage engine.
170
--echo # Create a non-transactional table.
171
eval CREATE TABLE t4 (c4 INT) ENGINE= $other_non_trans_engine_type;
172
--echo # Request a transactional lock, which is converted to non-transactional.
173
LOCK TABLE t4 IN SHARE MODE;
174
--echo # Try a conflict with the existing non-transactional lock.
175
--error ER_TABLE_NOT_LOCKED_FOR_WRITE
176
INSERT INTO t4 VALUES(444);
177
UNLOCK TABLES;
178
--echo # Set strict mode.
179
SET @@SQL_MODE= 'STRICT_ALL_TABLES';
180
--echo # Try a transactional lock, which would need a conversion.
181
--error ER_NO_AUTO_CONVERT_LOCK_STRICT
182
LOCK TABLE t4 IN SHARE MODE;
183
SET @@SQL_MODE= @wl3561_save_sql_mode;
184
#
185
--echo #
186
--echo # View with transactional and non-transactional storage engine.
187
CREATE VIEW v1 AS SELECT * FROM t3, t4 WHERE t3.c3 = t4.c4;
188
--echo # Request a share lock on the view, which is converted to read locks.
189
LOCK TABLE v1 IN SHARE MODE;
190
--echo # Show that read locks on the base tables prohibit writing ...
191
--error ER_TABLE_NOT_LOCKED_FOR_WRITE
192
INSERT INTO t3 SELECT * FROM t4;
193
--error ER_TABLE_NOT_LOCKED_FOR_WRITE
194
INSERT INTO t4 SELECT * FROM t3;
195
--echo # ... but allow reading.
196
SELECT COUNT(*) FROM t3, t4 WHERE t3.c3 = t4.c4;
197
SELECT COUNT(*) FROM v1;
198
--echo ## Report conversion on view due to existing non-transactional locks.
199
LOCK TABLE v1 IN EXCLUSIVE MODE;
200
INSERT INTO t3 VALUES(333);
201
INSERT INTO t4 VALUES(444);
202
--error ER_TABLE_NOT_LOCKED
203
INSERT INTO t1 VALUES(111);
204
UNLOCK TABLES;
205
--echo ## Now report conversion on base table again.
206
LOCK TABLE v1 IN EXCLUSIVE MODE;
207
INSERT INTO t3 VALUES(333);
208
INSERT INTO t4 VALUES(444);
209
--error ER_TABLE_NOT_LOCKED
210
INSERT INTO t1 VALUES(111);
211
UNLOCK TABLES;
212
DROP VIEW v1;
213
TRUNCATE t4;
214
#
215
--echo #
216
--echo # Insufficient privileges do not unlock tables nor end transactions.
217
--echo # Prepare database, tables and an user with insufficient privileges.
218
--echo # Make a new connection with this user.
219
CREATE DATABASE mysqltest;
220
eval CREATE TABLE mysqltest.t5 (c5 INT) ENGINE=$engine_type;
221
eval CREATE TABLE mysqltest.t6 (c6 INT) ENGINE=$engine_type;
222
CREATE USER mysqltest_1@localhost;
223
GRANT SELECT, INSERT ON mysqltest.* TO mysqltest_1@localhost;
224
connect (conn1,localhost,mysqltest_1,,);
225
    --echo # connection conn1.
226
    connection conn1;
227
    --echo # Show sufficient privileges to lock tables in the test database.
228
    LOCK TABLE t1 READ, t2 WRITE;
229
    --echo # Show insufficient privileges in the mysqltest database.
230
    --error ER_DBACCESS_DENIED_ERROR
231
    LOCK TABLE mysqltest.t5 READ, mysqltest.t6 WRITE;
232
    --echo # Show that the locks in 'test' still exist.
233
    --error ER_TABLE_NOT_LOCKED_FOR_WRITE
234
    INSERT INTO t1 SELECT * FROM t2;
235
    INSERT INTO t2 SELECT * FROM t1;
236
    --echo # Unlock tables.
237
    UNLOCK TABLES;
238
    --echo # Start transaction.
239
    START TRANSACTION;
240
    --echo # Insert a value.
241
    INSERT INTO t1 VALUES(111);
242
    --echo # Try a lock that fails on privileges.
243
    --error ER_DBACCESS_DENIED_ERROR
244
    LOCK TABLE mysqltest.t5 READ;
245
    --echo # Rollback transaction.
246
    ROLLBACK;
247
    --echo # Show that the inserted value has gone.
248
    SELECT * FROM t1;
249
    --echo # Drop the connection with the unprivileged user.
250
    disconnect conn1;
251
--echo # connection default.
252
connection default;
253
--echo #
254
--echo # Sufficient privileges do unlock tables and end transactions.
255
--echo # Grant sufficient privileges to the user.
256
--echo # Make a new connection with this user.
257
GRANT SELECT, INSERT, LOCK TABLES ON mysqltest.* TO mysqltest_1@localhost;
258
connect (conn1,localhost,mysqltest_1,,);
259
    --echo # connection conn1.
260
    connection conn1;
261
    --echo # Lock tables in the test database.
262
    LOCK TABLE t1 READ, t2 WRITE;
263
    --echo # Lock tables in the mysqltest database.
264
    LOCK TABLE mysqltest.t5 READ, mysqltest.t6 WRITE;
265
    --echo # Show that the locks in 'test' have been replaced ...
266
    --error ER_TABLE_NOT_LOCKED
267
    INSERT INTO t1 SELECT * FROM t2;
268
    --error ER_TABLE_NOT_LOCKED
269
    INSERT INTO t2 SELECT * FROM t1;
270
    --echo # ... by the locks in 'mysqltest'.
271
    --error ER_TABLE_NOT_LOCKED_FOR_WRITE
272
    INSERT INTO mysqltest.t5 SELECT * FROM mysqltest.t6;
273
    INSERT INTO mysqltest.t6 SELECT * FROM mysqltest.t5;
274
    --echo # Unlock tables.
275
    UNLOCK TABLES;
276
    --echo # Start transaction.
277
    START TRANSACTION;
278
    --echo # Insert a value.
279
    INSERT INTO t1 VALUES(111);
280
    --echo # Take a new lock.
281
    LOCK TABLE mysqltest.t5 READ;
282
    --echo # Rollback transaction.
283
    ROLLBACK;
284
    UNLOCK TABLES;
285
    --echo # Show that the inserted value had been committed.
286
    SELECT * FROM t1;
287
    TRUNCATE t1;
288
    disconnect conn1;
289
--echo # connection default.
290
connection default;
291
#
292
UNLOCK TABLES;
293
DROP USER mysqltest_1@localhost;
294
DROP DATABASE mysqltest;
295
DROP TABLE t1, t2, t3, t4;
296
#
297
# Overcome timing problems DROP t1 -> CREATE t1 (*locktrans_myisam).
298
--sleep 0.1
299
#
300
--echo #
301
--echo # WL3594 - transactional LOCK TABLE Testing - Functional tests
302
--echo # ============================================================
303
#
304
--echo # Prepare tables and connections.
305
--echo # Set AUTOCOMMIT= 0 in each connection.
306
SET AUTOCOMMIT= 0;
307
eval CREATE TABLE t1 (c1 INT) ENGINE=$engine_type;
308
eval CREATE TABLE t2 (c2 INT) ENGINE=$engine_type;
309
connect (conn1,localhost,root,,);
310
    --echo # connection conn1.
311
    connection conn1;
312
    SET AUTOCOMMIT= 0;
313
connect (conn2,localhost,root,,);
314
        --echo # connection conn2.
315
        connection conn2;
316
        SET AUTOCOMMIT= 0;
317
--echo # connection default.
318
connection default;
319
#
320
321
if ($transactional)
322
{
323
--echo #
324
--echo # Transactional lock behaviour:
325
--echo # LOCK TABLE does _not_ commit a transaction.
326
--echo # Insert a value.
327
INSERT INTO t1 VALUES (111);
328
--echo # Lock transactional.
329
LOCK TABLE t1 IN EXCLUSIVE MODE;
330
--echo # Rollback.
331
ROLLBACK;
332
--echo # Show that the inserted value has gone.
333
SELECT * FROM t1;
334
--echo #
335
--echo # After LOCK TABLE one can access tables not mentioned in LOCK TABLE.
336
--echo # Lock t1 transactional.
337
LOCK TABLE t1 IN EXCLUSIVE MODE;
338
--echo # Insert a value into t2.
339
INSERT INTO t2 VALUES (222);
340
--echo # Show that the inserted value is indeed in the table.
341
SELECT * FROM t2;
342
--echo #
343
--echo # One can issue LOCK TABLE many times, adding more tables.
344
--echo # Lock t2 transactional.
345
LOCK TABLE t2 IN EXCLUSIVE MODE;
346
--echo #
347
--echo # LOCK TABLE does not rollback a transaction.
348
--echo # Show that the inserted value is still in the table.
349
SELECT * FROM t2;
350
--echo # Rollback transaction.
351
ROLLBACK;
352
--echo # Show that the inserted value has gone.
353
SELECT * FROM t2;
354
--echo #
355
--echo # Tables are unlocked at the end of transaction (commit).
356
--echo # Take an exclusive lock.
357
LOCK TABLE t1 IN EXCLUSIVE MODE;
358
--echo # Commit.
359
COMMIT;
360
    --echo # connection conn1.
361
    connection conn1;
362
    --echo # Take an exclusive lock.
363
    --echo # This would fail after timeout if t1 is still locked.
364
    LOCK TABLE t1 IN EXCLUSIVE MODE;
365
    --echo # Commit.
366
    COMMIT;
367
--echo # connection default.
368
connection default;
369
--echo #
370
--echo # Tables are unlocked at the end of transaction (rollback).
371
--echo # Take an exclusive lock.
372
LOCK TABLE t1 IN EXCLUSIVE MODE;
373
--echo # Rollback.
374
ROLLBACK;
375
    --echo # connection conn1.
376
    connection conn1;
377
    --echo # Take an exclusive lock.
378
    --echo # This would fail after timeout if t1 is still locked.
379
    LOCK TABLE t1 IN EXCLUSIVE MODE;
380
    --echo # Rollback.
381
    ROLLBACK;
382
--echo # connection default.
383
connection default;
384
--echo #
385
--echo # UNLOCK TABLES does not touch a transaction when
386
--echo # no non-transactional table locks exist.
387
--echo # Take a transactional lock.
388
LOCK TABLE t1 IN EXCLUSIVE MODE;
389
--echo # Insert a value.
390
INSERT INTO t1 VALUES(111);
391
--echo # Unlock (non-transactional) table locks.
392
UNLOCK TABLES;
393
--echo # Show that the inserted value is still in the table.
394
SELECT * FROM t1;
395
--echo # Rollback.
396
ROLLBACK;
397
--echo # Show that the inserted value has gone.
398
SELECT * FROM t1;
399
--echo #
400
--echo # UNLOCK TABLES commits a transaction when
401
--echo # non-transactional table locks exist.
402
--echo # Take a non-transactional lock.
403
LOCK TABLE t1 WRITE;
404
--echo # Insert a value.
405
INSERT INTO t1 VALUES(111);
406
--echo # Unlock (non-transactional) table locks.
407
UNLOCK TABLES;
408
--echo # Show that the inserted value is still in the table.
409
SELECT * FROM t1;
410
--echo # Rollback.
411
ROLLBACK;
412
--echo # Show that the inserted value is still in the table.
413
SELECT * FROM t1;
414
TRUNCATE t1;
415
--echo #
416
--echo # START TRANSACTION removes a previous lock.
417
--echo # Take an exclusive lock.
418
LOCK TABLE t1 IN EXCLUSIVE MODE;
419
--echo # Start transaction.
420
START TRANSACTION;
421
    --echo # connection conn1.
422
    connection conn1;
423
    --echo # Take an exclusive lock.
424
    --echo # This would fail after timeout if t1 is still locked.
425
    LOCK TABLE t1 IN EXCLUSIVE MODE;
426
    COMMIT;
427
--echo # connection default.
428
connection default;
429
COMMIT;
430
--echo #
431
--echo # With Auto commit on, transactional locks will be ignored
432
--echo # Set AUTOCOMMIT= 1.
433
SET AUTOCOMMIT= 1;
434
--echo # Take an exclusive lock.
435
LOCK TABLE t1 IN EXCLUSIVE MODE;
436
    --echo # connection conn1.
437
    connection conn1;
438
    --echo # Set AUTOCOMMIT= 1.
439
    SET AUTOCOMMIT= 1;
440
    --echo # Take an exclusive lock.
441
    --echo # This would fail after timeout if t1 is still locked.
442
    LOCK TABLE t1 IN SHARE MODE;
443
    SET AUTOCOMMIT= 0;
444
    COMMIT;
445
--echo # connection default.
446
connection default;
447
UNLOCK TABLES;
448
SET AUTOCOMMIT= 0;
449
COMMIT;
450
--echo #
451
--echo # With Auto commit on, transactional locks can time out.
452
--echo # Default connection runs in transactional mode.
453
--echo # Set AUTOCOMMIT= 0.
454
SET AUTOCOMMIT= 0;
455
--echo # Take an exclusive lock, which persists.
456
LOCK TABLE t1 IN EXCLUSIVE MODE;
457
    --echo # connection conn1.
458
    connection conn1;
459
    --echo # conn1 runs in autocommit mode.
460
    --echo # Set AUTOCOMMIT= 1.
461
    SET AUTOCOMMIT= 1;
462
    --echo # Try an exclusive lock,
463
    --echo # which times out though running in autocommit mode.
464
    --error ER_LOCK_WAIT_TIMEOUT
465
    LOCK TABLE t1 IN SHARE MODE;
466
    SET AUTOCOMMIT= 0;
467
    COMMIT;
468
--echo # connection default.
469
connection default;
470
UNLOCK TABLES;
471
SET AUTOCOMMIT= 0;
472
COMMIT;
473
#
474
} 
475
476
--echo #
477
--echo # Normal WRITE locks go before readers (autocommit).
478
--echo # Set AUTOCOMMIT= 1.
479
SET AUTOCOMMIT= 1;
480
--echo # Insert a value.
481
INSERT INTO t1 VALUES(111);
482
--echo # Take a non-transactional lock.
483
LOCK TABLE t1 READ;
484
    --echo # connection conn1.
485
    connection conn1;
486
    --echo # Set AUTOCOMMIT= 1.
487
    SET AUTOCOMMIT= 1;
488
    --echo # Take a non-transactional WRITE lock,
489
    --echo # which waits in background until first read lock is released.
490
    send LOCK TABLE t1 WRITE;
491
--echo # connection default.
492
connection default;
493
--echo # Wait for the helper thread to sit on its lock.
494
while (`SELECT COUNT(*) < 1 FROM INFORMATION_SCHEMA.PROCESSLIST
495
        WHERE STATE LIKE '%lock%'`)
496
{
497
  --sleep 0.1
498
}
499
        --echo # connection conn2.
500
        connection conn2;
501
        --echo # Set AUTOCOMMIT= 1.
502
        SET AUTOCOMMIT= 1;
503
        --echo # Take a non-transactional READ lock,
504
        --echo # which waits in background until the WRITE lock is released.
505
        send LOCK TABLE t1 READ;
506
--echo # connection default.
507
connection default;
508
--echo # Wait for the helper threads to sit on their locks.
509
while (`SELECT COUNT(*) < 2 FROM INFORMATION_SCHEMA.PROCESSLIST
510
        WHERE STATE LIKE '%lock%'`)
511
{
512
  --sleep 0.1
513
}
514
--echo # Unlock this connections non-transactional lock.
515
UNLOCK TABLES;
516
    --echo # connection conn1.
517
    connection conn1;
518
    --echo # Now the WRITE lock is taken.
519
    reap;
520
    --echo # Insert a value.
521
    INSERT INTO t1 VALUES(1111);
522
    --echo # Unlock table.
523
    UNLOCK TABLES;
524
        --echo # connection conn2.
525
        connection conn2;
526
        --echo # Now the READ lock is taken.
527
        reap;
528
        --echo # Select from the table.
529
        SELECT * FROM t1;
530
        --echo # Unlock table.
531
        UNLOCK TABLES;
532
--echo # connection default.
533
connection default;
534
TRUNCATE t1;
535
--echo #
536
--echo # LOW_PRIORITY WRITE locks wait for readers (autocommit).
537
--echo # Insert a value.
538
INSERT INTO t1 VALUES(111);
539
--echo # Take a non-transactional lock.
540
LOCK TABLE t1 READ;
541
    --echo # connection conn1.
542
    connection conn1;
543
    --echo # Take a non-transactional LOW_PRIORITY WRITE lock,
544
    --echo # which waits in background until all read locks are released.
545
    send LOCK TABLE t1 LOW_PRIORITY WRITE;
546
--echo # connection default.
547
connection default;
548
--echo # Wait for the helper thread to sit on its lock.
549
while (`SELECT COUNT(*) < 1 FROM INFORMATION_SCHEMA.PROCESSLIST
550
        WHERE STATE LIKE '%lock%'`)
551
{
552
  --sleep 0.1
553
}
554
        --echo # connection conn2.
555
        connection conn2;
556
        --echo # Take a non-transactional READ lock,
557
        --echo # which goes before the LOW_PRIORITY WRITE lock.
558
        LOCK TABLE t1 READ;
559
        --echo # The READ lock could be taken immediately.
560
        --echo # Select from the table.
561
        SELECT * FROM t1;
562
        --echo # Unlock table.
563
        UNLOCK TABLES;
564
        SET AUTOCOMMIT= 0;
565
--echo # connection default.
566
connection default;
567
--echo # Unlock this connections non-transactional lock.
568
UNLOCK TABLES;
569
    --echo # connection conn1.
570
    connection conn1;
571
    --echo # Now the LOW_PRIORITY WRITE lock is taken.
572
    reap;
573
    --echo # Insert a value.
574
    INSERT INTO t1 VALUES(1111);
575
    --echo # Unlock table.
576
    UNLOCK TABLES;
577
    SET AUTOCOMMIT= 0;
578
--echo # connection default.
579
connection default;
580
TRUNCATE t1;
581
SET AUTOCOMMIT= 0;
582
COMMIT;
583
584
if ($transactional) 
585
{
586
--echo #
587
--echo # Normal WRITE locks go before readers (transaction).
588
--echo # Insert a value.
589
INSERT INTO t1 VALUES(111);
590
COMMIT;
591
--echo # Take a non-transactional lock.
592
LOCK TABLE t1 READ;
593
    --echo # connection conn1.
594
    connection conn1;
595
    --echo # Take a non-transactional WRITE lock,
596
    --echo # which waits in background until first read lock is released.
597
    send LOCK TABLE t1 WRITE;
598
--echo # connection default.
599
connection default;
600
--echo # Wait for the helper thread to sit on its lock.
601
while (`SELECT COUNT(*) < 1 FROM INFORMATION_SCHEMA.PROCESSLIST
602
        WHERE STATE LIKE '%lock%'`)
603
{
604
  --sleep 0.1
605
}
606
        --echo # connection conn2.
607
        connection conn2;
608
        --echo # Take a non-transactional READ lock,
609
        --echo # which waits in background until the WRITE lock is released.
610
        send LOCK TABLE t1 READ;
611
--echo # connection default.
612
connection default;
613
--echo # Wait for the helper threads to sit on their locks.
614
while (`SELECT COUNT(*) < 2 FROM INFORMATION_SCHEMA.PROCESSLIST
615
        WHERE STATE LIKE '%lock%'`)
616
{
617
  --sleep 0.1
618
}
619
--echo # Unlock this connections non-transactional lock.
620
UNLOCK TABLES;
621
    --echo # connection conn1.
622
    connection conn1;
623
    --echo # Now the WRITE lock is taken.
624
    reap;
625
    --echo # Insert a value.
626
    INSERT INTO t1 VALUES(1111);
627
    --echo # Unlock table.
628
    UNLOCK TABLES;
629
        --echo # connection conn2.
630
        connection conn2;
631
        --echo # Now the READ lock is taken.
632
        reap;
633
        --echo # Select from the table.
634
        SELECT * FROM t1;
635
        --echo # Unlock table.
636
        UNLOCK TABLES;
637
--echo # connection default.
638
connection default;
639
TRUNCATE t1;
640
COMMIT;
641
--echo #
642
--echo # LOW_PRIORITY WRITE behaves like WRITE in transaction mode.
643
--echo # Insert a value.
644
INSERT INTO t1 VALUES(111);
645
COMMIT;
646
--echo # Take a non-transactional lock.
647
LOCK TABLE t1 READ;
648
    --echo # connection conn1.
649
    connection conn1;
650
    --echo # Take a non-transactional LOW_PRIORITY WRITE lock,
651
    --echo # which waits in background until first read lock is released.
652
    send LOCK TABLE t1 LOW_PRIORITY WRITE;
653
--echo # connection default.
654
connection default;
655
--echo # Wait for the helper thread to sit on its lock.
656
while (`SELECT COUNT(*) < 1 FROM INFORMATION_SCHEMA.PROCESSLIST
657
        WHERE STATE LIKE '%lock%'`)
658
{
659
  --sleep 0.1
660
}
661
        --echo # connection conn2.
662
        connection conn2;
663
        --echo # Take a non-transactional READ lock,
664
        --echo # which waits in background for the LOW_PRIORITY WRITE lock.
665
        send LOCK TABLE t1 READ;
666
--echo # connection default.
667
connection default;
668
--echo # Wait for the helper threads to sit on their locks.
669
while (`SELECT COUNT(*) < 2 FROM INFORMATION_SCHEMA.PROCESSLIST
670
        WHERE STATE LIKE '%lock%'`)
671
{
672
  --sleep 0.1
673
}
674
--echo # Unlock this connections non-transactional lock.
675
UNLOCK TABLES;
676
    --echo # connection conn1.
677
    connection conn1;
678
    --echo # Now the LOW_PRIORITY WRITE lock is taken.
679
    reap;
680
    --echo # Insert a value.
681
    INSERT INTO t1 VALUES(1111);
682
    --echo # Unlock table.
683
    UNLOCK TABLES;
684
        --echo # connection conn2.
685
        connection conn2;
686
        --echo # Now the READ lock is taken.
687
        reap;
688
        --echo # Select from the table.
689
        SELECT * FROM t1;
690
        --echo # Unlock table.
691
        UNLOCK TABLES;
692
--echo # connection default.
693
connection default;
694
TRUNCATE t1;
695
COMMIT;
696
#
697
}
698
699
if ($nowait_support)
700
{
701
--echo #
702
--echo # NOWAIT.
703
--echo # Take an exclusive lock.
704
LOCK TABLE t1 IN EXCLUSIVE MODE;
705
    --echo # connection conn1.
706
    connection conn1;
707
    --echo # Try an exclusive lock,
708
    --echo # which conflicts and cannot immediately be taken.
709
    --error ER_LOCK_WAIT_TIMEOUT
710
    LOCK TABLE t1 IN SHARE MODE NOWAIT;
711
--echo # connection default.
712
connection default;
713
--echo # Commit.
714
COMMIT;
715
}
716
717
if ($transactional)
718
{
719
#
720
--echo #
721
--echo # Transactional table locks do not interfere with the global read lock.
722
--echo # Take an exclusive lock on t1.
723
LOCK TABLE t1 IN EXCLUSIVE MODE;
724
    --echo # connection conn1.
725
    connection conn1;
726
    --echo # Try an exclusive lock, which conflicts.
727
    --error ER_LOCK_WAIT_TIMEOUT
728
    LOCK TABLE t1 IN EXCLUSIVE MODE;
729
    --echo # Can take the global read lock when an exclusive lock exist.
730
    FLUSH TABLES WITH READ LOCK;
731
    --echo # Show that the global read lock exists.
732
    --error ER_CANT_UPDATE_WITH_READLOCK
733
    LOCK TABLE t2 WRITE;
734
--echo # connection default.
735
connection default;
736
--echo # Can take an exclusive lock when the global read lock exists.
737
--echo # Take an exclusive lock on t2.
738
LOCK TABLE t2 IN EXCLUSIVE MODE;
739
    --echo # connection conn1.
740
    connection conn1;
741
    --echo # Show that an exclusive lock on t1 exists.
742
    --error ER_LOCK_WAIT_TIMEOUT
743
    LOCK TABLE t1 IN EXCLUSIVE MODE;
744
    --echo # Show that an exclusive lock on t2 exists.
745
    --error ER_LOCK_WAIT_TIMEOUT
746
    LOCK TABLE t2 IN EXCLUSIVE MODE;
747
    --echo # Show that the global read lock exists.
748
    --error ER_CANT_UPDATE_WITH_READLOCK
749
    LOCK TABLE t2 WRITE;
750
    --echo # Release global read lock.
751
    UNLOCK TABLES;
752
    --echo # Commit.
753
    COMMIT;
754
--echo # connection default.
755
connection default;
756
UNLOCK TABLES;
757
--echo # Commit.
758
COMMIT;
759
#
760
# Derived from a suggestion from Sergei:
761
--echo #
762
--echo # Access conflict on INSERT.
763
--echo # Take an share lock on t1.
764
LOCK TABLE t1 IN SHARE MODE;
765
    --echo # connection conn1.
766
    connection conn1;
767
    SELECT GET_LOCK("mysqltest1", 10);
768
    --echo # Try to insert a value,
769
    --echo # which must wait in background for the lock to go away.
770
    send INSERT INTO t1 VALUES (111);
771
--echo ## connection default.
772
connection default;
773
--echo ## Wait in background until the insert times out and releases lock.
774
send SELECT GET_LOCK("mysqltest1", 10);
775
    --echo # connection conn1.
776
    connection conn1;
777
    --echo # Wait for INSERT to timeout.
778
    --error ER_LOCK_WAIT_TIMEOUT
779
    reap;
780
    SELECT RELEASE_LOCK("mysqltest1");
781
    COMMIT;
782
--echo # connection default.
783
connection default;
784
reap;
785
--echo # Commit.
786
COMMIT;
787
--echo # Show that the insert in conn1 failed.
788
SELECT * FROM t1;
789
#
790
# Derived from a suggestion from Sinisa (concurrent.inc):
791
--echo #
792
--echo # Access conflict on UPDATE with exclusive lock.
793
--echo # Insert a value.
794
INSERT INTO t1 VALUES (111);
795
COMMIT;
796
    --echo # connection conn1.
797
    connection conn1;
798
    --echo # Take an exclusive lock.
799
    LOCK TABLE t1 IN EXCLUSIVE MODE;
800
--echo # connection default.
801
connection default;
802
--echo # Try a second exclusive lock, which fails due to the other lock.
803
--error ER_LOCK_WAIT_TIMEOUT
804
LOCK TABLE t1 IN EXCLUSIVE MODE;
805
--echo # Try an update, which fails due to the exclusive lock.
806
--error ER_LOCK_WAIT_TIMEOUT
807
UPDATE t1 SET c1= 111222;
808
    --echo # connection conn1.
809
    connection conn1;
810
    --echo # The exclusive table locker can still update.
811
    UPDATE t1 SET c1= 111333;
812
--echo # connection default.
813
connection default;
814
--echo # Select is allowed despite the table lock, but sees old data.
815
SELECT * FROM t1;
816
    --echo # connection conn1.
817
    connection conn1;
818
    --echo # Commit.
819
    COMMIT;
820
--echo # connection default.
821
connection default;
822
--echo # It seems like the failed update began a transaction, so still old data.
823
SELECT * FROM t1;
824
--echo # Commit.
825
COMMIT;
826
--echo # Now select sees current data.
827
SELECT * FROM t1;
828
TRUNCATE t1;
829
COMMIT;
830
--echo #
831
--echo # Access conflict on UPDATE with share lock.
832
--echo # Insert a value.
833
INSERT INTO t1 VALUES (111);
834
COMMIT;
835
    --echo # connection conn1.
836
    connection conn1;
837
    --echo # Take a share lock.
838
    LOCK TABLE t1 IN SHARE MODE;
839
    --echo # Update with a single share lock is possible.
840
    UPDATE t1 SET c1= 111222;
841
    --echo # Commit to get rid of the row lock.
842
    COMMIT;
843
    --echo # Take a share lock.
844
    LOCK TABLE t1 IN SHARE MODE;
845
--echo # connection default.
846
connection default;
847
--echo # An exclusive lock is not possible on a share lock.
848
--error ER_LOCK_WAIT_TIMEOUT
849
LOCK TABLE t1 IN EXCLUSIVE MODE;
850
--echo # More share locks are possible.
851
LOCK TABLE t1 IN SHARE MODE;
852
--echo # Noone can update when multiple share locks exist.
853
--error ER_LOCK_WAIT_TIMEOUT
854
UPDATE t1 SET c1= 111333;
855
    --echo # connection conn1.
856
    connection conn1;
857
    --echo # Noone can update when multiple share locks exist.
858
    --error ER_LOCK_WAIT_TIMEOUT
859
    UPDATE t1 SET c1= 111444;
860
    COMMIT;
861
--echo # connection default.
862
connection default;
863
SELECT * FROM t1;
864
TRUNCATE t1;
865
COMMIT;
866
#
867
}
868
869
--echo #
870
--echo # LOCK TABLE is prohibited in stored procedure.
871
--error ER_SP_BADSTATEMENT
872
CREATE PROCEDURE lock_t1_excl()
873
  LOCK TABLE t1 IN EXCLUSIVE MODE;
874
#
875
--echo #
876
--echo # LOCK TABLE is prohibited in trigger.
877
--error ER_SP_BADSTATEMENT
878
CREATE TRIGGER t1_ai AFTER INSERT ON t1 FOR EACH ROW
879
  LOCK TABLE t2 IN EXCLUSIVE MODE;
880
#
881
882
if ($transactional)
883
{
884
--echo #
885
--echo # LOCK TABLE on a pre-locked table through a trigger.
886
--echo # Create a trigger on t1 that updates t2.
887
DELIMITER //;
888
CREATE TRIGGER t1_ai AFTER INSERT ON t1 FOR EACH ROW
889
BEGIN
890
  UPDATE t2 SET c2= c2 + 111;
891
END//
892
DELIMITER ;//
893
--echo # Take an exclusive lock on t1.
894
--echo # This pre-locks t2 through the trigger.
895
LOCK TABLE t1 IN EXCLUSIVE MODE;
896
    --echo # connection conn1.
897
    connection conn1;
898
    --echo # Try to take an exclusive lock on t2,
899
    --echo # which is pre-locked through the trigger on t1.
900
    --error ER_LOCK_WAIT_TIMEOUT
901
    LOCK TABLE t2 IN EXCLUSIVE MODE;
902
    COMMIT;
903
--echo # connection default.
904
connection default;
905
--echo # Commit to release the lock.
906
COMMIT;
907
DROP TRIGGER t1_ai;
908
#
909
--echo #
910
--echo # LOCK TABLE on a pre-locked table through a view.
911
--echo # Create a function that selects from t2.
912
DELIMITER //;
913
CREATE FUNCTION count_t2() RETURNS INT
914
BEGIN
915
  RETURN (SELECT COUNT(*) FROM t2);
916
END//
917
DELIMITER ;//
918
--echo # Create a view with t1 and the function.
919
CREATE VIEW v1 AS SELECT COUNT(*), count_t2() FROM t1 GROUP BY 2;
920
--echo # Take an exclusive lock on v1.
921
--echo # This pre-locks t2 through the view.
922
LOCK TABLE v1 IN EXCLUSIVE MODE;
923
    --echo # connection conn1.
924
    connection conn1;
925
    --echo # Try to take an exclusive lock on t2,
926
    --echo # which is pre-locked through the function in v1.
927
    --error ER_LOCK_WAIT_TIMEOUT
928
    LOCK TABLE t2 IN EXCLUSIVE MODE;
929
    COMMIT;
930
--echo # connection default.
931
connection default;
932
--echo # Commit to release the lock.
933
COMMIT;
934
DROP VIEW v1;
935
DROP FUNCTION count_t2;
936
#
937
--echo #
938
--echo # Transactional LOCK TABLE by-passes pre-lock.
939
--echo #
940
--echo # Insert a value to t1 and t2 each.
941
INSERT INTO t1 VALUES (111);
942
INSERT INTO t2 VALUES (222);
943
COMMIT;
944
--echo # Create a trigger on t1 that updates t2.
945
DELIMITER //;
946
CREATE TRIGGER t1_ai AFTER INSERT ON t1 FOR EACH ROW
947
BEGIN
948
  INSERT INTO t2 SELECT GET_LOCK("mysqltest1", 10);
949
  UPDATE t2 SET c2= c2 + 111;
950
  INSERT INTO t2 SELECT RELEASE_LOCK("mysqltest1");
951
END//
952
DELIMITER ;//
953
--echo # Take an SQL lock which blocks the trigger.
954
SELECT GET_LOCK("mysqltest1", 10);
955
    --echo # connection conn1.
956
    connection conn1;
957
    --echo # Insert into t1 to fire trigger. This waits on GET_LOCK.
958
    send INSERT INTO t1 VALUES(111222);
959
--echo # connection default.
960
connection default;
961
--echo # Wait for the helper thread to sit on its lock.
962
while (`SELECT COUNT(*) < 1 FROM INFORMATION_SCHEMA.PROCESSLIST
963
        WHERE STATE LIKE '%lock%'`)
964
{
965
  --sleep 0.1
966
}
967
--echo # Take an exclusive lock.
968
LOCK TABLE t2 IN EXCLUSIVE MODE;
969
--echo # Use the lock for insert.
970
INSERT INTO t2 VALUES (111333);
971
--echo # Commit to release the lock again.
972
COMMIT;
973
--echo # Release the SQL lock to let the trigger finish.
974
SELECT RELEASE_LOCK("mysqltest1");
975
    --echo # connection conn1.
976
    connection conn1;
977
    --echo # Trigger succeeded.
978
    reap;
979
    --echo # Commit.
980
    COMMIT;
981
--echo # connection default.
982
connection default;
983
--echo # Commit.
984
COMMIT;
985
--echo # Show the results.
986
SELECT * FROM t1;
987
SELECT * FROM t2;
988
TRUNCATE t1;
989
TRUNCATE t2;
990
COMMIT;
991
DROP TRIGGER t1_ai;
992
#
993
--echo #
994
--echo # Non-transactional LOCK TABLE cannot by-passes pre-lock.
995
--echo #
996
--echo # Insert a value to t1 and t2 each.
997
INSERT INTO t1 VALUES (111);
998
INSERT INTO t2 VALUES (222);
999
COMMIT;
1000
--echo # Create a trigger on t1 that updates t2.
1001
DELIMITER //;
1002
CREATE TRIGGER t1_ai AFTER INSERT ON t1 FOR EACH ROW
1003
BEGIN
1004
  # This will time out. So use a small value.
1005
  INSERT INTO t2 SELECT GET_LOCK("mysqltest1", 1);
1006
  UPDATE t2 SET c2= c2 + 111;
1007
  INSERT INTO t2 SELECT RELEASE_LOCK("mysqltest1");
1008
END//
1009
DELIMITER ;//
1010
--echo # Take an SQL lock which blocks the trigger.
1011
SELECT GET_LOCK("mysqltest1", 10);
1012
    --echo # connection conn1.
1013
    connection conn1;
1014
    --echo # Insert into t1 to fire trigger. This waits on GET_LOCK.
1015
    send INSERT INTO t1 VALUES(111222);
1016
--echo # connection default.
1017
connection default;
1018
--echo # Wait for the helper thread to sit on its lock.
1019
while (`SELECT COUNT(*) < 1 FROM INFORMATION_SCHEMA.PROCESSLIST
1020
        WHERE STATE LIKE '%lock%'`)
1021
{
1022
  --sleep 0.1
1023
}
1024
--echo # Take a write lock. This waits until the trigger times out.
1025
LOCK TABLE t2 WRITE;
1026
--echo # Use the lock for insert.
1027
INSERT INTO t2 VALUES (111333);
1028
--echo # Release the lock again.
1029
UNLOCK TABLES;
1030
--echo # Release the SQL lock.
1031
SELECT RELEASE_LOCK("mysqltest1");
1032
    --echo # connection conn1.
1033
    connection conn1;
1034
    --echo # Trigger timed out.
1035
    --error ER_LOCK_WAIT_TIMEOUT
1036
    reap;
1037
    --echo # Commit.
1038
    COMMIT;
1039
--echo # connection default.
1040
connection default;
1041
--echo # Commit.
1042
COMMIT;
1043
--echo # Show the results.
1044
SELECT * FROM t1;
1045
SELECT * FROM t2;
1046
TRUNCATE t1;
1047
TRUNCATE t2;
1048
COMMIT;
1049
DROP TRIGGER t1_ai;
1050
}
1051
1052
#
1053
--echo ## Cleanup.
1054
connection default;
1055
SET AUTOCOMMIT= 1;
1056
UNLOCK TABLES;
1057
disconnect conn1;
1058
disconnect conn2;
1059
DROP TABLE t1, t2;
1060
#
1061