Optimizations to ParseFinalize() to make up for the extra cleanup associated
[sqlite.git] / test / trans.test
blob6b8ad217a02ed9db09bd6baf0d4102ddf7d42eed
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.
16 set testdir [file dirname $argv0]
17 source $testdir/tester.tcl
19 # Create several tables to work with.
21 wal_set_journal_mode
22 do_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}
31 integrity_check trans-1.0.1
32 do_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}
41 do_test trans-1.2.1 {
42   sqlite3_txn_state db
43 } {0}
44 do_test trans-1.2.2 {
45   sqlite3_txn_state db main
46 } {0}
47 do_test trans-1.2.3 {
48   sqlite3_txn_state db temp
49 } {0}
50 do_test trans-1.2.4 {
51   sqlite3_txn_state db no-such-schema
52 } {-1}
54 do_test trans-1.9 {
55   sqlite3 altdb test.db
56   execsql {SELECT b FROM one ORDER BY a} altdb
57 } {one two three}
58 do_test trans-1.10 {
59   execsql {SELECT b FROM two ORDER BY a} altdb
60 } {I V X}
61 integrity_check trans-1.11
62 wal_check_journal_mode trans-1.12
64 # Basic transactions
66 do_test trans-2.1 {
67   set v [catch {execsql {BEGIN}} msg]
68   lappend v $msg
69 } {0 {}}
70 do_test trans-2.1b {
71   sqlite3_txn_state db
72 } {0}
73 do_test trans-2.2 {
74   set v [catch {execsql {END}} msg]
75   lappend v $msg
76 } {0 {}}
77 do_test trans-2.3 {
78   set v [catch {execsql {BEGIN TRANSACTION}} msg]
79   lappend v $msg
80 } {0 {}}
81 do_test trans-2.4 {
82   set v [catch {execsql {COMMIT TRANSACTION}} msg]
83   lappend v $msg
84 } {0 {}}
85 do_test trans-2.5 {
86   set v [catch {execsql {BEGIN TRANSACTION 'foo'}} msg]
87   lappend v $msg
88 } {0 {}}
89 do_test trans-2.6 {
90   set v [catch {execsql {ROLLBACK TRANSACTION 'foo'}} msg]
91   lappend v $msg
92 } {0 {}}
93 do_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}
101 integrity_check trans-2.11
102 wal_check_journal_mode trans-2.12
104 # Check the locking behavior
106 do_test trans-3.1 {
107   execsql {
108     BEGIN;
109     UPDATE one SET a = 0 WHERE 0;
110     SELECT a FROM one ORDER BY a;
111   }
112 } {1 2 3}
113 do_test trans-3.1b {
114   sqlite3_txn_state db
115 } {2}
116 do_test trans-3.1c {
117   sqlite3_txn_state db main
118 } {2}
119 do_test trans-3.1d {
120   sqlite3_txn_state db temp
121 } {0}
123 do_test trans-3.2 {
124   catchsql {
125     SELECT a FROM two ORDER BY a;
126   } altdb
127 } {0 {1 5 10}}
129 do_test trans-3.3 {
130   catchsql {
131     SELECT a FROM one ORDER BY a;
132   } altdb
133 } {0 {1 2 3}}
134 do_test trans-3.4 {
135   catchsql {
136     INSERT INTO one VALUES(4,'four');
137   }
138 } {0 {}}
139 do_test trans-3.5 {
140   catchsql {
141     SELECT a FROM two ORDER BY a;
142   } altdb
143 } {0 {1 5 10}}
144 do_test trans-3.6 {
145   catchsql {
146     SELECT a FROM one ORDER BY a;
147   } altdb
148 } {0 {1 2 3}}
149 do_test trans-3.7 {
150   catchsql {
151     INSERT INTO two VALUES(4,'IV');
152   }
153 } {0 {}}
154 do_test trans-3.8 {
155   catchsql {
156     SELECT a FROM two ORDER BY a;
157   } altdb
158 } {0 {1 5 10}}
159 do_test trans-3.9 {
160   catchsql {
161     SELECT a FROM one ORDER BY a;
162   } altdb
163 } {0 {1 2 3}}
164 do_test trans-3.10 {
165   execsql {END TRANSACTION}
166 } {}
167 do_test trans-3.10b {
168   sqlite3_txn_state db
169 } {0}
172 do_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}}
178 do_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}}
184 do_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}}
190 do_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}}
196 integrity_check trans-3.15
197 wal_check_journal_mode trans-3.16
199 do_test trans-4.1 {
200   set v [catch {execsql {
201     COMMIT;
202   } db} msg]
203   lappend v $msg
204 } {1 {cannot commit - no transaction is active}}
205 do_test trans-4.2 {
206   set v [catch {execsql {
207     ROLLBACK;
208   } db} msg]
209   lappend v $msg
210 } {1 {cannot rollback - no transaction is active}}
211 do_test trans-4.3 {
212   catchsql {
213     BEGIN TRANSACTION;
214     UPDATE two SET a = 0 WHERE 0;
215     SELECT a FROM two ORDER BY a;
216   } db
217 } {0 {1 4 5 10}}
218 do_test trans-4.4 {
219   catchsql {
220     SELECT a FROM two ORDER BY a;
221   } altdb
222 } {0 {1 4 5 10}}
223 do_test trans-4.5 {
224   catchsql {
225     SELECT a FROM one ORDER BY a;
226   } altdb
227 } {0 {1 2 3 4}}
228 do_test trans-4.6 {
229   catchsql {
230     BEGIN TRANSACTION;
231     SELECT a FROM one ORDER BY a;
232   } db
233 } {1 {cannot start a transaction within a transaction}}
234 do_test trans-4.7 {
235   catchsql {
236     SELECT a FROM two ORDER BY a;
237   } altdb
238 } {0 {1 4 5 10}}
239 do_test trans-4.8 {
240   catchsql {
241     SELECT a FROM one ORDER BY a;
242   } altdb
243 } {0 {1 2 3 4}}
244 do_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}}
251 do_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}}
257 do_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}}
263 integrity_check trans-4.12
264 wal_check_journal_mode trans-4.13
265 wal_check_journal_mode trans-4.14 altdb
266 do_test trans-4.98 {
267   altdb close
268   execsql {
269     DROP TABLE one;
270     DROP TABLE two;
271   }
272 } {}
273 integrity_check trans-4.99
275 # Check out the commit/rollback behavior of the database
277 do_test trans-5.1 {
278   execsql {SELECT name FROM sqlite_master WHERE type='table' ORDER BY name}
279 } {}
280 do_test trans-5.2 {
281   execsql {BEGIN TRANSACTION}
282   execsql {SELECT name FROM sqlite_master WHERE type='table' ORDER BY name}
283 } {}
284 do_test trans-5.2b {
285   sqlite3_txn_state db
286 } {1}
287 do_test trans-5.2c {
288   sqlite3_txn_state db main
289 } {1}
290 do_test trans-5.2d {
291   sqlite3_txn_state db temp
292 } {0}
293 do_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}
297 do_test trans-5.4 {
298   execsql {SELECT a,b FROM one ORDER BY b}
299 } {}
300 do_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}
304 do_test trans-5.6 {
305   execsql {ROLLBACK}
306   execsql {SELECT name FROM sqlite_master WHERE type='table' ORDER BY name}
307 } {}
308 do_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}}
315 # Test commits and rollbacks of table CREATE TABLEs, CREATE INDEXs
316 # DROP TABLEs and DROP INDEXs
318 do_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 } {}
325 do_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}
334 do_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}
342 do_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}
350 do_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}
362 do_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}
370 do_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}
379 do_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}
387 do_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}
400 do_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}
408 do_test trans-5.18 {
409   execsql {
410     SELECT * FROM t2;
411   }
412 } {1 2 3}
413 do_test trans-5.19 {
414   execsql {
415     SELECT x FROM t2 WHERE y=2;
416   }
417 } {1}
418 do_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 } {}
428 do_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}}
434 do_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}
442 do_test trans-5.23 {
443   execsql {
444     SELECT * FROM t2;
445   }
446 } {1 2 3}
447 integrity_check trans-5.23
450 # Try to DROP and CREATE tables and indices with the same name
451 # within a transaction.  Make sure ROLLBACK works.
453 do_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}
463 do_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 } {}
473 do_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}
479 do_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}
489 do_test trans-6.5 {
490   execsql2 {
491     ROLLBACK;
492     SELECT * FROM t1;
493   }
494 } {p 1 q 2 r 3}
495 do_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}
505 do_test trans-6.7 {
506   catchsql {
507     COMMIT;
508     SELECT * FROM t1;
509   }
510 } {1 {no such table: t1}}
512 # Repeat on a table with an automatically generated index.
514 do_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}
525 do_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 } {}
534 do_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}
540 do_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}
550 do_test trans-6.14 {
551   execsql2 {
552     ROLLBACK;
553     SELECT * FROM t1;
554   }
555 } {p 1 q 2 r 3}
556 do_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}
566 do_test trans-6.16 {
567   catchsql {
568     COMMIT;
569     SELECT * FROM t1;
570   }
571 } {1 {no such table: t1}}
573 do_test trans-6.20 {
574   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}
581 do_test trans-6.21 {
582   execsql {
583     CREATE INDEX i1 ON t1(b);
584     SELECT * FROM t1 WHERE b<1;
585   }
586 } {4 -5 -6 1 -2 -3}
587 do_test trans-6.22 {
588   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}
595 do_test trans-6.23 {
596   execsql {
597     SELECT * FROM t1 WHERE b<1;
598   }
599 } {4 -5 -6 1 -2 -3}
600 do_test trans-6.24 {
601   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}
609 do_test trans-6.25 {
610   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}
617 do_test trans-6.26 {
618   execsql {
619     SELECT * FROM t1 WHERE c<1;
620   }
621 } {4 -5 -6 1 -2 -3}
622 do_test trans-6.27 {
623   execsql {
624     ROLLBACK;
625     SELECT * FROM t1 WHERE b<1;
626   }
627 } {4 -5 -6 1 -2 -3}
628 do_test trans-6.28 {
629   execsql {
630     SELECT * FROM t1 WHERE c<1;
631   }
632 } {1 -2 -3 4 -5 -6}
634 # 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.
638 do_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}
649 do_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}
655 do_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}
663 do_test trans-6.33 {
664   execsql {
665     SELECT * FROM t1 WHERE b<1;
666   }
667 } {4 -5 -6 1 -2 -3}
668 do_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}
677 do_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}
685 do_test trans-6.36 {
686   execsql {
687     SELECT * FROM t1 WHERE c<1;
688   }
689 } {4 -5 -6 1 -2 -3}
690 do_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}
696 do_test trans-6.38 {
697   execsql {
698     ROLLBACK;
699     SELECT * FROM t1 WHERE b<1;
700   }
701 } {4 -5 -6 1 -2 -3}
702 do_test trans-6.39 {
703   execsql {
704     SELECT * FROM t1 WHERE c<1;
705   }
706 } {1 -2 -3 4 -5 -6}
707 integrity_check trans-6.40
709 # Test to make sure rollback restores the database back to its original
710 # state.
712 do_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}
727 do_test trans-7.2 {
728   execsql {SELECT md5sum(x,y,z) FROM t2}
729 } $checksum
730 do_test trans-7.2.1 {
731   execsql {SELECT md5sum(type,name,tbl_name,rootpage,sql) FROM sqlite_master}
732 } $checksum2
733 do_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
741 do_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
749 do_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
757 do_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
765 do_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
774 do_test trans-7.8 {
775   execsql {SELECT md5sum(type,name,tbl_name,rootpage,sql) FROM sqlite_master}
776 } $checksum2
777 ifcapable 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
788 do_test trans-7.10 {
789   execsql {SELECT md5sum(type,name,tbl_name,rootpage,sql) FROM sqlite_master}
790 } $checksum2
791 ifcapable 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
805 do_test trans-7.12 {
806   execsql {SELECT md5sum(type,name,tbl_name,rootpage,sql) FROM sqlite_master}
807 } $checksum2
808 ifcapable 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
818 do_test trans-7.14 {
819   execsql {SELECT md5sum(type,name,tbl_name,rootpage,sql) FROM sqlite_master}
820 } $checksum2
821 integrity_check trans-7.15
822 wal_check_journal_mode trans-7.16
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.
829 set fd [open test.tcl w]
830 puts $fd {
831   sqlite3_test_control_pending_byte 0x0010000
832   sqlite3 db test.db
833   db eval {
834     PRAGMA default_cache_size=20;
835     BEGIN;
836     CREATE TABLE t3 AS SELECT * FROM t2;
837     DELETE FROM t2;
838   }
839   sqlite_abort
841 close $fd
842 do_test trans-8.1 {
843   catch {exec [info nameofexec] test.tcl}
844   execsql {SELECT md5sum(x,y,z) FROM t2}
845 } $checksum
846 do_test trans-8.2 {
847   execsql {SELECT md5sum(type,name,tbl_name,rootpage,sql) FROM sqlite_master}
848 } $checksum2
849 integrity_check trans-8.3
850 set fd [open test.tcl w]
851 puts $fd {
852   sqlite3_test_control_pending_byte 0x0010000
853   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
863 close $fd
864 do_test trans-8.4 {
865   catch {exec [info nameofexec] test.tcl}
866   execsql {SELECT md5sum(x,y,z) FROM t2}
867 } $checksum
868 do_test trans-8.5 {
869   execsql {SELECT md5sum(type,name,tbl_name,rootpage,sql) FROM sqlite_master}
870 } $checksum2
871 integrity_check trans-8.6
872 wal_check_journal_mode trans-8.7
874 # 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.
878 do_test trans-9.1 {
879   execsql {
880     PRAGMA default_cache_size=10;
881   }
882   db close
883   sqlite3 db test.db
884   execsql {
885     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}
902 wal_check_journal_mode trans-9.1.1
904 # The following procedure computes a "signature" for table "t3".  If
905 # T3 changes in any way, the signature should change.  
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.
911 proc signature {} {
912   return [db eval {SELECT count(*), md5sum(x) FROM t3}]
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.
920 # 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".
924 if {[info exists G(isquick)] || (
925   $TEMP_STORE==3 && [regexp {^pcache[[:digit:]]*$} [permutation]]
926 ) } {
927   set limit 20
928 } elseif {[info exists G(issoak)]} {
929   set limit 100
930 } else {
931   set limit 40
934 # Do rollbacks.  Make sure the signature does not change.
936 for {set i 2} {$i<=$limit} {incr i} {
937   set ::sig [signature]
938   set cnt [lindex $::sig 0]
939   if {$i%2==0} {
940     execsql {PRAGMA fullfsync=ON}
941   } else {
942     execsql {PRAGMA fullfsync=OFF}
943   }
944   set sqlite_sync_count 0
945   set sqlite_fullsync_count 0
946   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} {
968     do_test trans-9.$i.3-$cnt {
969        execsql {
970          INSERT INTO t3 SELECT randstr(10,400) FROM t3 WHERE random()%10==0;
971        }
972     } {}
973     catch flush_async_queue
974     if {$tcl_platform(platform)=="unix"} {
975       do_test trans-9.$i.4-$cnt {
976          expr {$sqlite_sync_count>0}
977       } 1
978       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 {
984           expr {$sqlite_fullsync_count==0}
985         } {1}
986       }
987     }
988   }
990   wal_check_journal_mode trans-9.$i.6-$cnt
991   set ::pager_old_format 0
993    
994 finish_test