Upgraded SQLite 3 to version 3.3.12

This commit is contained in:
Ilia Alshanetsky 2007-02-09 03:17:47 +00:00
parent 7aa2282124
commit d35449bbfb
49 changed files with 5187 additions and 2911 deletions

View file

@ -31,6 +31,7 @@
** Macros for troubleshooting. Normally turned off
*/
#if 0
#define sqlite3DebugPrintf printf
#define TRACE1(X) sqlite3DebugPrintf(X)
#define TRACE2(X,Y) sqlite3DebugPrintf(X,Y)
#define TRACE3(X,Y,Z) sqlite3DebugPrintf(X,Y,Z)
@ -231,7 +232,6 @@ struct Pager {
u8 fullSync; /* Do extra syncs of the journal for robustness */
u8 full_fsync; /* Use F_FULLFSYNC when available */
u8 state; /* PAGER_UNLOCK, _SHARED, _RESERVED, etc. */
u8 errCode; /* One of several kinds of errors */
u8 tempFile; /* zFilename is a temporary file */
u8 readOnly; /* True for a read-only database */
u8 needSync; /* True if an fsync() is needed on the journal */
@ -239,6 +239,7 @@ struct Pager {
u8 alwaysRollback; /* Disable dont_rollback() for all pages */
u8 memDb; /* True to inhibit all file I/O */
u8 setMaster; /* True if a m-j name has been written to jrnl */
int errCode; /* One of several kinds of errors */
int dbSize; /* Number of pages in the file */
int origDbSize; /* dbSize before the current change */
int stmtSize; /* Size of database (in pages) at stmt_begin() */
@ -350,7 +351,9 @@ static const unsigned char aJournalMagic[] = {
/*
** The default size of a disk sector
*/
#define PAGER_SECTOR_SIZE 512
#ifndef PAGER_SECTOR_SIZE
# define PAGER_SECTOR_SIZE 512
#endif
/*
** Page number PAGER_MJ_PGNO is never used in an SQLite database (it is
@ -376,8 +379,8 @@ static const unsigned char aJournalMagic[] = {
static int cnt = 0;
if( !pager3_refinfo_enable ) return;
sqlite3DebugPrintf(
"REFCNT: %4d addr=%p nRef=%d\n",
p->pgno, PGHDR_TO_DATA(p), p->nRef
"REFCNT: %4d addr=%p nRef=%-3d total=%d\n",
p->pgno, PGHDR_TO_DATA(p), p->nRef, p->pPager->nRef
);
cnt++; /* Something to set a breakpoint on */
}
@ -476,12 +479,13 @@ static u32 retrieve32bits(PgHdr *p, int offset){
** will immediately return the same error code.
*/
static int pager_error(Pager *pPager, int rc){
int rc2 = rc & 0xff;
assert( pPager->errCode==SQLITE_FULL || pPager->errCode==SQLITE_OK );
if(
rc==SQLITE_FULL ||
rc==SQLITE_IOERR ||
rc==SQLITE_CORRUPT ||
rc==SQLITE_PROTOCOL
rc2==SQLITE_FULL ||
rc2==SQLITE_IOERR ||
rc2==SQLITE_CORRUPT ||
rc2==SQLITE_PROTOCOL
){
pPager->errCode = rc;
}
@ -846,6 +850,23 @@ static PgHdr *pager_lookup(Pager *pPager, Pgno pgno){
return p;
}
/*
** Unlock the database file.
**
** Once all locks have been removed from the database file, other
** processes or threads might change the file. So make sure all of
** our internal cache is invalidated.
*/
static void pager_unlock(Pager *pPager){
if( !MEMDB ){
sqlite3OsUnlock(pPager->fd, NO_LOCK);
pPager->dbSize = -1;
}
pPager->state = PAGER_UNLOCK;
assert( pPager->pAll==0 );
}
/*
** Unlock the database and clear the in-memory cache. This routine
** sets the state of the pager back to what it was when it was first
@ -870,11 +891,9 @@ static void pager_reset(Pager *pPager){
if( pPager->state>=PAGER_RESERVED ){
sqlite3pager_rollback(pPager);
}
sqlite3OsUnlock(pPager->fd, NO_LOCK);
pPager->state = PAGER_UNLOCK;
pPager->dbSize = -1;
pager_unlock(pPager);
pPager->nRef = 0;
assert( pPager->journalOpen==0 );
assert( pPager->errCode || (pPager->journalOpen==0 && pPager->stmtOpen==0) );
}
/*
@ -926,6 +945,7 @@ static int pager_unwritelock(Pager *pPager){
pPager->setMaster = 0;
pPager->needSync = 0;
pPager->pFirstSynced = pPager->pFirst;
pPager->dbSize = -1;
return rc;
}
@ -1340,6 +1360,10 @@ static int pager_playback(Pager *pPager){
pPager->journalOff = szJ;
break;
}else{
/* If we are unable to rollback a hot journal, then the database
** is probably not recoverable. Return CORRUPT.
*/
rc = SQLITE_CORRUPT;
goto end_playback;
}
}
@ -1416,6 +1440,7 @@ static int pager_stmt_playback(Pager *pPager){
if( pPager->state>=PAGER_EXCLUSIVE ){
rc = pager_truncate(pPager, pPager->stmtSize);
}
assert( pPager->state>=PAGER_SHARED );
pPager->dbSize = pPager->stmtSize;
/* Figure out how many records are in the statement journal.
@ -1793,14 +1818,19 @@ void enable_simulated_io_errors(void){
** response is to zero the memory at pDest and continue. A real IO error
** will presumably recur and be picked up later (Todo: Think about this).
*/
void sqlite3pager_read_fileheader(Pager *pPager, int N, unsigned char *pDest){
int sqlite3pager_read_fileheader(Pager *pPager, int N, unsigned char *pDest){
int rc = SQLITE_OK;
memset(pDest, 0, N);
if( MEMDB==0 ){
disable_simulated_io_errors();
sqlite3OsSeek(pPager->fd, 0);
sqlite3OsRead(pPager->fd, pDest, N);
enable_simulated_io_errors();
rc = sqlite3OsRead(pPager->fd, pDest, N);
if( rc==SQLITE_IOERR_SHORT_READ ){
rc = SQLITE_OK;
}
}
return rc;
}
/*
@ -1814,12 +1844,13 @@ void sqlite3pager_read_fileheader(Pager *pPager, int N, unsigned char *pDest){
*/
int sqlite3pager_pagecount(Pager *pPager){
i64 n;
int rc;
assert( pPager!=0 );
if( pPager->dbSize>=0 ){
n = pPager->dbSize;
} else {
if( sqlite3OsFileSize(pPager->fd, &n)!=SQLITE_OK ){
pager_error(pPager, SQLITE_IOERR);
if( (rc = sqlite3OsFileSize(pPager->fd, &n))!=SQLITE_OK ){
pager_error(pPager, rc);
return 0;
}
if( n>0 && n<pPager->pageSize ){
@ -1959,9 +1990,15 @@ static void memoryTruncate(Pager *pPager){
*/
static int pager_wait_on_lock(Pager *pPager, int locktype){
int rc;
/* The OS lock values must be the same as the Pager lock values */
assert( PAGER_SHARED==SHARED_LOCK );
assert( PAGER_RESERVED==RESERVED_LOCK );
assert( PAGER_EXCLUSIVE==EXCLUSIVE_LOCK );
/* If the file is currently unlocked then the size must be unknown */
assert( pPager->state>=PAGER_SHARED || pPager->dbSize<0 || MEMDB );
if( pPager->state>=locktype ){
rc = SQLITE_OK;
}else{
@ -1980,6 +2017,7 @@ static int pager_wait_on_lock(Pager *pPager, int locktype){
*/
int sqlite3pager_truncate(Pager *pPager, Pgno nPage){
int rc;
assert( pPager->state>=PAGER_SHARED || MEMDB );
sqlite3pager_pagecount(pPager);
if( pPager->errCode ){
rc = pPager->errCode;
@ -2026,7 +2064,6 @@ int sqlite3pager_truncate(Pager *pPager, Pgno nPage){
** to the caller.
*/
int sqlite3pager_close(Pager *pPager){
PgHdr *pPg, *pNext;
#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
/* A malloc() cannot fail in sqlite3ThreadData() as one or more calls to
** malloc() must have already been made by this thread before it gets
@ -2038,46 +2075,10 @@ int sqlite3pager_close(Pager *pPager){
assert( pTsd && pTsd->nAlloc );
#endif
switch( pPager->state ){
case PAGER_RESERVED:
case PAGER_SYNCED:
case PAGER_EXCLUSIVE: {
/* We ignore any IO errors that occur during the rollback
** operation. So disable IO error simulation so that testing
** works more easily.
*/
disable_simulated_io_errors();
sqlite3pager_rollback(pPager);
enable_simulated_io_errors();
if( !MEMDB ){
sqlite3OsUnlock(pPager->fd, NO_LOCK);
}
assert( pPager->errCode || pPager->journalOpen==0 );
break;
}
case PAGER_SHARED: {
if( !MEMDB ){
sqlite3OsUnlock(pPager->fd, NO_LOCK);
}
break;
}
default: {
/* Do nothing */
break;
}
}
for(pPg=pPager->pAll; pPg; pPg=pNext){
#ifndef NDEBUG
if( MEMDB ){
PgHistory *pHist = PGHDR_TO_HIST(pPg, pPager);
assert( !pPg->alwaysRollback );
assert( !pHist->pOrig );
assert( !pHist->pStmt );
}
#endif
pNext = pPg->pNextAll;
sqliteFree(pPg);
}
disable_simulated_io_errors();
pPager->errCode = 0;
pager_reset(pPager);
enable_simulated_io_errors();
TRACE2("CLOSE %d\n", PAGERID(pPager));
assert( pPager->errCode || (pPager->journalOpen==0 && pPager->stmtOpen==0) );
if( pPager->journalOpen ){
@ -2578,7 +2579,7 @@ int sqlite3pager_release_memory(int nReq){
** The error will be returned to the user (or users, in the case
** of a shared pager cache) of the pager for which the error occured.
*/
assert( rc==SQLITE_IOERR || rc==SQLITE_FULL );
assert( (rc&0xff)==SQLITE_IOERR || rc==SQLITE_FULL );
assert( p->state>=PAGER_RESERVED );
pager_error(p, rc);
}
@ -2659,8 +2660,7 @@ int sqlite3pager_get(Pager *pPager, Pgno pgno, void **ppPage){
*/
rc = sqlite3OsLock(pPager->fd, EXCLUSIVE_LOCK);
if( rc!=SQLITE_OK ){
sqlite3OsUnlock(pPager->fd, NO_LOCK);
pPager->state = PAGER_UNLOCK;
pager_unlock(pPager);
return pager_error(pPager, rc);
}
pPager->state = PAGER_EXCLUSIVE;
@ -2675,8 +2675,7 @@ int sqlite3pager_get(Pager *pPager, Pgno pgno, void **ppPage){
*/
rc = sqlite3OsOpenReadOnly(pPager->zJournal, &pPager->jfd);
if( rc!=SQLITE_OK ){
sqlite3OsUnlock(pPager->fd, NO_LOCK);
pPager->state = PAGER_UNLOCK;
pager_unlock(pPager);
return SQLITE_BUSY;
}
pPager->journalOpen = 1;
@ -2783,19 +2782,10 @@ int sqlite3pager_get(Pager *pPager, Pgno pgno, void **ppPage){
}
TRACE3("FETCH %d page %d\n", PAGERID(pPager), pPg->pgno);
CODEC1(pPager, PGHDR_TO_DATA(pPg), pPg->pgno, 3);
if( rc!=SQLITE_OK ){
i64 fileSize;
int rc2 = sqlite3OsFileSize(pPager->fd, &fileSize);
if( rc2!=SQLITE_OK || fileSize>=pgno*pPager->pageSize ){
/* An IO error occured in one of the the sqlite3OsSeek() or
** sqlite3OsRead() calls above. */
pPg->pgno = 0;
sqlite3pager_unref(PGHDR_TO_DATA(pPg));
return rc;
}else{
clear_simulated_io_error();
memset(PGHDR_TO_DATA(pPg), 0, pPager->pageSize);
}
if( rc!=SQLITE_OK && rc!=SQLITE_IOERR_SHORT_READ ){
pPg->pgno = 0;
sqlite3pager_unref(PGHDR_TO_DATA(pPg));
return rc;
}else{
TEST_INCR(pPager->nRead);
}
@ -2967,8 +2957,7 @@ failed_to_open_journal:
*/
sqlite3OsDelete(pPager->zJournal);
}else{
sqlite3OsUnlock(pPager->fd, NO_LOCK);
pPager->state = PAGER_UNLOCK;
pager_reset(pPager);
}
return rc;
}
@ -3227,6 +3216,7 @@ int sqlite3pager_write(void *pData){
/* Update the database size and return.
*/
assert( pPager->state>=PAGER_SHARED );
if( pPager->dbSize<(int)pPg->pgno ){
pPager->dbSize = pPg->pgno;
if( !MEMDB && pPager->dbSize==PENDING_BYTE/pPager->pageSize ){
@ -3302,6 +3292,7 @@ void sqlite3pager_dont_write(Pager *pPager, Pgno pgno){
assert( pPg!=0 ); /* We never call _dont_write unless the page is in mem */
pPg->alwaysRollback = 1;
if( pPg->dirty && !pPager->stmtInUse ){
assert( pPager->state>=PAGER_SHARED );
if( pPager->dbSize==(int)pPg->pgno && pPager->origDbSize<pPager->dbSize ){
/* If this pages is the last page in the file and the file has grown
** during the current transaction, then do NOT mark the page as clean.
@ -3331,7 +3322,8 @@ void sqlite3pager_dont_rollback(void *pData){
PgHdr *pPg = DATA_TO_PGHDR(pData);
Pager *pPager = pPg->pPager;
if( pPager->state!=PAGER_EXCLUSIVE || pPager->journalOpen==0 ) return;
assert( pPager->state>=PAGER_RESERVED );
if( pPager->journalOpen==0 ) return;
if( pPg->alwaysRollback || pPager->alwaysRollback || MEMDB ) return;
if( !pPg->inJournal && (int)pPg->pgno <= pPager->origDbSize ){
assert( pPager->aInJournal!=0 );
@ -3399,14 +3391,12 @@ int sqlite3pager_commit(Pager *pPager){
** if there have been no changes to the database file. */
assert( pPager->needSync==0 );
rc = pager_unwritelock(pPager);
pPager->dbSize = -1;
return rc;
}
assert( pPager->journalOpen );
rc = sqlite3pager_sync(pPager, 0, 0);
if( rc==SQLITE_OK ){
rc = pager_unwritelock(pPager);
pPager->dbSize = -1;
}
return rc;
}
@ -3464,7 +3454,6 @@ int sqlite3pager_rollback(Pager *pPager){
if( !pPager->dirtyCache || !pPager->journalOpen ){
rc = pager_unwritelock(pPager);
pPager->dbSize = -1;
return rc;
}
@ -3540,6 +3529,7 @@ int sqlite3pager_stmt_begin(Pager *pPager){
int rc;
char zTemp[SQLITE_TEMPNAME_SIZE];
assert( !pPager->stmtInUse );
assert( pPager->state>=PAGER_SHARED );
assert( pPager->dbSize>=0 );
TRACE2("STMT-BEGIN %d\n", PAGERID(pPager));
if( MEMDB ){