3 # The author disclaims copyright to this source code. In place of
4 # a legal notice, here is a blessing:
6 # 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.
10 #***********************************************************************
11 # This file implements regression tests for SQLite library. This
12 # file is a copy of "trans.test" modified to run under autovacuum mode.
13 # the point is to stress the autovacuum logic and try to get it to fail.
15 # $Id: avtrans.test,v 1.6 2007/09/12 17:01:45 danielk1977 Exp $
18 set testdir [file dirname $argv0]
19 source $testdir/tester.tcl
22 # Create several tables to work with.
25 execsql { PRAGMA auto_vacuum=ON }
28 CREATE TABLE one(a int PRIMARY KEY, b text);
29 INSERT INTO one VALUES(1,'one');
30 INSERT INTO one VALUES(2,'two');
31 INSERT INTO one VALUES(3,'three');
32 SELECT b FROM one ORDER BY a;
37 CREATE TABLE two(a int PRIMARY KEY, b text);
38 INSERT INTO two VALUES(1,'I');
39 INSERT INTO two VALUES(5,'V');
40 INSERT INTO two VALUES(10,'X');
41 SELECT b FROM two ORDER BY a;
46 execsql {SELECT b FROM one ORDER BY a} altdb
48 do_test avtrans-1.10 {
49 execsql {SELECT b FROM two ORDER BY a} altdb
51 integrity_check avtrans-1.11
52 wal_check_journal_mode avtrans-1.12
57 set v [catch {execsql {BEGIN}} msg]
61 set v [catch {execsql {END}} msg]
65 set v [catch {execsql {BEGIN TRANSACTION}} msg]
69 set v [catch {execsql {COMMIT TRANSACTION}} msg]
73 set v [catch {execsql {BEGIN TRANSACTION 'foo'}} msg]
77 set v [catch {execsql {ROLLBACK TRANSACTION 'foo'}} msg]
80 do_test avtrans-2.10 {
83 SELECT a FROM one ORDER BY a;
84 SELECT a FROM two ORDER BY a;
88 integrity_check avtrans-2.11
89 wal_check_journal_mode avtrans-2.12
91 # Check the locking behavior
93 sqlite3_soft_heap_limit 0
97 UPDATE one SET a = 0 WHERE 0;
98 SELECT a FROM one ORDER BY a;
101 do_test avtrans-3.2 {
103 SELECT a FROM two ORDER BY a;
106 do_test avtrans-3.3 {
108 SELECT a FROM one ORDER BY a;
111 do_test avtrans-3.4 {
113 INSERT INTO one VALUES(4,'four');
116 do_test avtrans-3.5 {
118 SELECT a FROM two ORDER BY a;
121 do_test avtrans-3.6 {
123 SELECT a FROM one ORDER BY a;
126 do_test avtrans-3.7 {
128 INSERT INTO two VALUES(4,'IV');
131 do_test avtrans-3.8 {
133 SELECT a FROM two ORDER BY a;
136 do_test avtrans-3.9 {
138 SELECT a FROM one ORDER BY a;
141 do_test avtrans-3.10 {
142 execsql {END TRANSACTION}
144 do_test avtrans-3.11 {
145 set v [catch {execsql {
146 SELECT a FROM two ORDER BY a;
150 do_test avtrans-3.12 {
151 set v [catch {execsql {
152 SELECT a FROM one ORDER BY a;
156 do_test avtrans-3.13 {
157 set v [catch {execsql {
158 SELECT a FROM two ORDER BY a;
162 do_test avtrans-3.14 {
163 set v [catch {execsql {
164 SELECT a FROM one ORDER BY a;
168 sqlite3_soft_heap_limit $cmdlinearg(soft-heap-limit)
169 integrity_check avtrans-3.15
171 do_test avtrans-4.1 {
172 set v [catch {execsql {
176 } {1 {cannot commit - no transaction is active}}
177 do_test avtrans-4.2 {
178 set v [catch {execsql {
182 } {1 {cannot rollback - no transaction is active}}
183 do_test avtrans-4.3 {
186 UPDATE two SET a = 0 WHERE 0;
187 SELECT a FROM two ORDER BY a;
190 do_test avtrans-4.4 {
192 SELECT a FROM two ORDER BY a;
195 do_test avtrans-4.5 {
197 SELECT a FROM one ORDER BY a;
200 do_test avtrans-4.6 {
203 SELECT a FROM one ORDER BY a;
205 } {1 {cannot start a transaction within a transaction}}
206 do_test avtrans-4.7 {
208 SELECT a FROM two ORDER BY a;
211 do_test avtrans-4.8 {
213 SELECT a FROM one ORDER BY a;
216 do_test avtrans-4.9 {
217 set v [catch {execsql {
219 SELECT a FROM two ORDER BY a;
223 do_test avtrans-4.10 {
224 set v [catch {execsql {
225 SELECT a FROM two ORDER BY a;
229 do_test avtrans-4.11 {
230 set v [catch {execsql {
231 SELECT a FROM one ORDER BY a;
235 integrity_check avtrans-4.12
236 do_test avtrans-4.98 {
243 integrity_check avtrans-4.99
245 # Check out the commit/rollback behavior of the database
247 do_test avtrans-5.1 {
248 execsql {SELECT name FROM sqlite_master WHERE type='table' ORDER BY name}
250 do_test avtrans-5.2 {
251 execsql {BEGIN TRANSACTION}
252 execsql {SELECT name FROM sqlite_master WHERE type='table' ORDER BY name}
254 do_test avtrans-5.3 {
255 execsql {CREATE TABLE one(a text, b int)}
256 execsql {SELECT name FROM sqlite_master WHERE type='table' ORDER BY name}
258 do_test avtrans-5.4 {
259 execsql {SELECT a,b FROM one ORDER BY b}
261 do_test avtrans-5.5 {
262 execsql {INSERT INTO one(a,b) VALUES('hello', 1)}
263 execsql {SELECT a,b FROM one ORDER BY b}
265 do_test avtrans-5.6 {
267 execsql {SELECT name FROM sqlite_master WHERE type='table' ORDER BY name}
269 do_test avtrans-5.7 {
271 execsql {SELECT a,b FROM one ORDER BY b}
274 } {1 {no such table: one}}
276 # Test commits and rollbacks of table CREATE TABLEs, CREATE INDEXs
277 # DROP TABLEs and DROP INDEXs
279 do_test avtrans-5.8 {
281 SELECT name fROM sqlite_master
282 WHERE type='table' OR type='index'
286 do_test avtrans-5.9 {
289 CREATE TABLE t1(a int, b int, c int);
290 SELECT name fROM sqlite_master
291 WHERE type='table' OR type='index'
295 do_test avtrans-5.10 {
297 CREATE INDEX i1 ON t1(a);
298 SELECT name fROM sqlite_master
299 WHERE type='table' OR type='index'
303 do_test avtrans-5.11 {
306 SELECT name fROM sqlite_master
307 WHERE type='table' OR type='index'
311 do_test avtrans-5.12 {
314 CREATE TABLE t2(a int, b int, c int);
315 CREATE INDEX i2a ON t2(a);
316 CREATE INDEX i2b ON t2(b);
318 SELECT name fROM sqlite_master
319 WHERE type='table' OR type='index'
323 do_test avtrans-5.13 {
326 SELECT name fROM sqlite_master
327 WHERE type='table' OR type='index'
331 do_test avtrans-5.14 {
335 SELECT name fROM sqlite_master
336 WHERE type='table' OR type='index'
340 do_test avtrans-5.15 {
343 SELECT name fROM sqlite_master
344 WHERE type='table' OR type='index'
348 do_test avtrans-5.16 {
352 CREATE TABLE t2(x int, y int, z int);
353 CREATE INDEX i2x ON t2(x);
354 CREATE INDEX i2y ON t2(y);
355 INSERT INTO t2 VALUES(1,2,3);
356 SELECT name fROM sqlite_master
357 WHERE type='table' OR type='index'
361 do_test avtrans-5.17 {
364 SELECT name fROM sqlite_master
365 WHERE type='table' OR type='index'
369 do_test avtrans-5.18 {
374 do_test avtrans-5.19 {
376 SELECT x FROM t2 WHERE y=2;
379 do_test avtrans-5.20 {
384 SELECT name fROM sqlite_master
385 WHERE type='table' OR type='index'
389 do_test avtrans-5.21 {
390 set r [catch {execsql {
394 } {1 {no such table: t2}}
395 do_test avtrans-5.22 {
398 SELECT name fROM sqlite_master
399 WHERE type='table' OR type='index'
403 do_test avtrans-5.23 {
408 integrity_check avtrans-5.23
411 # Try to DROP and CREATE tables and indices with the same name
412 # within a transaction. Make sure ROLLBACK works.
414 do_test avtrans-6.1 {
416 INSERT INTO t1 VALUES(1,2,3);
419 CREATE TABLE t1(p,q,r);
424 do_test avtrans-6.2 {
426 INSERT INTO t1 VALUES(1,2,3);
429 CREATE TABLE t1(p,q,r);
434 do_test avtrans-6.3 {
436 INSERT INTO t1 VALUES(1,2,3);
440 do_test avtrans-6.4 {
444 CREATE TABLE t1(a,b,c);
445 INSERT INTO t1 VALUES(4,5,6);
450 do_test avtrans-6.5 {
456 do_test avtrans-6.6 {
460 CREATE TABLE t1(a,b,c);
461 INSERT INTO t1 VALUES(4,5,6);
466 do_test avtrans-6.7 {
471 } {1 {no such table: t1}}
473 # Repeat on a table with an automatically generated index.
475 do_test avtrans-6.10 {
477 CREATE TABLE t1(a unique,b,c);
478 INSERT INTO t1 VALUES(1,2,3);
481 CREATE TABLE t1(p unique,q,r);
486 do_test avtrans-6.11 {
490 CREATE TABLE t1(p unique,q,r);
495 do_test avtrans-6.12 {
497 INSERT INTO t1 VALUES(1,2,3);
501 do_test avtrans-6.13 {
505 CREATE TABLE t1(a unique,b,c);
506 INSERT INTO t1 VALUES(4,5,6);
511 do_test avtrans-6.14 {
517 do_test avtrans-6.15 {
521 CREATE TABLE t1(a unique,b,c);
522 INSERT INTO t1 VALUES(4,5,6);
527 do_test avtrans-6.16 {
532 } {1 {no such table: t1}}
534 do_test avtrans-6.20 {
536 CREATE TABLE t1(a integer primary key,b,c);
537 INSERT INTO t1 VALUES(1,-2,-3);
538 INSERT INTO t1 VALUES(4,-5,-6);
542 do_test avtrans-6.21 {
544 CREATE INDEX i1 ON t1(b);
545 SELECT * FROM t1 WHERE b<1;
548 do_test avtrans-6.22 {
552 SELECT * FROM t1 WHERE b<1;
556 do_test avtrans-6.23 {
558 SELECT * FROM t1 WHERE b<1;
561 do_test avtrans-6.24 {
566 SELECT * FROM t1 WHERE b<1;
570 do_test avtrans-6.25 {
574 CREATE INDEX i1 ON t1(c);
575 SELECT * FROM t1 WHERE b<1;
578 do_test avtrans-6.26 {
580 SELECT * FROM t1 WHERE c<1;
583 do_test avtrans-6.27 {
586 SELECT * FROM t1 WHERE b<1;
589 do_test avtrans-6.28 {
591 SELECT * FROM t1 WHERE c<1;
595 # The following repeats steps 6.20 through 6.28, but puts a "unique"
596 # constraint the first field of the table in order to generate an
599 do_test avtrans-6.30 {
603 CREATE TABLE t1(a int unique,b,c);
605 INSERT INTO t1 VALUES(1,-2,-3);
606 INSERT INTO t1 VALUES(4,-5,-6);
607 SELECT * FROM t1 ORDER BY a;
610 do_test avtrans-6.31 {
612 CREATE INDEX i1 ON t1(b);
613 SELECT * FROM t1 WHERE b<1;
616 do_test avtrans-6.32 {
620 SELECT * FROM t1 WHERE b<1;
624 do_test avtrans-6.33 {
626 SELECT * FROM t1 WHERE b<1;
629 do_test avtrans-6.34 {
634 SELECT * FROM t1 WHERE b<1;
638 do_test avtrans-6.35 {
642 CREATE INDEX i1 ON t1(c);
643 SELECT * FROM t1 WHERE b<1;
646 do_test avtrans-6.36 {
648 SELECT * FROM t1 WHERE c<1;
651 do_test avtrans-6.37 {
654 SELECT * FROM t1 WHERE c<1;
657 do_test avtrans-6.38 {
660 SELECT * FROM t1 WHERE b<1;
663 do_test avtrans-6.39 {
665 SELECT * FROM t1 WHERE c<1;
668 integrity_check avtrans-6.40
670 ifcapable !floatingpoint {
675 # Test to make sure rollback restores the database back to its original
678 do_test avtrans-7.1 {
680 for {set i 0} {$i<1000} {incr i} {
681 set r1 [expr {rand()}]
682 set r2 [expr {rand()}]
683 set r3 [expr {rand()}]
684 execsql "INSERT INTO t2 VALUES($r1,$r2,$r3)"
687 set ::checksum [execsql {SELECT md5sum(x,y,z) FROM t2}]
689 execsql {SELECT md5sum(type,name,tbl_name,rootpage,sql) FROM sqlite_master}
691 execsql {SELECT count(*) FROM t2}
693 do_test avtrans-7.2 {
694 execsql {SELECT md5sum(x,y,z) FROM t2}
696 do_test avtrans-7.2.1 {
697 execsql {SELECT md5sum(type,name,tbl_name,rootpage,sql) FROM sqlite_master}
699 do_test avtrans-7.3 {
704 SELECT md5sum(x,y,z) FROM t2;
707 do_test avtrans-7.4 {
710 INSERT INTO t2 SELECT * FROM t2;
712 SELECT md5sum(x,y,z) FROM t2;
715 do_test avtrans-7.5 {
720 SELECT md5sum(x,y,z) FROM t2;
723 do_test avtrans-7.6 {
726 INSERT INTO t2 SELECT * FROM t2;
728 SELECT md5sum(x,y,z) FROM t2;
731 do_test avtrans-7.7 {
734 CREATE TABLE t3 AS SELECT * FROM t2;
735 INSERT INTO t2 SELECT * FROM t3;
737 SELECT md5sum(x,y,z) FROM t2;
740 do_test avtrans-7.8 {
741 execsql {SELECT md5sum(type,name,tbl_name,rootpage,sql) FROM sqlite_master}
744 do_test avtrans-7.9 {
747 CREATE TEMP TABLE t3 AS SELECT * FROM t2;
748 INSERT INTO t2 SELECT * FROM t3;
750 SELECT md5sum(x,y,z) FROM t2;
754 do_test avtrans-7.10 {
755 execsql {SELECT md5sum(type,name,tbl_name,rootpage,sql) FROM sqlite_master}
758 do_test avtrans-7.11 {
761 CREATE TEMP TABLE t3 AS SELECT * FROM t2;
762 INSERT INTO t2 SELECT * FROM t3;
765 CREATE INDEX i3a ON t3(x);
767 SELECT md5sum(x,y,z) FROM t2;
771 do_test avtrans-7.12 {
772 execsql {SELECT md5sum(type,name,tbl_name,rootpage,sql) FROM sqlite_master}
775 do_test avtrans-7.13 {
780 SELECT md5sum(x,y,z) FROM t2;
784 do_test avtrans-7.14 {
785 execsql {SELECT md5sum(type,name,tbl_name,rootpage,sql) FROM sqlite_master}
787 integrity_check avtrans-7.15
789 # Arrange for another process to begin modifying the database but abort
790 # and die in the middle of the modification. Then have this process read
791 # the database. This process should detect the journal file and roll it
792 # back. Verify that this happens correctly.
794 set fd [open test.tcl w]
798 PRAGMA default_cache_size=20;
800 CREATE TABLE t3 AS SELECT * FROM t2;
806 do_test avtrans-8.1 {
807 catch {exec [info nameofexec] test.tcl}
808 execsql {SELECT md5sum(x,y,z) FROM t2}
810 do_test avtrans-8.2 {
811 execsql {SELECT md5sum(type,name,tbl_name,rootpage,sql) FROM sqlite_master}
813 integrity_check avtrans-8.3
815 # In the following sequence of tests, compute the MD5 sum of the content
816 # of a table, make lots of modifications to that table, then do a rollback.
817 # Verify that after the rollback, the MD5 checksum is unchanged.
819 do_test avtrans-9.1 {
821 PRAGMA default_cache_size=10;
827 CREATE TABLE t3(x TEXT);
828 INSERT INTO t3 VALUES(randstr(10,400));
829 INSERT INTO t3 VALUES(randstr(10,400));
830 INSERT INTO t3 SELECT randstr(10,400) FROM t3;
831 INSERT INTO t3 SELECT randstr(10,400) FROM t3;
832 INSERT INTO t3 SELECT randstr(10,400) FROM t3;
833 INSERT INTO t3 SELECT randstr(10,400) FROM t3;
834 INSERT INTO t3 SELECT randstr(10,400) FROM t3;
835 INSERT INTO t3 SELECT randstr(10,400) FROM t3;
836 INSERT INTO t3 SELECT randstr(10,400) FROM t3;
837 INSERT INTO t3 SELECT randstr(10,400) FROM t3;
838 INSERT INTO t3 SELECT randstr(10,400) FROM t3;
840 SELECT count(*) FROM t3;
844 # The following procedure computes a "signature" for table "t3". If
845 # T3 changes in any way, the signature should change.
847 # This is used to test ROLLBACK. We gather a signature for t3, then
848 # make lots of changes to t3, then rollback and take another signature.
849 # The two signatures should be the same.
852 return [db eval {SELECT count(*), md5sum(x) FROM t3}]
855 # Repeat the following group of tests 20 times for quick testing and
856 # 40 times for full testing. Each iteration of the test makes table
857 # t3 a little larger, and thus takes a little longer, so doing 40 tests
858 # is more than 2.0 times slower than doing 20 tests. Considerably more.
860 if {[info exists G(isquick)]} {
866 # Do rollbacks. Make sure the signature does not change.
868 for {set i 2} {$i<=$limit} {incr i} {
869 set ::sig [signature]
870 set cnt [lindex $::sig 0]
872 execsql {PRAGMA fullfsync=ON}
874 execsql {PRAGMA fullfsync=OFF}
876 set sqlite_sync_count 0
877 set sqlite_fullsync_count 0
878 do_test avtrans-9.$i.1-$cnt {
881 DELETE FROM t3 WHERE random()%10!=0;
882 INSERT INTO t3 SELECT randstr(10,10)||x FROM t3;
883 INSERT INTO t3 SELECT randstr(10,10)||x FROM t3;
888 do_test avtrans-9.$i.2-$cnt {
891 DELETE FROM t3 WHERE random()%10!=0;
892 INSERT INTO t3 SELECT randstr(10,10)||x FROM t3;
893 DELETE FROM t3 WHERE random()%10!=0;
894 INSERT INTO t3 SELECT randstr(10,10)||x FROM t3;
900 do_test avtrans-9.$i.3-$cnt {
902 INSERT INTO t3 SELECT randstr(10,400) FROM t3 WHERE random()%10==0;
905 if {$tcl_platform(platform)=="unix"} {
906 do_test avtrans-9.$i.4-$cnt {
907 expr {$sqlite_sync_count>0}
909 ifcapable pager_pragmas {
910 do_test avtrans-9.$i.5-$cnt {
911 expr {$sqlite_fullsync_count>0}
914 do_test avtrans-9.$i.5-$cnt {
915 expr {$sqlite_fullsync_count==0}
919 wal_check_journal_mode avtrans-9.$i-6.$cnt
921 set ::pager_old_format 0
923 integrity_check avtrans-10.1
924 wal_check_journal_mode avtrans-10.2