diff --git a/manifest b/manifest index 7c9043e9f0..66799a7cef 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Version\s3.3.1\s(alpha)\s(CVS\s2953) -D 2006-01-16T02:39:05 +C Clarify\serror\shandling\sin\spager\scode.\sNo\sfunctional\schanges.\s(CVS\s2956) +D 2006-01-16T11:29:19 F Makefile.in ab3ffd8d469cef4477257169b82810030a6bb967 F Makefile.linux-gcc aee18d8a05546dcf1888bd4547e442008a49a092 F README 9c4e2d6706bdcc3efdd773ce752a8cdab4f90028 @@ -59,18 +59,18 @@ F src/os_unix.c 7daa1720d46bbc31c6138462b35876650eb1885e F src/os_unix.h 5768d56d28240d3fe4537fac08cc85e4fb52279e F src/os_win.c cd4ca2753aeaad11f5c9b9b6ef28752f45ed4529 F src/os_win.h 41a946bea10f61c158ce8645e7646b29d44f122b -F src/pager.c 12da1f38d60a2c44925281d3a1bc2769fa36428b +F src/pager.c 24d4b97c29a6a3d9f4437e6b56debb7e3f3183b2 F src/pager.h e0acb095b3ad0bca48f2ab00c87346665643f64f F src/parse.y 83df51fea35f68f7e07384d75dce83d1ed30434c F src/pragma.c 4496cc77dc35824e1c978c3d1413b8a5a4c777d3 -F src/prepare.c 1058dcb102005a880d757551d52a0a2830c05f27 +F src/prepare.c 368f5c04755f03dc04353513e6afcebb8ca8d53f F src/printf.c f47a2f4b5387cd2ebb12e9117a1a5d6bd9a2b812 F src/random.c d40f8d356cecbd351ccfab6eaedd7ec1b54f5261 F src/select.c 28d449c7762dd580aaba49a9c6c16e93ca951e49 F src/server.c 087b92a39d883e3fa113cae259d64e4c7438bc96 F src/shell.c 66b073375efbdee19045e7e0cd38b85f9aff71da F src/sqlite.h.in 492580f7e3ff71eb43193eb7bb98e2d549889ce3 -F src/sqliteInt.h ed482d6de58fa79000f9c3bb00d7740126fb55fb +F src/sqliteInt.h 940bb605c7ac9240934f0b866f90be899f5261fc F src/table.c 486dcfce532685b53b5a2b5da8bba0ded6fb2316 F src/tclsqlite.c d650bea0248fc0a310ddc2cb94273a3a5021fddf F src/test1.c d21e94ea95e76d8e838792806937332c5693dbf0 @@ -90,7 +90,7 @@ F src/vacuum.c 21a3c7f6f7be86bb1182fbc3df416ad702435b9e F src/vdbe.c 4db1a9000e238e068de56108f5a9708cd4124d55 F src/vdbe.h 8729a4ee16ff9aeab2af9667df3cf300ff978e13 F src/vdbeInt.h 5451cf71f229e366ac543607c0a17f36e5737ea9 -F src/vdbeapi.c afd3837cea0dec93dcb4724d073c84fa0da68e23 +F src/vdbeapi.c cac3f5bfb8ab9864ce5cea35eaae3d0d2efdc8ac F src/vdbeaux.c bfad18ca5d0372a34147ed98ac268b75ccb6858d F src/vdbefifo.c 9efb94c8c3f4c979ebd0028219483f88e57584f5 F src/vdbemem.c dd08a0eea4868ac4a2d91fdec32424308b1db772 @@ -341,7 +341,7 @@ F www/tclsqlite.tcl bb0d1357328a42b1993d78573e587c6dcbc964b9 F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0 F www/version3.tcl a99cf5f6d8bd4d5537584a2b342f0fb9fa601d8b F www/whentouse.tcl 97e2b5cd296f7d8057e11f44427dea8a4c2db513 -P 6591d365d4ba1263c3bc48f5ab47633fae2b2a3a -R 7d7be83f73b610d0efb0d6e55a70818a -U drh -Z 95511deea1a74daa9ad5dc683e2d355c +P bd7c5699939fda2bb792a0e2448df064a1171769 +R 24df549afc2503239ffb645fa43166ce +U danielk1977 +Z c2d3eab392f302df5565749bb5c35c05 diff --git a/manifest.uuid b/manifest.uuid index bd0165ee18..652b64d075 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -bd7c5699939fda2bb792a0e2448df064a1171769 \ No newline at end of file +7b48836214ea3152f46e2dffb097ae7ea14901f4 \ No newline at end of file diff --git a/src/pager.c b/src/pager.c index cc4f9a721e..37d61ccacf 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.237 2006/01/15 20:28:28 drh Exp $ +** @(#) $Id: pager.c,v 1.238 2006/01/16 11:29:19 danielk1977 Exp $ */ #ifndef SQLITE_OMIT_DISKIO #include "sqliteInt.h" @@ -225,6 +225,14 @@ struct PgHistory { /* ** A open page cache is an instance of the following structure. +** +** Pager.errCode may be set to SQLITE_IOERR, SQLITE_CORRUPT, SQLITE_PROTOCOL +** or SQLITE_FULL. Once one of the first three errors occurs, it persists +** and is returned as the result of every major pager API call. The +** SQLITE_FULL return code is slightly different. It persists only until the +** next successful rollback is performed on the pager cache. Also, +** SQLITE_FULL does not affect the sqlite3pager_get() and sqlite3pager_lookup() +** APIs, they may still be used successfully. */ struct Pager { u8 journalOpen; /* True if journal file descriptors is valid */ @@ -237,7 +245,7 @@ struct Pager { u8 noSync; /* Do not sync the journal if true */ u8 fullSync; /* Do extra syncs of the journal for robustness */ u8 state; /* PAGER_UNLOCK, _SHARED, _RESERVED, etc. */ - u8 errMask; /* One of several kinds of errors */ + 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 */ @@ -299,39 +307,6 @@ struct Pager { # define TEST_INCR(x) #endif -/* -** These are bits that can be set in Pager.errMask. -** -** TODO: Maybe we just want a variable - Pager.errCode. Can we really -** have two simultaneous error conditions? -** -** Recovering from an SQLITE_FULL, SQLITE_LOCK, SQLITE_CORRUPT or -** SQLITE_IOERR error is not a simple matter, particularly if the pager -** cache is shared between multiple connections. -** -** SQLITE_FULL (PAGER_ERR_FULL): -** Cleared when the transaction is rolled back. -** -** SQLITE_CORRUPT (PAGER_ERR_CORRUPT): -** Cannot be cleared. The upper layer must close the current pager -** and open a new one on the same file to continue. -** -** SQLITE_PROTOCOL (PAGER_ERR_LOCK): -** This error only occurs if an internal error occurs or another process -** is not following the sqlite locking protocol (i.e. someone is -** manipulating the database file using something other than sqlite). -** This is handled in the same way as database corruption - the error -** cannot be cleared except by closing the current pager and opening -** a brand new one on the same file. -** -** SQLITE_IOERR (PAGER_ERR_DISK): -** Cleared when the transaction is rolled back. -*/ -#define PAGER_ERR_FULL 0x01 /* a write() failed */ -#define PAGER_ERR_LOCK 0x02 /* error in the locking protocol */ -#define PAGER_ERR_CORRUPT 0x04 /* database or journal corruption */ -#define PAGER_ERR_DISK 0x08 /* general disk I/O error - bad hard drive? */ - /* ** Journal files begin with the following magic string. The data ** was obtained from /dev/random. It is used only as a sanity check. @@ -480,37 +455,19 @@ static u32 retrieve32bits(PgHdr *p, int offset){ } -/* -** Convert the bits in the pPager->errMask into an approprate -** return code. -*/ -static int pager_errcode(Pager *pPager){ - int rc = SQLITE_OK; - if( pPager->errMask & PAGER_ERR_LOCK ) rc = SQLITE_PROTOCOL; - if( pPager->errMask & PAGER_ERR_DISK ) rc = SQLITE_IOERR; - if( pPager->errMask & PAGER_ERR_FULL ) rc = SQLITE_FULL; - if( pPager->errMask & PAGER_ERR_CORRUPT ) rc = SQLITE_CORRUPT; - return rc; -} - /* ** This function should be called when an error occurs within the pager -** code to set the appropriate bits in Pager.errMask. +** code to set Pager.errCode. */ static int pager_error(Pager *pPager, int rc){ - switch( rc ){ - case SQLITE_PROTOCOL: - pPager->errMask |= PAGER_ERR_LOCK; - break; - case SQLITE_IOERR: - pPager->errMask |= PAGER_ERR_DISK; - break; - case SQLITE_FULL: - pPager->errMask |= PAGER_ERR_FULL; - break; - case SQLITE_CORRUPT: - pPager->errMask |= PAGER_ERR_CORRUPT; - break; + assert( pPager->errCode==SQLITE_FULL || pPager->errCode==SQLITE_OK ); + if( + rc==SQLITE_FULL || + rc==SQLITE_IOERR || + rc==SQLITE_CORRUPT || + rc==SQLITE_PROTOCOL + ){ + pPager->errCode = rc; } return rc; } @@ -537,7 +494,7 @@ static u32 pager_pagehash(PgHdr *pPage){ #define CHECK_PAGE(x) checkPage(x) static void checkPage(PgHdr *pPg){ Pager *pPager = pPg->pPager; - assert( !pPg->pageHash || pPager->errMask || MEMDB || pPg->dirty || + assert( !pPg->pageHash || pPager->errCode || MEMDB || pPg->dirty || pPg->pageHash==pager_pagehash(pPg) ); } @@ -879,7 +836,7 @@ static PgHdr *pager_lookup(Pager *pPager, Pgno pgno){ */ static void pager_reset(Pager *pPager){ PgHdr *pPg, *pNext; - if( pPager->errMask ) return; + if( pPager->errCode ) return; for(pPg=pPager->pAll; pPg; pPg=pNext){ pNext = pPg->pNextAll; sqliteFree(pPg); @@ -1500,8 +1457,7 @@ static int pager_stmt_playback(Pager *pPager){ end_stmt_playback: if( rc!=SQLITE_OK ){ - pPager->errMask |= PAGER_ERR_CORRUPT; - rc = SQLITE_CORRUPT; + rc = pager_error(pPager, SQLITE_CORRUPT); }else{ pPager->journalOff = szJ; /* pager_reload_cache(pPager); */ @@ -1833,7 +1789,7 @@ int sqlite3pager_pagecount(Pager *pPager){ n = pPager->dbSize; } else { if( sqlite3OsFileSize(pPager->fd, &n)!=SQLITE_OK ){ - pPager->errMask |= PAGER_ERR_DISK; + pager_error(pPager, SQLITE_IOERR); return 0; } if( n>0 && npageSize ){ @@ -1979,8 +1935,8 @@ static int pager_wait_on_lock(Pager *pPager, int locktype){ int sqlite3pager_truncate(Pager *pPager, Pgno nPage){ int rc; sqlite3pager_pagecount(pPager); - if( pPager->errMask!=0 ){ - rc = pager_errcode(pPager); + if( pPager->errCode ){ + rc = pPager->errCode; return rc; } if( nPage>=(unsigned)pPager->dbSize ){ @@ -2043,7 +1999,7 @@ int sqlite3pager_close(Pager *pPager){ if( !MEMDB ){ sqlite3OsUnlock(pPager->fd, NO_LOCK); } - assert( pPager->errMask || pPager->journalOpen==0 ); + assert( pPager->errCode || pPager->journalOpen==0 ); break; } case PAGER_SHARED: { @@ -2070,7 +2026,7 @@ int sqlite3pager_close(Pager *pPager){ sqliteFree(pPg); } TRACE2("CLOSE %d\n", PAGERID(pPager)); - assert( pPager->errMask || (pPager->journalOpen==0 && pPager->stmtOpen==0) ); + assert( pPager->errCode || (pPager->journalOpen==0 && pPager->stmtOpen==0) ); if( pPager->journalOpen ){ sqlite3OsClose(&pPager->jfd); } @@ -2367,7 +2323,7 @@ static int hasHotJournal(Pager *pPager){ ** Try to find a page in the cache that can be recycled. ** ** This routine may return SQLITE_IOERR, SQLITE_FULL or SQLITE_OK. It -** does not set the pPager->errMask variable. +** does not set the pPager->errCode variable. */ static int pager_recycle(Pager *pPager, int syncOk, PgHdr **ppPg){ PgHdr *pPg; @@ -2512,7 +2468,7 @@ int sqlite3pager_release_memory(int nReq){ if( rc!=SQLITE_OK ){ /* An error occured whilst writing to the database file or ** journal in pager_recycle(). The error is not returned to the - ** caller of this function. Instead, set the Pager.errMask variable. + ** caller of this function. Instead, set the Pager.errCode variable. ** 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. */ @@ -2565,8 +2521,8 @@ int sqlite3pager_get(Pager *pPager, Pgno pgno, void **ppPage){ */ assert( pPager!=0 ); *ppPage = 0; - if( pPager->errMask & ~(PAGER_ERR_FULL) ){ - return pager_errcode(pPager); + if( pPager->errCode && pPager->errCode!=SQLITE_FULL ){ + return pPager->errCode; } /* If this is the first page accessed, then get a SHARED lock @@ -2702,9 +2658,9 @@ int sqlite3pager_get(Pager *pPager, Pgno pgno, void **ppPage){ if( pPager->nExtra>0 ){ memset(PGHDR_TO_EXTRA(pPg, pPager), 0, pPager->nExtra); } - if( pPager->errMask!=0 ){ + if( pPager->errCode ){ sqlite3pager_unref(PGHDR_TO_DATA(pPg)); - rc = pager_errcode(pPager); + rc = pPager->errCode; return rc; } if( sqlite3pager_pagecount(pPager)<(int)pgno ){ @@ -2761,7 +2717,7 @@ void *sqlite3pager_lookup(Pager *pPager, Pgno pgno){ assert( pPager!=0 ); assert( pgno!=0 ); - if( pPager->errMask & ~(PAGER_ERR_FULL) ){ + if( pPager->errCode && pPager->errCode!=SQLITE_FULL ){ return 0; } pPg = pager_lookup(pPager, pgno); @@ -2859,8 +2815,8 @@ static int pager_open_journal(Pager *pPager){ pPager->needSync = 0; pPager->alwaysRollback = 0; pPager->nRec = 0; - if( pPager->errMask!=0 ){ - rc = pager_errcode(pPager); + if( pPager->errCode ){ + rc = pPager->errCode; goto failed_to_open_journal; } pPager->origDbSize = pPager->dbSize; @@ -2978,8 +2934,8 @@ int sqlite3pager_write(void *pData){ /* Check for errors */ - if( pPager->errMask ){ - return pager_errcode(pPager); + if( pPager->errCode ){ + return pPager->errCode; } if( pPager->readOnly ){ return SQLITE_PERM; @@ -3053,7 +3009,9 @@ int sqlite3pager_write(void *pData){ *(u32*)PGHDR_TO_EXTRA(pPg, pPager) = saved; if( rc!=SQLITE_OK ){ sqlite3pager_rollback(pPager); - pPager->errMask |= PAGER_ERR_FULL; + if( !pPager->errCode ){ + pager_error(pPager, SQLITE_FULL); + } return rc; } pPager->nRec++; @@ -3100,7 +3058,9 @@ int sqlite3pager_write(void *pData){ CODEC(pPager, pData, pPg->pgno, 0); if( rc!=SQLITE_OK ){ sqlite3pager_rollback(pPager); - pPager->errMask |= PAGER_ERR_FULL; + if( !pPager->errCode ){ + pager_error(pPager, SQLITE_FULL); + } return rc; } pPager->stmtNRec++; @@ -3260,15 +3220,15 @@ int sqlite3pager_commit(Pager *pPager){ int rc; PgHdr *pPg; - if( pPager->errMask==PAGER_ERR_FULL ){ + if( pPager->errCode==SQLITE_FULL ){ rc = sqlite3pager_rollback(pPager); if( rc==SQLITE_OK ){ rc = SQLITE_FULL; } return rc; } - if( pPager->errMask!=0 ){ - rc = pager_errcode(pPager); + if( pPager->errCode ){ + rc = pPager->errCode; return rc; } if( pPager->stateerrMask!=0 && pPager->errMask!=PAGER_ERR_FULL ){ + if( pPager->errCode && pPager->errCode!=SQLITE_FULL ){ if( pPager->state>=PAGER_EXCLUSIVE ){ pager_playback(pPager); } - return pager_errcode(pPager); + return pPager->errCode; } if( pPager->state==PAGER_RESERVED ){ int rc2; @@ -3397,7 +3357,7 @@ int sqlite3pager_rollback(Pager *pPager){ } if( rc!=SQLITE_OK ){ rc = SQLITE_CORRUPT_BKPT; - pPager->errMask |= PAGER_ERR_CORRUPT; + pager_error(pPager, SQLITE_CORRUPT); } pPager->dbSize = -1; return rc; @@ -3421,7 +3381,7 @@ int *sqlite3pager_stats(Pager *pPager){ a[2] = pPager->mxPage; a[3] = pPager->dbSize; a[4] = pPager->state; - a[5] = pPager->errMask; + a[5] = pPager->errCode; #ifdef SQLITE_TEST a[6] = pPager->nHit; a[7] = pPager->nMiss; diff --git a/src/prepare.c b/src/prepare.c index e7f13120fa..f68206fda7 100644 --- a/src/prepare.c +++ b/src/prepare.c @@ -13,7 +13,7 @@ ** interface, and routines that contribute to loading the database schema ** from disk. ** -** $Id: prepare.c,v 1.22 2006/01/13 06:33:24 danielk1977 Exp $ +** $Id: prepare.c,v 1.23 2006/01/16 11:29:20 danielk1977 Exp $ */ #include "sqliteInt.h" #include "os.h" @@ -495,6 +495,7 @@ int sqlite3_prepare( int rc = SQLITE_OK; int i; + /* Assert that malloc() has not failed */ assert( !sqlite3ThreadDataReadOnly()->mallocFailed ); assert( ppStmt ); diff --git a/src/sqliteInt.h b/src/sqliteInt.h index de97abb679..5a514df826 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -11,7 +11,7 @@ ************************************************************************* ** Internal interface definitions for SQLite. ** -** @(#) $Id: sqliteInt.h,v 1.467 2006/01/13 06:33:24 danielk1977 Exp $ +** @(#) $Id: sqliteInt.h,v 1.468 2006/01/16 11:29:20 danielk1977 Exp $ */ #ifndef _SQLITEINT_H_ #define _SQLITEINT_H_ @@ -1754,7 +1754,7 @@ KeyInfo *sqlite3IndexKeyinfo(Parse *, Index *); #endif void sqlite3MallocClearFailed(); -#ifdef NDEBUG +#ifndef SQLITE_MEMDEBUG #define sqlite3MallocDisallow() #define sqlite3MallocAllow() #else diff --git a/src/vdbeapi.c b/src/vdbeapi.c index 74bd8bd9d3..bad4a3600a 100644 --- a/src/vdbeapi.c +++ b/src/vdbeapi.c @@ -156,7 +156,8 @@ int sqlite3_step(sqlite3_stmt *pStmt){ sqlite3 *db; int rc; - assert(!sqlite3ThreadDataReadOnly()->mallocFailed); + /* Assert that malloc() has not failed */ + assert( !sqlite3ThreadDataReadOnly()->mallocFailed ); if( p==0 || p->magic!=VDBE_MAGIC_RUN ){ return SQLITE_MISUSE;