]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Add test cases for concurrent transactions and long-lived SELECT statements.
authordan <dan@noemail.net>
Thu, 27 Aug 2015 19:22:56 +0000 (19:22 +0000)
committerdan <dan@noemail.net>
Thu, 27 Aug 2015 19:22:56 +0000 (19:22 +0000)
FossilOrigin-Name: fd4798cb7af263409c20d3cf81236b830bd68570

manifest
manifest.uuid
test/concurrent2.test

index 4440e87c4050116e11f941ca95e1887ae85adb86..a9bcad179fd008abd73aafa56dc157b9a3063abe 100644 (file)
--- 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
index 72a90a6e055caf689f1da3808242b9ac6e551433..55734e47bad86ca9887dffd23fe56ccfe104bad1 100644 (file)
@@ -1 +1 @@
-fc17f73170a27c2fe511ed6b6d488535c4e35bae
\ No newline at end of file
+fd4798cb7af263409c20d3cf81236b830bd68570
\ No newline at end of file
index 8650caea2094c88b9c8a304aab7907f273bbb601..aa2cd6221733aa3eec8d6850cdf091973de4df9c 100644 (file)
@@ -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;
+    }
+  } {}
 }