blob: bbaedc5450c65c74586ef7fa61f5be6570fb488c [file] [log] [blame]
drhb19a2bc2001-09-16 00:13:26 +00001# 2001 September 15
drhc4a3c772001-04-04 11:48:57 +00002#
drhb19a2bc2001-09-16 00:13:26 +00003# The author disclaims copyright to this source code. In place of
4# a legal notice, here is a blessing:
drhc4a3c772001-04-04 11:48:57 +00005#
drhb19a2bc2001-09-16 00:13:26 +00006# May you do good and not evil.
7# May you find forgiveness for yourself and forgive others.
8# May you share freely, never taking more than you give.
drhc4a3c772001-04-04 11:48:57 +00009#
10#***********************************************************************
11# This file implements regression tests for SQLite library. The
12# focus of this script is database locks.
13#
danielk19778be02452009-04-28 16:37:59 +000014# $Id: trans.test,v 1.41 2009/04/28 16:37:59 danielk1977 Exp $
drhc4a3c772001-04-04 11:48:57 +000015
16
17set testdir [file dirname $argv0]
18source $testdir/tester.tcl
19
drhc4a3c772001-04-04 11:48:57 +000020# Create several tables to work with.
21#
dane106de62010-04-27 06:49:34 +000022wal_set_journal_mode
drhc4a3c772001-04-04 11:48:57 +000023do_test trans-1.0 {
24 execsql {
25 CREATE TABLE one(a int PRIMARY KEY, b text);
26 INSERT INTO one VALUES(1,'one');
27 INSERT INTO one VALUES(2,'two');
28 INSERT INTO one VALUES(3,'three');
29 SELECT b FROM one ORDER BY a;
30 }
31} {one two three}
drh1ef2ca02007-07-13 10:36:47 +000032integrity_check trans-1.0.1
drhc4a3c772001-04-04 11:48:57 +000033do_test trans-1.1 {
34 execsql {
35 CREATE TABLE two(a int PRIMARY KEY, b text);
36 INSERT INTO two VALUES(1,'I');
37 INSERT INTO two VALUES(5,'V');
38 INSERT INTO two VALUES(10,'X');
39 SELECT b FROM two ORDER BY a;
40 }
41} {I V X}
42do_test trans-1.9 {
drhef4ac8f2004-06-19 00:16:31 +000043 sqlite3 altdb test.db
drhc4a3c772001-04-04 11:48:57 +000044 execsql {SELECT b FROM one ORDER BY a} altdb
45} {one two three}
46do_test trans-1.10 {
47 execsql {SELECT b FROM two ORDER BY a} altdb
48} {I V X}
drh21504322002-06-25 13:16:02 +000049integrity_check trans-1.11
dane106de62010-04-27 06:49:34 +000050wal_check_journal_mode trans-1.12
drhc4a3c772001-04-04 11:48:57 +000051
52# Basic transactions
53#
54do_test trans-2.1 {
55 set v [catch {execsql {BEGIN}} msg]
56 lappend v $msg
57} {0 {}}
58do_test trans-2.2 {
59 set v [catch {execsql {END}} msg]
60 lappend v $msg
61} {0 {}}
62do_test trans-2.3 {
63 set v [catch {execsql {BEGIN TRANSACTION}} msg]
64 lappend v $msg
65} {0 {}}
66do_test trans-2.4 {
67 set v [catch {execsql {COMMIT TRANSACTION}} msg]
68 lappend v $msg
69} {0 {}}
70do_test trans-2.5 {
71 set v [catch {execsql {BEGIN TRANSACTION 'foo'}} msg]
72 lappend v $msg
73} {0 {}}
74do_test trans-2.6 {
75 set v [catch {execsql {ROLLBACK TRANSACTION 'foo'}} msg]
76 lappend v $msg
77} {0 {}}
78do_test trans-2.10 {
79 execsql {
80 BEGIN;
81 SELECT a FROM one ORDER BY a;
82 SELECT a FROM two ORDER BY a;
83 END;
84 }
85} {1 2 3 1 5 10}
drh21504322002-06-25 13:16:02 +000086integrity_check trans-2.11
dane106de62010-04-27 06:49:34 +000087wal_check_journal_mode trans-2.12
drhc4a3c772001-04-04 11:48:57 +000088
89# Check the locking behavior
90#
91do_test trans-3.1 {
92 execsql {
93 BEGIN;
danielk19771d850a72004-05-31 08:26:49 +000094 UPDATE one SET a = 0 WHERE 0;
drhc4a3c772001-04-04 11:48:57 +000095 SELECT a FROM one ORDER BY a;
96 }
97} {1 2 3}
98do_test trans-3.2 {
drha60accb2004-06-10 01:08:06 +000099 catchsql {
drhc4a3c772001-04-04 11:48:57 +0000100 SELECT a FROM two ORDER BY a;
drha60accb2004-06-10 01:08:06 +0000101 } altdb
102} {0 {1 5 10}}
danielk1977aef0bf62005-12-30 16:28:01 +0000103
drhc4a3c772001-04-04 11:48:57 +0000104do_test trans-3.3 {
drha60accb2004-06-10 01:08:06 +0000105 catchsql {
drhc4a3c772001-04-04 11:48:57 +0000106 SELECT a FROM one ORDER BY a;
drha60accb2004-06-10 01:08:06 +0000107 } altdb
108} {0 {1 2 3}}
drhc4a3c772001-04-04 11:48:57 +0000109do_test trans-3.4 {
drha60accb2004-06-10 01:08:06 +0000110 catchsql {
drhc4a3c772001-04-04 11:48:57 +0000111 INSERT INTO one VALUES(4,'four');
drha60accb2004-06-10 01:08:06 +0000112 }
drhc4a3c772001-04-04 11:48:57 +0000113} {0 {}}
drhc73d1f52001-09-17 20:48:30 +0000114do_test trans-3.5 {
drha60accb2004-06-10 01:08:06 +0000115 catchsql {
drhc4a3c772001-04-04 11:48:57 +0000116 SELECT a FROM two ORDER BY a;
drha60accb2004-06-10 01:08:06 +0000117 } altdb
118} {0 {1 5 10}}
drhc73d1f52001-09-17 20:48:30 +0000119do_test trans-3.6 {
drha60accb2004-06-10 01:08:06 +0000120 catchsql {
drhc4a3c772001-04-04 11:48:57 +0000121 SELECT a FROM one ORDER BY a;
drha60accb2004-06-10 01:08:06 +0000122 } altdb
123} {0 {1 2 3}}
drhc73d1f52001-09-17 20:48:30 +0000124do_test trans-3.7 {
drha60accb2004-06-10 01:08:06 +0000125 catchsql {
drhc4a3c772001-04-04 11:48:57 +0000126 INSERT INTO two VALUES(4,'IV');
drha60accb2004-06-10 01:08:06 +0000127 }
drhc4a3c772001-04-04 11:48:57 +0000128} {0 {}}
drhc73d1f52001-09-17 20:48:30 +0000129do_test trans-3.8 {
drha60accb2004-06-10 01:08:06 +0000130 catchsql {
drhc4a3c772001-04-04 11:48:57 +0000131 SELECT a FROM two ORDER BY a;
drha60accb2004-06-10 01:08:06 +0000132 } altdb
133} {0 {1 5 10}}
drhc73d1f52001-09-17 20:48:30 +0000134do_test trans-3.9 {
drha60accb2004-06-10 01:08:06 +0000135 catchsql {
drhc4a3c772001-04-04 11:48:57 +0000136 SELECT a FROM one ORDER BY a;
drha60accb2004-06-10 01:08:06 +0000137 } altdb
138} {0 {1 2 3}}
drhc4a3c772001-04-04 11:48:57 +0000139do_test trans-3.10 {
140 execsql {END TRANSACTION}
141} {}
danielk1977aef0bf62005-12-30 16:28:01 +0000142
drhc4a3c772001-04-04 11:48:57 +0000143do_test trans-3.11 {
144 set v [catch {execsql {
145 SELECT a FROM two ORDER BY a;
146 } altdb} msg]
147 lappend v $msg
148} {0 {1 4 5 10}}
149do_test trans-3.12 {
150 set v [catch {execsql {
151 SELECT a FROM one ORDER BY a;
152 } altdb} msg]
153 lappend v $msg
154} {0 {1 2 3 4}}
155do_test trans-3.13 {
156 set v [catch {execsql {
157 SELECT a FROM two ORDER BY a;
158 } db} msg]
159 lappend v $msg
160} {0 {1 4 5 10}}
161do_test trans-3.14 {
162 set v [catch {execsql {
163 SELECT a FROM one ORDER BY a;
164 } db} msg]
165 lappend v $msg
166} {0 {1 2 3 4}}
drh21504322002-06-25 13:16:02 +0000167integrity_check trans-3.15
dane106de62010-04-27 06:49:34 +0000168wal_check_journal_mode trans-3.16
drhc4a3c772001-04-04 11:48:57 +0000169
drhd4007282001-04-12 23:21:58 +0000170do_test trans-4.1 {
171 set v [catch {execsql {
172 COMMIT;
173 } db} msg]
174 lappend v $msg
drh6b8b8742002-08-18 20:28:06 +0000175} {1 {cannot commit - no transaction is active}}
drhd4007282001-04-12 23:21:58 +0000176do_test trans-4.2 {
177 set v [catch {execsql {
178 ROLLBACK;
179 } db} msg]
180 lappend v $msg
drh6b8b8742002-08-18 20:28:06 +0000181} {1 {cannot rollback - no transaction is active}}
drhd4007282001-04-12 23:21:58 +0000182do_test trans-4.3 {
drha60accb2004-06-10 01:08:06 +0000183 catchsql {
drhd4007282001-04-12 23:21:58 +0000184 BEGIN TRANSACTION;
danielk19771d850a72004-05-31 08:26:49 +0000185 UPDATE two SET a = 0 WHERE 0;
drhd4007282001-04-12 23:21:58 +0000186 SELECT a FROM two ORDER BY a;
drha60accb2004-06-10 01:08:06 +0000187 } db
drhd4007282001-04-12 23:21:58 +0000188} {0 {1 4 5 10}}
189do_test trans-4.4 {
drha60accb2004-06-10 01:08:06 +0000190 catchsql {
drhd4007282001-04-12 23:21:58 +0000191 SELECT a FROM two ORDER BY a;
drha60accb2004-06-10 01:08:06 +0000192 } altdb
193} {0 {1 4 5 10}}
drhd4007282001-04-12 23:21:58 +0000194do_test trans-4.5 {
drha60accb2004-06-10 01:08:06 +0000195 catchsql {
drhd4007282001-04-12 23:21:58 +0000196 SELECT a FROM one ORDER BY a;
drha60accb2004-06-10 01:08:06 +0000197 } altdb
198} {0 {1 2 3 4}}
drhd4007282001-04-12 23:21:58 +0000199do_test trans-4.6 {
drha60accb2004-06-10 01:08:06 +0000200 catchsql {
drhd4007282001-04-12 23:21:58 +0000201 BEGIN TRANSACTION;
202 SELECT a FROM one ORDER BY a;
drha60accb2004-06-10 01:08:06 +0000203 } db
drh6b8b8742002-08-18 20:28:06 +0000204} {1 {cannot start a transaction within a transaction}}
drhd4007282001-04-12 23:21:58 +0000205do_test trans-4.7 {
drha60accb2004-06-10 01:08:06 +0000206 catchsql {
drhd4007282001-04-12 23:21:58 +0000207 SELECT a FROM two ORDER BY a;
drha60accb2004-06-10 01:08:06 +0000208 } altdb
209} {0 {1 4 5 10}}
drhd4007282001-04-12 23:21:58 +0000210do_test trans-4.8 {
drha60accb2004-06-10 01:08:06 +0000211 catchsql {
drhd4007282001-04-12 23:21:58 +0000212 SELECT a FROM one ORDER BY a;
drha60accb2004-06-10 01:08:06 +0000213 } altdb
214} {0 {1 2 3 4}}
drhd4007282001-04-12 23:21:58 +0000215do_test trans-4.9 {
216 set v [catch {execsql {
217 END TRANSACTION;
218 SELECT a FROM two ORDER BY a;
219 } db} msg]
220 lappend v $msg
221} {0 {1 4 5 10}}
222do_test trans-4.10 {
223 set v [catch {execsql {
224 SELECT a FROM two ORDER BY a;
225 } altdb} msg]
226 lappend v $msg
227} {0 {1 4 5 10}}
228do_test trans-4.11 {
229 set v [catch {execsql {
230 SELECT a FROM one ORDER BY a;
231 } altdb} msg]
232 lappend v $msg
233} {0 {1 2 3 4}}
drh21504322002-06-25 13:16:02 +0000234integrity_check trans-4.12
dane106de62010-04-27 06:49:34 +0000235wal_check_journal_mode trans-4.13
236wal_check_journal_mode trans-4.14 altdb
drh21504322002-06-25 13:16:02 +0000237do_test trans-4.98 {
drhc4a3c772001-04-04 11:48:57 +0000238 altdb close
239 execsql {
240 DROP TABLE one;
241 DROP TABLE two;
242 }
243} {}
drh21504322002-06-25 13:16:02 +0000244integrity_check trans-4.99
drhc4a3c772001-04-04 11:48:57 +0000245
drhc73d1f52001-09-17 20:48:30 +0000246# Check out the commit/rollback behavior of the database
247#
248do_test trans-5.1 {
249 execsql {SELECT name FROM sqlite_master WHERE type='table' ORDER BY name}
250} {}
251do_test trans-5.2 {
252 execsql {BEGIN TRANSACTION}
253 execsql {SELECT name FROM sqlite_master WHERE type='table' ORDER BY name}
254} {}
255do_test trans-5.3 {
256 execsql {CREATE TABLE one(a text, b int)}
257 execsql {SELECT name FROM sqlite_master WHERE type='table' ORDER BY name}
258} {one}
259do_test trans-5.4 {
260 execsql {SELECT a,b FROM one ORDER BY b}
261} {}
262do_test trans-5.5 {
263 execsql {INSERT INTO one(a,b) VALUES('hello', 1)}
264 execsql {SELECT a,b FROM one ORDER BY b}
265} {hello 1}
266do_test trans-5.6 {
267 execsql {ROLLBACK}
268 execsql {SELECT name FROM sqlite_master WHERE type='table' ORDER BY name}
269} {}
270do_test trans-5.7 {
271 set v [catch {
272 execsql {SELECT a,b FROM one ORDER BY b}
273 } msg]
274 lappend v $msg
275} {1 {no such table: one}}
drhd4007282001-04-12 23:21:58 +0000276
drhafa4a022001-09-24 03:12:39 +0000277# Test commits and rollbacks of table CREATE TABLEs, CREATE INDEXs
278# DROP TABLEs and DROP INDEXs
279#
280do_test trans-5.8 {
281 execsql {
282 SELECT name fROM sqlite_master
283 WHERE type='table' OR type='index'
284 ORDER BY name
285 }
286} {}
287do_test trans-5.9 {
288 execsql {
289 BEGIN TRANSACTION;
290 CREATE TABLE t1(a int, b int, c int);
291 SELECT name fROM sqlite_master
292 WHERE type='table' OR type='index'
293 ORDER BY name;
294 }
295} {t1}
296do_test trans-5.10 {
297 execsql {
298 CREATE INDEX i1 ON t1(a);
299 SELECT name fROM sqlite_master
300 WHERE type='table' OR type='index'
301 ORDER BY name;
302 }
303} {i1 t1}
304do_test trans-5.11 {
305 execsql {
306 COMMIT;
307 SELECT name fROM sqlite_master
308 WHERE type='table' OR type='index'
309 ORDER BY name;
310 }
311} {i1 t1}
312do_test trans-5.12 {
313 execsql {
314 BEGIN TRANSACTION;
315 CREATE TABLE t2(a int, b int, c int);
316 CREATE INDEX i2a ON t2(a);
317 CREATE INDEX i2b ON t2(b);
318 DROP TABLE t1;
319 SELECT name fROM sqlite_master
320 WHERE type='table' OR type='index'
321 ORDER BY name;
322 }
323} {i2a i2b t2}
324do_test trans-5.13 {
325 execsql {
326 ROLLBACK;
327 SELECT name fROM sqlite_master
328 WHERE type='table' OR type='index'
329 ORDER BY name;
330 }
331} {i1 t1}
332do_test trans-5.14 {
333 execsql {
334 BEGIN TRANSACTION;
335 DROP INDEX i1;
336 SELECT name fROM sqlite_master
337 WHERE type='table' OR type='index'
338 ORDER BY name;
339 }
340} {t1}
341do_test trans-5.15 {
342 execsql {
343 ROLLBACK;
344 SELECT name fROM sqlite_master
345 WHERE type='table' OR type='index'
346 ORDER BY name;
347 }
348} {i1 t1}
349do_test trans-5.16 {
350 execsql {
351 BEGIN TRANSACTION;
352 DROP INDEX i1;
353 CREATE TABLE t2(x int, y int, z int);
354 CREATE INDEX i2x ON t2(x);
355 CREATE INDEX i2y ON t2(y);
356 INSERT INTO t2 VALUES(1,2,3);
357 SELECT name fROM sqlite_master
358 WHERE type='table' OR type='index'
359 ORDER BY name;
360 }
361} {i2x i2y t1 t2}
362do_test trans-5.17 {
363 execsql {
364 COMMIT;
365 SELECT name fROM sqlite_master
366 WHERE type='table' OR type='index'
367 ORDER BY name;
368 }
369} {i2x i2y t1 t2}
370do_test trans-5.18 {
371 execsql {
372 SELECT * FROM t2;
373 }
374} {1 2 3}
375do_test trans-5.19 {
376 execsql {
377 SELECT x FROM t2 WHERE y=2;
378 }
379} {1}
380do_test trans-5.20 {
381 execsql {
382 BEGIN TRANSACTION;
383 DROP TABLE t1;
384 DROP TABLE t2;
385 SELECT name fROM sqlite_master
386 WHERE type='table' OR type='index'
387 ORDER BY name;
388 }
389} {}
390do_test trans-5.21 {
391 set r [catch {execsql {
392 SELECT * FROM t2
393 }} msg]
394 lappend r $msg
395} {1 {no such table: t2}}
396do_test trans-5.22 {
397 execsql {
398 ROLLBACK;
399 SELECT name fROM sqlite_master
400 WHERE type='table' OR type='index'
401 ORDER BY name;
402 }
403} {i2x i2y t1 t2}
404do_test trans-5.23 {
405 execsql {
406 SELECT * FROM t2;
407 }
408} {1 2 3}
drh21504322002-06-25 13:16:02 +0000409integrity_check trans-5.23
410
drhafa4a022001-09-24 03:12:39 +0000411
drh74e24cd2002-01-09 03:19:59 +0000412# Try to DROP and CREATE tables and indices with the same name
413# within a transaction. Make sure ROLLBACK works.
414#
415do_test trans-6.1 {
416 execsql2 {
417 INSERT INTO t1 VALUES(1,2,3);
418 BEGIN TRANSACTION;
419 DROP TABLE t1;
420 CREATE TABLE t1(p,q,r);
421 ROLLBACK;
422 SELECT * FROM t1;
423 }
424} {a 1 b 2 c 3}
425do_test trans-6.2 {
426 execsql2 {
427 INSERT INTO t1 VALUES(1,2,3);
428 BEGIN TRANSACTION;
429 DROP TABLE t1;
430 CREATE TABLE t1(p,q,r);
431 COMMIT;
432 SELECT * FROM t1;
433 }
434} {}
435do_test trans-6.3 {
436 execsql2 {
437 INSERT INTO t1 VALUES(1,2,3);
438 SELECT * FROM t1;
439 }
440} {p 1 q 2 r 3}
441do_test trans-6.4 {
442 execsql2 {
443 BEGIN TRANSACTION;
444 DROP TABLE t1;
445 CREATE TABLE t1(a,b,c);
446 INSERT INTO t1 VALUES(4,5,6);
447 SELECT * FROM t1;
448 DROP TABLE t1;
449 }
450} {a 4 b 5 c 6}
451do_test trans-6.5 {
452 execsql2 {
453 ROLLBACK;
454 SELECT * FROM t1;
455 }
456} {p 1 q 2 r 3}
457do_test trans-6.6 {
458 execsql2 {
459 BEGIN TRANSACTION;
460 DROP TABLE t1;
461 CREATE TABLE t1(a,b,c);
462 INSERT INTO t1 VALUES(4,5,6);
463 SELECT * FROM t1;
464 DROP TABLE t1;
465 }
466} {a 4 b 5 c 6}
467do_test trans-6.7 {
468 catchsql {
469 COMMIT;
470 SELECT * FROM t1;
471 }
472} {1 {no such table: t1}}
473
drhd229ca92002-01-09 13:30:41 +0000474# Repeat on a table with an automatically generated index.
475#
476do_test trans-6.10 {
477 execsql2 {
478 CREATE TABLE t1(a unique,b,c);
479 INSERT INTO t1 VALUES(1,2,3);
480 BEGIN TRANSACTION;
481 DROP TABLE t1;
482 CREATE TABLE t1(p unique,q,r);
483 ROLLBACK;
484 SELECT * FROM t1;
485 }
486} {a 1 b 2 c 3}
487do_test trans-6.11 {
488 execsql2 {
489 BEGIN TRANSACTION;
490 DROP TABLE t1;
491 CREATE TABLE t1(p unique,q,r);
492 COMMIT;
493 SELECT * FROM t1;
494 }
495} {}
496do_test trans-6.12 {
497 execsql2 {
498 INSERT INTO t1 VALUES(1,2,3);
499 SELECT * FROM t1;
500 }
501} {p 1 q 2 r 3}
502do_test trans-6.13 {
503 execsql2 {
504 BEGIN TRANSACTION;
505 DROP TABLE t1;
506 CREATE TABLE t1(a unique,b,c);
507 INSERT INTO t1 VALUES(4,5,6);
508 SELECT * FROM t1;
509 DROP TABLE t1;
510 }
511} {a 4 b 5 c 6}
512do_test trans-6.14 {
513 execsql2 {
514 ROLLBACK;
515 SELECT * FROM t1;
516 }
517} {p 1 q 2 r 3}
518do_test trans-6.15 {
519 execsql2 {
520 BEGIN TRANSACTION;
521 DROP TABLE t1;
522 CREATE TABLE t1(a unique,b,c);
523 INSERT INTO t1 VALUES(4,5,6);
524 SELECT * FROM t1;
525 DROP TABLE t1;
526 }
527} {a 4 b 5 c 6}
528do_test trans-6.16 {
529 catchsql {
530 COMMIT;
531 SELECT * FROM t1;
532 }
533} {1 {no such table: t1}}
534
535do_test trans-6.20 {
drh74e24cd2002-01-09 03:19:59 +0000536 execsql {
537 CREATE TABLE t1(a integer primary key,b,c);
538 INSERT INTO t1 VALUES(1,-2,-3);
539 INSERT INTO t1 VALUES(4,-5,-6);
540 SELECT * FROM t1;
541 }
542} {1 -2 -3 4 -5 -6}
drhd229ca92002-01-09 13:30:41 +0000543do_test trans-6.21 {
drh74e24cd2002-01-09 03:19:59 +0000544 execsql {
545 CREATE INDEX i1 ON t1(b);
546 SELECT * FROM t1 WHERE b<1;
547 }
548} {4 -5 -6 1 -2 -3}
drhd229ca92002-01-09 13:30:41 +0000549do_test trans-6.22 {
drh74e24cd2002-01-09 03:19:59 +0000550 execsql {
551 BEGIN TRANSACTION;
552 DROP INDEX i1;
553 SELECT * FROM t1 WHERE b<1;
554 ROLLBACK;
555 }
556} {1 -2 -3 4 -5 -6}
drhd229ca92002-01-09 13:30:41 +0000557do_test trans-6.23 {
drh74e24cd2002-01-09 03:19:59 +0000558 execsql {
559 SELECT * FROM t1 WHERE b<1;
560 }
561} {4 -5 -6 1 -2 -3}
drhd229ca92002-01-09 13:30:41 +0000562do_test trans-6.24 {
drh74e24cd2002-01-09 03:19:59 +0000563 execsql {
564 BEGIN TRANSACTION;
565 DROP TABLE t1;
566 ROLLBACK;
567 SELECT * FROM t1 WHERE b<1;
568 }
569} {4 -5 -6 1 -2 -3}
570
drhd229ca92002-01-09 13:30:41 +0000571do_test trans-6.25 {
drh74e24cd2002-01-09 03:19:59 +0000572 execsql {
573 BEGIN TRANSACTION;
574 DROP INDEX i1;
575 CREATE INDEX i1 ON t1(c);
576 SELECT * FROM t1 WHERE b<1;
577 }
578} {1 -2 -3 4 -5 -6}
drhd229ca92002-01-09 13:30:41 +0000579do_test trans-6.26 {
drh74e24cd2002-01-09 03:19:59 +0000580 execsql {
581 SELECT * FROM t1 WHERE c<1;
582 }
583} {4 -5 -6 1 -2 -3}
drhd229ca92002-01-09 13:30:41 +0000584do_test trans-6.27 {
drh74e24cd2002-01-09 03:19:59 +0000585 execsql {
586 ROLLBACK;
587 SELECT * FROM t1 WHERE b<1;
588 }
589} {4 -5 -6 1 -2 -3}
drhd229ca92002-01-09 13:30:41 +0000590do_test trans-6.28 {
drh74e24cd2002-01-09 03:19:59 +0000591 execsql {
592 SELECT * FROM t1 WHERE c<1;
593 }
594} {1 -2 -3 4 -5 -6}
595
drhd229ca92002-01-09 13:30:41 +0000596# The following repeats steps 6.20 through 6.28, but puts a "unique"
597# constraint the first field of the table in order to generate an
598# automatic index.
599#
600do_test trans-6.30 {
601 execsql {
602 BEGIN TRANSACTION;
603 DROP TABLE t1;
604 CREATE TABLE t1(a int unique,b,c);
605 COMMIT;
606 INSERT INTO t1 VALUES(1,-2,-3);
607 INSERT INTO t1 VALUES(4,-5,-6);
608 SELECT * FROM t1 ORDER BY a;
609 }
610} {1 -2 -3 4 -5 -6}
611do_test trans-6.31 {
612 execsql {
613 CREATE INDEX i1 ON t1(b);
614 SELECT * FROM t1 WHERE b<1;
615 }
616} {4 -5 -6 1 -2 -3}
617do_test trans-6.32 {
618 execsql {
619 BEGIN TRANSACTION;
620 DROP INDEX i1;
621 SELECT * FROM t1 WHERE b<1;
622 ROLLBACK;
623 }
624} {1 -2 -3 4 -5 -6}
625do_test trans-6.33 {
626 execsql {
627 SELECT * FROM t1 WHERE b<1;
628 }
629} {4 -5 -6 1 -2 -3}
630do_test trans-6.34 {
631 execsql {
632 BEGIN TRANSACTION;
633 DROP TABLE t1;
634 ROLLBACK;
635 SELECT * FROM t1 WHERE b<1;
636 }
637} {4 -5 -6 1 -2 -3}
drh74e24cd2002-01-09 03:19:59 +0000638
drhd229ca92002-01-09 13:30:41 +0000639do_test trans-6.35 {
640 execsql {
641 BEGIN TRANSACTION;
642 DROP INDEX i1;
643 CREATE INDEX i1 ON t1(c);
644 SELECT * FROM t1 WHERE b<1;
645 }
646} {1 -2 -3 4 -5 -6}
647do_test trans-6.36 {
648 execsql {
649 SELECT * FROM t1 WHERE c<1;
650 }
651} {4 -5 -6 1 -2 -3}
drhda9e0342002-01-10 14:31:48 +0000652do_test trans-6.37 {
653 execsql {
654 DROP INDEX i1;
655 SELECT * FROM t1 WHERE c<1;
656 }
657} {1 -2 -3 4 -5 -6}
658do_test trans-6.38 {
drhd229ca92002-01-09 13:30:41 +0000659 execsql {
660 ROLLBACK;
661 SELECT * FROM t1 WHERE b<1;
662 }
663} {4 -5 -6 1 -2 -3}
drhda9e0342002-01-10 14:31:48 +0000664do_test trans-6.39 {
drhd229ca92002-01-09 13:30:41 +0000665 execsql {
666 SELECT * FROM t1 WHERE c<1;
667 }
668} {1 -2 -3 4 -5 -6}
drh21504322002-06-25 13:16:02 +0000669integrity_check trans-6.40
drh74e24cd2002-01-09 03:19:59 +0000670
drh28b4e482002-03-11 02:06:13 +0000671# Test to make sure rollback restores the database back to its original
672# state.
673#
674do_test trans-7.1 {
675 execsql {BEGIN}
676 for {set i 0} {$i<1000} {incr i} {
677 set r1 [expr {rand()}]
678 set r2 [expr {rand()}]
679 set r3 [expr {rand()}]
680 execsql "INSERT INTO t2 VALUES($r1,$r2,$r3)"
681 }
682 execsql {COMMIT}
683 set ::checksum [execsql {SELECT md5sum(x,y,z) FROM t2}]
684 set ::checksum2 [
685 execsql {SELECT md5sum(type,name,tbl_name,rootpage,sql) FROM sqlite_master}
686 ]
687 execsql {SELECT count(*) FROM t2}
688} {1001}
689do_test trans-7.2 {
690 execsql {SELECT md5sum(x,y,z) FROM t2}
691} $checksum
692do_test trans-7.2.1 {
693 execsql {SELECT md5sum(type,name,tbl_name,rootpage,sql) FROM sqlite_master}
694} $checksum2
695do_test trans-7.3 {
696 execsql {
697 BEGIN;
698 DELETE FROM t2;
699 ROLLBACK;
700 SELECT md5sum(x,y,z) FROM t2;
701 }
702} $checksum
703do_test trans-7.4 {
704 execsql {
705 BEGIN;
706 INSERT INTO t2 SELECT * FROM t2;
707 ROLLBACK;
708 SELECT md5sum(x,y,z) FROM t2;
709 }
710} $checksum
711do_test trans-7.5 {
712 execsql {
713 BEGIN;
714 DELETE FROM t2;
715 ROLLBACK;
716 SELECT md5sum(x,y,z) FROM t2;
717 }
718} $checksum
719do_test trans-7.6 {
720 execsql {
721 BEGIN;
722 INSERT INTO t2 SELECT * FROM t2;
723 ROLLBACK;
724 SELECT md5sum(x,y,z) FROM t2;
725 }
726} $checksum
727do_test trans-7.7 {
728 execsql {
729 BEGIN;
730 CREATE TABLE t3 AS SELECT * FROM t2;
731 INSERT INTO t2 SELECT * FROM t3;
732 ROLLBACK;
733 SELECT md5sum(x,y,z) FROM t2;
734 }
735} $checksum
736do_test trans-7.8 {
737 execsql {SELECT md5sum(type,name,tbl_name,rootpage,sql) FROM sqlite_master}
738} $checksum2
danielk197753c0f742005-03-29 03:10:59 +0000739ifcapable tempdb {
740 do_test trans-7.9 {
741 execsql {
742 BEGIN;
743 CREATE TEMP TABLE t3 AS SELECT * FROM t2;
744 INSERT INTO t2 SELECT * FROM t3;
745 ROLLBACK;
746 SELECT md5sum(x,y,z) FROM t2;
747 }
748 } $checksum
749}
drh28b4e482002-03-11 02:06:13 +0000750do_test trans-7.10 {
751 execsql {SELECT md5sum(type,name,tbl_name,rootpage,sql) FROM sqlite_master}
752} $checksum2
danielk197753c0f742005-03-29 03:10:59 +0000753ifcapable tempdb {
754 do_test trans-7.11 {
755 execsql {
756 BEGIN;
757 CREATE TEMP TABLE t3 AS SELECT * FROM t2;
758 INSERT INTO t2 SELECT * FROM t3;
759 DROP INDEX i2x;
760 DROP INDEX i2y;
761 CREATE INDEX i3a ON t3(x);
762 ROLLBACK;
763 SELECT md5sum(x,y,z) FROM t2;
764 }
765 } $checksum
766}
drh28b4e482002-03-11 02:06:13 +0000767do_test trans-7.12 {
768 execsql {SELECT md5sum(type,name,tbl_name,rootpage,sql) FROM sqlite_master}
769} $checksum2
danielk197753c0f742005-03-29 03:10:59 +0000770ifcapable tempdb {
771 do_test trans-7.13 {
772 execsql {
773 BEGIN;
774 DROP TABLE t2;
775 ROLLBACK;
776 SELECT md5sum(x,y,z) FROM t2;
777 }
778 } $checksum
779}
drh28b4e482002-03-11 02:06:13 +0000780do_test trans-7.14 {
781 execsql {SELECT md5sum(type,name,tbl_name,rootpage,sql) FROM sqlite_master}
782} $checksum2
drh21504322002-06-25 13:16:02 +0000783integrity_check trans-7.15
dane106de62010-04-27 06:49:34 +0000784wal_check_journal_mode trans-7.16
drh28b4e482002-03-11 02:06:13 +0000785
786# Arrange for another process to begin modifying the database but abort
787# and die in the middle of the modification. Then have this process read
788# the database. This process should detect the journal file and roll it
789# back. Verify that this happens correctly.
790#
791set fd [open test.tcl w]
792puts $fd {
danielk197762e5a812009-03-27 09:10:12 +0000793 sqlite3_test_control_pending_byte 0x0010000
drhef4ac8f2004-06-19 00:16:31 +0000794 sqlite3 db test.db
drh28b4e482002-03-11 02:06:13 +0000795 db eval {
drh489c4672004-03-08 13:26:17 +0000796 PRAGMA default_cache_size=20;
drh28b4e482002-03-11 02:06:13 +0000797 BEGIN;
798 CREATE TABLE t3 AS SELECT * FROM t2;
799 DELETE FROM t2;
800 }
801 sqlite_abort
802}
803close $fd
804do_test trans-8.1 {
805 catch {exec [info nameofexec] test.tcl}
806 execsql {SELECT md5sum(x,y,z) FROM t2}
807} $checksum
808do_test trans-8.2 {
809 execsql {SELECT md5sum(type,name,tbl_name,rootpage,sql) FROM sqlite_master}
810} $checksum2
drh21504322002-06-25 13:16:02 +0000811integrity_check trans-8.3
drh16e45a42008-04-19 20:34:18 +0000812set fd [open test.tcl w]
813puts $fd {
danielk197762e5a812009-03-27 09:10:12 +0000814 sqlite3_test_control_pending_byte 0x0010000
drh16e45a42008-04-19 20:34:18 +0000815 sqlite3 db test.db
816 db eval {
817 PRAGMA journal_mode=persist;
818 PRAGMA default_cache_size=20;
819 BEGIN;
820 CREATE TABLE t3 AS SELECT * FROM t2;
821 DELETE FROM t2;
822 }
823 sqlite_abort
824}
825close $fd
826do_test trans-8.4 {
827 catch {exec [info nameofexec] test.tcl}
828 execsql {SELECT md5sum(x,y,z) FROM t2}
829} $checksum
830do_test trans-8.5 {
831 execsql {SELECT md5sum(type,name,tbl_name,rootpage,sql) FROM sqlite_master}
832} $checksum2
833integrity_check trans-8.6
dane106de62010-04-27 06:49:34 +0000834wal_check_journal_mode trans-8.7
danielk197762e5a812009-03-27 09:10:12 +0000835
drh193a6b42002-07-07 16:52:46 +0000836# In the following sequence of tests, compute the MD5 sum of the content
837# of a table, make lots of modifications to that table, then do a rollback.
838# Verify that after the rollback, the MD5 checksum is unchanged.
839#
840do_test trans-9.1 {
841 execsql {
drh4303fee2003-02-15 23:09:17 +0000842 PRAGMA default_cache_size=10;
843 }
844 db close
drhef4ac8f2004-06-19 00:16:31 +0000845 sqlite3 db test.db
drh4303fee2003-02-15 23:09:17 +0000846 execsql {
drh193a6b42002-07-07 16:52:46 +0000847 BEGIN;
848 CREATE TABLE t3(x TEXT);
849 INSERT INTO t3 VALUES(randstr(10,400));
850 INSERT INTO t3 VALUES(randstr(10,400));
851 INSERT INTO t3 SELECT randstr(10,400) FROM t3;
852 INSERT INTO t3 SELECT randstr(10,400) FROM t3;
853 INSERT INTO t3 SELECT randstr(10,400) FROM t3;
854 INSERT INTO t3 SELECT randstr(10,400) FROM t3;
855 INSERT INTO t3 SELECT randstr(10,400) FROM t3;
856 INSERT INTO t3 SELECT randstr(10,400) FROM t3;
857 INSERT INTO t3 SELECT randstr(10,400) FROM t3;
858 INSERT INTO t3 SELECT randstr(10,400) FROM t3;
859 INSERT INTO t3 SELECT randstr(10,400) FROM t3;
860 COMMIT;
861 SELECT count(*) FROM t3;
862 }
863} {1024}
dane106de62010-04-27 06:49:34 +0000864wal_check_journal_mode trans-9.1.1
drh193a6b42002-07-07 16:52:46 +0000865
866# The following procedure computes a "signature" for table "t3". If
867# T3 changes in any way, the signature should change.
868#
869# This is used to test ROLLBACK. We gather a signature for t3, then
870# make lots of changes to t3, then rollback and take another signature.
871# The two signatures should be the same.
872#
873proc signature {} {
874 return [db eval {SELECT count(*), md5sum(x) FROM t3}]
875}
876
877# Repeat the following group of tests 20 times for quick testing and
878# 40 times for full testing. Each iteration of the test makes table
879# t3 a little larger, and thus takes a little longer, so doing 40 tests
880# is more than 2.0 times slower than doing 20 tests. Considerably more.
881#
danielk19778be02452009-04-28 16:37:59 +0000882# Also, if temporary tables are stored in memory and the test pcache
883# is in use, only 20 iterations. Otherwise the test pcache runs out
884# of page slots and SQLite reports "out of memory".
885#
dan430e74c2010-06-07 17:47:26 +0000886if {[info exists G(isquick)] || (
887 $TEMP_STORE==3 && [regexp {^pcache[[:digit:]]*$} [permutation]]
danielk19778be02452009-04-28 16:37:59 +0000888) } {
drh193a6b42002-07-07 16:52:46 +0000889 set limit 20
dan430e74c2010-06-07 17:47:26 +0000890} elseif {[info exists G(issoak)]} {
drh44548ec2007-06-18 12:22:43 +0000891 set limit 100
drh193a6b42002-07-07 16:52:46 +0000892} else {
893 set limit 40
894}
895
896# Do rollbacks. Make sure the signature does not change.
897#
898for {set i 2} {$i<=$limit} {incr i} {
899 set ::sig [signature]
900 set cnt [lindex $::sig 0]
drh4303fee2003-02-15 23:09:17 +0000901 if {$i%2==0} {
drhac530b12006-02-11 01:25:50 +0000902 execsql {PRAGMA fullfsync=ON}
drh4303fee2003-02-15 23:09:17 +0000903 } else {
drhac530b12006-02-11 01:25:50 +0000904 execsql {PRAGMA fullfsync=OFF}
drh4303fee2003-02-15 23:09:17 +0000905 }
drhb851b2c2005-03-10 14:11:12 +0000906 set sqlite_sync_count 0
907 set sqlite_fullsync_count 0
drh193a6b42002-07-07 16:52:46 +0000908 do_test trans-9.$i.1-$cnt {
909 execsql {
910 BEGIN;
911 DELETE FROM t3 WHERE random()%10!=0;
912 INSERT INTO t3 SELECT randstr(10,10)||x FROM t3;
913 INSERT INTO t3 SELECT randstr(10,10)||x FROM t3;
914 ROLLBACK;
915 }
916 signature
917 } $sig
918 do_test trans-9.$i.2-$cnt {
919 execsql {
920 BEGIN;
921 DELETE FROM t3 WHERE random()%10!=0;
922 INSERT INTO t3 SELECT randstr(10,10)||x FROM t3;
923 DELETE FROM t3 WHERE random()%10!=0;
924 INSERT INTO t3 SELECT randstr(10,10)||x FROM t3;
925 ROLLBACK;
926 }
927 signature
928 } $sig
929 if {$i<$limit} {
drhb851b2c2005-03-10 14:11:12 +0000930 do_test trans-9.$i.3-$cnt {
drh193a6b42002-07-07 16:52:46 +0000931 execsql {
932 INSERT INTO t3 SELECT randstr(10,400) FROM t3 WHERE random()%10==0;
933 }
934 } {}
dan0cf408f2010-07-13 07:38:51 +0000935 catch flush_async_queue
drh748f7632005-03-11 04:41:39 +0000936 if {$tcl_platform(platform)=="unix"} {
937 do_test trans-9.$i.4-$cnt {
938 expr {$sqlite_sync_count>0}
939 } 1
danielk19773bdca9c2006-01-17 09:35:01 +0000940 ifcapable pager_pragmas {
941 do_test trans-9.$i.5-$cnt {
942 expr {$sqlite_fullsync_count>0}
943 } [expr {$i%2==0}]
944 } else {
945 do_test trans-9.$i.5-$cnt {
danielk19774152e672007-09-12 17:01:45 +0000946 expr {$sqlite_fullsync_count==0}
danielk19773bdca9c2006-01-17 09:35:01 +0000947 } {1}
948 }
drh748f7632005-03-11 04:41:39 +0000949 }
drh193a6b42002-07-07 16:52:46 +0000950 }
dane106de62010-04-27 06:49:34 +0000951
952 wal_check_journal_mode trans-9.$i.6-$cnt
drh74587e52002-08-13 00:01:16 +0000953 set ::pager_old_format 0
drh193a6b42002-07-07 16:52:46 +0000954}
drh28b4e482002-03-11 02:06:13 +0000955
drhc4a3c772001-04-04 11:48:57 +0000956finish_test