]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Change the journal_mode pragma so that it always returns the current
authordrh <drh@noemail.net>
Mon, 20 Apr 2009 17:43:03 +0000 (17:43 +0000)
committerdrh <drh@noemail.net>
Mon, 20 Apr 2009 17:43:03 +0000 (17:43 +0000)
journal mode, even on a failed attempt to change the journal mode.
Allow the journal mode to be changed as long as there is not a pending
transaction.  Ticket #3811. (CVS 6526)

FossilOrigin-Name: 419e320ae51639794335d19699f8e1189e524e7d

manifest
manifest.uuid
src/build.c
src/pager.c
src/prepare.c
test/jrnlmode.test
test/jrnlmode3.test

index 7c014b8bb82c84c5536701e6140a05c190255944..d79431efc666a8ba0b893e7605077d6efaff539b 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Add\snew\stests\sto\sshow\sthat\sjournal_mode=OFF\sworks\swith\slocking_mode=EXCLUSIVE\nas\slong\sas\sthe\sjournal_mode\sis\sset\sprior\sto\sthe\sfirst\stransaction.\nTicket\s#3811.\s(CVS\s6525)
-D 2009-04-20T13:32:33
+C Change\sthe\sjournal_mode\spragma\sso\sthat\sit\salways\sreturns\sthe\scurrent\njournal\smode,\seven\son\sa\sfailed\sattempt\sto\schange\sthe\sjournal\smode.\nAllow\sthe\sjournal\smode\sto\sbe\schanged\sas\slong\sas\sthere\sis\snot\sa\spending\ntransaction.\s\sTicket\s#3811.\s(CVS\s6526)
+D 2009-04-20T17:43:03
 F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0
 F Makefile.in 583e87706abc3026960ed759aff6371faf84c211
 F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654
@@ -106,7 +106,7 @@ F src/btmutex.c 9b899c0d8df3bd68f527b0afe03088321b696d3c
 F src/btree.c b4ec46b3adc3e2d82704c949d4b654b031a64ad6
 F src/btree.h 99fcc7e8c4a1e35afe271bcb38de1a698dfc904e
 F src/btreeInt.h df64030d632f8c8ac217ed52e8b6b3eacacb33a5
-F src/build.c 2882f22078db1c3f887b1aca77ff460cf9461c62
+F src/build.c 18c5e51c2cbaab95b1d90d38f5a15005a430d047
 F src/callback.c 73016376d6848ba987709e8c9048d4f0e0776036
 F src/complete.c cb14e06dbe79dee031031f0d9e686ff306afe07c
 F src/date.c d327ec7bb2f64b08d32b1035de82b9ba8675de91
@@ -143,14 +143,14 @@ F src/os_common.h 8c61457df58f1a4bd5f5adc3e90e01b37bf7afbc
 F src/os_os2.c bed77dc26e3a95ce4a204936b9a1ca6fe612fcc5
 F src/os_unix.c 9ad9f45049a3c9eb0b0713b162ff0d7024ff7259
 F src/os_win.c c3d0354b9a7ae75e3e993e6c17f5deb061acbc36
-F src/pager.c 2ad6a948040f802508acddf4052f29b04802b3db
+F src/pager.c adfdf98f92bcab88246aaa5079df49f9441ebd81
 F src/pager.h 0c9f3520c00d8a3b8e792ca56c9a11b6b02b4b0f
 F src/parse.y b7e4341b21736a90b952aa6bb663ec98529b778e
 F src/pcache.c 395f752a13574120bd7513a400ba02a265aaa76d
 F src/pcache.h 9b927ccc5a538e31b4c3bc7eec4f976db42a1324
 F src/pcache1.c 35f8601c91c09a1e887a1914ebca07bb5afc7b89
 F src/pragma.c c26c16c49a80d03c8597f0e6c7daba53f283428f
-F src/prepare.c 0ad1ba3290e0626aa4e7589ed6ab6af2572875b0
+F src/prepare.c 72d74e6d3b9c8eb0663b33ec6438aa718096ac79
 F src/printf.c ea2d76000cc5f4579d7e9cb2f5460433eec0d384
 F src/random.c 676b9d7ac820fe81e6fb2394ac8c10cff7f38628
 F src/resolve.c 094e44450371fb27869eb8bf679aacbe51fdc56d
@@ -420,9 +420,9 @@ F test/join3.test 6f0c774ff1ba0489e6c88a3e77b9d3528fb4fda0
 F test/join4.test 1a352e4e267114444c29266ce79e941af5885916
 F test/join5.test 86675fc2919269aa923c84dd00ee4249b97990fe
 F test/journal1.test 36f2d1bb9bf03f790f43fbdb439e44c0657fab19
-F test/jrnlmode.test 05e1e187c5b64022e832761674ee2395f3267d01
+F test/jrnlmode.test 0584cbd11bf8999501abf1b991979f8aa69c265b
 F test/jrnlmode2.test bd846e10d463c0b6f8bded674cb07f94a0277097
-F test/jrnlmode3.test 4e9a1f6099a13ec863720de981e3044f735f02bf
+F test/jrnlmode3.test cfcdb12b90e640a23b92785a002d96c0624c8710
 F test/keyword1.test a2400977a2e4fde43bf33754c2929fda34dbca05
 F test/lastinsert.test 474d519c68cb79d07ecae56a763aa7f322c72f51
 F test/laststmtchanges.test ae613f53819206b3222771828d024154d51db200
@@ -718,7 +718,7 @@ F tool/speedtest16.c c8a9c793df96db7e4933f0852abb7a03d48f2e81
 F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff
 F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224
 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
-P 3182e8bf69eb4e5e4070930cb9c750942b1dc735
-R 63b3c0e9e8b9bff8f84a79194299cadb
+P e62ac26f72224a4ba6c7dc5c32b7e4370461764d
+R 39db01b2d3bd255afa6f732be2b5d532
 U drh
-Z b0e0f5d2013af325cce1fe669e1d8579
+Z d037c0a2ce0411a3e53db40f26904a65
index 24829e0b6b3023f08fe9f923a61e3b60a9ed0694..bcccd3f9fbbba2b3ac588d154906ee6e01b8aef6 100644 (file)
@@ -1 +1 @@
-e62ac26f72224a4ba6c7dc5c32b7e4370461764d
\ No newline at end of file
+419e320ae51639794335d19699f8e1189e524e7d
\ No newline at end of file
index a54efcf5d28dcd723ae7e59de63ca9daaccf338c..987a90c998ce91a10d31db151d519d0b8a1d7257 100644 (file)
@@ -22,7 +22,7 @@
 **     COMMIT
 **     ROLLBACK
 **
-** $Id: build.c,v 1.528 2009/04/08 13:51:51 drh Exp $
+** $Id: build.c,v 1.529 2009/04/20 17:43:03 drh Exp $
 */
 #include "sqliteInt.h"
 
@@ -158,7 +158,9 @@ void sqlite3FinishCoding(Parse *pParse){
         if( (mask & pParse->cookieMask)==0 ) continue;
         sqlite3VdbeUsesBtree(v, iDb);
         sqlite3VdbeAddOp2(v,OP_Transaction, iDb, (mask & pParse->writeMask)!=0);
-        sqlite3VdbeAddOp2(v,OP_VerifyCookie, iDb, pParse->cookieValue[iDb]);
+        if( db->init.busy==0 ){
+          sqlite3VdbeAddOp2(v,OP_VerifyCookie, iDb, pParse->cookieValue[iDb]);
+        }
       }
 #ifndef SQLITE_OMIT_VIRTUALTABLE
       {
index b42f299e2495b6cfeb72c19276716a8d9cf446fc..aef663c9588eda317ad4aeee7a87cd96ca15c0cc 100644 (file)
@@ -18,7 +18,7 @@
 ** file simultaneously, or one process from reading the database while
 ** another is writing.
 **
-** @(#) $Id: pager.c,v 1.581 2009/04/20 11:34:27 drh Exp $
+** @(#) $Id: pager.c,v 1.582 2009/04/20 17:43:03 drh Exp $
 */
 #ifndef SQLITE_OMIT_DISKIO
 #include "sqliteInt.h"
@@ -5195,11 +5195,14 @@ int sqlite3PagerLockingMode(Pager *pPager, int eMode){
 **    PAGER_JOURNALMODE_OFF
 **    PAGER_JOURNALMODE_MEMORY
 **
-** If the parameter is not _QUERY, then the journal-mode is set to the
-** value specified.  Except, an in-memory database can only have its
-** journal mode set to _OFF or _MEMORY.  Attempts to change the journal
-** mode of an in-memory database to something other than _OFF or _MEMORY
-** are silently ignored.
+** If the parameter is not _QUERY, then the journal_mode is set to the
+** value specified if the change is allowed.  The change is 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.
 **
 ** The returned indicate the current (possibly updated) journal-mode.
 */
@@ -5211,8 +5214,14 @@ int sqlite3PagerJournalMode(Pager *pPager, int eMode){
             || eMode==PAGER_JOURNALMODE_OFF 
             || eMode==PAGER_JOURNALMODE_MEMORY );
   assert( PAGER_JOURNALMODE_QUERY<0 );
-  if( eMode>=0 && (!MEMDB || eMode==PAGER_JOURNALMODE_MEMORY 
-                          || eMode==PAGER_JOURNALMODE_OFF) ){
+  if( eMode>=0
+   && (!MEMDB || eMode==PAGER_JOURNALMODE_MEMORY 
+              || eMode==PAGER_JOURNALMODE_OFF)
+   && !pPager->dbModified
+  ){
+    if( isOpen(pPager->jfd) ){
+      sqlite3OsClose(pPager->jfd);
+    }
     pPager->journalMode = (u8)eMode;
   }
   return (int)pPager->journalMode;
index e3479f3b89dd77e7b1b5862557935b9f7ea6cf27..c5f4de90429a97f4181f2256359c65b80a838579 100644 (file)
@@ -13,7 +13,7 @@
 ** interface, and routines that contribute to loading the database schema
 ** from disk.
 **
-** $Id: prepare.c,v 1.116 2009/04/02 18:32:27 drh Exp $
+** $Id: prepare.c,v 1.117 2009/04/20 17:43:03 drh Exp $
 */
 #include "sqliteInt.h"
 
@@ -127,6 +127,7 @@ int sqlite3InitCallback(void *pInit, int argc, char **argv, char **NotUsed){
 */
 static int sqlite3InitOne(sqlite3 *db, int iDb, char **pzErrMsg){
   int rc;
+  int i;
   BtCursor *curMain;
   int size;
   Table *pTab;
@@ -216,7 +217,8 @@ static int sqlite3InitOne(sqlite3 *db, int iDb, char **pzErrMsg){
   }
   sqlite3BtreeEnter(pDb->pBt);
   rc = sqlite3BtreeCursor(pDb->pBt, MASTER_ROOT, 0, 0, curMain);
-  if( rc!=SQLITE_OK && rc!=SQLITE_EMPTY ){
+  if( rc==SQLITE_EMPTY ) rc = SQLITE_OK;
+  if( rc!=SQLITE_OK ){
     sqlite3SetString(pzErrMsg, db, "%s", sqlite3ErrStr(rc));
     goto initone_error_out;
   }
@@ -238,17 +240,12 @@ static int sqlite3InitOne(sqlite3 *db, int iDb, char **pzErrMsg){
   ** Note: The #defined SQLITE_UTF* symbols in sqliteInt.h correspond to
   ** the possible values of meta[4].
   */
-  if( rc==SQLITE_OK ){
-    int i;
-    for(i=0; i<ArraySize(meta); i++){
-      rc = sqlite3BtreeGetMeta(pDb->pBt, i+1, (u32 *)&meta[i]);
-      if( rc ){
-        sqlite3SetString(pzErrMsg, db, "%s", sqlite3ErrStr(rc));
-        goto initone_error_out;
-      }
+  for(i=0; i<ArraySize(meta); i++){
+    rc = sqlite3BtreeGetMeta(pDb->pBt, i+1, (u32 *)&meta[i]);
+    if( rc ){
+      sqlite3SetString(pzErrMsg, db, "%s", sqlite3ErrStr(rc));
+      goto initone_error_out;
     }
-  }else{
-    memset(meta, 0, sizeof(meta));
   }
   pDb->pSchema->schema_cookie = meta[0];
 
index 900a77ff6e24e6030de054e2d0c48831ab63a3e6..114b255eca5a9a902e2da5c7480ec0326d18a5b1 100644 (file)
@@ -11,7 +11,7 @@
 # This file implements regression tests for SQLite library. The focus
 # of these tests is the journal mode pragma.
 #
-# $Id: jrnlmode.test,v 1.14 2009/04/10 15:02:44 danielk1977 Exp $
+# $Id: jrnlmode.test,v 1.15 2009/04/20 17:43:03 drh Exp $
 
 set testdir [file dirname $argv0]
 source $testdir/tester.tcl
@@ -282,6 +282,7 @@ ifcapable autovacuum&&pragma {
   } {3}
 
   do_test jrnlmode-4.2 {
+breakpoint
     execsql { PRAGMA journal_mode = off }
   } {off}
 
@@ -464,7 +465,7 @@ ifcapable pragma {
           INSERT INTO t4 VALUES(1, 2);
           PRAGMA journal_mode = memory;
       }
-    } {truncate memory}
+    } {truncate truncate}
     do_test jrnlmode-6.2 {
       file exists test.db-journal
     } {1}
@@ -476,14 +477,15 @@ ifcapable pragma {
     } {1 2}
     do_test jrnlmode-6.4 {
       file exists test.db-journal
-    } {0}
+    } {1}
     do_test jrnlmode-6.5 {
       execsql {
+        PRAGMA journal_mode = MEMORY;
         BEGIN;
           INSERT INTO t4 VALUES(3, 4);
       }
       file exists test.db-journal
-    } {0}
+    } {1}
     do_test jrnlmode-6.7 {
       execsql {
         COMMIT;
@@ -492,6 +494,13 @@ ifcapable pragma {
     } {1 2 3 4}
     do_test jrnlmode-6.8 {
       file exists test.db-journal
+    } {1}
+    do_test jrnlmode-6.9 {
+      execsql {
+        PRAGMA journal_mode = DELETE;
+        BEGIN IMMEDIATE; COMMIT;
+      }
+      file exists test.db-journal
     } {0}
   }
 }
index 7756104e812db0e5f5aa82a3cc5135e4e54d73c8..7a6f4c3adc4963ff95412a0e0a559708d34e4399 100644 (file)
@@ -9,7 +9,11 @@
 #
 #***********************************************************************
 #
-# $Id: jrnlmode3.test,v 1.4 2009/04/20 13:32:33 drh Exp $
+# Test cases inspired by ticket #3811.  Tests to make sure that
+# the journal_mode can only be changed at appropriate times and that
+# all reported changes are effective.
+#
+# $Id: jrnlmode3.test,v 1.5 2009/04/20 17:43:03 drh Exp $
 
 set testdir [file dirname $argv0]
 source $testdir/tester.tcl
@@ -19,7 +23,6 @@ ifcapable {!pager_pragmas} {
   return
 }
 
-# Ticket #3811
 #
 # Verify that journal_mode=OFF works as long as it occurs before the first
 # transaction, even if locking_mode=EXCLUSIVE is enabled.  The behavior if
@@ -66,5 +69,82 @@ do_test jrnlmode3-2.2 {
   }
 } {1 2}
 
+# Test cases to verify that we can move from any journal_mode
+# to any other, as long as we are not in a transaction.  Verify
+# that we cannot change journal_mode while a transaction is active.
+#
+set all_journal_modes {delete persist truncate memory off}
+set cnt 0
+foreach fromjmode $all_journal_modes {
+  foreach tojmode $all_journal_modes {
+
+    # Skip the no-change cases
+    if {$fromjmode==$tojmode} continue
+    incr cnt
+
+    # Start with a fresh database connection an empty database file.
+    #
+    db close
+    file delete -force test.db test.db-journal
+    sqlite3 db test.db
+
+    # Initialize the journal mode.
+    #
+    do_test jrnlmode3-3.$cnt.1-($fromjmode-to-$tojmode) {
+      db eval "PRAGMA journal_mode = $fromjmode;"
+    } $fromjmode
+
+    # Verify that the initial journal mode takes.
+    #
+    do_test jrnlmode3-3.$cnt.2 {
+      db eval {PRAGMA main.journal_mode}
+    } $fromjmode
+
+    # Start a transaction and try to change the journal mode within
+    # the transaction.  This should fail.
+    #
+    do_test jrnlmode3-3.$cnt.3 {
+      db eval {
+        CREATE TABLE t1(x);
+        BEGIN;
+        INSERT INTO t1 VALUES($cnt);
+      }
+      db eval "PRAGMA journal_mode=$tojmode"
+    } $fromjmode
+
+    # Rollback the transaction.  Verify that the rollback occurred
+    # if journal_mode!=OFF.
+    #
+    do_test jrnlmode3-3.$cnt.4 {
+      db eval {
+        ROLLBACK;
+        SELECT * FROM t1;
+      }
+    } [expr {$fromjmode=="off"?$cnt:""}]
+
+    # Now change the journal mode again.  This time the new mode
+    # should take.
+    #
+    do_test jrnlmode3-3.$cnt.5 {
+      db eval "PRAGMA journal_mode=$tojmode"
+    } $tojmode
+
+    # Do a the transaction.  Verify that the rollback occurred
+    # if journal_mode!=OFF.
+    #
+    do_test jrnlmode3-3.$cnt.6 {
+      db eval {
+        DROP TABLE IF EXISTS t1;
+        CREATE TABLE t1(x);
+        BEGIN;
+        INSERT INTO t1 VALUES(1);
+      }
+      db eval ROLLBACK
+      db eval {
+        SELECT * FROM t1;
+      }
+    } [expr {$tojmode=="off"?"1":""}]
+  }
+}
 
 finish_test