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