/ Check-in [83d4114f]
Login

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

Overview
Comment:Merge recent trunk micro-optimizations and the DESC index GROUP BY ORDER BY bug fix into the sessions branch.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | sessions
Files: files | file ages | folders
SHA1: 83d4114f2aa404e670ced33511183baacd813a01
User & Date: drh 2014-10-14 13:41:32
Context
2014-10-15
19:37
Merge latest trunk changes with this branch. check-in: 1b2824f1 user: dan tags: sessions
2014-10-14
13:41
Merge recent trunk micro-optimizations and the DESC index GROUP BY ORDER BY bug fix into the sessions branch. check-in: 83d4114f user: drh tags: sessions
2014-10-13
23:39
Optimize a database corruption test inside of the OP_Column opcode. check-in: 005e5b38 user: drh tags: trunk
2014-10-10
12:56
Merge all recent trunk changes. check-in: abfef254 user: drh tags: sessions
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/btree.c.

   772    772   **
   773    773   ** Calling this routine with a NULL cursor pointer returns false.
   774    774   **
   775    775   ** Use the separate sqlite3BtreeCursorRestore() routine to restore a cursor
   776    776   ** back to where it ought to be if this routine returns true.
   777    777   */
   778    778   int sqlite3BtreeCursorHasMoved(BtCursor *pCur){
   779         -  return pCur && pCur->eState!=CURSOR_VALID;
          779  +  return pCur->eState!=CURSOR_VALID;
   780    780   }
   781    781   
   782    782   /*
   783    783   ** This routine restores a cursor back to its original position after it
   784    784   ** has been moved by some outside activity (such as a btree rebalance or
   785    785   ** a row having been deleted out from under the cursor).  
   786    786   **
................................................................................
  5841   5841   ** If the cell content will fit on the page, then put it there.  If it
  5842   5842   ** will not fit, then make a copy of the cell content into pTemp if
  5843   5843   ** pTemp is not null.  Regardless of pTemp, allocate a new entry
  5844   5844   ** in pPage->apOvfl[] and make it point to the cell content (either
  5845   5845   ** in pTemp or the original pCell) and also record its index. 
  5846   5846   ** Allocating a new entry in pPage->aCell[] implies that 
  5847   5847   ** pPage->nOverflow is incremented.
  5848         -**
  5849         -** If nSkip is non-zero, then do not copy the first nSkip bytes of the
  5850         -** cell. The caller will overwrite them after this function returns. If
  5851         -** nSkip is non-zero, then pCell may not point to an invalid memory location 
  5852         -** (but pCell+nSkip is always valid).
  5853   5848   */
  5854   5849   static void insertCell(
  5855   5850     MemPage *pPage,   /* Page into which we are copying */
  5856   5851     int i,            /* New cell becomes the i-th cell of the page */
  5857   5852     u8 *pCell,        /* Content of the new cell */
  5858   5853     int sz,           /* Bytes of content in pCell */
  5859   5854     u8 *pTemp,        /* Temp storage space for pCell, if needed */
................................................................................
  5862   5857   ){
  5863   5858     int idx = 0;      /* Where to write new cell content in data[] */
  5864   5859     int j;            /* Loop counter */
  5865   5860     int end;          /* First byte past the last cell pointer in data[] */
  5866   5861     int ins;          /* Index in data[] where new cell pointer is inserted */
  5867   5862     int cellOffset;   /* Address of first cell pointer in data[] */
  5868   5863     u8 *data;         /* The content of the whole page */
  5869         -  int nSkip = (iChild ? 4 : 0);
  5870   5864   
  5871   5865     if( *pRC ) return;
  5872   5866   
  5873   5867     assert( i>=0 && i<=pPage->nCell+pPage->nOverflow );
  5874   5868     assert( MX_CELL(pPage->pBt)<=10921 );
  5875   5869     assert( pPage->nCell<=MX_CELL(pPage->pBt) || CORRUPT_DB );
  5876   5870     assert( pPage->nOverflow<=ArraySize(pPage->apOvfl) );
................................................................................
  5880   5874     ** malformed cell from a leaf page to an interior page, if the cell size
  5881   5875     ** wanted to be less than 4 but got rounded up to 4 on the leaf, then size
  5882   5876     ** might be less than 8 (leaf-size + pointer) on the interior node.  Hence
  5883   5877     ** the term after the || in the following assert(). */
  5884   5878     assert( sz==cellSizePtr(pPage, pCell) || (sz==8 && iChild>0) );
  5885   5879     if( pPage->nOverflow || sz+2>pPage->nFree ){
  5886   5880       if( pTemp ){
  5887         -      memcpy(pTemp+nSkip, pCell+nSkip, sz-nSkip);
         5881  +      memcpy(pTemp, pCell, sz);
  5888   5882         pCell = pTemp;
  5889   5883       }
  5890   5884       if( iChild ){
  5891   5885         put4byte(pCell, iChild);
  5892   5886       }
  5893   5887       j = pPage->nOverflow++;
  5894   5888       assert( j<(int)(sizeof(pPage->apOvfl)/sizeof(pPage->apOvfl[0])) );
................................................................................
  5909   5903       if( rc ){ *pRC = rc; return; }
  5910   5904       /* The allocateSpace() routine guarantees the following two properties
  5911   5905       ** if it returns success */
  5912   5906       assert( idx >= end+2 );
  5913   5907       assert( idx+sz <= (int)pPage->pBt->usableSize );
  5914   5908       pPage->nCell++;
  5915   5909       pPage->nFree -= (u16)(2 + sz);
  5916         -    memcpy(&data[idx+nSkip], pCell+nSkip, sz-nSkip);
         5910  +    memcpy(&data[idx], pCell, sz);
  5917   5911       if( iChild ){
  5918   5912         put4byte(&data[idx], iChild);
  5919   5913       }
  5920   5914       memmove(&data[ins+2], &data[ins], end-ins);
  5921   5915       put2byte(&data[ins], idx);
  5922   5916       put2byte(&data[pPage->hdrOffset+3], pPage->nCell);
  5923   5917   #ifndef SQLITE_OMIT_AUTOVACUUM

Changes to src/build.c.

  2743   2743       addr2 = sqlite3VdbeCurrentAddr(v);
  2744   2744       sqlite3VdbeAddOp4Int(v, OP_SorterCompare, iSorter, j2, regRecord,
  2745   2745                            pIndex->nKeyCol); VdbeCoverage(v);
  2746   2746       sqlite3UniqueConstraint(pParse, OE_Abort, pIndex);
  2747   2747     }else{
  2748   2748       addr2 = sqlite3VdbeCurrentAddr(v);
  2749   2749     }
  2750         -  sqlite3VdbeAddOp2(v, OP_SorterData, iSorter, regRecord);
         2750  +  sqlite3VdbeAddOp3(v, OP_SorterData, iSorter, regRecord, iIdx);
  2751   2751     sqlite3VdbeAddOp3(v, OP_IdxInsert, iIdx, regRecord, 1);
  2752   2752     sqlite3VdbeChangeP5(v, OPFLAG_USESEEKRESULT);
  2753   2753     sqlite3ReleaseTempReg(pParse, regRecord);
  2754   2754     sqlite3VdbeAddOp2(v, OP_SorterNext, iSorter, addr2); VdbeCoverage(v);
  2755   2755     sqlite3VdbeJumpHere(v, addr1);
  2756   2756   
  2757   2757     sqlite3VdbeAddOp1(v, OP_Close, iTab);

Changes to src/pcache1.c.

   684    684     assert( pCache->nPage >= pCache->nRecyclable );
   685    685     nPinned = pCache->nPage - pCache->nRecyclable;
   686    686     assert( pGroup->mxPinned == pGroup->nMaxPage + 10 - pGroup->nMinPage );
   687    687     assert( pCache->n90pct == pCache->nMax*9/10 );
   688    688     if( createFlag==1 && (
   689    689           nPinned>=pGroup->mxPinned
   690    690        || nPinned>=pCache->n90pct
   691         -     || pcache1UnderMemoryPressure(pCache)
          691  +     || (pcache1UnderMemoryPressure(pCache) && pCache->nRecyclable<nPinned)
   692    692     )){
   693    693       return 0;
   694    694     }
   695    695   
   696    696     if( pCache->nPage>=pCache->nHash ) pcache1ResizeHash(pCache);
   697    697     assert( pCache->nHash>0 && pCache->apHash );
   698    698   

Changes to src/select.c.

  1177   1177     int eDest = pDest->eDest;
  1178   1178     int iParm = pDest->iSDParm;
  1179   1179     int regRow;
  1180   1180     int regRowid;
  1181   1181     int nKey;
  1182   1182     int iSortTab;                   /* Sorter cursor to read from */
  1183   1183     int nSortData;                  /* Trailing values to read from sorter */
  1184         -  u8 p5;                          /* p5 parameter for 1st OP_Column */
  1185   1184     int i;
  1186   1185     int bSeq;                       /* True if sorter record includes seq. no. */
  1187   1186   #ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS
  1188   1187     struct ExprList_item *aOutEx = p->pEList->a;
  1189   1188   #endif
  1190   1189   
  1191   1190     if( pSort->labelBkOut ){
................................................................................
  1211   1210         addrOnce = sqlite3CodeOnce(pParse); VdbeCoverage(v);
  1212   1211       }
  1213   1212       sqlite3VdbeAddOp3(v, OP_OpenPseudo, iSortTab, regSortOut, nKey+1+nSortData);
  1214   1213       if( addrOnce ) sqlite3VdbeJumpHere(v, addrOnce);
  1215   1214       addr = 1 + sqlite3VdbeAddOp2(v, OP_SorterSort, iTab, addrBreak);
  1216   1215       VdbeCoverage(v);
  1217   1216       codeOffset(v, p->iOffset, addrContinue);
  1218         -    sqlite3VdbeAddOp2(v, OP_SorterData, iTab, regSortOut);
  1219         -    p5 = OPFLAG_CLEARCACHE;
         1217  +    sqlite3VdbeAddOp3(v, OP_SorterData, iTab, regSortOut, iSortTab);
  1220   1218       bSeq = 0;
  1221   1219     }else{
  1222   1220       addr = 1 + sqlite3VdbeAddOp2(v, OP_Sort, iTab, addrBreak); VdbeCoverage(v);
  1223   1221       codeOffset(v, p->iOffset, addrContinue);
  1224   1222       iSortTab = iTab;
  1225         -    p5 = 0;
  1226   1223       bSeq = 1;
  1227   1224     }
  1228   1225     for(i=0; i<nSortData; i++){
  1229   1226       sqlite3VdbeAddOp3(v, OP_Column, iSortTab, nKey+bSeq+i, regRow+i);
  1230         -    if( i==0 ) sqlite3VdbeChangeP5(v, p5);
  1231   1227       VdbeComment((v, "%s", aOutEx[i].zName ? aOutEx[i].zName : aOutEx[i].zSpan));
  1232   1228     }
  1233   1229     switch( eDest ){
  1234   1230       case SRT_Table:
  1235   1231       case SRT_EphemTab: {
  1236   1232         testcase( eDest==SRT_Table );
  1237   1233         testcase( eDest==SRT_EphemTab );
................................................................................
  5152   5148         ** (b0 is memory location iBMem+0, b1 is iBMem+1, and so forth)
  5153   5149         ** Then compare the current GROUP BY terms against the GROUP BY terms
  5154   5150         ** from the previous row currently stored in a0, a1, a2...
  5155   5151         */
  5156   5152         addrTopOfLoop = sqlite3VdbeCurrentAddr(v);
  5157   5153         sqlite3ExprCacheClear(pParse);
  5158   5154         if( groupBySort ){
  5159         -        sqlite3VdbeAddOp2(v, OP_SorterData, sAggInfo.sortingIdx, sortOut);
         5155  +        sqlite3VdbeAddOp3(v, OP_SorterData, sAggInfo.sortingIdx, sortOut,sortPTab);
  5160   5156         }
  5161   5157         for(j=0; j<pGroupBy->nExpr; j++){
  5162   5158           if( groupBySort ){
  5163   5159             sqlite3VdbeAddOp3(v, OP_Column, sortPTab, j, iBMem+j);
  5164         -          if( j==0 ) sqlite3VdbeChangeP5(v, OPFLAG_CLEARCACHE);
  5165   5160           }else{
  5166   5161             sAggInfo.directMode = 1;
  5167   5162             sqlite3ExprCode(pParse, pGroupBy->a[j].pExpr, iBMem+j);
  5168   5163           }
  5169   5164         }
  5170   5165         sqlite3VdbeAddOp4(v, OP_Compare, iAMem, iBMem, pGroupBy->nExpr,
  5171   5166                             (char*)sqlite3KeyInfoRef(pKeyInfo), P4_KEYINFO);

Changes to src/shell.c.

  4002   4002         if( p->echoOn ) printf("%s\n", zSql);
  4003   4003         nSql = 0;
  4004   4004       }
  4005   4005     }
  4006   4006     if( nSql ){
  4007   4007       if( !_all_whitespace(zSql) ){
  4008   4008         fprintf(stderr, "Error: incomplete SQL: %s\n", zSql);
         4009  +      errCnt++;
  4009   4010       }
  4010   4011       free(zSql);
  4011   4012     }
  4012   4013     free(zLine);
  4013   4014     return errCnt>0;
  4014   4015   }
  4015   4016   

Changes to src/sqliteInt.h.

   155    155   
   156    156   /*
   157    157   ** A macro to hint to the compiler that a function should not be
   158    158   ** inlined.
   159    159   */
   160    160   #if defined(__GNUC__)
   161    161   #  define SQLITE_NOINLINE  __attribute__((noinline))
   162         -#elif defined(_MSC_VER)
          162  +#elif defined(_MSC_VER) && _MSC_VER>=1310
   163    163   #  define SQLITE_NOINLINE  __declspec(noinline)
   164    164   #else
   165    165   #  define SQLITE_NOINLINE
   166    166   #endif
   167    167   
   168    168   /*
   169    169   ** The SQLITE_THREADSAFE macro must be defined as 0, 1, or 2.
................................................................................
  2673   2673   */
  2674   2674   #define OPFLAG_NCHANGE       0x01    /* Set to update db->nChange */
  2675   2675   #define OPFLAG_EPHEM         0x01    /* OP_Column: Ephemeral output is ok */
  2676   2676   #define OPFLAG_LASTROWID     0x02    /* Set to update db->lastRowid */
  2677   2677   #define OPFLAG_ISUPDATE      0x04    /* This OP_Insert is an sql UPDATE */
  2678   2678   #define OPFLAG_APPEND        0x08    /* This is likely to be an append */
  2679   2679   #define OPFLAG_USESEEKRESULT 0x10    /* Try to avoid a seek in BtreeInsert() */
  2680         -#define OPFLAG_CLEARCACHE    0x20    /* Clear pseudo-table cache in OP_Column */
  2681   2680   #define OPFLAG_ISNOOP        0x40    /* OP_Delete does pre-update-hook only */
  2682   2681   #define OPFLAG_LENGTHARG     0x40    /* OP_Column only used for length() */
  2683   2682   #define OPFLAG_TYPEOFARG     0x80    /* OP_Column only used for typeof() */
  2684   2683   #define OPFLAG_BULKCSR       0x01    /* OP_Open** used to open bulk cursor */
  2685   2684   #define OPFLAG_P2ISREG       0x02    /* P2 to OP_Open** is a register number */
  2686   2685   #define OPFLAG_PERMUTE       0x01    /* OP_Compare: use the permutation */
  2687   2686   

Changes to src/threads.c.

   101    101   #if SQLITE_OS_WIN && !SQLITE_OS_WINRT && SQLITE_THREADSAFE>0
   102    102   
   103    103   #define SQLITE_THREADS_IMPLEMENTED 1  /* Prevent the single-thread code below */
   104    104   #include <process.h>
   105    105   
   106    106   /* A running thread */
   107    107   struct SQLiteThread {
   108         -  uintptr_t tid;           /* The thread handle */
          108  +  void *tid;               /* The thread handle */
   109    109     unsigned id;             /* The thread identifier */
   110    110     void *(*xTask)(void*);   /* The routine to run as a thread */
   111    111     void *pIn;               /* Argument to xTask */
   112    112     void *pResult;           /* Result of xTask */
   113    113   };
   114    114   
   115    115   /* Thread procedure Win32 compatibility shim */
................................................................................
   149    149     p = sqlite3Malloc(sizeof(*p));
   150    150     if( p==0 ) return SQLITE_NOMEM;
   151    151     if( sqlite3GlobalConfig.bCoreMutex==0 ){
   152    152       memset(p, 0, sizeof(*p));
   153    153     }else{
   154    154       p->xTask = xTask;
   155    155       p->pIn = pIn;
   156         -    p->tid = _beginthreadex(0, 0, sqlite3ThreadProc, p, 0, &p->id);
          156  +    p->tid = (void*)_beginthreadex(0, 0, sqlite3ThreadProc, p, 0, &p->id);
   157    157       if( p->tid==0 ){
   158    158         memset(p, 0, sizeof(*p));
   159    159       }
   160    160     }
   161    161     if( p->xTask==0 ){
   162    162       p->id = GetCurrentThreadId();
   163    163       p->pResult = xTask(pIn);

Changes to src/vdbe.c.

   220    220       p->apCsr[iCur] = 0;
   221    221     }
   222    222     if( SQLITE_OK==sqlite3VdbeMemClearAndResize(pMem, nByte) ){
   223    223       p->apCsr[iCur] = pCx = (VdbeCursor*)pMem->z;
   224    224       memset(pCx, 0, sizeof(VdbeCursor));
   225    225       pCx->iDb = iDb;
   226    226       pCx->nField = nField;
          227  +    pCx->aOffset = &pCx->aType[nField];
   227    228       if( isBtreeCursor ){
   228    229         pCx->pCursor = (BtCursor*)
   229    230             &pMem->z[ROUND8(sizeof(VdbeCursor))+2*sizeof(u32)*nField];
   230    231         sqlite3BtreeCursorZero(pCx->pCursor);
   231    232       }
   232    233     }
   233    234     return pCx;
................................................................................
  2282   2283     assert( pOp->p3>0 && pOp->p3<=(p->nMem-p->nCursor) );
  2283   2284     pDest = &aMem[pOp->p3];
  2284   2285     memAboutToChange(p, pDest);
  2285   2286     assert( pOp->p1>=0 && pOp->p1<p->nCursor );
  2286   2287     pC = p->apCsr[pOp->p1];
  2287   2288     assert( pC!=0 );
  2288   2289     assert( p2<pC->nField );
  2289         -  aOffset = pC->aType + pC->nField;
         2290  +  aOffset = pC->aOffset;
  2290   2291   #ifndef SQLITE_OMIT_VIRTUALTABLE
  2291   2292     assert( pC->pVtabCursor==0 ); /* OP_Column never called on virtual table */
  2292   2293   #endif
  2293   2294     pCrsr = pC->pCursor;
  2294   2295     assert( pCrsr!=0 || pC->pseudoTableReg>0 ); /* pCrsr NULL on PseudoTables */
  2295   2296     assert( pCrsr!=0 || pC->nullRow );          /* pC->nullRow on PseudoTables */
  2296   2297   
  2297   2298     /* If the cursor cache is stale, bring it up-to-date */
  2298   2299     rc = sqlite3VdbeCursorMoveto(pC);
  2299   2300     if( rc ) goto abort_due_to_error;
  2300         -  if( pC->cacheStatus!=p->cacheCtr || (pOp->p5&OPFLAG_CLEARCACHE)!=0 ){
         2301  +  if( pC->cacheStatus!=p->cacheCtr ){
  2301   2302       if( pC->nullRow ){
  2302   2303         if( pCrsr==0 ){
  2303   2304           assert( pC->pseudoTableReg>0 );
  2304   2305           pReg = &aMem[pC->pseudoTableReg];
  2305   2306           assert( pReg->flags & MEM_Blob );
  2306   2307           assert( memIsValid(pReg) );
  2307   2308           pC->payloadSize = pC->szRow = avail = pReg->n;
................................................................................
  2338   2339           goto too_big;
  2339   2340         }
  2340   2341       }
  2341   2342       pC->cacheStatus = p->cacheCtr;
  2342   2343       pC->iHdrOffset = getVarint32(pC->aRow, offset);
  2343   2344       pC->nHdrParsed = 0;
  2344   2345       aOffset[0] = offset;
  2345         -    if( avail<offset ){
  2346         -      /* pC->aRow does not have to hold the entire row, but it does at least
  2347         -      ** need to cover the header of the record.  If pC->aRow does not contain
  2348         -      ** the complete header, then set it to zero, forcing the header to be
  2349         -      ** dynamically allocated. */
  2350         -      pC->aRow = 0;
  2351         -      pC->szRow = 0;
  2352         -    }
  2353   2346   
  2354   2347       /* Make sure a corrupt database has not given us an oversize header.
  2355   2348       ** Do this now to avoid an oversize memory allocation.
  2356   2349       **
  2357   2350       ** Type entries can be between 1 and 5 bytes each.  But 4 and 5 byte
  2358   2351       ** types use so much data space that there can only be 4096 and 32 of
  2359   2352       ** them, respectively.  So the maximum header length results from a
................................................................................
  2360   2353       ** 3-byte type for each of the maximum of 32768 columns plus three
  2361   2354       ** extra bytes for the header length itself.  32768*3 + 3 = 98307.
  2362   2355       */
  2363   2356       if( offset > 98307 || offset > pC->payloadSize ){
  2364   2357         rc = SQLITE_CORRUPT_BKPT;
  2365   2358         goto op_column_error;
  2366   2359       }
         2360  +
         2361  +    if( avail<offset ){
         2362  +      /* pC->aRow does not have to hold the entire row, but it does at least
         2363  +      ** need to cover the header of the record.  If pC->aRow does not contain
         2364  +      ** the complete header, then set it to zero, forcing the header to be
         2365  +      ** dynamically allocated. */
         2366  +      pC->aRow = 0;
         2367  +      pC->szRow = 0;
         2368  +    }
         2369  +
         2370  +    /* The following goto is an optimization.  It can be omitted and
         2371  +    ** everything will still work.  But OP_Column is measurably faster
         2372  +    ** by skipping the subsequent conditional, which is always true.
         2373  +    */
         2374  +    assert( pC->nHdrParsed<=p2 );         /* Conditional skipped */
         2375  +    goto op_column_read_header;
  2367   2376     }
  2368   2377   
  2369   2378     /* Make sure at least the first p2+1 entries of the header have been
  2370   2379     ** parsed and valid information is in aOffset[] and pC->aType[].
  2371   2380     */
  2372   2381     if( pC->nHdrParsed<=p2 ){
  2373   2382       /* If there is more header available for parsing in the record, try
  2374   2383       ** to extract additional fields up through the p2+1-th field 
  2375   2384       */
         2385  +    op_column_read_header:
  2376   2386       if( pC->iHdrOffset<aOffset[0] ){
  2377   2387         /* Make sure zData points to enough of the record to cover the header. */
  2378   2388         if( pC->aRow==0 ){
  2379   2389           memset(&sMem, 0, sizeof(sMem));
  2380   2390           rc = sqlite3VdbeMemFromBtree(pCrsr, 0, aOffset[0], 
  2381   2391                                        !pC->isTable, &sMem);
  2382   2392           if( rc!=SQLITE_OK ){
................................................................................
  2413   2423         pC->nHdrParsed = i;
  2414   2424         pC->iHdrOffset = (u32)(zHdr - zData);
  2415   2425         if( pC->aRow==0 ){
  2416   2426           sqlite3VdbeMemRelease(&sMem);
  2417   2427           sMem.flags = MEM_Null;
  2418   2428         }
  2419   2429     
  2420         -      /* If we have read more header data than was contained in the header,
  2421         -      ** or if the end of the last field appears to be past the end of the
  2422         -      ** record, or if the end of the last field appears to be before the end
  2423         -      ** of the record (when all fields present), then we must be dealing 
  2424         -      ** with a corrupt database.
         2430  +      /* The record is corrupt if any of the following are true:
         2431  +      ** (1) the bytes of the header extend past the declared header size
         2432  +      **          (zHdr>zEndHdr)
         2433  +      ** (2) the entire header was used but not all data was used
         2434  +      **          (zHdr==zEndHdr && offset!=pC->payloadSize)
         2435  +      ** (3) the end of the data extends beyond the end of the record.
         2436  +      **          (offset > pC->payloadSize)
  2425   2437         */
  2426         -      if( (zHdr > zEndHdr)
         2438  +      if( (zHdr>=zEndHdr && (zHdr>zEndHdr || offset!=pC->payloadSize))
  2427   2439          || (offset > pC->payloadSize)
  2428         -       || (zHdr==zEndHdr && offset!=pC->payloadSize)
  2429   2440         ){
  2430   2441           rc = SQLITE_CORRUPT_BKPT;
  2431   2442           goto op_column_error;
  2432   2443         }
  2433   2444       }
  2434   2445   
  2435   2446       /* If after trying to extra new entries from the header, nHdrParsed is
................................................................................
  2612   2623   
  2613   2624     /* Loop through the elements that will make up the record to figure
  2614   2625     ** out how much space is required for the new record.
  2615   2626     */
  2616   2627     pRec = pLast;
  2617   2628     do{
  2618   2629       assert( memIsValid(pRec) );
  2619         -    serial_type = sqlite3VdbeSerialType(pRec, file_format);
         2630  +    pRec->uTemp = serial_type = sqlite3VdbeSerialType(pRec, file_format);
  2620   2631       len = sqlite3VdbeSerialTypeLen(serial_type);
  2621   2632       if( pRec->flags & MEM_Zero ){
  2622   2633         if( nData ){
  2623   2634           sqlite3VdbeMemExpandBlob(pRec);
  2624   2635         }else{
  2625   2636           nZero += pRec->u.nZero;
  2626   2637           len -= pRec->u.nZero;
................................................................................
  2661   2672   
  2662   2673     /* Write the record */
  2663   2674     i = putVarint32(zNewRecord, nHdr);
  2664   2675     j = nHdr;
  2665   2676     assert( pData0<=pLast );
  2666   2677     pRec = pData0;
  2667   2678     do{
  2668         -    serial_type = sqlite3VdbeSerialType(pRec, file_format);
         2679  +    serial_type = pRec->uTemp;
  2669   2680       i += putVarint32(&zNewRecord[i], serial_type);            /* serial type */
  2670   2681       j += sqlite3VdbeSerialPut(&zNewRecord[j], pRec, serial_type); /* content */
  2671   2682     }while( (++pRec)<=pLast );
  2672   2683     assert( i==nHdr );
  2673   2684     assert( j==nByte );
  2674   2685   
  2675   2686     assert( pOp->p3>0 && pOp->p3<=(p->nMem-p->nCursor) );
................................................................................
  3560   3571       ** blob, or NULL.  But it needs to be an integer before we can do
  3561   3572       ** the seek, so convert it. */
  3562   3573       pIn3 = &aMem[pOp->p3];
  3563   3574       if( (pIn3->flags & (MEM_Int|MEM_Real|MEM_Str))==MEM_Str ){
  3564   3575         applyNumericAffinity(pIn3, 0);
  3565   3576       }
  3566   3577       iKey = sqlite3VdbeIntValue(pIn3);
  3567         -    pC->rowidIsValid = 0;
  3568   3578   
  3569   3579       /* If the P3 value could not be converted into an integer without
  3570   3580       ** loss of information, then special processing is required... */
  3571   3581       if( (pIn3->flags & MEM_Int)==0 ){
  3572   3582         if( (pIn3->flags & MEM_Real)==0 ){
  3573   3583           /* If the P3 value cannot be converted into any kind of a number,
  3574   3584           ** then the seek is not possible, so jump to P2 */
................................................................................
  3596   3606           assert( OP_SeekLE==(OP_SeekLT+1) );
  3597   3607           assert( OP_SeekGT==(OP_SeekGE+1) );
  3598   3608           assert( (OP_SeekLT & 0x0001)==(OP_SeekGE & 0x0001) );
  3599   3609           if( (oc & 0x0001)==(OP_SeekLT & 0x0001) ) oc++;
  3600   3610         }
  3601   3611       } 
  3602   3612       rc = sqlite3BtreeMovetoUnpacked(pC->pCursor, 0, (u64)iKey, 0, &res);
         3613  +    pC->movetoTarget = iKey;  /* Used by OP_Delete */
  3603   3614       if( rc!=SQLITE_OK ){
  3604   3615         goto abort_due_to_error;
  3605   3616       }
  3606         -    if( res==0 ){
  3607         -      pC->rowidIsValid = 1;
  3608         -      pC->lastRowid = iKey;
  3609         -    }
  3610   3617     }else{
  3611   3618       nField = pOp->p4.i;
  3612   3619       assert( pOp->p4type==P4_INT32 );
  3613   3620       assert( nField>0 );
  3614   3621       r.pKeyInfo = pC->pKeyInfo;
  3615   3622       r.nField = (u16)nField;
  3616   3623   
................................................................................
  3632   3639       { int i; for(i=0; i<r.nField; i++) assert( memIsValid(&r.aMem[i]) ); }
  3633   3640   #endif
  3634   3641       ExpandBlob(r.aMem);
  3635   3642       rc = sqlite3BtreeMovetoUnpacked(pC->pCursor, &r, 0, 0, &res);
  3636   3643       if( rc!=SQLITE_OK ){
  3637   3644         goto abort_due_to_error;
  3638   3645       }
  3639         -    pC->rowidIsValid = 0;
  3640   3646     }
  3641   3647     pC->deferredMoveto = 0;
  3642   3648     pC->cacheStatus = CACHE_STALE;
  3643   3649   #ifdef SQLITE_TEST
  3644   3650     sqlite3_search_count++;
  3645   3651   #endif
  3646   3652     if( oc>=OP_SeekGE ){  assert( oc==OP_SeekGE || oc==OP_SeekGT );
  3647   3653       if( res<0 || (res==0 && oc==OP_SeekGT) ){
  3648   3654         res = 0;
  3649   3655         rc = sqlite3BtreeNext(pC->pCursor, &res);
  3650   3656         if( rc!=SQLITE_OK ) goto abort_due_to_error;
  3651         -      pC->rowidIsValid = 0;
  3652   3657       }else{
  3653   3658         res = 0;
  3654   3659       }
  3655   3660     }else{
  3656   3661       assert( oc==OP_SeekLT || oc==OP_SeekLE );
  3657   3662       if( res>0 || (res==0 && oc==OP_SeekLT) ){
  3658   3663         res = 0;
  3659   3664         rc = sqlite3BtreePrevious(pC->pCursor, &res);
  3660   3665         if( rc!=SQLITE_OK ) goto abort_due_to_error;
  3661         -      pC->rowidIsValid = 0;
  3662   3666       }else{
  3663   3667         /* res might be negative because the table is empty.  Check to
  3664   3668         ** see if this is the case.
  3665   3669         */
  3666   3670         res = sqlite3BtreeEof(pC->pCursor);
  3667   3671       }
  3668   3672     }
................................................................................
  3691   3695     pC = p->apCsr[pOp->p1];
  3692   3696     assert( pC!=0 );
  3693   3697     assert( pC->pCursor!=0 );
  3694   3698     assert( pC->isTable );
  3695   3699     pC->nullRow = 0;
  3696   3700     pIn2 = &aMem[pOp->p2];
  3697   3701     pC->movetoTarget = sqlite3VdbeIntValue(pIn2);
  3698         -  pC->rowidIsValid = 0;
  3699   3702     pC->deferredMoveto = 1;
  3700   3703     break;
  3701   3704   }
  3702   3705     
  3703   3706   
  3704   3707   /* Opcode: Found P1 P2 P3 P4 *
  3705   3708   ** Synopsis: key=r[P3@P4]
................................................................................
  3877   3880     assert( pC->isTable );
  3878   3881     assert( pC->pseudoTableReg==0 );
  3879   3882     pCrsr = pC->pCursor;
  3880   3883     assert( pCrsr!=0 );
  3881   3884     res = 0;
  3882   3885     iKey = pIn3->u.i;
  3883   3886     rc = sqlite3BtreeMovetoUnpacked(pCrsr, 0, iKey, 0, &res);
  3884         -  pC->lastRowid = pIn3->u.i;
  3885         -  pC->rowidIsValid = res==0 ?1:0;
         3887  +  pC->movetoTarget = iKey;  /* Used by OP_Delete */
  3886   3888     pC->nullRow = 0;
  3887   3889     pC->cacheStatus = CACHE_STALE;
  3888   3890     pC->deferredMoveto = 0;
  3889   3891     VdbeBranchTaken(res!=0,2);
  3890   3892     if( res!=0 ){
  3891   3893       pc = pOp->p2 - 1;
  3892         -    assert( pC->rowidIsValid==0 );
  3893   3894     }
  3894   3895     pC->seekResult = res;
  3895   3896     break;
  3896   3897   }
  3897   3898   
  3898   3899   /* Opcode: Sequence P1 P2 * * *
  3899   3900   ** Synopsis: r[P2]=cursor[P1].ctr++
................................................................................
  4033   4034               && (++cnt<100));
  4034   4035         if( rc==SQLITE_OK && res==0 ){
  4035   4036           rc = SQLITE_FULL;   /* IMP: R-38219-53002 */
  4036   4037           goto abort_due_to_error;
  4037   4038         }
  4038   4039         assert( v>0 );  /* EV: R-40812-03570 */
  4039   4040       }
  4040         -    pC->rowidIsValid = 0;
  4041   4041       pC->deferredMoveto = 0;
  4042   4042       pC->cacheStatus = CACHE_STALE;
  4043   4043     }
  4044   4044     pOut->u.i = v;
  4045   4045     break;
  4046   4046   }
  4047   4047   
................................................................................
  4133   4133       op = ((pOp->p5 & OPFLAG_ISUPDATE) ? SQLITE_UPDATE : SQLITE_INSERT);
  4134   4134     }
  4135   4135   
  4136   4136   #ifdef SQLITE_ENABLE_PREUPDATE_HOOK
  4137   4137     /* Invoke the pre-update hook, if any */
  4138   4138     if( db->xPreUpdateCallback 
  4139   4139      && pOp->p4type==P4_TABLE
  4140         -   && (!(pOp->p5 & OPFLAG_ISUPDATE) || pC->rowidIsValid==0)
         4140  +   && !(pOp->p5 & OPFLAG_ISUPDATE)
  4141   4141      && HasRowid(pTab)
  4142   4142     ){
  4143   4143       sqlite3VdbePreUpdateHook(p, pC, SQLITE_INSERT, zDb, pTab, iKey, pOp->p2);
  4144   4144     }
  4145   4145   #endif
  4146   4146   
  4147   4147     if( pOp->p5 & OPFLAG_NCHANGE ) p->nChange++;
................................................................................
  4158   4158     }else{
  4159   4159       nZero = 0;
  4160   4160     }
  4161   4161     rc = sqlite3BtreeInsert(pC->pCursor, 0, iKey,
  4162   4162                             pData->z, pData->n, nZero,
  4163   4163                             (pOp->p5 & OPFLAG_APPEND)!=0, seekResult
  4164   4164     );
  4165         -  pC->rowidIsValid = 0;
  4166   4165     pC->deferredMoveto = 0;
  4167   4166     pC->cacheStatus = CACHE_STALE;
  4168   4167   
  4169   4168     /* Invoke the update-hook if required. */
  4170   4169     if( rc==SQLITE_OK && db->xUpdateCallback && op && HasRowid(pTab) ){
  4171   4170       db->xUpdateCallback(db->pUpdateArg, op, zDb, pTab->zName, iKey);
  4172   4171     }
................................................................................
  4196   4195   ** P4 is not NULL, and the OPFLAG_NCHANGE flag is set in P2.
  4197   4196   **
  4198   4197   ** If the OPFLAG_ISUPDATE flag is set in P2, then P3 contains the address
  4199   4198   ** of the memory cell that contains the value that the rowid of the row will
  4200   4199   ** be set to by the update.
  4201   4200   */
  4202   4201   case OP_Delete: {
  4203         -  i64 iKey;
  4204   4202     VdbeCursor *pC;
  4205   4203     const char *zDb;
  4206   4204     Table *pTab;
  4207   4205     int opflags;
  4208   4206   
  4209   4207     opflags = pOp->p2;
  4210   4208     assert( pOp->p1>=0 && pOp->p1<p->nCursor );
  4211   4209     pC = p->apCsr[pOp->p1];
  4212   4210     assert( pC!=0 );
  4213   4211     assert( pC->pCursor!=0 );  /* Only valid for real tables, no pseudotables */
  4214         -  iKey = pC->lastRowid;      /* Only used for the update hook */
  4215         -
  4216         -  /* The OP_Delete opcode always follows an OP_NotExists or OP_Last or
  4217         -  ** OP_Column on the same table without any intervening operations that
  4218         -  ** might move or invalidate the cursor.  Hence cursor pC is always pointing
  4219         -  ** to the row to be deleted and the sqlite3VdbeCursorMoveto() operation
  4220         -  ** below is always a no-op and cannot fail.  We will run it anyhow, though,
  4221         -  ** to guard against future changes to the code generator.
  4222         -  **/
  4223   4212     assert( pC->deferredMoveto==0 );
  4224         -  rc = sqlite3VdbeCursorMoveto(pC);
  4225         -  if( NEVER(rc!=SQLITE_OK) ) goto abort_due_to_error;
         4213  +
         4214  +#ifdef SQLITE_DEBUG
         4215  +  if( pOp->p4type==P4_TABLE && HasRowid(pOp->p4.pTab) ){
         4216  +    /* The seek operation that positioned the cursor prior to OP_Delete will
         4217  +    ** have also set the pC->movetoTarget field to the rowid of the row that
         4218  +    ** is being deleted */
         4219  +    i64 iKey = 0;
         4220  +    sqlite3BtreeKeySize(pC->pCursor, &iKey);
         4221  +    assert( pC->movetoTarget==iKey );
         4222  +  }
         4223  +#endif
  4226   4224   
  4227   4225     /* If the update-hook or pre-update-hook will be invoked, set iKey to 
  4228   4226     ** the rowid of the row being deleted. Set zDb and zTab as well.
  4229   4227     */
  4230   4228     if( pOp->p4.z && HAS_UPDATE_HOOK(db) ){
  4231   4229       assert( pC->iDb>=0 );
  4232         -    assert( pC->rowidIsValid || !HasRowid(pOp->p4.pTab) );
  4233         -    iKey = pC->lastRowid;
  4234   4230       zDb = db->aDb[pC->iDb].zName;
  4235   4231       pTab = pOp->p4.pTab;
  4236         - }
         4232  +  }
  4237   4233   
  4238   4234   #ifdef SQLITE_ENABLE_PREUPDATE_HOOK
  4239   4235     /* Invoke the pre-update-hook if required. */
  4240   4236     if( db->xPreUpdateCallback && pOp->p4.z && HasRowid(pTab) ){
  4241   4237       assert( !(opflags & OPFLAG_ISUPDATE) || (aMem[pOp->p3].flags & MEM_Int) );
  4242   4238       sqlite3VdbePreUpdateHook(p, pC,
  4243   4239           (opflags & OPFLAG_ISUPDATE) ? SQLITE_UPDATE : SQLITE_DELETE, 
  4244         -        zDb, pTab, iKey,
         4240  +        zDb, pTab, pC->movetoTarget,
  4245   4241           pOp->p3
  4246   4242       );
  4247   4243     }
  4248   4244   #endif
  4249   4245   
  4250   4246     if( opflags & OPFLAG_ISNOOP ) break;
  4251         -
         4247  + 
  4252   4248     rc = sqlite3BtreeDelete(pC->pCursor);
  4253   4249     pC->cacheStatus = CACHE_STALE;
  4254   4250   
  4255   4251     /* Update the change-counter and invoke the update-hook if required. */
  4256   4252     if( opflags & OPFLAG_NCHANGE ){
  4257   4253       p->nChange++;
  4258   4254       assert( pOp->p4.z );
  4259   4255       if( rc==SQLITE_OK && db->xUpdateCallback && HasRowid(pTab) ){
  4260         -      db->xUpdateCallback(db->pUpdateArg, SQLITE_DELETE, zDb, pTab->zName,iKey);
         4256  +      db->xUpdateCallback(db->pUpdateArg, SQLITE_DELETE, zDb, pTab->zName,
         4257  +                          pC->movetoTarget);
  4261   4258       }
  4262   4259     }
  4263   4260     break;
  4264   4261   }
  4265   4262   /* Opcode: ResetCount * * * * *
  4266   4263   **
  4267   4264   ** The value of the change counter is copied to the database handle
................................................................................
  4305   4302     VdbeBranchTaken(res!=0,2);
  4306   4303     if( res ){
  4307   4304       pc = pOp->p2-1;
  4308   4305     }
  4309   4306     break;
  4310   4307   };
  4311   4308   
  4312         -/* Opcode: SorterData P1 P2 * * *
         4309  +/* Opcode: SorterData P1 P2 P3 * *
  4313   4310   ** Synopsis: r[P2]=data
  4314   4311   **
  4315   4312   ** Write into register P2 the current sorter data for sorter cursor P1.
         4313  +** Then clear the column header cache on cursor P3.
         4314  +**
         4315  +** This opcode is normally use to move a record out of the sorter and into
         4316  +** a register that is the source for a pseudo-table cursor created using
         4317  +** OpenPseudo.  That pseudo-table cursor is the one that is identified by
         4318  +** parameter P3.  Clearing the P3 column cache as part of this opcode saves
         4319  +** us from having to issue a separate NullRow instruction to clear that cache.
  4316   4320   */
  4317   4321   case OP_SorterData: {
  4318   4322     VdbeCursor *pC;
  4319   4323   
  4320   4324     pOut = &aMem[pOp->p2];
  4321   4325     pC = p->apCsr[pOp->p1];
  4322   4326     assert( isSorter(pC) );
  4323   4327     rc = sqlite3VdbeSorterRowkey(pC, pOut);
  4324   4328     assert( rc!=SQLITE_OK || (pOut->flags & MEM_Blob) );
         4329  +  assert( pOp->p1>=0 && pOp->p1<p->nCursor );
         4330  +  p->apCsr[pOp->p3]->cacheStatus = CACHE_STALE;
  4325   4331     break;
  4326   4332   }
  4327   4333   
  4328   4334   /* Opcode: RowData P1 P2 * * *
  4329   4335   ** Synopsis: r[P2]=data
  4330   4336   **
  4331   4337   ** Write into register P2 the complete row data for cursor P1.
................................................................................
  4364   4370     assert( pC->isTable || pOp->opcode!=OP_RowData );
  4365   4371     assert( pC->isTable==0 || pOp->opcode==OP_RowData );
  4366   4372     assert( pC!=0 );
  4367   4373     assert( pC->nullRow==0 );
  4368   4374     assert( pC->pseudoTableReg==0 );
  4369   4375     assert( pC->pCursor!=0 );
  4370   4376     pCrsr = pC->pCursor;
  4371         -  assert( sqlite3BtreeCursorIsValid(pCrsr) );
  4372   4377   
  4373   4378     /* The OP_RowKey and OP_RowData opcodes always follow OP_NotExists or
  4374   4379     ** OP_Rewind/Op_Next with no intervening instructions that might invalidate
  4375         -  ** the cursor.  Hence the following sqlite3VdbeCursorMoveto() call is always
  4376         -  ** a no-op and can never fail.  But we leave it in place as a safety.
         4380  +  ** the cursor.  If this where not the case, on of the following assert()s
         4381  +  ** would fail.  Should this ever change (because of changes in the code
         4382  +  ** generator) then the fix would be to insert a call to
         4383  +  ** sqlite3VdbeCursorMoveto().
  4377   4384     */
  4378   4385     assert( pC->deferredMoveto==0 );
         4386  +  assert( sqlite3BtreeCursorIsValid(pCrsr) );
         4387  +#if 0  /* Not required due to the previous to assert() statements */
  4379   4388     rc = sqlite3VdbeCursorMoveto(pC);
  4380         -  if( NEVER(rc!=SQLITE_OK) ) goto abort_due_to_error;
         4389  +  if( rc!=SQLITE_OK ) goto abort_due_to_error;
         4390  +#endif
  4381   4391   
  4382   4392     if( pC->isTable==0 ){
  4383   4393       assert( !pC->isTable );
  4384   4394       VVA_ONLY(rc =) sqlite3BtreeKeySize(pCrsr, &n64);
  4385   4395       assert( rc==SQLITE_OK );    /* True because of CursorMoveto() call above */
  4386   4396       if( n64>db->aLimit[SQLITE_LIMIT_LENGTH] ){
  4387   4397         goto too_big;
................................................................................
  4442   4452       pModule = pVtab->pModule;
  4443   4453       assert( pModule->xRowid );
  4444   4454       rc = pModule->xRowid(pC->pVtabCursor, &v);
  4445   4455       sqlite3VtabImportErrmsg(p, pVtab);
  4446   4456   #endif /* SQLITE_OMIT_VIRTUALTABLE */
  4447   4457     }else{
  4448   4458       assert( pC->pCursor!=0 );
  4449         -    rc = sqlite3VdbeCursorMoveto(pC);
         4459  +    rc = sqlite3VdbeCursorRestore(pC);
  4450   4460       if( rc ) goto abort_due_to_error;
  4451         -    if( pC->rowidIsValid ){
  4452         -      v = pC->lastRowid;
  4453         -    }else{
  4454         -      rc = sqlite3BtreeKeySize(pC->pCursor, &v);
  4455         -      assert( rc==SQLITE_OK );  /* Always so because of CursorMoveto() above */
  4456         -    }
         4461  +    rc = sqlite3BtreeKeySize(pC->pCursor, &v);
         4462  +    assert( rc==SQLITE_OK );  /* Always so because of CursorRestore() above */
  4457   4463     }
  4458   4464     pOut->u.i = v;
  4459   4465     break;
  4460   4466   }
  4461   4467   
  4462   4468   /* Opcode: NullRow P1 * * * *
  4463   4469   **
................................................................................
  4468   4474   case OP_NullRow: {
  4469   4475     VdbeCursor *pC;
  4470   4476   
  4471   4477     assert( pOp->p1>=0 && pOp->p1<p->nCursor );
  4472   4478     pC = p->apCsr[pOp->p1];
  4473   4479     assert( pC!=0 );
  4474   4480     pC->nullRow = 1;
  4475         -  pC->rowidIsValid = 0;
  4476   4481     pC->cacheStatus = CACHE_STALE;
  4477   4482     if( pC->pCursor ){
  4478   4483       sqlite3BtreeClearCursor(pC->pCursor);
  4479   4484     }
  4480   4485     break;
  4481   4486   }
  4482   4487   
................................................................................
  4502   4507     assert( pC!=0 );
  4503   4508     pCrsr = pC->pCursor;
  4504   4509     res = 0;
  4505   4510     assert( pCrsr!=0 );
  4506   4511     rc = sqlite3BtreeLast(pCrsr, &res);
  4507   4512     pC->nullRow = (u8)res;
  4508   4513     pC->deferredMoveto = 0;
  4509         -  pC->rowidIsValid = 0;
  4510   4514     pC->cacheStatus = CACHE_STALE;
  4511   4515   #ifdef SQLITE_DEBUG
  4512   4516     pC->seekOp = OP_Last;
  4513   4517   #endif
  4514   4518     if( pOp->p2>0 ){
  4515   4519       VdbeBranchTaken(res!=0,2);
  4516   4520       if( res ) pc = pOp->p2 - 1;
................................................................................
  4569   4573       rc = sqlite3VdbeSorterRewind(pC, &res);
  4570   4574     }else{
  4571   4575       pCrsr = pC->pCursor;
  4572   4576       assert( pCrsr );
  4573   4577       rc = sqlite3BtreeFirst(pCrsr, &res);
  4574   4578       pC->deferredMoveto = 0;
  4575   4579       pC->cacheStatus = CACHE_STALE;
  4576         -    pC->rowidIsValid = 0;
  4577   4580     }
  4578   4581     pC->nullRow = (u8)res;
  4579   4582     assert( pOp->p2>0 && pOp->p2<p->nOp );
  4580   4583     VdbeBranchTaken(res!=0,2);
  4581   4584     if( res ){
  4582   4585       pc = pOp->p2 - 1;
  4583   4586     }
................................................................................
  4695   4698       p->aCounter[pOp->p5]++;
  4696   4699   #ifdef SQLITE_TEST
  4697   4700       sqlite3_search_count++;
  4698   4701   #endif
  4699   4702     }else{
  4700   4703       pC->nullRow = 1;
  4701   4704     }
  4702         -  pC->rowidIsValid = 0;
  4703   4705     goto check_for_interrupt;
  4704   4706   }
  4705   4707   
  4706   4708   /* Opcode: IdxInsert P1 P2 P3 * P5
  4707   4709   ** Synopsis: key=r[P2]
  4708   4710   **
  4709   4711   ** Register P2 holds an SQL index key made using the
................................................................................
  4811   4813   
  4812   4814     assert( pOp->p1>=0 && pOp->p1<p->nCursor );
  4813   4815     pC = p->apCsr[pOp->p1];
  4814   4816     assert( pC!=0 );
  4815   4817     pCrsr = pC->pCursor;
  4816   4818     assert( pCrsr!=0 );
  4817   4819     pOut->flags = MEM_Null;
  4818         -  rc = sqlite3VdbeCursorMoveto(pC);
  4819         -  if( NEVER(rc) ) goto abort_due_to_error;
         4820  +  assert( pC->isTable==0 );
  4820   4821     assert( pC->deferredMoveto==0 );
  4821         -  assert( pC->isTable==0 );
         4822  +
         4823  +  /* sqlite3VbeCursorRestore() can only fail if the record has been deleted
         4824  +  ** out from under the cursor.  That will never happend for an IdxRowid
         4825  +  ** opcode, hence the NEVER() arround the check of the return value.
         4826  +  */
         4827  +  rc = sqlite3VdbeCursorRestore(pC);
         4828  +  if( NEVER(rc!=SQLITE_OK) ) goto abort_due_to_error;
         4829  +
  4822   4830     if( !pC->nullRow ){
  4823   4831       rowid = 0;  /* Not needed.  Only used to silence a warning. */
  4824   4832       rc = sqlite3VdbeIdxRowid(db, pCrsr, &rowid);
  4825   4833       if( rc!=SQLITE_OK ){
  4826   4834         goto abort_due_to_error;
  4827   4835       }
  4828   4836       pOut->u.i = rowid;

Changes to src/vdbeInt.h.

    69     69     i16 nField;           /* Number of fields in the header */
    70     70     u16 nHdrParsed;       /* Number of header fields parsed so far */
    71     71   #ifdef SQLITE_DEBUG
    72     72     u8 seekOp;            /* Most recent seek operation on this cursor */
    73     73   #endif
    74     74     i8 iDb;               /* Index of cursor database in db->aDb[] (or -1) */
    75     75     u8 nullRow;           /* True if pointing to a row with no data */
    76         -  u8 rowidIsValid;      /* True if lastRowid is valid */
    77     76     u8 deferredMoveto;    /* A call to sqlite3BtreeMoveto() is needed */
    78     77     Bool isEphemeral:1;   /* True for an ephemeral table */
    79     78     Bool useRandomRowid:1;/* Generate new record numbers semi-randomly */
    80     79     Bool isTable:1;       /* True if a table requiring integer keys */
    81     80     Bool isOrdered:1;     /* True if the underlying table is BTREE_UNORDERED */
    82     81     Pgno pgnoRoot;        /* Root page of the open btree cursor */
    83     82     sqlite3_vtab_cursor *pVtabCursor;  /* The cursor for a virtual table */
    84     83     i64 seqCount;         /* Sequence counter */
    85     84     i64 movetoTarget;     /* Argument to the deferred sqlite3BtreeMoveto() */
    86         -  i64 lastRowid;        /* Rowid being deleted by OP_Delete */
    87     85     VdbeSorter *pSorter;  /* Sorter object for OP_SorterOpen cursors */
    88     86   
    89     87     /* Cached information about the header for the data record that the
    90     88     ** cursor is currently pointing to.  Only valid if cacheStatus matches
    91     89     ** Vdbe.cacheCtr.  Vdbe.cacheCtr will never take on the value of
    92     90     ** CACHE_STALE and so setting cacheStatus=CACHE_STALE guarantees that
    93     91     ** the cache is out of date.
................................................................................
    96     94     ** be NULL.
    97     95     */
    98     96     u32 cacheStatus;      /* Cache is valid if this matches Vdbe.cacheCtr */
    99     97     u32 payloadSize;      /* Total number of bytes in the record */
   100     98     u32 szRow;            /* Byte available in aRow */
   101     99     u32 iHdrOffset;       /* Offset to next unparsed byte of the header */
   102    100     const u8 *aRow;       /* Data for the current row, if all on one page */
          101  +  u32 *aOffset;         /* Pointer to aType[nField] */
   103    102     u32 aType[1];         /* Type values for all entries in the record */
   104    103     /* 2*nField extra array elements allocated for aType[], beyond the one
   105    104     ** static element declared in the structure.  nField total array slots for
   106    105     ** aType[] and nField+1 array slots for aOffset[] */
   107    106   };
   108    107   typedef struct VdbeCursor VdbeCursor;
   109    108   
................................................................................
   172    171     u16 flags;          /* Some combination of MEM_Null, MEM_Str, MEM_Dyn, etc. */
   173    172     u8  enc;            /* SQLITE_UTF8, SQLITE_UTF16BE, SQLITE_UTF16LE */
   174    173     int n;              /* Number of characters in string value, excluding '\0' */
   175    174     char *z;            /* String or BLOB value */
   176    175     /* ShallowCopy only needs to copy the information above */
   177    176     char *zMalloc;      /* Space to hold MEM_Str or MEM_Blob if szMalloc>0 */
   178    177     int szMalloc;       /* Size of the zMalloc allocation */
   179         -  int iPadding1;      /* Padding for 8-byte alignment */
          178  +  u32 uTemp;          /* Transient storage for serial_type in OP_MakeRecord */
   180    179     sqlite3 *db;        /* The associated database connection */
   181    180     void (*xDel)(void*);/* Destructor for Mem.z - only valid if MEM_Dyn */
   182    181   #ifdef SQLITE_DEBUG
   183    182     Mem *pScopyFrom;    /* This Mem is a shallow copy of pScopyFrom */
   184    183     void *pFiller;      /* So that sizeof(Mem) is a multiple of 8 */
   185    184   #endif
   186    185   };
................................................................................
   399    398   
   400    399   /*
   401    400   ** Function prototypes
   402    401   */
   403    402   void sqlite3VdbeFreeCursor(Vdbe *, VdbeCursor*);
   404    403   void sqliteVdbePopStack(Vdbe*,int);
   405    404   int sqlite3VdbeCursorMoveto(VdbeCursor*);
          405  +int sqlite3VdbeCursorRestore(VdbeCursor*);
   406    406   #if defined(SQLITE_DEBUG) || defined(VDBE_PROFILE)
   407    407   void sqlite3VdbePrintOp(FILE*, int, Op*);
   408    408   #endif
   409    409   u32 sqlite3VdbeSerialTypeLen(u32);
   410    410   u32 sqlite3VdbeSerialType(Mem*, int);
   411    411   u32 sqlite3VdbeSerialPut(unsigned char*, Mem*, u32);
   412    412   u32 sqlite3VdbeSerialGet(const unsigned char*, u32, Mem*);

Changes to src/vdbeaux.c.

  1742   1742       sqlite3BtreeClose(pCx->pBt);
  1743   1743       /* The pCx->pCursor will be close automatically, if it exists, by
  1744   1744       ** the call above. */
  1745   1745     }else if( pCx->pCursor ){
  1746   1746       sqlite3BtreeCloseCursor(pCx->pCursor);
  1747   1747     }
  1748   1748   #ifndef SQLITE_OMIT_VIRTUALTABLE
  1749         -  if( pCx->pVtabCursor ){
         1749  +  else if( pCx->pVtabCursor ){
  1750   1750       sqlite3_vtab_cursor *pVtabCursor = pCx->pVtabCursor;
  1751   1751       const sqlite3_module *pModule = pVtabCursor->pVtab->pModule;
  1752   1752       p->inVtabMethod = 1;
  1753   1753       pModule->xClose(pVtabCursor);
  1754   1754       p->inVtabMethod = 0;
  1755   1755     }
  1756   1756   #endif
................................................................................
  1785   1785   ** open cursors.
  1786   1786   */
  1787   1787   static void closeAllCursors(Vdbe *p){
  1788   1788     if( p->pFrame ){
  1789   1789       VdbeFrame *pFrame;
  1790   1790       for(pFrame=p->pFrame; pFrame->pParent; pFrame=pFrame->pParent);
  1791   1791       sqlite3VdbeFrameRestore(pFrame);
         1792  +    p->pFrame = 0;
         1793  +    p->nFrame = 0;
  1792   1794     }
  1793         -  p->pFrame = 0;
  1794         -  p->nFrame = 0;
         1795  +  assert( p->nFrame==0 );
  1795   1796   
  1796   1797     if( p->apCsr ){
  1797   1798       int i;
  1798   1799       for(i=0; i<p->nCursor; i++){
  1799   1800         VdbeCursor *pC = p->apCsr[i];
  1800   1801         if( pC ){
  1801   1802           sqlite3VdbeFreeCursor(p, pC);
................................................................................
  1809   1810     while( p->pDelFrame ){
  1810   1811       VdbeFrame *pDel = p->pDelFrame;
  1811   1812       p->pDelFrame = pDel->pParent;
  1812   1813       sqlite3VdbeFrameDelete(pDel);
  1813   1814     }
  1814   1815   
  1815   1816     /* Delete any auxdata allocations made by the VM */
  1816         -  sqlite3VdbeDeleteAuxData(p, -1, 0);
         1817  +  if( p->pAuxData ) sqlite3VdbeDeleteAuxData(p, -1, 0);
  1817   1818     assert( p->pAuxData==0 );
  1818   1819   }
  1819   1820   
  1820   1821   /*
  1821   1822   ** Clean up the VM after a single run.
  1822   1823   */
  1823   1824   static void Cleanup(Vdbe *p){
................................................................................
  2715   2716   #ifdef SQLITE_TEST
  2716   2717     extern int sqlite3_search_count;
  2717   2718   #endif
  2718   2719     assert( p->deferredMoveto );
  2719   2720     assert( p->isTable );
  2720   2721     rc = sqlite3BtreeMovetoUnpacked(p->pCursor, 0, p->movetoTarget, 0, &res);
  2721   2722     if( rc ) return rc;
  2722         -  p->lastRowid = p->movetoTarget;
  2723   2723     if( res!=0 ) return SQLITE_CORRUPT_BKPT;
  2724         -  p->rowidIsValid = 1;
  2725   2724   #ifdef SQLITE_TEST
  2726   2725     sqlite3_search_count++;
  2727   2726   #endif
  2728   2727     p->deferredMoveto = 0;
  2729   2728     p->cacheStatus = CACHE_STALE;
  2730   2729     return SQLITE_OK;
  2731   2730   }
................................................................................
  2742   2741     assert( p->pCursor!=0 );
  2743   2742     assert( sqlite3BtreeCursorHasMoved(p->pCursor) );
  2744   2743     rc = sqlite3BtreeCursorRestore(p->pCursor, &isDifferentRow);
  2745   2744     p->cacheStatus = CACHE_STALE;
  2746   2745     if( isDifferentRow ) p->nullRow = 1;
  2747   2746     return rc;
  2748   2747   }
         2748  +
         2749  +/*
         2750  +** Check to ensure that the cursor is valid.  Restore the cursor
         2751  +** if need be.  Return any I/O error from the restore operation.
         2752  +*/
         2753  +int sqlite3VdbeCursorRestore(VdbeCursor *p){
         2754  +  if( sqlite3BtreeCursorHasMoved(p->pCursor) ){
         2755  +    return handleMovedCursor(p);
         2756  +  }
         2757  +  return SQLITE_OK;
         2758  +}
  2749   2759   
  2750   2760   /*
  2751   2761   ** Make sure the cursor p is ready to read or write the row to which it
  2752   2762   ** was last positioned.  Return an error code if an OOM fault or I/O error
  2753   2763   ** prevents us from positioning the cursor to its correct position.
  2754   2764   **
  2755   2765   ** If a MoveTo operation is pending on the given cursor, then do that
................................................................................
  2760   2770   ** If the cursor is already pointing to the correct row and that row has
  2761   2771   ** not been deleted out from under the cursor, then this routine is a no-op.
  2762   2772   */
  2763   2773   int sqlite3VdbeCursorMoveto(VdbeCursor *p){
  2764   2774     if( p->deferredMoveto ){
  2765   2775       return handleDeferredMoveto(p);
  2766   2776     }
  2767         -  if( sqlite3BtreeCursorHasMoved(p->pCursor) ){
         2777  +  if( p->pCursor && sqlite3BtreeCursorHasMoved(p->pCursor) ){
  2768   2778       return handleMovedCursor(p);
  2769   2779     }
  2770   2780     return SQLITE_OK;
  2771   2781   }
  2772   2782   
  2773   2783   /*
  2774   2784   ** The following functions:

Changes to src/where.c.

  2205   2205           whereKeyStats(pParse, p, pRec, 0, a);
  2206   2206           iLower = a[0];
  2207   2207           iUpper = a[0] + a[1];
  2208   2208         }
  2209   2209   
  2210   2210         assert( pLower==0 || (pLower->eOperator & (WO_GT|WO_GE))!=0 );
  2211   2211         assert( pUpper==0 || (pUpper->eOperator & (WO_LT|WO_LE))!=0 );
  2212         -      assert( p->pKeyInfo!=0 && p->pKeyInfo->aSortOrder!=0 );
  2213         -      if( p->pKeyInfo->aSortOrder[nEq] ){
         2212  +      assert( p->aSortOrder!=0 );
         2213  +      if( p->aSortOrder[nEq] ){
  2214   2214           /* The roles of pLower and pUpper are swapped for a DESC index */
  2215   2215           SWAP(WhereTerm*, pLower, pUpper);
  2216   2216         }
  2217   2217   
  2218   2218         /* If possible, improve on the iLower estimate using ($P:$L). */
  2219   2219         if( pLower ){
  2220   2220           int bOk;                    /* True if value is extracted from pExpr */
................................................................................
  2733   2733     sqlite3StrAccumAppendAll(pStr, zColumn);
  2734   2734     sqlite3StrAccumAppend(pStr, zOp, 1);
  2735   2735     sqlite3StrAccumAppend(pStr, "?", 1);
  2736   2736   }
  2737   2737   
  2738   2738   /*
  2739   2739   ** Argument pLevel describes a strategy for scanning table pTab. This 
  2740         -** function returns a pointer to a string buffer containing a description
  2741         -** of the subset of table rows scanned by the strategy in the form of an
  2742         -** SQL expression. Or, if all rows are scanned, NULL is returned.
         2740  +** function appends text to pStr that describes the subset of table
         2741  +** rows scanned by the strategy in the form of an SQL expression.
  2743   2742   **
  2744   2743   ** For example, if the query:
  2745   2744   **
  2746   2745   **   SELECT * FROM t1 WHERE a=1 AND b>2;
  2747   2746   **
  2748   2747   ** is run and there is an index on (a, b), then this function returns a
  2749   2748   ** string similar to:
  2750   2749   **
  2751   2750   **   "a=? AND b>?"
  2752         -**
  2753         -** The returned pointer points to memory obtained from sqlite3DbMalloc().
  2754         -** It is the responsibility of the caller to free the buffer when it is
  2755         -** no longer required.
  2756   2751   */
  2757         -static char *explainIndexRange(sqlite3 *db, WhereLoop *pLoop, Table *pTab){
         2752  +static void explainIndexRange(StrAccum *pStr, WhereLoop *pLoop, Table *pTab){
  2758   2753     Index *pIndex = pLoop->u.btree.pIndex;
  2759   2754     u16 nEq = pLoop->u.btree.nEq;
  2760   2755     u16 nSkip = pLoop->u.btree.nSkip;
  2761   2756     int i, j;
  2762   2757     Column *aCol = pTab->aCol;
  2763   2758     i16 *aiColumn = pIndex->aiColumn;
  2764         -  StrAccum txt;
  2765   2759   
  2766         -  if( nEq==0 && (pLoop->wsFlags & (WHERE_BTM_LIMIT|WHERE_TOP_LIMIT))==0 ){
  2767         -    return 0;
  2768         -  }
  2769         -  sqlite3StrAccumInit(&txt, 0, 0, SQLITE_MAX_LENGTH);
  2770         -  txt.db = db;
  2771         -  sqlite3StrAccumAppend(&txt, " (", 2);
         2760  +  if( nEq==0 && (pLoop->wsFlags&(WHERE_BTM_LIMIT|WHERE_TOP_LIMIT))==0 ) return;
         2761  +  sqlite3StrAccumAppend(pStr, " (", 2);
  2772   2762     for(i=0; i<nEq; i++){
  2773   2763       char *z = aiColumn[i] < 0 ? "rowid" : aCol[aiColumn[i]].zName;
  2774   2764       if( i>=nSkip ){
  2775         -      explainAppendTerm(&txt, i, z, "=");
         2765  +      explainAppendTerm(pStr, i, z, "=");
  2776   2766       }else{
  2777         -      if( i ) sqlite3StrAccumAppend(&txt, " AND ", 5);
  2778         -      sqlite3StrAccumAppend(&txt, "ANY(", 4);
  2779         -      sqlite3StrAccumAppendAll(&txt, z);
  2780         -      sqlite3StrAccumAppend(&txt, ")", 1);
         2767  +      if( i ) sqlite3StrAccumAppend(pStr, " AND ", 5);
         2768  +      sqlite3XPrintf(pStr, 0, "ANY(%s)", z);
  2781   2769       }
  2782   2770     }
  2783   2771   
  2784   2772     j = i;
  2785   2773     if( pLoop->wsFlags&WHERE_BTM_LIMIT ){
  2786   2774       char *z = aiColumn[j] < 0 ? "rowid" : aCol[aiColumn[j]].zName;
  2787         -    explainAppendTerm(&txt, i++, z, ">");
         2775  +    explainAppendTerm(pStr, i++, z, ">");
  2788   2776     }
  2789   2777     if( pLoop->wsFlags&WHERE_TOP_LIMIT ){
  2790   2778       char *z = aiColumn[j] < 0 ? "rowid" : aCol[aiColumn[j]].zName;
  2791         -    explainAppendTerm(&txt, i, z, "<");
         2779  +    explainAppendTerm(pStr, i, z, "<");
  2792   2780     }
  2793         -  sqlite3StrAccumAppend(&txt, ")", 1);
  2794         -  return sqlite3StrAccumFinish(&txt);
         2781  +  sqlite3StrAccumAppend(pStr, ")", 1);
  2795   2782   }
  2796   2783   
  2797   2784   /*
  2798   2785   ** This function is a no-op unless currently processing an EXPLAIN QUERY PLAN
  2799   2786   ** command. If the query being compiled is an EXPLAIN QUERY PLAN, a single
  2800   2787   ** record is added to the output to describe the table scan strategy in 
  2801   2788   ** pLevel.
................................................................................
  2811   2798   #ifndef SQLITE_DEBUG
  2812   2799     if( pParse->explain==2 )
  2813   2800   #endif
  2814   2801     {
  2815   2802       struct SrcList_item *pItem = &pTabList->a[pLevel->iFrom];
  2816   2803       Vdbe *v = pParse->pVdbe;      /* VM being constructed */
  2817   2804       sqlite3 *db = pParse->db;     /* Database handle */
  2818         -    char *zMsg;                   /* Text to add to EQP output */
  2819   2805       int iId = pParse->iSelectId;  /* Select id (left-most output column) */
  2820   2806       int isSearch;                 /* True for a SEARCH. False for SCAN. */
  2821   2807       WhereLoop *pLoop;             /* The controlling WhereLoop object */
  2822   2808       u32 flags;                    /* Flags that describe this loop */
         2809  +    char *zMsg;                   /* Text to add to EQP output */
         2810  +    StrAccum str;                 /* EQP output string */
         2811  +    char zBuf[100];               /* Initial space for EQP output string */
  2823   2812   
  2824   2813       pLoop = pLevel->pWLoop;
  2825   2814       flags = pLoop->wsFlags;
  2826   2815       if( (flags&WHERE_MULTI_OR) || (wctrlFlags&WHERE_ONETABLE_ONLY) ) return;
  2827   2816   
  2828   2817       isSearch = (flags&(WHERE_BTM_LIMIT|WHERE_TOP_LIMIT))!=0
  2829   2818               || ((flags&WHERE_VIRTUALTABLE)==0 && (pLoop->u.btree.nEq>0))
  2830   2819               || (wctrlFlags&(WHERE_ORDERBY_MIN|WHERE_ORDERBY_MAX));
  2831   2820   
  2832         -    zMsg = sqlite3MPrintf(db, "%s", isSearch?"SEARCH":"SCAN");
         2821  +    sqlite3StrAccumInit(&str, zBuf, sizeof(zBuf), SQLITE_MAX_LENGTH);
         2822  +    str.db = db;
         2823  +    sqlite3StrAccumAppendAll(&str, isSearch ? "SEARCH" : "SCAN");
  2833   2824       if( pItem->pSelect ){
  2834         -      zMsg = sqlite3MAppendf(db, zMsg, "%s SUBQUERY %d", zMsg,pItem->iSelectId);
         2825  +      sqlite3XPrintf(&str, 0, " SUBQUERY %d", pItem->iSelectId);
  2835   2826       }else{
  2836         -      zMsg = sqlite3MAppendf(db, zMsg, "%s TABLE %s", zMsg, pItem->zName);
         2827  +      sqlite3XPrintf(&str, 0, " TABLE %s", pItem->zName);
  2837   2828       }
  2838   2829   
  2839   2830       if( pItem->zAlias ){
  2840         -      zMsg = sqlite3MAppendf(db, zMsg, "%s AS %s", zMsg, pItem->zAlias);
         2831  +      sqlite3XPrintf(&str, 0, " AS %s", pItem->zAlias);
  2841   2832       }
  2842         -    if( (flags & (WHERE_IPK|WHERE_VIRTUALTABLE))==0
  2843         -     && ALWAYS(pLoop->u.btree.pIndex!=0)
  2844         -    ){
  2845         -      const char *zFmt;
  2846         -      Index *pIdx = pLoop->u.btree.pIndex;
  2847         -      char *zWhere = explainIndexRange(db, pLoop, pItem->pTab);
         2833  +    if( (flags & (WHERE_IPK|WHERE_VIRTUALTABLE))==0 ){
         2834  +      const char *zFmt = 0;
         2835  +      Index *pIdx;
         2836  +
         2837  +      assert( pLoop->u.btree.pIndex!=0 );
         2838  +      pIdx = pLoop->u.btree.pIndex;
  2848   2839         assert( !(flags&WHERE_AUTO_INDEX) || (flags&WHERE_IDX_ONLY) );
  2849   2840         if( !HasRowid(pItem->pTab) && IsPrimaryKeyIndex(pIdx) ){
  2850         -        zFmt = zWhere ? "%s USING PRIMARY KEY%.0s%s" : "%s%.0s%s";
         2841  +        if( isSearch ){
         2842  +          zFmt = "PRIMARY KEY";
         2843  +        }
  2851   2844         }else if( flags & WHERE_AUTO_INDEX ){
  2852         -        zFmt = "%s USING AUTOMATIC COVERING INDEX%.0s%s";
         2845  +        zFmt = "AUTOMATIC COVERING INDEX";
  2853   2846         }else if( flags & WHERE_IDX_ONLY ){
  2854         -        zFmt = "%s USING COVERING INDEX %s%s";
         2847  +        zFmt = "COVERING INDEX %s";
  2855   2848         }else{
  2856         -        zFmt = "%s USING INDEX %s%s";
         2849  +        zFmt = "INDEX %s";
  2857   2850         }
  2858         -      zMsg = sqlite3MAppendf(db, zMsg, zFmt, zMsg, pIdx->zName, zWhere);
  2859         -      sqlite3DbFree(db, zWhere);
         2851  +      if( zFmt ){
         2852  +        sqlite3StrAccumAppend(&str, " USING ", 7);
         2853  +        sqlite3XPrintf(&str, 0, zFmt, pIdx->zName);
         2854  +        explainIndexRange(&str, pLoop, pItem->pTab);
         2855  +      }
  2860   2856       }else if( (flags & WHERE_IPK)!=0 && (flags & WHERE_CONSTRAINT)!=0 ){
  2861         -      zMsg = sqlite3MAppendf(db, zMsg, "%s USING INTEGER PRIMARY KEY", zMsg);
  2862         -
         2857  +      const char *zRange;
  2863   2858         if( flags&(WHERE_COLUMN_EQ|WHERE_COLUMN_IN) ){
  2864         -        zMsg = sqlite3MAppendf(db, zMsg, "%s (rowid=?)", zMsg);
         2859  +        zRange = "(rowid=?)";
  2865   2860         }else if( (flags&WHERE_BOTH_LIMIT)==WHERE_BOTH_LIMIT ){
  2866         -        zMsg = sqlite3MAppendf(db, zMsg, "%s (rowid>? AND rowid<?)", zMsg);
         2861  +        zRange = "(rowid>? AND rowid<?)";
  2867   2862         }else if( flags&WHERE_BTM_LIMIT ){
  2868         -        zMsg = sqlite3MAppendf(db, zMsg, "%s (rowid>?)", zMsg);
  2869         -      }else if( ALWAYS(flags&WHERE_TOP_LIMIT) ){
  2870         -        zMsg = sqlite3MAppendf(db, zMsg, "%s (rowid<?)", zMsg);
         2863  +        zRange = "(rowid>?)";
         2864  +      }else{
         2865  +        assert( flags&WHERE_TOP_LIMIT);
         2866  +        zRange = "(rowid<?)";
  2871   2867         }
         2868  +      sqlite3StrAccumAppendAll(&str, " USING INTEGER PRIMARY KEY ");
         2869  +      sqlite3StrAccumAppendAll(&str, zRange);
  2872   2870       }
  2873   2871   #ifndef SQLITE_OMIT_VIRTUALTABLE
  2874   2872       else if( (flags & WHERE_VIRTUALTABLE)!=0 ){
  2875         -      zMsg = sqlite3MAppendf(db, zMsg, "%s VIRTUAL TABLE INDEX %d:%s", zMsg,
         2873  +      sqlite3XPrintf(&str, 0, " VIRTUAL TABLE INDEX %d:%s",
  2876   2874                     pLoop->u.vtab.idxNum, pLoop->u.vtab.idxStr);
  2877   2875       }
  2878   2876   #endif
  2879         -    zMsg = sqlite3MAppendf(db, zMsg, "%s", zMsg);
         2877  +#ifdef SQLITE_EXPLAIN_ESTIMATED_ROWS
         2878  +    if( pLoop->nOut>=10 ){
         2879  +      sqlite3XPrintf(&str, 0, " (~%llu rows)", sqlite3LogEstToInt(pLoop->nOut));
         2880  +    }else{
         2881  +      sqlite3StrAccumAppend(&str, " (~1 row)", 9);
         2882  +    }
         2883  +#endif
         2884  +    zMsg = sqlite3StrAccumFinish(&str);
  2880   2885       sqlite3VdbeAddOp4(v, OP_Explain, iId, iLevel, iFrom, zMsg, P4_DYNAMIC);
  2881   2886     }
  2882   2887   }
  2883   2888   #else
  2884   2889   # define explainOneScan(u,v,w,x,y,z)
  2885   2890   #endif /* SQLITE_OMIT_EXPLAIN */
  2886   2891   
................................................................................
  5351   5356               pColl = sqlite3ExprCollSeq(pWInfo->pParse, pOrderBy->a[i].pExpr);
  5352   5357               if( !pColl ) pColl = db->pDfltColl;
  5353   5358               if( sqlite3StrICmp(pColl->zName, pIndex->azColl[j])!=0 ) continue;
  5354   5359             }
  5355   5360             isMatch = 1;
  5356   5361             break;
  5357   5362           }
  5358         -        if( isMatch && (pWInfo->wctrlFlags & WHERE_GROUPBY)==0 ){
         5363  +        if( isMatch && (wctrlFlags & WHERE_GROUPBY)==0 ){
  5359   5364             /* Make sure the sort order is compatible in an ORDER BY clause.
  5360   5365             ** Sort order is irrelevant for a GROUP BY clause. */
  5361   5366             if( revSet ){
  5362   5367               if( (rev ^ revIdx)!=pOrderBy->a[i].sortOrder ) isMatch = 0;
  5363   5368             }else{
  5364   5369               rev = revIdx ^ pOrderBy->a[i].sortOrder;
  5365   5370               if( rev ) *pRevMask |= MASKBIT(iLoop);
................................................................................
  5816   5821         pWInfo->nOBSat = pFrom->isOrdered;
  5817   5822         if( pWInfo->nOBSat<0 ) pWInfo->nOBSat = 0;
  5818   5823         pWInfo->revMask = pFrom->revLoop;
  5819   5824       }
  5820   5825       if( (pWInfo->wctrlFlags & WHERE_SORTBYGROUP)
  5821   5826           && pWInfo->nOBSat==pWInfo->pOrderBy->nExpr
  5822   5827       ){
  5823         -      Bitmask notUsed = 0;
         5828  +      Bitmask revMask = 0;
  5824   5829         int nOrder = wherePathSatisfiesOrderBy(pWInfo, pWInfo->pOrderBy, 
  5825         -          pFrom, 0, nLoop-1, pFrom->aLoop[nLoop-1], &notUsed
         5830  +          pFrom, 0, nLoop-1, pFrom->aLoop[nLoop-1], &revMask
  5826   5831         );
  5827   5832         assert( pWInfo->sorted==0 );
  5828         -      pWInfo->sorted = (nOrder==pWInfo->pOrderBy->nExpr);
         5833  +      if( nOrder==pWInfo->pOrderBy->nExpr ){
         5834  +        pWInfo->sorted = 1;
         5835  +        pWInfo->revMask = revMask;
         5836  +      }
  5829   5837       }
  5830   5838     }
  5831   5839   
  5832   5840   
  5833   5841     pWInfo->nRowOut = pFrom->nRow;
  5834   5842   
  5835   5843     /* Free temporary memory and return success */

Changes to test/hook.test.

   198    198   # ROWID tables are modified.
   199    199   #
   200    200   breakpoint
   201    201   do_test hook-4.1.2w {
   202    202     set ::update_hook {}
   203    203     execsql {
   204    204       INSERT INTO t1w VALUES(4, 'four');
          205  +PRAGMA vdbe_debug=on;
          206  +PRAGMA vdbe_addoptrace=on;
   205    207       DELETE FROM t1w WHERE b = 'two';
   206    208       UPDATE t1w SET b = '' WHERE a = 1 OR a = 3;
   207    209       DELETE FROM t1w WHERE 1; -- Avoid the truncate optimization (for now)
   208    210     }
   209    211     set ::update_hook
   210    212   } {}
   211    213   

Changes to test/index5.test.

    12     12   
    13     13   
    14     14   set testdir [file dirname $argv0]
    15     15   source $testdir/tester.tcl
    16     16   set ::testprefix index5
    17     17   
    18     18   do_test 1.1 {
           19  +  if {[permutation]=="memsubsys1"} {
           20  +    execsql { PRAGMA auto_vacuum = 0; }
           21  +  }
    19     22     execsql {
    20     23       PRAGMA page_size = 1024;
    21     24       CREATE TABLE t1(x);
    22     25       BEGIN;
    23     26     }
    24     27     for {set i 0} {$i < 100000} {incr i} {
    25     28       execsql { INSERT INTO t1 VALUES(randstr(100,100)) }
................................................................................
    34     37   
    35     38   db close
    36     39   testvfs tvfs
    37     40   tvfs filter xWrite
    38     41   tvfs script write_cb
    39     42   proc write_cb {xCall file handle iOfst args} {
    40     43     if {[file tail $file]=="test.db"} {
    41         -    lappend ::write_list [expr $iOfst/1024]
           44  +    lappend ::write_list [expr $iOfst/1024 + 1]
    42     45     }
    43     46   }
    44     47   
    45     48   do_test 1.2 {
    46     49     sqlite3 db test.db -vfs tvfs
    47     50     set ::write_list [list]
    48     51     execsql { CREATE INDEX i1 ON t1(x) }

Changes to test/releasetest.tcl.

     9      9   This Tcl script is used to test the various configurations required
    10     10   before releasing a new version. Supported command line options (all 
    11     11   optional) are:
    12     12   
    13     13       -makefile PATH-TO-MAKEFILE           (default "releasetest.mk")
    14     14       -platform PLATFORM                   (see below)
    15     15       -quick    BOOLEAN                    (default "0")
           16  +    -config   CONFIGNAME                 (Run only CONFIGNAME)
    16     17   
    17     18   The default value for -makefile is "./releasetest.mk".
    18     19   
    19     20   The script determines the default value for -platform using the
    20     21   $tcl_platform(os) and $tcl_platform(machine) variables. Supported 
    21     22   platforms are "Linux-x86", "Linux-x86_64" and "Darwin-i386".
    22     23   
................................................................................
   288    289   # Currently the only option supported is "-makefile", default
   289    290   # "releasetest.mk". Set the ::MAKEFILE variable to the value of this
   290    291   # option.
   291    292   #
   292    293   proc process_options {argv} {
   293    294     set ::MAKEFILE releasetest.mk                       ;# Default value
   294    295     set ::QUICK    0                                    ;# Default value
          296  +  set config {}
   295    297     set platform $::tcl_platform(os)-$::tcl_platform(machine)
   296    298   
   297    299     for {set i 0} {$i < [llength $argv]} {incr i} {
   298    300       switch -- [lindex $argv $i] {
   299    301         -makefile {
   300    302           incr i
   301    303           set ::MAKEFILE [lindex $argv $i]
................................................................................
   306    308           set platform [lindex $argv $i]
   307    309         }
   308    310   
   309    311         -quick {
   310    312           incr i
   311    313           set ::QUICK [lindex $argv $i]
   312    314         }
          315  +
          316  +      -config {
          317  +        incr i
          318  +        set config [lindex $argv $i]
          319  +      }
   313    320     
   314    321         default {
   315    322           puts stderr ""
   316    323           puts stderr [string trim $::USAGE_MESSAGE]
   317    324           exit -1
   318    325         }
   319    326       }
................................................................................
   329    336         lappend print "\"$p\""
   330    337       }
   331    338       lset print end "or [lindex $print end]"
   332    339       puts "[join $print {, }]."
   333    340       exit
   334    341     }
   335    342   
   336         -  set ::CONFIGLIST $::Platforms($platform)
          343  +  if {$config!=""} {
          344  +    if {[llength $config]==1} {lappend config fulltest}
          345  +    set ::CONFIGLIST $config
          346  +  } else {
          347  +    set ::CONFIGLIST $::Platforms($platform)
          348  +  }
   337    349     puts "Running the following configurations for $platform:"
   338    350     puts "    [string trim $::CONFIGLIST]"
   339    351   }
   340    352   
   341    353   # Main routine.
   342    354   #
   343    355   proc main {argv} {

Changes to test/speedtest1.c.

   930    930       nElem, nElem
   931    931     );
   932    932     speedtest1_run();
   933    933     speedtest1_end_test();
   934    934   
   935    935   }
   936    936   
          937  +#ifdef SQLITE_ENABLE_RTREE
   937    938   /* Generate two numbers between 1 and mx.  The first number is less than
   938    939   ** the second.  Usually the numbers are near each other but can sometimes
   939    940   ** be far apart.
   940    941   */
   941    942   static void twoCoords(
   942    943     int p1, int p2,                   /* Parameters adjusting sizes */
   943    944     unsigned mx,                      /* Range of 1..mx */
................................................................................
   950    951     if( speedtest1_random()%p2==0 ) span = mx/2;
   951    952     d = speedtest1_random()%span + 1;
   952    953     x0 = speedtest1_random()%(mx-d) + 1;
   953    954     x1 = x0 + d;
   954    955     *pX0 = x0;
   955    956     *pX1 = x1;
   956    957   }
          958  +#endif
   957    959   
          960  +#ifdef SQLITE_ENABLE_RTREE
   958    961   /* The following routine is an R-Tree geometry callback.  It returns
   959    962   ** true if the object overlaps a slice on the Y coordinate between the
   960    963   ** two values given as arguments.  In other words
   961    964   **
   962    965   **     SELECT count(*) FROM rt1 WHERE id MATCH xslice(10,20);
   963    966   **
   964    967   ** Is the same as saying:
................................................................................
   970    973     int nCoord,
   971    974     double *aCoord,
   972    975     int *pRes
   973    976   ){
   974    977     *pRes = aCoord[3]>=p->aParam[0] && aCoord[2]<=p->aParam[1];
   975    978     return SQLITE_OK;
   976    979   }
          980  +#endif /* SQLITE_ENABLE_RTREE */
   977    981   
          982  +#ifdef SQLITE_ENABLE_RTREE
   978    983   /*
   979    984   ** A testset for the R-Tree virtual table
   980    985   */
   981    986   void testset_rtree(int p1, int p2){
   982    987     unsigned i, n;
   983    988     unsigned mxCoord;
   984    989     unsigned x0, x1, y0, y1, z0, z1;
................................................................................
  1106   1111     speedtest1_prepare("SELECT * FROM rt1 WHERE id=?1");
  1107   1112     for(i=1; i<=n; i++){
  1108   1113       sqlite3_bind_int(g.pStmt, 1, i);
  1109   1114       speedtest1_run();
  1110   1115     }
  1111   1116     speedtest1_end_test();
  1112   1117   }
         1118  +#endif /* SQLITE_ENABLE_RTREE */
  1113   1119   
  1114   1120   /*
  1115   1121   ** A testset used for debugging speedtest1 itself.
  1116   1122   */
  1117   1123   void testset_debug1(void){
  1118   1124     unsigned i, n;
  1119   1125     unsigned x1, x2;
................................................................................
  1325   1331     if( strcmp(zTSet,"main")==0 ){
  1326   1332       testset_main();
  1327   1333     }else if( strcmp(zTSet,"debug1")==0 ){
  1328   1334       testset_debug1();
  1329   1335     }else if( strcmp(zTSet,"cte")==0 ){
  1330   1336       testset_cte();
  1331   1337     }else if( strcmp(zTSet,"rtree")==0 ){
         1338  +#ifdef SQLITE_ENABLE_RTREE
  1332   1339       testset_rtree(6, 147);
         1340  +#else
         1341  +    fatal_error("compile with -DSQLITE_ENABLE_RTREE to enable "
         1342  +                "the R-Tree tests\n");
         1343  +#endif
  1333   1344     }else{
  1334   1345       fatal_error("unknown testset: \"%s\"\nChoices: main debug1 cte rtree\n",
  1335   1346                    zTSet);
  1336   1347     }
  1337   1348     speedtest1_final();
  1338   1349   
  1339   1350     /* Database connection statistics printed after both prepared statements

Added test/tkt-ba7cbfaedc.test.

            1  +# 2014-10-11
            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 that ticket [ba7cbfaedc] has been fixed.
           13  +#
           14  +
           15  +set testdir [file dirname $argv0]
           16  +source $testdir/tester.tcl
           17  +set testprefix tkt-ba7cbfaedc
           18  +
           19  +do_execsql_test 1 {
           20  +  CREATE TABLE t1 (x, y);
           21  +  INSERT INTO t1 VALUES (3, 'a');
           22  +  INSERT INTO t1 VALUES (1, 'a'); 
           23  +  INSERT INTO t1 VALUES (2, 'b');
           24  +  INSERT INTO t1 VALUES (2, 'a');
           25  +  INSERT INTO t1 VALUES (3, 'b');
           26  +  INSERT INTO t1 VALUES (1, 'b'); 
           27  +}
           28  +
           29  +do_execsql_test 1.1 {
           30  +  CREATE INDEX i1 ON t1(x, y);
           31  +}
           32  +
           33  +foreach {n idx} {
           34  +  1 { CREATE INDEX i1 ON t1(x, y) }
           35  +  2 { CREATE INDEX i1 ON t1(x DESC, y) }
           36  +  3 { CREATE INDEX i1 ON t1(x, y DESC) }
           37  +  4 { CREATE INDEX i1 ON t1(x DESC, y DESC) }
           38  +} {
           39  +  catchsql { DROP INDEX i1 }
           40  +  execsql $idx
           41  +  foreach {tn q res} {
           42  +    1 "GROUP BY x, y ORDER BY x, y"            {1 a 1 b   2 a 2 b   3 a 3 b}
           43  +    2 "GROUP BY x, y ORDER BY x DESC, y"       {3 a 3 b   2 a 2 b   1 a 1 b}
           44  +    3 "GROUP BY x, y ORDER BY x, y DESC"       {1 b 1 a   2 b 2 a   3 b 3 a}
           45  +    4 "GROUP BY x, y ORDER BY x DESC, y DESC"  {3 b 3 a   2 b 2 a   1 b 1 a}
           46  +  } {
           47  +    do_execsql_test 1.$n.$tn "SELECT * FROM t1 $q" $res
           48  +  }
           49  +}
           50  +
           51  +do_execsql_test 2.0 {
           52  +  drop table if exists t1;
           53  +  create table t1(id int);
           54  +  insert into t1(id) values(1),(2),(3),(4),(5);
           55  +  create index t1_idx_id on t1(id asc);
           56  +  select * from t1 group by id order by id;
           57  +  select * from t1 group by id order by id asc;
           58  +  select * from t1 group by id order by id desc;
           59  +} {
           60  +  1 2 3 4 5   1 2 3 4 5   5 4 3 2 1
           61  +}
           62  +
           63  +finish_test
           64  +
           65  +