]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Clarify error handling in pager code. No functional changes. (CVS 2956)
authordanielk1977 <danielk1977@noemail.net>
Mon, 16 Jan 2006 11:29:19 +0000 (11:29 +0000)
committerdanielk1977 <danielk1977@noemail.net>
Mon, 16 Jan 2006 11:29:19 +0000 (11:29 +0000)
FossilOrigin-Name: 7b48836214ea3152f46e2dffb097ae7ea14901f4

manifest
manifest.uuid
src/pager.c
src/prepare.c
src/sqliteInt.h
src/vdbeapi.c

index 7c9043e9f0aff7ad239d4aaa3680790a4f09ee82..66799a7ceff4c43edc7fe69acccdfbc901be0e71 100644 (file)
--- 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
index bd0165ee1879ac51f3fb9d79e22d521b61debd8e..652b64d075f2c88f9dbd8aa13156d497020e7e23 100644 (file)
@@ -1 +1 @@
-bd7c5699939fda2bb792a0e2448df064a1171769
\ No newline at end of file
+7b48836214ea3152f46e2dffb097ae7ea14901f4
\ No newline at end of file
index cc4f9a721e7a2482f89f80c4ccd82f3af2484ad2..37d61ccacfc1b31c1da6f34ad1b9b9b431949ac9 100644 (file)
@@ -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 && n<pPager->pageSize ){
@@ -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->state<PAGER_RESERVED ){
@@ -3379,11 +3339,11 @@ int sqlite3pager_rollback(Pager *pPager){
     return rc;
   }
 
-  if( pPager->errMask!=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;
index e7f13120fa48c65d1674308ff8d3b4cffbb2559d..f68206fda76391f4402bd91a7e13bb1b9b4e9fc7 100644 (file)
@@ -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 );
index de97abb6795adf838a212a7808e8baacf1a48043..5a514df826f3b15aff528915df7d80e1028976dd 100644 (file)
@@ -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
index 74bd8bd9d3451f3d7d8909f17aa1fa16453ef5c7..bad4a3600a4ff3bf61feb6cfcb594a1e72380db2 100644 (file)
@@ -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;