xref: /sqlite-3.40.0/test/savepoint7.test (revision dca595c4)
1e77593fcSdrh# 2012 March 31
2e77593fcSdrh#
3e77593fcSdrh# The author disclaims copyright to this source code.  In place of
4e77593fcSdrh# a legal notice, here is a blessing:
5e77593fcSdrh#
6e77593fcSdrh#    May you do good and not evil.
7e77593fcSdrh#    May you find forgiveness for yourself and forgive others.
8e77593fcSdrh#    May you share freely, never taking more than you give.
9e77593fcSdrh#
10e77593fcSdrh#***********************************************************************
11e77593fcSdrh#
12e77593fcSdrh# Focus on the interaction between RELEASE and ROLLBACK TO with
13e77593fcSdrh# pending query aborts.  See ticket [27ca74af3c083f787a1c44b11fbb7c53bdbbcf1e].
14e77593fcSdrh#
15e77593fcSdrh
16e77593fcSdrhset testdir [file dirname $argv0]
17e77593fcSdrhsource $testdir/tester.tcl
18e77593fcSdrh
19e77593fcSdrh# The RELEASE of an inner savepoint should not effect pending queries.
20e77593fcSdrh#
21e77593fcSdrhdo_test savepoint7-1.1 {
22e77593fcSdrh  db eval {
23e77593fcSdrh    CREATE TABLE t1(a,b,c);
24e77593fcSdrh    CREATE TABLE t2(x,y,z);
25e77593fcSdrh    INSERT INTO t1 VALUES(1,2,3);
26e77593fcSdrh    INSERT INTO t1 VALUES(4,5,6);
27e77593fcSdrh    INSERT INTO t1 VALUES(7,8,9);
28e77593fcSdrh    SAVEPOINT x1;
29e77593fcSdrh  }
30e77593fcSdrh  db eval {SELECT * FROM t1} {
31e77593fcSdrh    db eval {
32e77593fcSdrh      SAVEPOINT x2;
3385fabf14Sdrh      CREATE TABLE IF NOT EXISTS t3(xyz);
34e77593fcSdrh      INSERT INTO t2 VALUES($a,$b,$c);
35e77593fcSdrh      RELEASE x2;
36e77593fcSdrh    }
37e77593fcSdrh  }
38e77593fcSdrh  db eval {SELECT * FROM t2; RELEASE x1}
39e77593fcSdrh} {1 2 3 4 5 6 7 8 9}
40e77593fcSdrh
41e77593fcSdrhdo_test savepoint7-1.2 {
42e77593fcSdrh  db eval {DELETE FROM t2;}
43e77593fcSdrh  db eval {SELECT * FROM t1} {
44e77593fcSdrh    db eval {
45e77593fcSdrh      SAVEPOINT x2;
46e77593fcSdrh      INSERT INTO t2 VALUES($a,$b,$c);
47e77593fcSdrh      RELEASE x2;
48e77593fcSdrh    }
49e77593fcSdrh  }
5085fabf14Sdrh  db eval {SELECT * FROM t2;}
51e77593fcSdrh} {1 2 3 4 5 6 7 8 9}
52e77593fcSdrh
53e77593fcSdrhdo_test savepoint7-1.3 {
54e77593fcSdrh  db eval {DELETE FROM t2; BEGIN;}
55e77593fcSdrh  db eval {SELECT * FROM t1} {
56e77593fcSdrh    db eval {
57e77593fcSdrh      SAVEPOINT x2;
58e77593fcSdrh      INSERT INTO t2 VALUES($a,$b,$c);
59e77593fcSdrh      RELEASE x2;
60e77593fcSdrh    }
61e77593fcSdrh  }
62e77593fcSdrh  db eval {SELECT * FROM t2; ROLLBACK;}
63e77593fcSdrh} {1 2 3 4 5 6 7 8 9}
64e77593fcSdrh
65e77593fcSdrh# However, a ROLLBACK of an inner savepoint will abort all queries, including
66e77593fcSdrh# queries in outer contexts.
67e77593fcSdrh#
68e77593fcSdrhdo_test savepoint7-2.1 {
6985fabf14Sdrh  db eval {DELETE FROM t2; SAVEPOINT x1; CREATE TABLE t4(abc);}
70e77593fcSdrh  set rc [catch {
71e77593fcSdrh    db eval {SELECT * FROM t1} {
72e77593fcSdrh      db eval {
73e77593fcSdrh        SAVEPOINT x2;
74e77593fcSdrh        INSERT INTO t2 VALUES($a,$b,$c);
75e77593fcSdrh        ROLLBACK TO x2;
76e77593fcSdrh      }
77e77593fcSdrh    }
78e77593fcSdrh  } msg]
79e77593fcSdrh  db eval {RELEASE x1}
80e77593fcSdrh  list $rc $msg [db eval {SELECT * FROM t2}]
8177b1deecSdrh} {1 {abort due to ROLLBACK} {}}
82e77593fcSdrh
83e77593fcSdrhdo_test savepoint7-2.2 {
84e77593fcSdrh  db eval {DELETE FROM t2;}
85e77593fcSdrh  set rc [catch {
86e77593fcSdrh    db eval {SELECT * FROM t1} {
87e77593fcSdrh      db eval {
88e77593fcSdrh        SAVEPOINT x2;
8985fabf14Sdrh        CREATE TABLE t5(pqr);
90e77593fcSdrh        INSERT INTO t2 VALUES($a,$b,$c);
91e77593fcSdrh        ROLLBACK TO x2;
92e77593fcSdrh      }
93e77593fcSdrh    }
94e77593fcSdrh  } msg]
95e77593fcSdrh  list $rc $msg [db eval {SELECT * FROM t2}]
9677b1deecSdrh} {1 {abort due to ROLLBACK} {}}
97e77593fcSdrh
98*dca595c4Sdrh# Ticket: https://www.sqlite.org/src/tktview/7f7f8026eda387d544b
99*dca595c4Sdrh# Segfault in the in-memory journal logic triggered by a tricky
100*dca595c4Sdrh# combination of SAVEPOINT operations.
101*dca595c4Sdrh#
102*dca595c4Sdrhunset -nocomplain i
103*dca595c4Sdrhfor {set i 248} {$i<=253} {incr i} {
104*dca595c4Sdrh  do_test savepoint7-3.$i {
105*dca595c4Sdrh    db close
106*dca595c4Sdrh    forcedelete test.db
107*dca595c4Sdrh    sqlite3 db test.db
108*dca595c4Sdrh    db eval {
109*dca595c4Sdrh      PRAGMA page_size=1024;
110*dca595c4Sdrh      PRAGMA temp_store=MEMORY;
111*dca595c4Sdrh      BEGIN;
112*dca595c4Sdrh      CREATE TABLE t1(x INTEGER PRIMARY KEY, y TEXT);
113*dca595c4Sdrh      WITH RECURSIVE c(x) AS (VALUES(1) UNION SELECT x+1 FROM c WHERE x<$::i)
114*dca595c4Sdrh      INSERT INTO t1(x,y) SELECT x*10, printf('%04d%.800c',x,'*') FROM c;
115*dca595c4Sdrh      SAVEPOINT one;
116*dca595c4Sdrh        SELECT count(*) FROM t1;
117*dca595c4Sdrh        WITH RECURSIVE c(x) AS (VALUES(1) UNION SELECT x+1 FROM c WHERE x<$::i)
118*dca595c4Sdrh        INSERT INTO t1(x,y) SELECT x*10+1, printf('%04d%.800c',x,'*') FROM c;
119*dca595c4Sdrh      ROLLBACK TO one;
120*dca595c4Sdrh        SELECT count(*) FROM t1;
121*dca595c4Sdrh        SAVEPOINT twoB;
122*dca595c4Sdrh          WITH RECURSIVE c(x) AS (VALUES(1) UNION SELECT x+1 FROM c WHERE x<10)
123*dca595c4Sdrh          INSERT INTO t1(x,y) SELECT x*10+2, printf('%04d%.800c',x,'*') FROM c;
124*dca595c4Sdrh        ROLLBACK TO twoB;
125*dca595c4Sdrh      RELEASE one;
126*dca595c4Sdrh      COMMIT;
127*dca595c4Sdrh    }
128*dca595c4Sdrh  } [list $i $i]
129*dca595c4Sdrh}
130*dca595c4Sdrh
131*dca595c4Sdrh
132e77593fcSdrhfinish_test
133