/ Check-in [d9eef5b0]
Login

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

Overview
Comment:Merge the latest changes from sessions.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | rtree-enhancements
Files: files | file ages | folders
SHA1:d9eef5b03c7c4bb69c11eda41152ee81aed1cac7
User & Date: drh 2014-04-18 01:14:46
Context
2014-04-18
01:37
Further improvements to the RTREE_DECODE_COORD() method, to take advantage of known processor byte orders when available. This makes the code 3% faster, according to valgrind. Also add test cases to make sure the on-disk representation is correct. check-in: 6f3e94f4 user: drh tags: rtree-enhancements
01:14
Merge the latest changes from sessions. check-in: d9eef5b0 user: drh tags: rtree-enhancements
01:10
Merge recent trunk changes into sessions. check-in: 95e77efe user: drh tags: sessions
2014-04-17
23:23
Performance optimization on byte-swapping in R-Tree. check-in: 444084fd user: drh tags: rtree-enhancements
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/alter.c.

   112    112     unsigned char const *zNew = sqlite3_value_text(argv[2]);
   113    113   
   114    114     unsigned const char *z;         /* Pointer to token */
   115    115     int n;                          /* Length of token z */
   116    116     int token;                      /* Type of token */
   117    117   
   118    118     UNUSED_PARAMETER(NotUsed);
          119  +  if( zInput==0 || zOld==0 ) return;
   119    120     for(z=zInput; *z; z=z+n){
   120    121       n = sqlite3GetToken(z, &token);
   121    122       if( token==TK_REFERENCES ){
   122    123         char *zParent;
   123    124         do {
   124    125           z += n;
   125    126           n = sqlite3GetToken(z, &token);

Changes to src/btree.c.

   442    442   */
   443    443   #ifdef SQLITE_DEBUG
   444    444   static int cursorHoldsMutex(BtCursor *p){
   445    445     return sqlite3_mutex_held(p->pBt->mutex);
   446    446   }
   447    447   #endif
   448    448   
   449         -
   450         -#ifndef SQLITE_OMIT_INCRBLOB
   451    449   /*
   452         -** Invalidate the overflow page-list cache for cursor pCur, if any.
          450  +** Invalidate the overflow cache of the cursor passed as the first argument.
          451  +** on the shared btree structure pBt.
   453    452   */
   454         -static void invalidateOverflowCache(BtCursor *pCur){
   455         -  assert( cursorHoldsMutex(pCur) );
   456         -  sqlite3_free(pCur->aOverflow);
   457         -  pCur->aOverflow = 0;
   458         -}
          453  +#define invalidateOverflowCache(pCur) (pCur->curFlags &= ~BTCF_ValidOvfl)
   459    454   
   460    455   /*
   461    456   ** Invalidate the overflow page-list cache for all cursors opened
   462    457   ** on the shared btree structure pBt.
   463    458   */
   464    459   static void invalidateAllOverflowCache(BtShared *pBt){
   465    460     BtCursor *p;
   466    461     assert( sqlite3_mutex_held(pBt->mutex) );
   467    462     for(p=pBt->pCursor; p; p=p->pNext){
   468    463       invalidateOverflowCache(p);
   469    464     }
   470    465   }
   471    466   
          467  +#ifndef SQLITE_OMIT_INCRBLOB
   472    468   /*
   473    469   ** This function is called before modifying the contents of a table
   474    470   ** to invalidate any incrblob cursors that are open on the
   475    471   ** row or one of the rows being modified.
   476    472   **
   477    473   ** If argument isClearTable is true, then the entire contents of the
   478    474   ** table is about to be deleted. In this case invalidate all incrblob
................................................................................
   487    483     i64 iRow,               /* The rowid that might be changing */
   488    484     int isClearTable        /* True if all rows are being deleted */
   489    485   ){
   490    486     BtCursor *p;
   491    487     BtShared *pBt = pBtree->pBt;
   492    488     assert( sqlite3BtreeHoldsMutex(pBtree) );
   493    489     for(p=pBt->pCursor; p; p=p->pNext){
   494         -    if( p->isIncrblobHandle && (isClearTable || p->info.nKey==iRow) ){
          490  +    if( (p->curFlags & BTCF_Incrblob)!=0 && (isClearTable || p->info.nKey==iRow) ){
   495    491         p->eState = CURSOR_INVALID;
   496    492       }
   497    493     }
   498    494   }
   499    495   
   500    496   #else
   501         -  /* Stub functions when INCRBLOB is omitted */
   502         -  #define invalidateOverflowCache(x)
   503         -  #define invalidateAllOverflowCache(x)
          497  +  /* Stub function when INCRBLOB is omitted */
   504    498     #define invalidateIncrblobCursors(x,y,z)
   505    499   #endif /* SQLITE_OMIT_INCRBLOB */
   506    500   
   507    501   /*
   508    502   ** Set bit pgno of the BtShared.pHasContent bitvec. This is called 
   509    503   ** when a page that previously contained data becomes a free-list leaf 
   510    504   ** page.
................................................................................
  2559   2553   ** is capable of reading or writing to the databse.  Cursors that
  2560   2554   ** have been tripped into the CURSOR_FAULT state are not counted.
  2561   2555   */
  2562   2556   static int countValidCursors(BtShared *pBt, int wrOnly){
  2563   2557     BtCursor *pCur;
  2564   2558     int r = 0;
  2565   2559     for(pCur=pBt->pCursor; pCur; pCur=pCur->pNext){
  2566         -    if( (wrOnly==0 || pCur->wrFlag) && pCur->eState!=CURSOR_FAULT ) r++; 
         2560  +    if( (wrOnly==0 || (pCur->curFlags & BTCF_WriteFlag)!=0)
         2561  +     && pCur->eState!=CURSOR_FAULT ) r++; 
  2567   2562     }
  2568   2563     return r;
  2569   2564   }
  2570   2565   #endif
  2571   2566   
  2572   2567   /*
  2573   2568   ** If there are no outstanding cursors and we are not in the middle
................................................................................
  3634   3629     /* Now that no other errors can occur, finish filling in the BtCursor
  3635   3630     ** variables and link the cursor into the BtShared list.  */
  3636   3631     pCur->pgnoRoot = (Pgno)iTable;
  3637   3632     pCur->iPage = -1;
  3638   3633     pCur->pKeyInfo = pKeyInfo;
  3639   3634     pCur->pBtree = p;
  3640   3635     pCur->pBt = pBt;
  3641         -  pCur->wrFlag = (u8)wrFlag;
         3636  +  assert( wrFlag==0 || wrFlag==BTCF_WriteFlag );
         3637  +  pCur->curFlags = wrFlag;
  3642   3638     pCur->pNext = pBt->pCursor;
  3643   3639     if( pCur->pNext ){
  3644   3640       pCur->pNext->pPrev = pCur;
  3645   3641     }
  3646   3642     pBt->pCursor = pCur;
  3647   3643     pCur->eState = CURSOR_INVALID;
  3648   3644     return SQLITE_OK;
................................................................................
  3704   3700       if( pCur->pNext ){
  3705   3701         pCur->pNext->pPrev = pCur->pPrev;
  3706   3702       }
  3707   3703       for(i=0; i<=pCur->iPage; i++){
  3708   3704         releasePage(pCur->apPage[i]);
  3709   3705       }
  3710   3706       unlockBtreeIfUnused(pBt);
  3711         -    invalidateOverflowCache(pCur);
         3707  +    sqlite3DbFree(pBtree->db, pCur->aOverflow);
  3712   3708       /* sqlite3_free(pCur); */
  3713   3709       sqlite3BtreeLeave(pBtree);
  3714   3710     }
  3715   3711     return SQLITE_OK;
  3716   3712   }
  3717   3713   
  3718   3714   /*
................................................................................
  3743   3739   #endif
  3744   3740   #ifdef _MSC_VER
  3745   3741     /* Use a real function in MSVC to work around bugs in that compiler. */
  3746   3742     static void getCellInfo(BtCursor *pCur){
  3747   3743       if( pCur->info.nSize==0 ){
  3748   3744         int iPage = pCur->iPage;
  3749   3745         btreeParseCell(pCur->apPage[iPage],pCur->aiIdx[iPage],&pCur->info);
  3750         -      pCur->validNKey = 1;
         3746  +      pCur->curFlags |= BTCF_ValidNKey;
  3751   3747       }else{
  3752   3748         assertCellInfo(pCur);
  3753   3749       }
  3754   3750     }
  3755   3751   #else /* if not _MSC_VER */
  3756   3752     /* Use a macro in all other compilers so that the function is inlined */
  3757   3753   #define getCellInfo(pCur)                                                      \
  3758   3754     if( pCur->info.nSize==0 ){                                                   \
  3759   3755       int iPage = pCur->iPage;                                                   \
  3760         -    btreeParseCell(pCur->apPage[iPage],pCur->aiIdx[iPage],&pCur->info); \
  3761         -    pCur->validNKey = 1;                                                       \
         3756  +    btreeParseCell(pCur->apPage[iPage],pCur->aiIdx[iPage],&pCur->info);        \
         3757  +    pCur->curFlags |= BTCF_ValidNKey;                                          \
  3762   3758     }else{                                                                       \
  3763   3759       assertCellInfo(pCur);                                                      \
  3764   3760     }
  3765   3761   #endif /* _MSC_VER */
  3766   3762   
  3767   3763   #ifndef NDEBUG  /* The next routine used only within assert() statements */
  3768   3764   /*
................................................................................
  3925   3921       memcpy(pBuf, pPayload, nByte);
  3926   3922     }
  3927   3923     return SQLITE_OK;
  3928   3924   }
  3929   3925   
  3930   3926   /*
  3931   3927   ** This function is used to read or overwrite payload information
  3932         -** for the entry that the pCur cursor is pointing to. If the eOp
  3933         -** parameter is 0, this is a read operation (data copied into
  3934         -** buffer pBuf). If it is non-zero, a write (data copied from
  3935         -** buffer pBuf).
         3928  +** for the entry that the pCur cursor is pointing to. The eOp
         3929  +** argument is interpreted as follows:
         3930  +**
         3931  +**   0: The operation is a read. Populate the overflow cache.
         3932  +**   1: The operation is a write. Populate the overflow cache.
         3933  +**   2: The operation is a read. Do not populate the overflow cache.
  3936   3934   **
  3937   3935   ** A total of "amt" bytes are read or written beginning at "offset".
  3938   3936   ** Data is read to or from the buffer pBuf.
  3939   3937   **
  3940   3938   ** The content being read or written might appear on the main page
  3941   3939   ** or be scattered out on multiple overflow pages.
  3942   3940   **
  3943         -** If the BtCursor.isIncrblobHandle flag is set, and the current
  3944         -** cursor entry uses one or more overflow pages, this function
  3945         -** allocates space for and lazily popluates the overflow page-list 
  3946         -** cache array (BtCursor.aOverflow). Subsequent calls use this
  3947         -** cache to make seeking to the supplied offset more efficient.
         3941  +** If the current cursor entry uses one or more overflow pages and the
         3942  +** eOp argument is not 2, this function may allocate space for and lazily 
         3943  +** popluates the overflow page-list cache array (BtCursor.aOverflow). 
         3944  +** Subsequent calls use this cache to make seeking to the supplied offset 
         3945  +** more efficient.
  3948   3946   **
  3949   3947   ** Once an overflow page-list cache has been allocated, it may be
  3950   3948   ** invalidated if some other cursor writes to the same table, or if
  3951   3949   ** the cursor is moved to a different row. Additionally, in auto-vacuum
  3952   3950   ** mode, the following events may invalidate an overflow page-list cache.
  3953   3951   **
  3954   3952   **   * An incremental vacuum,
................................................................................
  3964   3962   ){
  3965   3963     unsigned char *aPayload;
  3966   3964     int rc = SQLITE_OK;
  3967   3965     u32 nKey;
  3968   3966     int iIdx = 0;
  3969   3967     MemPage *pPage = pCur->apPage[pCur->iPage]; /* Btree page of current entry */
  3970   3968     BtShared *pBt = pCur->pBt;                  /* Btree this cursor belongs to */
         3969  +#ifdef SQLITE_DIRECT_OVERFLOW_READ
         3970  +  int bEnd;                                   /* True if reading to end of data */
         3971  +#endif
  3971   3972   
  3972   3973     assert( pPage );
  3973   3974     assert( pCur->eState==CURSOR_VALID );
  3974   3975     assert( pCur->aiIdx[pCur->iPage]<pPage->nCell );
  3975   3976     assert( cursorHoldsMutex(pCur) );
         3977  +  assert( eOp!=2 || offset==0 );      /* Always start from beginning for eOp==2 */
  3976   3978   
  3977   3979     getCellInfo(pCur);
  3978   3980     aPayload = pCur->info.pCell + pCur->info.nHeader;
  3979   3981     nKey = (pPage->intKey ? 0 : (int)pCur->info.nKey);
         3982  +#ifdef SQLITE_DIRECT_OVERFLOW_READ
         3983  +  bEnd = (offset+amt==nKey+pCur->info.nData);
         3984  +#endif
  3980   3985   
  3981   3986     if( NEVER(offset+amt > nKey+pCur->info.nData) 
  3982   3987      || &aPayload[pCur->info.nLocal] > &pPage->aData[pBt->usableSize]
  3983   3988     ){
  3984   3989       /* Trying to read or write past the end of the data is an error */
  3985   3990       return SQLITE_CORRUPT_BKPT;
  3986   3991     }
................................................................................
  3987   3992   
  3988   3993     /* Check if data must be read/written to/from the btree page itself. */
  3989   3994     if( offset<pCur->info.nLocal ){
  3990   3995       int a = amt;
  3991   3996       if( a+offset>pCur->info.nLocal ){
  3992   3997         a = pCur->info.nLocal - offset;
  3993   3998       }
  3994         -    rc = copyPayload(&aPayload[offset], pBuf, a, eOp, pPage->pDbPage);
         3999  +    rc = copyPayload(&aPayload[offset], pBuf, a, (eOp & 0x01), pPage->pDbPage);
  3995   4000       offset = 0;
  3996   4001       pBuf += a;
  3997   4002       amt -= a;
  3998   4003     }else{
  3999   4004       offset -= pCur->info.nLocal;
  4000   4005     }
  4001   4006   
  4002   4007     if( rc==SQLITE_OK && amt>0 ){
  4003   4008       const u32 ovflSize = pBt->usableSize - 4;  /* Bytes content per ovfl page */
  4004   4009       Pgno nextPage;
  4005   4010   
  4006   4011       nextPage = get4byte(&aPayload[pCur->info.nLocal]);
  4007   4012   
  4008         -#ifndef SQLITE_OMIT_INCRBLOB
  4009         -    /* If the isIncrblobHandle flag is set and the BtCursor.aOverflow[]
  4010         -    ** has not been allocated, allocate it now. The array is sized at
  4011         -    ** one entry for each overflow page in the overflow chain. The
  4012         -    ** page number of the first overflow page is stored in aOverflow[0],
  4013         -    ** etc. A value of 0 in the aOverflow[] array means "not yet known"
  4014         -    ** (the cache is lazily populated).
         4013  +    /* If the BtCursor.aOverflow[] has not been allocated, allocate it now.
         4014  +    ** Except, do not allocate aOverflow[] for eOp==2.
         4015  +    **
         4016  +    ** The aOverflow[] array is sized at one entry for each overflow page
         4017  +    ** in the overflow chain. The page number of the first overflow page is
         4018  +    ** stored in aOverflow[0], etc. A value of 0 in the aOverflow[] array
         4019  +    ** means "not yet known" (the cache is lazily populated).
  4015   4020       */
  4016         -    if( pCur->isIncrblobHandle && !pCur->aOverflow ){
         4021  +    if( eOp!=2 && (pCur->curFlags & BTCF_ValidOvfl)==0 ){
  4017   4022         int nOvfl = (pCur->info.nPayload-pCur->info.nLocal+ovflSize-1)/ovflSize;
  4018         -      pCur->aOverflow = (Pgno *)sqlite3MallocZero(sizeof(Pgno)*nOvfl);
  4019         -      /* nOvfl is always positive.  If it were zero, fetchPayload would have
  4020         -      ** been used instead of this routine. */
  4021         -      if( ALWAYS(nOvfl) && !pCur->aOverflow ){
  4022         -        rc = SQLITE_NOMEM;
         4023  +      if( nOvfl>pCur->nOvflAlloc ){
         4024  +        Pgno *aNew = (Pgno*)sqlite3DbRealloc(
         4025  +            pCur->pBtree->db, pCur->aOverflow, nOvfl*2*sizeof(Pgno)
         4026  +        );
         4027  +        if( aNew==0 ){
         4028  +          rc = SQLITE_NOMEM;
         4029  +        }else{
         4030  +          pCur->nOvflAlloc = nOvfl*2;
         4031  +          pCur->aOverflow = aNew;
         4032  +        }
         4033  +      }
         4034  +      if( rc==SQLITE_OK ){
         4035  +        memset(pCur->aOverflow, 0, nOvfl*sizeof(Pgno));
         4036  +        pCur->curFlags |= BTCF_ValidOvfl;
  4023   4037         }
  4024   4038       }
  4025   4039   
  4026   4040       /* If the overflow page-list cache has been allocated and the
  4027   4041       ** entry for the first required overflow page is valid, skip
  4028   4042       ** directly to it.
  4029   4043       */
  4030         -    if( pCur->aOverflow && pCur->aOverflow[offset/ovflSize] ){
         4044  +    if( (pCur->curFlags & BTCF_ValidOvfl)!=0 && pCur->aOverflow[offset/ovflSize] ){
  4031   4045         iIdx = (offset/ovflSize);
  4032   4046         nextPage = pCur->aOverflow[iIdx];
  4033   4047         offset = (offset%ovflSize);
  4034   4048       }
  4035         -#endif
  4036   4049   
  4037   4050       for( ; rc==SQLITE_OK && amt>0 && nextPage; iIdx++){
  4038   4051   
  4039         -#ifndef SQLITE_OMIT_INCRBLOB
  4040   4052         /* If required, populate the overflow page-list cache. */
  4041         -      if( pCur->aOverflow ){
         4053  +      if( (pCur->curFlags & BTCF_ValidOvfl)!=0 ){
  4042   4054           assert(!pCur->aOverflow[iIdx] || pCur->aOverflow[iIdx]==nextPage);
  4043   4055           pCur->aOverflow[iIdx] = nextPage;
  4044   4056         }
  4045         -#endif
  4046   4057   
  4047   4058         if( offset>=ovflSize ){
  4048   4059           /* The only reason to read this page is to obtain the page
  4049   4060           ** number for the next page in the overflow chain. The page
  4050   4061           ** data is not required. So first try to lookup the overflow
  4051   4062           ** page-list cache, if any, then fall back to the getOverflowPage()
  4052   4063           ** function.
         4064  +        **
         4065  +        ** Note that the aOverflow[] array must be allocated because eOp!=2
         4066  +        ** here.  If eOp==2, then offset==0 and this branch is never taken.
  4053   4067           */
  4054         -#ifndef SQLITE_OMIT_INCRBLOB
  4055         -        if( pCur->aOverflow && pCur->aOverflow[iIdx+1] ){
         4068  +        assert( eOp!=2 );
         4069  +        assert( pCur->curFlags & BTCF_ValidOvfl );
         4070  +        if( pCur->aOverflow[iIdx+1] ){
  4056   4071             nextPage = pCur->aOverflow[iIdx+1];
  4057         -        } else 
  4058         -#endif
         4072  +        }else{
  4059   4073             rc = getOverflowPage(pBt, nextPage, 0, &nextPage);
         4074  +        }
  4060   4075           offset -= ovflSize;
  4061   4076         }else{
  4062   4077           /* Need to read this page properly. It contains some of the
  4063   4078           ** range of data that is being read (eOp==0) or written (eOp!=0).
  4064   4079           */
  4065   4080   #ifdef SQLITE_DIRECT_OVERFLOW_READ
  4066   4081           sqlite3_file *fd;
................................................................................
  4074   4089           /* If all the following are true:
  4075   4090           **
  4076   4091           **   1) this is a read operation, and 
  4077   4092           **   2) data is required from the start of this overflow page, and
  4078   4093           **   3) the database is file-backed, and
  4079   4094           **   4) there is no open write-transaction, and
  4080   4095           **   5) the database is not a WAL database,
         4096  +        **   6) all data from the page is being read.
  4081   4097           **
  4082   4098           ** then data can be read directly from the database file into the
  4083   4099           ** output buffer, bypassing the page-cache altogether. This speeds
  4084   4100           ** up loading large records that span many overflow pages.
  4085   4101           */
  4086         -        if( eOp==0                                             /* (1) */
         4102  +        if( (eOp&0x01)==0                                      /* (1) */
  4087   4103            && offset==0                                          /* (2) */
         4104  +         && (bEnd || a==ovflSize)                              /* (6) */
  4088   4105            && pBt->inTransaction==TRANS_READ                     /* (4) */
  4089   4106            && (fd = sqlite3PagerFile(pBt->pPager))->pMethods     /* (3) */
  4090   4107            && pBt->pPage1->aData[19]==0x01                       /* (5) */
  4091   4108           ){
  4092   4109             u8 aSave[4];
  4093   4110             u8 *aWrite = &pBuf[-4];
  4094   4111             memcpy(aSave, aWrite, 4);
................................................................................
  4097   4114             memcpy(aWrite, aSave, 4);
  4098   4115           }else
  4099   4116   #endif
  4100   4117   
  4101   4118           {
  4102   4119             DbPage *pDbPage;
  4103   4120             rc = sqlite3PagerAcquire(pBt->pPager, nextPage, &pDbPage,
  4104         -              (eOp==0 ? PAGER_GET_READONLY : 0)
         4121  +              ((eOp&0x01)==0 ? PAGER_GET_READONLY : 0)
  4105   4122             );
  4106   4123             if( rc==SQLITE_OK ){
  4107   4124               aPayload = sqlite3PagerGetData(pDbPage);
  4108   4125               nextPage = get4byte(aPayload);
  4109         -            rc = copyPayload(&aPayload[offset+4], pBuf, a, eOp, pDbPage);
         4126  +            rc = copyPayload(&aPayload[offset+4], pBuf, a, (eOp&0x01), pDbPage);
  4110   4127               sqlite3PagerUnref(pDbPage);
  4111   4128               offset = 0;
  4112   4129             }
  4113   4130           }
  4114   4131           amt -= a;
  4115   4132           pBuf += a;
  4116   4133         }
................................................................................
  4253   4270     assert( pCur->eState==CURSOR_VALID );
  4254   4271     assert( pCur->iPage<BTCURSOR_MAX_DEPTH );
  4255   4272     assert( pCur->iPage>=0 );
  4256   4273     if( pCur->iPage>=(BTCURSOR_MAX_DEPTH-1) ){
  4257   4274       return SQLITE_CORRUPT_BKPT;
  4258   4275     }
  4259   4276     rc = getAndInitPage(pBt, newPgno, &pNewPage,
  4260         -               pCur->wrFlag==0 ? PAGER_GET_READONLY : 0);
         4277  +               (pCur->curFlags & BTCF_WriteFlag)==0 ? PAGER_GET_READONLY : 0);
  4261   4278     if( rc ) return rc;
  4262   4279     pCur->apPage[i+1] = pNewPage;
  4263   4280     pCur->aiIdx[i+1] = 0;
  4264   4281     pCur->iPage++;
  4265   4282   
  4266   4283     pCur->info.nSize = 0;
  4267         -  pCur->validNKey = 0;
         4284  +  pCur->curFlags &= ~(BTCF_ValidNKey|BTCF_ValidOvfl);
  4268   4285     if( pNewPage->nCell<1 || pNewPage->intKey!=pCur->apPage[i]->intKey ){
  4269   4286       return SQLITE_CORRUPT_BKPT;
  4270   4287     }
  4271   4288     return SQLITE_OK;
  4272   4289   }
  4273   4290   
  4274   4291   #if 0
................................................................................
  4318   4335     );
  4319   4336   #endif
  4320   4337     testcase( pCur->aiIdx[pCur->iPage-1] > pCur->apPage[pCur->iPage-1]->nCell );
  4321   4338   
  4322   4339     releasePage(pCur->apPage[pCur->iPage]);
  4323   4340     pCur->iPage--;
  4324   4341     pCur->info.nSize = 0;
  4325         -  pCur->validNKey = 0;
         4342  +  pCur->curFlags &= ~(BTCF_ValidNKey|BTCF_ValidOvfl);
  4326   4343   }
  4327   4344   
  4328   4345   /*
  4329   4346   ** Move the cursor to point to the root page of its b-tree structure.
  4330   4347   **
  4331   4348   ** If the table has a virtual root page, then the cursor is moved to point
  4332   4349   ** to the virtual root page instead of the actual root page. A table has a
................................................................................
  4365   4382     if( pCur->iPage>=0 ){
  4366   4383       while( pCur->iPage ) releasePage(pCur->apPage[pCur->iPage--]);
  4367   4384     }else if( pCur->pgnoRoot==0 ){
  4368   4385       pCur->eState = CURSOR_INVALID;
  4369   4386       return SQLITE_OK;
  4370   4387     }else{
  4371   4388       rc = getAndInitPage(pCur->pBtree->pBt, pCur->pgnoRoot, &pCur->apPage[0],
  4372         -                        pCur->wrFlag==0 ? PAGER_GET_READONLY : 0);
         4389  +                 (pCur->curFlags & BTCF_WriteFlag)==0 ? PAGER_GET_READONLY : 0);
  4373   4390       if( rc!=SQLITE_OK ){
  4374   4391         pCur->eState = CURSOR_INVALID;
  4375   4392         return rc;
  4376   4393       }
  4377   4394       pCur->iPage = 0;
  4378   4395     }
  4379   4396     pRoot = pCur->apPage[0];
................................................................................
  4392   4409     assert( pRoot->intKey==1 || pRoot->intKey==0 );
  4393   4410     if( pRoot->isInit==0 || (pCur->pKeyInfo==0)!=pRoot->intKey ){
  4394   4411       return SQLITE_CORRUPT_BKPT;
  4395   4412     }
  4396   4413   
  4397   4414     pCur->aiIdx[0] = 0;
  4398   4415     pCur->info.nSize = 0;
  4399         -  pCur->atLast = 0;
  4400         -  pCur->validNKey = 0;
         4416  +  pCur->curFlags &= ~(BTCF_AtLast|BTCF_ValidNKey|BTCF_ValidOvfl);
  4401   4417   
  4402   4418     if( pRoot->nCell>0 ){
  4403   4419       pCur->eState = CURSOR_VALID;
  4404   4420     }else if( !pRoot->leaf ){
  4405   4421       Pgno subpage;
  4406   4422       if( pRoot->pgno!=1 ) return SQLITE_CORRUPT_BKPT;
  4407   4423       subpage = get4byte(&pRoot->aData[pRoot->hdrOffset+8]);
................................................................................
  4456   4472       pgno = get4byte(&pPage->aData[pPage->hdrOffset+8]);
  4457   4473       pCur->aiIdx[pCur->iPage] = pPage->nCell;
  4458   4474       rc = moveToChild(pCur, pgno);
  4459   4475     }
  4460   4476     if( rc==SQLITE_OK ){
  4461   4477       pCur->aiIdx[pCur->iPage] = pPage->nCell-1;
  4462   4478       pCur->info.nSize = 0;
  4463         -    pCur->validNKey = 0;
         4479  +    pCur->curFlags &= ~BTCF_ValidNKey;
  4464   4480     }
  4465   4481     return rc;
  4466   4482   }
  4467   4483   
  4468   4484   /* Move the cursor to the first entry in the table.  Return SQLITE_OK
  4469   4485   ** on success.  Set *pRes to 0 if the cursor actually points to something
  4470   4486   ** or set *pRes to 1 if the table is empty.
................................................................................
  4495   4511   int sqlite3BtreeLast(BtCursor *pCur, int *pRes){
  4496   4512     int rc;
  4497   4513    
  4498   4514     assert( cursorHoldsMutex(pCur) );
  4499   4515     assert( sqlite3_mutex_held(pCur->pBtree->db->mutex) );
  4500   4516   
  4501   4517     /* If the cursor already points to the last entry, this is a no-op. */
  4502         -  if( CURSOR_VALID==pCur->eState && pCur->atLast ){
         4518  +  if( CURSOR_VALID==pCur->eState && (pCur->curFlags & BTCF_AtLast)!=0 ){
  4503   4519   #ifdef SQLITE_DEBUG
  4504   4520       /* This block serves to assert() that the cursor really does point 
  4505   4521       ** to the last entry in the b-tree. */
  4506   4522       int ii;
  4507   4523       for(ii=0; ii<pCur->iPage; ii++){
  4508   4524         assert( pCur->aiIdx[ii]==pCur->apPage[ii]->nCell );
  4509   4525       }
................................................................................
  4518   4534       if( CURSOR_INVALID==pCur->eState ){
  4519   4535         assert( pCur->pgnoRoot==0 || pCur->apPage[pCur->iPage]->nCell==0 );
  4520   4536         *pRes = 1;
  4521   4537       }else{
  4522   4538         assert( pCur->eState==CURSOR_VALID );
  4523   4539         *pRes = 0;
  4524   4540         rc = moveToRightmost(pCur);
  4525         -      pCur->atLast = rc==SQLITE_OK ?1:0;
         4541  +      if( rc==SQLITE_OK ){
         4542  +        pCur->curFlags |= BTCF_AtLast;
         4543  +      }else{
         4544  +        pCur->curFlags &= ~BTCF_AtLast;
         4545  +      }
         4546  +   
  4526   4547       }
  4527   4548     }
  4528   4549     return rc;
  4529   4550   }
  4530   4551   
  4531   4552   /* Move the cursor so that it points to an entry near the key 
  4532   4553   ** specified by pIdxKey or intKey.   Return a success code.
................................................................................
  4569   4590     assert( cursorHoldsMutex(pCur) );
  4570   4591     assert( sqlite3_mutex_held(pCur->pBtree->db->mutex) );
  4571   4592     assert( pRes );
  4572   4593     assert( (pIdxKey==0)==(pCur->pKeyInfo==0) );
  4573   4594   
  4574   4595     /* If the cursor is already positioned at the point we are trying
  4575   4596     ** to move to, then just return without doing any work */
  4576         -  if( pCur->eState==CURSOR_VALID && pCur->validNKey 
         4597  +  if( pCur->eState==CURSOR_VALID && (pCur->curFlags & BTCF_ValidNKey)!=0
  4577   4598      && pCur->apPage[0]->intKey 
  4578   4599     ){
  4579   4600       if( pCur->info.nKey==intKey ){
  4580   4601         *pRes = 0;
  4581   4602         return SQLITE_OK;
  4582   4603       }
  4583         -    if( pCur->atLast && pCur->info.nKey<intKey ){
         4604  +    if( (pCur->curFlags & BTCF_AtLast)!=0 && pCur->info.nKey<intKey ){
  4584   4605         *pRes = -1;
  4585   4606         return SQLITE_OK;
  4586   4607       }
  4587   4608     }
  4588   4609   
  4589   4610     if( pIdxKey ){
  4590   4611       xRecordCompare = sqlite3VdbeFindCompare(pIdxKey);
................................................................................
  4643   4664             lwr = idx+1;
  4644   4665             if( lwr>upr ){ c = -1; break; }
  4645   4666           }else if( nCellKey>intKey ){
  4646   4667             upr = idx-1;
  4647   4668             if( lwr>upr ){ c = +1; break; }
  4648   4669           }else{
  4649   4670             assert( nCellKey==intKey );
  4650         -          pCur->validNKey = 1;
         4671  +          pCur->curFlags |= BTCF_ValidNKey;
  4651   4672             pCur->info.nKey = nCellKey;
  4652   4673             pCur->aiIdx[pCur->iPage] = (u16)idx;
  4653   4674             if( !pPage->leaf ){
  4654   4675               lwr = idx;
  4655   4676               goto moveto_next_layer;
  4656   4677             }else{
  4657   4678               *pRes = 0;
................................................................................
  4700   4721             nCell = (int)pCur->info.nKey;
  4701   4722             pCellKey = sqlite3Malloc( nCell );
  4702   4723             if( pCellKey==0 ){
  4703   4724               rc = SQLITE_NOMEM;
  4704   4725               goto moveto_finish;
  4705   4726             }
  4706   4727             pCur->aiIdx[pCur->iPage] = (u16)idx;
  4707         -          rc = accessPayload(pCur, 0, nCell, (unsigned char*)pCellKey, 0);
         4728  +          rc = accessPayload(pCur, 0, nCell, (unsigned char*)pCellKey, 2);
  4708   4729             if( rc ){
  4709   4730               sqlite3_free(pCellKey);
  4710   4731               goto moveto_finish;
  4711   4732             }
  4712   4733             c = xRecordCompare(nCell, pCellKey, pIdxKey, 0);
  4713   4734             sqlite3_free(pCellKey);
  4714   4735           }
................................................................................
  4747   4768       }
  4748   4769       pCur->aiIdx[pCur->iPage] = (u16)lwr;
  4749   4770       rc = moveToChild(pCur, chldPg);
  4750   4771       if( rc ) break;
  4751   4772     }
  4752   4773   moveto_finish:
  4753   4774     pCur->info.nSize = 0;
  4754         -  pCur->validNKey = 0;
         4775  +  pCur->curFlags &= ~(BTCF_ValidNKey|BTCF_ValidOvfl);
  4755   4776     return rc;
  4756   4777   }
  4757   4778   
  4758   4779   
  4759   4780   /*
  4760   4781   ** Return TRUE if the cursor is not pointing at an entry of the table.
  4761   4782   **
................................................................................
  4792   4813     MemPage *pPage;
  4793   4814   
  4794   4815     assert( cursorHoldsMutex(pCur) );
  4795   4816     assert( pRes!=0 );
  4796   4817     assert( *pRes==0 || *pRes==1 );
  4797   4818     assert( pCur->skipNext==0 || pCur->eState!=CURSOR_VALID );
  4798   4819     if( pCur->eState!=CURSOR_VALID ){
         4820  +    invalidateOverflowCache(pCur);
  4799   4821       rc = restoreCursorPosition(pCur);
  4800   4822       if( rc!=SQLITE_OK ){
  4801   4823         *pRes = 0;
  4802   4824         return rc;
  4803   4825       }
  4804   4826       if( CURSOR_INVALID==pCur->eState ){
  4805   4827         *pRes = 1;
................................................................................
  4825   4847     ** to be invalid here. This can only occur if a second cursor modifies
  4826   4848     ** the page while cursor pCur is holding a reference to it. Which can
  4827   4849     ** only happen if the database is corrupt in such a way as to link the
  4828   4850     ** page into more than one b-tree structure. */
  4829   4851     testcase( idx>pPage->nCell );
  4830   4852   
  4831   4853     pCur->info.nSize = 0;
  4832         -  pCur->validNKey = 0;
         4854  +  pCur->curFlags &= ~(BTCF_ValidNKey|BTCF_ValidOvfl);
  4833   4855     if( idx>=pPage->nCell ){
  4834   4856       if( !pPage->leaf ){
  4835   4857         rc = moveToChild(pCur, get4byte(&pPage->aData[pPage->hdrOffset+8]));
  4836   4858         if( rc ){
  4837   4859           *pRes = 0;
  4838   4860           return rc;
  4839   4861         }
................................................................................
  4886   4908     int rc;
  4887   4909     MemPage *pPage;
  4888   4910   
  4889   4911     assert( cursorHoldsMutex(pCur) );
  4890   4912     assert( pRes!=0 );
  4891   4913     assert( *pRes==0 || *pRes==1 );
  4892   4914     assert( pCur->skipNext==0 || pCur->eState!=CURSOR_VALID );
  4893         -  pCur->atLast = 0;
         4915  +  pCur->curFlags &= ~(BTCF_AtLast|BTCF_ValidOvfl);
  4894   4916     if( pCur->eState!=CURSOR_VALID ){
  4895   4917       if( ALWAYS(pCur->eState>=CURSOR_REQUIRESEEK) ){
  4896   4918         rc = btreeRestoreCursorPosition(pCur);
  4897   4919         if( rc!=SQLITE_OK ){
  4898   4920           *pRes = 0;
  4899   4921           return rc;
  4900   4922         }
................................................................................
  4931   4953           pCur->eState = CURSOR_INVALID;
  4932   4954           *pRes = 1;
  4933   4955           return SQLITE_OK;
  4934   4956         }
  4935   4957         moveToParent(pCur);
  4936   4958       }
  4937   4959       pCur->info.nSize = 0;
  4938         -    pCur->validNKey = 0;
         4960  +    pCur->curFlags &= ~(BTCF_ValidNKey|BTCF_ValidOvfl);
  4939   4961   
  4940   4962       pCur->aiIdx[pCur->iPage]--;
  4941   4963       pPage = pCur->apPage[pCur->iPage];
  4942   4964       if( pPage->intKey && !pPage->leaf ){
  4943   4965         rc = sqlite3BtreePrevious(pCur, pRes);
  4944   4966       }else{
  4945   4967         rc = SQLITE_OK;
................................................................................
  6956   6978   
  6957   6979     if( pCur->eState==CURSOR_FAULT ){
  6958   6980       assert( pCur->skipNext!=SQLITE_OK );
  6959   6981       return pCur->skipNext;
  6960   6982     }
  6961   6983   
  6962   6984     assert( cursorHoldsMutex(pCur) );
  6963         -  assert( pCur->wrFlag && pBt->inTransaction==TRANS_WRITE
         6985  +  assert( (pCur->curFlags & BTCF_WriteFlag)!=0 && pBt->inTransaction==TRANS_WRITE
  6964   6986                 && (pBt->btsFlags & BTS_READ_ONLY)==0 );
  6965   6987     assert( hasSharedCacheTableLock(p, pCur->pgnoRoot, pCur->pKeyInfo!=0, 2) );
  6966   6988   
  6967   6989     /* Assert that the caller has been consistent. If this cursor was opened
  6968   6990     ** expecting an index b-tree, then the caller should be inserting blob
  6969   6991     ** keys with no associated data. If the cursor was opened expecting an
  6970   6992     ** intkey table, the caller should be inserting integer keys with a
................................................................................
  6989   7011       /* If this is an insert into a table b-tree, invalidate any incrblob 
  6990   7012       ** cursors open on the row being replaced */
  6991   7013       invalidateIncrblobCursors(p, nKey, 0);
  6992   7014   
  6993   7015       /* If the cursor is currently on the last row and we are appending a
  6994   7016       ** new row onto the end, set the "loc" to avoid an unnecessary btreeMoveto()
  6995   7017       ** call */
  6996         -    if( pCur->validNKey && nKey>0 && pCur->info.nKey==nKey-1 ){
         7018  +    if( (pCur->curFlags&BTCF_ValidNKey)!=0 && nKey>0 && pCur->info.nKey==nKey-1 ){
  6997   7019         loc = -1;
  6998   7020       }
  6999   7021     }
  7000   7022   
  7001   7023     if( !loc ){
  7002   7024       rc = btreeMoveto(pCur, pKey, nKey, appendBias, &loc);
  7003   7025       if( rc ) return rc;
................................................................................
  7042   7064       assert( pPage->leaf );
  7043   7065     }
  7044   7066     insertCell(pPage, idx, newCell, szNew, 0, 0, &rc);
  7045   7067     assert( rc!=SQLITE_OK || pPage->nCell>0 || pPage->nOverflow>0 );
  7046   7068   
  7047   7069     /* If no error has occurred and pPage has an overflow cell, call balance() 
  7048   7070     ** to redistribute the cells within the tree. Since balance() may move
  7049         -  ** the cursor, zero the BtCursor.info.nSize and BtCursor.validNKey
         7071  +  ** the cursor, zero the BtCursor.info.nSize and BTCF_ValidNKey
  7050   7072     ** variables.
  7051   7073     **
  7052   7074     ** Previous versions of SQLite called moveToRoot() to move the cursor
  7053   7075     ** back to the root page as balance() used to invalidate the contents
  7054   7076     ** of BtCursor.apPage[] and BtCursor.aiIdx[]. Instead of doing that,
  7055   7077     ** set the cursor state to "invalid". This makes common insert operations
  7056   7078     ** slightly faster.
................................................................................
  7062   7084     ** the b-tree if possible. If the cursor is left pointing to the last
  7063   7085     ** entry in the table, and the next row inserted has an integer key
  7064   7086     ** larger than the largest existing key, it is possible to insert the
  7065   7087     ** row without seeking the cursor. This can be a big performance boost.
  7066   7088     */
  7067   7089     pCur->info.nSize = 0;
  7068   7090     if( rc==SQLITE_OK && pPage->nOverflow ){
  7069         -    pCur->validNKey = 0;
         7091  +    pCur->curFlags &= ~(BTCF_ValidNKey);
  7070   7092       rc = balance(pCur);
  7071   7093   
  7072   7094       /* Must make sure nOverflow is reset to zero even if the balance()
  7073   7095       ** fails. Internal data structure corruption will result otherwise. 
  7074   7096       ** Also, set the cursor state to invalid. This stops saveCursorPosition()
  7075   7097       ** from trying to save the current position of the cursor.  */
  7076   7098       pCur->apPage[pCur->iPage]->nOverflow = 0;
................................................................................
  7094   7116     unsigned char *pCell;                /* Pointer to cell to delete */
  7095   7117     int iCellIdx;                        /* Index of cell to delete */
  7096   7118     int iCellDepth;                      /* Depth of node containing pCell */ 
  7097   7119   
  7098   7120     assert( cursorHoldsMutex(pCur) );
  7099   7121     assert( pBt->inTransaction==TRANS_WRITE );
  7100   7122     assert( (pBt->btsFlags & BTS_READ_ONLY)==0 );
  7101         -  assert( pCur->wrFlag );
         7123  +  assert( pCur->curFlags & BTCF_WriteFlag );
  7102   7124     assert( hasSharedCacheTableLock(p, pCur->pgnoRoot, pCur->pKeyInfo!=0, 2) );
  7103   7125     assert( !hasReadConflicts(p, pCur->pgnoRoot) );
  7104   7126   
  7105   7127     if( NEVER(pCur->aiIdx[pCur->iPage]>=pCur->apPage[pCur->iPage]->nCell) 
  7106   7128      || NEVER(pCur->eState!=CURSOR_VALID)
  7107   7129     ){
  7108   7130       return SQLITE_ERROR;  /* Something has gone awry. */
................................................................................
  8407   8429   ** parameters that attempt to write past the end of the existing data,
  8408   8430   ** no modifications are made and SQLITE_CORRUPT is returned.
  8409   8431   */
  8410   8432   int sqlite3BtreePutData(BtCursor *pCsr, u32 offset, u32 amt, void *z){
  8411   8433     int rc;
  8412   8434     assert( cursorHoldsMutex(pCsr) );
  8413   8435     assert( sqlite3_mutex_held(pCsr->pBtree->db->mutex) );
  8414         -  assert( pCsr->isIncrblobHandle );
         8436  +  assert( pCsr->curFlags & BTCF_Incrblob );
  8415   8437   
  8416   8438     rc = restoreCursorPosition(pCsr);
  8417   8439     if( rc!=SQLITE_OK ){
  8418   8440       return rc;
  8419   8441     }
  8420   8442     assert( pCsr->eState!=CURSOR_REQUIRESEEK );
  8421   8443     if( pCsr->eState!=CURSOR_VALID ){
................................................................................
  8436   8458     /* Check some assumptions: 
  8437   8459     **   (a) the cursor is open for writing,
  8438   8460     **   (b) there is a read/write transaction open,
  8439   8461     **   (c) the connection holds a write-lock on the table (if required),
  8440   8462     **   (d) there are no conflicting read-locks, and
  8441   8463     **   (e) the cursor points at a valid row of an intKey table.
  8442   8464     */
  8443         -  if( !pCsr->wrFlag ){
         8465  +  if( (pCsr->curFlags & BTCF_WriteFlag)==0 ){
  8444   8466       return SQLITE_READONLY;
  8445   8467     }
  8446   8468     assert( (pCsr->pBt->btsFlags & BTS_READ_ONLY)==0
  8447   8469                 && pCsr->pBt->inTransaction==TRANS_WRITE );
  8448   8470     assert( hasSharedCacheTableLock(pCsr->pBtree, pCsr->pgnoRoot, 0, 2) );
  8449   8471     assert( !hasReadConflicts(pCsr->pBtree, pCsr->pgnoRoot) );
  8450   8472     assert( pCsr->apPage[pCsr->iPage]->intKey );
  8451   8473   
  8452   8474     return accessPayload(pCsr, offset, amt, (unsigned char *)z, 1);
  8453   8475   }
  8454   8476   
  8455   8477   /* 
  8456         -** Set a flag on this cursor to cache the locations of pages from the 
  8457         -** overflow list for the current row. This is used by cursors opened
  8458         -** for incremental blob IO only.
  8459         -**
  8460         -** This function sets a flag only. The actual page location cache
  8461         -** (stored in BtCursor.aOverflow[]) is allocated and used by function
  8462         -** accessPayload() (the worker function for sqlite3BtreeData() and
  8463         -** sqlite3BtreePutData()).
         8478  +** Mark this cursor as an incremental blob cursor.
  8464   8479   */
  8465         -void sqlite3BtreeCacheOverflow(BtCursor *pCur){
  8466         -  assert( cursorHoldsMutex(pCur) );
  8467         -  assert( sqlite3_mutex_held(pCur->pBtree->db->mutex) );
  8468         -  invalidateOverflowCache(pCur);
  8469         -  pCur->isIncrblobHandle = 1;
         8480  +void sqlite3BtreeIncrblobCursor(BtCursor *pCur){
         8481  +  pCur->curFlags |= BTCF_Incrblob;
  8470   8482   }
  8471   8483   #endif
  8472   8484   
  8473   8485   /*
  8474   8486   ** Set both the "read version" (single byte at byte offset 18) and 
  8475   8487   ** "write version" (single byte at byte offset 19) fields in the database
  8476   8488   ** header to iVersion.

Changes to src/btree.h.

   186    186   int sqlite3BtreeDataSize(BtCursor*, u32 *pSize);
   187    187   int sqlite3BtreeData(BtCursor*, u32 offset, u32 amt, void*);
   188    188   
   189    189   char *sqlite3BtreeIntegrityCheck(Btree*, int *aRoot, int nRoot, int, int*);
   190    190   struct Pager *sqlite3BtreePager(Btree*);
   191    191   
   192    192   int sqlite3BtreePutData(BtCursor*, u32 offset, u32 amt, void*);
   193         -void sqlite3BtreeCacheOverflow(BtCursor *);
          193  +void sqlite3BtreeIncrblobCursor(BtCursor *);
   194    194   void sqlite3BtreeClearCursor(BtCursor *);
   195    195   int sqlite3BtreeSetVersion(Btree *pBt, int iVersion);
   196    196   void sqlite3BtreeCursorHints(BtCursor *, unsigned int mask);
   197    197   
   198    198   #ifndef NDEBUG
   199    199   int sqlite3BtreeCursorIsValid(BtCursor*);
   200    200   #endif

Changes to src/btreeInt.h.

   492    492   ** found at self->pBt->mutex. 
   493    493   */
   494    494   struct BtCursor {
   495    495     Btree *pBtree;            /* The Btree to which this cursor belongs */
   496    496     BtShared *pBt;            /* The BtShared this cursor points to */
   497    497     BtCursor *pNext, *pPrev;  /* Forms a linked list of all cursors */
   498    498     struct KeyInfo *pKeyInfo; /* Argument passed to comparison function */
   499         -#ifndef SQLITE_OMIT_INCRBLOB
   500    499     Pgno *aOverflow;          /* Cache of overflow page locations */
   501         -#endif
          500  +  CellInfo info;            /* A parse of the cell we are pointing at */
          501  +  i64 nKey;                 /* Size of pKey, or last integer key */
          502  +  void *pKey;               /* Saved key that was cursor last known position */
   502    503     Pgno pgnoRoot;            /* The root page of this tree */
   503         -  CellInfo info;            /* A parse of the cell we are pointing at */
   504         -  i64 nKey;        /* Size of pKey, or last integer key */
   505         -  void *pKey;      /* Saved key that was cursor's last known position */
          504  +  int nOvflAlloc;           /* Allocated size of aOverflow[] array */
   506    505     int skipNext;    /* Prev() is noop if negative. Next() is noop if positive */
   507         -  u8 wrFlag;                /* True if writable */
   508         -  u8 atLast;                /* Cursor pointing to the last entry */
   509         -  u8 validNKey;             /* True if info.nKey is valid */
          506  +  u8 curFlags;              /* zero or more BTCF_* flags defined below */
   510    507     u8 eState;                /* One of the CURSOR_XXX constants (see below) */
   511         -#ifndef SQLITE_OMIT_INCRBLOB
   512         -  u8 isIncrblobHandle;      /* True if this cursor is an incr. io handle */
   513         -#endif
   514    508     u8 hints;                             /* As configured by CursorSetHints() */
   515    509     i16 iPage;                            /* Index of current page in apPage */
   516    510     u16 aiIdx[BTCURSOR_MAX_DEPTH];        /* Current index in apPage[i] */
   517    511     MemPage *apPage[BTCURSOR_MAX_DEPTH];  /* Pages from root to current page */
   518    512   };
   519    513   
          514  +/*
          515  +** Legal values for BtCursor.curFlags
          516  +*/
          517  +#define BTCF_WriteFlag    0x01   /* True if a write cursor */
          518  +#define BTCF_ValidNKey    0x02   /* True if info.nKey is valid */
          519  +#define BTCF_ValidOvfl    0x04   /* True if aOverflow is valid */
          520  +#define BTCF_AtLast       0x08   /* Cursor is pointing ot the last entry */
          521  +#define BTCF_Incrblob     0x10   /* True if an incremental I/O handle */
          522  +
   520    523   /*
   521    524   ** Potential values for BtCursor.eState.
   522    525   **
   523    526   ** CURSOR_INVALID:
   524    527   **   Cursor does not point to a valid entry. This can happen (for example) 
   525    528   **   because the table is empty or because BtreeCursorFirst() has not been
   526    529   **   called.

Changes to src/build.c.

  2676   2676     ** records into the sorter. */
  2677   2677     sqlite3OpenTable(pParse, iTab, iDb, pTab, OP_OpenRead);
  2678   2678     addr1 = sqlite3VdbeAddOp2(v, OP_Rewind, iTab, 0); VdbeCoverage(v);
  2679   2679     regRecord = sqlite3GetTempReg(pParse);
  2680   2680   
  2681   2681     sqlite3GenerateIndexKey(pParse,pIndex,iTab,regRecord,0,&iPartIdxLabel,0,0);
  2682   2682     sqlite3VdbeAddOp2(v, OP_SorterInsert, iSorter, regRecord);
  2683         -  sqlite3VdbeResolveLabel(v, iPartIdxLabel);
         2683  +  sqlite3ResolvePartIdxLabel(pParse, iPartIdxLabel);
  2684   2684     sqlite3VdbeAddOp2(v, OP_Next, iTab, addr1+1); VdbeCoverage(v);
  2685   2685     sqlite3VdbeJumpHere(v, addr1);
  2686   2686     if( memRootPage<0 ) sqlite3VdbeAddOp2(v, OP_Clear, tnum, iDb);
  2687   2687     sqlite3VdbeAddOp4(v, OP_OpenWrite, iIdx, tnum, iDb, 
  2688   2688                       (char *)pKey, P4_KEYINFO);
  2689   2689     sqlite3VdbeChangeP5(v, OPFLAG_BULKCSR|((memRootPage>=0)?OPFLAG_P2ISREG:0));
  2690   2690   

Changes to src/delete.c.

   747    747       if( aRegIdx!=0 && aRegIdx[i]==0 ) continue;
   748    748       if( pIdx==pPk ) continue;
   749    749       VdbeModuleComment((v, "GenRowIdxDel for %s", pIdx->zName));
   750    750       r1 = sqlite3GenerateIndexKey(pParse, pIdx, iDataCur, 0, 1,
   751    751                                    &iPartIdxLabel, pPrior, r1);
   752    752       sqlite3VdbeAddOp3(v, OP_IdxDelete, iIdxCur+i, r1,
   753    753                         pIdx->uniqNotNull ? pIdx->nKeyCol : pIdx->nColumn);
   754         -    sqlite3VdbeResolveLabel(v, iPartIdxLabel);
          754  +    sqlite3ResolvePartIdxLabel(pParse, iPartIdxLabel);
   755    755       pPrior = pIdx;
   756    756     }
   757    757   }
   758    758   
   759    759   /*
   760    760   ** Generate code that will assemble an index key and stores it in register
   761    761   ** regOut.  The key with be for index pIdx which is an index on pTab.
................................................................................
   766    766   ** Return a register number which is the first in a block of
   767    767   ** registers that holds the elements of the index key.  The
   768    768   ** block of registers has already been deallocated by the time
   769    769   ** this routine returns.
   770    770   **
   771    771   ** If *piPartIdxLabel is not NULL, fill it in with a label and jump
   772    772   ** to that label if pIdx is a partial index that should be skipped.
          773  +** The label should be resolved using sqlite3ResolvePartIdxLabel().
   773    774   ** A partial index should be skipped if its WHERE clause evaluates
   774    775   ** to false or null.  If pIdx is not a partial index, *piPartIdxLabel
   775    776   ** will be set to zero which is an empty label that is ignored by
   776         -** sqlite3VdbeResolveLabel().
          777  +** sqlite3ResolvePartIdxLabel().
   777    778   **
   778    779   ** The pPrior and regPrior parameters are used to implement a cache to
   779    780   ** avoid unnecessary register loads.  If pPrior is not NULL, then it is
   780    781   ** a pointer to a different index for which an index key has just been
   781    782   ** computed into register regPrior.  If the current pIdx index is generating
   782    783   ** its key into the same sequence of registers and if pPrior and pIdx share
   783    784   ** a column in common, then the register corresponding to that column already
................................................................................
   802    803     int regBase;
   803    804     int nCol;
   804    805   
   805    806     if( piPartIdxLabel ){
   806    807       if( pIdx->pPartIdxWhere ){
   807    808         *piPartIdxLabel = sqlite3VdbeMakeLabel(v);
   808    809         pParse->iPartIdxTab = iDataCur;
          810  +      sqlite3ExprCachePush(pParse);
   809    811         sqlite3ExprIfFalse(pParse, pIdx->pPartIdxWhere, *piPartIdxLabel, 
   810    812                            SQLITE_JUMPIFNULL);
   811    813       }else{
   812    814         *piPartIdxLabel = 0;
   813    815       }
   814    816     }
   815    817     nCol = (prefixOnly && pIdx->uniqNotNull) ? pIdx->nKeyCol : pIdx->nColumn;
................................................................................
   829    831     }
   830    832     if( regOut ){
   831    833       sqlite3VdbeAddOp3(v, OP_MakeRecord, regBase, nCol, regOut);
   832    834     }
   833    835     sqlite3ReleaseTempRange(pParse, regBase, nCol);
   834    836     return regBase;
   835    837   }
          838  +
          839  +/*
          840  +** If a prior call to sqlite3GenerateIndexKey() generated a jump-over label
          841  +** because it was a partial index, then this routine should be called to
          842  +** resolve that label.
          843  +*/
          844  +void sqlite3ResolvePartIdxLabel(Parse *pParse, int iLabel){
          845  +  if( iLabel ){
          846  +    sqlite3VdbeResolveLabel(pParse->pVdbe, iLabel);
          847  +    sqlite3ExprCachePop(pParse);
          848  +  }
          849  +}

Changes to src/expr.c.

  1879   1879         break;
  1880   1880       }
  1881   1881     }
  1882   1882   
  1883   1883     if( testAddr>=0 ){
  1884   1884       sqlite3VdbeJumpHere(v, testAddr);
  1885   1885     }
  1886         -  sqlite3ExprCachePop(pParse, 1);
         1886  +  sqlite3ExprCachePop(pParse);
  1887   1887   
  1888   1888     return rReg;
  1889   1889   }
  1890   1890   #endif /* SQLITE_OMIT_SUBQUERY */
  1891   1891   
  1892   1892   #ifndef SQLITE_OMIT_SUBQUERY
  1893   1893   /*
................................................................................
  2014   2014         /* The OP_Found at the top of this branch jumps here when true, 
  2015   2015         ** causing the overall IN expression evaluation to fall through.
  2016   2016         */
  2017   2017         sqlite3VdbeJumpHere(v, j1);
  2018   2018       }
  2019   2019     }
  2020   2020     sqlite3ReleaseTempReg(pParse, r1);
  2021         -  sqlite3ExprCachePop(pParse, 1);
         2021  +  sqlite3ExprCachePop(pParse);
  2022   2022     VdbeComment((v, "end IN expr"));
  2023   2023   }
  2024   2024   #endif /* SQLITE_OMIT_SUBQUERY */
  2025   2025   
  2026   2026   /*
  2027   2027   ** Duplicate an 8-byte value
  2028   2028   */
................................................................................
  2197   2197       printf("PUSH to %d\n", pParse->iCacheLevel);
  2198   2198     }
  2199   2199   #endif
  2200   2200   }
  2201   2201   
  2202   2202   /*
  2203   2203   ** Remove from the column cache any entries that were added since the
  2204         -** the previous N Push operations.  In other words, restore the cache
  2205         -** to the state it was in N Pushes ago.
         2204  +** the previous sqlite3ExprCachePush operation.  In other words, restore
         2205  +** the cache to the state it was in prior the most recent Push.
  2206   2206   */
  2207         -void sqlite3ExprCachePop(Parse *pParse, int N){
         2207  +void sqlite3ExprCachePop(Parse *pParse){
  2208   2208     int i;
  2209   2209     struct yColCache *p;
  2210         -  assert( N>0 );
  2211         -  assert( pParse->iCacheLevel>=N );
  2212         -  pParse->iCacheLevel -= N;
         2210  +  assert( pParse->iCacheLevel>=1 );
         2211  +  pParse->iCacheLevel--;
  2213   2212   #ifdef SQLITE_DEBUG
  2214   2213     if( pParse->db->flags & SQLITE_VdbeAddopTrace ){
  2215   2214       printf("POP  to %d\n", pParse->iCacheLevel);
  2216   2215     }
  2217   2216   #endif
  2218   2217     for(i=0, p=pParse->aColCache; i<SQLITE_N_COLCACHE; i++, p++){
  2219   2218       if( p->iReg && p->iLevel>pParse->iCacheLevel ){
................................................................................
  2683   2682           sqlite3ExprCode(pParse, pFarg->a[0].pExpr, target);
  2684   2683           for(i=1; i<nFarg; i++){
  2685   2684             sqlite3VdbeAddOp2(v, OP_NotNull, target, endCoalesce);
  2686   2685             VdbeCoverage(v);
  2687   2686             sqlite3ExprCacheRemove(pParse, target, 1);
  2688   2687             sqlite3ExprCachePush(pParse);
  2689   2688             sqlite3ExprCode(pParse, pFarg->a[i].pExpr, target);
  2690         -          sqlite3ExprCachePop(pParse, 1);
         2689  +          sqlite3ExprCachePop(pParse);
  2691   2690           }
  2692   2691           sqlite3VdbeResolveLabel(v, endCoalesce);
  2693   2692           break;
  2694   2693         }
  2695   2694   
  2696   2695         /* The UNLIKELY() function is a no-op.  The result is the value
  2697   2696         ** of the first argument.
................................................................................
  2737   2736                     pDef->funcFlags & (OPFLAG_LENGTHARG|OPFLAG_TYPEOFARG);
  2738   2737             }
  2739   2738           }
  2740   2739   
  2741   2740           sqlite3ExprCachePush(pParse);     /* Ticket 2ea2425d34be */
  2742   2741           sqlite3ExprCodeExprList(pParse, pFarg, r1,
  2743   2742                                   SQLITE_ECEL_DUP|SQLITE_ECEL_FACTOR);
  2744         -        sqlite3ExprCachePop(pParse, 1);   /* Ticket 2ea2425d34be */
         2743  +        sqlite3ExprCachePop(pParse);      /* Ticket 2ea2425d34be */
  2745   2744         }else{
  2746   2745           r1 = 0;
  2747   2746         }
  2748   2747   #ifndef SQLITE_OMIT_VIRTUALTABLE
  2749   2748         /* Possibly overload the function if the first argument is
  2750   2749         ** a virtual table column.
  2751   2750         **
................................................................................
  2957   2956           }
  2958   2957           nextCase = sqlite3VdbeMakeLabel(v);
  2959   2958           testcase( pTest->op==TK_COLUMN );
  2960   2959           sqlite3ExprIfFalse(pParse, pTest, nextCase, SQLITE_JUMPIFNULL);
  2961   2960           testcase( aListelem[i+1].pExpr->op==TK_COLUMN );
  2962   2961           sqlite3ExprCode(pParse, aListelem[i+1].pExpr, target);
  2963   2962           sqlite3VdbeAddOp2(v, OP_Goto, 0, endLabel);
  2964         -        sqlite3ExprCachePop(pParse, 1);
         2963  +        sqlite3ExprCachePop(pParse);
  2965   2964           sqlite3VdbeResolveLabel(v, nextCase);
  2966   2965         }
  2967   2966         if( (nExpr&1)!=0 ){
  2968   2967           sqlite3ExprCachePush(pParse);
  2969   2968           sqlite3ExprCode(pParse, pEList->a[nExpr-1].pExpr, target);
  2970         -        sqlite3ExprCachePop(pParse, 1);
         2969  +        sqlite3ExprCachePop(pParse);
  2971   2970         }else{
  2972   2971           sqlite3VdbeAddOp2(v, OP_Null, 0, target);
  2973   2972         }
  2974   2973         assert( db->mallocFailed || pParse->nErr>0 
  2975   2974              || pParse->iCacheLevel==iCacheLevel );
  2976   2975         sqlite3VdbeResolveLabel(v, endLabel);
  2977   2976         break;
................................................................................
  3542   3541       case TK_AND: {
  3543   3542         int d2 = sqlite3VdbeMakeLabel(v);
  3544   3543         testcase( jumpIfNull==0 );
  3545   3544         sqlite3ExprIfFalse(pParse, pExpr->pLeft, d2,jumpIfNull^SQLITE_JUMPIFNULL);
  3546   3545         sqlite3ExprCachePush(pParse);
  3547   3546         sqlite3ExprIfTrue(pParse, pExpr->pRight, dest, jumpIfNull);
  3548   3547         sqlite3VdbeResolveLabel(v, d2);
  3549         -      sqlite3ExprCachePop(pParse, 1);
         3548  +      sqlite3ExprCachePop(pParse);
  3550   3549         break;
  3551   3550       }
  3552   3551       case TK_OR: {
  3553   3552         testcase( jumpIfNull==0 );
  3554   3553         sqlite3ExprIfTrue(pParse, pExpr->pLeft, dest, jumpIfNull);
  3555   3554         sqlite3ExprCachePush(pParse);
  3556   3555         sqlite3ExprIfTrue(pParse, pExpr->pRight, dest, jumpIfNull);
  3557         -      sqlite3ExprCachePop(pParse, 1);
         3556  +      sqlite3ExprCachePop(pParse);
  3558   3557         break;
  3559   3558       }
  3560   3559       case TK_NOT: {
  3561   3560         testcase( jumpIfNull==0 );
  3562   3561         sqlite3ExprIfFalse(pParse, pExpr->pLeft, dest, jumpIfNull);
  3563   3562         break;
  3564   3563       }
................................................................................
  3696   3695   
  3697   3696     switch( pExpr->op ){
  3698   3697       case TK_AND: {
  3699   3698         testcase( jumpIfNull==0 );
  3700   3699         sqlite3ExprIfFalse(pParse, pExpr->pLeft, dest, jumpIfNull);
  3701   3700         sqlite3ExprCachePush(pParse);
  3702   3701         sqlite3ExprIfFalse(pParse, pExpr->pRight, dest, jumpIfNull);
  3703         -      sqlite3ExprCachePop(pParse, 1);
         3702  +      sqlite3ExprCachePop(pParse);
  3704   3703         break;
  3705   3704       }
  3706   3705       case TK_OR: {
  3707   3706         int d2 = sqlite3VdbeMakeLabel(v);
  3708   3707         testcase( jumpIfNull==0 );
  3709   3708         sqlite3ExprIfTrue(pParse, pExpr->pLeft, d2, jumpIfNull^SQLITE_JUMPIFNULL);
  3710   3709         sqlite3ExprCachePush(pParse);
  3711   3710         sqlite3ExprIfFalse(pParse, pExpr->pRight, dest, jumpIfNull);
  3712   3711         sqlite3VdbeResolveLabel(v, d2);
  3713         -      sqlite3ExprCachePop(pParse, 1);
         3712  +      sqlite3ExprCachePop(pParse);
  3714   3713         break;
  3715   3714       }
  3716   3715       case TK_NOT: {
  3717   3716         testcase( jumpIfNull==0 );
  3718   3717         sqlite3ExprIfTrue(pParse, pExpr->pLeft, dest, jumpIfNull);
  3719   3718         break;
  3720   3719       }

Changes to src/main.c.

  3221   3221       **    }
  3222   3222       */
  3223   3223       case SQLITE_TESTCTRL_ALWAYS: {
  3224   3224         int x = va_arg(ap,int);
  3225   3225         rc = ALWAYS(x);
  3226   3226         break;
  3227   3227       }
         3228  +
         3229  +    /*
         3230  +    **   sqlite3_test_control(SQLITE_TESTCTRL_BYTEORDER);
         3231  +    **
         3232  +    ** The integer returned reveals the byte-order of the computer on which
         3233  +    ** SQLite is running:
         3234  +    **
         3235  +    **       1     big-endian,    determined at run-time
         3236  +    **      10     little-endian, determined at run-time
         3237  +    **  432101     big-endian,    determined at compile-time
         3238  +    **  123410     little-endian, determined at compile-time
         3239  +    */ 
         3240  +    case SQLITE_TESTCTRL_BYTEORDER: {
         3241  +      rc = SQLITE_BYTEORDER*100 + SQLITE_LITTLEENDIAN*10 + SQLITE_BIGENDIAN;
         3242  +      break;
         3243  +    }
  3228   3244   
  3229   3245       /*   sqlite3_test_control(SQLITE_TESTCTRL_RESERVE, sqlite3 *db, int N)
  3230   3246       **
  3231   3247       ** Set the nReserve size to N for the main database on the database
  3232   3248       ** connection db.
  3233   3249       */
  3234   3250       case SQLITE_TESTCTRL_RESERVE: {

Changes to src/pager.c.

  1620   1620     u32 cksum = 0;                   /* Checksum of string zMaster */
  1621   1621   
  1622   1622     assert( pPager->setMaster==0 );
  1623   1623     assert( !pagerUseWal(pPager) );
  1624   1624   
  1625   1625     if( !zMaster 
  1626   1626      || pPager->journalMode==PAGER_JOURNALMODE_MEMORY 
  1627         -   || pPager->journalMode==PAGER_JOURNALMODE_OFF 
         1627  +   || !isOpen(pPager->jfd)
  1628   1628     ){
  1629   1629       return SQLITE_OK;
  1630   1630     }
  1631   1631     pPager->setMaster = 1;
  1632         -  assert( isOpen(pPager->jfd) );
  1633   1632     assert( pPager->journalHdr <= pPager->journalOff );
  1634   1633   
  1635   1634     /* Calculate the length in bytes and the checksum of zMaster */
  1636   1635     for(nMaster=0; zMaster[nMaster]; nMaster++){
  1637   1636       cksum += zMaster[nMaster];
  1638   1637     }
  1639   1638   

Changes to src/pragma.c.

  1924   1924             sqlite3VdbeAddOp4(v, OP_String8, 0, 4, 0, pIdx->zName, P4_TRANSIENT);
  1925   1925             sqlite3VdbeAddOp3(v, OP_Concat, 4, 3, 3);
  1926   1926             sqlite3VdbeAddOp2(v, OP_ResultRow, 3, 1);
  1927   1927             jmp4 = sqlite3VdbeAddOp1(v, OP_IfPos, 1); VdbeCoverage(v);
  1928   1928             sqlite3VdbeAddOp0(v, OP_Halt);
  1929   1929             sqlite3VdbeJumpHere(v, jmp4);
  1930   1930             sqlite3VdbeJumpHere(v, jmp2);
  1931         -          sqlite3VdbeResolveLabel(v, jmp3);
         1931  +          sqlite3ResolvePartIdxLabel(pParse, jmp3);
  1932   1932           }
  1933   1933           sqlite3VdbeAddOp2(v, OP_Next, iDataCur, loopTop); VdbeCoverage(v);
  1934   1934           sqlite3VdbeJumpHere(v, loopTop-1);
  1935   1935   #ifndef SQLITE_OMIT_BTREECOUNT
  1936   1936           sqlite3VdbeAddOp4(v, OP_String8, 0, 2, 0, 
  1937   1937                        "wrong # of entries in index ", P4_STATIC);
  1938   1938           for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){

Changes to src/rowset.c.

   108    108     struct RowSetChunk *pChunk;    /* List of all chunk allocations */
   109    109     sqlite3 *db;                   /* The database connection */
   110    110     struct RowSetEntry *pEntry;    /* List of entries using pRight */
   111    111     struct RowSetEntry *pLast;     /* Last entry on the pEntry list */
   112    112     struct RowSetEntry *pFresh;    /* Source of new entry objects */
   113    113     struct RowSetEntry *pForest;   /* List of binary trees of entries */
   114    114     u16 nFresh;                    /* Number of objects on pFresh */
   115         -  u8 rsFlags;                    /* Various flags */
   116         -  u8 iBatch;                     /* Current insert batch */
          115  +  u16 rsFlags;                   /* Various flags */
          116  +  int iBatch;                    /* Current insert batch */
   117    117   };
   118    118   
   119    119   /*
   120    120   ** Allowed values for RowSet.rsFlags
   121    121   */
   122    122   #define ROWSET_SORTED  0x01   /* True if RowSet.pEntry is sorted */
   123    123   #define ROWSET_NEXT    0x02   /* True if sqlite3RowSetNext() has been called */
................................................................................
   443    443   ** Check to see if element iRowid was inserted into the rowset as
   444    444   ** part of any insert batch prior to iBatch.  Return 1 or 0.
   445    445   **
   446    446   ** If this is the first test of a new batch and if there exist entires
   447    447   ** on pRowSet->pEntry, then sort those entires into the forest at
   448    448   ** pRowSet->pForest so that they can be tested.
   449    449   */
   450         -int sqlite3RowSetTest(RowSet *pRowSet, u8 iBatch, sqlite3_int64 iRowid){
          450  +int sqlite3RowSetTest(RowSet *pRowSet, int iBatch, sqlite3_int64 iRowid){
   451    451     struct RowSetEntry *p, *pTree;
   452    452   
   453    453     /* This routine is never called after sqlite3RowSetNext() */
   454    454     assert( pRowSet!=0 && (pRowSet->rsFlags & ROWSET_NEXT)==0 );
   455    455   
   456    456     /* Sort entries into the forest on the first test of a new batch 
   457    457     */

Changes to src/shell.c.

  3023   3023         { "pending_byte",          SQLITE_TESTCTRL_PENDING_BYTE           },
  3024   3024         { "assert",                SQLITE_TESTCTRL_ASSERT                 },
  3025   3025         { "always",                SQLITE_TESTCTRL_ALWAYS                 },
  3026   3026         { "reserve",               SQLITE_TESTCTRL_RESERVE                },
  3027   3027         { "optimizations",         SQLITE_TESTCTRL_OPTIMIZATIONS          },
  3028   3028         { "iskeyword",             SQLITE_TESTCTRL_ISKEYWORD              },
  3029   3029         { "scratchmalloc",         SQLITE_TESTCTRL_SCRATCHMALLOC          },
         3030  +      { "byteorder",             SQLITE_TESTCTRL_BYTEORDER              },
  3030   3031       };
  3031   3032       int testctrl = -1;
  3032   3033       int rc = 0;
  3033   3034       int i, n;
  3034   3035       open_db(p, 0);
  3035   3036   
  3036   3037       /* convert testctrl text option to value. allow any unique prefix
................................................................................
  3063   3064             } else {
  3064   3065               fprintf(stderr,"Error: testctrl %s takes a single int option\n",
  3065   3066                       azArg[1]);
  3066   3067             }
  3067   3068             break;
  3068   3069   
  3069   3070           /* sqlite3_test_control(int) */
  3070         -        case SQLITE_TESTCTRL_PRNG_SAVE:           
  3071         -        case SQLITE_TESTCTRL_PRNG_RESTORE:        
         3071  +        case SQLITE_TESTCTRL_PRNG_SAVE:
         3072  +        case SQLITE_TESTCTRL_PRNG_RESTORE:
  3072   3073           case SQLITE_TESTCTRL_PRNG_RESET:
         3074  +        case SQLITE_TESTCTRL_BYTEORDER:
  3073   3075             if( nArg==2 ){
  3074   3076               rc = sqlite3_test_control(testctrl);
  3075   3077               fprintf(p->out, "%d (0x%08x)\n", rc, rc);
  3076   3078             } else {
  3077   3079               fprintf(stderr,"Error: testctrl %s takes no options\n", azArg[1]);
  3078   3080             }
  3079   3081             break;

Changes to src/sqlite.h.in.

  6114   6114   #define SQLITE_TESTCTRL_OPTIMIZATIONS           15
  6115   6115   #define SQLITE_TESTCTRL_ISKEYWORD               16
  6116   6116   #define SQLITE_TESTCTRL_SCRATCHMALLOC           17
  6117   6117   #define SQLITE_TESTCTRL_LOCALTIME_FAULT         18
  6118   6118   #define SQLITE_TESTCTRL_EXPLAIN_STMT            19
  6119   6119   #define SQLITE_TESTCTRL_NEVER_CORRUPT           20
  6120   6120   #define SQLITE_TESTCTRL_VDBE_COVERAGE           21
  6121         -#define SQLITE_TESTCTRL_LAST                    21
         6121  +#define SQLITE_TESTCTRL_BYTEORDER               22
         6122  +#define SQLITE_TESTCTRL_LAST                    22
  6122   6123   
  6123   6124   /*
  6124   6125   ** CAPI3REF: SQLite Runtime Status
  6125   6126   **
  6126   6127   ** ^This interface is used to retrieve runtime status information
  6127   6128   ** about the performance of SQLite, and optionally to reset various
  6128   6129   ** highwater marks.  ^The first argument is an integer code for

Changes to src/sqliteInt.h.

   542    542   **
   543    543   **    0.5 -> -10           0.1 -> -33        0.0625 -> -40
   544    544   */
   545    545   typedef INT16_TYPE LogEst;
   546    546   
   547    547   /*
   548    548   ** Macros to determine whether the machine is big or little endian,
   549         -** evaluated at runtime.
          549  +** and whether or not that determination is run-time or compile-time.
          550  +**
          551  +** For best performance, an attempt is made to guess at the byte-order
          552  +** using C-preprocessor macros.  If that is unsuccessful, or if
          553  +** -DSQLITE_RUNTIME_BYTEORDER=1 is set, then byte-order is determined
          554  +** at run-time.
   550    555   */
   551    556   #ifdef SQLITE_AMALGAMATION
   552    557   const int sqlite3one = 1;
   553    558   #else
   554    559   extern const int sqlite3one;
   555    560   #endif
   556         -#if defined(i386) || defined(__i386__) || defined(_M_IX86)\
   557         -                             || defined(__x86_64) || defined(__x86_64__)
          561  +#if (defined(i386)     || defined(__i386__)   || defined(_M_IX86) ||    \
          562  +     defined(__x86_64) || defined(__x86_64__) || defined(_M_X64)  ||    \
          563  +     defined(_M_AMD64) || defined(_M_ARM)     || defined(__x86)   ||    \
          564  +     defined(__arm__)) && !defined(SQLITE_RUNTIME_BYTEORDER)
          565  +# define SQLITE_BYTEORDER    1234
   558    566   # define SQLITE_BIGENDIAN    0
   559    567   # define SQLITE_LITTLEENDIAN 1
   560    568   # define SQLITE_UTF16NATIVE  SQLITE_UTF16LE
   561         -#else
          569  +#endif
          570  +#if (defined(sparc)    || defined(__ppc__))  \
          571  +    && !defined(SQLITE_RUNTIME_BYTEORDER)
          572  +# define SQLITE_BYTEORDER    4321
          573  +# define SQLITE_BIGENDIAN    1
          574  +# define SQLITE_LITTLEENDIAN 0
          575  +# define SQLITE_UTF16NATIVE  SQLITE_UTF16BE
          576  +#endif
          577  +#if !defined(SQLITE_BYTEORDER)
          578  +# define SQLITE_BYTEORDER    0     /* 0 means "unknown at compile-time" */
   562    579   # define SQLITE_BIGENDIAN    (*(char *)(&sqlite3one)==0)
   563    580   # define SQLITE_LITTLEENDIAN (*(char *)(&sqlite3one)==1)
   564         -# define SQLITE_UTF16NATIVE (SQLITE_BIGENDIAN?SQLITE_UTF16BE:SQLITE_UTF16LE)
          581  +# define SQLITE_UTF16NATIVE  (SQLITE_BIGENDIAN?SQLITE_UTF16BE:SQLITE_UTF16LE)
   565    582   #endif
   566    583   
   567    584   /*
   568    585   ** Constants for the largest and smallest possible 64-bit signed integers.
   569    586   ** These macros are designed to work correctly on both 32-bit and 64-bit
   570    587   ** compilers.
   571    588   */
................................................................................
  3027   3044   void sqlite3BitvecDestroy(Bitvec*);
  3028   3045   u32 sqlite3BitvecSize(Bitvec*);
  3029   3046   int sqlite3BitvecBuiltinTest(int,int*);
  3030   3047   
  3031   3048   RowSet *sqlite3RowSetInit(sqlite3*, void*, unsigned int);
  3032   3049   void sqlite3RowSetClear(RowSet*);
  3033   3050   void sqlite3RowSetInsert(RowSet*, i64);
  3034         -int sqlite3RowSetTest(RowSet*, u8 iBatch, i64);
         3051  +int sqlite3RowSetTest(RowSet*, int iBatch, i64);
  3035   3052   int sqlite3RowSetNext(RowSet*, i64*);
  3036   3053   
  3037   3054   void sqlite3CreateView(Parse*,Token*,Token*,Token*,Select*,int,int);
  3038   3055   
  3039   3056   #if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_VIRTUALTABLE)
  3040   3057     int sqlite3ViewGetColumnNames(Parse*,Table*);
  3041   3058   #else
................................................................................
  3091   3108   int sqlite3WhereBreakLabel(WhereInfo*);
  3092   3109   int sqlite3WhereOkOnePass(WhereInfo*, int*);
  3093   3110   int sqlite3ExprCodeGetColumn(Parse*, Table*, int, int, int, u8);
  3094   3111   void sqlite3ExprCodeGetColumnOfTable(Vdbe*, Table*, int, int, int);
  3095   3112   void sqlite3ExprCodeMove(Parse*, int, int, int);
  3096   3113   void sqlite3ExprCacheStore(Parse*, int, int, int);
  3097   3114   void sqlite3ExprCachePush(Parse*);
  3098         -void sqlite3ExprCachePop(Parse*, int);
         3115  +void sqlite3ExprCachePop(Parse*);
  3099   3116   void sqlite3ExprCacheRemove(Parse*, int, int);
  3100   3117   void sqlite3ExprCacheClear(Parse*);
  3101   3118   void sqlite3ExprCacheAffinityChange(Parse*, int, int);
  3102   3119   void sqlite3ExprCode(Parse*, Expr*, int);
  3103   3120   void sqlite3ExprCodeFactorable(Parse*, Expr*, int);
  3104   3121   void sqlite3ExprCodeAtInit(Parse*, Expr*, int, u8);
  3105   3122   int sqlite3ExprCodeTemp(Parse*, Expr*, int*);
................................................................................
  3143   3160   int sqlite3ExprIsInteger(Expr*, int*);
  3144   3161   int sqlite3ExprCanBeNull(const Expr*);
  3145   3162   int sqlite3ExprNeedsNoAffinityChange(const Expr*, char);
  3146   3163   int sqlite3IsRowid(const char*);
  3147   3164   void sqlite3GenerateRowDelete(Parse*,Table*,Trigger*,int,int,int,i16,u8,u8,u8);
  3148   3165   void sqlite3GenerateRowIndexDelete(Parse*, Table*, int, int, int*);
  3149   3166   int sqlite3GenerateIndexKey(Parse*, Index*, int, int, int, int*,Index*,int);
         3167  +void sqlite3ResolvePartIdxLabel(Parse*,int);
  3150   3168   void sqlite3GenerateConstraintChecks(Parse*,Table*,int*,int,int,int,int,
  3151   3169                                        u8,u8,int,int*);
  3152   3170   void sqlite3CompleteInsertion(Parse*,Table*,int,int,int,int*,int,int,int);
  3153   3171   int sqlite3OpenTableAndIndices(Parse*, Table*, int, int, u8*, int*, int*);
  3154   3172   void sqlite3BeginWriteOperation(Parse*, int, int);
  3155   3173   void sqlite3MultiWrite(Parse*);
  3156   3174   void sqlite3MayAbort(Parse*);

Changes to src/test_btree.c.

    47     47   */
    48     48   void sqlite3BtreeCursorList(Btree *p){
    49     49   #ifdef SQLITE_DEBUG
    50     50     BtCursor *pCur;
    51     51     BtShared *pBt = p->pBt;
    52     52     for(pCur=pBt->pCursor; pCur; pCur=pCur->pNext){
    53     53       MemPage *pPage = pCur->apPage[pCur->iPage];
    54         -    char *zMode = pCur->wrFlag ? "rw" : "ro";
           54  +    char *zMode = (pCur->curFlags & BTCF_WriteFlag) ? "rw" : "ro";
    55     55       sqlite3DebugPrintf("CURSOR %p rooted at %4d(%s) currently at %d.%d%s\n",
    56     56          pCur, pCur->pgnoRoot, zMode,
    57     57          pPage ? pPage->pgno : 0, pCur->aiIdx[pCur->iPage],
    58     58          (pCur->eState==CURSOR_VALID) ? "" : " eof"
    59     59       );
    60     60     }
    61     61   #endif
    62     62   }

Changes to src/vdbe.c.

  5284   5284       sqlite3VdbeMemSetRowSet(pIn1);
  5285   5285       if( (pIn1->flags & MEM_RowSet)==0 ) goto no_mem;
  5286   5286     }
  5287   5287   
  5288   5288     assert( pOp->p4type==P4_INT32 );
  5289   5289     assert( iSet==-1 || iSet>=0 );
  5290   5290     if( iSet ){
  5291         -    exists = sqlite3RowSetTest(pIn1->u.pRowSet, 
  5292         -                               (u8)(iSet>=0 ? iSet & 0xf : 0xff),
  5293         -                               pIn3->u.i);
         5291  +    exists = sqlite3RowSetTest(pIn1->u.pRowSet, iSet, pIn3->u.i);
  5294   5292       VdbeBranchTaken(exists!=0,2);
  5295   5293       if( exists ){
  5296   5294         pc = pOp->p2 - 1;
  5297   5295         break;
  5298   5296       }
  5299   5297     }
  5300   5298     if( iSet>=0 ){

Changes to src/vdbeaux.c.

   273    273   ** a prior call to sqlite3VdbeMakeLabel().
   274    274   */
   275    275   void sqlite3VdbeResolveLabel(Vdbe *v, int x){
   276    276     Parse *p = v->pParse;
   277    277     int j = -1-x;
   278    278     assert( v->magic==VDBE_MAGIC_INIT );
   279    279     assert( j<p->nLabel );
   280         -  if( j>=0 && p->aLabel ){
          280  +  if( ALWAYS(j>=0) && p->aLabel ){
   281    281       p->aLabel[j] = v->nOp;
   282    282     }
   283    283     p->iFixedOp = v->nOp - 1;
   284    284   }
   285    285   
   286    286   /*
   287    287   ** Mark the VDBE as one that can only be run one time.

Changes to src/vdbeblob.c.

    75     75         rc = SQLITE_ERROR;
    76     76         sqlite3_finalize(p->pStmt);
    77     77         p->pStmt = 0;
    78     78       }else{
    79     79         p->iOffset = pC->aType[p->iCol + pC->nField];
    80     80         p->nByte = sqlite3VdbeSerialTypeLen(type);
    81     81         p->pCsr =  pC->pCursor;
    82         -      sqlite3BtreeEnterCursor(p->pCsr);
    83         -      sqlite3BtreeCacheOverflow(p->pCsr);
    84         -      sqlite3BtreeLeaveCursor(p->pCsr);
           82  +      sqlite3BtreeIncrblobCursor(p->pCsr);
    85     83       }
    86     84     }
    87     85   
    88     86     if( rc==SQLITE_ROW ){
    89     87       rc = SQLITE_OK;
    90     88     }else if( p->pStmt ){
    91     89       rc = sqlite3_finalize(p->pStmt);

Changes to src/where.c.

  2837   2837           disableTerm(pLevel, pLoop->aLTerm[j]);
  2838   2838         }
  2839   2839       }
  2840   2840       pLevel->op = OP_VNext;
  2841   2841       pLevel->p1 = iCur;
  2842   2842       pLevel->p2 = sqlite3VdbeCurrentAddr(v);
  2843   2843       sqlite3ReleaseTempRange(pParse, iReg, nConstraint+2);
  2844         -    sqlite3ExprCachePop(pParse, 1);
         2844  +    sqlite3ExprCachePop(pParse);
  2845   2845     }else
  2846   2846   #endif /* SQLITE_OMIT_VIRTUALTABLE */
  2847   2847   
  2848   2848     if( (pLoop->wsFlags & WHERE_IPK)!=0
  2849   2849      && (pLoop->wsFlags & (WHERE_COLUMN_IN|WHERE_COLUMN_EQ))!=0
  2850   2850     ){
  2851   2851       /* Case 2:  We can directly reference a single row using an
................................................................................
  3706   3706         WhereLoop *p = pWInfo->pLoops;
  3707   3707         pWInfo->pLoops = p->pNextLoop;
  3708   3708         whereLoopDelete(db, p);
  3709   3709       }
  3710   3710       sqlite3DbFree(db, pWInfo);
  3711   3711     }
  3712   3712   }
         3713  +
         3714  +/*
         3715  +** Return TRUE if the set of WHERE clause terms used by pA is a proper
         3716  +** subset of the WHERE clause terms used by pB.
         3717  +*/
         3718  +static int whereLoopProperSubset(const WhereLoop *pA, const WhereLoop *pB){
         3719  +  int i, j;
         3720  +  assert( pA->nLTerm<pB->nLTerm );  /* Checked by calling function */
         3721  +  for(j=0, i=pA->nLTerm-1; i>=0 && j>=0; i--){
         3722  +    for(j=pB->nLTerm-1; j>=0; j--){
         3723  +      if( pB->aLTerm[j]==pA->aLTerm[i] ) break;
         3724  +    }
         3725  +  }
         3726  +  return j>=0;
         3727  +}
         3728  +
         3729  +/*
         3730  +** Try to adjust the cost of WhereLoop pTemplate upwards or downwards so
         3731  +** that:
         3732  +**
         3733  +**   (1) pTemplate costs less than any other WhereLoops that are a proper
         3734  +**       subset of pTemplate
         3735  +**
         3736  +**   (2) pTemplate costs more than any other WhereLoops for which pTemplate
         3737  +**       is a proper subset.
         3738  +**
         3739  +** To say "WhereLoop X is a proper subset of Y" means that X uses fewer
         3740  +** WHERE clause terms than Y and that every WHERE clause term used by X is
         3741  +** also used by Y.
         3742  +*/
         3743  +static void whereLoopAdjustCost(const WhereLoop *p, WhereLoop *pTemplate){
         3744  +  if( (pTemplate->wsFlags & WHERE_INDEXED)==0 ) return;
         3745  +  for(; p; p=p->pNextLoop){
         3746  +    if( p->iTab!=pTemplate->iTab ) continue;
         3747  +    if( (p->wsFlags & WHERE_INDEXED)==0 ) continue;
         3748  +    if( p->nLTerm<pTemplate->nLTerm
         3749  +     && (p->rRun<pTemplate->rRun || (p->rRun==pTemplate->rRun &&
         3750  +                                     p->nOut<=pTemplate->nOut))
         3751  +     && whereLoopProperSubset(p, pTemplate)
         3752  +    ){
         3753  +      pTemplate->rRun = p->rRun;
         3754  +      pTemplate->nOut = p->nOut - 1;
         3755  +    }else
         3756  +    if( p->nLTerm>pTemplate->nLTerm
         3757  +     && (p->rRun>pTemplate->rRun || (p->rRun==pTemplate->rRun &&
         3758  +                                     p->nOut>=pTemplate->nOut))
         3759  +     && whereLoopProperSubset(pTemplate, p)
         3760  +    ){
         3761  +      pTemplate->rRun = p->rRun;
         3762  +      pTemplate->nOut = p->nOut + 1;
         3763  +    }
         3764  +  }
         3765  +}
         3766  +
         3767  +/*
         3768  +** Search the list of WhereLoops in *ppPrev looking for one that can be
         3769  +** supplanted by pTemplate.
         3770  +**
         3771  +** Return NULL if the WhereLoop list contains an entry that can supplant
         3772  +** pTemplate, in other words if pTemplate does not belong on the list.
         3773  +**
         3774  +** If pX is a WhereLoop that pTemplate can supplant, then return the
         3775  +** link that points to pX.
         3776  +**
         3777  +** If pTemplate cannot supplant any existing element of the list but needs
         3778  +** to be added to the list, then return a pointer to the tail of the list.
         3779  +*/
         3780  +static WhereLoop **whereLoopFindLesser(
         3781  +  WhereLoop **ppPrev,
         3782  +  const WhereLoop *pTemplate
         3783  +){
         3784  +  WhereLoop *p;
         3785  +  for(p=(*ppPrev); p; ppPrev=&p->pNextLoop, p=*ppPrev){
         3786  +    if( p->iTab!=pTemplate->iTab || p->iSortIdx!=pTemplate->iSortIdx ){
         3787  +      /* If either the iTab or iSortIdx values for two WhereLoop are different
         3788  +      ** then those WhereLoops need to be considered separately.  Neither is
         3789  +      ** a candidate to replace the other. */
         3790  +      continue;
         3791  +    }
         3792  +    /* In the current implementation, the rSetup value is either zero
         3793  +    ** or the cost of building an automatic index (NlogN) and the NlogN
         3794  +    ** is the same for compatible WhereLoops. */
         3795  +    assert( p->rSetup==0 || pTemplate->rSetup==0 
         3796  +                 || p->rSetup==pTemplate->rSetup );
         3797  +
         3798  +    /* whereLoopAddBtree() always generates and inserts the automatic index
         3799  +    ** case first.  Hence compatible candidate WhereLoops never have a larger
         3800  +    ** rSetup. Call this SETUP-INVARIANT */
         3801  +    assert( p->rSetup>=pTemplate->rSetup );
         3802  +
         3803  +    /* If existing WhereLoop p is better than pTemplate, pTemplate can be
         3804  +    ** discarded.  WhereLoop p is better if:
         3805  +    **   (1)  p has no more dependencies than pTemplate, and
         3806  +    **   (2)  p has an equal or lower cost than pTemplate
         3807  +    */
         3808  +    if( (p->prereq & pTemplate->prereq)==p->prereq    /* (1)  */
         3809  +     && p->rSetup<=pTemplate->rSetup                  /* (2a) */
         3810  +     && p->rRun<=pTemplate->rRun                      /* (2b) */
         3811  +     && p->nOut<=pTemplate->nOut                      /* (2c) */
         3812  +    ){
         3813  +      return 0;  /* Discard pTemplate */
         3814  +    }
         3815  +
         3816  +    /* If pTemplate is always better than p, then cause p to be overwritten
         3817  +    ** with pTemplate.  pTemplate is better than p if:
         3818  +    **   (1)  pTemplate has no more dependences than p, and
         3819  +    **   (2)  pTemplate has an equal or lower cost than p.
         3820  +    */
         3821  +    if( (p->prereq & pTemplate->prereq)==pTemplate->prereq   /* (1)  */
         3822  +     && p->rRun>=pTemplate->rRun                             /* (2a) */
         3823  +     && p->nOut>=pTemplate->nOut                             /* (2b) */
         3824  +    ){
         3825  +      assert( p->rSetup>=pTemplate->rSetup ); /* SETUP-INVARIANT above */
         3826  +      break;   /* Cause p to be overwritten by pTemplate */
         3827  +    }
         3828  +  }
         3829  +  return ppPrev;
         3830  +}
  3713   3831   
  3714   3832   /*
  3715   3833   ** Insert or replace a WhereLoop entry using the template supplied.
  3716   3834   **
  3717   3835   ** An existing WhereLoop entry might be overwritten if the new template
  3718   3836   ** is better and has fewer dependencies.  Or the template will be ignored
  3719   3837   ** and no insert will occur if an existing WhereLoop is faster and has
  3720   3838   ** fewer dependencies than the template.  Otherwise a new WhereLoop is
  3721   3839   ** added based on the template.
  3722   3840   **
  3723         -** If pBuilder->pOrSet is not NULL then we only care about only the
         3841  +** If pBuilder->pOrSet is not NULL then we care about only the
  3724   3842   ** prerequisites and rRun and nOut costs of the N best loops.  That
  3725   3843   ** information is gathered in the pBuilder->pOrSet object.  This special
  3726   3844   ** processing mode is used only for OR clause processing.
  3727   3845   **
  3728   3846   ** When accumulating multiple loops (when pBuilder->pOrSet is NULL) we
  3729   3847   ** still might overwrite similar loops with the new template if the
  3730         -** template is better.  Loops may be overwritten if the following 
         3848  +** new template is better.  Loops may be overwritten if the following 
  3731   3849   ** conditions are met:
  3732   3850   **
  3733   3851   **    (1)  They have the same iTab.
  3734   3852   **    (2)  They have the same iSortIdx.
  3735   3853   **    (3)  The template has same or fewer dependencies than the current loop
  3736   3854   **    (4)  The template has the same or lower cost than the current loop
  3737         -**    (5)  The template uses more terms of the same index but has no additional
  3738         -**         dependencies          
  3739   3855   */
  3740   3856   static int whereLoopInsert(WhereLoopBuilder *pBuilder, WhereLoop *pTemplate){
  3741         -  WhereLoop **ppPrev, *p, *pNext = 0;
         3857  +  WhereLoop **ppPrev, *p;
  3742   3858     WhereInfo *pWInfo = pBuilder->pWInfo;
  3743   3859     sqlite3 *db = pWInfo->pParse->db;
  3744   3860   
  3745   3861     /* If pBuilder->pOrSet is defined, then only keep track of the costs
  3746   3862     ** and prereqs.
  3747   3863     */
  3748   3864     if( pBuilder->pOrSet!=0 ){
................................................................................
  3757   3873         sqlite3DebugPrintf(x?"   or-%d:  ":"   or-X:  ", n);
  3758   3874         whereLoopPrint(pTemplate, pBuilder->pWC);
  3759   3875       }
  3760   3876   #endif
  3761   3877       return SQLITE_OK;
  3762   3878     }
  3763   3879   
  3764         -  /* Search for an existing WhereLoop to overwrite, or which takes
  3765         -  ** priority over pTemplate.
  3766         -  */
  3767         -  for(ppPrev=&pWInfo->pLoops, p=*ppPrev; p; ppPrev=&p->pNextLoop, p=*ppPrev){
  3768         -    if( p->iTab!=pTemplate->iTab || p->iSortIdx!=pTemplate->iSortIdx ){
  3769         -      /* If either the iTab or iSortIdx values for two WhereLoop are different
  3770         -      ** then those WhereLoops need to be considered separately.  Neither is
  3771         -      ** a candidate to replace the other. */
  3772         -      continue;
  3773         -    }
  3774         -    /* In the current implementation, the rSetup value is either zero
  3775         -    ** or the cost of building an automatic index (NlogN) and the NlogN
  3776         -    ** is the same for compatible WhereLoops. */
  3777         -    assert( p->rSetup==0 || pTemplate->rSetup==0 
  3778         -                 || p->rSetup==pTemplate->rSetup );
  3779         -
  3780         -    /* whereLoopAddBtree() always generates and inserts the automatic index
  3781         -    ** case first.  Hence compatible candidate WhereLoops never have a larger
  3782         -    ** rSetup. Call this SETUP-INVARIANT */
  3783         -    assert( p->rSetup>=pTemplate->rSetup );
  3784         -
  3785         -    if( (p->prereq & pTemplate->prereq)==p->prereq
  3786         -     && p->rSetup<=pTemplate->rSetup
  3787         -     && p->rRun<=pTemplate->rRun
  3788         -     && p->nOut<=pTemplate->nOut
  3789         -    ){
  3790         -      /* This branch taken when p is equal or better than pTemplate in 
  3791         -      ** all of (1) dependencies (2) setup-cost, (3) run-cost, and
  3792         -      ** (4) number of output rows. */
  3793         -      assert( p->rSetup==pTemplate->rSetup );
  3794         -      if( p->prereq==pTemplate->prereq
  3795         -       && p->nLTerm<pTemplate->nLTerm
  3796         -       && (p->wsFlags & pTemplate->wsFlags & WHERE_INDEXED)!=0
  3797         -       && (p->u.btree.pIndex==pTemplate->u.btree.pIndex
  3798         -          || pTemplate->rRun+p->nLTerm<=p->rRun+pTemplate->nLTerm)
  3799         -      ){
  3800         -        /* Overwrite an existing WhereLoop with an similar one that uses
  3801         -        ** more terms of the index */
  3802         -        pNext = p->pNextLoop;
  3803         -        break;
  3804         -      }else{
  3805         -        /* pTemplate is not helpful.
  3806         -        ** Return without changing or adding anything */
  3807         -        goto whereLoopInsert_noop;
  3808         -      }
  3809         -    }
  3810         -    if( (p->prereq & pTemplate->prereq)==pTemplate->prereq
  3811         -     && p->rRun>=pTemplate->rRun
  3812         -     && p->nOut>=pTemplate->nOut
  3813         -    ){
  3814         -      /* Overwrite an existing WhereLoop with a better one: one that is
  3815         -      ** better at one of (1) dependencies, (2) setup-cost, (3) run-cost
  3816         -      ** or (4) number of output rows, and is no worse in any of those
  3817         -      ** categories. */
  3818         -      assert( p->rSetup>=pTemplate->rSetup ); /* SETUP-INVARIANT above */
  3819         -      pNext = p->pNextLoop;
  3820         -      break;
  3821         -    }
         3880  +  /* Look for an existing WhereLoop to replace with pTemplate
         3881  +  */
         3882  +  whereLoopAdjustCost(pWInfo->pLoops, pTemplate);
         3883  +  ppPrev = whereLoopFindLesser(&pWInfo->pLoops, pTemplate);
         3884  +
         3885  +  if( ppPrev==0 ){
         3886  +    /* There already exists a WhereLoop on the list that is better
         3887  +    ** than pTemplate, so just ignore pTemplate */
         3888  +#if WHERETRACE_ENABLED /* 0x8 */
         3889  +    if( sqlite3WhereTrace & 0x8 ){
         3890  +      sqlite3DebugPrintf("ins-noop: ");
         3891  +      whereLoopPrint(pTemplate, pBuilder->pWC);
         3892  +    }
         3893  +#endif
         3894  +    return SQLITE_OK;  
         3895  +  }else{
         3896  +    p = *ppPrev;
  3822   3897     }
  3823   3898   
  3824   3899     /* If we reach this point it means that either p[] should be overwritten
  3825   3900     ** with pTemplate[] if p[] exists, or if p==NULL then allocate a new
  3826   3901     ** WhereLoop and insert it.
  3827   3902     */
  3828   3903   #if WHERETRACE_ENABLED /* 0x8 */
................................................................................
  3832   3907         whereLoopPrint(p, pBuilder->pWC);
  3833   3908       }
  3834   3909       sqlite3DebugPrintf("ins-new:  ");
  3835   3910       whereLoopPrint(pTemplate, pBuilder->pWC);
  3836   3911     }
  3837   3912   #endif
  3838   3913     if( p==0 ){
  3839         -    p = sqlite3DbMallocRaw(db, sizeof(WhereLoop));
         3914  +    /* Allocate a new WhereLoop to add to the end of the list */
         3915  +    *ppPrev = p = sqlite3DbMallocRaw(db, sizeof(WhereLoop));
  3840   3916       if( p==0 ) return SQLITE_NOMEM;
  3841   3917       whereLoopInit(p);
         3918  +    p->pNextLoop = 0;
         3919  +  }else{
         3920  +    /* We will be overwriting WhereLoop p[].  But before we do, first
         3921  +    ** go through the rest of the list and delete any other entries besides
         3922  +    ** p[] that are also supplated by pTemplate */
         3923  +    WhereLoop **ppTail = &p->pNextLoop;
         3924  +    WhereLoop *pToDel;
         3925  +    while( *ppTail ){
         3926  +      ppTail = whereLoopFindLesser(ppTail, pTemplate);
         3927  +      if( NEVER(ppTail==0) ) break;
         3928  +      pToDel = *ppTail;
         3929  +      if( pToDel==0 ) break;
         3930  +      *ppTail = pToDel->pNextLoop;
         3931  +#if WHERETRACE_ENABLED /* 0x8 */
         3932  +      if( sqlite3WhereTrace & 0x8 ){
         3933  +        sqlite3DebugPrintf("ins-del: ");
         3934  +        whereLoopPrint(pToDel, pBuilder->pWC);
         3935  +      }
         3936  +#endif
         3937  +      whereLoopDelete(db, pToDel);
         3938  +    }
  3842   3939     }
  3843   3940     whereLoopXfer(db, p, pTemplate);
  3844         -  p->pNextLoop = pNext;
  3845         -  *ppPrev = p;
  3846   3941     if( (p->wsFlags & WHERE_VIRTUALTABLE)==0 ){
  3847   3942       Index *pIndex = p->u.btree.pIndex;
  3848   3943       if( pIndex && pIndex->tnum==0 ){
  3849   3944         p->u.btree.pIndex = 0;
  3850   3945       }
  3851   3946     }
  3852   3947     return SQLITE_OK;
  3853         -
  3854         -  /* Jump here if the insert is a no-op */
  3855         -whereLoopInsert_noop:
  3856         -#if WHERETRACE_ENABLED /* 0x8 */
  3857         -  if( sqlite3WhereTrace & 0x8 ){
  3858         -    sqlite3DebugPrintf("ins-noop: ");
  3859         -    whereLoopPrint(pTemplate, pBuilder->pWC);
  3860         -  }
  3861         -#endif
  3862         -  return SQLITE_OK;  
  3863   3948   }
  3864   3949   
  3865   3950   /*
  3866   3951   ** Adjust the WhereLoop.nOut value downward to account for terms of the
  3867   3952   ** WHERE clause that reference the loop but which are not used by an
  3868   3953   ** index.
  3869   3954   **

Changes to test/alter.test.

   870    870     INSERT INTO t16a VALUES('cba',5.5,98,'fizzle');
   871    871     SELECT * FROM t16a ORDER BY a;
   872    872   } {abc 1.25 99 xyzzy cba 5.5 98 fizzle}
   873    873   do_execsql_test alter-16.2 {
   874    874     ALTER TABLE t16a RENAME TO t16a_rn;
   875    875     SELECT * FROM t16a_rn ORDER BY a;
   876    876   } {abc 1.25 99 xyzzy cba 5.5 98 fizzle}
          877  +
          878  +#-------------------------------------------------------------------------
          879  +# Verify that NULL values into the internal-use-only sqlite_rename_*()
          880  +# functions do not cause problems.
          881  +#
          882  +do_execsql_test alter-17.1 {
          883  +  SELECT sqlite_rename_table('CREATE TABLE xyz(a,b,c)','abc');
          884  +} {{CREATE TABLE "abc"(a,b,c)}}
          885  +do_execsql_test alter-17.2 {
          886  +  SELECT sqlite_rename_table('CREATE TABLE xyz(a,b,c)',NULL);
          887  +} {{CREATE TABLE "(NULL)"(a,b,c)}}
          888  +do_execsql_test alter-17.3 {
          889  +  SELECT sqlite_rename_table(NULL,'abc');
          890  +} {{}}
          891  +do_execsql_test alter-17.4 {
          892  +  SELECT sqlite_rename_trigger('CREATE TRIGGER r1 ON xyz WHEN','abc');
          893  +} {{CREATE TRIGGER r1 ON "abc" WHEN}}
          894  +do_execsql_test alter-17.5 {
          895  +  SELECT sqlite_rename_trigger('CREATE TRIGGER r1 ON xyz WHEN',NULL);
          896  +} {{CREATE TRIGGER r1 ON "(NULL)" WHEN}}
          897  +do_execsql_test alter-17.6 {
          898  +  SELECT sqlite_rename_trigger(NULL,'abc');
          899  +} {{}}
          900  +do_execsql_test alter-17.7 {
          901  +  SELECT sqlite_rename_parent('CREATE TABLE t1(a REFERENCES "xyzzy")',
          902  +         'xyzzy','lmnop');
          903  +} {{CREATE TABLE t1(a REFERENCES "lmnop")}}
          904  +do_execsql_test alter-17.8 {
          905  +  SELECT sqlite_rename_parent('CREATE TABLE t1(a REFERENCES "xyzzy")',
          906  +         'xyzzy',NULL);
          907  +} {{CREATE TABLE t1(a REFERENCES "(NULL)")}}
          908  +do_execsql_test alter-17.9 {
          909  +  SELECT sqlite_rename_parent('CREATE TABLE t1(a REFERENCES "xyzzy")',
          910  +         NULL, 'lmnop');
          911  +} {{}}
          912  +do_execsql_test alter-17.10 {
          913  +  SELECT sqlite_rename_parent(NULL,'abc','xyz');
          914  +} {{}}
   877    915   
   878    916   finish_test

Changes to test/func.test.

  1297   1297   do_test func-29.3 {
  1298   1298     db close
  1299   1299     sqlite3 db test.db
  1300   1300     sqlite3_db_status db CACHE_MISS 1
  1301   1301     db eval {SELECT typeof(+x) FROM t29 ORDER BY id}
  1302   1302   } {integer null real blob text}
  1303   1303   if {[permutation] != "mmap"} {
  1304         -  do_test func-29.4 {
  1305         -    set x [lindex [sqlite3_db_status db CACHE_MISS 1] 1]
  1306         -    if {$x>100} {set x many}
  1307         -    set x
  1308         -  } {many}
         1304  +  ifcapable !direct_read {
         1305  +    do_test func-29.4 {
         1306  +      set x [lindex [sqlite3_db_status db CACHE_MISS 1] 1]
         1307  +      if {$x>100} {set x many}
         1308  +      set x
         1309  +    } {many}
         1310  +  }
  1309   1311   }
  1310   1312   do_test func-29.5 {
  1311   1313     db close
  1312   1314     sqlite3 db test.db
  1313   1315     sqlite3_db_status db CACHE_MISS 1
  1314   1316     db eval {SELECT sum(length(x)) FROM t29}
  1315   1317   } {1000009}

Changes to test/index6.test.

   243    243   do_execsql_test index6-5.0 {
   244    244     CREATE INDEX t3b ON t3(b) WHERE xyzzy.t3.b BETWEEN 5 AND 10;
   245    245                                  /* ^^^^^-- ignored */
   246    246     ANALYZE;
   247    247     SELECT count(*) FROM t3 WHERE t3.b BETWEEN 5 AND 10;
   248    248     SELECT stat+0 FROM sqlite_stat1 WHERE idx='t3b';
   249    249   } {6 6}
          250  +
          251  +# Test case for ticket [2ea3e9fe6379fc3f6ce7e090ce483c1a3a80d6c9] from
          252  +# 2014-04-13: Partial index causes assertion fault on UPDATE OR REPLACE.
          253  +#
          254  +do_execsql_test index6-6.0 {
          255  +  CREATE TABLE t6(a,b);
          256  +  CREATE UNIQUE INDEX t6ab ON t1(a,b);
          257  +  CREATE INDEX t6b ON t6(b) WHERE b=1;
          258  +  INSERT INTO t6(a,b) VALUES(123,456);
          259  +  SELECT * FROM t6;
          260  +} {123 456}
          261  +do_execsql_test index6-6.1 {
          262  +  UPDATE OR REPLACE t6 SET b=789;
          263  +  SELECT * FROM t6;
          264  +} {123 789}
          265  +do_execsql_test index6-6.2 {
          266  +  PRAGMA integrity_check;
          267  +} {ok}
          268  +
   250    269   
   251    270   finish_test

Changes to test/wal.test.

  1569   1569     } [wal_file_size 1 1024]
  1570   1570   }
  1571   1571   
  1572   1572   db close
  1573   1573   sqlite3_shutdown
  1574   1574   test_sqlite3_log
  1575   1575   sqlite3_initialize
         1576  +
         1577  +# Make sure PRAGMA journal_mode=WAL works with ATTACHED databases in
         1578  +# all journal modes.
         1579  +#
         1580  +foreach mode {OFF MEMORY PERSIST DELETE TRUNCATE WAL} {
         1581  +  delete_file test.db test2.db
         1582  +  sqlite3 db test.db
         1583  +  do_test wal-25.$mode {
         1584  +    db eval "PRAGMA journal_mode=$mode"
         1585  +    db eval {ATTACH 'test2.db' AS t2; PRAGMA journal_mode=WAL;}
         1586  +  } {wal}
         1587  +  db close
         1588  +}
  1576   1589   
  1577   1590   finish_test

Changes to test/whereD.test.

   213    213   } {3 4 3 4}
   214    214   do_execsql_test 4.7 {
   215    215     SELECT * FROM t44 LEFT JOIN t46 ON a=c
   216    216      WHERE d=4 OR d IS NULL
   217    217      ORDER BY a;
   218    218   } {3 4 3 4}
   219    219   
          220  +# Verify fix of a bug reported on the mailing list by Peter Reid
          221  +#
          222  +do_execsql_test 5.1 {
          223  +  DROP TABLE IF EXISTS t;
          224  +  CREATE TABLE t(c0,c1,c2,c3,c4,c5,c6,c7,c8,c9,c10,c11,c12,c13,c14,c15,c16,c17);
          225  +  CREATE INDEX tc0 ON t(c0);
          226  +  CREATE INDEX tc1 ON t(c1);
          227  +  CREATE INDEX tc2 ON t(c2);
          228  +  CREATE INDEX tc3 ON t(c3);
          229  +  CREATE INDEX tc4 ON t(c4);
          230  +  CREATE INDEX tc5 ON t(c5);
          231  +  CREATE INDEX tc6 ON t(c6);
          232  +  CREATE INDEX tc7 ON t(c7);
          233  +  CREATE INDEX tc8 ON t(c8);
          234  +  CREATE INDEX tc9 ON t(c9);
          235  +  CREATE INDEX tc10 ON t(c10);
          236  +  CREATE INDEX tc11 ON t(c11);
          237  +  CREATE INDEX tc12 ON t(c12);
          238  +  CREATE INDEX tc13 ON t(c13);
          239  +  CREATE INDEX tc14 ON t(c14);
          240  +  CREATE INDEX tc15 ON t(c15);
          241  +  CREATE INDEX tc16 ON t(c16);
          242  +  CREATE INDEX tc17 ON t(c17);
          243  +  
          244  +  INSERT INTO t(c0, c16) VALUES (1,1);
          245  +  
          246  +  SELECT * FROM t WHERE
          247  +    c0=1 or  c1=1 or  c2=1 or  c3=1 or
          248  +    c4=1 or  c5=1 or  c6=1 or  c7=1 or
          249  +    c8=1 or  c9=1 or c10=1 or c11=1 or
          250  +    c12=1 or c13=1 or c14=1 or c15=1 or
          251  +    c16=1 or c17=1;
          252  +} {1 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 1 {}}
          253  +do_execsql_test 5.2 {
          254  +  DELETE FROM t;
          255  +  INSERT INTO t(c0,c17) VALUES(1,1);
          256  +  SELECT * FROM t WHERE
          257  +    c0=1 or  c1=1 or  c2=1 or  c3=1 or
          258  +    c4=1 or  c5=1 or  c6=1 or  c7=1 or
          259  +    c8=1 or  c9=1 or c10=1 or c11=1 or
          260  +    c12=1 or c13=1 or c14=1 or c15=1 or
          261  +    c16=1 or c17=1;
          262  +} {1 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 1}
          263  +do_execsql_test 5.3 {
          264  +  DELETE FROM t;
          265  +  INSERT INTO t(c0,c15) VALUES(1,1);
          266  +  SELECT * FROM t WHERE
          267  +    c0=1 or  c1=1 or  c2=1 or  c3=1 or
          268  +    c4=1 or  c5=1 or  c6=1 or  c7=1 or
          269  +    c8=1 or  c9=1 or c10=1 or c11=1 or
          270  +    c12=1 or c13=1 or c14=1 or c15=1 or
          271  +    c16=1 or c17=1;
          272  +} {1 {} {} {} {} {} {} {} {} {} {} {} {} {} {} 1 {} {}}
   220    273   
   221    274   
   222    275   finish_test

Added test/whereH.test.

            1  +# 2014-03-31
            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  +# 
           12  +# Test cases for query planning decisions where one candidate index
           13  +# covers a proper superset of the WHERE clause terms of another
           14  +# candidate index.
           15  +#
           16  +
           17  +set testdir [file dirname $argv0]
           18  +source $testdir/tester.tcl
           19  +
           20  +do_execsql_test whereH-1.1 {
           21  +  CREATE TABLE t1(a,b,c,d);
           22  +  CREATE INDEX t1abc ON t1(a,b,c);
           23  +  CREATE INDEX t1bc ON t1(b,c);
           24  +
           25  +  EXPLAIN QUERY PLAN
           26  +  SELECT d FROM t1 WHERE a=? AND b=? AND c>=? ORDER BY c;
           27  +} {/INDEX t1abc /}
           28  +do_execsql_test whereH-1.2 {
           29  +  EXPLAIN QUERY PLAN
           30  +  SELECT d FROM t1 WHERE a=? AND b=? AND c>=? ORDER BY c;
           31  +} {~/TEMP B-TREE FOR ORDER BY/}
           32  +
           33  +do_execsql_test whereH-2.1 {
           34  +  DROP TABLE t1;
           35  +  CREATE TABLE t1(a,b,c,d);
           36  +  CREATE INDEX t1bc ON t1(b,c);
           37  +  CREATE INDEX t1abc ON t1(a,b,c);
           38  +
           39  +  EXPLAIN QUERY PLAN
           40  +  SELECT d FROM t1 WHERE a=? AND b=? AND c>=? ORDER BY c;
           41  +} {/INDEX t1abc /}
           42  +do_execsql_test whereH-2.2 {
           43  +  EXPLAIN QUERY PLAN
           44  +  SELECT d FROM t1 WHERE a=? AND b=? AND c>=? ORDER BY c;
           45  +} {~/TEMP B-TREE FOR ORDER BY/}
           46  +
           47  +do_execsql_test whereH-3.1 {
           48  +  DROP TABLE t1;
           49  +  CREATE TABLE t1(a,b,c,d,e);
           50  +  CREATE INDEX t1cd ON t1(c,d);
           51  +  CREATE INDEX t1bcd ON t1(b,c,d);
           52  +  CREATE INDEX t1abcd ON t1(a,b,c,d);
           53  +
           54  +  EXPLAIN QUERY PLAN
           55  +  SELECT d FROM t1 WHERE a=? AND b=? AND c=? AND d>=? ORDER BY d;
           56  +} {/INDEX t1abcd /}
           57  +do_execsql_test whereH-3.2 {
           58  +  EXPLAIN QUERY PLAN
           59  +  SELECT d FROM t1 WHERE a=? AND b=? AND c=? AND d>=? ORDER BY d;
           60  +} {~/TEMP B-TREE FOR ORDER BY/}
           61  +
           62  +do_execsql_test whereH-4.1 {
           63  +  DROP TABLE t1;
           64  +  CREATE TABLE t1(a,b,c,d,e);
           65  +  CREATE INDEX t1cd ON t1(c,d);
           66  +  CREATE INDEX t1abcd ON t1(a,b,c,d);
           67  +  CREATE INDEX t1bcd ON t1(b,c,d);
           68  +
           69  +  EXPLAIN QUERY PLAN
           70  +  SELECT d FROM t1 WHERE a=? AND b=? AND c=? AND d>=? ORDER BY d;
           71  +} {/INDEX t1abcd /}
           72  +do_execsql_test whereH-4.2 {
           73  +  EXPLAIN QUERY PLAN
           74  +  SELECT d FROM t1 WHERE a=? AND b=? AND c=? AND d>=? ORDER BY d;
           75  +} {~/TEMP B-TREE FOR ORDER BY/}
           76  +
           77  +do_execsql_test whereH-5.1 {
           78  +  DROP TABLE t1;
           79  +  CREATE TABLE t1(a,b,c,d,e);
           80  +  CREATE INDEX t1bcd ON t1(b,c,d);
           81  +  CREATE INDEX t1cd ON t1(c,d);
           82  +  CREATE INDEX t1abcd ON t1(a,b,c,d);
           83  +
           84  +  EXPLAIN QUERY PLAN
           85  +  SELECT d FROM t1 WHERE a=? AND b=? AND c=? AND d>=? ORDER BY d;
           86  +} {/INDEX t1abcd /}
           87  +do_execsql_test whereH-5.2 {
           88  +  EXPLAIN QUERY PLAN
           89  +  SELECT d FROM t1 WHERE a=? AND b=? AND c=? AND d>=? ORDER BY d;
           90  +} {~/TEMP B-TREE FOR ORDER BY/}
           91  +
           92  +do_execsql_test whereH-6.1 {
           93  +  DROP TABLE t1;
           94  +  CREATE TABLE t1(a,b,c,d,e);
           95  +  CREATE INDEX t1bcd ON t1(b,c,d);
           96  +  CREATE INDEX t1abcd ON t1(a,b,c,d);
           97  +  CREATE INDEX t1cd ON t1(c,d);
           98  +
           99  +  EXPLAIN QUERY PLAN
          100  +  SELECT d FROM t1 WHERE a=? AND b=? AND c=? AND d>=? ORDER BY d;
          101  +} {/INDEX t1abcd /}
          102  +do_execsql_test whereH-6.2 {
          103  +  EXPLAIN QUERY PLAN
          104  +  SELECT d FROM t1 WHERE a=? AND b=? AND c=? AND d>=? ORDER BY d;
          105  +} {~/TEMP B-TREE FOR ORDER BY/}
          106  +
          107  +do_execsql_test whereH-7.1 {
          108  +  DROP TABLE t1;
          109  +  CREATE TABLE t1(a,b,c,d,e);
          110  +  CREATE INDEX t1abcd ON t1(a,b,c,d);
          111  +  CREATE INDEX t1bcd ON t1(b,c,d);
          112  +  CREATE INDEX t1cd ON t1(c,d);
          113  +
          114  +  EXPLAIN QUERY PLAN
          115  +  SELECT d FROM t1 WHERE a=? AND b=? AND c=? AND d>=? ORDER BY d;
          116  +} {/INDEX t1abcd /}
          117  +do_execsql_test whereH-7.2 {
          118  +  EXPLAIN QUERY PLAN
          119  +  SELECT d FROM t1 WHERE a=? AND b=? AND c=? AND d>=? ORDER BY d;
          120  +} {~/TEMP B-TREE FOR ORDER BY/}
          121  +
          122  +do_execsql_test whereH-8.1 {
          123  +  DROP TABLE t1;
          124  +  CREATE TABLE t1(a,b,c,d,e);
          125  +  CREATE INDEX t1abcd ON t1(a,b,c,d);
          126  +  CREATE INDEX t1cd ON t1(c,d);
          127  +  CREATE INDEX t1bcd ON t1(b,c,d);
          128  +
          129  +  EXPLAIN QUERY PLAN
          130  +  SELECT d FROM t1 WHERE a=? AND b=? AND c=? AND d>=? ORDER BY d;
          131  +} {/INDEX t1abcd /}
          132  +do_execsql_test whereH-8.2 {
          133  +  EXPLAIN QUERY PLAN
          134  +  SELECT d FROM t1 WHERE a=? AND b=? AND c=? AND d>=? ORDER BY d;
          135  +} {~/TEMP B-TREE FOR ORDER BY/}
          136  +
          137  +
          138  +
          139  +finish_test