diff --git a/manifest b/manifest index 0f2ced6d05..7848ebdfb4 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\sthe\sobsolete\sstatic\smutexes.\s\sUse\sonly\sthe\slastest\sstatic\smutex\scode.\s(CVS\s4259) -D 2007-08-21T13:51:23 +C Delay\sopening\stemporary\spager\sfiles\suntil\sthey\sare\sfirst\swritten.\s(CVS\s4260) +D 2007-08-21T14:27:02 F Makefile.in 0c0e53720f658c7a551046442dd7afba0b72bfbe F Makefile.linux-gcc 65241babba6faf1152bf86574477baab19190499 F README 9c4e2d6706bdcc3efdd773ce752a8cdab4f90028 @@ -114,7 +114,7 @@ F src/os_unix.c 7aad42b1ee70d68034a4ac45fa822edccdc3d9e6 F src/os_unix.h 5768d56d28240d3fe4537fac08cc85e4fb52279e F src/os_win.c 29c0e19c1072679a4c7818c49fab2f35d2ad7747 F src/os_win.h 41a946bea10f61c158ce8645e7646b29d44f122b -F src/pager.c bb25ee85c990241be0f321978e6c5f6b645692b2 +F src/pager.c df16604a2a8c6808cd9b309a7e1bdb556d868c8e F src/pager.h 53087c6fb9db01aed17c7fd044662a27507e89b8 F src/parse.y 2d2ce439dc6184621fb0b86f4fc5aca7f391a590 F src/pragma.c 9b989506a1b7c8aecd6befb8235e2f57a4aba7e5 @@ -220,7 +220,7 @@ F test/collate6.test 8be65a182abaac8011a622131486dafb8076e907 F test/collate7.test e23677b1fd271505302643a98178952bb65b6f21 F test/collate8.test 7ed2461305ac959886a064dc1e3cf15e155a183f F test/colmeta.test 6505c73ab58796afcb7c89ba9f429d573fbc6e53 -F test/conflict.test ac40064d46c4c259cf6c216d30aa5bcc26e7eea2 +F test/conflict.test 79b5214ef7a52f3e58a50ae5c60c37e7594d04e9 F test/corrupt.test 18c7a995b1af76a8c8600b996257f2c7b7bff083 F test/corrupt2.test 572f8df0303d0ce63ddad5c5c9101a83a345ae46 F test/corrupt3.test 263e8bb04e2728df832fddf6973cf54c91db0c32 @@ -558,7 +558,7 @@ F www/tclsqlite.tcl 8be95ee6dba05eabcd27a9d91331c803f2ce2130 F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0 F www/version3.tcl 890248cf7b70e60c383b0e84d77d5132b3ead42b F www/whentouse.tcl fc46eae081251c3c181bd79c5faef8195d7991a5 -P a87f32e13e91250ab4d9366d2e9a3a7024a12fb9 -R 0b7b982232326cbf89fa9a6240b3b769 -U drh -Z 004bb3b1aa3b13212b12a95be5a80713 +P 6225cd461cdd2132eeb480aa4deb8986b7f63c15 +R 75c714761e5d5dec4034adbc16c873e3 +U danielk1977 +Z ca42567df49c41054078dbc0243fa598 diff --git a/manifest.uuid b/manifest.uuid index 3b7094d4b1..f405a8ffe5 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -6225cd461cdd2132eeb480aa4deb8986b7f63c15 \ No newline at end of file +3fb97a63ef70662abdba18ce8b480e6b0badcfb1 \ No newline at end of file diff --git a/src/pager.c b/src/pager.c index f13f34c920..208241a5c6 100644 --- a/src/pager.c +++ b/src/pager.c @@ -18,7 +18,7 @@ ** file simultaneously, or one process from reading the database while ** another is writing. ** -** @(#) $Id: pager.c,v 1.363 2007/08/21 10:44:16 drh Exp $ +** @(#) $Id: pager.c,v 1.364 2007/08/21 14:27:02 danielk1977 Exp $ */ #ifndef SQLITE_OMIT_DISKIO #include "sqliteInt.h" @@ -549,6 +549,16 @@ static int write32bits(sqlite3_file *fd, i64 offset, u32 val){ return sqlite3OsWrite(fd, ac, 4, offset); } +/* +** If file pFd is open, call sqlite3OsUnlock() on it. +*/ +static int osUnlock(sqlite3_file *pFd, int eLock){ + if( !pFd->pMethods ){ + return SQLITE_OK; + } + return sqlite3OsUnlock(pFd, eLock); +} + /* ** This function should be called when an error occurs within the pager ** code. The first argument is a pointer to the pager structure, the @@ -930,7 +940,7 @@ static PgHdr *pager_lookup(Pager *pPager, Pgno pgno){ static void pager_unlock(Pager *pPager){ if( !pPager->exclusiveMode ){ if( !MEMDB ){ - sqlite3OsUnlock(pPager->fd, NO_LOCK); + osUnlock(pPager->fd, NO_LOCK); pPager->dbSize = -1; IOTRACE(("UNLOCK %p\n", pPager)) } @@ -1045,7 +1055,7 @@ static int pager_end_transaction(Pager *pPager){ } if( !pPager->exclusiveMode ){ - rc2 = sqlite3OsUnlock(pPager->fd, SHARED_LOCK); + rc2 = osUnlock(pPager->fd, SHARED_LOCK); pPager->state = PAGER_SHARED; }else if( pPager->state==PAGER_SYNCED ){ pPager->state = PAGER_EXCLUSIVE; @@ -1318,7 +1328,7 @@ static void pager_truncate_cache(Pager *pPager); */ static int pager_truncate(Pager *pPager, int nPage){ int rc = SQLITE_OK; - if( pPager->state>=PAGER_EXCLUSIVE ){ + if( pPager->state>=PAGER_EXCLUSIVE && pPager->fd->pMethods ){ rc = sqlite3OsTruncate(pPager->fd, pPager->pageSize*(i64)nPage); } if( rc==SQLITE_OK ){ @@ -1335,7 +1345,14 @@ static int pager_truncate(Pager *pPager, int nPage){ ** by sqlite3OsSectorSize() and the pageSize. */ static void setSectorSize(Pager *pPager){ - pPager->sectorSize = sqlite3OsSectorSize(pPager->fd); + assert(pPager->fd->pMethods||pPager->tempFile); + if( !pPager->tempFile ){ + /* Sector size doesn't matter for temporary files. Also, the file + ** may not have been opened yet, in whcih case the OsSectorSize() + ** call will segfault. + */ + pPager->sectorSize = sqlite3OsSectorSize(pPager->fd); + } if( pPager->sectorSizepageSize ){ pPager->sectorSize = pPager->pageSize; } @@ -1823,10 +1840,13 @@ int sqlite3PagerOpen( } } }else{ - rc = sqlite3PagerOpentemp(pVfs, pPager->fd, pPager->zFilename); - if( rc==SQLITE_OK ){ - tempFile = 1; - } + /* If a temporary file is requested, it is not opened immediately. + ** In this case we accept the default page size and delay actually + ** opening the file until the first call to OsWrite(). + */ + /* rc = sqlite3PagerOpentemp(pVfs, pPager->fd, pPager->zFilename); */ + tempFile = 1; + pPager->state = PAGER_EXCLUSIVE; } if( pPager && rc==SQLITE_OK ){ @@ -1887,7 +1907,7 @@ int sqlite3PagerOpen( /* pPager->pFirstSynced = 0; */ /* pPager->pLast = 0; */ pPager->nExtra = FORCE_ALIGNMENT(nExtra); - assert(pPager->fd->pMethods||memDb); + assert(pPager->fd->pMethods||memDb||tempFile); if( !memDb ){ setSectorSize(pPager); } @@ -1999,7 +2019,8 @@ void enable_simulated_io_errors(void){ int sqlite3PagerReadFileheader(Pager *pPager, int N, unsigned char *pDest){ int rc = SQLITE_OK; memset(pDest, 0, N); - if( MEMDB==0 ){ + assert(MEMDB||pPager->fd->pMethods||pPager->tempFile); + if( pPager->fd->pMethods ){ IOTRACE(("DBHDR %p 0 %d\n", pPager, N)) rc = sqlite3OsRead(pPager->fd, pDest, N, 0); if( rc==SQLITE_IOERR_SHORT_READ ){ @@ -2019,7 +2040,7 @@ int sqlite3PagerReadFileheader(Pager *pPager, int N, unsigned char *pDest){ ** file is 4096 bytes, 5 is returned instead of 4. */ int sqlite3PagerPagecount(Pager *pPager){ - i64 n; + i64 n = 0; int rc; assert( pPager!=0 ); if( pPager->errCode ){ @@ -2028,7 +2049,9 @@ int sqlite3PagerPagecount(Pager *pPager){ if( pPager->dbSize>=0 ){ n = pPager->dbSize; } else { - if( (rc = sqlite3OsFileSize(pPager->fd, &n))!=SQLITE_OK ){ + assert(pPager->fd->pMethods||pPager->tempFile); + if( (pPager->fd->pMethods) + && (rc = sqlite3OsFileSize(pPager->fd, &n))!=SQLITE_OK ){ pager_error(pPager, rc); return 0; } @@ -2570,6 +2593,14 @@ static int pager_write_pagelist(PgHdr *pList){ pList = sort_pagelist(pList); while( pList ){ + + /* If the file has not yet been opened, open it now. */ + if( !pPager->fd->pMethods ){ + assert(pPager->tempFile); + rc = sqlite3PagerOpentemp(pPager->pVfs, pPager->fd, pPager->zFilename); + if( rc ) return rc; + } + assert( pList->dirty ); /* If there are dirty pages in the page cache with page numbers greater ** than Pager.dbSize, this means sqlite3PagerTruncate() was called to @@ -2834,6 +2865,10 @@ static int readDbPage(Pager *pPager, PgHdr *pPg, Pgno pgno){ int rc; i64 offset; assert( MEMDB==0 ); + assert(pPager->fd->pMethods||pPager->tempFile); + if( !pPager->fd->pMethods ){ + return SQLITE_IOERR_SHORT_READ; + } offset = (pgno-1)*(i64)pPager->pageSize; rc = sqlite3OsRead(pPager->fd, PGHDR_TO_DATA(pPg), pPager->pageSize, offset); PAGER_INCR(sqlite3_pager_readdb_count); diff --git a/test/conflict.test b/test/conflict.test index bc972b6654..6bca1e839f 100644 --- a/test/conflict.test +++ b/test/conflict.test @@ -13,7 +13,7 @@ # This file implements tests for the conflict resolution extension # to SQLite. # -# $Id: conflict.test,v 1.29 2007/04/06 21:42:22 drh Exp $ +# $Id: conflict.test,v 1.30 2007/08/21 14:27:02 danielk1977 Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl @@ -285,20 +285,23 @@ do_test conflict-6.0 { # t3 Number of temporary files for tables # t4 Number of temporary files for statement journals # +# Update: Since temporary table files are now opened lazily, and none +# of the following tests use large quantities of data, t3 is always 0. +# foreach {i conf1 cmd t0 t1 t2 t3 t4} { 1 {} UPDATE 1 {6 7 8 9} 1 0 1 - 2 REPLACE UPDATE 0 {7 6 9} 1 1 0 - 3 IGNORE UPDATE 0 {6 7 3 9} 1 1 0 + 2 REPLACE UPDATE 0 {7 6 9} 1 0 0 + 3 IGNORE UPDATE 0 {6 7 3 9} 1 0 0 4 FAIL UPDATE 1 {6 7 3 4} 1 0 0 5 ABORT UPDATE 1 {1 2 3 4} 1 0 1 6 ROLLBACK UPDATE 1 {1 2 3 4} 0 0 0 - 7 REPLACE {UPDATE OR IGNORE} 0 {6 7 3 9} 1 1 0 - 8 IGNORE {UPDATE OR REPLACE} 0 {7 6 9} 1 1 0 - 9 FAIL {UPDATE OR IGNORE} 0 {6 7 3 9} 1 1 0 - 10 ABORT {UPDATE OR REPLACE} 0 {7 6 9} 1 1 0 - 11 ROLLBACK {UPDATE OR IGNORE} 0 {6 7 3 9} 1 1 0 - 12 {} {UPDATE OR IGNORE} 0 {6 7 3 9} 1 1 0 - 13 {} {UPDATE OR REPLACE} 0 {7 6 9} 1 1 0 + 7 REPLACE {UPDATE OR IGNORE} 0 {6 7 3 9} 1 0 0 + 8 IGNORE {UPDATE OR REPLACE} 0 {7 6 9} 1 0 0 + 9 FAIL {UPDATE OR IGNORE} 0 {6 7 3 9} 1 0 0 + 10 ABORT {UPDATE OR REPLACE} 0 {7 6 9} 1 0 0 + 11 ROLLBACK {UPDATE OR IGNORE} 0 {6 7 3 9} 1 0 0 + 12 {} {UPDATE OR IGNORE} 0 {6 7 3 9} 1 0 0 + 13 {} {UPDATE OR REPLACE} 0 {7 6 9} 1 0 0 14 {} {UPDATE OR FAIL} 1 {6 7 3 4} 1 0 0 15 {} {UPDATE OR ABORT} 1 {1 2 3 4} 1 0 1 16 {} {UPDATE OR ROLLBACK} 1 {1 2 3 4} 0 0 0