/ Check-in [79125ec9]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Merge enhancements from trunk, and in particular the WAL overwrite feature.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | apple-osx
Files: files | file ages | folders
SHA1: 79125ec9d2cdb96d65ceeb19c2862665f9267d4e
User & Date: drh 2016-01-11 12:49:55
Context
2016-01-11
13:03
Import the version number change to 3.11.0. check-in: 132772d1 user: drh tags: apple-osx
12:49
Merge enhancements from trunk, and in particular the WAL overwrite feature. check-in: 79125ec9 user: drh tags: apple-osx
12:13
If a single page is written to the wal file more than once, instead of appending the second and subsequent copy to the wal file, overwrite the first. Update: See the important bug fix at [f694e60a]! check-in: d493d4f1 user: dan tags: trunk
2016-01-06
14:35
Merge all version 3.10.0 updates. check-in: 77c28c2b user: drh tags: apple-osx
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/btmutex.c.

   164    164     assert( p->sharable==0 || p->locked==0 || sqlite3_mutex_held(p->pBt->mutex) );
   165    165     assert( p->sharable==0 || p->locked==0 || sqlite3_mutex_held(p->db->mutex) );
   166    166   
   167    167     return (p->sharable==0 || p->locked);
   168    168   }
   169    169   #endif
   170    170   
   171         -
   172         -#ifndef SQLITE_OMIT_INCRBLOB
   173         -/*
   174         -** Enter and leave a mutex on a Btree given a cursor owned by that
   175         -** Btree.  These entry points are used by incremental I/O and can be
   176         -** omitted if that module is not used.
   177         -*/
   178         -void sqlite3BtreeEnterCursor(BtCursor *pCur){
   179         -  sqlite3BtreeEnter(pCur->pBtree);
   180         -}
   181         -void sqlite3BtreeLeaveCursor(BtCursor *pCur){
   182         -  sqlite3BtreeLeave(pCur->pBtree);
   183         -}
   184         -#endif /* SQLITE_OMIT_INCRBLOB */
   185         -
   186    171   
   187    172   /*
   188    173   ** Enter the mutex on every Btree associated with a database
   189    174   ** connection.  This is needed (for example) prior to parsing
   190    175   ** a statement since we will be comparing table and column names
   191    176   ** against all schemas and we do not want those schemas being
   192    177   ** reset out from under us.
................................................................................
   213    198     assert( sqlite3_mutex_held(db->mutex) );
   214    199     for(i=0; i<db->nDb; i++){
   215    200       p = db->aDb[i].pBt;
   216    201       if( p ) sqlite3BtreeLeave(p);
   217    202     }
   218    203   }
   219    204   
   220         -/*
   221         -** Return true if a particular Btree requires a lock.  Return FALSE if
   222         -** no lock is ever required since it is not sharable.
   223         -*/
   224         -int sqlite3BtreeSharable(Btree *p){
   225         -  return p->sharable;
   226         -}
   227         -
   228    205   #ifndef NDEBUG
   229    206   /*
   230    207   ** Return true if the current thread holds the database connection
   231    208   ** mutex and all required BtShared mutexes.
   232    209   **
   233    210   ** This routine is used inside assert() statements only.
   234    211   */
................................................................................
   294    271       Btree *p = db->aDb[i].pBt;
   295    272       if( p ){
   296    273         p->pBt->db = p->db;
   297    274       }
   298    275     }
   299    276   }
   300    277   #endif /* if SQLITE_THREADSAFE */
          278  +
          279  +#ifndef SQLITE_OMIT_INCRBLOB
          280  +/*
          281  +** Enter a mutex on a Btree given a cursor owned by that Btree. 
          282  +**
          283  +** These entry points are used by incremental I/O only. Enter() is required 
          284  +** any time OMIT_SHARED_CACHE is not defined, regardless of whether or not 
          285  +** the build is threadsafe. Leave() is only required by threadsafe builds.
          286  +*/
          287  +void sqlite3BtreeEnterCursor(BtCursor *pCur){
          288  +  sqlite3BtreeEnter(pCur->pBtree);
          289  +}
          290  +# if SQLITE_THREADSAFE
          291  +void sqlite3BtreeLeaveCursor(BtCursor *pCur){
          292  +  sqlite3BtreeLeave(pCur->pBtree);
          293  +}
          294  +# endif
          295  +#endif /* ifndef SQLITE_OMIT_INCRBLOB */
          296  +
   301    297   #endif /* ifndef SQLITE_OMIT_SHARED_CACHE */

Changes to src/btree.c.

   452    452   **
   453    453   ** Verify that the cursor holds the mutex on its BtShared
   454    454   */
   455    455   #ifdef SQLITE_DEBUG
   456    456   static int cursorHoldsMutex(BtCursor *p){
   457    457     return sqlite3_mutex_held(p->pBt->mutex);
   458    458   }
          459  +static int cursorOwnsBtShared(BtCursor *p){
          460  +  assert( cursorHoldsMutex(p) );
          461  +  return (p->pBtree->db==p->pBt->db);
          462  +}
   459    463   #endif
   460    464   
   461    465   /*
   462    466   ** Invalidate the overflow cache of the cursor passed as the first argument.
   463    467   ** on the shared btree structure pBt.
   464    468   */
   465    469   #define invalidateOverflowCache(pCur) (pCur->curFlags &= ~BTCF_ValidOvfl)
................................................................................
   788    792   ** saved position info stored by saveCursorPosition(), so there can be
   789    793   ** at most one effective restoreCursorPosition() call after each 
   790    794   ** saveCursorPosition().
   791    795   */
   792    796   static int btreeRestoreCursorPosition(BtCursor *pCur){
   793    797     int rc;
   794    798     int skipNext;
   795         -  assert( cursorHoldsMutex(pCur) );
          799  +  assert( cursorOwnsBtShared(pCur) );
   796    800     assert( pCur->eState>=CURSOR_REQUIRESEEK );
   797    801     if( pCur->eState==CURSOR_FAULT ){
   798    802       return pCur->skipNext;
   799    803     }
   800    804     pCur->eState = CURSOR_INVALID;
   801    805     rc = btreeMoveto(pCur, pCur->pKey, pCur->nKey, 0, &skipNext);
   802    806     if( rc==SQLITE_OK ){
................................................................................
  3149   3153   ** of A's read lock.  A tries to promote to reserved but is blocked by B.
  3150   3154   ** One or the other of the two processes must give way or there can be
  3151   3155   ** no progress.  By returning SQLITE_BUSY and not invoking the busy callback
  3152   3156   ** when A already has a read lock, we encourage A to give up and let B
  3153   3157   ** proceed.
  3154   3158   */
  3155   3159   int sqlite3BtreeBeginTrans(Btree *p, int wrflag){
  3156         -  sqlite3 *pBlock = 0;
  3157   3160     BtShared *pBt = p->pBt;
  3158   3161     int rc = SQLITE_OK;
  3159   3162   
  3160   3163     sqlite3BtreeEnter(p);
  3161   3164     btreeIntegrity(p);
  3162   3165   
  3163   3166     /* If the btree is already in a write-transaction, or it
................................................................................
  3172   3175     /* Write transactions are not possible on a read-only database */
  3173   3176     if( (pBt->btsFlags & BTS_READ_ONLY)!=0 && wrflag ){
  3174   3177       rc = SQLITE_READONLY;
  3175   3178       goto trans_begun;
  3176   3179     }
  3177   3180   
  3178   3181   #ifndef SQLITE_OMIT_SHARED_CACHE
  3179         -  /* If another database handle has already opened a write transaction 
  3180         -  ** on this shared-btree structure and a second write transaction is
  3181         -  ** requested, return SQLITE_LOCKED.
  3182         -  */
  3183         -  if( (wrflag && pBt->inTransaction==TRANS_WRITE)
  3184         -   || (pBt->btsFlags & BTS_PENDING)!=0
  3185         -  ){
  3186         -    pBlock = pBt->pWriter->db;
  3187         -  }else if( wrflag>1 ){
  3188         -    BtLock *pIter;
  3189         -    for(pIter=pBt->pLock; pIter; pIter=pIter->pNext){
  3190         -      if( pIter->pBtree!=p ){
  3191         -        pBlock = pIter->pBtree->db;
  3192         -        break;
  3193         -      }
  3194         -    }
  3195         -  }
  3196         -  if( pBlock ){
  3197         -    sqlite3ConnectionBlocked(p->db, pBlock);
  3198         -    rc = SQLITE_LOCKED_SHAREDCACHE;
  3199         -    goto trans_begun;
         3182  +  {
         3183  +    sqlite3 *pBlock = 0;
         3184  +    /* If another database handle has already opened a write transaction 
         3185  +    ** on this shared-btree structure and a second write transaction is
         3186  +    ** requested, return SQLITE_LOCKED.
         3187  +    */
         3188  +    if( (wrflag && pBt->inTransaction==TRANS_WRITE)
         3189  +     || (pBt->btsFlags & BTS_PENDING)!=0
         3190  +    ){
         3191  +      pBlock = pBt->pWriter->db;
         3192  +    }else if( wrflag>1 ){
         3193  +      BtLock *pIter;
         3194  +      for(pIter=pBt->pLock; pIter; pIter=pIter->pNext){
         3195  +        if( pIter->pBtree!=p ){
         3196  +          pBlock = pIter->pBtree->db;
         3197  +          break;
         3198  +        }
         3199  +      }
         3200  +    }
         3201  +    if( pBlock ){
         3202  +      sqlite3ConnectionBlocked(p->db, pBlock);
         3203  +      rc = SQLITE_LOCKED_SHAREDCACHE;
         3204  +      goto trans_begun;
         3205  +    }
  3200   3206     }
  3201   3207   #endif
  3202   3208   
  3203   3209     /* Any read-only or read-write transaction implies a read-lock on 
  3204   3210     ** page 1. So if some other shared-cache client already has a write-lock 
  3205   3211     ** on page 1, the transaction cannot be opened. */
  3206   3212     rc = querySharedCacheTableLock(p, MASTER_ROOT, READ_LOCK);
................................................................................
  4309   4315   ** that the cursor has Cursor.eState==CURSOR_VALID.
  4310   4316   **
  4311   4317   ** Failure is not possible.  This function always returns SQLITE_OK.
  4312   4318   ** It might just as well be a procedure (returning void) but we continue
  4313   4319   ** to return an integer result code for historical reasons.
  4314   4320   */
  4315   4321   int sqlite3BtreeDataSize(BtCursor *pCur, u32 *pSize){
  4316         -  assert( cursorHoldsMutex(pCur) );
         4322  +  assert( cursorOwnsBtShared(pCur) );
  4317   4323     assert( pCur->eState==CURSOR_VALID );
  4318   4324     assert( pCur->iPage>=0 );
  4319   4325     assert( pCur->iPage<BTCURSOR_MAX_DEPTH );
  4320   4326     assert( pCur->apPage[pCur->iPage]->intKeyLeaf==1 );
  4321   4327     getCellInfo(pCur);
  4322   4328     *pSize = pCur->info.nPayload;
  4323   4329     return SQLITE_OK;
................................................................................
  4689   4695   
  4690   4696   #ifndef SQLITE_OMIT_INCRBLOB
  4691   4697     if ( pCur->eState==CURSOR_INVALID ){
  4692   4698       return SQLITE_ABORT;
  4693   4699     }
  4694   4700   #endif
  4695   4701   
  4696         -  assert( cursorHoldsMutex(pCur) );
         4702  +  assert( cursorOwnsBtShared(pCur) );
  4697   4703     rc = restoreCursorPosition(pCur);
  4698   4704     if( rc==SQLITE_OK ){
  4699   4705       assert( pCur->eState==CURSOR_VALID );
  4700   4706       assert( pCur->iPage>=0 && pCur->apPage[pCur->iPage] );
  4701   4707       assert( pCur->aiIdx[pCur->iPage]<pCur->apPage[pCur->iPage]->nCell );
  4702   4708       rc = accessPayload(pCur, offset, amt, pBuf, 0);
  4703   4709     }
................................................................................
  4727   4733     BtCursor *pCur,      /* Cursor pointing to entry to read from */
  4728   4734     u32 *pAmt            /* Write the number of available bytes here */
  4729   4735   ){
  4730   4736     u32 amt;
  4731   4737     assert( pCur!=0 && pCur->iPage>=0 && pCur->apPage[pCur->iPage]);
  4732   4738     assert( pCur->eState==CURSOR_VALID );
  4733   4739     assert( sqlite3_mutex_held(pCur->pBtree->db->mutex) );
  4734         -  assert( cursorHoldsMutex(pCur) );
         4740  +  assert( cursorOwnsBtShared(pCur) );
  4735   4741     assert( pCur->aiIdx[pCur->iPage]<pCur->apPage[pCur->iPage]->nCell );
  4736   4742     assert( pCur->info.nSize>0 );
  4737   4743     assert( pCur->info.pPayload>pCur->apPage[pCur->iPage]->aData || CORRUPT_DB );
  4738   4744     assert( pCur->info.pPayload<pCur->apPage[pCur->iPage]->aDataEnd ||CORRUPT_DB);
  4739   4745     amt = (int)(pCur->apPage[pCur->iPage]->aDataEnd - pCur->info.pPayload);
  4740   4746     if( pCur->info.nLocal<amt ) amt = pCur->info.nLocal;
  4741   4747     *pAmt = amt;
................................................................................
  4773   4779   ** the new child page does not match the flags field of the parent (i.e.
  4774   4780   ** if an intkey page appears to be the parent of a non-intkey page, or
  4775   4781   ** vice-versa).
  4776   4782   */
  4777   4783   static int moveToChild(BtCursor *pCur, u32 newPgno){
  4778   4784     BtShared *pBt = pCur->pBt;
  4779   4785   
  4780         -  assert( cursorHoldsMutex(pCur) );
         4786  +  assert( cursorOwnsBtShared(pCur) );
  4781   4787     assert( pCur->eState==CURSOR_VALID );
  4782   4788     assert( pCur->iPage<BTCURSOR_MAX_DEPTH );
  4783   4789     assert( pCur->iPage>=0 );
  4784   4790     if( pCur->iPage>=(BTCURSOR_MAX_DEPTH-1) ){
  4785   4791       return SQLITE_CORRUPT_BKPT;
  4786   4792     }
  4787   4793     pCur->info.nSize = 0;
................................................................................
  4819   4825   **
  4820   4826   ** pCur->idx is set to the cell index that contains the pointer
  4821   4827   ** to the page we are coming from.  If we are coming from the
  4822   4828   ** right-most child page then pCur->idx is set to one more than
  4823   4829   ** the largest cell index.
  4824   4830   */
  4825   4831   static void moveToParent(BtCursor *pCur){
  4826         -  assert( cursorHoldsMutex(pCur) );
         4832  +  assert( cursorOwnsBtShared(pCur) );
  4827   4833     assert( pCur->eState==CURSOR_VALID );
  4828   4834     assert( pCur->iPage>0 );
  4829   4835     assert( pCur->apPage[pCur->iPage] );
  4830   4836     assertParentIndex(
  4831   4837       pCur->apPage[pCur->iPage-1], 
  4832   4838       pCur->aiIdx[pCur->iPage-1], 
  4833   4839       pCur->apPage[pCur->iPage]->pgno
................................................................................
  4859   4865   ** structure the flags byte is set to 0x02 or 0x0A, indicating an index
  4860   4866   ** b-tree).
  4861   4867   */
  4862   4868   static int moveToRoot(BtCursor *pCur){
  4863   4869     MemPage *pRoot;
  4864   4870     int rc = SQLITE_OK;
  4865   4871   
  4866         -  assert( cursorHoldsMutex(pCur) );
         4872  +  assert( cursorOwnsBtShared(pCur) );
  4867   4873     assert( CURSOR_INVALID < CURSOR_REQUIRESEEK );
  4868   4874     assert( CURSOR_VALID   < CURSOR_REQUIRESEEK );
  4869   4875     assert( CURSOR_FAULT   > CURSOR_REQUIRESEEK );
  4870   4876     if( pCur->eState>=CURSOR_REQUIRESEEK ){
  4871   4877       if( pCur->eState==CURSOR_FAULT ){
  4872   4878         assert( pCur->skipNext!=SQLITE_OK );
  4873   4879         return pCur->skipNext;
................................................................................
  4938   4944   ** in ascending order.
  4939   4945   */
  4940   4946   static int moveToLeftmost(BtCursor *pCur){
  4941   4947     Pgno pgno;
  4942   4948     int rc = SQLITE_OK;
  4943   4949     MemPage *pPage;
  4944   4950   
  4945         -  assert( cursorHoldsMutex(pCur) );
         4951  +  assert( cursorOwnsBtShared(pCur) );
  4946   4952     assert( pCur->eState==CURSOR_VALID );
  4947   4953     while( rc==SQLITE_OK && !(pPage = pCur->apPage[pCur->iPage])->leaf ){
  4948   4954       assert( pCur->aiIdx[pCur->iPage]<pPage->nCell );
  4949   4955       pgno = get4byte(findCell(pPage, pCur->aiIdx[pCur->iPage]));
  4950   4956       rc = moveToChild(pCur, pgno);
  4951   4957     }
  4952   4958     return rc;
................................................................................
  4963   4969   ** key in ascending order.
  4964   4970   */
  4965   4971   static int moveToRightmost(BtCursor *pCur){
  4966   4972     Pgno pgno;
  4967   4973     int rc = SQLITE_OK;
  4968   4974     MemPage *pPage = 0;
  4969   4975   
  4970         -  assert( cursorHoldsMutex(pCur) );
         4976  +  assert( cursorOwnsBtShared(pCur) );
  4971   4977     assert( pCur->eState==CURSOR_VALID );
  4972   4978     while( !(pPage = pCur->apPage[pCur->iPage])->leaf ){
  4973   4979       pgno = get4byte(&pPage->aData[pPage->hdrOffset+8]);
  4974   4980       pCur->aiIdx[pCur->iPage] = pPage->nCell;
  4975   4981       rc = moveToChild(pCur, pgno);
  4976   4982       if( rc ) return rc;
  4977   4983     }
................................................................................
  4984   4990   /* Move the cursor to the first entry in the table.  Return SQLITE_OK
  4985   4991   ** on success.  Set *pRes to 0 if the cursor actually points to something
  4986   4992   ** or set *pRes to 1 if the table is empty.
  4987   4993   */
  4988   4994   int sqlite3BtreeFirst(BtCursor *pCur, int *pRes){
  4989   4995     int rc;
  4990   4996   
  4991         -  assert( cursorHoldsMutex(pCur) );
         4997  +  assert( cursorOwnsBtShared(pCur) );
  4992   4998     assert( sqlite3_mutex_held(pCur->pBtree->db->mutex) );
  4993   4999     rc = moveToRoot(pCur);
  4994   5000     if( rc==SQLITE_OK ){
  4995   5001       if( pCur->eState==CURSOR_INVALID ){
  4996   5002         assert( pCur->pgnoRoot==0 || pCur->apPage[pCur->iPage]->nCell==0 );
  4997   5003         *pRes = 1;
  4998   5004       }else{
................................................................................
  5007   5013   /* Move the cursor to the last entry in the table.  Return SQLITE_OK
  5008   5014   ** on success.  Set *pRes to 0 if the cursor actually points to something
  5009   5015   ** or set *pRes to 1 if the table is empty.
  5010   5016   */
  5011   5017   int sqlite3BtreeLast(BtCursor *pCur, int *pRes){
  5012   5018     int rc;
  5013   5019    
  5014         -  assert( cursorHoldsMutex(pCur) );
         5020  +  assert( cursorOwnsBtShared(pCur) );
  5015   5021     assert( sqlite3_mutex_held(pCur->pBtree->db->mutex) );
  5016   5022   
  5017   5023     /* If the cursor already points to the last entry, this is a no-op. */
  5018   5024     if( CURSOR_VALID==pCur->eState && (pCur->curFlags & BTCF_AtLast)!=0 ){
  5019   5025   #ifdef SQLITE_DEBUG
  5020   5026       /* This block serves to assert() that the cursor really does point 
  5021   5027       ** to the last entry in the b-tree. */
................................................................................
  5085   5091     i64 intKey,              /* The table key */
  5086   5092     int biasRight,           /* If true, bias the search to the high end */
  5087   5093     int *pRes                /* Write search results here */
  5088   5094   ){
  5089   5095     int rc;
  5090   5096     RecordCompare xRecordCompare;
  5091   5097   
  5092         -  assert( cursorHoldsMutex(pCur) );
         5098  +  assert( cursorOwnsBtShared(pCur) );
  5093   5099     assert( sqlite3_mutex_held(pCur->pBtree->db->mutex) );
  5094   5100     assert( pRes );
  5095   5101     assert( (pIdxKey==0)==(pCur->pKeyInfo==0) );
  5096   5102   
  5097   5103     /* If the cursor is already positioned at the point we are trying
  5098   5104     ** to move to, then just return without doing any work */
  5099   5105     if( pCur->eState==CURSOR_VALID && (pCur->curFlags & BTCF_ValidNKey)!=0
................................................................................
  5333   5339   ** implementation does use this hint, however.)
  5334   5340   */
  5335   5341   static SQLITE_NOINLINE int btreeNext(BtCursor *pCur, int *pRes){
  5336   5342     int rc;
  5337   5343     int idx;
  5338   5344     MemPage *pPage;
  5339   5345   
  5340         -  assert( cursorHoldsMutex(pCur) );
         5346  +  assert( cursorOwnsBtShared(pCur) );
  5341   5347     assert( pCur->skipNext==0 || pCur->eState!=CURSOR_VALID );
  5342   5348     assert( *pRes==0 );
  5343   5349     if( pCur->eState!=CURSOR_VALID ){
  5344   5350       assert( (pCur->curFlags & BTCF_ValidOvfl)==0 );
  5345   5351       rc = restoreCursorPosition(pCur);
  5346   5352       if( rc!=SQLITE_OK ){
  5347   5353         return rc;
................................................................................
  5397   5403       return SQLITE_OK;
  5398   5404     }else{
  5399   5405       return moveToLeftmost(pCur);
  5400   5406     }
  5401   5407   }
  5402   5408   int sqlite3BtreeNext(BtCursor *pCur, int *pRes){
  5403   5409     MemPage *pPage;
  5404         -  assert( cursorHoldsMutex(pCur) );
         5410  +  assert( cursorOwnsBtShared(pCur) );
  5405   5411     assert( pRes!=0 );
  5406   5412     assert( *pRes==0 || *pRes==1 );
  5407   5413     assert( pCur->skipNext==0 || pCur->eState!=CURSOR_VALID );
  5408   5414     pCur->info.nSize = 0;
  5409   5415     pCur->curFlags &= ~(BTCF_ValidNKey|BTCF_ValidOvfl);
  5410   5416     *pRes = 0;
  5411   5417     if( pCur->eState!=CURSOR_VALID ) return btreeNext(pCur, pRes);
................................................................................
  5442   5448   ** SQLite btree implementation does not. (Note that the comdb2 btree
  5443   5449   ** implementation does use this hint, however.)
  5444   5450   */
  5445   5451   static SQLITE_NOINLINE int btreePrevious(BtCursor *pCur, int *pRes){
  5446   5452     int rc;
  5447   5453     MemPage *pPage;
  5448   5454   
  5449         -  assert( cursorHoldsMutex(pCur) );
         5455  +  assert( cursorOwnsBtShared(pCur) );
  5450   5456     assert( pRes!=0 );
  5451   5457     assert( *pRes==0 );
  5452   5458     assert( pCur->skipNext==0 || pCur->eState!=CURSOR_VALID );
  5453   5459     assert( (pCur->curFlags & (BTCF_AtLast|BTCF_ValidOvfl|BTCF_ValidNKey))==0 );
  5454   5460     assert( pCur->info.nSize==0 );
  5455   5461     if( pCur->eState!=CURSOR_VALID ){
  5456   5462       rc = restoreCursorPosition(pCur);
................................................................................
  5498   5504       }else{
  5499   5505         rc = SQLITE_OK;
  5500   5506       }
  5501   5507     }
  5502   5508     return rc;
  5503   5509   }
  5504   5510   int sqlite3BtreePrevious(BtCursor *pCur, int *pRes){
  5505         -  assert( cursorHoldsMutex(pCur) );
         5511  +  assert( cursorOwnsBtShared(pCur) );
  5506   5512     assert( pRes!=0 );
  5507   5513     assert( *pRes==0 || *pRes==1 );
  5508   5514     assert( pCur->skipNext==0 || pCur->eState!=CURSOR_VALID );
  5509   5515     *pRes = 0;
  5510   5516     pCur->curFlags &= ~(BTCF_AtLast|BTCF_ValidOvfl|BTCF_ValidNKey);
  5511   5517     pCur->info.nSize = 0;
  5512   5518     if( pCur->eState!=CURSOR_VALID
................................................................................
  7978   7984     unsigned char *newCell = 0;
  7979   7985   
  7980   7986     if( pCur->eState==CURSOR_FAULT ){
  7981   7987       assert( pCur->skipNext!=SQLITE_OK );
  7982   7988       return pCur->skipNext;
  7983   7989     }
  7984   7990   
  7985         -  assert( cursorHoldsMutex(pCur) );
         7991  +  assert( cursorOwnsBtShared(pCur) );
  7986   7992     assert( (pCur->curFlags & BTCF_WriteFlag)!=0
  7987   7993                 && pBt->inTransaction==TRANS_WRITE
  7988   7994                 && (pBt->btsFlags & BTS_READ_ONLY)==0 );
  7989   7995     assert( hasSharedCacheTableLock(p, pCur->pgnoRoot, pCur->pKeyInfo!=0, 2) );
  7990   7996   
  7991   7997     /* Assert that the caller has been consistent. If this cursor was opened
  7992   7998     ** expecting an index b-tree, then the caller should be inserting blob
................................................................................
  8125   8131     MemPage *pPage;                      /* Page to delete cell from */
  8126   8132     unsigned char *pCell;                /* Pointer to cell to delete */
  8127   8133     int iCellIdx;                        /* Index of cell to delete */
  8128   8134     int iCellDepth;                      /* Depth of node containing pCell */ 
  8129   8135     u16 szCell;                          /* Size of the cell being deleted */
  8130   8136     int bSkipnext = 0;                   /* Leaf cursor in SKIPNEXT state */
  8131   8137   
  8132         -  assert( cursorHoldsMutex(pCur) );
         8138  +  assert( cursorOwnsBtShared(pCur) );
  8133   8139     assert( pBt->inTransaction==TRANS_WRITE );
  8134   8140     assert( (pBt->btsFlags & BTS_READ_ONLY)==0 );
  8135   8141     assert( pCur->curFlags & BTCF_WriteFlag );
  8136   8142     assert( hasSharedCacheTableLock(p, pCur->pgnoRoot, pCur->pKeyInfo!=0, 2) );
  8137   8143     assert( !hasReadConflicts(p, pCur->pgnoRoot) );
  8138   8144     assert( pCur->aiIdx[pCur->iPage]<pCur->apPage[pCur->iPage]->nCell );
  8139   8145     assert( pCur->eState==CURSOR_VALID );
................................................................................
  9587   9593   ** Only the data content may only be modified, it is not possible to 
  9588   9594   ** change the length of the data stored. If this function is called with
  9589   9595   ** parameters that attempt to write past the end of the existing data,
  9590   9596   ** no modifications are made and SQLITE_CORRUPT is returned.
  9591   9597   */
  9592   9598   int sqlite3BtreePutData(BtCursor *pCsr, u32 offset, u32 amt, void *z){
  9593   9599     int rc;
  9594         -  assert( cursorHoldsMutex(pCsr) );
         9600  +  assert( cursorOwnsBtShared(pCsr) );
  9595   9601     assert( sqlite3_mutex_held(pCsr->pBtree->db->mutex) );
  9596   9602     assert( pCsr->curFlags & BTCF_Incrblob );
  9597   9603   
  9598   9604     rc = restoreCursorPosition(pCsr);
  9599   9605     if( rc!=SQLITE_OK ){
  9600   9606       return rc;
  9601   9607     }
................................................................................
  9694   9700     return (p->pBt->btsFlags & BTS_READ_ONLY)!=0;
  9695   9701   }
  9696   9702   
  9697   9703   /*
  9698   9704   ** Return the size of the header added to each page by this module.
  9699   9705   */
  9700   9706   int sqlite3HeaderSizeBtree(void){ return ROUND8(sizeof(MemPage)); }
         9707  +
         9708  +#if !defined(SQLITE_OMIT_SHARED_CACHE)
         9709  +/*
         9710  +** Return true if the Btree passed as the only argument is sharable.
         9711  +*/
         9712  +int sqlite3BtreeSharable(Btree *p){
         9713  +  return p->sharable;
         9714  +}
         9715  +#endif

Changes to src/btree.h.

   283    283   ** If we are not using shared cache, then there is no need to
   284    284   ** use mutexes to access the BtShared structures.  So make the
   285    285   ** Enter and Leave procedures no-ops.
   286    286   */
   287    287   #ifndef SQLITE_OMIT_SHARED_CACHE
   288    288     void sqlite3BtreeEnter(Btree*);
   289    289     void sqlite3BtreeEnterAll(sqlite3*);
          290  +  int sqlite3BtreeSharable(Btree*);
          291  +  void sqlite3BtreeEnterCursor(BtCursor*);
   290    292   #else
   291    293   # define sqlite3BtreeEnter(X) 
   292    294   # define sqlite3BtreeEnterAll(X)
          295  +# define sqlite3BtreeSharable(X) 0
          296  +# define sqlite3BtreeEnterCursor(X)
   293    297   #endif
   294    298   
   295    299   #if !defined(SQLITE_OMIT_SHARED_CACHE) && SQLITE_THREADSAFE
   296         -  int sqlite3BtreeSharable(Btree*);
   297    300     void sqlite3BtreeLeave(Btree*);
   298         -  void sqlite3BtreeEnterCursor(BtCursor*);
   299    301     void sqlite3BtreeLeaveCursor(BtCursor*);
   300    302     void sqlite3BtreeLeaveAll(sqlite3*);
   301    303   #ifndef NDEBUG
   302    304     /* These routines are used inside assert() statements only. */
   303    305     int sqlite3BtreeHoldsMutex(Btree*);
   304    306     int sqlite3BtreeHoldsAllMutexes(sqlite3*);
   305    307     int sqlite3SchemaMutexHeld(sqlite3*,int,Schema*);
   306    308   #endif
   307    309   #else
   308    310   
   309         -# define sqlite3BtreeSharable(X) 0
   310    311   # define sqlite3BtreeLeave(X)
   311         -# define sqlite3BtreeEnterCursor(X)
   312    312   # define sqlite3BtreeLeaveCursor(X)
   313    313   # define sqlite3BtreeLeaveAll(X)
   314    314   
   315    315   # define sqlite3BtreeHoldsMutex(X) 1
   316    316   # define sqlite3BtreeHoldsAllMutexes(X) 1
   317    317   # define sqlite3SchemaMutexHeld(X,Y,Z) 1
   318    318   #endif
   319    319   
   320    320   
   321    321   #endif /* _BTREE_H_ */

Changes to src/build.c.

    20     20   **     creating ID lists
    21     21   **     BEGIN TRANSACTION
    22     22   **     COMMIT
    23     23   **     ROLLBACK
    24     24   */
    25     25   #include "sqliteInt.h"
    26     26   
    27         -/*
    28         -** This routine is called when a new SQL statement is beginning to
    29         -** be parsed.  Initialize the pParse structure as needed.
    30         -*/
    31         -void sqlite3BeginParse(Parse *pParse, int explainFlag){
    32         -  pParse->explain = (u8)explainFlag;
    33         -  pParse->nVar = 0;
    34         -}
    35         -
    36     27   #ifndef SQLITE_OMIT_SHARED_CACHE
    37     28   /*
    38     29   ** The TableLock structure is only used by the sqlite3TableLock() and
    39     30   ** codeTableLocks() functions.
    40     31   */
    41     32   struct TableLock {
    42     33     int iDb;             /* The database containing the table to be locked */

Changes to src/expr.c.

   457    457     if( pToken ){
   458    458       if( op!=TK_INTEGER || pToken->z==0
   459    459             || sqlite3GetInt32(pToken->z, &iValue)==0 ){
   460    460         nExtra = pToken->n+1;
   461    461         assert( iValue>=0 );
   462    462       }
   463    463     }
   464         -  pNew = sqlite3DbMallocZero(db, sizeof(Expr)+nExtra);
          464  +  pNew = sqlite3DbMallocRaw(db, sizeof(Expr)+nExtra);
   465    465     if( pNew ){
          466  +    memset(pNew, 0, sizeof(Expr));
   466    467       pNew->op = (u8)op;
   467    468       pNew->iAgg = -1;
   468    469       if( pToken ){
   469    470         if( nExtra==0 ){
   470    471           pNew->flags |= EP_IntValue;
   471    472           pNew->u.iValue = iValue;
   472    473         }else{

Changes to src/func.c.

   563    563     sqlite3_result_int(context, sqlite3_total_changes(db));
   564    564   }
   565    565   
   566    566   /*
   567    567   ** A structure defining how to do GLOB-style comparisons.
   568    568   */
   569    569   struct compareInfo {
   570         -  u8 matchAll;
   571         -  u8 matchOne;
   572         -  u8 matchSet;
   573         -  u8 noCase;
          570  +  u8 matchAll;          /* "*" or "%" */
          571  +  u8 matchOne;          /* "?" or "_" */
          572  +  u8 matchSet;          /* "[" or 0 */
          573  +  u8 noCase;            /* true to ignore case differences */
   574    574   };
   575    575   
   576    576   /*
   577    577   ** For LIKE and GLOB matching on EBCDIC machines, assume that every
   578    578   ** character is exactly one byte in size.  Also, provde the Utf8Read()
   579    579   ** macro for fast reading of the next character in the common case where
   580    580   ** the next character is ASCII.
................................................................................
   629    629   **
   630    630   ** This routine is usually quick, but can be N**2 in the worst case.
   631    631   */
   632    632   static int patternCompare(
   633    633     const u8 *zPattern,              /* The glob pattern */
   634    634     const u8 *zString,               /* The string to compare against the glob */
   635    635     const struct compareInfo *pInfo, /* Information about how to do the compare */
   636         -  u32 esc                          /* The escape character */
          636  +  u32 matchOther                   /* The escape char (LIKE) or '[' (GLOB) */
   637    637   ){
   638    638     u32 c, c2;                       /* Next pattern and input string chars */
   639    639     u32 matchOne = pInfo->matchOne;  /* "?" or "_" */
   640    640     u32 matchAll = pInfo->matchAll;  /* "*" or "%" */
   641         -  u32 matchOther;                  /* "[" or the escape character */
   642    641     u8 noCase = pInfo->noCase;       /* True if uppercase==lowercase */
   643    642     const u8 *zEscaped = 0;          /* One past the last escaped input char */
   644    643     
   645         -  /* The GLOB operator does not have an ESCAPE clause.  And LIKE does not
   646         -  ** have the matchSet operator.  So we either have to look for one or
   647         -  ** the other, never both.  Hence the single variable matchOther is used
   648         -  ** to store the one we have to look for.
   649         -  */
   650         -  matchOther = esc ? esc : pInfo->matchSet;
   651         -
   652    644     while( (c = Utf8Read(zPattern))!=0 ){
   653    645       if( c==matchAll ){  /* Match "*" */
   654    646         /* Skip over multiple "*" characters in the pattern.  If there
   655    647         ** are also "?" characters, skip those as well, but consume a
   656    648         ** single character of the input string for each "?" skipped */
   657    649         while( (c=Utf8Read(zPattern)) == matchAll || c == matchOne ){
   658    650           if( c==matchOne && sqlite3Utf8Read(&zString)==0 ){
   659    651             return 0;
   660    652           }
   661    653         }
   662    654         if( c==0 ){
   663    655           return 1;   /* "*" at the end of the pattern matches */
   664    656         }else if( c==matchOther ){
   665         -        if( esc ){
          657  +        if( pInfo->matchSet==0 ){
   666    658             c = sqlite3Utf8Read(&zPattern);
   667    659             if( c==0 ) return 0;
   668    660           }else{
   669    661             /* "[...]" immediately follows the "*".  We have to do a slow
   670    662             ** recursive search in this case, but it is an unusual case. */
   671    663             assert( matchOther<0x80 );  /* '[' is a single-byte character */
   672    664             while( *zString
   673         -                 && patternCompare(&zPattern[-1],zString,pInfo,esc)==0 ){
          665  +                 && patternCompare(&zPattern[-1],zString,pInfo,matchOther)==0 ){
   674    666               SQLITE_SKIP_UTF8(zString);
   675    667             }
   676    668             return *zString!=0;
   677    669           }
   678    670         }
   679    671   
   680    672         /* At this point variable c contains the first character of the
................................................................................
   692    684             cx = sqlite3Toupper(c);
   693    685             c = sqlite3Tolower(c);
   694    686           }else{
   695    687             cx = c;
   696    688           }
   697    689           while( (c2 = *(zString++))!=0 ){
   698    690             if( c2!=c && c2!=cx ) continue;
   699         -          if( patternCompare(zPattern,zString,pInfo,esc) ) return 1;
          691  +          if( patternCompare(zPattern,zString,pInfo,matchOther) ) return 1;
   700    692           }
   701    693         }else{
   702    694           while( (c2 = Utf8Read(zString))!=0 ){
   703    695             if( c2!=c ) continue;
   704         -          if( patternCompare(zPattern,zString,pInfo,esc) ) return 1;
          696  +          if( patternCompare(zPattern,zString,pInfo,matchOther) ) return 1;
   705    697           }
   706    698         }
   707    699         return 0;
   708    700       }
   709    701       if( c==matchOther ){
   710         -      if( esc ){
          702  +      if( pInfo->matchSet==0 ){
   711    703           c = sqlite3Utf8Read(&zPattern);
   712    704           if( c==0 ) return 0;
   713    705           zEscaped = zPattern;
   714    706         }else{
   715    707           u32 prior_c = 0;
   716    708           int seen = 0;
   717    709           int invert = 0;
................................................................................
   756    748     return *zString==0;
   757    749   }
   758    750   
   759    751   /*
   760    752   ** The sqlite3_strglob() interface.
   761    753   */
   762    754   int sqlite3_strglob(const char *zGlobPattern, const char *zString){
   763         -  return patternCompare((u8*)zGlobPattern, (u8*)zString, &globInfo, 0)==0;
          755  +  return patternCompare((u8*)zGlobPattern, (u8*)zString, &globInfo, '[')==0;
   764    756   }
   765    757   
   766    758   /*
   767    759   ** The sqlite3_strlike() interface.
   768    760   */
   769    761   int sqlite3_strlike(const char *zPattern, const char *zStr, unsigned int esc){
   770    762     return patternCompare((u8*)zPattern, (u8*)zStr, &likeInfoNorm, esc)==0;
................................................................................
   794    786   */
   795    787   static void likeFunc(
   796    788     sqlite3_context *context, 
   797    789     int argc, 
   798    790     sqlite3_value **argv
   799    791   ){
   800    792     const unsigned char *zA, *zB;
   801         -  u32 escape = 0;
          793  +  u32 escape;
   802    794     int nPat;
   803    795     sqlite3 *db = sqlite3_context_db_handle(context);
          796  +  struct compareInfo *pInfo = sqlite3_user_data(context);
   804    797   
   805    798   #ifdef SQLITE_LIKE_DOESNT_MATCH_BLOBS
   806    799     if( sqlite3_value_type(argv[0])==SQLITE_BLOB
   807    800      || sqlite3_value_type(argv[1])==SQLITE_BLOB
   808    801     ){
   809    802   #ifdef SQLITE_TEST
   810    803       sqlite3_like_count++;
................................................................................
   836    829       if( zEsc==0 ) return;
   837    830       if( sqlite3Utf8CharLen((char*)zEsc, -1)!=1 ){
   838    831         sqlite3_result_error(context, 
   839    832             "ESCAPE expression must be a single character", -1);
   840    833         return;
   841    834       }
   842    835       escape = sqlite3Utf8Read(&zEsc);
          836  +  }else{
          837  +    escape = pInfo->matchSet;
   843    838     }
   844    839     if( zA && zB ){
   845         -    struct compareInfo *pInfo = sqlite3_user_data(context);
   846    840   #ifdef SQLITE_TEST
   847    841       sqlite3_like_count++;
   848    842   #endif
   849         -    
   850    843       sqlite3_result_int(context, patternCompare(zB, zA, pInfo, escape));
   851    844     }
   852    845   }
   853    846   
   854    847   /*
   855    848   ** Implementation of the NULLIF(x,y) function.  The result is the first
   856    849   ** argument if the arguments are different.  The result is NULL if the

Changes to src/mem5.c.

    98     98     u8 *zPool;       /* Memory available to be allocated */
    99     99     
   100    100     /*
   101    101     ** Mutex to control access to the memory allocation subsystem.
   102    102     */
   103    103     sqlite3_mutex *mutex;
   104    104   
          105  +#if defined(SQLITE_DEBUG) || defined(SQLITE_TEST)
   105    106     /*
   106    107     ** Performance statistics
   107    108     */
   108    109     u64 nAlloc;         /* Total number of calls to malloc */
   109    110     u64 totalAlloc;     /* Total of all malloc calls - includes internal frag */
   110    111     u64 totalExcess;    /* Total internal fragmentation */
   111    112     u32 currentOut;     /* Current checkout, including internal fragmentation */
   112    113     u32 currentCount;   /* Current number of distinct checkouts */
   113    114     u32 maxOut;         /* Maximum instantaneous currentOut */
   114    115     u32 maxCount;       /* Maximum instantaneous currentCount */
   115    116     u32 maxRequest;     /* Largest allocation (exclusive of internal frag) */
          117  +#endif
   116    118     
   117    119     /*
   118    120     ** Lists of free blocks.  aiFreelist[0] is a list of free blocks of
   119    121     ** size mem5.szAtom.  aiFreelist[1] holds blocks of size szAtom*2.
   120    122     ** aiFreelist[2] holds free blocks of size szAtom*4.  And so forth.
   121    123     */
   122    124     int aiFreelist[LOGMAX+1];
................................................................................
   220    222     int iBin;        /* Index into mem5.aiFreelist[] */
   221    223     int iFullSz;     /* Size of allocation rounded up to power of 2 */
   222    224     int iLogsize;    /* Log2 of iFullSz/POW2_MIN */
   223    225   
   224    226     /* nByte must be a positive */
   225    227     assert( nByte>0 );
   226    228   
          229  +  /* No more than 1GiB per allocation */
          230  +  if( nByte > 0x40000000 ) return 0;
          231  +
          232  +#if defined(SQLITE_DEBUG) || defined(SQLITE_TEST)
   227    233     /* Keep track of the maximum allocation request.  Even unfulfilled
   228    234     ** requests are counted */
   229    235     if( (u32)nByte>mem5.maxRequest ){
   230         -    /* Abort if the requested allocation size is larger than the largest
   231         -    ** power of two that we can represent using 32-bit signed integers. */
   232         -    if( nByte > 0x40000000 ) return 0;
   233    236       mem5.maxRequest = nByte;
   234    237     }
          238  +#endif
          239  +
   235    240   
   236    241     /* Round nByte up to the next valid power of two */
   237    242     for(iFullSz=mem5.szAtom,iLogsize=0; iFullSz<nByte; iFullSz*=2,iLogsize++){}
   238    243   
   239    244     /* Make sure mem5.aiFreelist[iLogsize] contains at least one free
   240    245     ** block.  If not, then split a block of the next larger power of
   241    246     ** two in order to create a new free block of size iLogsize.
................................................................................
   254    259       iBin--;
   255    260       newSize = 1 << iBin;
   256    261       mem5.aCtrl[i+newSize] = CTRL_FREE | iBin;
   257    262       memsys5Link(i+newSize, iBin);
   258    263     }
   259    264     mem5.aCtrl[i] = iLogsize;
   260    265   
          266  +#if defined(SQLITE_DEBUG) || defined(SQLITE_TEST)
   261    267     /* Update allocator performance statistics. */
   262    268     mem5.nAlloc++;
   263    269     mem5.totalAlloc += iFullSz;
   264    270     mem5.totalExcess += iFullSz - nByte;
   265    271     mem5.currentCount++;
   266    272     mem5.currentOut += iFullSz;
   267    273     if( mem5.maxCount<mem5.currentCount ) mem5.maxCount = mem5.currentCount;
   268    274     if( mem5.maxOut<mem5.currentOut ) mem5.maxOut = mem5.currentOut;
          275  +#endif
   269    276   
   270    277   #ifdef SQLITE_DEBUG
   271    278     /* Make sure the allocated memory does not assume that it is set to zero
   272    279     ** or retains a value from a previous allocation */
   273    280     memset(&mem5.zPool[i*mem5.szAtom], 0xAA, iFullSz);
   274    281   #endif
   275    282   
................................................................................
   296    303   
   297    304     iLogsize = mem5.aCtrl[iBlock] & CTRL_LOGSIZE;
   298    305     size = 1<<iLogsize;
   299    306     assert( iBlock+size-1<(u32)mem5.nBlock );
   300    307   
   301    308     mem5.aCtrl[iBlock] |= CTRL_FREE;
   302    309     mem5.aCtrl[iBlock+size-1] |= CTRL_FREE;
          310  +
          311  +#if defined(SQLITE_DEBUG) || defined(SQLITE_TEST)
   303    312     assert( mem5.currentCount>0 );
   304    313     assert( mem5.currentOut>=(size*mem5.szAtom) );
   305    314     mem5.currentCount--;
   306    315     mem5.currentOut -= size*mem5.szAtom;
   307    316     assert( mem5.currentOut>0 || mem5.currentCount==0 );
   308    317     assert( mem5.currentCount>0 || mem5.currentOut==0 );
          318  +#endif
   309    319   
   310    320     mem5.aCtrl[iBlock] = CTRL_FREE | iLogsize;
   311    321     while( ALWAYS(iLogsize<LOGMAX) ){
   312    322       int iBuddy;
   313    323       if( (iBlock>>iLogsize) & 1 ){
   314    324         iBuddy = iBlock - size;
   315    325       }else{

Changes to src/os_unix.c.

   721    721     { "fchown",       (sqlite3_syscall_ptr)fchown,          0 },
   722    722   #define osFchown    ((int(*)(int,uid_t,gid_t))aSyscall[20].pCurrent)
   723    723   
   724    724     { "geteuid",      (sqlite3_syscall_ptr)geteuid,         0 },
   725    725   #define osGeteuid   ((uid_t(*)(void))aSyscall[21].pCurrent)
   726    726   
   727    727   #if !defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0
   728         -  { "mmap",       (sqlite3_syscall_ptr)mmap,     0 },
          728  +  { "mmap",         (sqlite3_syscall_ptr)mmap,            0 },
          729  +#else
          730  +  { "mmap",         (sqlite3_syscall_ptr)0,               0 },
          731  +#endif
   729    732   #define osMmap ((void*(*)(void*,size_t,int,int,int,off_t))aSyscall[22].pCurrent)
   730    733   
          734  +#if !defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0
   731    735     { "munmap",       (sqlite3_syscall_ptr)munmap,          0 },
          736  +#else
          737  +  { "munmap",       (sqlite3_syscall_ptr)0,               0 },
          738  +#endif
   732    739   #define osMunmap ((void*(*)(void*,size_t))aSyscall[23].pCurrent)
   733    740   
   734         -#if HAVE_MREMAP
          741  +#if HAVE_MREMAP && (!defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0)
   735    742     { "mremap",       (sqlite3_syscall_ptr)mremap,          0 },
   736    743   #else
   737    744     { "mremap",       (sqlite3_syscall_ptr)0,               0 },
   738    745   #endif
   739    746   #define osMremap ((void*(*)(void*,size_t,size_t,int,...))aSyscall[24].pCurrent)
   740    747   
          748  +#if !defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0
   741    749     { "getpagesize",  (sqlite3_syscall_ptr)unixGetpagesize, 0 },
          750  +#else
          751  +  { "getpagesize",  (sqlite3_syscall_ptr)0,               0 },
          752  +#endif
   742    753   #define osGetpagesize ((int(*)(void))aSyscall[25].pCurrent)
   743    754   
   744    755     { "readlink",     (sqlite3_syscall_ptr)readlink,        0 },
   745    756   #define osReadlink ((ssize_t(*)(const char*,char*,size_t))aSyscall[26].pCurrent)
   746    757   
   747         -#endif
   748    758   
   749    759   }; /* End of the overrideable system calls */
   750    760   
   751    761   
   752    762   /*
   753    763   ** On some systems, calls to fchown() will trigger a message in a security
   754    764   ** log if they come from non-root processes.  So avoid calling fchown() if

Changes to src/parse.y.

   110    110   
   111    111   // Input is a single SQL command
   112    112   input ::= cmdlist.
   113    113   cmdlist ::= cmdlist ecmd.
   114    114   cmdlist ::= ecmd.
   115    115   ecmd ::= SEMI.
   116    116   ecmd ::= explain cmdx SEMI.
   117         -explain ::= .           { sqlite3BeginParse(pParse, 0); }
          117  +explain ::= .
   118    118   %ifndef SQLITE_OMIT_EXPLAIN
   119         -explain ::= EXPLAIN.              { sqlite3BeginParse(pParse, 1); }
   120         -explain ::= EXPLAIN QUERY PLAN.   { sqlite3BeginParse(pParse, 2); }
          119  +explain ::= EXPLAIN.              { pParse->explain = 1; }
          120  +explain ::= EXPLAIN QUERY PLAN.   { pParse->explain = 2; }
   121    121   %endif  SQLITE_OMIT_EXPLAIN
   122    122   cmdx ::= cmd.           { sqlite3FinishCoding(pParse); }
   123    123   
   124    124   ///////////////////// Begin and end transactions. ////////////////////////////
   125    125   //
   126    126   
   127    127   cmd ::= BEGIN transtype(Y) trans_opt.  {sqlite3BeginTransaction(pParse, Y);}

Changes to src/pcache.h.

    50     50   #define PGHDR_DIRTY           0x002  /* Page is on the PCache.pDirty list */
    51     51   #define PGHDR_WRITEABLE       0x004  /* Journaled and ready to modify */
    52     52   #define PGHDR_NEED_SYNC       0x008  /* Fsync the rollback journal before
    53     53                                        ** writing this page to the database */
    54     54   #define PGHDR_NEED_READ       0x010  /* Content is unread */
    55     55   #define PGHDR_DONT_WRITE      0x020  /* Do not write content to disk */
    56     56   #define PGHDR_MMAP            0x040  /* This is an mmap page object */
           57  +
           58  +#define PGHDR_WAL_APPEND      0x080  /* Appended to wal file */
    57     59   
    58     60   /* Initialize and shutdown the page cache subsystem */
    59     61   int sqlite3PcacheInitialize(void);
    60     62   void sqlite3PcacheShutdown(void);
    61     63   
    62     64   /* Page cache buffer management:
    63     65   ** These routines implement SQLITE_CONFIG_PAGECACHE.

Changes to src/select.c.

   107    107     u16 selFlags,         /* Flag parameters, such as SF_Distinct */
   108    108     Expr *pLimit,         /* LIMIT value.  NULL means not used */
   109    109     Expr *pOffset         /* OFFSET value.  NULL means no offset */
   110    110   ){
   111    111     Select *pNew;
   112    112     Select standin;
   113    113     sqlite3 *db = pParse->db;
   114         -  pNew = sqlite3DbMallocZero(db, sizeof(*pNew) );
          114  +  pNew = sqlite3DbMallocRaw(db, sizeof(*pNew) );
   115    115     if( pNew==0 ){
   116    116       assert( db->mallocFailed );
   117    117       pNew = &standin;
   118         -    memset(pNew, 0, sizeof(*pNew));
   119    118     }
   120    119     if( pEList==0 ){
   121    120       pEList = sqlite3ExprListAppend(pParse, 0, sqlite3Expr(db,TK_ASTERISK,0));
   122    121     }
   123    122     pNew->pEList = pEList;
          123  +  pNew->op = TK_SELECT;
          124  +  pNew->selFlags = selFlags;
          125  +  pNew->iLimit = 0;
          126  +  pNew->iOffset = 0;
          127  +  pNew->addrOpenEphm[0] = -1;
          128  +  pNew->addrOpenEphm[1] = -1;
          129  +  pNew->nSelectRow = 0;
   124    130     if( pSrc==0 ) pSrc = sqlite3DbMallocZero(db, sizeof(*pSrc));
   125    131     pNew->pSrc = pSrc;
   126    132     pNew->pWhere = pWhere;
   127    133     pNew->pGroupBy = pGroupBy;
   128    134     pNew->pHaving = pHaving;
   129    135     pNew->pOrderBy = pOrderBy;
   130         -  pNew->selFlags = selFlags;
   131         -  pNew->op = TK_SELECT;
          136  +  pNew->pPrior = 0;
          137  +  pNew->pNext = 0;
   132    138     pNew->pLimit = pLimit;
   133    139     pNew->pOffset = pOffset;
          140  +  pNew->pWith = 0;
   134    141     assert( pOffset==0 || pLimit!=0 || pParse->nErr>0 || db->mallocFailed!=0 );
   135         -  pNew->addrOpenEphm[0] = -1;
   136         -  pNew->addrOpenEphm[1] = -1;
   137    142     if( db->mallocFailed ) {
   138    143       clearSelect(db, pNew, pNew!=&standin);
   139    144       pNew = 0;
   140    145     }else{
   141    146       assert( pNew->pSrc!=0 || pParse->nErr>0 );
   142    147     }
   143    148     assert( pNew!=&standin );

Changes to src/sqliteInt.h.

   763    763   #endif
   764    764   
   765    765   /*
   766    766   ** Default maximum size of memory used by memory-mapped I/O in the VFS
   767    767   */
   768    768   #ifdef __APPLE__
   769    769   # include <TargetConditionals.h>
   770         -# if TARGET_OS_IPHONE
   771         -#   undef SQLITE_MAX_MMAP_SIZE
   772         -#   define SQLITE_MAX_MMAP_SIZE 0
   773         -# endif
   774    770   #endif
   775    771   #ifndef SQLITE_MAX_MMAP_SIZE
   776    772   # if defined(__linux__) \
   777    773     || defined(_WIN32) \
   778    774     || (defined(__APPLE__) && defined(__MACH__)) \
   779    775     || defined(__sun) \
   780    776     || defined(__FreeBSD__) \
................................................................................
  3346   3342   u32 sqlite3ExprListFlags(const ExprList*);
  3347   3343   int sqlite3Init(sqlite3*, char**);
  3348   3344   int sqlite3InitCallback(void*, int, char**, char**);
  3349   3345   void sqlite3Pragma(Parse*,Token*,Token*,Token*,int);
  3350   3346   void sqlite3ResetAllSchemasOfConnection(sqlite3*);
  3351   3347   void sqlite3ResetOneSchema(sqlite3*,int);
  3352   3348   void sqlite3CollapseDatabaseArray(sqlite3*);
  3353         -void sqlite3BeginParse(Parse*,int);
  3354   3349   void sqlite3CommitInternalChanges(sqlite3*);
  3355   3350   void sqlite3DeleteColumnNames(sqlite3*,Table*);
  3356   3351   int sqlite3ColumnsFromExprList(Parse*,ExprList*,i16*,Column**);
  3357   3352   Table *sqlite3ResultSetOfSelect(Parse*,Select*);
  3358   3353   void sqlite3OpenMasterTable(Parse *, int);
  3359   3354   Index *sqlite3PrimaryKeyIndex(Table*);
  3360   3355   i16 sqlite3ColumnOfIndex(Index*, i16);

Changes to src/tclsqlite.c.

  2971   2971   #endif
  2972   2972   
  2973   2973     if( objc==2 ){
  2974   2974       zArg = Tcl_GetStringFromObj(objv[1], 0);
  2975   2975       if( strcmp(zArg,"-version")==0 ){
  2976   2976         Tcl_AppendResult(interp,sqlite3_libversion(), (char*)0);
  2977   2977         return TCL_OK;
         2978  +    }
         2979  +    if( strcmp(zArg,"-sourceid")==0 ){
         2980  +      Tcl_AppendResult(interp,sqlite3_sourceid(), (char*)0);
         2981  +      return TCL_OK;
  2978   2982       }
  2979   2983       if( strcmp(zArg,"-has-codec")==0 ){
  2980   2984   #ifdef SQLITE_HAS_CODEC
  2981   2985         Tcl_AppendResult(interp,"1",(char*)0);
  2982   2986   #else
  2983   2987         Tcl_AppendResult(interp,"0",(char*)0);
  2984   2988   #endif

Changes to src/vdbeInt.h.

   485    485   void sqlite3VdbeSorterClose(sqlite3 *, VdbeCursor *);
   486    486   int sqlite3VdbeSorterRowkey(const VdbeCursor *, Mem *);
   487    487   int sqlite3VdbeSorterNext(sqlite3 *, const VdbeCursor *, int *);
   488    488   int sqlite3VdbeSorterRewind(const VdbeCursor *, int *);
   489    489   int sqlite3VdbeSorterWrite(const VdbeCursor *, Mem *);
   490    490   int sqlite3VdbeSorterCompare(const VdbeCursor *, Mem *, int, int *);
   491    491   
   492         -#if !defined(SQLITE_OMIT_SHARED_CACHE) && SQLITE_THREADSAFE>0
          492  +#if !defined(SQLITE_OMIT_SHARED_CACHE) 
   493    493     void sqlite3VdbeEnter(Vdbe*);
   494         -  void sqlite3VdbeLeave(Vdbe*);
   495    494   #else
   496    495   # define sqlite3VdbeEnter(X)
          496  +#endif
          497  +
          498  +#if !defined(SQLITE_OMIT_SHARED_CACHE) && SQLITE_THREADSAFE>0
          499  +  void sqlite3VdbeLeave(Vdbe*);
          500  +#else
   497    501   # define sqlite3VdbeLeave(X)
   498    502   #endif
   499    503   
   500    504   #ifdef SQLITE_DEBUG
   501    505   void sqlite3VdbeMemAboutToChange(Vdbe*,Mem*);
   502    506   int sqlite3VdbeCheckMemInvariants(Mem*);
   503    507   #endif

Changes to src/vdbeaux.c.

  1313   1313     assert( i<(int)sizeof(p->btreeMask)*8 );
  1314   1314     DbMaskSet(p->btreeMask, i);
  1315   1315     if( i!=1 && sqlite3BtreeSharable(p->db->aDb[i].pBt) ){
  1316   1316       DbMaskSet(p->lockMask, i);
  1317   1317     }
  1318   1318   }
  1319   1319   
  1320         -#if !defined(SQLITE_OMIT_SHARED_CACHE) && SQLITE_THREADSAFE>0
         1320  +#if !defined(SQLITE_OMIT_SHARED_CACHE)
  1321   1321   /*
  1322   1322   ** If SQLite is compiled to support shared-cache mode and to be threadsafe,
  1323   1323   ** this routine obtains the mutex associated with each BtShared structure
  1324   1324   ** that may be accessed by the VM passed as an argument. In doing so it also
  1325   1325   ** sets the BtShared.db member of each of the BtShared structures, ensuring
  1326   1326   ** that the correct busy-handler callback is invoked if required.
  1327   1327   **

Changes to src/wal.c.

   441    441     u8 ckptLock;               /* True if holding a checkpoint lock */
   442    442     u8 readOnly;               /* WAL_RDWR, WAL_RDONLY, or WAL_SHM_RDONLY */
   443    443     u8 truncateOnCommit;       /* True to truncate WAL file on commit */
   444    444     u8 syncHeader;             /* Fsync the WAL header if true */
   445    445     u8 padToSectorBoundary;    /* Pad transactions out to the next sector */
   446    446     WalIndexHdr hdr;           /* Wal-index header for current transaction */
   447    447     u32 minFrame;              /* Ignore wal frames before this one */
          448  +  u32 iReCksum;              /* On commit, recalculate checksums from here */
   448    449     const char *zWalName;      /* Name of WAL file */
   449    450     u32 nCkpt;                 /* Checkpoint sequence counter in the wal-header */
   450    451   #ifdef SQLITE_DEBUG
   451    452     u8 lockError;              /* True if a locking error has occurred */
   452    453   #endif
   453    454   #ifdef SQLITE_ENABLE_SNAPSHOT
   454    455     WalIndexHdr *pSnapshot;    /* Start transaction here if not NULL */
................................................................................
   694    695     u8 *aFrame                      /* OUT: Write encoded frame here */
   695    696   ){
   696    697     int nativeCksum;                /* True for native byte-order checksums */
   697    698     u32 *aCksum = pWal->hdr.aFrameCksum;
   698    699     assert( WAL_FRAME_HDRSIZE==24 );
   699    700     sqlite3Put4byte(&aFrame[0], iPage);
   700    701     sqlite3Put4byte(&aFrame[4], nTruncate);
   701         -  memcpy(&aFrame[8], pWal->hdr.aSalt, 8);
          702  +  if( pWal->iReCksum==0 ){
          703  +    memcpy(&aFrame[8], pWal->hdr.aSalt, 8);
   702    704   
   703         -  nativeCksum = (pWal->hdr.bigEndCksum==SQLITE_BIGENDIAN);
   704         -  walChecksumBytes(nativeCksum, aFrame, 8, aCksum, aCksum);
   705         -  walChecksumBytes(nativeCksum, aData, pWal->szPage, aCksum, aCksum);
          705  +    nativeCksum = (pWal->hdr.bigEndCksum==SQLITE_BIGENDIAN);
          706  +    walChecksumBytes(nativeCksum, aFrame, 8, aCksum, aCksum);
          707  +    walChecksumBytes(nativeCksum, aData, pWal->szPage, aCksum, aCksum);
   706    708   
   707         -  sqlite3Put4byte(&aFrame[16], aCksum[0]);
   708         -  sqlite3Put4byte(&aFrame[20], aCksum[1]);
          709  +    sqlite3Put4byte(&aFrame[16], aCksum[0]);
          710  +    sqlite3Put4byte(&aFrame[20], aCksum[1]);
          711  +  }
   709    712   }
   710    713   
   711    714   /*
   712    715   ** Check to see if the frame with header in aFrame[] and content
   713    716   ** in aData[] is valid.  If it is a valid frame, fill *piPage and
   714    717   ** *pnTruncate and return true.  Return if the frame is not valid.
   715    718   */
................................................................................
  2645   2648   */
  2646   2649   int sqlite3WalBeginWriteTransaction(Wal *pWal){
  2647   2650     int rc;
  2648   2651   
  2649   2652     /* Cannot start a write transaction without first holding a read
  2650   2653     ** transaction. */
  2651   2654     assert( pWal->readLock>=0 );
         2655  +  assert( pWal->writeLock==0 && pWal->iReCksum==0 );
  2652   2656   
  2653   2657     if( pWal->readOnly ){
  2654   2658       return SQLITE_READONLY;
  2655   2659     }
  2656   2660   
  2657   2661     /* Only one writer allowed at a time.  Get the write lock.  Return
  2658   2662     ** SQLITE_BUSY if unable.
................................................................................
  2680   2684   ** End a write transaction.  The commit has already been done.  This
  2681   2685   ** routine merely releases the lock.
  2682   2686   */
  2683   2687   int sqlite3WalEndWriteTransaction(Wal *pWal){
  2684   2688     if( pWal->writeLock ){
  2685   2689       walUnlockExclusive(pWal, WAL_WRITE_LOCK, 1);
  2686   2690       pWal->writeLock = 0;
         2691  +    pWal->iReCksum = 0;
  2687   2692       pWal->truncateOnCommit = 0;
  2688   2693     }
  2689   2694     return SQLITE_OK;
  2690   2695   }
  2691   2696   
  2692   2697   /*
  2693   2698   ** If any data has been written (but not committed) to the log file, this
................................................................................
  2915   2920     rc = walWriteToLog(p, aFrame, sizeof(aFrame), iOffset);
  2916   2921     if( rc ) return rc;
  2917   2922     /* Write the page data */
  2918   2923     rc = walWriteToLog(p, pData, p->szPage, iOffset+sizeof(aFrame));
  2919   2924   #endif
  2920   2925     return rc;
  2921   2926   }
         2927  +
         2928  +/*
         2929  +** This function is called as part of committing a transaction within which
         2930  +** one or more frames have been overwritten. It updates the checksums for
         2931  +** all frames written to the wal file by the current transaction starting
         2932  +** with the earliest to have been overwritten.
         2933  +**
         2934  +** SQLITE_OK is returned if successful, or an SQLite error code otherwise.
         2935  +*/
         2936  +static int walRewriteChecksums(Wal *pWal, u32 iLast){
         2937  +  const int szPage = pWal->szPage;/* Database page size */
         2938  +  int rc = SQLITE_OK;             /* Return code */
         2939  +  u8 *aBuf;                       /* Buffer to load data from wal file into */
         2940  +  u8 aFrame[WAL_FRAME_HDRSIZE];   /* Buffer to assemble frame-headers in */
         2941  +  u32 iRead;                      /* Next frame to read from wal file */
         2942  +  i64 iCksumOff;
         2943  +
         2944  +  aBuf = sqlite3_malloc(szPage + WAL_FRAME_HDRSIZE);
         2945  +  if( aBuf==0 ) return SQLITE_NOMEM;
         2946  +
         2947  +  /* Find the checksum values to use as input for the recalculating the
         2948  +  ** first checksum. If the first frame is frame 1 (implying that the current
         2949  +  ** transaction restarted the wal file), these values must be read from the
         2950  +  ** wal-file header. Otherwise, read them from the frame header of the
         2951  +  ** previous frame.  */
         2952  +  assert( pWal->iReCksum>0 );
         2953  +  if( pWal->iReCksum==1 ){
         2954  +    iCksumOff = 24;
         2955  +  }else{
         2956  +    iCksumOff = walFrameOffset(pWal->iReCksum-1, szPage) + 16;
         2957  +  }
         2958  +  rc = sqlite3OsRead(pWal->pWalFd, aBuf, sizeof(u32)*2, iCksumOff);
         2959  +  pWal->hdr.aFrameCksum[0] = sqlite3Get4byte(aBuf);
         2960  +  pWal->hdr.aFrameCksum[1] = sqlite3Get4byte(&aBuf[sizeof(u32)]);
         2961  +
         2962  +  iRead = pWal->iReCksum;
         2963  +  pWal->iReCksum = 0;
         2964  +  for(; rc==SQLITE_OK && iRead<=iLast; iRead++){
         2965  +    i64 iOff = walFrameOffset(iRead, szPage);
         2966  +    rc = sqlite3OsRead(pWal->pWalFd, aBuf, szPage+WAL_FRAME_HDRSIZE, iOff);
         2967  +    if( rc==SQLITE_OK ){
         2968  +      u32 iPgno, nDbSize;
         2969  +      iPgno = sqlite3Get4byte(aBuf);
         2970  +      nDbSize = sqlite3Get4byte(&aBuf[4]);
         2971  +
         2972  +      walEncodeFrame(pWal, iPgno, nDbSize, &aBuf[WAL_FRAME_HDRSIZE], aFrame);
         2973  +      rc = sqlite3OsWrite(pWal->pWalFd, aFrame, sizeof(aFrame), iOff);
         2974  +    }
         2975  +  }
         2976  +
         2977  +  sqlite3_free(aBuf);
         2978  +  return rc;
         2979  +}
  2922   2980   
  2923   2981   /* 
  2924   2982   ** Write a set of frames to the log. The caller must hold the write-lock
  2925   2983   ** on the log file (obtained using sqlite3WalBeginWriteTransaction()).
  2926   2984   */
  2927   2985   int sqlite3WalFrames(
  2928   2986     Wal *pWal,                      /* Wal handle to write to */
................................................................................
  2936   2994     u32 iFrame;                     /* Next frame address */
  2937   2995     PgHdr *p;                       /* Iterator to run through pList with. */
  2938   2996     PgHdr *pLast = 0;               /* Last frame in list */
  2939   2997     int nExtra = 0;                 /* Number of extra copies of last page */
  2940   2998     int szFrame;                    /* The size of a single frame */
  2941   2999     i64 iOffset;                    /* Next byte to write in WAL file */
  2942   3000     WalWriter w;                    /* The writer */
         3001  +  u32 iFirst = 0;                 /* First frame that may be overwritten */
         3002  +  WalIndexHdr *pLive;             /* Pointer to shared header */
  2943   3003   
  2944   3004     assert( pList );
  2945   3005     assert( pWal->writeLock );
  2946   3006   
  2947   3007     /* If this frame set completes a transaction, then nTruncate>0.  If
  2948   3008     ** nTruncate==0 then this frame set does not complete the transaction. */
  2949   3009     assert( (isCommit!=0)==(nTruncate!=0) );
................................................................................
  2950   3010   
  2951   3011   #if defined(SQLITE_TEST) && defined(SQLITE_DEBUG)
  2952   3012     { int cnt; for(cnt=0, p=pList; p; p=p->pDirty, cnt++){}
  2953   3013       WALTRACE(("WAL%p: frame write begin. %d frames. mxFrame=%d. %s\n",
  2954   3014                 pWal, cnt, pWal->hdr.mxFrame, isCommit ? "Commit" : "Spill"));
  2955   3015     }
  2956   3016   #endif
         3017  +
         3018  +  pLive = (WalIndexHdr*)walIndexHdr(pWal);
         3019  +  if( memcmp(&pWal->hdr, (void *)pLive, sizeof(WalIndexHdr))!=0 ){
         3020  +    iFirst = pLive->mxFrame+1;
         3021  +  }
  2957   3022   
  2958   3023     /* See if it is possible to write these frames into the start of the
  2959   3024     ** log file, instead of appending to it at pWal->hdr.mxFrame.
  2960   3025     */
  2961   3026     if( SQLITE_OK!=(rc = walRestartLog(pWal)) ){
  2962   3027       return rc;
  2963   3028     }
................................................................................
  3022   3087     }
  3023   3088   #endif
  3024   3089   
  3025   3090   
  3026   3091     /* Write all frames into the log file exactly once */
  3027   3092     for(p=pList; p; p=p->pDirty){
  3028   3093       int nDbSize;   /* 0 normally.  Positive == commit flag */
         3094  +
         3095  +    /* Check if this page has already been written into the wal file by
         3096  +    ** the current transaction. If so, overwrite the existing frame and
         3097  +    ** set Wal.writeLock to WAL_WRITELOCK_RECKSUM - indicating that 
         3098  +    ** checksums must be recomputed when the transaction is committed.  */
         3099  +    if( iFirst && (p->pDirty || isCommit==0) ){
         3100  +      u32 iWrite = 0;
         3101  +      VVA_ONLY(rc =) sqlite3WalFindFrame(pWal, p->pgno, &iWrite);
         3102  +      assert( rc==SQLITE_OK || iWrite==0 );
         3103  +      if( iWrite>=iFirst ){
         3104  +        i64 iOff = walFrameOffset(iWrite, szPage) + WAL_FRAME_HDRSIZE;
         3105  +        if( pWal->iReCksum==0 || iWrite<pWal->iReCksum ){
         3106  +          pWal->iReCksum = iWrite;
         3107  +        }
         3108  +        rc = sqlite3OsWrite(pWal->pWalFd, p->pData, szPage, iOff);
         3109  +        if( rc ) return rc;
         3110  +        p->flags &= ~PGHDR_WAL_APPEND;
         3111  +        continue;
         3112  +      }
         3113  +    }
         3114  +
  3029   3115       iFrame++;
  3030   3116       assert( iOffset==walFrameOffset(iFrame, szPage) );
  3031   3117       nDbSize = (isCommit && p->pDirty==0) ? nTruncate : 0;
  3032   3118       rc = walWriteOneFrame(&w, p, nDbSize, iOffset);
  3033   3119       if( rc ) return rc;
  3034   3120       pLast = p;
  3035   3121       iOffset += szFrame;
         3122  +    p->flags |= PGHDR_WAL_APPEND;
         3123  +  }
         3124  +
         3125  +  /* Recalculate checksums within the wal file if required. */
         3126  +  if( isCommit && pWal->iReCksum ){
         3127  +    rc = walRewriteChecksums(pWal, iFrame);
         3128  +    if( rc ) return rc;
  3036   3129     }
  3037   3130   
  3038   3131     /* If this is the end of a transaction, then we might need to pad
  3039   3132     ** the transaction and/or sync the WAL file.
  3040   3133     **
  3041   3134     ** Padding and syncing only occur if this set of frames complete a
  3042   3135     ** transaction and if PRAGMA synchronous=FULL.  If synchronous==NORMAL
................................................................................
  3083   3176     /* Append data to the wal-index. It is not necessary to lock the 
  3084   3177     ** wal-index to do this as the SQLITE_SHM_WRITE lock held on the wal-index
  3085   3178     ** guarantees that there are no other writers, and no data that may
  3086   3179     ** be in use by existing readers is being overwritten.
  3087   3180     */
  3088   3181     iFrame = pWal->hdr.mxFrame;
  3089   3182     for(p=pList; p && rc==SQLITE_OK; p=p->pDirty){
         3183  +    if( (p->flags & PGHDR_WAL_APPEND)==0 ) continue;
  3090   3184       iFrame++;
  3091   3185       rc = walIndexAppend(pWal, iFrame, p->pgno);
  3092   3186     }
  3093   3187     while( rc==SQLITE_OK && nExtra>0 ){
  3094   3188       iFrame++;
  3095   3189       nExtra--;
  3096   3190       rc = walIndexAppend(pWal, iFrame, pLast->pgno);
................................................................................
  3195   3289       if( isChanged && pWal->pDbFd->pMethods->iVersion>=3 ){
  3196   3290         sqlite3OsUnfetch(pWal->pDbFd, 0, 0);
  3197   3291       }
  3198   3292     }
  3199   3293   
  3200   3294     /* Copy data from the log to the database file. */
  3201   3295     if( rc==SQLITE_OK ){
         3296  +
  3202   3297       if( pWal->hdr.mxFrame && walPagesize(pWal)!=nBuf ){
  3203   3298         rc = SQLITE_CORRUPT_BKPT;
  3204   3299       }else{
  3205   3300         rc = walCheckpoint(pWal, eMode2, xBusy2, pBusyArg, sync_flags, zBuf);
  3206   3301       }
  3207   3302   
  3208   3303       /* If no error occurred, set the output variables. */

Changes to test/fuzzcheck.c.

   861    861           zExpSql = argv[++i];
   862    862         }else
   863    863         if( strcmp(z,"help")==0 ){
   864    864           showHelp();
   865    865           return 0;
   866    866         }else
   867    867         if( strcmp(z,"limit-mem")==0 ){
          868  +#if !defined(SQLITE_ENABLE_MEMSYS3) && !defined(SQLITE_ENABLE_MEMSYS5)
          869  +        fatalError("the %s option requires -DSQLITE_ENABLE_MEMSYS5 or _MEMSYS3",
          870  +                   argv[i]);
          871  +#else
   868    872           if( i>=argc-1 ) fatalError("missing arguments on %s", argv[i]);
   869    873           nMem = integerValue(argv[++i]);
          874  +#endif
   870    875         }else
   871    876         if( strcmp(z,"limit-vdbe")==0 ){
   872    877           vdbeLimitFlag = 1;
   873    878         }else
   874    879         if( strcmp(z,"load-sql")==0 ){
   875    880           zInsSql = "INSERT INTO xsql(sqltext) VALUES(CAST(readfile(?1) AS text))";
   876    881           iFirstInsArg = i+1;

Changes to test/tester.tcl.

  1049   1049         if {[info exists known_error($x)]} {incr nKnown}
  1050   1050       }
  1051   1051     }
  1052   1052     if {$nKnown>0} {
  1053   1053       output2 "[expr {$nErr-$nKnown}] new errors and $nKnown known errors\
  1054   1054            out of $nTest tests"
  1055   1055     } else {
  1056         -    output2 "$nErr errors out of $nTest tests"
         1056  +    set cpuinfo {}
         1057  +    if {[catch {exec hostname} hname]==0} {set cpuinfo [string trim $hname]}
         1058  +    append cpuinfo " $::tcl_platform(os)"
         1059  +    append cpuinfo " [expr {$::tcl_platform(pointerSize)*8}]-bit"
         1060  +    append cpuinfo " [string map {E -e} $::tcl_platform(byteOrder)]"
         1061  +    output2 "SQLite [sqlite3 -sourceid]"
         1062  +    output2 "$nErr errors out of $nTest tests on $cpuinfo"
  1057   1063     }
  1058   1064     if {$nErr>$nKnown} {
  1059   1065       output2 -nonewline "!Failures on these tests:"
  1060   1066       foreach x [set_test_counter fail_list] {
  1061   1067         if {![info exists known_error($x)]} {output2 -nonewline " $x"}
  1062   1068       }
  1063   1069       output2 ""

Changes to test/vtabH.test.

    64     64   set x4 abandonint
    65     65   set x5 babble
    66     66   set x6 baboon
    67     67   set x7 backbone
    68     68   set x8 backarrow
    69     69   set x9 castle
    70     70   
    71         -db func glob gfunc
           71  +db func glob -argcount 2 gfunc
    72     72   proc gfunc {a b} {
    73     73     incr ::gfunc
    74     74     return 1
    75     75   }
    76     76   
    77         -db func like lfunc
           77  +db func like -argcount 2 lfunc
    78     78   proc lfunc {a b} {
    79     79     incr ::gfunc 100
    80     80     return 1
    81     81   }
    82     82   
    83         -db func regexp rfunc
           83  +db func regexp -argcount 2 rfunc
    84     84   proc rfunc {a b} {
    85     85     incr ::gfunc 10000
    86     86     return 1
    87     87   }
    88     88   
    89     89   foreach ::tclvar_set_omit {0 1} {
    90     90     foreach {tn expr res cnt} {

Changes to test/wal.test.

   721    721       SELECT count(*) FROM t1;
   722    722       PRAGMA integrity_check;
   723    723     }
   724    724   } {16 ok}
   725    725   do_test wal-11.6 {
   726    726     execsql COMMIT
   727    727     list [expr [file size test.db]/1024] [file size test.db-wal]
   728         -} [list 3 [wal_file_size 41 1024]]
          728  +} [list 3 [wal_file_size 40 1024]]
   729    729   do_test wal-11.7 {
   730    730     execsql { 
   731    731       SELECT count(*) FROM t1;
   732    732       PRAGMA integrity_check;
   733    733     }
   734    734   } {16 ok}
   735    735   do_test wal-11.8 {
   736    736     execsql { PRAGMA wal_checkpoint }
   737    737     list [expr [file size test.db]/1024] [file size test.db-wal]
   738         -} [list 37 [wal_file_size 41 1024]]
          738  +} [list 37 [wal_file_size 40 1024]]
   739    739   do_test wal-11.9 {
   740    740     ifcapable enable_persist_wal {
   741    741       file_control_persist_wal db 0
   742    742     }
   743    743     db close
   744    744     list [expr [file size test.db]/1024] [log_deleted test.db-wal]
   745    745   } {37 1}
   746    746   sqlite3_wal db test.db
   747         -set nWal 39
   748         -if {[permutation]!="mmap"} {set nWal 37}
   749         -ifcapable !mmap {set nWal 37}
          747  +
          748  +# After adding the capability of WAL to overwrite prior uncommitted
          749  +# frame in the WAL-file with revised content, the size of the WAL file
          750  +# following cache-spill is smaller.
          751  +#
          752  +#set nWal 39
          753  +#if {[permutation]!="mmap"} {set nWal 37}
          754  +#ifcapable !mmap {set nWal 37}
          755  +set nWal 34
          756  +
   750    757   ifcapable enable_persist_wal {
   751    758     file_control_persist_wal db 0
   752    759   }
   753    760   do_test wal-11.10 {
   754    761     execsql {
   755    762       PRAGMA cache_size = 10;
   756    763       BEGIN;

Added test/waloverwrite.test.

            1  +# 2010 May 5
            2  +#
            3  +# The author disclaims copyright to this source code.  In place of
            4  +# a legal notice, here is a blessing:
            5  +#
            6  +#    May you do good and not evil.
            7  +#    May you find forgiveness for yourself and forgive others.
            8  +#    May you share freely, never taking more than you give.
            9  +#
           10  +#***********************************************************************
           11  +# This file implements regression tests for SQLite library.  The
           12  +# focus of this file is testing the operation of the library in
           13  +# "PRAGMA journal_mode=WAL" mode.
           14  +#
           15  +
           16  +set testdir [file dirname $argv0]
           17  +source $testdir/tester.tcl
           18  +source $testdir/wal_common.tcl
           19  +set testprefix waloverwrite
           20  +
           21  +ifcapable !wal {finish_test ; return }
           22  +
           23  +# Simple test:
           24  +#
           25  +# Test cases *.1 - *.6:
           26  +#
           27  +#   + Create a database of blobs roughly 50 pages in size.
           28  +#
           29  +#   + Set the db cache size to something much smaller than this (5 pages)
           30  +#
           31  +#   + Within a transaction, loop through the set of blobs 5 times. Update
           32  +#      each blob as it is visited.
           33  +#
           34  +#   + Test that the wal file is roughly 50 pages in size - even though many
           35  +#      database pages have been written to it multiple times.
           36  +#
           37  +#   + Take a copy of the database and wal file. Test that recovery can
           38  +#     be run on it.
           39  +#
           40  +# Test cases *.7 - *.9:
           41  +#
           42  +#   + Same thing, but before committing the statement transaction open
           43  +#     a SAVEPOINT, update the blobs another 5 times, then roll it back.
           44  +#
           45  +#   + Check that if recovery is run on the resulting wal file, the rolled
           46  +#     back changes from within the SAVEPOINT are not present in the db.
           47  +#
           48  +# The above is run twice - once where the wal file is empty at the start of
           49  +# step 3 (tn==1) and once where it already contains a transaction (tn==2).
           50  +#
           51  +foreach {tn xtra} {
           52  +  1 {}
           53  +  2 { UPDATE t1 SET y = randomblob(799) WHERE x=4 }
           54  +} {
           55  +  reset_db
           56  +  do_execsql_test 1.$tn.0 {
           57  +    CREATE TABLE t1(x, y);
           58  +    CREATE TABLE t2(x, y);
           59  +    CREATE INDEX i1y ON t1(y);
           60  +  
           61  +    WITH cnt(i) AS (
           62  +      SELECT 1 UNION ALL SELECT i+1 FROM cnt WHERE i<20
           63  +    )
           64  +    INSERT INTO t1 SELECT i, randomblob(800) FROM cnt;
           65  +  } {}
           66  +  
           67  +  do_test 1.$tn.1 {
           68  +    set nPg [db one { PRAGMA page_count } ]
           69  +    expr $nPg>40 && $nPg<50
           70  +  } {1}
           71  +  
           72  +  do_test 1.$tn.2 {
           73  +    db close
           74  +    sqlite3 db test.db
           75  +  
           76  +    execsql {PRAGMA journal_mode = wal}
           77  +    execsql {PRAGMA cache_size = 5}
           78  +    execsql $xtra
           79  +  
           80  +    db transaction {
           81  +      for {set i 0} {$i < 5} {incr i} {
           82  +        foreach x [db eval {SELECT x FROM t1}] {
           83  +          execsql { UPDATE t1 SET y = randomblob(799) WHERE x=$x }
           84  +        }
           85  +      }
           86  +    }
           87  +  
           88  +    set nPg [wal_frame_count test.db-wal 1024]
           89  +    expr $nPg>40 && $nPg<60
           90  +  } {1}
           91  +  
           92  +  do_execsql_test 1.$tn.3 { PRAGMA integrity_check } ok
           93  +  
           94  +  do_test 1.$tn.4 {
           95  +    forcedelete test.db2 test.db2-wal
           96  +    forcecopy test.db test.db2
           97  +    sqlite3 db2 test.db2
           98  +    execsql { SELECT sum(length(y)) FROM t1 } db2
           99  +  } [expr 20*800]
          100  +  
          101  +  do_test 1.$tn.5 {
          102  +    db2 close
          103  +    forcecopy test.db test.db2
          104  +    forcecopy test.db-wal test.db2-wal
          105  +    sqlite3 db2 test.db2
          106  +    execsql { SELECT sum(length(y)) FROM t1 } db2
          107  +  } [expr 20*799]
          108  +  
          109  +  do_test 1.$tn.6 {
          110  +    execsql { PRAGMA integrity_check } db2
          111  +  } ok
          112  +  db2 close
          113  +
          114  +  do_test 1.$tn.7 {
          115  +    execsql { PRAGMA wal_checkpoint }
          116  +    db transaction {
          117  +      for {set i 0} {$i < 1} {incr i} {
          118  +        foreach x [db eval {SELECT x FROM t1}] {
          119  +          execsql { UPDATE t1 SET y = randomblob(798) WHERE x=$x }
          120  +        }
          121  +      }
          122  +
          123  +      execsql {
          124  +        WITH cnt(i) AS (SELECT 1 UNION ALL SELECT i+1 FROM cnt WHERE i<20)
          125  +        INSERT INTO t2 SELECT i, randomblob(800) FROM cnt;
          126  +      }
          127  +
          128  +      execsql {SAVEPOINT abc}
          129  +      for {set i 0} {$i < 5} {incr i} {
          130  +        foreach x [db eval {SELECT x FROM t1}] {
          131  +          execsql { UPDATE t1 SET y = randomblob(797) WHERE x=$x }
          132  +        }
          133  +      }
          134  +      breakpoint
          135  +      execsql {ROLLBACK TO abc}
          136  +
          137  +    }
          138  +
          139  +    set nPg [wal_frame_count test.db-wal 1024]
          140  +    expr $nPg>55 && $nPg<75
          141  +  } {1}
          142  +
          143  +  do_test 1.$tn.8 {
          144  +    forcedelete test.db2 test.db2-wal
          145  +    forcecopy test.db test.db2
          146  +    sqlite3 db2 test.db2
          147  +    execsql { SELECT sum(length(y)) FROM t1 } db2
          148  +  } [expr 20*799]
          149  +
          150  +  do_test 1.$tn.9 {
          151  +    db2 close
          152  +    forcecopy test.db-wal test.db2-wal
          153  +    sqlite3 db2 test.db2
          154  +    execsql { SELECT sum(length(y)) FROM t1 } db2
          155  +  } [expr 20*798]
          156  +
          157  +  do_test 1.$tn.9 {
          158  +    execsql { PRAGMA integrity_check } db2
          159  +  } ok
          160  +  db2 close
          161  +}
          162  +
          163  +finish_test
          164  +