]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Cherry-pick the multi-file transaction fix for ticket [f3e5abed55] out of
authordrh <drh@noemail.net>
Fri, 30 Jul 2010 11:20:35 +0000 (11:20 +0000)
committerdrh <drh@noemail.net>
Fri, 30 Jul 2010 11:20:35 +0000 (11:20 +0000)
the experimental branch.

FossilOrigin-Name: 40f7f0a583e6bba66cd006253a0ef4623ea74f17

manifest
manifest.uuid
src/pager.c
src/pager.h
src/vdbeaux.c
test/tkt-f3e5abed55.test [new file with mode: 0644]

index 0279e04f113d808a0b5b0179423eec2ca4f4c87f..fbacb619e7ea3e44f16dcdcab4968bddbb048b74 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,8 @@
-C Add\stests\sto\scheck\sthat\sthe\sICU\sregexp()\sfunction\scan\sonly\sbe\scalled\swith\sexactly\stwo\sarguments.
-D 2010-07-30T05:06:05
+-----BEGIN PGP SIGNED MESSAGE-----
+Hash: SHA1
+
+C Cherry-pick\sthe\smulti-file\stransaction\sfix\sfor\sticket\s[f3e5abed55]\sout\sof\nthe\sexperimental\sbranch.
+D 2010-07-30T11:20:36
 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
 F Makefile.in ec08dc838fd8110fe24c92e5130bcd91cbb1ff2e
 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
@@ -156,8 +159,8 @@ F src/os_common.h a8f95b81eca8a1ab8593d23e94f8a35f35d4078f
 F src/os_os2.c 72d0b2e562952a2464308c4ce5f7913ac10bef3e
 F src/os_unix.c 3109e0e5a0d5551bab2e8c7322b20a3b8b171248
 F src/os_win.c 1f8b0a1a5bcf6289e7754d0d3c16cec16d4c93ab
-F src/pager.c 33117640d8e0058dbf705b95e20ebf246cbb4bc1
-F src/pager.h 879fdde5a102d2f21a3135d6f647530b21c2796c
+F src/pager.c d559cc0bb784fe5f5b812b2bc2329f09231515a5
+F src/pager.h 80726162dc3942f59ab27b738fb667b9ba0a89d5
 F src/parse.y 12b7ebd61ea54f0e1b1083ff69cc2c8ce9353d58
 F src/pcache.c 1e9aa2dbc0845b52e1b51cc39753b6d1e041cb07
 F src/pcache.h c683390d50f856d4cd8e24342ae62027d1bb6050
@@ -222,7 +225,7 @@ F src/vdbe.c cefff41564b68a412e65e6a1013ec1b1c1ece6c4
 F src/vdbe.h 4de0efb4b0fdaaa900cf419b35c458933ef1c6d2
 F src/vdbeInt.h ffd68c4d4229227a5089bec53a1c635146177abc
 F src/vdbeapi.c d0f4407e465f261780ad725c1caece7d66a6aa35
-F src/vdbeaux.c 77442ab4233858cf603910429033fbbd997ecdef
+F src/vdbeaux.c 8a443e73760ca65ffdfda3e26df4c8c90eeefa11
 F src/vdbeblob.c 258a6010ba7a82b72b327fb24c55790655689256
 F src/vdbemem.c 5e579abf6532001dfbee0e640dc34eae897a9807
 F src/vdbetrace.c 864cef96919323482ebd9986f2132435115e9cc2
@@ -645,6 +648,7 @@ F test/tkt-9d68c883.test 458f7d82a523d7644b54b497c986378a7d8c8b67
 F test/tkt-cbd054fa6b.test f14f97ea43662e6f70c9e63287081e8be5d9d589
 F test/tkt-d11f09d36e.test fb44f7961aa6d4b632fb7b9768239832210b5fc7
 F test/tkt-d82e3f3721.test 731359dfdcdb36fea0559cd33fec39dd0ceae8e6
+F test/tkt-f3e5abed55.test 91713833e266fbdc60f2030e05647ad4762073f6
 F test/tkt-f777251dc7a.test 6f24c053bc5cdb7e1e19be9a72c8887cf41d5e87
 F test/tkt-f973c7ac31.test 1da0ed15ec2c7749fb5ce2828cd69d07153ad9f4
 F test/tkt-fc62af4523.test 72825d3febdedcd5593a27989fc05accdbfc2bb4
@@ -839,7 +843,14 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff
 F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224
 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f
-P d37443d33388b402e610a00c362a1e2e79548801
-R 1df44901de4b741a545cdb85506640b4
-U dan
-Z 47b66d0e2bb0d61fe912692f971ceef4
+P 451d965742cc219db709939b4ba1da2f2343dbce
+R b0221ec16dca16ffff1bd5b40fa2847e
+U drh
+Z 3292246f79754c1a33410d74f4888b7e
+-----BEGIN PGP SIGNATURE-----
+Version: GnuPG v1.4.6 (GNU/Linux)
+
+iD8DBQFMUrWIoxKgR168RlERAgl9AJ9pHsRDtGgzTlt5S8NSiNWiQ7ew2QCdH2kx
+84Gf1zkCE4fUgXSzHJvHTGU=
+=LLzG
+-----END PGP SIGNATURE-----
index 98e63518650b59628d0ec7dbfeeab0127d6a9a90..1ceb992a2364822ab7422e906cafa70397305c73 100644 (file)
@@ -1 +1 @@
-451d965742cc219db709939b4ba1da2f2343dbce
\ No newline at end of file
+40f7f0a583e6bba66cd006253a0ef4623ea74f17
\ No newline at end of file
index d5bbae145c6ab7b2f9cc7795fcbd62df3c432c93..003ff6a2d6485e9805bf8007f83e99cebedad261 100644 (file)
@@ -5061,6 +5061,26 @@ int sqlite3PagerSync(Pager *pPager){
   return rc;
 }
 
+/*
+** This function may only be called while a write-transaction is active in
+** rollback. If the connection is in WAL mode, this call is a no-op. 
+** Otherwise, if the connection does not already have an EXCLUSIVE lock on 
+** the database file, an attempt is made to obtain one.
+**
+** If the EXCLUSIVE lock is already held or the attempt to obtain it is
+** successful, or the connection is in WAL mode, SQLITE_OK is returned.
+** Otherwise, either SQLITE_BUSY or an SQLITE_IOERR_XXX error code is 
+** returned.
+*/
+int sqlite3PagerExclusiveLock(Pager *pPager){
+  int rc = SQLITE_OK;
+  assert( pPager->state>=PAGER_RESERVED );
+  if( 0==pagerUseWal(pPager) ){
+    rc = pager_wait_on_lock(pPager, PAGER_EXCLUSIVE);
+  }
+  return rc;
+}
+
 /*
 ** Sync the database file for the pager pPager. zMaster points to the name
 ** of a master journal file that should be written into the individual
index 6036827e43f504fd70e2e3bf73b5d3362bc698b5..3b724c4ba88de6a6cc993ebc7f805616db5cc6a8 100644 (file)
@@ -129,6 +129,7 @@ void *sqlite3PagerGetExtra(DbPage *);
 int sqlite3PagerPagecount(Pager*, int*);
 int sqlite3PagerBegin(Pager*, int exFlag, int);
 int sqlite3PagerCommitPhaseOne(Pager*,const char *zMaster, int);
+int sqlite3PagerExclusiveLock(Pager*);
 int sqlite3PagerSync(Pager *pPager);
 int sqlite3PagerCommitPhaseTwo(Pager*);
 int sqlite3PagerRollback(Pager*);
index c7cd3e4284381f74cd7f49c963fe1cef8ef6c56d..295a8c3a8d2d9cd840b83b38b7905bb95fa6ae5a 100644 (file)
@@ -1646,9 +1646,6 @@ static int vdbeCommit(sqlite3 *db, Vdbe *p){
   ** to the transaction.
   */
   rc = sqlite3VtabSync(db, &p->zErrMsg);
-  if( rc!=SQLITE_OK ){
-    return rc;
-  }
 
   /* This loop determines (a) if the commit hook should be invoked and
   ** (b) how many database files have open write transactions, not 
@@ -1656,13 +1653,17 @@ static int vdbeCommit(sqlite3 *db, Vdbe *p){
   ** one database file has an open write transaction, a master journal
   ** file is required for an atomic commit.
   */ 
-  for(i=0; i<db->nDb; i++){ 
+  for(i=0; rc==SQLITE_OK && i<db->nDb; i++){ 
     Btree *pBt = db->aDb[i].pBt;
     if( sqlite3BtreeIsInTrans(pBt) ){
       needXcommit = 1;
       if( i!=1 ) nTrans++;
+      rc = sqlite3PagerExclusiveLock(sqlite3BtreePager(pBt));
     }
   }
+  if( rc!=SQLITE_OK ){
+    return rc;
+  }
 
   /* If there are any write-transactions at all, invoke the commit hook */
   if( needXcommit && db->xCommitCallback ){
@@ -1801,6 +1802,7 @@ static int vdbeCommit(sqlite3 *db, Vdbe *p){
       }
     }
     sqlite3OsCloseFree(pMaster);
+    assert( rc!=SQLITE_BUSY );
     if( rc!=SQLITE_OK ){
       sqlite3DbFree(db, zMaster);
       return rc;
diff --git a/test/tkt-f3e5abed55.test b/test/tkt-f3e5abed55.test
new file mode 100644 (file)
index 0000000..d574480
--- /dev/null
@@ -0,0 +1,113 @@
+# 2010 July 29
+#
+# 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.
+#
+#***********************************************************************
+#
+
+set testdir [file dirname $argv0]
+source $testdir/tester.tcl
+source $testdir/malloc_common.tcl
+
+foreach f [glob -nocomplain test.db*mj*] { file delete -force $f }
+file delete -force test.db2
+
+do_test tkt-f3e5abed55-1.1 {
+  execsql {
+    ATTACH 'test.db2' AS aux;
+    CREATE TABLE main.t1(a, b);
+    CREATE TABLE aux.t2(c, d);
+  }
+} {}
+
+do_test tkt-f3e5abed55-1.2 {
+  glob -nocomplain test.db*mj*
+} {}
+
+do_test tkt-f3e5abed55-1.3 {
+  sqlite3 db2 test.db
+  execsql { BEGIN; SELECT * FROM t1 } db2
+} {}
+
+do_test tkt-f3e5abed55-1.4 {
+  execsql {
+    BEGIN;
+      INSERT INTO t1 VALUES(1, 2);
+      INSERT INTO t2 VALUES(1, 2);
+  }
+  catchsql COMMIT
+} {1 {database is locked}}
+
+do_test tkt-f3e5abed55-1.5 {
+  execsql COMMIT db2
+  execsql COMMIT
+} {}
+
+do_test tkt-f3e5abed55-1.6 {
+  glob -nocomplain test.db*mj*
+} {}
+foreach f [glob -nocomplain test.db*mj*] { file delete -force $f }
+db close
+db2 close
+
+
+
+# Set up a testvfs so that the next time SQLite tries to delete the
+# file "test.db-journal", a snapshot of the current file-system contents
+# is taken.
+#
+testvfs tvfs -default 1
+tvfs script xDelete
+tvfs filter xDelete
+proc xDelete {method file args} {
+  if {[file tail $file] == "test.db-journal"} {
+    faultsim_save
+    tvfs filter {}
+  }
+  return "SQLITE_OK"
+}
+
+sqlite3 db  test.db
+sqlite3 db2 test.db
+do_test tkt-f3e5abed55-2.1 {
+  execsql {
+    ATTACH 'test.db2' AS aux;
+    BEGIN;
+      INSERT INTO t1 VALUES(3, 4);
+      INSERT INTO t2 VALUES(3, 4);
+  }
+} {}
+do_test tkt-f3e5abed55-2.2 {
+  execsql { BEGIN; SELECT * FROM t1 } db2
+} {1 2}
+do_test tkt-f3e5abed55-2.3 {
+  catchsql COMMIT
+} {1 {database is locked}}
+
+do_test tkt-f3e5abed55-2.4 {
+  execsql COMMIT db2
+  execsql {
+    COMMIT;
+    SELECT * FROM t1;
+    SELECT * FROM t2;
+  }
+} {1 2 3 4 1 2 3 4}
+do_test tkt-f3e5abed55-2.5 {
+  db close
+  db2 close
+  faultsim_restore_and_reopen
+  execsql {
+    ATTACH 'test.db2' AS aux;
+    SELECT * FROM t1;
+    SELECT * FROM t2;
+  }
+} {1 2 3 4 1 2 3 4}
+
+
+finish_test
+