blob: 6b8ad217a02ed9db09bd6baf0d4102ddf7d42eed [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#
drhc4a3c772001-04-04 11:48:57 +000014
15
16set testdir [file dirname $argv0]
17source $testdir/tester.tcl
18
drhc4a3c772001-04-04 11:48:57 +000019# Create several tables to work with.
20#
dane106de62010-04-27 06:49:34 +000021wal_set_journal_mode
drhc4a3c772001-04-04 11:48:57 +000022do_test trans-1.0 {
23 execsql {
24 CREATE TABLE one(a int PRIMARY KEY, b text);
25 INSERT INTO one VALUES(1,'one');
26 INSERT INTO one VALUES(2,'two');
27 INSERT INTO one VALUES(3,'three');
28 SELECT b FROM one ORDER BY a;
29 }
30} {one two three}
drh1ef2ca02007-07-13 10:36:47 +000031integrity_check trans-1.0.1
drhc4a3c772001-04-04 11:48:57 +000032do_test trans-1.1 {
33 execsql {
34 CREATE TABLE two(a int PRIMARY KEY, b text);
35 INSERT INTO two VALUES(1,'I');
36 INSERT INTO two VALUES(5,'V');
37 INSERT INTO two VALUES(10,'X');
38 SELECT b FROM two ORDER BY a;
39 }
40} {I V X}
drh99744fa2020-08-25 19:09:07 +000041do_test trans-1.2.1 {
42 sqlite3_txn_state db
43} {0}
44do_test trans-1.2.2 {
45 sqlite3_txn_state db main
46} {0}
47do_test trans-1.2.3 {
48 sqlite3_txn_state db temp
49} {0}
50do_test trans-1.2.4 {
51 sqlite3_txn_state db no-such-schema
52} {-1}
53
drhc4a3c772001-04-04 11:48:57 +000054do_test trans-1.9 {
drhef4ac8f2004-06-19 00:16:31 +000055 sqlite3 altdb test.db
drhc4a3c772001-04-04 11:48:57 +000056 execsql {SELECT b FROM one ORDER BY a} altdb
57} {one two three}
58do_test trans-1.10 {
59 execsql {SELECT b FROM two ORDER BY a} altdb
60} {I V X}
drh21504322002-06-25 13:16:02 +000061integrity_check trans-1.11
dane106de62010-04-27 06:49:34 +000062wal_check_journal_mode trans-1.12
drhc4a3c772001-04-04 11:48:57 +000063
64# Basic transactions
65#
66do_test trans-2.1 {
67 set v [catch {execsql {BEGIN}} msg]
68 lappend v $msg
69} {0 {}}
drh99744fa2020-08-25 19:09:07 +000070do_test trans-2.1b {
71 sqlite3_txn_state db
72} {0}
drhc4a3c772001-04-04 11:48:57 +000073do_test trans-2.2 {
74 set v [catch {execsql {END}} msg]
75 lappend v $msg
76} {0 {}}
77do_test trans-2.3 {
78 set v [catch {execsql {BEGIN TRANSACTION}} msg]
79 lappend v $msg
80} {0 {}}
81do_test trans-2.4 {
82 set v [catch {execsql {COMMIT TRANSACTION}} msg]
83 lappend v $msg
84} {0 {}}
85do_test trans-2.5 {
86 set v [catch {execsql {BEGIN TRANSACTION 'foo'}} msg]
87 lappend v $msg
88} {0 {}}
89do_test trans-2.6 {
90 set v [catch {execsql {ROLLBACK TRANSACTION 'foo'}} msg]
91 lappend v $msg
92} {0 {}}
93do_test trans-2.10 {
94 execsql {
95 BEGIN;
96 SELECT a FROM one ORDER BY a;
97 SELECT a FROM two ORDER BY a;
98 END;
99 }
100} {1 2 3 1 5 10}
drh21504322002-06-25 13:16:02 +0000101integrity_check trans-2.11
dane106de62010-04-27 06:49:34 +0000102wal_check_journal_mode trans-2.12
drhc4a3c772001-04-04 11:48:57 +0000103
104# Check the locking behavior
105#
106do_test trans-3.1 {
107 execsql {
108 BEGIN;
danielk19771d850a72004-05-31 08:26:49 +0000109 UPDATE one SET a = 0 WHERE 0;
drhc4a3c772001-04-04 11:48:57 +0000110 SELECT a FROM one ORDER BY a;
111 }
112} {1 2 3}
drh99744fa2020-08-25 19:09:07 +0000113do_test trans-3.1b {
114 sqlite3_txn_state db
115} {2}
116do_test trans-3.1c {
117 sqlite3_txn_state db main
118} {2}
119do_test trans-3.1d {
120 sqlite3_txn_state db temp
121} {0}
122
drhc4a3c772001-04-04 11:48:57 +0000123do_test trans-3.2 {
drha60accb2004-06-10 01:08:06 +0000124 catchsql {
drhc4a3c772001-04-04 11:48:57 +0000125 SELECT a FROM two ORDER BY a;
drha60accb2004-06-10 01:08:06 +0000126 } altdb
127} {0 {1 5 10}}
danielk1977aef0bf62005-12-30 16:28:01 +0000128
drhc4a3c772001-04-04 11:48:57 +0000129do_test trans-3.3 {
drha60accb2004-06-10 01:08:06 +0000130 catchsql {
drhc4a3c772001-04-04 11:48:57 +0000131 SELECT a FROM one ORDER BY a;
drha60accb2004-06-10 01:08:06 +0000132 } altdb
133} {0 {1 2 3}}
drhc4a3c772001-04-04 11:48:57 +0000134do_test trans-3.4 {
drha60accb2004-06-10 01:08:06 +0000135 catchsql {
drhc4a3c772001-04-04 11:48:57 +0000136 INSERT INTO one VALUES(4,'four');
drha60accb2004-06-10 01:08:06 +0000137 }
drhc4a3c772001-04-04 11:48:57 +0000138} {0 {}}
drhc73d1f52001-09-17 20:48:30 +0000139do_test trans-3.5 {
drha60accb2004-06-10 01:08:06 +0000140 catchsql {
drhc4a3c772001-04-04 11:48:57 +0000141 SELECT a FROM two ORDER BY a;
drha60accb2004-06-10 01:08:06 +0000142 } altdb
143} {0 {1 5 10}}
drhc73d1f52001-09-17 20:48:30 +0000144do_test trans-3.6 {
drha60accb2004-06-10 01:08:06 +0000145 catchsql {
drhc4a3c772001-04-04 11:48:57 +0000146 SELECT a FROM one ORDER BY a;
drha60accb2004-06-10 01:08:06 +0000147 } altdb
148} {0 {1 2 3}}
drhc73d1f52001-09-17 20:48:30 +0000149do_test trans-3.7 {
drha60accb2004-06-10 01:08:06 +0000150 catchsql {
drhc4a3c772001-04-04 11:48:57 +0000151 INSERT INTO two VALUES(4,'IV');
drha60accb2004-06-10 01:08:06 +0000152 }
drhc4a3c772001-04-04 11:48:57 +0000153} {0 {}}
drhc73d1f52001-09-17 20:48:30 +0000154do_test trans-3.8 {
drha60accb2004-06-10 01:08:06 +0000155 catchsql {
drhc4a3c772001-04-04 11:48:57 +0000156 SELECT a FROM two ORDER BY a;
drha60accb2004-06-10 01:08:06 +0000157 } altdb
158} {0 {1 5 10}}
drhc73d1f52001-09-17 20:48:30 +0000159do_test trans-3.9 {
drha60accb2004-06-10 01:08:06 +0000160 catchsql {
drhc4a3c772001-04-04 11:48:57 +0000161 SELECT a FROM one ORDER BY a;
drha60accb2004-06-10 01:08:06 +0000162 } altdb
163} {0 {1 2 3}}
drhc4a3c772001-04-04 11:48:57 +0000164do_test trans-3.10 {
165 execsql {END TRANSACTION}
166} {}
drh99744fa2020-08-25 19:09:07 +0000167do_test trans-3.10b {
168 sqlite3_txn_state db
169} {0}
170
danielk1977aef0bf62005-12-30 16:28:01 +0000171
drhc4a3c772001-04-04 11:48:57 +0000172do_test trans-3.11 {
173 set v [catch {execsql {
174 SELECT a FROM two ORDER BY a;
175 } altdb} msg]
176 lappend v $msg
177} {0 {1 4 5 10}}
178do_test trans-3.12 {
179 set v [catch {execsql {
180 SELECT a FROM one ORDER BY a;
181 } altdb} msg]
182 lappend v $msg
183} {0 {1 2 3 4}}
184do_test trans-3.13 {
185 set v [catch {execsql {
186 SELECT a FROM two ORDER BY a;
187 } db} msg]
188 lappend v $msg
189} {0 {1 4 5 10}}
190do_test trans-3.14 {
191 set v [catch {execsql {
192 SELECT a FROM one ORDER BY a;
193 } db} msg]
194 lappend v $msg
195} {0 {1 2 3 4}}
drh21504322002-06-25 13:16:02 +0000196integrity_check trans-3.15
dane106de62010-04-27 06:49:34 +0000197wal_check_journal_mode trans-3.16
drhc4a3c772001-04-04 11:48:57 +0000198
drhd4007282001-04-12 23:21:58 +0000199do_test trans-4.1 {
200 set v [catch {execsql {
201 COMMIT;
202 } db} msg]
203 lappend v $msg
drh6b8b8742002-08-18 20:28:06 +0000204} {1 {cannot commit - no transaction is active}}
drhd4007282001-04-12 23:21:58 +0000205do_test trans-4.2 {
206 set v [catch {execsql {
207 ROLLBACK;
208 } db} msg]
209 lappend v $msg
drh6b8b8742002-08-18 20:28:06 +0000210} {1 {cannot rollback - no transaction is active}}
drhd4007282001-04-12 23:21:58 +0000211do_test trans-4.3 {
drha60accb2004-06-10 01:08:06 +0000212 catchsql {
drhd4007282001-04-12 23:21:58 +0000213 BEGIN TRANSACTION;
danielk19771d850a72004-05-31 08:26:49 +0000214 UPDATE two SET a = 0 WHERE 0;
drhd4007282001-04-12 23:21:58 +0000215 SELECT a FROM two ORDER BY a;
drha60accb2004-06-10 01:08:06 +0000216 } db
drhd4007282001-04-12 23:21:58 +0000217} {0 {1 4 5 10}}
218do_test trans-4.4 {
drha60accb2004-06-10 01:08:06 +0000219 catchsql {
drhd4007282001-04-12 23:21:58 +0000220 SELECT a FROM two ORDER BY a;
drha60accb2004-06-10 01:08:06 +0000221 } altdb
222} {0 {1 4 5 10}}
drhd4007282001-04-12 23:21:58 +0000223do_test trans-4.5 {
drha60accb2004-06-10 01:08:06 +0000224 catchsql {
drhd4007282001-04-12 23:21:58 +0000225 SELECT a FROM one ORDER BY a;
drha60accb2004-06-10 01:08:06 +0000226 } altdb
227} {0 {1 2 3 4}}
drhd4007282001-04-12 23:21:58 +0000228do_test trans-4.6 {
drha60accb2004-06-10 01:08:06 +0000229 catchsql {
drhd4007282001-04-12 23:21:58 +0000230 BEGIN TRANSACTION;
231 SELECT a FROM one ORDER BY a;
drha60accb2004-06-10 01:08:06 +0000232 } db
drh6b8b8742002-08-18 20:28:06 +0000233} {1 {cannot start a transaction within a transaction}}
drhd4007282001-04-12 23:21:58 +0000234do_test trans-4.7 {
drha60accb2004-06-10 01:08:06 +0000235 catchsql {
drhd4007282001-04-12 23:21:58 +0000236 SELECT a FROM two ORDER BY a;
drha60accb2004-06-10 01:08:06 +0000237 } altdb
238} {0 {1 4 5 10}}
drhd4007282001-04-12 23:21:58 +0000239do_test trans-4.8 {
drha60accb2004-06-10 01:08:06 +0000240 catchsql {
drhd4007282001-04-12 23:21:58 +0000241 SELECT a FROM one ORDER BY a;
drha60accb2004-06-10 01:08:06 +0000242 } altdb
243} {0 {1 2 3 4}}
drhd4007282001-04-12 23:21:58 +0000244do_test trans-4.9 {
245 set v [catch {execsql {
246 END TRANSACTION;
247 SELECT a FROM two ORDER BY a;
248 } db} msg]
249 lappend v $msg
250} {0 {1 4 5 10}}
251do_test trans-4.10 {
252 set v [catch {execsql {
253 SELECT a FROM two ORDER BY a;
254 } altdb} msg]
255 lappend v $msg
256} {0 {1 4 5 10}}
257do_test trans-4.11 {
258 set v [catch {execsql {
259 SELECT a FROM one ORDER BY a;
260 } altdb} msg]
261 lappend v $msg
262} {0 {1 2 3 4}}
drh21504322002-06-25 13:16:02 +0000263integrity_check trans-4.12
dane106de62010-04-27 06:49:34 +0000264wal_check_journal_mode trans-4.13
265wal_check_journal_mode trans-4.14 altdb
drh21504322002-06-25 13:16:02 +0000266do_test trans-4.98 {
drhc4a3c772001-04-04 11:48:57 +0000267 altdb close
268 execsql {
269 DROP TABLE one;
270 DROP TABLE two;
271 }
272} {}
drh21504322002-06-25 13:16:02 +0000273integrity_check trans-4.99
drhc4a3c772001-04-04 11:48:57 +0000274
drhc73d1f52001-09-17 20:48:30 +0000275# Check out the commit/rollback behavior of the database
276#
277do_test trans-5.1 {
278 execsql {SELECT name FROM sqlite_master WHERE type='table' ORDER BY name}
279} {}
280do_test trans-5.2 {
281 execsql {BEGIN TRANSACTION}
282 execsql {SELECT name FROM sqlite_master WHERE type='table' ORDER BY name}
283} {}
drh99744fa2020-08-25 19:09:07 +0000284do_test trans-5.2b {
285 sqlite3_txn_state db
286} {1}
287do_test trans-5.2c {
288 sqlite3_txn_state db main
289} {1}
290do_test trans-5.2d {
291 sqlite3_txn_state db temp
292} {0}
drhc73d1f52001-09-17 20:48:30 +0000293do_test trans-5.3 {
294 execsql {CREATE TABLE one(a text, b int)}
295 execsql {SELECT name FROM sqlite_master WHERE type='table' ORDER BY name}
296} {one}
297do_test trans-5.4 {
298 execsql {SELECT a,b FROM one ORDER BY b}
299} {}
300do_test trans-5.5 {
301 execsql {INSERT INTO one(a,b) VALUES('hello', 1)}
302 execsql {SELECT a,b FROM one ORDER BY b}
303} {hello 1}
304do_test trans-5.6 {
305 execsql {ROLLBACK}
306 execsql {SELECT name FROM sqlite_master WHERE type='table' ORDER BY name}
307} {}
308do_test trans-5.7 {
309 set v [catch {
310 execsql {SELECT a,b FROM one ORDER BY b}
311 } msg]
312 lappend v $msg
313} {1 {no such table: one}}
drhd4007282001-04-12 23:21:58 +0000314
drhafa4a022001-09-24 03:12:39 +0000315# Test commits and rollbacks of table CREATE TABLEs, CREATE INDEXs
316# DROP TABLEs and DROP INDEXs
317#
318do_test trans-5.8 {
319 execsql {
320 SELECT name fROM sqlite_master
321 WHERE type='table' OR type='index'
322 ORDER BY name
323 }
324} {}
325do_test trans-5.9 {
326 execsql {
327 BEGIN TRANSACTION;
328 CREATE TABLE t1(a int, b int, c int);
329 SELECT name fROM sqlite_master
330 WHERE type='table' OR type='index'
331 ORDER BY name;
332 }
333} {t1}
334do_test trans-5.10 {
335 execsql {
336 CREATE INDEX i1 ON t1(a);
337 SELECT name fROM sqlite_master
338 WHERE type='table' OR type='index'
339 ORDER BY name;
340 }
341} {i1 t1}
342do_test trans-5.11 {
343 execsql {
344 COMMIT;
345 SELECT name fROM sqlite_master
346 WHERE type='table' OR type='index'
347 ORDER BY name;
348 }
349} {i1 t1}
350do_test trans-5.12 {
351 execsql {
352 BEGIN TRANSACTION;
353 CREATE TABLE t2(a int, b int, c int);
354 CREATE INDEX i2a ON t2(a);
355 CREATE INDEX i2b ON t2(b);
356 DROP TABLE t1;
357 SELECT name fROM sqlite_master
358 WHERE type='table' OR type='index'
359 ORDER BY name;
360 }
361} {i2a i2b t2}
362do_test trans-5.13 {
363 execsql {
364 ROLLBACK;
365 SELECT name fROM sqlite_master
366 WHERE type='table' OR type='index'
367 ORDER BY name;
368 }
369} {i1 t1}
370do_test trans-5.14 {
371 execsql {
372 BEGIN TRANSACTION;
373 DROP INDEX i1;
374 SELECT name fROM sqlite_master
375 WHERE type='table' OR type='index'
376 ORDER BY name;
377 }
378} {t1}
379do_test trans-5.15 {
380 execsql {
381 ROLLBACK;
382 SELECT name fROM sqlite_master
383 WHERE type='table' OR type='index'
384 ORDER BY name;
385 }
386} {i1 t1}
387do_test trans-5.16 {
388 execsql {
389 BEGIN TRANSACTION;
390 DROP INDEX i1;
391 CREATE TABLE t2(x int, y int, z int);
392 CREATE INDEX i2x ON t2(x);
393 CREATE INDEX i2y ON t2(y);
394 INSERT INTO t2 VALUES(1,2,3);
395 SELECT name fROM sqlite_master
396 WHERE type='table' OR type='index'
397 ORDER BY name;
398 }
399} {i2x i2y t1 t2}
400do_test trans-5.17 {
401 execsql {
402 COMMIT;
403 SELECT name fROM sqlite_master
404 WHERE type='table' OR type='index'
405 ORDER BY name;
406 }
407} {i2x i2y t1 t2}
408do_test trans-5.18 {
409 execsql {
410 SELECT * FROM t2;
411 }
412} {1 2 3}
413do_test trans-5.19 {
414 execsql {
415 SELECT x FROM t2 WHERE y=2;
416 }
417} {1}
418do_test trans-5.20 {
419 execsql {
420 BEGIN TRANSACTION;
421 DROP TABLE t1;
422 DROP TABLE t2;
423 SELECT name fROM sqlite_master
424 WHERE type='table' OR type='index'
425 ORDER BY name;
426 }
427} {}
428do_test trans-5.21 {
429 set r [catch {execsql {
430 SELECT * FROM t2
431 }} msg]
432 lappend r $msg
433} {1 {no such table: t2}}
434do_test trans-5.22 {
435 execsql {
436 ROLLBACK;
437 SELECT name fROM sqlite_master
438 WHERE type='table' OR type='index'
439 ORDER BY name;
440 }
441} {i2x i2y t1 t2}
442do_test trans-5.23 {
443 execsql {
444 SELECT * FROM t2;
445 }
446} {1 2 3}
drh21504322002-06-25 13:16:02 +0000447integrity_check trans-5.23
448
drhafa4a022001-09-24 03:12:39 +0000449
drh74e24cd2002-01-09 03:19:59 +0000450# Try to DROP and CREATE tables and indices with the same name
451# within a transaction. Make sure ROLLBACK works.
452#
453do_test trans-6.1 {
454 execsql2 {
455 INSERT INTO t1 VALUES(1,2,3);
456 BEGIN TRANSACTION;
457 DROP TABLE t1;
458 CREATE TABLE t1(p,q,r);
459 ROLLBACK;
460 SELECT * FROM t1;
461 }
462} {a 1 b 2 c 3}
463do_test trans-6.2 {
464 execsql2 {
465 INSERT INTO t1 VALUES(1,2,3);
466 BEGIN TRANSACTION;
467 DROP TABLE t1;
468 CREATE TABLE t1(p,q,r);
469 COMMIT;
470 SELECT * FROM t1;
471 }
472} {}
473do_test trans-6.3 {
474 execsql2 {
475 INSERT INTO t1 VALUES(1,2,3);
476 SELECT * FROM t1;
477 }
478} {p 1 q 2 r 3}
479do_test trans-6.4 {
480 execsql2 {
481 BEGIN TRANSACTION;
482 DROP TABLE t1;
483 CREATE TABLE t1(a,b,c);
484 INSERT INTO t1 VALUES(4,5,6);
485 SELECT * FROM t1;
486 DROP TABLE t1;
487 }
488} {a 4 b 5 c 6}
489do_test trans-6.5 {
490 execsql2 {
491 ROLLBACK;
492 SELECT * FROM t1;
493 }
494} {p 1 q 2 r 3}
495do_test trans-6.6 {
496 execsql2 {
497 BEGIN TRANSACTION;
498 DROP TABLE t1;
499 CREATE TABLE t1(a,b,c);
500 INSERT INTO t1 VALUES(4,5,6);
501 SELECT * FROM t1;
502 DROP TABLE t1;
503 }
504} {a 4 b 5 c 6}
505do_test trans-6.7 {
506 catchsql {
507 COMMIT;
508 SELECT * FROM t1;
509 }
510} {1 {no such table: t1}}
511
drhd229ca92002-01-09 13:30:41 +0000512# Repeat on a table with an automatically generated index.
513#
514do_test trans-6.10 {
515 execsql2 {
516 CREATE TABLE t1(a unique,b,c);
517 INSERT INTO t1 VALUES(1,2,3);
518 BEGIN TRANSACTION;
519 DROP TABLE t1;
520 CREATE TABLE t1(p unique,q,r);
521 ROLLBACK;
522 SELECT * FROM t1;
523 }
524} {a 1 b 2 c 3}
525do_test trans-6.11 {
526 execsql2 {
527 BEGIN TRANSACTION;
528 DROP TABLE t1;
529 CREATE TABLE t1(p unique,q,r);
530 COMMIT;
531 SELECT * FROM t1;
532 }
533} {}
534do_test trans-6.12 {
535 execsql2 {
536 INSERT INTO t1 VALUES(1,2,3);
537 SELECT * FROM t1;
538 }
539} {p 1 q 2 r 3}
540do_test trans-6.13 {
541 execsql2 {
542 BEGIN TRANSACTION;
543 DROP TABLE t1;
544 CREATE TABLE t1(a unique,b,c);
545 INSERT INTO t1 VALUES(4,5,6);
546 SELECT * FROM t1;
547 DROP TABLE t1;
548 }
549} {a 4 b 5 c 6}
550do_test trans-6.14 {
551 execsql2 {
552 ROLLBACK;
553 SELECT * FROM t1;
554 }
555} {p 1 q 2 r 3}
556do_test trans-6.15 {
557 execsql2 {
558 BEGIN TRANSACTION;
559 DROP TABLE t1;
560 CREATE TABLE t1(a unique,b,c);
561 INSERT INTO t1 VALUES(4,5,6);
562 SELECT * FROM t1;
563 DROP TABLE t1;
564 }
565} {a 4 b 5 c 6}
566do_test trans-6.16 {
567 catchsql {
568 COMMIT;
569 SELECT * FROM t1;
570 }
571} {1 {no such table: t1}}
572
573do_test trans-6.20 {
drh74e24cd2002-01-09 03:19:59 +0000574 execsql {
575 CREATE TABLE t1(a integer primary key,b,c);
576 INSERT INTO t1 VALUES(1,-2,-3);
577 INSERT INTO t1 VALUES(4,-5,-6);
578 SELECT * FROM t1;
579 }
580} {1 -2 -3 4 -5 -6}
drhd229ca92002-01-09 13:30:41 +0000581do_test trans-6.21 {
drh74e24cd2002-01-09 03:19:59 +0000582 execsql {
583 CREATE INDEX i1 ON t1(b);
584 SELECT * FROM t1 WHERE b<1;
585 }
586} {4 -5 -6 1 -2 -3}
drhd229ca92002-01-09 13:30:41 +0000587do_test trans-6.22 {
drh74e24cd2002-01-09 03:19:59 +0000588 execsql {
589 BEGIN TRANSACTION;
590 DROP INDEX i1;
591 SELECT * FROM t1 WHERE b<1;
592 ROLLBACK;
593 }
594} {1 -2 -3 4 -5 -6}
drhd229ca92002-01-09 13:30:41 +0000595do_test trans-6.23 {
drh74e24cd2002-01-09 03:19:59 +0000596 execsql {
597 SELECT * FROM t1 WHERE b<1;
598 }
599} {4 -5 -6 1 -2 -3}
drhd229ca92002-01-09 13:30:41 +0000600do_test trans-6.24 {
drh74e24cd2002-01-09 03:19:59 +0000601 execsql {
602 BEGIN TRANSACTION;
603 DROP TABLE t1;
604 ROLLBACK;
605 SELECT * FROM t1 WHERE b<1;
606 }
607} {4 -5 -6 1 -2 -3}
608
drhd229ca92002-01-09 13:30:41 +0000609do_test trans-6.25 {
drh74e24cd2002-01-09 03:19:59 +0000610 execsql {
611 BEGIN TRANSACTION;
612 DROP INDEX i1;
613 CREATE INDEX i1 ON t1(c);
614 SELECT * FROM t1 WHERE b<1;
615 }
616} {1 -2 -3 4 -5 -6}
drhd229ca92002-01-09 13:30:41 +0000617do_test trans-6.26 {
drh74e24cd2002-01-09 03:19:59 +0000618 execsql {
619 SELECT * FROM t1 WHERE c<1;
620 }
621} {4 -5 -6 1 -2 -3}
drhd229ca92002-01-09 13:30:41 +0000622do_test trans-6.27 {
drh74e24cd2002-01-09 03:19:59 +0000623 execsql {
624 ROLLBACK;
625 SELECT * FROM t1 WHERE b<1;
626 }
627} {4 -5 -6 1 -2 -3}
drhd229ca92002-01-09 13:30:41 +0000628do_test trans-6.28 {
drh74e24cd2002-01-09 03:19:59 +0000629 execsql {
630 SELECT * FROM t1 WHERE c<1;
631 }
632} {1 -2 -3 4 -5 -6}
633
drhd229ca92002-01-09 13:30:41 +0000634# The following repeats steps 6.20 through 6.28, but puts a "unique"
635# constraint the first field of the table in order to generate an
636# automatic index.
637#
638do_test trans-6.30 {
639 execsql {
640 BEGIN TRANSACTION;
641 DROP TABLE t1;
642 CREATE TABLE t1(a int unique,b,c);
643 COMMIT;
644 INSERT INTO t1 VALUES(1,-2,-3);
645 INSERT INTO t1 VALUES(4,-5,-6);
646 SELECT * FROM t1 ORDER BY a;
647 }
648} {1 -2 -3 4 -5 -6}
649do_test trans-6.31 {
650 execsql {
651 CREATE INDEX i1 ON t1(b);
652 SELECT * FROM t1 WHERE b<1;
653 }
654} {4 -5 -6 1 -2 -3}
655do_test trans-6.32 {
656 execsql {
657 BEGIN TRANSACTION;
658 DROP INDEX i1;
659 SELECT * FROM t1 WHERE b<1;
660 ROLLBACK;
661 }
662} {1 -2 -3 4 -5 -6}
663do_test trans-6.33 {
664 execsql {
665 SELECT * FROM t1 WHERE b<1;
666 }
667} {4 -5 -6 1 -2 -3}
668do_test trans-6.34 {
669 execsql {
670 BEGIN TRANSACTION;
671 DROP TABLE t1;
672 ROLLBACK;
673 SELECT * FROM t1 WHERE b<1;
674 }
675} {4 -5 -6 1 -2 -3}
drh74e24cd2002-01-09 03:19:59 +0000676
drhd229ca92002-01-09 13:30:41 +0000677do_test trans-6.35 {
678 execsql {
679 BEGIN TRANSACTION;
680 DROP INDEX i1;
681 CREATE INDEX i1 ON t1(c);
682 SELECT * FROM t1 WHERE b<1;
683 }
684} {1 -2 -3 4 -5 -6}
685do_test trans-6.36 {
686 execsql {
687 SELECT * FROM t1 WHERE c<1;
688 }
689} {4 -5 -6 1 -2 -3}
drhda9e0342002-01-10 14:31:48 +0000690do_test trans-6.37 {
691 execsql {
692 DROP INDEX i1;
693 SELECT * FROM t1 WHERE c<1;
694 }
695} {1 -2 -3 4 -5 -6}
696do_test trans-6.38 {
drhd229ca92002-01-09 13:30:41 +0000697 execsql {
698 ROLLBACK;
699 SELECT * FROM t1 WHERE b<1;
700 }
701} {4 -5 -6 1 -2 -3}
drhda9e0342002-01-10 14:31:48 +0000702do_test trans-6.39 {
drhd229ca92002-01-09 13:30:41 +0000703 execsql {
704 SELECT * FROM t1 WHERE c<1;
705 }
706} {1 -2 -3 4 -5 -6}
drh21504322002-06-25 13:16:02 +0000707integrity_check trans-6.40
drh74e24cd2002-01-09 03:19:59 +0000708
drh28b4e482002-03-11 02:06:13 +0000709# Test to make sure rollback restores the database back to its original
710# state.
711#
712do_test trans-7.1 {
713 execsql {BEGIN}
714 for {set i 0} {$i<1000} {incr i} {
715 set r1 [expr {rand()}]
716 set r2 [expr {rand()}]
717 set r3 [expr {rand()}]
718 execsql "INSERT INTO t2 VALUES($r1,$r2,$r3)"
719 }
720 execsql {COMMIT}
721 set ::checksum [execsql {SELECT md5sum(x,y,z) FROM t2}]
722 set ::checksum2 [
723 execsql {SELECT md5sum(type,name,tbl_name,rootpage,sql) FROM sqlite_master}
724 ]
725 execsql {SELECT count(*) FROM t2}
726} {1001}
727do_test trans-7.2 {
728 execsql {SELECT md5sum(x,y,z) FROM t2}
729} $checksum
730do_test trans-7.2.1 {
731 execsql {SELECT md5sum(type,name,tbl_name,rootpage,sql) FROM sqlite_master}
732} $checksum2
733do_test trans-7.3 {
734 execsql {
735 BEGIN;
736 DELETE FROM t2;
737 ROLLBACK;
738 SELECT md5sum(x,y,z) FROM t2;
739 }
740} $checksum
741do_test trans-7.4 {
742 execsql {
743 BEGIN;
744 INSERT INTO t2 SELECT * FROM t2;
745 ROLLBACK;
746 SELECT md5sum(x,y,z) FROM t2;
747 }
748} $checksum
749do_test trans-7.5 {
750 execsql {
751 BEGIN;
752 DELETE FROM t2;
753 ROLLBACK;
754 SELECT md5sum(x,y,z) FROM t2;
755 }
756} $checksum
757do_test trans-7.6 {
758 execsql {
759 BEGIN;
760 INSERT INTO t2 SELECT * FROM t2;
761 ROLLBACK;
762 SELECT md5sum(x,y,z) FROM t2;
763 }
764} $checksum
765do_test trans-7.7 {
766 execsql {
767 BEGIN;
768 CREATE TABLE t3 AS SELECT * FROM t2;
769 INSERT INTO t2 SELECT * FROM t3;
770 ROLLBACK;
771 SELECT md5sum(x,y,z) FROM t2;
772 }
773} $checksum
774do_test trans-7.8 {
775 execsql {SELECT md5sum(type,name,tbl_name,rootpage,sql) FROM sqlite_master}
776} $checksum2
danielk197753c0f742005-03-29 03:10:59 +0000777ifcapable tempdb {
778 do_test trans-7.9 {
779 execsql {
780 BEGIN;
781 CREATE TEMP TABLE t3 AS SELECT * FROM t2;
782 INSERT INTO t2 SELECT * FROM t3;
783 ROLLBACK;
784 SELECT md5sum(x,y,z) FROM t2;
785 }
786 } $checksum
787}
drh28b4e482002-03-11 02:06:13 +0000788do_test trans-7.10 {
789 execsql {SELECT md5sum(type,name,tbl_name,rootpage,sql) FROM sqlite_master}
790} $checksum2
danielk197753c0f742005-03-29 03:10:59 +0000791ifcapable tempdb {
792 do_test trans-7.11 {
793 execsql {
794 BEGIN;
795 CREATE TEMP TABLE t3 AS SELECT * FROM t2;
796 INSERT INTO t2 SELECT * FROM t3;
797 DROP INDEX i2x;
798 DROP INDEX i2y;
799 CREATE INDEX i3a ON t3(x);
800 ROLLBACK;
801 SELECT md5sum(x,y,z) FROM t2;
802 }
803 } $checksum
804}
drh28b4e482002-03-11 02:06:13 +0000805do_test trans-7.12 {
806 execsql {SELECT md5sum(type,name,tbl_name,rootpage,sql) FROM sqlite_master}
807} $checksum2
danielk197753c0f742005-03-29 03:10:59 +0000808ifcapable tempdb {
809 do_test trans-7.13 {
810 execsql {
811 BEGIN;
812 DROP TABLE t2;
813 ROLLBACK;
814 SELECT md5sum(x,y,z) FROM t2;
815 }
816 } $checksum
817}
drh28b4e482002-03-11 02:06:13 +0000818do_test trans-7.14 {
819 execsql {SELECT md5sum(type,name,tbl_name,rootpage,sql) FROM sqlite_master}
820} $checksum2
drh21504322002-06-25 13:16:02 +0000821integrity_check trans-7.15
dane106de62010-04-27 06:49:34 +0000822wal_check_journal_mode trans-7.16
drh28b4e482002-03-11 02:06:13 +0000823
824# Arrange for another process to begin modifying the database but abort
825# and die in the middle of the modification. Then have this process read
826# the database. This process should detect the journal file and roll it
827# back. Verify that this happens correctly.
828#
829set fd [open test.tcl w]
830puts $fd {
danielk197762e5a812009-03-27 09:10:12 +0000831 sqlite3_test_control_pending_byte 0x0010000
drhef4ac8f2004-06-19 00:16:31 +0000832 sqlite3 db test.db
drh28b4e482002-03-11 02:06:13 +0000833 db eval {
drh489c4672004-03-08 13:26:17 +0000834 PRAGMA default_cache_size=20;
drh28b4e482002-03-11 02:06:13 +0000835 BEGIN;
836 CREATE TABLE t3 AS SELECT * FROM t2;
837 DELETE FROM t2;
838 }
839 sqlite_abort
840}
841close $fd
842do_test trans-8.1 {
843 catch {exec [info nameofexec] test.tcl}
844 execsql {SELECT md5sum(x,y,z) FROM t2}
845} $checksum
846do_test trans-8.2 {
847 execsql {SELECT md5sum(type,name,tbl_name,rootpage,sql) FROM sqlite_master}
848} $checksum2
drh21504322002-06-25 13:16:02 +0000849integrity_check trans-8.3
drh16e45a42008-04-19 20:34:18 +0000850set fd [open test.tcl w]
851puts $fd {
danielk197762e5a812009-03-27 09:10:12 +0000852 sqlite3_test_control_pending_byte 0x0010000
drh16e45a42008-04-19 20:34:18 +0000853 sqlite3 db test.db
854 db eval {
855 PRAGMA journal_mode=persist;
856 PRAGMA default_cache_size=20;
857 BEGIN;
858 CREATE TABLE t3 AS SELECT * FROM t2;
859 DELETE FROM t2;
860 }
861 sqlite_abort
862}
863close $fd
864do_test trans-8.4 {
865 catch {exec [info nameofexec] test.tcl}
866 execsql {SELECT md5sum(x,y,z) FROM t2}
867} $checksum
868do_test trans-8.5 {
869 execsql {SELECT md5sum(type,name,tbl_name,rootpage,sql) FROM sqlite_master}
870} $checksum2
871integrity_check trans-8.6
dane106de62010-04-27 06:49:34 +0000872wal_check_journal_mode trans-8.7
danielk197762e5a812009-03-27 09:10:12 +0000873
drh193a6b42002-07-07 16:52:46 +0000874# In the following sequence of tests, compute the MD5 sum of the content
875# of a table, make lots of modifications to that table, then do a rollback.
876# Verify that after the rollback, the MD5 checksum is unchanged.
877#
878do_test trans-9.1 {
879 execsql {
drh4303fee2003-02-15 23:09:17 +0000880 PRAGMA default_cache_size=10;
881 }
882 db close
drhef4ac8f2004-06-19 00:16:31 +0000883 sqlite3 db test.db
drh4303fee2003-02-15 23:09:17 +0000884 execsql {
drh193a6b42002-07-07 16:52:46 +0000885 BEGIN;
886 CREATE TABLE t3(x TEXT);
887 INSERT INTO t3 VALUES(randstr(10,400));
888 INSERT INTO t3 VALUES(randstr(10,400));
889 INSERT INTO t3 SELECT randstr(10,400) FROM t3;
890 INSERT INTO t3 SELECT randstr(10,400) FROM t3;
891 INSERT INTO t3 SELECT randstr(10,400) FROM t3;
892 INSERT INTO t3 SELECT randstr(10,400) FROM t3;
893 INSERT INTO t3 SELECT randstr(10,400) FROM t3;
894 INSERT INTO t3 SELECT randstr(10,400) FROM t3;
895 INSERT INTO t3 SELECT randstr(10,400) FROM t3;
896 INSERT INTO t3 SELECT randstr(10,400) FROM t3;
897 INSERT INTO t3 SELECT randstr(10,400) FROM t3;
898 COMMIT;
899 SELECT count(*) FROM t3;
900 }
901} {1024}
dane106de62010-04-27 06:49:34 +0000902wal_check_journal_mode trans-9.1.1
drh193a6b42002-07-07 16:52:46 +0000903
904# The following procedure computes a "signature" for table "t3". If
905# T3 changes in any way, the signature should change.
906#
907# This is used to test ROLLBACK. We gather a signature for t3, then
908# make lots of changes to t3, then rollback and take another signature.
909# The two signatures should be the same.
910#
911proc signature {} {
912 return [db eval {SELECT count(*), md5sum(x) FROM t3}]
913}
914
915# Repeat the following group of tests 20 times for quick testing and
916# 40 times for full testing. Each iteration of the test makes table
917# t3 a little larger, and thus takes a little longer, so doing 40 tests
918# is more than 2.0 times slower than doing 20 tests. Considerably more.
919#
danielk19778be02452009-04-28 16:37:59 +0000920# Also, if temporary tables are stored in memory and the test pcache
921# is in use, only 20 iterations. Otherwise the test pcache runs out
922# of page slots and SQLite reports "out of memory".
923#
dan430e74c2010-06-07 17:47:26 +0000924if {[info exists G(isquick)] || (
925 $TEMP_STORE==3 && [regexp {^pcache[[:digit:]]*$} [permutation]]
danielk19778be02452009-04-28 16:37:59 +0000926) } {
drh193a6b42002-07-07 16:52:46 +0000927 set limit 20
dan430e74c2010-06-07 17:47:26 +0000928} elseif {[info exists G(issoak)]} {
drh44548ec2007-06-18 12:22:43 +0000929 set limit 100
drh193a6b42002-07-07 16:52:46 +0000930} else {
931 set limit 40
932}
933
934# Do rollbacks. Make sure the signature does not change.
935#
936for {set i 2} {$i<=$limit} {incr i} {
937 set ::sig [signature]
938 set cnt [lindex $::sig 0]
drh4303fee2003-02-15 23:09:17 +0000939 if {$i%2==0} {
drhac530b12006-02-11 01:25:50 +0000940 execsql {PRAGMA fullfsync=ON}
drh4303fee2003-02-15 23:09:17 +0000941 } else {
drhac530b12006-02-11 01:25:50 +0000942 execsql {PRAGMA fullfsync=OFF}
drh4303fee2003-02-15 23:09:17 +0000943 }
drhb851b2c2005-03-10 14:11:12 +0000944 set sqlite_sync_count 0
945 set sqlite_fullsync_count 0
drh193a6b42002-07-07 16:52:46 +0000946 do_test trans-9.$i.1-$cnt {
947 execsql {
948 BEGIN;
949 DELETE FROM t3 WHERE random()%10!=0;
950 INSERT INTO t3 SELECT randstr(10,10)||x FROM t3;
951 INSERT INTO t3 SELECT randstr(10,10)||x FROM t3;
952 ROLLBACK;
953 }
954 signature
955 } $sig
956 do_test trans-9.$i.2-$cnt {
957 execsql {
958 BEGIN;
959 DELETE FROM t3 WHERE random()%10!=0;
960 INSERT INTO t3 SELECT randstr(10,10)||x FROM t3;
961 DELETE FROM t3 WHERE random()%10!=0;
962 INSERT INTO t3 SELECT randstr(10,10)||x FROM t3;
963 ROLLBACK;
964 }
965 signature
966 } $sig
967 if {$i<$limit} {
drhb851b2c2005-03-10 14:11:12 +0000968 do_test trans-9.$i.3-$cnt {
drh193a6b42002-07-07 16:52:46 +0000969 execsql {
970 INSERT INTO t3 SELECT randstr(10,400) FROM t3 WHERE random()%10==0;
971 }
972 } {}
dan0cf408f2010-07-13 07:38:51 +0000973 catch flush_async_queue
drh748f7632005-03-11 04:41:39 +0000974 if {$tcl_platform(platform)=="unix"} {
975 do_test trans-9.$i.4-$cnt {
976 expr {$sqlite_sync_count>0}
977 } 1
danielk19773bdca9c2006-01-17 09:35:01 +0000978 ifcapable pager_pragmas {
979 do_test trans-9.$i.5-$cnt {
980 expr {$sqlite_fullsync_count>0}
981 } [expr {$i%2==0}]
982 } else {
983 do_test trans-9.$i.5-$cnt {
danielk19774152e672007-09-12 17:01:45 +0000984 expr {$sqlite_fullsync_count==0}
danielk19773bdca9c2006-01-17 09:35:01 +0000985 } {1}
986 }
drh748f7632005-03-11 04:41:39 +0000987 }
drh193a6b42002-07-07 16:52:46 +0000988 }
dane106de62010-04-27 06:49:34 +0000989
990 wal_check_journal_mode trans-9.$i.6-$cnt
drh74587e52002-08-13 00:01:16 +0000991 set ::pager_old_format 0
drh193a6b42002-07-07 16:52:46 +0000992}
drh28b4e482002-03-11 02:06:13 +0000993
drhc4a3c772001-04-04 11:48:57 +0000994finish_test