]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Only error out on a database file move when attempting to start a write
authordrh <drh@noemail.net>
Fri, 6 Dec 2013 17:23:38 +0000 (17:23 +0000)
committerdrh <drh@noemail.net>
Fri, 6 Dec 2013 17:23:38 +0000 (17:23 +0000)
transaction.  Assume read transactions are still safe.  And make the error
SQLITE_READONLY_DBMOVED instead of SQLITE_IOERR_NODB.

FossilOrigin-Name: 28348f2ada98c616241a51aecb70b63e87e6ddbb

manifest
manifest.uuid
src/pager.c
src/sqlite.h.in
src/test_vfstrace.c
test/pager4.test

index feb65446f144e9bc755a561501dc1518ca72b621..a5b6b1110c5193506056405f43105ba969dda28d 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Add\scode\sto\sdetect\sif\sthe\sdatabase\sfile\sis\smoved\sor\sdeleted\sout\sfrom\sunder\nSQLite\sand\sreturn\san\sSQLITE_IOERR_NODB.
-D 2013-12-06T15:37:35.675
+C Only\serror\sout\son\sa\sdatabase\sfile\smove\swhen\sattempting\sto\sstart\sa\swrite\ntransaction.\s\sAssume\sread\stransactions\sare\sstill\ssafe.\s\sAnd\smake\sthe\serror\nSQLITE_READONLY_DBMOVED\sinstead\sof\sSQLITE_IOERR_NODB.
+D 2013-12-06T17:23:38.532
 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
 F Makefile.in e1a9b4258bbde53f5636f4e238c65b7e11459e2b
 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
@@ -207,7 +207,7 @@ F src/os.h 4a46270a64e9193af4a0aaa3bc2c66dc07c29b3f
 F src/os_common.h 92815ed65f805560b66166e3583470ff94478f04
 F src/os_unix.c f076587029285554a3a65d30d0e71d50cd61f41f
 F src/os_win.c f149798adb6f32db835b2c9f9fac83d86015e004
-F src/pager.c 3648e602d484020d10cb514b04ef8f445ed06f30
+F src/pager.c 938874307e1b07a98a181cbab41c5625f2aa1666
 F src/pager.h f094af9f6ececfaa8a1e93876905a4f34233fb0c
 F src/parse.y acee1a9958539e21263362b194594c5255ad2fca
 F src/pcache.c f8043b433a57aba85384a531e3937a804432a346
@@ -221,7 +221,7 @@ F src/resolve.c 7eda9097b29fcf3d2b42fdc17d1de672134e09b6
 F src/rowset.c 64655f1a627c9c212d9ab497899e7424a34222e0
 F src/select.c d41381d80a22d3a83352aeca274cccf264ac277a
 F src/shell.c 936a72ff784efff3832cce274a96ed0b036e6758
-F src/sqlite.h.in 4373b4a913ea460d91a9a4a54906ee18b350d573
+F src/sqlite.h.in 5ae0618d16a393ff8e66d1e373d3670892c2d254
 F src/sqlite3.rc 11094cc6a157a028b301a9f06b3d03089ea37c3e
 F src/sqlite3ext.h 886f5a34de171002ad46fae8c36a7d8051c190fc
 F src/sqliteInt.h f3a5d663fe9c6c0b2ee7fc2e20a6204eaea5bc7c
@@ -272,7 +272,7 @@ F src/test_syscall.c 16dbe79fb320fadb5acd7a0a59f49e52ab2d2091
 F src/test_tclvar.c f4dc67d5f780707210d6bb0eb6016a431c04c7fa
 F src/test_thread.c 1e133a40b50e9c035b00174035b846e7eef481cb
 F src/test_vfs.c e72f555ef7a59080f898fcf1a233deb9eb704ea9
-F src/test_vfstrace.c 21b99a6fe3f4c8be13c0fe83006ee13873154d78
+F src/test_vfstrace.c 3a0ab304682fecbceb689e7d9b904211fde11d78
 F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9
 F src/tokenize.c ec4c1a62b890bf1dbcdb966399e140b904c700a4
 F src/trigger.c d84e1f3669e9a217731a14a9d472b1c7b87c87ba
@@ -726,7 +726,7 @@ F test/oserror.test 50417780d0e0d7cd23cf12a8277bb44024765df3
 F test/pager1.test 1acbdb14c5952a72dd43129cabdbf69aaa3ed1fa
 F test/pager2.test 67b8f40ae98112bcdba1f2b2d03ea83266418c71
 F test/pager3.test 3856d9c80839be0668efee1b74811b1b7f7fc95f
-F test/pager4.test 1848509f0aa83f99d438a2bae02c3fd64dd1afe6
+F test/pager4.test afbffa3f6813bd9bf126eb5e66bc954717f36de5
 F test/pagerfault.test 7285379906ab2f1108b8e82bbdf2d386cc8ff3ff
 F test/pagerfault2.test caf4c7facb914fd3b03a17b31ae2b180c8d6ca1f
 F test/pagerfault3.test 1003fcda009bf48a8e22a516e193b6ef0dd1bbd8
@@ -1146,10 +1146,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381
 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01
 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff
-P 27392118af4c38c5203a04b8013e1afdb1cebd0d
-R 0833e0746c0a3bdbdf22e2e06343a85a
-T *branch * detect-moved-db
-T *sym-detect-moved-db *
-T -sym-trunk *
+P 8759a8e4d83b163e315eff316cf163f6ea42f2bb
+R 2ad1eaf9a51016580f9868708a4f6a69
 U drh
-Z 9ba43ea2faea1b2f751f5fd7fd1e8bc8
+Z 59055776a0fdbfce14961d0c6b6be93f
index a2f643fbba166a309b7c3548356531dc3b6925cc..a13ba15e4f5dca74b5766412af09fccfc510e156 100644 (file)
@@ -1 +1 @@
-8759a8e4d83b163e315eff316cf163f6ea42f2bb
\ No newline at end of file
+28348f2ada98c616241a51aecb70b63e87e6ddbb
\ No newline at end of file
index 78cb78ab2339e335891d9c0ad237d45681861b21..5803b2927d1ed689cf48dc73dfb59ba8e284d603 100644 (file)
@@ -4799,7 +4799,7 @@ int sqlite3PagerOpen(
 
 /* Verify that the database file has not be deleted or renamed out from
 ** under the pager.  Return SQLITE_OK if the database is still were it ought
-** to be on disk.  Return non-zero (SQLITE_IOERR_NODB or some other error
+** to be on disk.  Return non-zero (SQLITE_READONLY_DBMOVED or some other error
 ** code from sqlite3OsAccess()) if the database has gone missing.
 */
 static int databaseIsUnmoved(Pager *pPager){
@@ -4814,7 +4814,7 @@ static int databaseIsUnmoved(Pager *pPager){
   dc = sqlite3OsDeviceCharacteristics(pPager->fd);
   if( (dc&fixedFlags)==fixedFlags ) return SQLITE_OK;
   rc = sqlite3OsAccess(pPager->pVfs, pPager->zFilename, SQLITE_ACCESS_EXISTS, &x);
-  if( rc==SQLITE_OK && !x ) rc = SQLITE_IOERR_NODB;
+  if( rc==SQLITE_OK && !x ) rc = SQLITE_READONLY_DBMOVED;
   return rc;
 }
 
@@ -4991,10 +4991,6 @@ int sqlite3PagerSharedLock(Pager *pPager){
       goto failed;
     }
 
-    /* Verify that the database is unmoved and undeleted */
-    rc = databaseIsUnmoved(pPager);
-    if( rc ) goto failed;
-
     /* If a journal file exists, and there is no RESERVED lock on the
     ** database file, then it either needs to be played back or deleted.
     */
@@ -5498,13 +5494,19 @@ static int pager_open_journal(Pager *pPager){
             (SQLITE_OPEN_DELETEONCLOSE|SQLITE_OPEN_TEMP_JOURNAL):
             (SQLITE_OPEN_MAIN_JOURNAL)
           );
-  #ifdef SQLITE_ENABLE_ATOMIC_WRITE
-        rc = sqlite3JournalOpen(
-            pVfs, pPager->zJournal, pPager->jfd, flags, jrnlBufferSize(pPager)
-        );
-  #else
-        rc = sqlite3OsOpen(pVfs, pPager->zJournal, pPager->jfd, flags, 0);
-  #endif
+
+        /* Verify that the database still has the same name as it did when
+        ** it was originally opened. */
+        rc = databaseIsUnmoved(pPager);
+        if( rc==SQLITE_OK ){
+#ifdef SQLITE_ENABLE_ATOMIC_WRITE
+          rc = sqlite3JournalOpen(
+              pVfs, pPager->zJournal, pPager->jfd, flags, jrnlBufferSize(pPager)
+          );
+#else
+          rc = sqlite3OsOpen(pVfs, pPager->zJournal, pPager->jfd, flags, 0);
+#endif
+        }
       }
       assert( rc!=SQLITE_OK || isOpen(pPager->jfd) );
     }
index de6b59b0b7a224f2210fb921c31f01bcde937fd4..f4692f286a50c78a771106130e8c3adb352ba6fd 100644 (file)
@@ -475,7 +475,6 @@ int sqlite3_exec(
 #define SQLITE_IOERR_MMAP              (SQLITE_IOERR | (24<<8))
 #define SQLITE_IOERR_GETTEMPPATH       (SQLITE_IOERR | (25<<8))
 #define SQLITE_IOERR_CONVPATH          (SQLITE_IOERR | (26<<8))
-#define SQLITE_IOERR_NODB              (SQLITE_IOERR | (27<<8))
 #define SQLITE_LOCKED_SHAREDCACHE      (SQLITE_LOCKED |  (1<<8))
 #define SQLITE_BUSY_RECOVERY           (SQLITE_BUSY   |  (1<<8))
 #define SQLITE_BUSY_SNAPSHOT           (SQLITE_BUSY   |  (2<<8))
@@ -487,6 +486,7 @@ int sqlite3_exec(
 #define SQLITE_READONLY_RECOVERY       (SQLITE_READONLY | (1<<8))
 #define SQLITE_READONLY_CANTLOCK       (SQLITE_READONLY | (2<<8))
 #define SQLITE_READONLY_ROLLBACK       (SQLITE_READONLY | (3<<8))
+#define SQLITE_READONLY_DBMOVED        (SQLITE_READONLY | (4<<8))
 #define SQLITE_ABORT_ROLLBACK          (SQLITE_ABORT | (2<<8))
 #define SQLITE_CONSTRAINT_CHECK        (SQLITE_CONSTRAINT | (1<<8))
 #define SQLITE_CONSTRAINT_COMMITHOOK   (SQLITE_CONSTRAINT | (2<<8))
index 8d56cf89464cb427a09a17347640349bfa35e9f3..c1792f116e265552257b4727497f26f237cfc5c3 100644 (file)
@@ -262,7 +262,7 @@ static void vfstrace_print_errcode(
     case SQLITE_IOERR_SEEK:         zVal = "SQLITE_IOERR_SEEK";         break;
     case SQLITE_IOERR_GETTEMPPATH:  zVal = "SQLITE_IOERR_GETTEMPPATH";  break;
     case SQLITE_IOERR_CONVPATH:     zVal = "SQLITE_IOERR_CONVPATH";     break;
-    case SQLITE_IOERR_NODB:         zVal = "SQLITE_IOERR_NODB";         break;
+    case SQLITE_READONLY_DBMOVED:   zVal = "SQLITE_READONLY_DBMOVED";   break;
     case SQLITE_LOCKED_SHAREDCACHE: zVal = "SQLITE_LOCKED_SHAREDCACHE"; break;
     case SQLITE_BUSY_RECOVERY:      zVal = "SQLITE_BUSY_RECOVERY";      break;
     case SQLITE_CANTOPEN_NOTEMPDIR: zVal = "SQLITE_CANTOPEN_NOTEMPDIR"; break;
index dbe9bf8195b39ceddd4e14893961570e9278d14a..e757dbe171e255510dfa9853ff2766c338c56a3f 100644 (file)
@@ -18,16 +18,66 @@ if {$tcl_platform(platform)!="unix"} return
 set testdir [file dirname $argv0]
 source $testdir/tester.tcl
 
+# Create a database file for testing
+#
 do_execsql_test pager4-1.1 {
   CREATE TABLE t1(a,b,c);
   INSERT INTO t1 VALUES(673,'stone','philips');
   SELECT * FROM t1;
 } {673 stone philips}
+
+# After renaming the database file while it is open, one can still
+# read from the database, but writing returns a READONLY error.
+#
 file delete -force test-xyz.db
 file rename test.db test-xyz.db
 do_catchsql_test pager4-1.2 {
   SELECT * FROM t1;
-} {1 {disk I/O error}}
+} {0 {673 stone philips}}
+do_catchsql_test pager4-1.3 {
+  UPDATE t1 SET a=537;
+} {1 {attempt to write a readonly database}}
+
+# Changing the name back clears the READONLY error
+#
+file rename test-xyz.db test.db
+do_catchsql_test pager4-1.4 {
+  SELECT * FROM t1;
+} {0 {673 stone philips}}
+do_catchsql_test pager4-1.5 {
+  UPDATE t1 SET a=537;
+  SELECT * FROM t1;
+} {0 {537 stone philips}}
+
+# We can write to a renamed database if journal_mode=OFF or
+# journal_mode=MEMORY.
+#
+file rename test.db test-xyz.db
+do_catchsql_test pager4-1.6 {
+  PRAGMA journal_mode=OFF;
+  UPDATE t1 SET a=107;
+  SELECT * FROM t1;
+} {0 {off 107 stone philips}}
+do_catchsql_test pager4-1.7 {
+  PRAGMA journal_mode=MEMORY;
+  UPDATE t1 SET b='magpie';
+  SELECT * FROM t1;
+} {0 {memory 107 magpie philips}}
+
+# Any other journal mode gives a READONLY error
+#
+do_catchsql_test pager4-1.8 {
+  PRAGMA journal_mode=DELETE;
+  UPDATE t1 SET c='jaguar';
+} {1 {attempt to write a readonly database}}
+do_catchsql_test pager4-1.9 {
+  PRAGMA journal_mode=TRUNCATE;
+  UPDATE t1 SET c='jaguar';
+} {1 {attempt to write a readonly database}}
+do_catchsql_test pager4-1.10 {
+  PRAGMA journal_mode=PERSIST;
+  UPDATE t1 SET c='jaguar';
+} {1 {attempt to write a readonly database}}
 
 
 finish_test