1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-08-08 14:02:16 +03:00

Set the Pager.eState variable to PAGER_ERROR whenever the pager enters the error state.

FossilOrigin-Name: 4d384761d27425b71555f4f3262778277a955835
This commit is contained in:
dan
2010-08-03 18:18:41 +00:00
parent b22aa4a63d
commit a42c66bdfb
3 changed files with 101 additions and 95 deletions

View File

@@ -1,5 +1,5 @@
C Add\scomments\sto\sclarify\sthe\spurpose\sof\sthe\spager\s"error\sstate". C Set\sthe\sPager.eState\svariable\sto\sPAGER_ERROR\swhenever\sthe\spager\senters\sthe\serror\sstate.
D 2010-08-03T15:57:10 D 2010-08-03T18:18:42
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
F Makefile.in ec08dc838fd8110fe24c92e5130bcd91cbb1ff2e F Makefile.in ec08dc838fd8110fe24c92e5130bcd91cbb1ff2e
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
@@ -156,7 +156,7 @@ F src/os_common.h a8f95b81eca8a1ab8593d23e94f8a35f35d4078f
F src/os_os2.c 72d0b2e562952a2464308c4ce5f7913ac10bef3e F src/os_os2.c 72d0b2e562952a2464308c4ce5f7913ac10bef3e
F src/os_unix.c ae5ca8a6031380708f3fec7be325233d49944914 F src/os_unix.c ae5ca8a6031380708f3fec7be325233d49944914
F src/os_win.c 51cb62f76262d961ea4249489383d714501315a7 F src/os_win.c 51cb62f76262d961ea4249489383d714501315a7
F src/pager.c 809f4dfbca43fd64ef27855e193d8544a5054668 F src/pager.c b48eb75d41fd1bce0e9911209785aef4381258ef
F src/pager.h 80726162dc3942f59ab27b738fb667b9ba0a89d5 F src/pager.h 80726162dc3942f59ab27b738fb667b9ba0a89d5
F src/parse.y 12b7ebd61ea54f0e1b1083ff69cc2c8ce9353d58 F src/parse.y 12b7ebd61ea54f0e1b1083ff69cc2c8ce9353d58
F src/pcache.c 1e9aa2dbc0845b52e1b51cc39753b6d1e041cb07 F src/pcache.c 1e9aa2dbc0845b52e1b51cc39753b6d1e041cb07
@@ -841,7 +841,7 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff
F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224
F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f
P 16dcf5a6d3ebff9a734705693b5ac740f4ff2cc1 P fde4c59782e98366792e1552fd122e7d80a277ff
R f5f08ae2bf16feac4ddffb2e7526923b R dd009cdb2bebe6c9ea312f79af5244c4
U dan U dan
Z 158c2b787243a4910abe77703b2eb315 Z 18695678602885240568b79d8561ccf5

View File

@@ -1 +1 @@
fde4c59782e98366792e1552fd122e7d80a277ff 4d384761d27425b71555f4f3262778277a955835

View File

@@ -291,6 +291,7 @@ int sqlite3PagerTrace=1; /* True to enable tracing */
#define PAGER_WRITER_CACHEMOD 3 #define PAGER_WRITER_CACHEMOD 3
#define PAGER_WRITER_DBMOD 4 #define PAGER_WRITER_DBMOD 4
#define PAGER_WRITER_FINISHED 5 #define PAGER_WRITER_FINISHED 5
#define PAGER_ERROR 6
/* /*
@@ -696,6 +697,7 @@ static int assert_pager_state(Pager *p){
|| p->eState==PAGER_WRITER_CACHEMOD || p->eState==PAGER_WRITER_CACHEMOD
|| p->eState==PAGER_WRITER_DBMOD || p->eState==PAGER_WRITER_DBMOD
|| p->eState==PAGER_WRITER_FINISHED || p->eState==PAGER_WRITER_FINISHED
|| p->eState==PAGER_ERROR
); );
/* Regardless of the current state, a temp-file connection always behaves /* Regardless of the current state, a temp-file connection always behaves
@@ -718,21 +720,27 @@ static int assert_pager_state(Pager *p){
case PAGER_NONE: case PAGER_NONE:
assert( !MEMDB ); assert( !MEMDB );
assert( !p->tempFile ); assert( !p->tempFile );
assert( pPager->errCode==SQLITE_OK );
assert( sqlite3PcacheRefCount(pPager->pPCache)==0 );
break; break;
case PAGER_READER: case PAGER_READER:
assert( pPager->errCode==SQLITE_OK );
assert( p->eLock>=SHARED_LOCK || p->noReadlock ); assert( p->eLock>=SHARED_LOCK || p->noReadlock );
break; break;
case PAGER_WRITER_INITIAL: case PAGER_WRITER_INITIAL:
assert( pPager->errCode==SQLITE_OK );
if( !pagerUseWal(pPager) ){ if( !pagerUseWal(pPager) ){
assert( p->eLock>=RESERVED_LOCK ); assert( p->eLock>=RESERVED_LOCK );
} }
assert( pPager->dbSize==pPager->dbOrigSize ); assert( pPager->dbSize==pPager->dbOrigSize );
assert( pPager->dbOrigSize==pPager->dbFileSize ); assert( pPager->dbOrigSize==pPager->dbFileSize );
assert( pPager->setMaster==0 );
break; break;
case PAGER_WRITER_CACHEMOD: case PAGER_WRITER_CACHEMOD:
assert( pPager->errCode==SQLITE_OK );
if( !pagerUseWal(pPager) ){ if( !pagerUseWal(pPager) ){
/* It is possible that if journal_mode=wal here that neither the /* It is possible that if journal_mode=wal here that neither the
** journal file nor the WAL file are open. This happens during ** journal file nor the WAL file are open. This happens during
@@ -749,6 +757,7 @@ static int assert_pager_state(Pager *p){
break; break;
case PAGER_WRITER_DBMOD: case PAGER_WRITER_DBMOD:
assert( pPager->errCode==SQLITE_OK );
assert( !pagerUseWal(pPager) ); assert( !pagerUseWal(pPager) );
assert( p->eLock>=EXCLUSIVE_LOCK || pagerUseWal(pPager) ); assert( p->eLock>=EXCLUSIVE_LOCK || pagerUseWal(pPager) );
assert( isOpen(p->jfd) assert( isOpen(p->jfd)
@@ -758,6 +767,7 @@ static int assert_pager_state(Pager *p){
break; break;
case PAGER_WRITER_FINISHED: case PAGER_WRITER_FINISHED:
assert( pPager->errCode==SQLITE_OK );
assert( !pagerUseWal(pPager) ); assert( !pagerUseWal(pPager) );
assert( p->eLock>=EXCLUSIVE_LOCK || pagerUseWal(pPager) ); assert( p->eLock>=EXCLUSIVE_LOCK || pagerUseWal(pPager) );
assert( isOpen(p->jfd) assert( isOpen(p->jfd)
@@ -765,6 +775,15 @@ static int assert_pager_state(Pager *p){
|| p->journalMode==PAGER_JOURNALMODE_WAL || p->journalMode==PAGER_JOURNALMODE_WAL
); );
break; break;
case PAGER_ERROR:
/* There must be at least one outstanding reference to the pager if
** in ERROR state. Otherwise the pager should have already dropped
** back to NONE state.
*/
assert( pPager->errCode!=SQLITE_OK );
assert( sqlite3PcacheRefCount(pPager->pPCache)>0 );
break;
} }
return 1; return 1;
@@ -787,7 +806,8 @@ static char *print_pager_state(Pager *p){
p->eState==PAGER_WRITER_INITIAL ? "WRITER_INITIAL" : p->eState==PAGER_WRITER_INITIAL ? "WRITER_INITIAL" :
p->eState==PAGER_WRITER_CACHEMOD ? "WRITER_CACHEMOD" : p->eState==PAGER_WRITER_CACHEMOD ? "WRITER_CACHEMOD" :
p->eState==PAGER_WRITER_DBMOD ? "WRITER_DBMOD" : p->eState==PAGER_WRITER_DBMOD ? "WRITER_DBMOD" :
p->eState==PAGER_WRITER_FINISHED ? "WRITER_FINISHED" : "?error?" p->eState==PAGER_WRITER_FINISHED ? "WRITER_FINISHED" :
p->eState==PAGER_ERROR ? "ERROR" : "?error?"
, p->eLock==NO_LOCK ? "NONE" : , p->eLock==NO_LOCK ? "NONE" :
p->eLock==RESERVED_LOCK ? "RESERVED" : p->eLock==RESERVED_LOCK ? "RESERVED" :
p->eLock==EXCLUSIVE_LOCK ? "EXCLUSIVE" : p->eLock==EXCLUSIVE_LOCK ? "EXCLUSIVE" :
@@ -1443,17 +1463,12 @@ static PgHdr *pager_lookup(Pager *pPager, Pgno pgno){
} }
/* /*
** Unless the pager is in error-state, discard all in-memory pages. If ** Discard the entire contents of the in-memory page-cache.
** the pager is in error-state, then this call is a no-op.
**
** TODO: Why can we not reset the pager while in error state?
*/ */
static void pager_reset(Pager *pPager){ static void pager_reset(Pager *pPager){
if( SQLITE_OK==pPager->errCode ){
sqlite3BackupRestart(pPager->pBackup); sqlite3BackupRestart(pPager->pBackup);
sqlite3PcacheClear(pPager->pPCache); sqlite3PcacheClear(pPager->pPCache);
} }
}
/* /*
** Free all structures in the Pager.aSavepoint[] array and set both ** Free all structures in the Pager.aSavepoint[] array and set both
@@ -1505,8 +1520,16 @@ static int addToSavepointBitvecs(Pager *pPager, Pgno pgno){
** treated as a hot-journal and rolled back. ** treated as a hot-journal and rolled back.
*/ */
static void pager_unlock(Pager *pPager){ static void pager_unlock(Pager *pPager){
if( !pPager->exclusiveMode ){
int rc = SQLITE_OK; /* Return code */ sqlite3BitvecDestroy(pPager->pInJournal);
pPager->pInJournal = 0;
releaseAllSavepoints(pPager);
if( pagerUseWal(pPager) ){
assert( !isOpen(pPager->jfd) );
sqlite3WalEndReadTransaction(pPager->pWal);
pPager->eState = PAGER_NONE;
}else if( !pPager->exclusiveMode ){
int iDc = isOpen(pPager->fd)?sqlite3OsDeviceCharacteristics(pPager->fd):0; int iDc = isOpen(pPager->fd)?sqlite3OsDeviceCharacteristics(pPager->fd):0;
/* If the operating system support deletion of open files, then /* If the operating system support deletion of open files, then
@@ -1520,40 +1543,33 @@ static void pager_unlock(Pager *pPager){
assert( (PAGER_JOURNALMODE_DELETE & 5)!=1 ); assert( (PAGER_JOURNALMODE_DELETE & 5)!=1 );
assert( (PAGER_JOURNALMODE_TRUNCATE & 5)==1 ); assert( (PAGER_JOURNALMODE_TRUNCATE & 5)==1 );
assert( (PAGER_JOURNALMODE_PERSIST & 5)==1 ); assert( (PAGER_JOURNALMODE_PERSIST & 5)==1 );
if( 0==(iDc & SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN) if( 0==(iDc & SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN)
|| 1!=(pPager->journalMode & 5) || 1!=(pPager->journalMode & 5)
){ ){
sqlite3OsClose(pPager->jfd); sqlite3OsClose(pPager->jfd);
} }
osUnlock(pPager, NO_LOCK);
sqlite3BitvecDestroy(pPager->pInJournal); /* The pager state may be changed from PAGER_ERROR to PAGER_NONE here
pPager->pInJournal = 0; ** without clearing the error code. This is intentional - the error
releaseAllSavepoints(pPager); ** code is cleared and the cache reset in the block below.
if( pagerUseWal(pPager) ){
sqlite3WalEndReadTransaction(pPager->pWal);
}else{
rc = osUnlock(pPager, NO_LOCK);
}
if( rc ){
pPager->errCode = rc;
}
IOTRACE(("UNLOCK %p\n", pPager))
/* If Pager.errCode is set, the contents of the pager cache cannot be
** trusted. Now that the pager file is unlocked, the contents of the
** cache can be discarded and the error code safely cleared.
*/ */
if( pPager->errCode ){ assert( pPager->errCode || pPager->eState!=PAGER_ERROR );
if( rc==SQLITE_OK ){
pPager->errCode = SQLITE_OK;
}
pager_reset(pPager);
}
pPager->changeCountDone = 0; pPager->changeCountDone = 0;
pPager->eState = PAGER_NONE; pPager->eState = PAGER_NONE;
IOTRACE(("UNLOCK %p\n", pPager))
}
/* If Pager.errCode is set, the contents of the pager cache cannot be
** trusted. Now that there are no outstanding references to the pager,
** it can safely move back to PAGER_NONE state. This happens in both
** normal and exclusive-locking mode.
*/
if( pPager->errCode ){
pager_reset(pPager);
pPager->changeCountDone = 0;
pPager->eState = PAGER_NONE;
pPager->errCode = SQLITE_OK;
} }
} }
@@ -1586,6 +1602,7 @@ static int pager_error(Pager *pPager, int rc){
); );
if( rc2==SQLITE_FULL || rc2==SQLITE_IOERR ){ if( rc2==SQLITE_FULL || rc2==SQLITE_IOERR ){
pPager->errCode = rc; pPager->errCode = rc;
pPager->eState = PAGER_ERROR;
} }
return rc; return rc;
} }
@@ -1652,6 +1669,7 @@ static int pager_end_transaction(Pager *pPager, int hasMaster){
/* Do nothing if the pager does not have an open write transaction. */ /* Do nothing if the pager does not have an open write transaction. */
assert( assert_pager_state(pPager) ); assert( assert_pager_state(pPager) );
assert( pPager->eState!=PAGER_ERROR );
if( pPager->eState<PAGER_WRITER_INITIAL && pPager->eLock<RESERVED_LOCK ){ if( pPager->eState<PAGER_WRITER_INITIAL && pPager->eLock<RESERVED_LOCK ){
return SQLITE_OK; return SQLITE_OK;
} }
@@ -1741,7 +1759,8 @@ static int pager_end_transaction(Pager *pPager, int hasMaster){
** call to pager_unlock(), as described above. ** call to pager_unlock(), as described above.
*/ */
static void pagerUnlockAndRollback(Pager *pPager){ static void pagerUnlockAndRollback(Pager *pPager){
if( pPager->errCode==SQLITE_OK ){ if( pPager->eState!=PAGER_ERROR ){
assert( assert_pager_state(pPager) );
if( pPager->eState>=PAGER_WRITER_INITIAL ){ if( pPager->eState>=PAGER_WRITER_INITIAL ){
sqlite3BeginBenignMalloc(); sqlite3BeginBenignMalloc();
sqlite3PagerRollback(pPager); sqlite3PagerRollback(pPager);
@@ -2199,6 +2218,7 @@ delmaster_out:
*/ */
static int pager_truncate(Pager *pPager, Pgno nPage){ static int pager_truncate(Pager *pPager, Pgno nPage){
int rc = SQLITE_OK; int rc = SQLITE_OK;
assert( pPager->eState!=PAGER_ERROR );
if( pPager->eState>=PAGER_WRITER_DBMOD && isOpen(pPager->fd) ){ if( pPager->eState>=PAGER_WRITER_DBMOD && isOpen(pPager->fd) ){
i64 currentSize, newSize; i64 currentSize, newSize;
/* TODO: Is it safe to use Pager.dbFileSize here? */ /* TODO: Is it safe to use Pager.dbFileSize here? */
@@ -2833,6 +2853,7 @@ static int pagerPlaybackSavepoint(Pager *pPager, PagerSavepoint *pSavepoint){
int rc = SQLITE_OK; /* Return code */ int rc = SQLITE_OK; /* Return code */
Bitvec *pDone = 0; /* Bitvec to ensure pages played back only once */ Bitvec *pDone = 0; /* Bitvec to ensure pages played back only once */
assert( pPager->eState!=PAGER_ERROR );
assert( pPager->eState>=PAGER_WRITER_INITIAL ); assert( pPager->eState>=PAGER_WRITER_INITIAL );
/* Allocate a bitvec to use to store the set of pages rolled back */ /* Allocate a bitvec to use to store the set of pages rolled back */
@@ -3080,6 +3101,12 @@ void sqlite3PagerSetBusyhandler(
int sqlite3PagerSetPagesize(Pager *pPager, u16 *pPageSize, int nReserve){ int sqlite3PagerSetPagesize(Pager *pPager, u16 *pPageSize, int nReserve){
int rc = pPager->errCode; int rc = pPager->errCode;
/* It is not possible to do a full assert_pager_state() here, as this
** function may be called from within PagerOpen(), before the state
** of the Pager object is internally consistent.
*/
assert( rc==SQLITE_OK || pPager->eState==PAGER_ERROR );
if( rc==SQLITE_OK ){ if( rc==SQLITE_OK ){
u16 pageSize = *pPageSize; u16 pageSize = *pPageSize;
assert( pageSize==0 || (pageSize>=512 && pageSize<=SQLITE_MAX_PAGE_SIZE) ); assert( pageSize==0 || (pageSize>=512 && pageSize<=SQLITE_MAX_PAGE_SIZE) );
@@ -3370,7 +3397,7 @@ int sqlite3PagerClose(Pager *pPager){
disable_simulated_io_errors(); disable_simulated_io_errors();
sqlite3BeginBenignMalloc(); sqlite3BeginBenignMalloc();
pPager->errCode = 0; /* pPager->errCode = 0; */
pPager->exclusiveMode = 0; pPager->exclusiveMode = 0;
#ifndef SQLITE_OMIT_WAL #ifndef SQLITE_OMIT_WAL
sqlite3WalClose(pPager->pWal, sqlite3WalClose(pPager->pWal,
@@ -3383,14 +3410,19 @@ int sqlite3PagerClose(Pager *pPager){
if( MEMDB ){ if( MEMDB ){
pager_unlock(pPager); pager_unlock(pPager);
}else{ }else{
/* Set Pager.journalHdr to -1 for the benefit of the pager_playback() /* If it is open, sync the journal file before calling UnlockAndRollback.
** call which may be made from within pagerUnlockAndRollback(). If it ** If this is not done, then an unsynced portion of the open journal
** is not -1, then the unsynced portion of an open journal file may ** file may be played back into the database. If a power failure occurs
** be played back into the database. If a power failure occurs while ** while this is happening, the database could become corrupt.
** this is happening, the database may become corrupt. **
** If an error occurs while trying to sync the journal, shift the pager
** into the ERROR state. This causes UnlockAndRollback to unlock the
** database and close the journal file without attempting to roll it
** back or finalize it. The next database user will have to do hot-journal
** rollback before accessing the database file.
*/ */
if( isOpen(pPager->jfd) ){ if( isOpen(pPager->jfd) ){
pPager->errCode = pagerSyncHotJournal(pPager); pager_error(pPager, pagerSyncHotJournal(pPager));
} }
pagerUnlockAndRollback(pPager); pagerUnlockAndRollback(pPager);
} }
@@ -4359,24 +4391,10 @@ int sqlite3PagerSharedLock(Pager *pPager){
assert( assert_pager_state(pPager) ); assert( assert_pager_state(pPager) );
if( NEVER(MEMDB && pPager->errCode) ){ return pPager->errCode; } if( NEVER(MEMDB && pPager->errCode) ){ return pPager->errCode; }
/* If this database is in an error-state, now is a chance to clear
** the error. Discard the contents of the pager-cache and rollback
** any hot journal in the file-system.
*/
if( pPager->errCode ){
if( isOpen(pPager->jfd) || pPager->zJournal ){
isErrorReset = 1;
}
pPager->errCode = SQLITE_OK;
pPager->eState = PAGER_NONE;
pager_reset(pPager);
}
if( !pagerUseWal(pPager) && pPager->eState==PAGER_NONE ){ if( !pagerUseWal(pPager) && pPager->eState==PAGER_NONE ){
sqlite3_vfs * const pVfs = pPager->pVfs; sqlite3_vfs * const pVfs = pPager->pVfs;
assert( !MEMDB && !pPager->tempFile ); assert( !MEMDB && !pPager->tempFile );
assert( sqlite3PcacheRefCount(pPager->pPCache)==0 );
assert( pPager->noReadlock==0 || pPager->readOnly ); assert( pPager->noReadlock==0 || pPager->readOnly );
if( pPager->noReadlock==0 ){ if( pPager->noReadlock==0 ){
@@ -4474,6 +4492,7 @@ int sqlite3PagerSharedLock(Pager *pPager){
if( isOpen(pPager->jfd) ){ if( isOpen(pPager->jfd) ){
rc = pagerSyncHotJournal(pPager); rc = pagerSyncHotJournal(pPager);
if( rc==SQLITE_OK ){ if( rc==SQLITE_OK ){
assert( pPager->eState==PAGER_NONE );
pPager->eState = PAGER_WRITER_FINISHED; pPager->eState = PAGER_WRITER_FINISHED;
rc = pager_playback(pPager, 1); rc = pager_playback(pPager, 1);
pPager->eState = PAGER_NONE; pPager->eState = PAGER_NONE;
@@ -4540,16 +4559,13 @@ int sqlite3PagerSharedLock(Pager *pPager){
} }
if( pPager->eState==PAGER_NONE && rc==SQLITE_OK ){ if( pPager->eState==PAGER_NONE && rc==SQLITE_OK ){
pPager->eState = PAGER_NONE;
rc = pagerPagecount(pPager, &pPager->dbSize); rc = pagerPagecount(pPager, &pPager->dbSize);
} }
failed: failed:
if( rc!=SQLITE_OK ){ if( rc!=SQLITE_OK ){
pager_unlock(pPager); pager_unlock(pPager);
assert( (pPager->eState==PAGER_NONE) assert( pPager->eState==PAGER_NONE );
|| (pPager->exclusiveMode && pagerUseWal(pPager))
);
}else{ }else{
pPager->eState = PAGER_READER; pPager->eState = PAGER_READER;
} }
@@ -4962,14 +4978,16 @@ static int pager_write(PgHdr *pPg){
/* This routine is not called unless a write-transaction has already /* This routine is not called unless a write-transaction has already
** been started. The journal file may or may not be open at this point. ** been started. The journal file may or may not be open at this point.
** It is never called in the ERROR state.
*/ */
assert( pPager->eState>=PAGER_WRITER_INITIAL ); assert( pPager->eState==PAGER_WRITER_INITIAL
assert( pPager->eState!=PAGER_WRITER_FINISHED ); || pPager->eState==PAGER_WRITER_CACHEMOD
|| pPager->eState==PAGER_WRITER_DBMOD
);
assert( assert_pager_state(pPager) ); assert( assert_pager_state(pPager) );
/* If an error has been previously detected, report the same error /* If an error has been previously detected, report the same error
** again. ** again. This should not happen, but the check provides robustness. */
*/
if( NEVER(pPager->errCode) ) return pPager->errCode; if( NEVER(pPager->errCode) ) return pPager->errCode;
/* Higher-level routines never call this function if database is not /* Higher-level routines never call this function if database is not
@@ -5113,6 +5131,7 @@ int sqlite3PagerWrite(DbPage *pDbPage){
Pgno nPagePerSector = (pPager->sectorSize/pPager->pageSize); Pgno nPagePerSector = (pPager->sectorSize/pPager->pageSize);
assert( pPager->eState>=PAGER_WRITER_INITIAL ); assert( pPager->eState>=PAGER_WRITER_INITIAL );
assert( pPager->eState!=PAGER_ERROR );
assert( assert_pager_state(pPager) ); assert( assert_pager_state(pPager) );
if( nPagePerSector>1 ){ if( nPagePerSector>1 ){
@@ -5408,11 +5427,6 @@ int sqlite3PagerCommitPhaseOne(
); );
assert( assert_pager_state(pPager) ); assert( assert_pager_state(pPager) );
#if 0
/* The dbOrigSize is never set if journal_mode=OFF */
assert( pPager->journalMode!=PAGER_JOURNALMODE_OFF || pPager->dbOrigSize==0 );
#endif
/* If a prior error occurred, report that error again. */ /* If a prior error occurred, report that error again. */
if( pPager->errCode ) return pPager->errCode; if( pPager->errCode ) return pPager->errCode;
@@ -5682,8 +5696,12 @@ int sqlite3PagerRollback(Pager *pPager){
int rc = SQLITE_OK; /* Return code */ int rc = SQLITE_OK; /* Return code */
PAGERTRACE(("ROLLBACK %d\n", PAGERID(pPager))); PAGERTRACE(("ROLLBACK %d\n", PAGERID(pPager)));
/* PagerRollback() is a no-op if called in READER or NONE state. */ /* PagerRollback() is a no-op if called in READER or NONE state. If
** the pager is already in the ERROR state, the rollback is not
** attempted here. Instead, the error code is returned to the caller.
*/
assert( assert_pager_state(pPager) ); assert( assert_pager_state(pPager) );
if( pPager->eState==PAGER_ERROR ) return pPager->errCode;
if( pPager->eState<=PAGER_READER ) return SQLITE_OK; if( pPager->eState<=PAGER_READER ) return SQLITE_OK;
if( pagerUseWal(pPager) ){ if( pagerUseWal(pPager) ){
@@ -5691,25 +5709,13 @@ int sqlite3PagerRollback(Pager *pPager){
rc = sqlite3PagerSavepoint(pPager, SAVEPOINT_ROLLBACK, -1); rc = sqlite3PagerSavepoint(pPager, SAVEPOINT_ROLLBACK, -1);
rc2 = pager_end_transaction(pPager, pPager->setMaster); rc2 = pager_end_transaction(pPager, pPager->setMaster);
if( rc==SQLITE_OK ) rc = rc2; if( rc==SQLITE_OK ) rc = rc2;
}else if( pPager->eState==PAGER_WRITER_INITIAL ){ }else if( !isOpen(pPager->jfd) ){
rc = pager_end_transaction(pPager, 0); rc = pager_end_transaction(pPager, 0);
}else if( pPager->errCode && pPager->errCode!=SQLITE_FULL ){
if( pPager->eState>=PAGER_WRITER_DBMOD ){
pager_playback(pPager, 0);
}
rc = pPager->errCode;
}else{
if( pPager->eState==PAGER_WRITER_CACHEMOD ){
int rc2;
rc = pager_playback(pPager, 0);
rc2 = pager_end_transaction(pPager, pPager->setMaster);
if( rc==SQLITE_OK ){
rc = rc2;
}
}else{ }else{
rc = pager_playback(pPager, 0); rc = pager_playback(pPager, 0);
} }
} assert( pPager->eState==PAGER_READER || rc!=SQLITE_OK );
assert( rc==SQLITE_OK || rc==SQLITE_FULL || (rc&0xFF)==SQLITE_IOERR );
/* If an error occurs during a ROLLBACK, we can no longer trust the pager /* 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. ** cache. So call pager_error() on the way out to make any error persistent.