Index: src/pager.c ================================================================== --- src/pager.c +++ src/pager.c @@ -4887,19 +4887,19 @@ */ rc = sqlite3OsCheckReservedLock(pPager->fd, &locked); if( rc==SQLITE_OK && !locked ){ Pgno nPage; /* Number of pages in database file */ - /* Check the size of the database file. If it consists of 0 pages, - ** then delete the journal file. See the header comment above for - ** the reasoning here. Delete the obsolete journal file under - ** a RESERVED lock to avoid race conditions and to avoid violating - ** [H33020]. + /* Check the size of the database file. If it consists of 0 pages + ** and the journal is not being persisted, then delete the journal + ** file. See the header comment above for the reasoning here. + ** Delete the obsolete journal file under a RESERVED lock to avoid + ** race conditions and to avoid violating [H33020]. */ rc = pagerPagecount(pPager, &nPage); if( rc==SQLITE_OK ){ - if( nPage==0 ){ + if( nPage==0 && !jrnlOpen ){ sqlite3BeginBenignMalloc(); if( pagerLockDb(pPager, RESERVED_LOCK)==SQLITE_OK ){ sqlite3OsDelete(pVfs, pPager->zJournal, 0); if( !pPager->exclusiveMode ) pagerUnlockDb(pPager, SHARED_LOCK); } Index: test/corruptH.test ================================================================== --- test/corruptH.test +++ test/corruptH.test @@ -17,10 +17,22 @@ # Do not use a codec for tests in this file, as the database file is # manipulated directly using tcl scripts (using the [hexio_write] command). # do_not_use_codec database_may_be_corrupt + +# The corruption migrations tested by the code in this file are not detected +# mmap mode. +# +# The reason is that in mmap mode, the different queries may use different +# PgHdr objects for the same page (same data, but different PgHdr container +# objects). And so the corruption is not detected. +# +if {[permutation]=="mmap"} { + finish_test + return +} # Initialize the database. # do_execsql_test 1.1 { PRAGMA page_size=1024; @@ -50,10 +62,11 @@ hexio_write test.db [expr {($r(t2)-1)*1024 + 11}] [format %.2X $r(t1)] sqlite3 db test.db } {} do_test 1.3 { +breakpoint db eval { PRAGMA secure_delete=1 } list [catch { db eval { SELECT * FROM t1 WHERE a IN (1, 2) } { db eval { DELETE FROM t2 } } @@ -95,31 +108,20 @@ sqlite3 db test.db } {} -# The corruption migration caused by the test case below does not -# cause corruption to be detected in mmap mode. -# # The trick here is that the root page of the tree scanned by the outer # query is also currently on the free-list. So while the first seek on # the table (for a==1) works, by the time the second is attempted The # "INSERT INTO t2..." statements have recycled the root page of t1 and # used it as an index leaf. Normally, BtreeMovetoUnpacked() detects # that the PgHdr object associated with said root page does not match # the cursor (as it is now marked with PgHdr.intKey==0) and returns # SQLITE_CORRUPT. # -# However, in mmap mode, the outer query and the inner queries use -# different PgHdr objects (same data, but different PgHdr container -# objects). And so the corruption is not detected. Instead, the second -# seek fails to find anything and only a single row is returned. -# set res23 {1 {database disk image is malformed}} -if {[permutation]=="mmap"} { - set res23 {0 one} -} do_test 2.3 { list [catch { set res [list] db eval { SELECT * FROM t1 WHERE a IN (1, 2) } { db eval { Index: test/uri.test ================================================================== --- test/uri.test +++ test/uri.test @@ -236,16 +236,18 @@ testvfs tvfs1 tvfs1 filter {xOpen xDelete xAccess xFullPathname} tvfs1 script tvfs1_callback proc tvfs1_callback {method filename args} { set ::T1([file tail $filename]) 1 + return SQLITE_OK } testvfs tvfs2 tvfs2 filter {xOpen xDelete xAccess xFullPathname} tvfs2 script tvfs2_callback proc tvfs2_callback {method filename args} { set ::T2([file tail $filename]) 1 + return SQLITE_OK } catch {db close} eval forcedelete [glob test.db*] do_test 5.1.1 {