]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
If you delete a database file but not its *-wal file, then open the database
authordrh <drh@noemail.net>
Thu, 1 Jul 2010 19:45:34 +0000 (19:45 +0000)
committerdrh <drh@noemail.net>
Thu, 1 Jul 2010 19:45:34 +0000 (19:45 +0000)
(thus creating a new empty database file) the *-wal file is automatically
deleted.

FossilOrigin-Name: 95c69dfbddaf4367cd699dfe8fcf8e06030c1f53

manifest
manifest.uuid
src/pager.c
test/wal4.test [new file with mode: 0644]

index 304145c057499f5e5cefc722cdebf6786a53158e..eed809a96266d011350b9d5fcf7c0da1aa0b0be9 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,8 @@
-C Add\stests\sto\spager1.test\sand\spagerfault.test.
-D 2010-07-01T19:01:56
+-----BEGIN PGP SIGNED MESSAGE-----
+Hash: SHA1
+
+C If\syou\sdelete\sa\sdatabase\sfile\sbut\snot\sits\s*-wal\sfile,\sthen\sopen\sthe\sdatabase\n(thus\screating\sa\snew\sempty\sdatabase\sfile)\sthe\s*-wal\sfile\sis\sautomatically\ndeleted.
+D 2010-07-01T19:45:35
 F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0
 F Makefile.in a5cad1f8f3e021356bfcc6c77dc16f6f1952bbc3
 F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654
@@ -156,7 +159,7 @@ F src/os_common.h a8f95b81eca8a1ab8593d23e94f8a35f35d4078f
 F src/os_os2.c 665876d5eec7585226b0a1cf5e18098de2b2da19
 F src/os_unix.c ec7c7f7ca224ce2ff58736eebf804b48a75f9946
 F src/os_win.c 48f67798969ba983487fed5691059ade7fff2ef7
-F src/pager.c 19975354882e9ac8d361bb3c1c434fd3aa9b0928
+F src/pager.c 2ce3612ab02a87b3c59c30bd412facc0bcc76ee9
 F src/pager.h 879fdde5a102d2f21a3135d6f647530b21c2796c
 F src/parse.y ace5c7a125d9f2a410e431ee3209034105045f7e
 F src/pcache.c 1e9aa2dbc0845b52e1b51cc39753b6d1e041cb07
@@ -776,6 +779,7 @@ F test/vtab_shared.test 0eff9ce4f19facbe0a3e693f6c14b80711a4222d
 F test/wal.test 1891e6f72dd437a1c2a48091aa9182ba17a8f780
 F test/wal2.test 9f2c2a00358b1466bc38feda85f105a4fb52f251
 F test/wal3.test bb3bc0be06411c2d147c1d1d636b6208fbe0349d
+F test/wal4.test 640be93f5422df37203aa5e7c06b24fb5e4a2439
 F test/wal_common.tcl 875ee2118cd7b292ba22fb9bfa66a984b5226b13
 F test/walbak.test e5632adde03fbb0533b9928a89468566ef78a710
 F test/walcksum.test a37b36375c595e61bdb7e1ec49b5f0979b6fc7ce
@@ -829,7 +833,14 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff
 F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224
 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f
-P a8f6341d3b12d64ef56ed05226e3b4f183b8957d
-R b06840e637f43962c2afd5444d532e11
-U dan
-Z fe3e1bcbb9bcaec1df9d747e7acac3b7
+P c6e75950928954fbb1590f952e3cdbcb0753b745
+R f7186a46c1dcd52609a2789564f69cd8
+U drh
+Z 3a354030eb2816ac63480d6e68d82e49
+-----BEGIN PGP SIGNATURE-----
+Version: GnuPG v1.4.6 (GNU/Linux)
+
+iD8DBQFMLPBjoxKgR168RlERAqIFAJ9cSOQ6YZOm/Gu4IvyKKa1xG8xpCgCggbR1
+xxpDAqZSMt9gn5sgaTshVfc=
+=eCFs
+-----END PGP SIGNATURE-----
index cdb996725e844f4893aae3ba4c40f15374403a10..79b10eed337a3cdb0ce1564dd89e67035b2556b5 100644 (file)
@@ -1 +1 @@
-c6e75950928954fbb1590f952e3cdbcb0753b745
\ No newline at end of file
+95c69dfbddaf4367cd699dfe8fcf8e06030c1f53
\ No newline at end of file
index b2e148712604b51e6fee7129e243aef31d2e7c4e..f7fcd617215a3d35ecccadfb3fd459c942c1149a 100644 (file)
@@ -2414,12 +2414,19 @@ static int pagerBeginReadTransaction(Pager *pPager){
 }
 
 /*
-** Check if the *-wal file that corresponds to the database opened by pPager
-** exists. Assuming no error occurs, set *pExists to 1 if the file exists,
-** or 0 otherwise and return SQLITE_OK. If an IO or OOM error occurs, return
+** Check for the existence of or delete the *-wal file that corresponds to
+** the database opened by pPager.
+**
+** When pExists!=NULL, set *pExists to 1 if the *-wal file exists, or 0
+** if the *-wal file does not exist.
+**
+** When pExists==NULL, delete the *-wal file if it exists, or the do
+** nothing if the *-wal file does not exist.
+**
+** Return SQLITE_OK on success. If on an IO or OOM error occurs, return
 ** an SQLite error code.
 */
-static int pagerHasWAL(Pager *pPager, int *pExists){
+static int pagerCheckForOrDeleteWAL(Pager *pPager, int *pExists){
   int rc;                         /* Return code */
   char *zWal;                     /* Name of the WAL file */
 
@@ -2428,7 +2435,11 @@ static int pagerHasWAL(Pager *pPager, int *pExists){
   if( !zWal ){
     rc = SQLITE_NOMEM;
   }else{
-    rc = sqlite3OsAccess(pPager->pVfs, zWal, SQLITE_ACCESS_EXISTS, pExists);
+    if( pExists ){
+      rc = sqlite3OsAccess(pPager->pVfs, zWal, SQLITE_ACCESS_EXISTS, pExists);
+    }else{
+      rc = sqlite3OsDelete(pPager->pVfs, zWal, 0);
+    }
     sqlite3_free(zWal);
   }
   return rc;
@@ -2436,22 +2447,38 @@ static int pagerHasWAL(Pager *pPager, int *pExists){
 
 /*
 ** Check if the *-wal file that corresponds to the database opened by pPager
-** exists. If it does, open the pager in WAL mode. Otherwise, if no error
-** occurs, make sure Pager.journalMode is not set to PAGER_JOURNALMODE_WAL.
-** If an IO or OOM error occurs, return an SQLite error code.
+** exists if the database is not empy, or verify that the *-wal file does
+** not exist (by deleting it) if the database file is empty.
+**
+** If the database is not empty and the *-wal file exists, open the pager
+** in WAL mode.  If the database is empty or if no *-wal file exists and
+** if no error occurs, make sure Pager.journalMode is not set to
+** PAGER_JOURNALMODE_WAL.
+**
+** Return SQLITE_OK or an error code.
 **
 ** If the WAL file is opened, also open a snapshot (read transaction).
 **
 ** The caller must hold a SHARED lock on the database file to call this
 ** function. Because an EXCLUSIVE lock on the db file is required to delete 
-** a WAL, this ensures there is no race condition between the xAccess() 
-** below and an xDelete() being executed by some other connection.
+** a WAL on a none-empty database, this ensures there is no race condition 
+** between the xAccess() below and an xDelete() being executed by some 
+** other connection.
 */
 static int pagerOpenWalIfPresent(Pager *pPager){
   int rc = SQLITE_OK;
   if( !pPager->tempFile ){
     int isWal;                    /* True if WAL file exists */
-    rc = pagerHasWAL(pPager, &isWal);
+    int nPage;                    /* Size of the database file */
+    assert( pPager->state>=SHARED_LOCK );
+    rc = sqlite3PagerPagecount(pPager, &nPage);
+    if( rc ) return rc;
+    if( nPage==0 ){
+      rc = pagerCheckForOrDeleteWAL(pPager, 0);
+      isWal = 0;
+    }else{
+      rc = pagerCheckForOrDeleteWAL(pPager, &isWal);
+    }
     if( rc==SQLITE_OK ){
       if( isWal ){
         pager_reset(pPager);
@@ -6071,7 +6098,7 @@ int sqlite3PagerCloseWal(Pager *pPager){
     int logexists = 0;
     rc = sqlite3OsLock(pPager->fd, SQLITE_LOCK_SHARED);
     if( rc==SQLITE_OK ){
-      rc = pagerHasWAL(pPager, &logexists);
+      rc = pagerCheckForOrDeleteWAL(pPager, &logexists);
     }
     if( rc==SQLITE_OK && logexists ){
       rc = sqlite3WalOpen(pPager->pVfs, pPager->fd,
diff --git a/test/wal4.test b/test/wal4.test
new file mode 100644 (file)
index 0000000..c255182
--- /dev/null
@@ -0,0 +1,52 @@
+# 2010 July 1
+#
+# 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.
+#
+#***********************************************************************
+# Verify that an empty database and a non-empty WAL file do not
+# result in database corruption
+#
+
+set testdir [file dirname $argv0]
+source $testdir/tester.tcl
+source $testdir/malloc_common.tcl
+ifcapable !wal {finish_test ; return }
+
+do_test wal4-1.1 {
+  db close
+  file delete -force wal4.db wal4.db-journal wal4.db-wal wal4.db-shm
+  file delete -force test.db test.db-journal test.db-wal test.db-shm
+  sqlite3 db2 wal4.db
+  db2 eval {
+    PRAGMA journal_mode=WAL;
+    CREATE TABLE t1(x);
+    INSERT INTO t1 VALUES(1);
+    INSERT INTO t1 VALUES(2);
+    SELECT x FROM t1 ORDER BY x;
+  }
+} {wal 1 2}
+do_test wal4-1.2 {
+  file delete -force test.db test.db-journal test.db-wal
+  file copy wal4.db-wal test.db-wal
+  sqlite3 db test.db
+  catchsql {
+    SELECT * FROM t1;
+  }
+} {1 {no such table: t1}}
+
+do_malloc_test wal4-2.0 -tclprep {
+  db close
+  file delete -force test.db test.db-journal test.db-wal
+  file copy wal4.db-wal test.db-wal
+  sqlite3 db test.db
+} -sqlbody {
+  SELECT name FROM sqlite_master
+}  
+
+
+finish_test