]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Refactor and simplify the logic used to change journalmode.
authordrh <drh@noemail.net>
Fri, 11 Jun 2010 17:01:24 +0000 (17:01 +0000)
committerdrh <drh@noemail.net>
Fri, 11 Jun 2010 17:01:24 +0000 (17:01 +0000)
FossilOrigin-Name: 95cc3f6fdec5494560c3cd4439d06870d1c62506

manifest
manifest.uuid
src/backup.c
src/build.c
src/pager.c
src/pager.h
src/vacuum.c
src/vdbe.c

index 359f5b6cd51d39e4b86fdce68d28fb87cfb5ab23..c374482ea87630fcb14379b5e9bb9b4de18986a3 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,8 +1,8 @@
 -----BEGIN PGP SIGNED MESSAGE-----
 Hash: SHA1
 
-C Adding\soriginal\sart\sfor\sthe\snew\sSQLite\slogo.
-D 2010-06-10T16:25:55
+C Refactor\sand\ssimplify\sthe\slogic\sused\sto\schange\sjournalmode.
+D 2010-06-11T17:01:25
 F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0
 F Makefile.in a5cad1f8f3e021356bfcc6c77dc16f6f1952bbc3
 F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654
@@ -113,13 +113,13 @@ F src/alter.c a9ff6f14b3935502537e90194b66c7bc79bed317
 F src/analyze.c 3457a2af126eb78f20ad239c225a2c8ed61b78b6
 F src/attach.c 47b230972b52580e3b3bd6ee69e55f3a043b615b
 F src/auth.c 523da7fb4979469955d822ff9298352d6b31de34
-F src/backup.c de9809091b3b99f69e37261c133f7f8b19f6eca6
+F src/backup.c 3dc89da1da8b948554d5daedab5fec1097188a2d
 F src/bitvec.c 06ad2c36a9c3819c0b9cbffec7b15f58d5d834e0
 F src/btmutex.c 96a12f50f7a17475155971a241d85ec5171573ff
 F src/btree.c 5934a9f5a328488cca392766bb841ff41c9083a9
 F src/btree.h dd83041eda10c17daf023257c1fc883b5f71f85a
 F src/btreeInt.h b0c87f6725b06a0aa194a6d25d54b16ce9d6e291
-F src/build.c fa9bf633653e03111dc6fd406912cfb3c047bb85
+F src/build.c 9d48f4023d5e3d0a6807f1f531d8d7187d252c57
 F src/callback.c 01843bdf4b0420fd28046525d150fcd9802931a9
 F src/complete.c dc1d136c0feee03c2f7550bafc0d29075e36deac
 F src/ctime.c 51553a859994d01d8bf3500747f66a890c459774
@@ -159,8 +159,8 @@ F src/os_common.h a8f95b81eca8a1ab8593d23e94f8a35f35d4078f
 F src/os_os2.c 665876d5eec7585226b0a1cf5e18098de2b2da19
 F src/os_unix.c 12051d37e533cdaa8bb13c9d9fe2a13e08552187
 F src/os_win.c 0cf1f571546f165001e2391b5d4a4a16d86977d3
-F src/pager.c dde0b7447763299ebc4f27a7c3ab25b3b136c69f
-F src/pager.h 76466c3a5af56943537f68b1f16567101a0cd1d0
+F src/pager.c 2964185d4356d0dc159b8340e52d2538d32394e5
+F src/pager.h ca1f23c0cf137ac26f8908df2427c8b308361efd
 F src/parse.y ace5c7a125d9f2a410e431ee3209034105045f7e
 F src/pcache.c 1e9aa2dbc0845b52e1b51cc39753b6d1e041cb07
 F src/pcache.h c683390d50f856d4cd8e24342ae62027d1bb6050
@@ -219,8 +219,8 @@ F src/trigger.c 8927588cb9e6d47f933b53bfe74200fbb504100d
 F src/update.c 9859f2056c7739a1db0d9774ccb6c2f0cee6d1de
 F src/utf.c 1baeeac91707a4df97ccc6141ec0f808278af685
 F src/util.c 32aebf04c10e51ad3977a928b7416bed671b620b
-F src/vacuum.c b17355fc10cef0875626932ec2f1fa1deb0daa48
-F src/vdbe.c 965247d966bb5bc9db819e27c076c8acd43ea4fd
+F src/vacuum.c 241a8386727c1497eba4955933356dfba6ff8c9f
+F src/vdbe.c 8a910a19981b8f670f4d67b5b0673459de50ccba
 F src/vdbe.h 471f6a3dcec4817ca33596fe7f6654d56c0e75f3
 F src/vdbeInt.h 19ebc8c2a2e938340051ee65af3f377fb99102d1
 F src/vdbeapi.c dc3138f10afbc95ed3c21dd25abb154504b1db9d
@@ -823,14 +823,14 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff
 F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224
 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f
-P 5d694f04fecf47ca325e108d463c24f42def55d5
-R 10695bb8a15b034a4e06a10daf5b2617
+P af353bd89e5ec89f113d217225cc59cbc8373d64
+R 3e2d7a9cc84ff16ee3e947d8ce602cce
 U drh
-Z 161ce96e4e9771649be68619f8c3c2db
+Z e14f3acbecbf2df0abe6fde12480ec15
 -----BEGIN PGP SIGNATURE-----
 Version: GnuPG v1.4.6 (GNU/Linux)
 
-iD8DBQFMERIWoxKgR168RlERAqHeAKCF217UHq/n+fo3jhftqof1D81x0ACfYIyS
-Y/99t0MEsIlG4IyOHOkiOQk=
-=qrJ/
+iD8DBQFMEmvooxKgR168RlERAg5RAJ9VmP08NyW1of8QWkDMnAiHK8A/xgCeLBcs
+hbn4o1Zj2vKA/g5KFcfNycs=
+=Li8t
 -----END PGP SIGNATURE-----
index e7ae47c2beaf690f6ee9902e992a0ba18ba2a353..cc28afffbf92651218f626495a38969256ee7357 100644 (file)
@@ -1 +1 @@
-af353bd89e5ec89f113d217225cc59cbc8373d64
\ No newline at end of file
+95cc3f6fdec5494560c3cd4439d06870d1c62506
\ No newline at end of file
index 3e2cba5ff248832157d474c2166ef59469d2040a..1478a991b33b616f14a2eecbeb321c567886541d 100644 (file)
@@ -335,8 +335,7 @@ int sqlite3_backup_step(sqlite3_backup *p, int nPage){
     ** and the page sizes are different between source and destination */
     pgszSrc = sqlite3BtreeGetPageSize(p->pSrc);
     pgszDest = sqlite3BtreeGetPageSize(p->pDest);
-    destMode = sqlite3PagerJournalMode(sqlite3BtreePager(p->pDest),
-                                         PAGER_JOURNALMODE_QUERY);
+    destMode = sqlite3PagerGetJournalMode(sqlite3BtreePager(p->pDest));
     if( SQLITE_OK==rc && destMode==PAGER_JOURNALMODE_WAL && pgszSrc!=pgszDest ){
       rc = SQLITE_READONLY;
     }
index 38166ce7f1ae4685e7cbb8cbe2801e51ba11f1a3..4c00e398e223e2610c55363d2205b5119e29e35c 100644 (file)
@@ -3422,7 +3422,7 @@ int sqlite3OpenTempDatabase(Parse *pParse){
       db->mallocFailed = 1;
       return 1;
     }
-    sqlite3PagerJournalMode(sqlite3BtreePager(pBt), db->dfltJournalMode);
+    sqlite3PagerSetJournalMode(sqlite3BtreePager(pBt), db->dfltJournalMode);
   }
   return 0;
 }
index 9e1ea7aa89f78df824d3c499512aa007010f5939..2b102fbea9a35d4c1f5e62e8ed8a51a11898ed6c 100644 (file)
@@ -5815,9 +5815,8 @@ int sqlite3PagerLockingMode(Pager *pPager, int eMode){
 }
 
 /*
-** Get/set the journal-mode for this pager. Parameter eMode must be one of:
+** Set the journal-mode for this pager. Parameter eMode must be one of:
 **
-**    PAGER_JOURNALMODE_QUERY
 **    PAGER_JOURNALMODE_DELETE
 **    PAGER_JOURNALMODE_TRUNCATE
 **    PAGER_JOURNALMODE_PERSIST
@@ -5825,55 +5824,94 @@ int sqlite3PagerLockingMode(Pager *pPager, int eMode){
 **    PAGER_JOURNALMODE_MEMORY
 **    PAGER_JOURNALMODE_WAL
 **
-** If the parameter is not _QUERY, then the journal_mode is set to the
-** value specified if the change is allowed. The change may be disallowed
-** for the following reasons:
+** The journalmode is set to the value specified if the change is allowed.
+** The change may be disallowed for the following reasons:
 **
 **   *  An in-memory database can only have its journal_mode set to _OFF
 **      or _MEMORY.
 **
-**   *  The journal mode may not be changed while a transaction is active.
+**   *  Temporary databases cannot have _WAL journalmode.
 **
 ** The returned indicate the current (possibly updated) journal-mode.
 */
-int sqlite3PagerJournalMode(Pager *pPager, int eMode){
-  assert( eMode==PAGER_JOURNALMODE_QUERY
-            || eMode==PAGER_JOURNALMODE_DELETE
+int sqlite3PagerSetJournalMode(Pager *pPager, int eMode){
+  u8 eOld = pPager->journalMode;    /* Prior journalmode */
+
+  /* The eMode parameter is always valid */
+  assert(      eMode==PAGER_JOURNALMODE_DELETE
             || eMode==PAGER_JOURNALMODE_TRUNCATE
             || eMode==PAGER_JOURNALMODE_PERSIST
             || eMode==PAGER_JOURNALMODE_OFF 
             || eMode==PAGER_JOURNALMODE_WAL 
             || eMode==PAGER_JOURNALMODE_MEMORY );
-  assert( PAGER_JOURNALMODE_QUERY<0 );
 
-  if( eMode==PAGER_JOURNALMODE_WAL 
-   && pPager->journalMode==PAGER_JOURNALMODE_DELETE
-  ){
-    pPager->journalMode = PAGER_JOURNALMODE_WAL;
-  }else if( eMode>=0
-   && (pPager->tempFile==0 || eMode!=PAGER_JOURNALMODE_WAL)
-   && (!MEMDB || eMode==PAGER_JOURNALMODE_MEMORY||eMode==PAGER_JOURNALMODE_OFF)
-   && !pPager->dbModified
-   && (!isOpen(pPager->jfd) || 0==pPager->journalOff)
-  ){
-    if( isOpen(pPager->jfd) ){
-      sqlite3OsClose(pPager->jfd);
+  /* Do not allow the journalmode of a TEMP database to be changed to WAL
+  */
+  if( pPager->tempFile && eMode==PAGER_JOURNALMODE_WAL ){
+    assert( eOld!=PAGER_JOURNALMODE_WAL );
+    eMode = eOld;
+  }
+
+  /* Do allow the journalmode of an in-memory database to be set to
+  ** anything other than MEMORY or OFF
+  */
+  if( MEMDB ){
+    assert( eOld==PAGER_JOURNALMODE_MEMORY || eOld==PAGER_JOURNALMODE_OFF );
+    if( eMode!=PAGER_JOURNALMODE_MEMORY && eMode!=PAGER_JOURNALMODE_OFF ){
+      eMode = eOld;
     }
-    assert( (PAGER_JOURNALMODE_TRUNCATE & 1)==1 );
-    assert( (PAGER_JOURNALMODE_PERSIST & 1)==1 );
-    assert( (PAGER_JOURNALMODE_DELETE & 1)==0 );
-    assert( (PAGER_JOURNALMODE_MEMORY & 1)==0 );
-    assert( (PAGER_JOURNALMODE_OFF & 1)==0 );
-    if( (pPager->journalMode & 1)==1 && (eMode & 1)==0
-         && !pPager->exclusiveMode ){
-      sqlite3OsDelete(pPager->pVfs, pPager->zJournal, 0);
+  }
+
+  if( eMode!=eOld ){
+    /* When changing between rollback modes, close the journal file prior
+    ** to the change.  But when changing from a rollback mode to WAL, keep
+    ** the journal open since there is a rollback-style transaction in play
+    ** used to convert the version numbers in the btree header.
+    */
+    if( isOpen(pPager->jfd) && eMode!=PAGER_JOURNALMODE_WAL ){
+      sqlite3OsClose(pPager->jfd);
     }
 
+    /* Change the journal mode. */
     pPager->journalMode = (u8)eMode;
+
+    /* When transistioning from TRUNCATE or PERSIST to any other journal
+    ** mode (and we are not in locking_mode=EXCLUSIVE) then delete the
+    ** journal file.
+    */
+    assert( (PAGER_JOURNALMODE_TRUNCATE & 5)==1 );
+    assert( (PAGER_JOURNALMODE_PERSIST & 5)==1 );
+    assert( (PAGER_JOURNALMODE_DELETE & 5)!=1 );
+    assert( (PAGER_JOURNALMODE_MEMORY & 5)!=1 );
+    assert( (PAGER_JOURNALMODE_OFF & 5)!=1 );
+    assert( (PAGER_JOURNALMODE_WAL & 5)!=1 );
+    if( (eOld & 5)==1 && (eMode & 5)!=1 && !pPager->exclusiveMode ){
+      sqlite3OsDelete(pPager->pVfs, pPager->zJournal, 0);
+    }
   }
+
+  /* Return the new journal mode */
   return (int)pPager->journalMode;
 }
 
+/*
+** Return the current journal mode.
+*/
+int sqlite3PagerGetJournalMode(Pager *pPager){
+  return (int)pPager->journalMode;
+}
+
+/*
+** Return TRUE if the pager is in a state where it is OK to change the
+** journalmode.  Journalmode changes can only happen when the database
+** is unmodified.
+*/
+int sqlite3PagerOkToChangeJournalMode(Pager *pPager){
+  if( pPager->dbModified ) return 0;
+  if( isOpen(pPager->jfd) && pPager->journalOff>0 ) return 0;
+  return 1;
+}
+
 /*
 ** Get/set the size-limit used for persistent journal files.
 **
index 57ceb046311133412c37070fa9529896eb8ca4fa..9f77cde079739f1db8383968b22f2caf54047583 100644 (file)
@@ -68,9 +68,9 @@ typedef struct PgHdr DbPage;
 #define PAGER_LOCKINGMODE_EXCLUSIVE   1
 
 /*
-** Valid values for the second argument to sqlite3PagerJournalMode().
+** Numeric constants that encode the journalmode.  
 */
-#define PAGER_JOURNALMODE_QUERY      -1
+#define PAGER_JOURNALMODE_QUERY     (-1)  /* Query the value of journalmode */
 #define PAGER_JOURNALMODE_DELETE      0   /* Commit by deleting journal file */
 #define PAGER_JOURNALMODE_PERSIST     1   /* Commit by zeroing journal header */
 #define PAGER_JOURNALMODE_OFF         2   /* Journal omitted.  */
@@ -104,7 +104,9 @@ int sqlite3PagerMaxPageCount(Pager*, int);
 void sqlite3PagerSetCachesize(Pager*, int);
 void sqlite3PagerSetSafetyLevel(Pager*,int,int);
 int sqlite3PagerLockingMode(Pager *, int);
-int sqlite3PagerJournalMode(Pager *, int);
+int sqlite3PagerSetJournalMode(Pager *, int);
+int sqlite3PagerGetJournalMode(Pager*);
+int sqlite3PagerOkToChangeJournalMode(Pager*);
 i64 sqlite3PagerJournalSizeLimit(Pager *, i64);
 sqlite3_backup **sqlite3PagerBackupPtr(Pager*);
 
index e95b4aa90290edda180eb76bf22248a5552e5d6f..a0bf1ebfe449ce434e172a74622b20864f1d532a 100644 (file)
@@ -173,8 +173,8 @@ int sqlite3RunVacuum(char **pzErrMsg, sqlite3 *db){
 #endif
 
   /* Do not attempt to change the page size for a WAL database */
-  if( sqlite3PagerJournalMode(sqlite3BtreePager(pMain),
-                              PAGER_JOURNALMODE_QUERY)==PAGER_JOURNALMODE_WAL ){
+  if( sqlite3PagerGetJournalMode(sqlite3BtreePager(pMain))
+                                               ==PAGER_JOURNALMODE_WAL ){
     db->nextPagesize = 0;
   }
 
index 89a8c340bec2e4b51de49b9eb85d8de6131034a7..14785d35d54d5bb361cbc035575bd4037b08d0bb 100644 (file)
@@ -5176,7 +5176,6 @@ case OP_JournalMode: {    /* out2-prerelease */
   Pager *pPager;                  /* Pager associated with pBt */
   int eNew;                       /* New journal mode */
   int eOld;                       /* The old journal mode */
-  const sqlite3_vfs *pVfs;        /* The VFS of pPager */
   const char *zFilename;          /* Name of database file for pPager */
 
   eNew = pOp->p3;
@@ -5211,10 +5210,12 @@ case OP_JournalMode: {    /* out2-prerelease */
 
   pBt = db->aDb[pOp->p1].pBt;
   pPager = sqlite3BtreePager(pBt);
+  eOld = sqlite3PagerGetJournalMode(pPager);
+  if( eNew==PAGER_JOURNALMODE_QUERY ) eNew = eOld;
+  if( !sqlite3PagerOkToChangeJournalMode(pPager) ) eNew = eOld;
 
 #ifndef SQLITE_OMIT_WAL
   zFilename = sqlite3PagerFilename(pPager);
-  pVfs = sqlite3PagerVfs(pPager);
 
   /* Do not allow a transition to journal_mode=WAL for a database
   ** in temporary storage or if the VFS does not support xShmOpen.
@@ -5223,59 +5224,56 @@ case OP_JournalMode: {    /* out2-prerelease */
    && (zFilename[0]==0                         /* Temp file */
        || !sqlite3PagerWalSupported(pPager))   /* No xShmOpen support */
   ){
-    eNew = PAGER_JOURNALMODE_QUERY;
+    eNew = eOld;
   }
 
-  if( eNew!=PAGER_JOURNALMODE_QUERY ){
-    eOld = sqlite3PagerJournalMode(pPager, PAGER_JOURNALMODE_QUERY);
-    if( (eNew!=eOld)
-     && (eOld==PAGER_JOURNALMODE_WAL || eNew==PAGER_JOURNALMODE_WAL)
-    ){
-      if( !db->autoCommit || db->activeVdbeCnt>1 ){
-        rc = SQLITE_ERROR;
-        sqlite3SetString(&p->zErrMsg, db, 
-            "cannot change %s wal mode from within a transaction",
-            (eNew==PAGER_JOURNALMODE_WAL ? "into" : "out of")
-        );
-        break;
-      }else{
-  
-        if( eOld==PAGER_JOURNALMODE_WAL ){
-          /* If leaving WAL mode, close the log file. If successful, the call
-          ** to PagerCloseWal() checkpoints and deletes the write-ahead-log 
-          ** file. An EXCLUSIVE lock may still be held on the database file 
-          ** after a successful return. 
-          */
-          rc = sqlite3PagerCloseWal(pPager);
-          if( rc==SQLITE_OK ){
-            sqlite3PagerJournalMode(pPager, eNew);
-          }else if( rc==SQLITE_BUSY && pOp->p5==0 ){
-            goto abort_due_to_error;
-          }
-        }else{
-          sqlite3PagerJournalMode(pPager, PAGER_JOURNALMODE_DELETE);
-          rc = SQLITE_OK;
-        }
-  
-        /* Open a transaction on the database file. Regardless of the journal
-        ** mode, this transaction always uses a rollback journal.
+  if( (eNew!=eOld)
+   && (eOld==PAGER_JOURNALMODE_WAL || eNew==PAGER_JOURNALMODE_WAL)
+  ){
+    if( !db->autoCommit || db->activeVdbeCnt>1 ){
+      rc = SQLITE_ERROR;
+      sqlite3SetString(&p->zErrMsg, db, 
+          "cannot change %s wal mode from within a transaction",
+          (eNew==PAGER_JOURNALMODE_WAL ? "into" : "out of")
+      );
+      break;
+    }else{
+      if( eOld==PAGER_JOURNALMODE_WAL ){
+        /* If leaving WAL mode, close the log file. If successful, the call
+        ** to PagerCloseWal() checkpoints and deletes the write-ahead-log 
+        ** file. An EXCLUSIVE lock may still be held on the database file 
+        ** after a successful return. 
         */
-        assert( sqlite3BtreeIsInTrans(pBt)==0 );
+        rc = sqlite3PagerCloseWal(pPager);
         if( rc==SQLITE_OK ){
-          rc = sqlite3BtreeSetVersion(pBt, 
-                                      (eNew==PAGER_JOURNALMODE_WAL ? 2 : 1));
-          if( rc==SQLITE_BUSY && pOp->p5==0 ) goto abort_due_to_error;
-        }
-        if( rc==SQLITE_BUSY ){
-          eNew = PAGER_JOURNALMODE_QUERY;
-          rc = SQLITE_OK;
+          sqlite3PagerSetJournalMode(pPager, eNew);
+        }else if( rc==SQLITE_BUSY && pOp->p5==0 ){
+          goto abort_due_to_error;
         }
+      }else{
+        sqlite3PagerSetJournalMode(pPager, PAGER_JOURNALMODE_DELETE);
+        rc = SQLITE_OK;
+      }
+  
+      /* Open a transaction on the database file. Regardless of the journal
+      ** mode, this transaction always uses a rollback journal.
+      */
+      assert( sqlite3BtreeIsInTrans(pBt)==0 );
+      if( rc==SQLITE_OK ){
+        rc = sqlite3BtreeSetVersion(pBt, 
+                                    (eNew==PAGER_JOURNALMODE_WAL ? 2 : 1));
+        if( rc==SQLITE_BUSY && pOp->p5==0 ) goto abort_due_to_error;
+      }
+      if( rc==SQLITE_BUSY ){
+        eNew = eOld;
+        rc = SQLITE_OK;
       }
     }
   }
 #endif /* ifndef SQLITE_OMIT_WAL */
 
-  eNew = sqlite3PagerJournalMode(pPager, eNew);
+  eNew = sqlite3PagerSetJournalMode(pPager, eNew);
   pOut = &aMem[pOp->p2];
   pOut->flags = MEM_Str|MEM_Static|MEM_Term;
   pOut->z = (char *)sqlite3JournalModename(eNew);