From: dan Date: Tue, 3 Aug 2010 06:42:39 +0000 (+0000) Subject: Incremental checkin on pager state refactoring. X-Git-Tag: version-3.7.2~53^2~26 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=763afe62e1defca58ce0f865af2bfe0f51bca804;p=thirdparty%2Fsqlite.git Incremental checkin on pager state refactoring. FossilOrigin-Name: 0a636798bdb6961a47327091715b254f79add823 --- diff --git a/manifest b/manifest index d8a6e2a31d..625d681ee0 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Experimental\srefactoring\sof\sthe\sPager\sobject\sstate. -D 2010-08-02T14:32:52 +C Incremental\scheckin\son\spager\sstate\srefactoring. +D 2010-08-03T06:42:40 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in ec08dc838fd8110fe24c92e5130bcd91cbb1ff2e F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -156,7 +156,7 @@ F src/os_common.h a8f95b81eca8a1ab8593d23e94f8a35f35d4078f F src/os_os2.c 72d0b2e562952a2464308c4ce5f7913ac10bef3e F src/os_unix.c ae5ca8a6031380708f3fec7be325233d49944914 F src/os_win.c 51cb62f76262d961ea4249489383d714501315a7 -F src/pager.c 94f00bedf9afb83c47f9b5d8bf8608f0eff088dd +F src/pager.c a22869257641c379545e482d843904702d027db7 F src/pager.h 80726162dc3942f59ab27b738fb667b9ba0a89d5 F src/parse.y 12b7ebd61ea54f0e1b1083ff69cc2c8ce9353d58 F src/pcache.c 1e9aa2dbc0845b52e1b51cc39753b6d1e041cb07 @@ -207,7 +207,7 @@ F src/test_osinst.c f408c6a181f2fb04c56273afd5c3e1e82f60392c F src/test_pcache.c 7bf828972ac0d2403f5cfa4cd14da41f8ebe73d8 F src/test_schema.c 8c06ef9ddb240c7a0fcd31bc221a6a2aade58bf0 F src/test_server.c bbba05c144b5fc4b52ff650a4328027b3fa5fcc6 -F src/test_stat.c 6ebaf2a86d01ccda24e49c148f1d33e8badda06e +F src/test_stat.c dcabb7d39da058cbfc9ddc427cd92fbf14822b28 F src/test_tclvar.c f4dc67d5f780707210d6bb0eb6016a431c04c7fa F src/test_thread.c bedd05cad673dba53326f3aa468cc803038896c0 F src/test_vfs.c 7e291f85256516ebde6633bc381ff7eedfa30234 @@ -227,8 +227,8 @@ F src/vdbeblob.c 258a6010ba7a82b72b327fb24c55790655689256 F src/vdbemem.c 5e579abf6532001dfbee0e640dc34eae897a9807 F src/vdbetrace.c 864cef96919323482ebd9986f2132435115e9cc2 F src/vtab.c 82200af3881fa4e1c9cf07cf31d98c09d437e3ab -F src/wal.c 72cb5df7f4c26f83cb661d5a607b9918da99f758 -F src/wal.h 906c85760598b18584921fe08008435aa4eeeeb2 +F src/wal.c 6e04bccccd75acf86725cc8cb4b107cd245e018c +F src/wal.h 96669b645e27cd5a111ba59f0cae7743a207bc3c F src/walker.c 3112bb3afe1d85dc52317cb1d752055e9a781f8f F src/where.c 79202ca81e740eeb1f54512147e29b6c518d84ca F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2 @@ -547,7 +547,7 @@ F test/pageropt.test 8146bf448cf09e87bb1867c2217b921fb5857806 F test/pagesize.test 76aa9f23ecb0741a4ed9d2e16c5fa82671f28efb F test/pcache.test 4118a183908ecaed343a06fcef3ba82e87e0129d F test/pcache2.test 0d85f2ab6963aee28c671d4c71bec038c00a1d16 -F test/permutations.test 3fe47c21c32b294b2354e702a25bfbff65747bb1 +F test/permutations.test 17498d1219f922d5a6da893a94c4dc7766fb2426 F test/pragma.test ed78d200f65c6998df51196cb8c39d5300570f24 F test/pragma2.test 5364893491b9231dd170e3459bfc2e2342658b47 F test/printf.test 05970cde31b1a9f54bd75af60597be75a5c54fea @@ -841,7 +841,7 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f -P 347f22a5b777af92873590a5b9af5a6498bef918 -R fb51b6835fc754e61c37a4fea5d6298b +P 03a240514aa07a22db787d221641253f23933e88 +R 0befc920b01bc332d217d8425323f579 U dan -Z 550ac78d14ba82c7a2ec704cc3fbe702 +Z 0621f056ce54ddd71f6be378b7d6f549 diff --git a/manifest.uuid b/manifest.uuid index 0099265206..2daa895065 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -03a240514aa07a22db787d221641253f23933e88 \ No newline at end of file +0a636798bdb6961a47327091715b254f79add823 \ No newline at end of file diff --git a/src/pager.c b/src/pager.c index 947194927f..c9f2d2ebf5 100644 --- a/src/pager.c +++ b/src/pager.c @@ -130,13 +130,24 @@ int sqlite3PagerTrace=1; /* True to enable tracing */ ** pager may be in any one of the following six states: ** ** NONE: +** The pager starts up in this state. Nothing is guaranteed in this +** state - the file may or may not be locked and the database size is +** unknown. The database may not be read or written. +** ** * No read or write transaction is active. ** * Any lock, or no lock at all, may be held on the database file. +** * The dbSize, dbOrigSize and dbFileSize variables may not be trusted. ** ** READER: -** * A read transaction is active. +** In this state all the requirements for reading the database in +** rollback (non-WAL) mode are met. Unless the pager is (or recently +** was) in exclusive-locking mode, a user-level read transaction is +** open. The database size is known in this state. +** +** * A read transaction may be active. ** * A SHARED or greater lock is held on the database file. -** * The dbSize variable is valid. +** * The dbSize variable may be trusted (even if a user-level read +** transaction is not active). ** ** WRITER_INITIAL: ** * A write transaction is active. @@ -167,8 +178,7 @@ int sqlite3PagerTrace=1; /* True to enable tracing */ ** commit the transaction. If an error did occur, the caller will need ** to rollback the transaction. ** -** -** Allowable transitions and the [function] that performe each: +** Allowable transitions and the [function] that performs each: ** ** NONE -> READER [PagerSharedLock] ** READER -> WRITER_INITIAL [PagerBegin] @@ -182,6 +192,19 @@ int sqlite3PagerTrace=1; /* True to enable tracing */ ** WRITER_FINISHED -> READER [pager_end_transaction] ** ** READER -> NONE [pager_unlock] +** +** Notes: +** +** * A pager is never in WRITER_DBMOD or WRITER_FINISHED state if the +** connection is open in WAL mode. A WAL connection is always in one +** of the first four states. +** +** * Normally, a connection open in exclusive mode is never in PAGER_NONE +** state. There are two exceptions: immediately after exclusive-mode has +** been turned on (and before any read or write transactions are +** executed), and when the pager is leaving the "error state". +** +** * See also: assert_pager_state(). */ #define PAGER_NONE 0 #define PAGER_READER 1 @@ -425,8 +448,8 @@ struct Pager { u8 state; /* PAGER_UNLOCK, _SHARED, _RESERVED, etc. */ u8 dbModified; /* True if there are any changes to the Db */ u8 journalStarted; /* True if header of journal is synced */ -#endif u8 dbSizeValid; /* Set when dbSize is correct */ +#endif u8 eState; /* Pager state (NONE, READER, WRITER_INITIAL..) */ u8 eLock; /* Current lock held on database file */ @@ -623,7 +646,6 @@ static int assert_pager_state(Pager *p){ case PAGER_NONE: assert( !MEMDB ); assert( !p->tempFile ); - assert( !pagerUseWal(pPager) ); break; case PAGER_READER: @@ -1348,7 +1370,6 @@ static void pager_reset(Pager *pPager){ if( SQLITE_OK==pPager->errCode ){ sqlite3BackupRestart(pPager->pBackup); sqlite3PcacheClear(pPager->pPCache); - pPager->dbSizeValid = 0; } } @@ -1428,14 +1449,6 @@ static void pager_unlock(Pager *pPager){ pPager->pInJournal = 0; releaseAllSavepoints(pPager); - /* If the file is unlocked, somebody else might change it. The - ** values stored in Pager.dbSize etc. might become invalid if - ** this happens. One can argue that this doesn't need to be cleared - ** until the change-counter check fails in PagerSharedLock(). - ** Clearing the page size cache here is being conservative. - */ - pPager->dbSizeValid = 0; - if( pagerUseWal(pPager) ){ sqlite3WalEndReadTransaction(pPager->pWal); }else{ @@ -2589,6 +2602,7 @@ static int pagerBeginReadTransaction(Pager *pPager){ int changed = 0; /* True if cache must be reset */ assert( pagerUseWal(pPager) ); + assert( pPager->eState==PAGER_NONE || pPager->eState==PAGER_SHARED ); /* sqlite3WalEndReadTransaction() was not called for the previous ** transaction in locking_mode=EXCLUSIVE. So call it now. If we @@ -2598,19 +2612,41 @@ static int pagerBeginReadTransaction(Pager *pPager){ sqlite3WalEndReadTransaction(pPager->pWal); rc = sqlite3WalBeginReadTransaction(pPager->pWal, &changed); - if( rc==SQLITE_OK ){ - int dummy; - if( changed ){ - pager_reset(pPager); - assert( pPager->errCode || pPager->dbSizeValid==0 ); - } - rc = sqlite3PagerPagecount(pPager, &dummy); + if( rc==SQLITE_OK && changed ){ + pager_reset(pPager); } - pPager->eState = PAGER_READER; return rc; } + +/* +** TODO: Description here. +*/ +static int pagerPagecount(Pager *pPager, Pgno *pnPage){ + Pgno nPage; /* Value to return via *pnPage */ + + assert( pPager->eState==PAGER_NONE ); + nPage = sqlite3WalDbsize(pPager->pWal); + if( nPage==0 ){ + i64 n = 0; /* Size of db file in bytes */ + assert( isOpen(pPager->fd) || pPager->tempFile ); + if( isOpen(pPager->fd) ){ + int rc = sqlite3OsFileSize(pPager->fd, &n); + if( rc!=SQLITE_OK ){ + return rc; + } + } + nPage = (Pgno)(n / pPager->pageSize); + if( nPage==0 && n>0 ){ + nPage = 1; + } + } + *pnPage = nPage; + return SQLITE_OK; +} + + /* ** Check if the *-wal file that corresponds to the database opened by pPager ** exists if the database is not empy, or verify that the *-wal file does @@ -2635,10 +2671,11 @@ static int pagerOpenWalIfPresent(Pager *pPager){ int rc = SQLITE_OK; if( !pPager->tempFile ){ int isWal; /* True if WAL file exists */ - int nPage; /* Size of the database file */ + Pgno nPage; /* Size of the database file */ + assert( pPager->eState==PAGER_NONE ); assert( pPager->eLock>=SHARED_LOCK || pPager->noReadlock ); - rc = sqlite3PagerPagecount(pPager, &nPage); + rc = pagerPagecount(pPager, &nPage); if( rc ) return rc; if( nPage==0 ){ rc = sqlite3OsDelete(pPager->pVfs, pPager->zWal, 0); @@ -2650,7 +2687,7 @@ static int pagerOpenWalIfPresent(Pager *pPager){ } if( rc==SQLITE_OK ){ if( isWal ){ - pager_reset(pPager); + assert( sqlite3PcachePagecount(pPager->pPCache)==0 ); rc = sqlite3PagerOpenWal(pPager, 0); if( rc==SQLITE_OK ){ rc = pagerBeginReadTransaction(pPager); @@ -2960,11 +2997,19 @@ int sqlite3PagerSetPagesize(Pager *pPager, u16 *pPageSize, int nReserve){ && sqlite3PcacheRefCount(pPager->pPCache)==0 && pageSize && pageSize!=pPager->pageSize ){ - char *pNew = (char *)sqlite3PageMalloc(pageSize); + char *pNew; /* New temp space */ + i64 nByte = 0; + if( pPager->eState>PAGER_NONE && isOpen(pPager->fd) ){ + rc = sqlite3OsFileSize(pPager->fd, &nByte); + if( rc!=SQLITE_OK ) return rc; + } + pNew = (char *)sqlite3PageMalloc(pageSize); if( !pNew ){ rc = SQLITE_NOMEM; }else{ + assert( pPager->eState==PAGER_NONE || pPager->eState==PAGER_READER ); pager_reset(pPager); + pPager->dbSize = nByte/pageSize; pPager->pageSize = pageSize; sqlite3PageFree(pPager->pTmpSpace); pPager->pTmpSpace = pNew; @@ -3088,15 +3133,18 @@ int sqlite3PagerReadFileheader(Pager *pPager, int N, unsigned char *pDest){ int sqlite3PagerPagecount(Pager *pPager, int *pnPage){ Pgno nPage = 0; /* Value to return via *pnPage */ + assert( pPager->eState>=PAGER_SHARED ); + assert( pPager->eState!=PAGER_WRITER_FINISHED ); + /* Determine the number of pages in the file. Store this in nPage. */ - if( pPager->dbSizeValid ){ + if( pPager->eState>PAGER_NONE ){ nPage = pPager->dbSize; }else{ int rc; /* Error returned by OsFileSize() */ i64 n = 0; /* File size in bytes returned by OsFileSize() */ if( pagerUseWal(pPager) && pPager->eState!=PAGER_NONE ){ - sqlite3WalDbsize(pPager->pWal, &nPage); + nPage = sqlite3WalDbsize(pPager->pWal); } if( nPage==0 ){ @@ -3116,7 +3164,6 @@ int sqlite3PagerPagecount(Pager *pPager, int *pnPage){ if( pPager->eState!=PAGER_NONE ){ pPager->dbSize = nPage; pPager->dbFileSize = nPage; - pPager->dbSizeValid = 1; } } @@ -3235,7 +3282,6 @@ static void assertTruncateConstraint(Pager *pPager){ ** truncation will be done when the current transaction is committed. */ void sqlite3PagerTruncateImage(Pager *pPager, Pgno nPage){ - assert( pPager->dbSizeValid ); assert( pPager->dbSize>=nPage ); assert( pPager->eState>=PAGER_WRITER_CACHEMOD ); pPager->dbSize = nPage; @@ -4064,7 +4110,6 @@ int sqlite3PagerOpen( /* pPager->stmtOpen = 0; */ /* pPager->stmtInUse = 0; */ /* pPager->nRef = 0; */ - pPager->dbSizeValid = (u8)memDb; /* pPager->stmtSize = 0; */ /* pPager->stmtJSize = 0; */ /* pPager->nPage = 0; */ @@ -4146,10 +4191,9 @@ static int hasHotJournal(Pager *pPager, int *pExists){ int exists = 1; /* True if a journal file is present */ int jrnlOpen = !!isOpen(pPager->jfd); - assert( pPager!=0 ); assert( pPager->useJournal ); assert( isOpen(pPager->fd) ); - assert( pPager->eState<=PAGER_SHARED ); + assert( pPager->eState==PAGER_NONE ); assert( jrnlOpen==0 || ( sqlite3OsDeviceCharacteristics(pPager->jfd) & SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN @@ -4172,7 +4216,7 @@ static int hasHotJournal(Pager *pPager, int *pExists){ */ rc = sqlite3OsCheckReservedLock(pPager->fd, &locked); if( rc==SQLITE_OK && !locked ){ - int nPage; + 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 @@ -4180,7 +4224,7 @@ static int hasHotJournal(Pager *pPager, int *pExists){ ** a RESERVED lock to avoid race conditions and to avoid violating ** [H33020]. */ - rc = sqlite3PagerPagecount(pPager, &nPage); + rc = pagerPagecount(pPager, &nPage); if( rc==SQLITE_OK ){ if( nPage==0 ){ sqlite3BeginBenignMalloc(); @@ -4268,8 +4312,13 @@ int sqlite3PagerSharedLock(Pager *pPager){ int isErrorReset = 0; /* True if recovering from error state */ /* This routine is only called from b-tree and only when there are no - ** outstanding pages */ + ** outstanding pages. This implies that the pager state should either + ** be NONE or READER. READER is only possible if the pager is or was in + ** exclusive access mode. + */ assert( sqlite3PcacheRefCount(pPager->pPCache)==0 ); + assert( pPager->eState==PAGER_NONE || pPager->eState==PAGER_READER ); + assert( assert_pager_state(pPager) ); if( NEVER(MEMDB && pPager->errCode) ){ return pPager->errCode; } /* If this database is in an error-state, now is a chance to clear @@ -4281,14 +4330,12 @@ int sqlite3PagerSharedLock(Pager *pPager){ isErrorReset = 1; } pPager->errCode = SQLITE_OK; + pPager->eState = PAGER_NONE; pager_reset(pPager); } - if( pagerUseWal(pPager) ){ - rc = pagerBeginReadTransaction(pPager); - }else if( pPager->eState==PAGER_NONE || isErrorReset ){ + if( !pagerUseWal(pPager) && pPager->eState==PAGER_NONE ){ sqlite3_vfs * const pVfs = pPager->pVfs; - int isHotJournal = 0; assert( !MEMDB && !pPager->tempFile ); assert( sqlite3PcacheRefCount(pPager->pPCache)==0 ); @@ -4301,18 +4348,17 @@ int sqlite3PagerSharedLock(Pager *pPager){ return pager_error(pPager, rc); } } - pPager->eState = PAGER_READER; /* If a journal file exists, and there is no RESERVED lock on the ** database file, then it either needs to be played back or deleted. */ if( !isErrorReset ){ - rc = hasHotJournal(pPager, &isHotJournal); + rc = hasHotJournal(pPager, &isErrorReset); if( rc!=SQLITE_OK ){ goto failed; } } - if( isErrorReset || isHotJournal ){ + if( isErrorReset ){ /* Get an EXCLUSIVE lock on the database file. At this point it is ** important that a RESERVED lock is not obtained on the way to the ** EXCLUSIVE lock. If it were, another process might open the @@ -4389,7 +4435,7 @@ int sqlite3PagerSharedLock(Pager *pPager){ if( rc==SQLITE_OK ){ pPager->eState = PAGER_WRITER_FINISHED; rc = pager_playback(pPager, 1); - pPager->eState = PAGER_READER; + pPager->eState = PAGER_NONE; } if( rc!=SQLITE_OK ){ rc = pager_error(pPager, rc); @@ -4399,7 +4445,7 @@ int sqlite3PagerSharedLock(Pager *pPager){ osUnlock(pPager, SHARED_LOCK); } - assert( pPager->eState==PAGER_READER ); + assert( pPager->eState==PAGER_NONE ); assert( (pPager->eLock==SHARED_LOCK) || (pPager->exclusiveMode && pPager->eLock>SHARED_LOCK) ); @@ -4422,14 +4468,11 @@ int sqlite3PagerSharedLock(Pager *pPager){ ** detected. The chance of an undetected change is so small that ** it can be neglected. */ - int nPage = 0; + Pgno nPage = 0; char dbFileVers[sizeof(pPager->dbFileVers)]; - sqlite3PagerPagecount(pPager, &nPage); - if( pPager->errCode ){ - rc = pPager->errCode; - goto failed; - } + rc = pagerPagecount(pPager, &nPage); + if( rc ) goto failed; if( nPage>0 ){ IOTRACE(("CKVERS %p %d\n", pPager, sizeof(dbFileVers))); @@ -4445,7 +4488,6 @@ int sqlite3PagerSharedLock(Pager *pPager){ pager_reset(pPager); } } - assert( pPager->eState==PAGER_READER ); /* If there is a WAL file in the file-system, open this database in WAL ** mode. Otherwise, the following function call is a no-op. @@ -4453,10 +4495,21 @@ int sqlite3PagerSharedLock(Pager *pPager){ rc = pagerOpenWalIfPresent(pPager); } + if( pagerUseWal(pPager) && rc==SQLITE_OK ){ + rc = pagerBeginReadTransaction(pPager); + } + + if( pPager->eState==PAGER_NONE && rc==SQLITE_OK ){ + pPager->eState = PAGER_NONE; + rc = pagerPagecount(pPager, &pPager->dbSize); + } + failed: if( rc!=SQLITE_OK ){ /* pager_unlock() is a no-op for exclusive mode and in-memory databases. */ pager_unlock(pPager); + }else{ + pPager->eState = PAGER_READER; } return rc; } @@ -4713,7 +4766,6 @@ static int pager_open_journal(Pager *pPager){ if( NEVER(pPager->errCode) ) return pPager->errCode; if( !pagerUseWal(pPager) && pPager->journalMode!=PAGER_JOURNALMODE_OFF ){ - testcase( pPager->dbSizeValid==0 ); rc = sqlite3PagerPagecount(pPager, &nPage); if( rc ) return rc; pPager->pInJournal = sqlite3BitvecCreate(nPage); @@ -5636,10 +5688,6 @@ int sqlite3PagerRollback(Pager *pPager){ rc = pager_playback(pPager, 0); } - if( !MEMDB ){ - pPager->dbSizeValid = 0; - } - /* If an error occurs during a ROLLBACK, we can no longer trust the pager ** cache. So call pager_error() on the way out to make any error ** persistent. @@ -5692,7 +5740,7 @@ int *sqlite3PagerStats(Pager *pPager){ a[0] = sqlite3PcacheRefCount(pPager->pPCache); a[1] = sqlite3PcachePagecount(pPager->pPCache); a[2] = sqlite3PcacheGetCachesize(pPager->pPCache); - a[3] = pPager->dbSizeValid ? (int) pPager->dbSize : -1; + a[3] = pPager->eState==PAGER_NONE ? -1 : (int) pPager->dbSize; a[4] = pPager->eState; a[5] = pPager->errCode; a[6] = pPager->nHit; @@ -6010,7 +6058,6 @@ int sqlite3PagerMovepage(Pager *pPager, DbPage *pPg, Pgno pgno, int isCommit){ if( MEMDB ){ /* Do not discard pages from an in-memory database since we might ** need to rollback later. Just move the page out of the way. */ - assert( pPager->dbSizeValid ); sqlite3PcacheMove(pPgOld, pPager->dbSize+1); }else{ sqlite3PcacheDrop(pPgOld); @@ -6287,21 +6334,24 @@ int sqlite3PagerWalSupported(Pager *pPager){ ** file (not a temp file or an in-memory database), and the WAL file ** is not already open, make an attempt to open it now. If successful, ** return SQLITE_OK. If an error occurs or the VFS used by the pager does -** not support the xShmXXX() methods, return an error code. *pisOpen is +** not support the xShmXXX() methods, return an error code. *pbOpen is ** not modified in either case. ** ** If the pager is open on a temp-file (or in-memory database), or if -** the WAL file is already open, set *pisOpen to 1 and return SQLITE_OK +** the WAL file is already open, set *pbOpen to 1 and return SQLITE_OK ** without doing anything. */ int sqlite3PagerOpenWal( Pager *pPager, /* Pager object */ - int *pisOpen /* OUT: Set to true if call is a no-op */ + int *pbOpen /* OUT: Set to true if call is a no-op */ ){ int rc = SQLITE_OK; /* Return code */ - assert( pPager->eState>=PAGER_READER ); - assert( (pisOpen==0 && !pPager->tempFile && !pPager->pWal) || *pisOpen==0 ); + assert( assert_pager_state(pPager) ); + assert( pPager->eState==PAGER_NONE || pbOpen ); + assert( pPager->eState==PAGER_READER || !pbOpen ); + assert( pbOpen==0 || *pbOpen==0 ); + assert( pbOpen!=0 || (!pPager->tempFile && !pPager->pWal) ); if( !pPager->tempFile && !pPager->pWal ){ if( !sqlite3PagerWalSupported(pPager) ) return SQLITE_CANTOPEN; @@ -6313,9 +6363,10 @@ int sqlite3PagerOpenWal( rc = sqlite3WalOpen(pPager->pVfs, pPager->fd, pPager->zWal, &pPager->pWal); if( rc==SQLITE_OK ){ pPager->journalMode = PAGER_JOURNALMODE_WAL; + pPager->eState = PAGER_NONE; } }else{ - *pisOpen = 1; + *pbOpen = 1; } return rc; diff --git a/src/test_stat.c b/src/test_stat.c index 894be80ecb..1534621114 100644 --- a/src/test_stat.c +++ b/src/test_stat.c @@ -376,7 +376,13 @@ static int statNext(sqlite3_vtab_cursor *pCursor){ if( pCsr->aPage[0].pPg==0 ){ rc = sqlite3_step(pCsr->pStmt); if( rc==SQLITE_ROW ){ + int nPage; u32 iRoot = sqlite3_column_int64(pCsr->pStmt, 1); + sqlite3PagerPagecount(pPager, &nPage); + if( nPage==0 ){ + pCsr->isEof = 1; + return sqlite3_reset(pCsr->pStmt); + } rc = sqlite3PagerGet(pPager, iRoot, &pCsr->aPage[0].pPg); pCsr->aPage[0].iPgno = iRoot; pCsr->aPage[0].iCell = 0; @@ -486,17 +492,9 @@ static int statFilter( int idxNum, const char *idxStr, int argc, sqlite3_value **argv ){ - sqlite3 *db = ((StatTable *)(pCursor->pVtab))->db; StatCursor *pCsr = (StatCursor *)pCursor; - int nPage = 0; statResetCsr((StatCursor *)pCursor); - sqlite3PagerPagecount(sqlite3BtreePager(db->aDb[0].pBt), &nPage); - if( nPage==0 ){ - pCsr->isEof = 1; - return SQLITE_OK; - } - return statNext(pCursor); } diff --git a/src/wal.c b/src/wal.c index 3ac8071548..be8c466428 100644 --- a/src/wal.c +++ b/src/wal.c @@ -2166,11 +2166,13 @@ int sqlite3WalRead( /* -** Set *pPgno to the size of the database file (or zero, if unknown). +** Return the size of the database in pages (or zero, if unknown). */ -void sqlite3WalDbsize(Wal *pWal, Pgno *pPgno){ - assert( pWal->readLock>=0 || pWal->lockError ); - *pPgno = pWal->hdr.nPage; +Pgno sqlite3WalDbsize(Wal *pWal){ + if( pWal && pWal->readLock>=0 ){ + return pWal->hdr.nPage; + } + return 0; } diff --git a/src/wal.h b/src/wal.h index f29d5838f5..f20dfa8e17 100644 --- a/src/wal.h +++ b/src/wal.h @@ -25,7 +25,7 @@ # define sqlite3WalBeginReadTransaction(y,z) 0 # define sqlite3WalEndReadTransaction(z) # define sqlite3WalRead(v,w,x,y,z) 0 -# define sqlite3WalDbsize(y,z) +# define sqlite3WalDbsize(y) 0 # define sqlite3WalBeginWriteTransaction(y) 0 # define sqlite3WalEndWriteTransaction(x) 0 # define sqlite3WalUndo(x,y,z) 0 @@ -61,9 +61,8 @@ void sqlite3WalEndReadTransaction(Wal *pWal); /* Read a page from the write-ahead log, if it is present. */ int sqlite3WalRead(Wal *pWal, Pgno pgno, int *pInWal, int nOut, u8 *pOut); -/* Return the size of the database as it existed at the beginning -** of the snapshot */ -void sqlite3WalDbsize(Wal *pWal, Pgno *pPgno); +/* If the WAL is not empty, return the size of the database. */ +Pgno sqlite3WalDbsize(Wal *pWal); /* Obtain or release the WRITER lock. */ int sqlite3WalBeginWriteTransaction(Wal *pWal); diff --git a/test/permutations.test b/test/permutations.test index f1fb74fe61..086897c468 100644 --- a/test/permutations.test +++ b/test/permutations.test @@ -129,7 +129,7 @@ test_suite "veryquick" -prefix "" -description { This test suite is the same as the "quick" tests, except that some files that test malloc and IO errors are omitted. } -files [ - test_set $allquicktests -exclude *malloc* *ioerr* *fault* + test_set $allquicktests -exclude *malloc* *ioerr* *fault* ] test_suite "quick" -prefix "" -description {