Index: src/pager.c ================================================================== --- src/pager.c +++ src/pager.c @@ -16,11 +16,11 @@ ** is separate from the database file. The pager also implements file ** locking to prevent two processes from writing the same database ** file simultaneously, or one process from reading the database while ** another is writing. ** -** @(#) $Id: pager.c,v 1.314 2007/04/02 05:07:47 danielk1977 Exp $ +** @(#) $Id: pager.c,v 1.315 2007/04/02 11:08:59 danielk1977 Exp $ */ #ifndef SQLITE_OMIT_DISKIO #include "sqliteInt.h" #include "os.h" #include "pager.h" @@ -2758,10 +2758,11 @@ int ro; assert( !pPager->tempFile ); rc = sqlite3OsOpenReadWrite(pPager->zJournal, &pPager->jfd, &ro); if( ro ){ rc = SQLITE_BUSY; + sqlite3OsClose(&pPager->jfd); } } if( rc!=SQLITE_OK ){ pager_unlock(pPager); return SQLITE_BUSY; @@ -2798,10 +2799,15 @@ PgHdr *pPage1 = pager_lookup(pPager, 1); if( pPage1 ){ unlinkPage(pPage1); + /* Make sure the former page 1 is right at the start of the + ** free-list. This triggers a special case in pagerAllocatePage() + ** to re-use this page even if the total number of pages in + ** the cache is less than Pager.mxPage. + */ assert( pPager->pFirst==pPager->pFirstSynced ); pPage1->pNextFree = pPager->pFirst; if( pPager->pFirst ){ pPager->pFirst->pPrevFree = pPage1; }else{ @@ -2808,11 +2814,10 @@ assert( !pPager->pLast ); pPager->pLast = pPage1; } pPager->pFirst = pPage1; pPager->pFirstSynced = pPage1; - } assert( !pager_lookup(pPager, 1) ); rc = sqlite3PagerAcquire(pPager, 1, &pPage1, 0); if( rc==SQLITE_OK ){ Index: test/misc7.test ================================================================== --- test/misc7.test +++ test/misc7.test @@ -8,11 +8,11 @@ # May you share freely, never taking more than you give. # #*********************************************************************** # This file implements regression tests for SQLite library. # -# $Id: misc7.test,v 1.10 2007/04/02 05:07:48 danielk1977 Exp $ +# $Id: misc7.test,v 1.11 2007/04/02 11:08:59 danielk1977 Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl do_test misc7-1 { @@ -327,16 +327,53 @@ error $msg } } sqlite3 db test.db + +do_test misc7-16.X { + execsql { + SELECT count(*) FROM t3; + } +} {32} + set sqlite_pager_n_sort_bucket 4 do_test misc7-17 { execsql { PRAGMA integrity_check; VACUUM; PRAGMA integrity_check; } } {ok ok} set sqlite_pager_n_sort_bucket 0 + +#---------------------------------------------------------------------- +# Test the situation where a hot-journal is discovered but write-access +# to it is denied. This should return SQLITE_BUSY. +# +do_test misc7-17.1 { + execsql { + BEGIN; + DELETE FROM t3 WHERE (oid%3)==0; + } + copy_file test.db bak.db + copy_file test.db-journal bak.db-journal + execsql { + COMMIT; + } + + copy_file bak.db test.db + copy_file bak.db-journal test.db-journal + file attributes test.db-journal -permissions r-------- + + catchsql { + SELECT count(*) FROM t3; + } +} {1 {database is locked}} +do_test misc7-17.2 { + file attributes test.db-journal -permissions rw------- + catchsql { + SELECT count(*) FROM t3; + } +} {0 28} finish_test