Incremental checkin on pager state refactoring.

FossilOrigin-Name: 0a636798bdb6961a47327091715b254f79add823
This commit is contained in:
dan 2010-08-03 06:42:39 +00:00
parent d08640871c
commit 763afe62e1
7 changed files with 144 additions and 94 deletions

View File

@ -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

View File

@ -1 +1 @@
03a240514aa07a22db787d221641253f23933e88
0a636798bdb6961a47327091715b254f79add823

View File

@ -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;

View File

@ -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);
}

View File

@ -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;
}

View File

@ -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);

View File

@ -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 {