]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Drop any existing mapping of the database file when exiting the pager "error state...
authordan <dan@noemail.net>
Sat, 6 Jul 2013 17:57:39 +0000 (17:57 +0000)
committerdan <dan@noemail.net>
Sat, 6 Jul 2013 17:57:39 +0000 (17:57 +0000)
FossilOrigin-Name: 0ae7e75b215b0d75920769da9146c54ce2ad3ce0

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

index 23133400161b36662add986b7f110c86280eede5..4d509540ae24373292fb9266b49fd8935b387407 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Fix\stwo\stest\sscript\sproblems\srevealed\sby\spermutations.test.
-D 2013-07-05T19:16:58.185
+C Drop\sany\sexisting\smapping\sof\sthe\sdatabase\sfile\swhen\sexiting\sthe\spager\s"error\sstate",\sas\sit\smay\sat\sthis\spoint\sbe\stoo\slarge\sfor\sthe\sdatabase\sfile.\sDo\snot\sinvoke\sfile-control\sMMAP_LIMIT\sif\sthe\sdatabase\sfile\shandle\sdoes\snot\ssupport\sxFetch\sand\sxUnfetch\s(on\sthe\sgrounds\sthat\sxUnfetch(0)\scalls\sto\sinvalidate\sthe\smapping\scannot\sbe\smade).
+D 2013-07-06T17:57:39.341
 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
 F Makefile.in 5e41da95d92656a5004b03d3576e8b226858a28e
 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
@@ -204,7 +204,7 @@ F src/os.h 4a46270a64e9193af4a0aaa3bc2c66dc07c29b3f
 F src/os_common.h 92815ed65f805560b66166e3583470ff94478f04
 F src/os_unix.c 9eafa5458cf2ff684ddccff82c9bb113c7cad847
 F src/os_win.c 074cb2b9bca6a1c2bd72acf04666cdc554bfaa9b
-F src/pager.c 79df56da9dd49aceaa4cac207484a9a82cba40ae
+F src/pager.c 5d2f7475260a8588f9c441bb309d2b7eaa7ded3b
 F src/pager.h 5cb78b8e1adfd5451e600be7719f5a99d87ac3b1
 F src/parse.y 9acfcc83ddbf0cf82f0ed9582ccf0ad6c366ff37
 F src/pcache.c f8043b433a57aba85384a531e3937a804432a346
@@ -268,7 +268,7 @@ F src/test_superlock.c 2b97936ca127d13962c3605dbc9a4ef269c424cd
 F src/test_syscall.c 16dbe79fb320fadb5acd7a0a59f49e52ab2d2091
 F src/test_tclvar.c f4dc67d5f780707210d6bb0eb6016a431c04c7fa
 F src/test_thread.c 1e133a40b50e9c035b00174035b846e7eef481cb
-F src/test_vfs.c 8e6087a8b3dcc260282074b0efba14b76311120c
+F src/test_vfs.c 12d9931f65acde64961523b6f420ba7cd057fbd7
 F src/test_vfstrace.c 34b544e80ba7fb77be15395a609c669df2e660a2
 F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9
 F src/tokenize.c e0e8fd3cb90a88451f6b6425726c84747b6b20d7
@@ -680,6 +680,7 @@ F test/misuse.test ba4fb5d1a6101d1c171ea38b3c613d0661c83054
 F test/mmap1.test 93d167b328255cbe6679fe1e1a23be1b1197d07b
 F test/mmap2.test 9d6dd9ddb4ad2379f29cc78f38ce1e63ed418022
 F test/mmap3.test c92273e16eb8d23c1d55c9815b446bb72ef0512e
+F test/mmapfault.test 97507ee06172df99057dbf1c40294eabd82cbb13
 F test/multiplex.test e08cc7177bd6d85990ee1d71100bb6c684c02256
 F test/multiplex2.test 580ca5817c7edbe4cc68fa150609c9473393003a
 F test/multiplex3.test d228f59eac91839a977eac19f21d053f03e4d101
@@ -1100,7 +1101,7 @@ F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
 F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381
 F tool/wherecosttest.c f407dc4c79786982a475261866a161cd007947ae
 F tool/win/sqlite.vsix 97894c2790eda7b5bce3cc79cb2a8ec2fde9b3ac
-P ff8c3f7840a0a8d87453b94b9884ee26d5d92da5
-R 56be08aa68ca7836af91c2136feb349d
+P 60cf7e44871ca8d2136ddad02188f0b9f9c380c1
+R a3d4118f345e93dec612dcda9d6a1643
 U dan
-Z 08268413632a362597d53f1432d728b7
+Z 5f805b6fdaecab7821c75d7c85386fd6
index 51a4d44eb9ca51ba74121e9c0cc33df341893db5..f316275b230e0b6ed8c31ed2e953a7270c64940f 100644 (file)
@@ -1 +1 @@
-60cf7e44871ca8d2136ddad02188f0b9f9c380c1
\ No newline at end of file
+0ae7e75b215b0d75920769da9146c54ce2ad3ce0
\ No newline at end of file
index 645cc3d9a03e9a799c01b5c0f60786c60b74f27d..b2082289681271c1c0cbbdf389acf2080550df06 100644 (file)
@@ -1812,6 +1812,7 @@ static void pager_unlock(Pager *pPager){
     pPager->changeCountDone = pPager->tempFile;
     pPager->eState = PAGER_OPEN;
     pPager->errCode = SQLITE_OK;
+    if( USEFETCH(pPager) ) sqlite3OsUnfetch(pPager->fd, 0, 0);
   }
 
   pPager->journalOff = 0;
@@ -3378,10 +3379,10 @@ void sqlite3PagerSetCachesize(Pager *pPager, int mxPage){
 static void pagerFixMaplimit(Pager *pPager){
 #if SQLITE_MAX_MMAP_SIZE>0
   sqlite3_file *fd = pPager->fd;
-  if( isOpen(fd) ){
+  if( isOpen(fd) && fd->pMethods->iVersion>=3 ){
     sqlite3_int64 sz;
-    pPager->bUseFetch = (fd->pMethods->iVersion>=3) && pPager->szMmap>0;
     sz = pPager->szMmap;
+    pPager->bUseFetch = (sz>0);
     sqlite3OsFileControlHint(pPager->fd, SQLITE_FCNTL_MMAP_SIZE, &sz);
   }
 #endif
index fcd577439cfd6c72dde48358921420cf6ef1f86d..8b6b530bb64c53c6bfd141c2916637d8805b0e0b 100644 (file)
@@ -190,8 +190,11 @@ static int tvfsShmMap(sqlite3_file*,int,int,int, void volatile **);
 static void tvfsShmBarrier(sqlite3_file*);
 static int tvfsShmUnmap(sqlite3_file*, int);
 
+static int tvfsFetch(sqlite3_file*, sqlite3_int64, int, void**);
+static int tvfsUnfetch(sqlite3_file*, sqlite3_int64, void*);
+
 static sqlite3_io_methods tvfs_io_methods = {
-  2,                              /* iVersion */
+  3,                              /* iVersion */
   tvfsClose,                      /* xClose */
   tvfsRead,                       /* xRead */
   tvfsWrite,                      /* xWrite */
@@ -207,7 +210,9 @@ static sqlite3_io_methods tvfs_io_methods = {
   tvfsShmMap,                     /* xShmMap */
   tvfsShmLock,                    /* xShmLock */
   tvfsShmBarrier,                 /* xShmBarrier */
-  tvfsShmUnmap                    /* xShmUnmap */
+  tvfsShmUnmap,                   /* xShmUnmap */
+  tvfsFetch,
+  tvfsUnfetch
 };
 
 static int tvfsResultCode(Testvfs *p, int *pRc){
@@ -618,7 +623,10 @@ static int tvfsOpen(
 
     pMethods = (sqlite3_io_methods *)ckalloc(nByte);
     memcpy(pMethods, &tvfs_io_methods, nByte);
-    pMethods->iVersion = pVfs->iVersion;
+    pMethods->iVersion = pFd->pReal->pMethods->iVersion;
+    if( pMethods->iVersion>pVfs->iVersion ){
+      pMethods->iVersion = pVfs->iVersion;
+    }
     if( pVfs->iVersion>1 && ((Testvfs *)pVfs->pAppData)->isNoshm ){
       pMethods->xShmUnmap = 0;
       pMethods->xShmLock = 0;
@@ -993,6 +1001,21 @@ static int tvfsShmUnmap(
   return rc;
 }
 
+static int tvfsFetch(
+    sqlite3_file *pFile, 
+    sqlite3_int64 iOfst, 
+    int iAmt, 
+    void **pp
+){
+  TestvfsFd *pFd = tvfsGetFd(pFile);
+  return sqlite3OsFetch(pFd->pReal, iOfst, iAmt, pp);
+}
+
+static int tvfsUnfetch(sqlite3_file *pFile, sqlite3_int64 iOfst, void *p){
+  TestvfsFd *pFd = tvfsGetFd(pFile);
+  return sqlite3OsUnfetch(pFd->pReal, iOfst, p);
+}
+
 static int testvfs_obj_cmd(
   ClientData cd,
   Tcl_Interp *interp,
@@ -1343,7 +1366,7 @@ static int testvfs_cmd(
   Tcl_Obj *CONST objv[]
 ){
   static sqlite3_vfs tvfs_vfs = {
-    2,                            /* iVersion */
+    3,                            /* iVersion */
     0,                            /* szOsFile */
     0,                            /* mxPathname */
     0,                            /* pNext */
@@ -1369,6 +1392,9 @@ static int testvfs_cmd(
     tvfsCurrentTime,              /* xCurrentTime */
     0,                            /* xGetLastError */
     0,                            /* xCurrentTimeInt64 */
+    0,                            /* xSetSystemCall */
+    0,                            /* xGetSystemCall */
+    0,                            /* xNextSystemCall */
   };
 
   Testvfs *p;                     /* New object */
@@ -1382,7 +1408,7 @@ static int testvfs_cmd(
   int isDefault = 0;              /* True if -default is passed */
   int szOsFile = 0;               /* Value passed to -szosfile */
   int mxPathname = -1;            /* Value passed to -mxpathname */
-  int iVersion = 2;               /* Value passed to -iversion */
+  int iVersion = 3;               /* Value passed to -iversion */
 
   if( objc<2 || 0!=(objc%2) ) goto bad_args;
   for(i=2; i<objc; i += 2){
diff --git a/test/mmapfault.test b/test/mmapfault.test
new file mode 100644 (file)
index 0000000..248b5ba
--- /dev/null
@@ -0,0 +1,77 @@
+# 2013-05-23
+#
+# 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
+ifcapable !mmap {
+  finish_test
+  return
+}
+set testprefix mmapfault
+
+set a_string_counter 1
+proc a_string {n} {
+  global a_string_counter
+  incr a_string_counter
+  string range [string repeat "${a_string_counter}." $n] 1 $n
+}
+db func a_string a_string
+
+do_test 1-pre {
+  execsql {
+    CREATE TABLE t1(a UNIQUE, b UNIQUE);
+    INSERT INTO t1 VALUES(a_string(200), a_string(300));
+    INSERT INTO t1 SELECT a_string(200), a_string(300) FROM t1;
+    INSERT INTO t1 SELECT a_string(200), a_string(300) FROM t1;
+  }
+  faultsim_save_and_close
+} {}
+
+
+do_faultsim_test 1 -prep {
+  faultsim_restore_and_reopen
+  db func a_string a_string
+  breakpoint
+  execsql {
+    PRAGMA mmap_size = 1000000;
+    PRAGMA cache_size = 5;
+    BEGIN;
+      INSERT INTO t1 SELECT a_string(200), a_string(300) FROM t1;
+      INSERT INTO t1 SELECT a_string(200), a_string(300) FROM t1;
+      INSERT INTO t1 SELECT a_string(200), a_string(300) FROM t1;
+      INSERT INTO t1 SELECT a_string(200), a_string(300) FROM t1;
+  }
+} -body {
+  execsql { INSERT INTO t1 VALUES(a_string(200), a_string(300)) }
+} -test {
+  faultsim_test_result {0 {}} 
+
+  if {[sqlite3_get_autocommit db]} {
+    sqlite3 db2 test.db
+    set nRow [db2 one {SELECT count(*) FROM t1}]
+    if {$nRow!=4} { error "Database content appears incorrect (1)" }
+    db2 close
+  }
+
+  execsql { INSERT INTO t1 VALUES(a_string(201), a_string(301)) }
+  set nRow [db one {SELECT count(*) FROM t1}]
+  if {$nRow!=5 && $nRow!=66 && $nRow!=65} { 
+    error "Database content appears incorrect (2) ($nRow)" 
+  }
+
+  catch { execsql COMMIT }
+}
+
+
+
+finish_test