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