-C Fix\sa\sproblem\swhereby\sconcurrent\stransactions\swould\snot\sconsider\spages\sread\sby\sthe\stransaction\sbefore\sthe\sfirst\swrite\sstatement.
-D 2015-08-27T17:42:38.260
+C Add\stest\scases\sfor\sconcurrent\stransactions\sand\slong-lived\sSELECT\sstatements.
+D 2015-08-27T19:22:56.303
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
F Makefile.in e2218eb228374422969de7b1680eda6864affcef
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
F test/colname.test 08948a4809d22817e0e5de89c7c0a8bd90cb551b
F test/concfault.test 500f17c3fcfe7705114422bcc6ddd3c740001a43
F test/concurrent.test 634b6a88f1942f5d68cc89d4d5efa2b11ba7913c
-F test/concurrent2.test d42aaa1d0aaf2c41c8d5de204962b125b411557d
+F test/concurrent2.test f20913d376d993a85f28ef3323f09d4cba37206a
F test/concurrent3.test 0a5f7e3036d1eccf0782d7153ac21f5f222e9468
F test/conflict.test 841bcf7cabbfca39c577eb8411ea8601843b46a8
F test/conflict2.test 0d3af4fb534fa1bd020c79960bb56e4d52655f09
F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b
F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
-P 69394ddaa2bc9d26477b4359c676c598b733ac9f
-R aacab69ab35db4167de1724271774606
+P fc17f73170a27c2fe511ed6b6d488535c4e35bae
+R 54233c250c37b5d4c5cad57267aa2abd
U dan
-Z d9ef073e0b6bc6533e113c00c2daa9fc
+Z 1ef37227dc1b9c5caa6e609be7886347
} {0 {}}
}
+#-------------------------------------------------------------------------
+# Test that even if a SELECT statement appears before all writes within
+# a CONCURRENT transaction, the pages it reads are still considered when
+# considering whether or not the transaction may be committed.
+#
do_multiclient_test tn {
- do_test 10.$tn.1 {
+ do_test 10.$tn.1.1 {
sql1 {
PRAGMA journal_mode = wal;
CREATE TABLE t1(a);
CREATE TABLE t2(b);
+ CREATE TABLE t3(c);
INSERT INTO t1 VALUES(1), (2), (3);
INSERT INTO t2 VALUES(1), (2), (3);
+ INSERT INTO t3 VALUES(1), (2), (3);
}
} {wal}
- do_test 10.$tn.2 {
+ do_test 10.$tn.1.2 {
sql1 {
BEGIN CONCURRENT;
SELECT * FROM t1;
}
} {1 2 3}
- do_test 10.$tn.3 {
+ do_test 10.$tn.1.3 {
sql2 { INSERT INTO t1 VALUES(4) }
list [catch {sql1 COMMIT} msg] $msg
} {1 {database is locked}}
+ sql1 ROLLBACK
+
+ # In this case, because the "SELECT * FROM t1" is first stepped before
+ # the "BEGIN CONCURRENT", the pages it reads are not recorded by the
+ # pager object. And so the transaction can be committed. Technically
+ # this behaviour (the effect of an ongoing SELECT on a BEGIN CONCURRENT
+ # transacation) is undefined.
+ #
+ do_test 10.$tn.2.1 {
+ code1 {
+ set ::stmt [sqlite3_prepare db "SELECT * FROM t1" -1 dummy]
+ sqlite3_step $::stmt
+ }
+ } {SQLITE_ROW}
+ do_test 10.$tn.2.2 {
+ sql1 {
+ BEGIN CONCURRENT;
+ INSERT INTO t2 VALUES(4);
+ }
+ code1 {
+ set res [list]
+ lappend res [sqlite3_column_int $::stmt 0]
+ while {[sqlite3_step $::stmt]=="SQLITE_ROW"} {
+ lappend res [sqlite3_column_int $::stmt 0]
+ }
+ sqlite3_finalize $::stmt
+ set res
+ }
+ } {1 2 3 4}
+ do_test 10.$tn.2.3 {
+ sql2 { INSERT INTO t1 VALUES(5) }
+ sql1 COMMIT
+ } {}
+
+ # More tests surrounding long-lived prepared statements and concurrent
+ # transactions.
+ do_test 10.$tn.3.1 {
+ sql1 {
+ BEGIN CONCURRENT;
+ SELECT * FROM t1;
+ COMMIT;
+ }
+ sql1 {
+ BEGIN CONCURRENT;
+ INSERT INTO t2 VALUES(5);
+ }
+ sql2 {
+ INSERT INTO t1 VALUES(5);
+ }
+ sql1 COMMIT
+ sql3 {
+ SELECT * FROM t2;
+ }
+ } {1 2 3 4 5}
+ do_test 10.$tn.3.2 {
+ sql1 {
+ BEGIN CONCURRENT;
+ SELECT * FROM t1;
+ ROLLBACK;
+ }
+ sql1 {
+ BEGIN CONCURRENT;
+ INSERT INTO t2 VALUES(6);
+ }
+ sql2 {
+ INSERT INTO t1 VALUES(6);
+ }
+ sql1 COMMIT
+ sql3 { SELECT * FROM t2 }
+ } {1 2 3 4 5 6}
+ do_test 10.$tn.3.3 {
+ sql1 { BEGIN CONCURRENT }
+ code1 {
+ set ::stmt [sqlite3_prepare db "SELECT * FROM t1" -1 dummy]
+ sqlite3_step $::stmt
+ }
+ sql1 {
+ INSERT INTO t2 VALUES(7);
+ SELECT * FROM t3;
+ ROLLBACK;
+ BEGIN CONCURRENT;
+ }
+ sql2 { INSERT INTO t3 VALUES(5) }
+ code1 { sqlite3_finalize $::stmt }
+ sql1 {
+ INSERT INTO t2 VALUES(8);
+ COMMIT;
+ }
+ } {}
}