xref: /sqlite-3.40.0/test/avtrans.test (revision 1b91c729)
1# 2001 September 15
2#
3# The author disclaims copyright to this source code.  In place of
4# a legal notice, here is a blessing:
5#
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.
9#
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.
14#
15# $Id: avtrans.test,v 1.3 2006/01/23 21:37:32 drh Exp $
16
17
18set testdir [file dirname $argv0]
19source $testdir/tester.tcl
20
21
22# Create several tables to work with.
23#
24do_test avtrans-1.0 {
25  execsql {
26    PRAGMA auto_vacuum=ON;
27    CREATE TABLE one(a int PRIMARY KEY, b text);
28    INSERT INTO one VALUES(1,'one');
29    INSERT INTO one VALUES(2,'two');
30    INSERT INTO one VALUES(3,'three');
31    SELECT b FROM one ORDER BY a;
32  }
33} {one two three}
34do_test avtrans-1.1 {
35  execsql {
36    CREATE TABLE two(a int PRIMARY KEY, b text);
37    INSERT INTO two VALUES(1,'I');
38    INSERT INTO two VALUES(5,'V');
39    INSERT INTO two VALUES(10,'X');
40    SELECT b FROM two ORDER BY a;
41  }
42} {I V X}
43do_test avtrans-1.9 {
44  sqlite3 altdb test.db
45  execsql {SELECT b FROM one ORDER BY a} altdb
46} {one two three}
47do_test avtrans-1.10 {
48  execsql {SELECT b FROM two ORDER BY a} altdb
49} {I V X}
50integrity_check avtrans-1.11
51
52# Basic transactions
53#
54do_test avtrans-2.1 {
55  set v [catch {execsql {BEGIN}} msg]
56  lappend v $msg
57} {0 {}}
58do_test avtrans-2.2 {
59  set v [catch {execsql {END}} msg]
60  lappend v $msg
61} {0 {}}
62do_test avtrans-2.3 {
63  set v [catch {execsql {BEGIN TRANSACTION}} msg]
64  lappend v $msg
65} {0 {}}
66do_test avtrans-2.4 {
67  set v [catch {execsql {COMMIT TRANSACTION}} msg]
68  lappend v $msg
69} {0 {}}
70do_test avtrans-2.5 {
71  set v [catch {execsql {BEGIN TRANSACTION 'foo'}} msg]
72  lappend v $msg
73} {0 {}}
74do_test avtrans-2.6 {
75  set v [catch {execsql {ROLLBACK TRANSACTION 'foo'}} msg]
76  lappend v $msg
77} {0 {}}
78do_test avtrans-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}
86integrity_check avtrans-2.11
87
88# Check the locking behavior
89#
90do_test avtrans-3.1 {
91  execsql {
92    BEGIN;
93    UPDATE one SET a = 0 WHERE 0;
94    SELECT a FROM one ORDER BY a;
95  }
96} {1 2 3}
97do_test avtrans-3.2 {
98  catchsql {
99    SELECT a FROM two ORDER BY a;
100  } altdb
101} {0 {1 5 10}}
102do_test avtrans-3.3 {
103  catchsql {
104    SELECT a FROM one ORDER BY a;
105  } altdb
106} {0 {1 2 3}}
107do_test avtrans-3.4 {
108  catchsql {
109    INSERT INTO one VALUES(4,'four');
110  }
111} {0 {}}
112do_test avtrans-3.5 {
113  catchsql {
114    SELECT a FROM two ORDER BY a;
115  } altdb
116} {0 {1 5 10}}
117do_test avtrans-3.6 {
118  catchsql {
119    SELECT a FROM one ORDER BY a;
120  } altdb
121} {0 {1 2 3}}
122do_test avtrans-3.7 {
123  catchsql {
124    INSERT INTO two VALUES(4,'IV');
125  }
126} {0 {}}
127do_test avtrans-3.8 {
128  catchsql {
129    SELECT a FROM two ORDER BY a;
130  } altdb
131} {0 {1 5 10}}
132do_test avtrans-3.9 {
133  catchsql {
134    SELECT a FROM one ORDER BY a;
135  } altdb
136} {0 {1 2 3}}
137do_test avtrans-3.10 {
138  execsql {END TRANSACTION}
139} {}
140do_test avtrans-3.11 {
141  set v [catch {execsql {
142    SELECT a FROM two ORDER BY a;
143  } altdb} msg]
144  lappend v $msg
145} {0 {1 4 5 10}}
146do_test avtrans-3.12 {
147  set v [catch {execsql {
148    SELECT a FROM one ORDER BY a;
149  } altdb} msg]
150  lappend v $msg
151} {0 {1 2 3 4}}
152do_test avtrans-3.13 {
153  set v [catch {execsql {
154    SELECT a FROM two ORDER BY a;
155  } db} msg]
156  lappend v $msg
157} {0 {1 4 5 10}}
158do_test avtrans-3.14 {
159  set v [catch {execsql {
160    SELECT a FROM one ORDER BY a;
161  } db} msg]
162  lappend v $msg
163} {0 {1 2 3 4}}
164integrity_check avtrans-3.15
165
166do_test avtrans-4.1 {
167  set v [catch {execsql {
168    COMMIT;
169  } db} msg]
170  lappend v $msg
171} {1 {cannot commit - no transaction is active}}
172do_test avtrans-4.2 {
173  set v [catch {execsql {
174    ROLLBACK;
175  } db} msg]
176  lappend v $msg
177} {1 {cannot rollback - no transaction is active}}
178do_test avtrans-4.3 {
179  catchsql {
180    BEGIN TRANSACTION;
181    UPDATE two SET a = 0 WHERE 0;
182    SELECT a FROM two ORDER BY a;
183  } db
184} {0 {1 4 5 10}}
185do_test avtrans-4.4 {
186  catchsql {
187    SELECT a FROM two ORDER BY a;
188  } altdb
189} {0 {1 4 5 10}}
190do_test avtrans-4.5 {
191  catchsql {
192    SELECT a FROM one ORDER BY a;
193  } altdb
194} {0 {1 2 3 4}}
195do_test avtrans-4.6 {
196  catchsql {
197    BEGIN TRANSACTION;
198    SELECT a FROM one ORDER BY a;
199  } db
200} {1 {cannot start a transaction within a transaction}}
201do_test avtrans-4.7 {
202  catchsql {
203    SELECT a FROM two ORDER BY a;
204  } altdb
205} {0 {1 4 5 10}}
206do_test avtrans-4.8 {
207  catchsql {
208    SELECT a FROM one ORDER BY a;
209  } altdb
210} {0 {1 2 3 4}}
211do_test avtrans-4.9 {
212  set v [catch {execsql {
213    END TRANSACTION;
214    SELECT a FROM two ORDER BY a;
215  } db} msg]
216  lappend v $msg
217} {0 {1 4 5 10}}
218do_test avtrans-4.10 {
219  set v [catch {execsql {
220    SELECT a FROM two ORDER BY a;
221  } altdb} msg]
222  lappend v $msg
223} {0 {1 4 5 10}}
224do_test avtrans-4.11 {
225  set v [catch {execsql {
226    SELECT a FROM one ORDER BY a;
227  } altdb} msg]
228  lappend v $msg
229} {0 {1 2 3 4}}
230integrity_check avtrans-4.12
231do_test avtrans-4.98 {
232  altdb close
233  execsql {
234    DROP TABLE one;
235    DROP TABLE two;
236  }
237} {}
238integrity_check avtrans-4.99
239
240# Check out the commit/rollback behavior of the database
241#
242do_test avtrans-5.1 {
243  execsql {SELECT name FROM sqlite_master WHERE type='table' ORDER BY name}
244} {}
245do_test avtrans-5.2 {
246  execsql {BEGIN TRANSACTION}
247  execsql {SELECT name FROM sqlite_master WHERE type='table' ORDER BY name}
248} {}
249do_test avtrans-5.3 {
250  execsql {CREATE TABLE one(a text, b int)}
251  execsql {SELECT name FROM sqlite_master WHERE type='table' ORDER BY name}
252} {one}
253do_test avtrans-5.4 {
254  execsql {SELECT a,b FROM one ORDER BY b}
255} {}
256do_test avtrans-5.5 {
257  execsql {INSERT INTO one(a,b) VALUES('hello', 1)}
258  execsql {SELECT a,b FROM one ORDER BY b}
259} {hello 1}
260do_test avtrans-5.6 {
261  execsql {ROLLBACK}
262  execsql {SELECT name FROM sqlite_master WHERE type='table' ORDER BY name}
263} {}
264do_test avtrans-5.7 {
265  set v [catch {
266    execsql {SELECT a,b FROM one ORDER BY b}
267  } msg]
268  lappend v $msg
269} {1 {no such table: one}}
270
271# Test commits and rollbacks of table CREATE TABLEs, CREATE INDEXs
272# DROP TABLEs and DROP INDEXs
273#
274do_test avtrans-5.8 {
275  execsql {
276    SELECT name fROM sqlite_master
277    WHERE type='table' OR type='index'
278    ORDER BY name
279  }
280} {}
281do_test avtrans-5.9 {
282  execsql {
283    BEGIN TRANSACTION;
284    CREATE TABLE t1(a int, b int, c int);
285    SELECT name fROM sqlite_master
286    WHERE type='table' OR type='index'
287    ORDER BY name;
288  }
289} {t1}
290do_test avtrans-5.10 {
291  execsql {
292    CREATE INDEX i1 ON t1(a);
293    SELECT name fROM sqlite_master
294    WHERE type='table' OR type='index'
295    ORDER BY name;
296  }
297} {i1 t1}
298do_test avtrans-5.11 {
299  execsql {
300    COMMIT;
301    SELECT name fROM sqlite_master
302    WHERE type='table' OR type='index'
303    ORDER BY name;
304  }
305} {i1 t1}
306do_test avtrans-5.12 {
307  execsql {
308    BEGIN TRANSACTION;
309    CREATE TABLE t2(a int, b int, c int);
310    CREATE INDEX i2a ON t2(a);
311    CREATE INDEX i2b ON t2(b);
312    DROP TABLE t1;
313    SELECT name fROM sqlite_master
314    WHERE type='table' OR type='index'
315    ORDER BY name;
316  }
317} {i2a i2b t2}
318do_test avtrans-5.13 {
319  execsql {
320    ROLLBACK;
321    SELECT name fROM sqlite_master
322    WHERE type='table' OR type='index'
323    ORDER BY name;
324  }
325} {i1 t1}
326do_test avtrans-5.14 {
327  execsql {
328    BEGIN TRANSACTION;
329    DROP INDEX i1;
330    SELECT name fROM sqlite_master
331    WHERE type='table' OR type='index'
332    ORDER BY name;
333  }
334} {t1}
335do_test avtrans-5.15 {
336  execsql {
337    ROLLBACK;
338    SELECT name fROM sqlite_master
339    WHERE type='table' OR type='index'
340    ORDER BY name;
341  }
342} {i1 t1}
343do_test avtrans-5.16 {
344  execsql {
345    BEGIN TRANSACTION;
346    DROP INDEX i1;
347    CREATE TABLE t2(x int, y int, z int);
348    CREATE INDEX i2x ON t2(x);
349    CREATE INDEX i2y ON t2(y);
350    INSERT INTO t2 VALUES(1,2,3);
351    SELECT name fROM sqlite_master
352    WHERE type='table' OR type='index'
353    ORDER BY name;
354  }
355} {i2x i2y t1 t2}
356do_test avtrans-5.17 {
357  execsql {
358    COMMIT;
359    SELECT name fROM sqlite_master
360    WHERE type='table' OR type='index'
361    ORDER BY name;
362  }
363} {i2x i2y t1 t2}
364do_test avtrans-5.18 {
365  execsql {
366    SELECT * FROM t2;
367  }
368} {1 2 3}
369do_test avtrans-5.19 {
370  execsql {
371    SELECT x FROM t2 WHERE y=2;
372  }
373} {1}
374do_test avtrans-5.20 {
375  execsql {
376    BEGIN TRANSACTION;
377    DROP TABLE t1;
378    DROP TABLE t2;
379    SELECT name fROM sqlite_master
380    WHERE type='table' OR type='index'
381    ORDER BY name;
382  }
383} {}
384do_test avtrans-5.21 {
385  set r [catch {execsql {
386    SELECT * FROM t2
387  }} msg]
388  lappend r $msg
389} {1 {no such table: t2}}
390do_test avtrans-5.22 {
391  execsql {
392    ROLLBACK;
393    SELECT name fROM sqlite_master
394    WHERE type='table' OR type='index'
395    ORDER BY name;
396  }
397} {i2x i2y t1 t2}
398do_test avtrans-5.23 {
399  execsql {
400    SELECT * FROM t2;
401  }
402} {1 2 3}
403integrity_check avtrans-5.23
404
405
406# Try to DROP and CREATE tables and indices with the same name
407# within a transaction.  Make sure ROLLBACK works.
408#
409do_test avtrans-6.1 {
410  execsql2 {
411    INSERT INTO t1 VALUES(1,2,3);
412    BEGIN TRANSACTION;
413    DROP TABLE t1;
414    CREATE TABLE t1(p,q,r);
415    ROLLBACK;
416    SELECT * FROM t1;
417  }
418} {a 1 b 2 c 3}
419do_test avtrans-6.2 {
420  execsql2 {
421    INSERT INTO t1 VALUES(1,2,3);
422    BEGIN TRANSACTION;
423    DROP TABLE t1;
424    CREATE TABLE t1(p,q,r);
425    COMMIT;
426    SELECT * FROM t1;
427  }
428} {}
429do_test avtrans-6.3 {
430  execsql2 {
431    INSERT INTO t1 VALUES(1,2,3);
432    SELECT * FROM t1;
433  }
434} {p 1 q 2 r 3}
435do_test avtrans-6.4 {
436  execsql2 {
437    BEGIN TRANSACTION;
438    DROP TABLE t1;
439    CREATE TABLE t1(a,b,c);
440    INSERT INTO t1 VALUES(4,5,6);
441    SELECT * FROM t1;
442    DROP TABLE t1;
443  }
444} {a 4 b 5 c 6}
445do_test avtrans-6.5 {
446  execsql2 {
447    ROLLBACK;
448    SELECT * FROM t1;
449  }
450} {p 1 q 2 r 3}
451do_test avtrans-6.6 {
452  execsql2 {
453    BEGIN TRANSACTION;
454    DROP TABLE t1;
455    CREATE TABLE t1(a,b,c);
456    INSERT INTO t1 VALUES(4,5,6);
457    SELECT * FROM t1;
458    DROP TABLE t1;
459  }
460} {a 4 b 5 c 6}
461do_test avtrans-6.7 {
462  catchsql {
463    COMMIT;
464    SELECT * FROM t1;
465  }
466} {1 {no such table: t1}}
467
468# Repeat on a table with an automatically generated index.
469#
470do_test avtrans-6.10 {
471  execsql2 {
472    CREATE TABLE t1(a unique,b,c);
473    INSERT INTO t1 VALUES(1,2,3);
474    BEGIN TRANSACTION;
475    DROP TABLE t1;
476    CREATE TABLE t1(p unique,q,r);
477    ROLLBACK;
478    SELECT * FROM t1;
479  }
480} {a 1 b 2 c 3}
481do_test avtrans-6.11 {
482  execsql2 {
483    BEGIN TRANSACTION;
484    DROP TABLE t1;
485    CREATE TABLE t1(p unique,q,r);
486    COMMIT;
487    SELECT * FROM t1;
488  }
489} {}
490do_test avtrans-6.12 {
491  execsql2 {
492    INSERT INTO t1 VALUES(1,2,3);
493    SELECT * FROM t1;
494  }
495} {p 1 q 2 r 3}
496do_test avtrans-6.13 {
497  execsql2 {
498    BEGIN TRANSACTION;
499    DROP TABLE t1;
500    CREATE TABLE t1(a unique,b,c);
501    INSERT INTO t1 VALUES(4,5,6);
502    SELECT * FROM t1;
503    DROP TABLE t1;
504  }
505} {a 4 b 5 c 6}
506do_test avtrans-6.14 {
507  execsql2 {
508    ROLLBACK;
509    SELECT * FROM t1;
510  }
511} {p 1 q 2 r 3}
512do_test avtrans-6.15 {
513  execsql2 {
514    BEGIN TRANSACTION;
515    DROP TABLE t1;
516    CREATE TABLE t1(a unique,b,c);
517    INSERT INTO t1 VALUES(4,5,6);
518    SELECT * FROM t1;
519    DROP TABLE t1;
520  }
521} {a 4 b 5 c 6}
522do_test avtrans-6.16 {
523  catchsql {
524    COMMIT;
525    SELECT * FROM t1;
526  }
527} {1 {no such table: t1}}
528
529do_test avtrans-6.20 {
530  execsql {
531    CREATE TABLE t1(a integer primary key,b,c);
532    INSERT INTO t1 VALUES(1,-2,-3);
533    INSERT INTO t1 VALUES(4,-5,-6);
534    SELECT * FROM t1;
535  }
536} {1 -2 -3 4 -5 -6}
537do_test avtrans-6.21 {
538  execsql {
539    CREATE INDEX i1 ON t1(b);
540    SELECT * FROM t1 WHERE b<1;
541  }
542} {4 -5 -6 1 -2 -3}
543do_test avtrans-6.22 {
544  execsql {
545    BEGIN TRANSACTION;
546    DROP INDEX i1;
547    SELECT * FROM t1 WHERE b<1;
548    ROLLBACK;
549  }
550} {1 -2 -3 4 -5 -6}
551do_test avtrans-6.23 {
552  execsql {
553    SELECT * FROM t1 WHERE b<1;
554  }
555} {4 -5 -6 1 -2 -3}
556do_test avtrans-6.24 {
557  execsql {
558    BEGIN TRANSACTION;
559    DROP TABLE t1;
560    ROLLBACK;
561    SELECT * FROM t1 WHERE b<1;
562  }
563} {4 -5 -6 1 -2 -3}
564
565do_test avtrans-6.25 {
566  execsql {
567    BEGIN TRANSACTION;
568    DROP INDEX i1;
569    CREATE INDEX i1 ON t1(c);
570    SELECT * FROM t1 WHERE b<1;
571  }
572} {1 -2 -3 4 -5 -6}
573do_test avtrans-6.26 {
574  execsql {
575    SELECT * FROM t1 WHERE c<1;
576  }
577} {4 -5 -6 1 -2 -3}
578do_test avtrans-6.27 {
579  execsql {
580    ROLLBACK;
581    SELECT * FROM t1 WHERE b<1;
582  }
583} {4 -5 -6 1 -2 -3}
584do_test avtrans-6.28 {
585  execsql {
586    SELECT * FROM t1 WHERE c<1;
587  }
588} {1 -2 -3 4 -5 -6}
589
590# The following repeats steps 6.20 through 6.28, but puts a "unique"
591# constraint the first field of the table in order to generate an
592# automatic index.
593#
594do_test avtrans-6.30 {
595  execsql {
596    BEGIN TRANSACTION;
597    DROP TABLE t1;
598    CREATE TABLE t1(a int unique,b,c);
599    COMMIT;
600    INSERT INTO t1 VALUES(1,-2,-3);
601    INSERT INTO t1 VALUES(4,-5,-6);
602    SELECT * FROM t1 ORDER BY a;
603  }
604} {1 -2 -3 4 -5 -6}
605do_test avtrans-6.31 {
606  execsql {
607    CREATE INDEX i1 ON t1(b);
608    SELECT * FROM t1 WHERE b<1;
609  }
610} {4 -5 -6 1 -2 -3}
611do_test avtrans-6.32 {
612  execsql {
613    BEGIN TRANSACTION;
614    DROP INDEX i1;
615    SELECT * FROM t1 WHERE b<1;
616    ROLLBACK;
617  }
618} {1 -2 -3 4 -5 -6}
619do_test avtrans-6.33 {
620  execsql {
621    SELECT * FROM t1 WHERE b<1;
622  }
623} {4 -5 -6 1 -2 -3}
624do_test avtrans-6.34 {
625  execsql {
626    BEGIN TRANSACTION;
627    DROP TABLE t1;
628    ROLLBACK;
629    SELECT * FROM t1 WHERE b<1;
630  }
631} {4 -5 -6 1 -2 -3}
632
633do_test avtrans-6.35 {
634  execsql {
635    BEGIN TRANSACTION;
636    DROP INDEX i1;
637    CREATE INDEX i1 ON t1(c);
638    SELECT * FROM t1 WHERE b<1;
639  }
640} {1 -2 -3 4 -5 -6}
641do_test avtrans-6.36 {
642  execsql {
643    SELECT * FROM t1 WHERE c<1;
644  }
645} {4 -5 -6 1 -2 -3}
646do_test avtrans-6.37 {
647  execsql {
648    DROP INDEX i1;
649    SELECT * FROM t1 WHERE c<1;
650  }
651} {1 -2 -3 4 -5 -6}
652do_test avtrans-6.38 {
653  execsql {
654    ROLLBACK;
655    SELECT * FROM t1 WHERE b<1;
656  }
657} {4 -5 -6 1 -2 -3}
658do_test avtrans-6.39 {
659  execsql {
660    SELECT * FROM t1 WHERE c<1;
661  }
662} {1 -2 -3 4 -5 -6}
663integrity_check avtrans-6.40
664
665ifcapable !floatingpoint {
666  finish_test
667  return
668}
669
670# Test to make sure rollback restores the database back to its original
671# state.
672#
673do_test avtrans-7.1 {
674  execsql {BEGIN}
675  for {set i 0} {$i<1000} {incr i} {
676    set r1 [expr {rand()}]
677    set r2 [expr {rand()}]
678    set r3 [expr {rand()}]
679    execsql "INSERT INTO t2 VALUES($r1,$r2,$r3)"
680  }
681  execsql {COMMIT}
682  set ::checksum [execsql {SELECT md5sum(x,y,z) FROM t2}]
683  set ::checksum2 [
684    execsql {SELECT md5sum(type,name,tbl_name,rootpage,sql) FROM sqlite_master}
685  ]
686  execsql {SELECT count(*) FROM t2}
687} {1001}
688do_test avtrans-7.2 {
689  execsql {SELECT md5sum(x,y,z) FROM t2}
690} $checksum
691do_test avtrans-7.2.1 {
692  execsql {SELECT md5sum(type,name,tbl_name,rootpage,sql) FROM sqlite_master}
693} $checksum2
694do_test avtrans-7.3 {
695  execsql {
696    BEGIN;
697    DELETE FROM t2;
698    ROLLBACK;
699    SELECT md5sum(x,y,z) FROM t2;
700  }
701} $checksum
702do_test avtrans-7.4 {
703  execsql {
704    BEGIN;
705    INSERT INTO t2 SELECT * FROM t2;
706    ROLLBACK;
707    SELECT md5sum(x,y,z) FROM t2;
708  }
709} $checksum
710do_test avtrans-7.5 {
711  execsql {
712    BEGIN;
713    DELETE FROM t2;
714    ROLLBACK;
715    SELECT md5sum(x,y,z) FROM t2;
716  }
717} $checksum
718do_test avtrans-7.6 {
719  execsql {
720    BEGIN;
721    INSERT INTO t2 SELECT * FROM t2;
722    ROLLBACK;
723    SELECT md5sum(x,y,z) FROM t2;
724  }
725} $checksum
726do_test avtrans-7.7 {
727  execsql {
728    BEGIN;
729    CREATE TABLE t3 AS SELECT * FROM t2;
730    INSERT INTO t2 SELECT * FROM t3;
731    ROLLBACK;
732    SELECT md5sum(x,y,z) FROM t2;
733  }
734} $checksum
735do_test avtrans-7.8 {
736  execsql {SELECT md5sum(type,name,tbl_name,rootpage,sql) FROM sqlite_master}
737} $checksum2
738ifcapable tempdb {
739  do_test avtrans-7.9 {
740    execsql {
741      BEGIN;
742      CREATE TEMP TABLE t3 AS SELECT * FROM t2;
743      INSERT INTO t2 SELECT * FROM t3;
744      ROLLBACK;
745      SELECT md5sum(x,y,z) FROM t2;
746    }
747  } $checksum
748}
749do_test avtrans-7.10 {
750  execsql {SELECT md5sum(type,name,tbl_name,rootpage,sql) FROM sqlite_master}
751} $checksum2
752ifcapable tempdb {
753  do_test avtrans-7.11 {
754    execsql {
755      BEGIN;
756      CREATE TEMP TABLE t3 AS SELECT * FROM t2;
757      INSERT INTO t2 SELECT * FROM t3;
758      DROP INDEX i2x;
759      DROP INDEX i2y;
760      CREATE INDEX i3a ON t3(x);
761      ROLLBACK;
762      SELECT md5sum(x,y,z) FROM t2;
763    }
764  } $checksum
765}
766do_test avtrans-7.12 {
767  execsql {SELECT md5sum(type,name,tbl_name,rootpage,sql) FROM sqlite_master}
768} $checksum2
769ifcapable tempdb {
770  do_test avtrans-7.13 {
771    execsql {
772      BEGIN;
773      DROP TABLE t2;
774      ROLLBACK;
775      SELECT md5sum(x,y,z) FROM t2;
776    }
777  } $checksum
778}
779do_test avtrans-7.14 {
780  execsql {SELECT md5sum(type,name,tbl_name,rootpage,sql) FROM sqlite_master}
781} $checksum2
782integrity_check avtrans-7.15
783
784# Arrange for another process to begin modifying the database but abort
785# and die in the middle of the modification.  Then have this process read
786# the database.  This process should detect the journal file and roll it
787# back.  Verify that this happens correctly.
788#
789set fd [open test.tcl w]
790puts $fd {
791  sqlite3 db test.db
792  db eval {
793    PRAGMA default_cache_size=20;
794    BEGIN;
795    CREATE TABLE t3 AS SELECT * FROM t2;
796    DELETE FROM t2;
797  }
798  sqlite_abort
799}
800close $fd
801do_test avtrans-8.1 {
802  catch {exec [info nameofexec] test.tcl}
803  execsql {SELECT md5sum(x,y,z) FROM t2}
804} $checksum
805do_test avtrans-8.2 {
806  execsql {SELECT md5sum(type,name,tbl_name,rootpage,sql) FROM sqlite_master}
807} $checksum2
808integrity_check avtrans-8.3
809
810# In the following sequence of tests, compute the MD5 sum of the content
811# of a table, make lots of modifications to that table, then do a rollback.
812# Verify that after the rollback, the MD5 checksum is unchanged.
813#
814do_test avtrans-9.1 {
815  execsql {
816    PRAGMA default_cache_size=10;
817  }
818  db close
819  sqlite3 db test.db
820  execsql {
821    BEGIN;
822    CREATE TABLE t3(x TEXT);
823    INSERT INTO t3 VALUES(randstr(10,400));
824    INSERT INTO t3 VALUES(randstr(10,400));
825    INSERT INTO t3 SELECT randstr(10,400) FROM t3;
826    INSERT INTO t3 SELECT randstr(10,400) FROM t3;
827    INSERT INTO t3 SELECT randstr(10,400) FROM t3;
828    INSERT INTO t3 SELECT randstr(10,400) FROM t3;
829    INSERT INTO t3 SELECT randstr(10,400) FROM t3;
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    COMMIT;
835    SELECT count(*) FROM t3;
836  }
837} {1024}
838
839# The following procedure computes a "signature" for table "t3".  If
840# T3 changes in any way, the signature should change.
841#
842# This is used to test ROLLBACK.  We gather a signature for t3, then
843# make lots of changes to t3, then rollback and take another signature.
844# The two signatures should be the same.
845#
846proc signature {} {
847  return [db eval {SELECT count(*), md5sum(x) FROM t3}]
848}
849
850# Repeat the following group of tests 20 times for quick testing and
851# 40 times for full testing.  Each iteration of the test makes table
852# t3 a little larger, and thus takes a little longer, so doing 40 tests
853# is more than 2.0 times slower than doing 20 tests.  Considerably more.
854#
855if {[info exists ISQUICK]} {
856  set limit 20
857} else {
858  set limit 40
859}
860
861# Do rollbacks.  Make sure the signature does not change.
862#
863for {set i 2} {$i<=$limit} {incr i} {
864  set ::sig [signature]
865  set cnt [lindex $::sig 0]
866  if {$i%2==0} {
867    execsql {PRAGMA synchronous=FULL}
868  } else {
869    execsql {PRAGMA synchronous=NORMAL}
870  }
871  set sqlite_sync_count 0
872  set sqlite_fullsync_count 0
873  do_test avtrans-9.$i.1-$cnt {
874     execsql {
875       BEGIN;
876       DELETE FROM t3 WHERE random()%10!=0;
877       INSERT INTO t3 SELECT randstr(10,10)||x FROM t3;
878       INSERT INTO t3 SELECT randstr(10,10)||x FROM t3;
879       ROLLBACK;
880     }
881     signature
882  } $sig
883  do_test avtrans-9.$i.2-$cnt {
884     execsql {
885       BEGIN;
886       DELETE FROM t3 WHERE random()%10!=0;
887       INSERT INTO t3 SELECT randstr(10,10)||x FROM t3;
888       DELETE FROM t3 WHERE random()%10!=0;
889       INSERT INTO t3 SELECT randstr(10,10)||x FROM t3;
890       ROLLBACK;
891     }
892     signature
893  } $sig
894  if {$i<$limit} {
895    do_test avtrans-9.$i.3-$cnt {
896       execsql {
897         INSERT INTO t3 SELECT randstr(10,400) FROM t3 WHERE random()%10==0;
898       }
899    } {}
900    if {$tcl_platform(platform)=="unix"} {
901      do_test avtrans-9.$i.4-$cnt {
902         expr {$sqlite_sync_count>0}
903      } 1
904      ifcapable pager_pragmas {
905        do_test avtrans-9.$i.5-$cnt {
906           expr {$sqlite_fullsync_count>0}
907        } [expr {$i%2==0}]
908      } else {
909        do_test avtrans-9.$i.5-$cnt {
910           expr {$sqlite_fullsync_count>0}
911        } {1}
912      }
913    }
914  }
915  set ::pager_old_format 0
916}
917integrity_check avtrans-10.1
918
919finish_test
920