adds recent updates to CHANGELOG.md
[sqlcipher.git] / test / trans.test
blobbbaedc5450c65c74586ef7fa61f5be6570fb488c
1 # 2001 September 15
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.  The
12 # focus of this script is database locks.
14 # $Id: trans.test,v 1.41 2009/04/28 16:37:59 danielk1977 Exp $
17 set testdir [file dirname $argv0]
18 source $testdir/tester.tcl
20 # Create several tables to work with.
22 wal_set_journal_mode
23 do_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}
32 integrity_check trans-1.0.1
33 do_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}
42 do_test trans-1.9 {
43   sqlite3 altdb test.db
44   execsql {SELECT b FROM one ORDER BY a} altdb
45 } {one two three}
46 do_test trans-1.10 {
47   execsql {SELECT b FROM two ORDER BY a} altdb
48 } {I V X}
49 integrity_check trans-1.11
50 wal_check_journal_mode trans-1.12
52 # Basic transactions
54 do_test trans-2.1 {
55   set v [catch {execsql {BEGIN}} msg]
56   lappend v $msg
57 } {0 {}}
58 do_test trans-2.2 {
59   set v [catch {execsql {END}} msg]
60   lappend v $msg
61 } {0 {}}
62 do_test trans-2.3 {
63   set v [catch {execsql {BEGIN TRANSACTION}} msg]
64   lappend v $msg
65 } {0 {}}
66 do_test trans-2.4 {
67   set v [catch {execsql {COMMIT TRANSACTION}} msg]
68   lappend v $msg
69 } {0 {}}
70 do_test trans-2.5 {
71   set v [catch {execsql {BEGIN TRANSACTION 'foo'}} msg]
72   lappend v $msg
73 } {0 {}}
74 do_test trans-2.6 {
75   set v [catch {execsql {ROLLBACK TRANSACTION 'foo'}} msg]
76   lappend v $msg
77 } {0 {}}
78 do_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}
86 integrity_check trans-2.11
87 wal_check_journal_mode trans-2.12
89 # Check the locking behavior
91 do_test trans-3.1 {
92   execsql {
93     BEGIN;
94     UPDATE one SET a = 0 WHERE 0;
95     SELECT a FROM one ORDER BY a;
96   }
97 } {1 2 3}
98 do_test trans-3.2 {
99   catchsql {
100     SELECT a FROM two ORDER BY a;
101   } altdb
102 } {0 {1 5 10}}
104 do_test trans-3.3 {
105   catchsql {
106     SELECT a FROM one ORDER BY a;
107   } altdb
108 } {0 {1 2 3}}
109 do_test trans-3.4 {
110   catchsql {
111     INSERT INTO one VALUES(4,'four');
112   }
113 } {0 {}}
114 do_test trans-3.5 {
115   catchsql {
116     SELECT a FROM two ORDER BY a;
117   } altdb
118 } {0 {1 5 10}}
119 do_test trans-3.6 {
120   catchsql {
121     SELECT a FROM one ORDER BY a;
122   } altdb
123 } {0 {1 2 3}}
124 do_test trans-3.7 {
125   catchsql {
126     INSERT INTO two VALUES(4,'IV');
127   }
128 } {0 {}}
129 do_test trans-3.8 {
130   catchsql {
131     SELECT a FROM two ORDER BY a;
132   } altdb
133 } {0 {1 5 10}}
134 do_test trans-3.9 {
135   catchsql {
136     SELECT a FROM one ORDER BY a;
137   } altdb
138 } {0 {1 2 3}}
139 do_test trans-3.10 {
140   execsql {END TRANSACTION}
141 } {}
143 do_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}}
149 do_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}}
155 do_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}}
161 do_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}}
167 integrity_check trans-3.15
168 wal_check_journal_mode trans-3.16
170 do_test trans-4.1 {
171   set v [catch {execsql {
172     COMMIT;
173   } db} msg]
174   lappend v $msg
175 } {1 {cannot commit - no transaction is active}}
176 do_test trans-4.2 {
177   set v [catch {execsql {
178     ROLLBACK;
179   } db} msg]
180   lappend v $msg
181 } {1 {cannot rollback - no transaction is active}}
182 do_test trans-4.3 {
183   catchsql {
184     BEGIN TRANSACTION;
185     UPDATE two SET a = 0 WHERE 0;
186     SELECT a FROM two ORDER BY a;
187   } db
188 } {0 {1 4 5 10}}
189 do_test trans-4.4 {
190   catchsql {
191     SELECT a FROM two ORDER BY a;
192   } altdb
193 } {0 {1 4 5 10}}
194 do_test trans-4.5 {
195   catchsql {
196     SELECT a FROM one ORDER BY a;
197   } altdb
198 } {0 {1 2 3 4}}
199 do_test trans-4.6 {
200   catchsql {
201     BEGIN TRANSACTION;
202     SELECT a FROM one ORDER BY a;
203   } db
204 } {1 {cannot start a transaction within a transaction}}
205 do_test trans-4.7 {
206   catchsql {
207     SELECT a FROM two ORDER BY a;
208   } altdb
209 } {0 {1 4 5 10}}
210 do_test trans-4.8 {
211   catchsql {
212     SELECT a FROM one ORDER BY a;
213   } altdb
214 } {0 {1 2 3 4}}
215 do_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}}
222 do_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}}
228 do_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}}
234 integrity_check trans-4.12
235 wal_check_journal_mode trans-4.13
236 wal_check_journal_mode trans-4.14 altdb
237 do_test trans-4.98 {
238   altdb close
239   execsql {
240     DROP TABLE one;
241     DROP TABLE two;
242   }
243 } {}
244 integrity_check trans-4.99
246 # Check out the commit/rollback behavior of the database
248 do_test trans-5.1 {
249   execsql {SELECT name FROM sqlite_master WHERE type='table' ORDER BY name}
250 } {}
251 do_test trans-5.2 {
252   execsql {BEGIN TRANSACTION}
253   execsql {SELECT name FROM sqlite_master WHERE type='table' ORDER BY name}
254 } {}
255 do_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}
259 do_test trans-5.4 {
260   execsql {SELECT a,b FROM one ORDER BY b}
261 } {}
262 do_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}
266 do_test trans-5.6 {
267   execsql {ROLLBACK}
268   execsql {SELECT name FROM sqlite_master WHERE type='table' ORDER BY name}
269 } {}
270 do_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}}
277 # Test commits and rollbacks of table CREATE TABLEs, CREATE INDEXs
278 # DROP TABLEs and DROP INDEXs
280 do_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 } {}
287 do_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}
296 do_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}
304 do_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}
312 do_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}
324 do_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}
332 do_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}
341 do_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}
349 do_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}
362 do_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}
370 do_test trans-5.18 {
371   execsql {
372     SELECT * FROM t2;
373   }
374 } {1 2 3}
375 do_test trans-5.19 {
376   execsql {
377     SELECT x FROM t2 WHERE y=2;
378   }
379 } {1}
380 do_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 } {}
390 do_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}}
396 do_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}
404 do_test trans-5.23 {
405   execsql {
406     SELECT * FROM t2;
407   }
408 } {1 2 3}
409 integrity_check trans-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 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}
425 do_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 } {}
435 do_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}
441 do_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}
451 do_test trans-6.5 {
452   execsql2 {
453     ROLLBACK;
454     SELECT * FROM t1;
455   }
456 } {p 1 q 2 r 3}
457 do_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}
467 do_test trans-6.7 {
468   catchsql {
469     COMMIT;
470     SELECT * FROM t1;
471   }
472 } {1 {no such table: t1}}
474 # Repeat on a table with an automatically generated index.
476 do_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}
487 do_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 } {}
496 do_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}
502 do_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}
512 do_test trans-6.14 {
513   execsql2 {
514     ROLLBACK;
515     SELECT * FROM t1;
516   }
517 } {p 1 q 2 r 3}
518 do_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}
528 do_test trans-6.16 {
529   catchsql {
530     COMMIT;
531     SELECT * FROM t1;
532   }
533 } {1 {no such table: t1}}
535 do_test trans-6.20 {
536   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}
543 do_test trans-6.21 {
544   execsql {
545     CREATE INDEX i1 ON t1(b);
546     SELECT * FROM t1 WHERE b<1;
547   }
548 } {4 -5 -6 1 -2 -3}
549 do_test trans-6.22 {
550   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}
557 do_test trans-6.23 {
558   execsql {
559     SELECT * FROM t1 WHERE b<1;
560   }
561 } {4 -5 -6 1 -2 -3}
562 do_test trans-6.24 {
563   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}
571 do_test trans-6.25 {
572   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}
579 do_test trans-6.26 {
580   execsql {
581     SELECT * FROM t1 WHERE c<1;
582   }
583 } {4 -5 -6 1 -2 -3}
584 do_test trans-6.27 {
585   execsql {
586     ROLLBACK;
587     SELECT * FROM t1 WHERE b<1;
588   }
589 } {4 -5 -6 1 -2 -3}
590 do_test trans-6.28 {
591   execsql {
592     SELECT * FROM t1 WHERE c<1;
593   }
594 } {1 -2 -3 4 -5 -6}
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
598 # automatic index.
600 do_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}
611 do_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}
617 do_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}
625 do_test trans-6.33 {
626   execsql {
627     SELECT * FROM t1 WHERE b<1;
628   }
629 } {4 -5 -6 1 -2 -3}
630 do_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}
639 do_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}
647 do_test trans-6.36 {
648   execsql {
649     SELECT * FROM t1 WHERE c<1;
650   }
651 } {4 -5 -6 1 -2 -3}
652 do_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}
658 do_test trans-6.38 {
659   execsql {
660     ROLLBACK;
661     SELECT * FROM t1 WHERE b<1;
662   }
663 } {4 -5 -6 1 -2 -3}
664 do_test trans-6.39 {
665   execsql {
666     SELECT * FROM t1 WHERE c<1;
667   }
668 } {1 -2 -3 4 -5 -6}
669 integrity_check trans-6.40
671 # Test to make sure rollback restores the database back to its original
672 # state.
674 do_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}
689 do_test trans-7.2 {
690   execsql {SELECT md5sum(x,y,z) FROM t2}
691 } $checksum
692 do_test trans-7.2.1 {
693   execsql {SELECT md5sum(type,name,tbl_name,rootpage,sql) FROM sqlite_master}
694 } $checksum2
695 do_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
703 do_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
711 do_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
719 do_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
727 do_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
736 do_test trans-7.8 {
737   execsql {SELECT md5sum(type,name,tbl_name,rootpage,sql) FROM sqlite_master}
738 } $checksum2
739 ifcapable 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
750 do_test trans-7.10 {
751   execsql {SELECT md5sum(type,name,tbl_name,rootpage,sql) FROM sqlite_master}
752 } $checksum2
753 ifcapable 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
767 do_test trans-7.12 {
768   execsql {SELECT md5sum(type,name,tbl_name,rootpage,sql) FROM sqlite_master}
769 } $checksum2
770 ifcapable 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
780 do_test trans-7.14 {
781   execsql {SELECT md5sum(type,name,tbl_name,rootpage,sql) FROM sqlite_master}
782 } $checksum2
783 integrity_check trans-7.15
784 wal_check_journal_mode trans-7.16
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.
791 set fd [open test.tcl w]
792 puts $fd {
793   sqlite3_test_control_pending_byte 0x0010000
794   sqlite3 db test.db
795   db eval {
796     PRAGMA default_cache_size=20;
797     BEGIN;
798     CREATE TABLE t3 AS SELECT * FROM t2;
799     DELETE FROM t2;
800   }
801   sqlite_abort
803 close $fd
804 do_test trans-8.1 {
805   catch {exec [info nameofexec] test.tcl}
806   execsql {SELECT md5sum(x,y,z) FROM t2}
807 } $checksum
808 do_test trans-8.2 {
809   execsql {SELECT md5sum(type,name,tbl_name,rootpage,sql) FROM sqlite_master}
810 } $checksum2
811 integrity_check trans-8.3
812 set fd [open test.tcl w]
813 puts $fd {
814   sqlite3_test_control_pending_byte 0x0010000
815   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
825 close $fd
826 do_test trans-8.4 {
827   catch {exec [info nameofexec] test.tcl}
828   execsql {SELECT md5sum(x,y,z) FROM t2}
829 } $checksum
830 do_test trans-8.5 {
831   execsql {SELECT md5sum(type,name,tbl_name,rootpage,sql) FROM sqlite_master}
832 } $checksum2
833 integrity_check trans-8.6
834 wal_check_journal_mode trans-8.7
836 # 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.
840 do_test trans-9.1 {
841   execsql {
842     PRAGMA default_cache_size=10;
843   }
844   db close
845   sqlite3 db test.db
846   execsql {
847     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}
864 wal_check_journal_mode trans-9.1.1
866 # The following procedure computes a "signature" for table "t3".  If
867 # T3 changes in any way, the signature should change.  
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.
873 proc signature {} {
874   return [db eval {SELECT count(*), md5sum(x) FROM t3}]
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.
882 # 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".
886 if {[info exists G(isquick)] || (
887   $TEMP_STORE==3 && [regexp {^pcache[[:digit:]]*$} [permutation]]
888 ) } {
889   set limit 20
890 } elseif {[info exists G(issoak)]} {
891   set limit 100
892 } else {
893   set limit 40
896 # Do rollbacks.  Make sure the signature does not change.
898 for {set i 2} {$i<=$limit} {incr i} {
899   set ::sig [signature]
900   set cnt [lindex $::sig 0]
901   if {$i%2==0} {
902     execsql {PRAGMA fullfsync=ON}
903   } else {
904     execsql {PRAGMA fullfsync=OFF}
905   }
906   set sqlite_sync_count 0
907   set sqlite_fullsync_count 0
908   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} {
930     do_test trans-9.$i.3-$cnt {
931        execsql {
932          INSERT INTO t3 SELECT randstr(10,400) FROM t3 WHERE random()%10==0;
933        }
934     } {}
935     catch flush_async_queue
936     if {$tcl_platform(platform)=="unix"} {
937       do_test trans-9.$i.4-$cnt {
938          expr {$sqlite_sync_count>0}
939       } 1
940       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 {
946           expr {$sqlite_fullsync_count==0}
947         } {1}
948       }
949     }
950   }
952   wal_check_journal_mode trans-9.$i.6-$cnt
953   set ::pager_old_format 0
955    
956 finish_test