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=full }
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;
35 do_test avtrans-1.0.1 { execsql { PRAGMA auto_vacuum } } 1
38 CREATE TABLE two(a int PRIMARY KEY, b text);
39 INSERT INTO two VALUES(1,'I');
40 INSERT INTO two VALUES(5,'V');
41 INSERT INTO two VALUES(10,'X');
42 SELECT b FROM two ORDER BY a;
47 execsql {SELECT b FROM one ORDER BY a} altdb
49 do_test avtrans-1.10 {
50 execsql {SELECT b FROM two ORDER BY a} altdb
52 integrity_check avtrans-1.11
53 wal_check_journal_mode avtrans-1.12
58 set v [catch {execsql {BEGIN}} msg]
62 set v [catch {execsql {END}} msg]
66 set v [catch {execsql {BEGIN TRANSACTION}} msg]
70 set v [catch {execsql {COMMIT TRANSACTION}} msg]
74 set v [catch {execsql {BEGIN TRANSACTION 'foo'}} msg]
78 set v [catch {execsql {ROLLBACK TRANSACTION 'foo'}} msg]
81 do_test avtrans-2.10 {
84 SELECT a FROM one ORDER BY a;
85 SELECT a FROM two ORDER BY a;
89 integrity_check avtrans-2.11
90 wal_check_journal_mode avtrans-2.12
92 # Check the locking behavior
94 sqlite3_soft_heap_limit 0
98 UPDATE one SET a = 0 WHERE 0;
99 SELECT a FROM one ORDER BY a;
102 do_test avtrans-3.2 {
104 SELECT a FROM two ORDER BY a;
107 do_test avtrans-3.3 {
109 SELECT a FROM one ORDER BY a;
112 do_test avtrans-3.4 {
114 INSERT INTO one VALUES(4,'four');
117 do_test avtrans-3.5 {
119 SELECT a FROM two ORDER BY a;
122 do_test avtrans-3.6 {
124 SELECT a FROM one ORDER BY a;
127 do_test avtrans-3.7 {
129 INSERT INTO two VALUES(4,'IV');
132 do_test avtrans-3.8 {
134 SELECT a FROM two ORDER BY a;
137 do_test avtrans-3.9 {
139 SELECT a FROM one ORDER BY a;
142 do_test avtrans-3.10 {
143 execsql {END TRANSACTION}
145 do_test avtrans-3.11 {
146 set v [catch {execsql {
147 SELECT a FROM two ORDER BY a;
151 do_test avtrans-3.12 {
152 set v [catch {execsql {
153 SELECT a FROM one ORDER BY a;
157 do_test avtrans-3.13 {
158 set v [catch {execsql {
159 SELECT a FROM two ORDER BY a;
163 do_test avtrans-3.14 {
164 set v [catch {execsql {
165 SELECT a FROM one ORDER BY a;
169 sqlite3_soft_heap_limit $cmdlinearg(soft-heap-limit)
170 integrity_check avtrans-3.15
172 do_test avtrans-4.1 {
173 set v [catch {execsql {
177 } {1 {cannot commit - no transaction is active}}
178 do_test avtrans-4.2 {
179 set v [catch {execsql {
183 } {1 {cannot rollback - no transaction is active}}
184 do_test avtrans-4.3 {
187 UPDATE two SET a = 0 WHERE 0;
188 SELECT a FROM two ORDER BY a;
191 do_test avtrans-4.4 {
193 SELECT a FROM two ORDER BY a;
196 do_test avtrans-4.5 {
198 SELECT a FROM one ORDER BY a;
201 do_test avtrans-4.6 {
204 SELECT a FROM one ORDER BY a;
206 } {1 {cannot start a transaction within a transaction}}
207 do_test avtrans-4.7 {
209 SELECT a FROM two ORDER BY a;
212 do_test avtrans-4.8 {
214 SELECT a FROM one ORDER BY a;
217 do_test avtrans-4.9 {
218 set v [catch {execsql {
220 SELECT a FROM two ORDER BY a;
224 do_test avtrans-4.10 {
225 set v [catch {execsql {
226 SELECT a FROM two ORDER BY a;
230 do_test avtrans-4.11 {
231 set v [catch {execsql {
232 SELECT a FROM one ORDER BY a;
236 integrity_check avtrans-4.12
237 do_test avtrans-4.98 {
244 integrity_check avtrans-4.99
246 # Check out the commit/rollback behavior of the database
248 do_test avtrans-5.1 {
249 execsql {SELECT name FROM sqlite_master WHERE type='table' ORDER BY name}
251 do_test avtrans-5.2 {
252 execsql {BEGIN TRANSACTION}
253 execsql {SELECT name FROM sqlite_master WHERE type='table' ORDER BY name}
255 do_test avtrans-5.3 {
256 execsql {CREATE TABLE one(a text, b int)}
257 execsql {SELECT name FROM sqlite_master WHERE type='table' ORDER BY name}
259 do_test avtrans-5.4 {
260 execsql {SELECT a,b FROM one ORDER BY b}
262 do_test avtrans-5.5 {
263 execsql {INSERT INTO one(a,b) VALUES('hello', 1)}
264 execsql {SELECT a,b FROM one ORDER BY b}
266 do_test avtrans-5.6 {
268 execsql {SELECT name FROM sqlite_master WHERE type='table' ORDER BY name}
270 do_test avtrans-5.7 {
272 execsql {SELECT a,b FROM one ORDER BY b}
275 } {1 {no such table: one}}
277 # Test commits and rollbacks of table CREATE TABLEs, CREATE INDEXs
278 # DROP TABLEs and DROP INDEXs
280 do_test avtrans-5.8 {
282 SELECT name fROM sqlite_master
283 WHERE type='table' OR type='index'
287 do_test avtrans-5.9 {
290 CREATE TABLE t1(a int, b int, c int);
291 SELECT name fROM sqlite_master
292 WHERE type='table' OR type='index'
296 do_test avtrans-5.10 {
298 CREATE INDEX i1 ON t1(a);
299 SELECT name fROM sqlite_master
300 WHERE type='table' OR type='index'
304 do_test avtrans-5.11 {
307 SELECT name fROM sqlite_master
308 WHERE type='table' OR type='index'
312 do_test avtrans-5.12 {
315 CREATE TABLE t2(a int, b int, c int);
316 CREATE INDEX i2a ON t2(a);
317 CREATE INDEX i2b ON t2(b);
319 SELECT name fROM sqlite_master
320 WHERE type='table' OR type='index'
324 do_test avtrans-5.13 {
327 SELECT name fROM sqlite_master
328 WHERE type='table' OR type='index'
332 do_test avtrans-5.14 {
336 SELECT name fROM sqlite_master
337 WHERE type='table' OR type='index'
341 do_test avtrans-5.15 {
344 SELECT name fROM sqlite_master
345 WHERE type='table' OR type='index'
349 do_test avtrans-5.16 {
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'
362 do_test avtrans-5.17 {
365 SELECT name fROM sqlite_master
366 WHERE type='table' OR type='index'
370 do_test avtrans-5.18 {
375 do_test avtrans-5.19 {
377 SELECT x FROM t2 WHERE y=2;
380 do_test avtrans-5.20 {
385 SELECT name fROM sqlite_master
386 WHERE type='table' OR type='index'
390 do_test avtrans-5.21 {
391 set r [catch {execsql {
395 } {1 {no such table: t2}}
396 do_test avtrans-5.22 {
399 SELECT name fROM sqlite_master
400 WHERE type='table' OR type='index'
404 do_test avtrans-5.23 {
409 integrity_check avtrans-5.23
412 # Try to DROP and CREATE tables and indices with the same name
413 # within a transaction. Make sure ROLLBACK works.
415 do_test avtrans-6.1 {
417 INSERT INTO t1 VALUES(1,2,3);
420 CREATE TABLE t1(p,q,r);
425 do_test avtrans-6.2 {
427 INSERT INTO t1 VALUES(1,2,3);
430 CREATE TABLE t1(p,q,r);
435 do_test avtrans-6.3 {
437 INSERT INTO t1 VALUES(1,2,3);
441 do_test avtrans-6.4 {
445 CREATE TABLE t1(a,b,c);
446 INSERT INTO t1 VALUES(4,5,6);
451 do_test avtrans-6.5 {
457 do_test avtrans-6.6 {
461 CREATE TABLE t1(a,b,c);
462 INSERT INTO t1 VALUES(4,5,6);
467 do_test avtrans-6.7 {
472 } {1 {no such table: t1}}
474 # Repeat on a table with an automatically generated index.
476 do_test avtrans-6.10 {
478 CREATE TABLE t1(a unique,b,c);
479 INSERT INTO t1 VALUES(1,2,3);
482 CREATE TABLE t1(p unique,q,r);
487 do_test avtrans-6.11 {
491 CREATE TABLE t1(p unique,q,r);
496 do_test avtrans-6.12 {
498 INSERT INTO t1 VALUES(1,2,3);
502 do_test avtrans-6.13 {
506 CREATE TABLE t1(a unique,b,c);
507 INSERT INTO t1 VALUES(4,5,6);
512 do_test avtrans-6.14 {
518 do_test avtrans-6.15 {
522 CREATE TABLE t1(a unique,b,c);
523 INSERT INTO t1 VALUES(4,5,6);
528 do_test avtrans-6.16 {
533 } {1 {no such table: t1}}
535 do_test avtrans-6.20 {
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);
543 do_test avtrans-6.21 {
545 CREATE INDEX i1 ON t1(b);
546 SELECT * FROM t1 WHERE b<1;
549 do_test avtrans-6.22 {
553 SELECT * FROM t1 WHERE b<1;
557 do_test avtrans-6.23 {
559 SELECT * FROM t1 WHERE b<1;
562 do_test avtrans-6.24 {
567 SELECT * FROM t1 WHERE b<1;
571 do_test avtrans-6.25 {
575 CREATE INDEX i1 ON t1(c);
576 SELECT * FROM t1 WHERE b<1;
579 do_test avtrans-6.26 {
581 SELECT * FROM t1 WHERE c<1;
584 do_test avtrans-6.27 {
587 SELECT * FROM t1 WHERE b<1;
590 do_test avtrans-6.28 {
592 SELECT * FROM t1 WHERE c<1;
596 # 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
600 do_test avtrans-6.30 {
604 CREATE TABLE t1(a int unique,b,c);
606 INSERT INTO t1 VALUES(1,-2,-3);
607 INSERT INTO t1 VALUES(4,-5,-6);
608 SELECT * FROM t1 ORDER BY a;
611 do_test avtrans-6.31 {
613 CREATE INDEX i1 ON t1(b);
614 SELECT * FROM t1 WHERE b<1;
617 do_test avtrans-6.32 {
621 SELECT * FROM t1 WHERE b<1;
625 do_test avtrans-6.33 {
627 SELECT * FROM t1 WHERE b<1;
630 do_test avtrans-6.34 {
635 SELECT * FROM t1 WHERE b<1;
639 do_test avtrans-6.35 {
643 CREATE INDEX i1 ON t1(c);
644 SELECT * FROM t1 WHERE b<1;
647 do_test avtrans-6.36 {
649 SELECT * FROM t1 WHERE c<1;
652 do_test avtrans-6.37 {
655 SELECT * FROM t1 WHERE c<1;
658 do_test avtrans-6.38 {
661 SELECT * FROM t1 WHERE b<1;
664 do_test avtrans-6.39 {
666 SELECT * FROM t1 WHERE c<1;
669 integrity_check avtrans-6.40
671 ifcapable !floatingpoint {
676 # Test to make sure rollback restores the database back to its original
679 do_test avtrans-7.1 {
681 for {set i 0} {$i<1000} {incr i} {
682 set r1 [expr {rand()}]
683 set r2 [expr {rand()}]
684 set r3 [expr {rand()}]
685 execsql "INSERT INTO t2 VALUES($r1,$r2,$r3)"
688 set ::checksum [execsql {SELECT md5sum(x,y,z) FROM t2}]
690 execsql {SELECT md5sum(type,name,tbl_name,rootpage,sql) FROM sqlite_master}
692 execsql {SELECT count(*) FROM t2}
694 do_test avtrans-7.2 {
695 execsql {SELECT md5sum(x,y,z) FROM t2}
697 do_test avtrans-7.2.1 {
698 execsql {SELECT md5sum(type,name,tbl_name,rootpage,sql) FROM sqlite_master}
700 do_test avtrans-7.3 {
705 SELECT md5sum(x,y,z) FROM t2;
708 do_test avtrans-7.4 {
711 INSERT INTO t2 SELECT * FROM t2;
713 SELECT md5sum(x,y,z) FROM t2;
716 do_test avtrans-7.5 {
721 SELECT md5sum(x,y,z) FROM t2;
724 do_test avtrans-7.6 {
727 INSERT INTO t2 SELECT * FROM t2;
729 SELECT md5sum(x,y,z) FROM t2;
732 do_test avtrans-7.7 {
735 CREATE TABLE t3 AS SELECT * FROM t2;
736 INSERT INTO t2 SELECT * FROM t3;
738 SELECT md5sum(x,y,z) FROM t2;
741 do_test avtrans-7.8 {
742 execsql {SELECT md5sum(type,name,tbl_name,rootpage,sql) FROM sqlite_master}
745 do_test avtrans-7.9 {
748 CREATE TEMP TABLE t3 AS SELECT * FROM t2;
749 INSERT INTO t2 SELECT * FROM t3;
751 SELECT md5sum(x,y,z) FROM t2;
755 do_test avtrans-7.10 {
756 execsql {SELECT md5sum(type,name,tbl_name,rootpage,sql) FROM sqlite_master}
759 do_test avtrans-7.11 {
762 CREATE TEMP TABLE t3 AS SELECT * FROM t2;
763 INSERT INTO t2 SELECT * FROM t3;
766 CREATE INDEX i3a ON t3(x);
768 SELECT md5sum(x,y,z) FROM t2;
772 do_test avtrans-7.12 {
773 execsql {SELECT md5sum(type,name,tbl_name,rootpage,sql) FROM sqlite_master}
776 do_test avtrans-7.13 {
781 SELECT md5sum(x,y,z) FROM t2;
785 do_test avtrans-7.14 {
786 execsql {SELECT md5sum(type,name,tbl_name,rootpage,sql) FROM sqlite_master}
788 integrity_check avtrans-7.15
790 # Arrange for another process to begin modifying the database but abort
791 # and die in the middle of the modification. Then have this process read
792 # the database. This process should detect the journal file and roll it
793 # back. Verify that this happens correctly.
795 set fd [open test.tcl w]
799 PRAGMA default_cache_size=20;
801 CREATE TABLE t3 AS SELECT * FROM t2;
807 do_test avtrans-8.1 {
808 catch {exec [info nameofexec] test.tcl}
809 execsql {SELECT md5sum(x,y,z) FROM t2}
811 do_test avtrans-8.2 {
812 execsql {SELECT md5sum(type,name,tbl_name,rootpage,sql) FROM sqlite_master}
814 integrity_check avtrans-8.3
816 # In the following sequence of tests, compute the MD5 sum of the content
817 # of a table, make lots of modifications to that table, then do a rollback.
818 # Verify that after the rollback, the MD5 checksum is unchanged.
820 do_test avtrans-9.1 {
822 PRAGMA default_cache_size=10;
828 CREATE TABLE t3(x TEXT);
829 INSERT INTO t3 VALUES(randstr(10,400));
830 INSERT INTO t3 VALUES(randstr(10,400));
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;
839 INSERT INTO t3 SELECT randstr(10,400) FROM t3;
841 SELECT count(*) FROM t3;
845 # The following procedure computes a "signature" for table "t3". If
846 # T3 changes in any way, the signature should change.
848 # This is used to test ROLLBACK. We gather a signature for t3, then
849 # make lots of changes to t3, then rollback and take another signature.
850 # The two signatures should be the same.
853 return [db eval {SELECT count(*), md5sum(x) FROM t3}]
856 # Repeat the following group of tests 20 times for quick testing and
857 # 40 times for full testing. Each iteration of the test makes table
858 # t3 a little larger, and thus takes a little longer, so doing 40 tests
859 # is more than 2.0 times slower than doing 20 tests. Considerably more.
861 if {[info exists G(isquick)]} {
867 # Do rollbacks. Make sure the signature does not change.
869 for {set i 2} {$i<=$limit} {incr i} {
870 set ::sig [signature]
871 set cnt [lindex $::sig 0]
873 execsql {PRAGMA fullfsync=ON}
875 execsql {PRAGMA fullfsync=OFF}
877 set sqlite_sync_count 0
878 set sqlite_fullsync_count 0
879 do_test avtrans-9.$i.1-$cnt {
882 DELETE FROM t3 WHERE random()%10!=0;
883 INSERT INTO t3 SELECT randstr(10,10)||x FROM t3;
884 INSERT INTO t3 SELECT randstr(10,10)||x FROM t3;
889 do_test avtrans-9.$i.2-$cnt {
892 DELETE FROM t3 WHERE random()%10!=0;
893 INSERT INTO t3 SELECT randstr(10,10)||x FROM t3;
894 DELETE FROM t3 WHERE random()%10!=0;
895 INSERT INTO t3 SELECT randstr(10,10)||x FROM t3;
901 do_test avtrans-9.$i.3-$cnt {
903 INSERT INTO t3 SELECT randstr(10,400) FROM t3 WHERE random()%10==0;
906 if {$tcl_platform(platform)=="unix"} {
907 do_test avtrans-9.$i.4-$cnt {
908 expr {$sqlite_sync_count>0}
910 ifcapable pager_pragmas {
911 do_test avtrans-9.$i.5-$cnt {
912 expr {$sqlite_fullsync_count>0}
915 do_test avtrans-9.$i.5-$cnt {
916 expr {$sqlite_fullsync_count==0}
920 wal_check_journal_mode avtrans-9.$i-6.$cnt
922 set ::pager_old_format 0
924 integrity_check avtrans-10.1
925 wal_check_journal_mode avtrans-10.2