Merge updates from trunk.
[sqlite.git] / test / savepoint7.test
blob59c3cd6cdca08d45b1aa2f8ef97437a4406c45c8
1 # 2012 March 31
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 #***********************************************************************
12 # Focus on the interaction between RELEASE and ROLLBACK TO with
13 # pending query aborts.  See ticket [27ca74af3c083f787a1c44b11fbb7c53bdbbcf1e].
16 set testdir [file dirname $argv0]
17 source $testdir/tester.tcl
19 # The RELEASE of an inner savepoint should not effect pending queries.
21 do_test savepoint7-1.1 {
22   db eval {
23     CREATE TABLE t1(a,b,c);
24     CREATE TABLE t2(x,y,z);
25     INSERT INTO t1 VALUES(1,2,3);
26     INSERT INTO t1 VALUES(4,5,6);
27     INSERT INTO t1 VALUES(7,8,9);
28     SAVEPOINT x1;
29   }
30   db eval {SELECT * FROM t1} {
31     db eval {
32       SAVEPOINT x2;
33       CREATE TABLE IF NOT EXISTS t3(xyz);
34       INSERT INTO t2 VALUES($a,$b,$c);
35       RELEASE x2;
36     }
37   }
38   db eval {SELECT * FROM t2; RELEASE x1}
39 } {1 2 3 4 5 6 7 8 9}
41 do_test savepoint7-1.2 {
42   db eval {DELETE FROM t2;}
43   db eval {SELECT * FROM t1} {
44     db eval {
45       SAVEPOINT x2;
46       INSERT INTO t2 VALUES($a,$b,$c);
47       RELEASE x2;
48     }
49   }
50   db eval {SELECT * FROM t2;}
51 } {1 2 3 4 5 6 7 8 9}
53 do_test savepoint7-1.3 {
54   db eval {DELETE FROM t2; BEGIN;}
55   db eval {SELECT * FROM t1} {
56     db eval {
57       SAVEPOINT x2;
58       INSERT INTO t2 VALUES($a,$b,$c);
59       RELEASE x2;
60     }
61   }
62   db eval {SELECT * FROM t2; ROLLBACK;}
63 } {1 2 3 4 5 6 7 8 9}
65 # However, a ROLLBACK of an inner savepoint will abort all queries, including
66 # queries in outer contexts.
68 do_test savepoint7-2.1 {
69   db eval {DELETE FROM t2; SAVEPOINT x1; CREATE TABLE t4(abc);}
70   set rc [catch {
71     db eval {SELECT * FROM t1} {
72       db eval {
73         SAVEPOINT x2;
74         INSERT INTO t2 VALUES($a,$b,$c);
75         ROLLBACK TO x2;
76       }
77     }
78   } msg]
79   db eval {RELEASE x1}
80   list $rc $msg [db eval {SELECT * FROM t2}]
81 } {1 {abort due to ROLLBACK} {}}
83 do_test savepoint7-2.2 {
84   db eval {DELETE FROM t2;}
85   set rc [catch {
86     db eval {SELECT * FROM t1} {
87       db eval {
88         SAVEPOINT x2;
89         CREATE TABLE t5(pqr);
90         INSERT INTO t2 VALUES($a,$b,$c);
91         ROLLBACK TO x2;
92       }
93     }
94   } msg]
95   list $rc $msg [db eval {SELECT * FROM t2}]
96 } {1 {abort due to ROLLBACK} {}}
98 # Ticket: https://www.sqlite.org/src/tktview/7f7f8026eda387d544b
99 # Segfault in the in-memory journal logic triggered by a tricky
100 # combination of SAVEPOINT operations.
102 unset -nocomplain i
103 for {set i 248} {$i<=253} {incr i} {
104   do_test savepoint7-3.$i {
105     db close
106     forcedelete test.db
107     sqlite3 db test.db
108     db eval {
109       PRAGMA page_size=1024;
110       PRAGMA temp_store=MEMORY;
111       BEGIN;
112       CREATE TABLE t1(x INTEGER PRIMARY KEY, y TEXT);
113       WITH RECURSIVE c(x) AS (VALUES(1) UNION SELECT x+1 FROM c WHERE x<$::i)
114       INSERT INTO t1(x,y) SELECT x*10, printf('%04d%.800c',x,'*') FROM c;
115       SAVEPOINT one;
116         SELECT count(*) FROM t1;
117         WITH RECURSIVE c(x) AS (VALUES(1) UNION SELECT x+1 FROM c WHERE x<$::i)
118         INSERT INTO t1(x,y) SELECT x*10+1, printf('%04d%.800c',x,'*') FROM c;
119       ROLLBACK TO one;
120         SELECT count(*) FROM t1;
121         SAVEPOINT twoB;
122           WITH RECURSIVE c(x) AS (VALUES(1) UNION SELECT x+1 FROM c WHERE x<10)
123           INSERT INTO t1(x,y) SELECT x*10+2, printf('%04d%.800c',x,'*') FROM c;
124         ROLLBACK TO twoB;
125       RELEASE one;
126       COMMIT;
127     }
128   } [list $i $i]
132 finish_test