From: dan Date: Thu, 27 Aug 2015 19:22:56 +0000 (+0000) Subject: Add test cases for concurrent transactions and long-lived SELECT statements. X-Git-Url: http://git.ipfire.org/gitweb/?a=commitdiff_plain;h=6b3e51bd330c9510695fbbd6443ab3f7a5e3d029;p=thirdparty%2Fsqlite.git Add test cases for concurrent transactions and long-lived SELECT statements. FossilOrigin-Name: fd4798cb7af263409c20d3cf81236b830bd68570 --- diff --git a/manifest b/manifest index 4440e87c40..a9bcad179f 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -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 @@ -525,7 +525,7 @@ F test/colmeta.test 2c765ea61ee37bc43bbe6d6047f89004e6508eb1 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 @@ -1382,7 +1382,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 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 diff --git a/manifest.uuid b/manifest.uuid index 72a90a6e05..55734e47ba 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -fc17f73170a27c2fe511ed6b6d488535c4e35bae \ No newline at end of file +fd4798cb7af263409c20d3cf81236b830bd68570 \ No newline at end of file diff --git a/test/concurrent2.test b/test/concurrent2.test index 8650caea20..aa2cd62217 100644 --- a/test/concurrent2.test +++ b/test/concurrent2.test @@ -427,18 +427,25 @@ do_multiclient_test tn { } {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; @@ -446,10 +453,99 @@ do_multiclient_test tn { } } {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; + } + } {} }