| Index: third_party/sqlite/src/src/vdbe.c | 
| diff --git a/third_party/sqlite/src/src/vdbe.c b/third_party/sqlite/src/src/vdbe.c | 
| index 5376b08a00ef9d9f2d27e0d54627fcbe64af20ff..366c7a01661b2d48e986d903d412981e69df33f5 100644 | 
| --- a/third_party/sqlite/src/src/vdbe.c | 
| +++ b/third_party/sqlite/src/src/vdbe.c | 
| @@ -9,33 +9,8 @@ | 
| **    May you share freely, never taking more than you give. | 
| ** | 
| ************************************************************************* | 
| -** The code in this file implements execution method of the | 
| -** Virtual Database Engine (VDBE).  A separate file ("vdbeaux.c") | 
| -** handles housekeeping details such as creating and deleting | 
| -** VDBE instances.  This file is solely interested in executing | 
| -** the VDBE program. | 
| -** | 
| -** In the external interface, an "sqlite3_stmt*" is an opaque pointer | 
| -** to a VDBE. | 
| -** | 
| -** The SQL parser generates a program which is then executed by | 
| -** the VDBE to do the work of the SQL statement.  VDBE programs are | 
| -** similar in form to assembly language.  The program consists of | 
| -** a linear sequence of operations.  Each operation has an opcode | 
| -** and 5 operands.  Operands P1, P2, and P3 are integers.  Operand P4 | 
| -** is a null-terminated string.  Operand P5 is an unsigned character. | 
| -** Few opcodes use all 5 operands. | 
| -** | 
| -** Computation results are stored on a set of registers numbered beginning | 
| -** with 1 and going up to Vdbe.nMem.  Each register can store | 
| -** either an integer, a null-terminated string, a floating point | 
| -** number, or the SQL "NULL" value.  An implicit conversion from one | 
| -** type to the other occurs as necessary. | 
| -** | 
| -** Most of the code in this file is taken up by the sqlite3VdbeExec() | 
| -** function which does the work of interpreting a VDBE program. | 
| -** But other routines are also provided to help in building up | 
| -** a program instruction by instruction. | 
| +** The code in this file implements the function that runs the | 
| +** bytecode of a prepared statement. | 
| ** | 
| ** Various scripts scan this source file in order to generate HTML | 
| ** documentation, headers files, or other derived files.  The formatting | 
| @@ -49,10 +24,14 @@ | 
| /* | 
| ** Invoke this macro on memory cells just prior to changing the | 
| ** value of the cell.  This macro verifies that shallow copies are | 
| -** not misused. | 
| +** not misused.  A shallow copy of a string or blob just copies a | 
| +** pointer to the string or blob, not the content.  If the original | 
| +** is changed while the copy is still in use, the string or blob might | 
| +** be changed out from under the copy.  This macro verifies that nothing | 
| +** like that ever happens. | 
| */ | 
| #ifdef SQLITE_DEBUG | 
| -# define memAboutToChange(P,M) sqlite3VdbeMemPrepareToChange(P,M) | 
| +# define memAboutToChange(P,M) sqlite3VdbeMemAboutToChange(P,M) | 
| #else | 
| # define memAboutToChange(P,M) | 
| #endif | 
| @@ -70,8 +49,8 @@ int sqlite3_search_count = 0; | 
|  | 
| /* | 
| ** When this global variable is positive, it gets decremented once before | 
| -** each instruction in the VDBE.  When reaches zero, the u1.isInterrupted | 
| -** field of the sqlite3 structure is set in order to simulate and interrupt. | 
| +** each instruction in the VDBE.  When it reaches zero, the u1.isInterrupted | 
| +** field of the sqlite3 structure is set in order to simulate an interrupt. | 
| ** | 
| ** This facility is used for testing purposes only.  It does not function | 
| ** in an ordinary build. | 
| @@ -108,7 +87,7 @@ static void updateMaxBlobsize(Mem *p){ | 
| #endif | 
|  | 
| /* | 
| -** The next global variable is incremented each type the OP_Found opcode | 
| +** The next global variable is incremented each time the OP_Found opcode | 
| ** is executed. This is used to test whether or not the foreign key | 
| ** operation implemented using OP_FkIsZero is working. This variable | 
| ** has no function other than to help verify the correct operation of the | 
| @@ -129,11 +108,45 @@ int sqlite3_found_count = 0; | 
| #endif | 
|  | 
| /* | 
| +** Invoke the VDBE coverage callback, if that callback is defined.  This | 
| +** feature is used for test suite validation only and does not appear an | 
| +** production builds. | 
| +** | 
| +** M is an integer, 2 or 3, that indices how many different ways the | 
| +** branch can go.  It is usually 2.  "I" is the direction the branch | 
| +** goes.  0 means falls through.  1 means branch is taken.  2 means the | 
| +** second alternative branch is taken. | 
| +** | 
| +** iSrcLine is the source code line (from the __LINE__ macro) that | 
| +** generated the VDBE instruction.  This instrumentation assumes that all | 
| +** source code is in a single file (the amalgamation).  Special values 1 | 
| +** and 2 for the iSrcLine parameter mean that this particular branch is | 
| +** always taken or never taken, respectively. | 
| +*/ | 
| +#if !defined(SQLITE_VDBE_COVERAGE) | 
| +# define VdbeBranchTaken(I,M) | 
| +#else | 
| +# define VdbeBranchTaken(I,M) vdbeTakeBranch(pOp->iSrcLine,I,M) | 
| +  static void vdbeTakeBranch(int iSrcLine, u8 I, u8 M){ | 
| +    if( iSrcLine<=2 && ALWAYS(iSrcLine>0) ){ | 
| +      M = iSrcLine; | 
| +      /* Assert the truth of VdbeCoverageAlwaysTaken() and | 
| +      ** VdbeCoverageNeverTaken() */ | 
| +      assert( (M & I)==I ); | 
| +    }else{ | 
| +      if( sqlite3GlobalConfig.xVdbeBranch==0 ) return;  /*NO_TEST*/ | 
| +      sqlite3GlobalConfig.xVdbeBranch(sqlite3GlobalConfig.pVdbeBranchArg, | 
| +                                      iSrcLine,I,M); | 
| +    } | 
| +  } | 
| +#endif | 
| + | 
| +/* | 
| ** Convert the given register into a string if it isn't one | 
| ** already. Return non-zero if a malloc() fails. | 
| */ | 
| #define Stringify(P, enc) \ | 
| -   if(((P)->flags&(MEM_Str|MEM_Blob))==0 && sqlite3VdbeMemStringify(P,enc)) \ | 
| +   if(((P)->flags&(MEM_Str|MEM_Blob))==0 && sqlite3VdbeMemStringify(P,enc,0)) \ | 
| { goto no_mem; } | 
|  | 
| /* | 
| @@ -145,41 +158,14 @@ int sqlite3_found_count = 0; | 
| ** | 
| ** This routine converts an ephemeral string into a dynamically allocated | 
| ** string that the register itself controls.  In other words, it | 
| -** converts an MEM_Ephem string into an MEM_Dyn string. | 
| +** converts an MEM_Ephem string into a string with P.z==P.zMalloc. | 
| */ | 
| #define Deephemeralize(P) \ | 
| if( ((P)->flags&MEM_Ephem)!=0 \ | 
| && sqlite3VdbeMemMakeWriteable(P) ){ goto no_mem;} | 
|  | 
| -/* | 
| -** Call sqlite3VdbeMemExpandBlob() on the supplied value (type Mem*) | 
| -** P if required. | 
| -*/ | 
| -#define ExpandBlob(P) (((P)->flags&MEM_Zero)?sqlite3VdbeMemExpandBlob(P):0) | 
| - | 
| -/* | 
| -** Argument pMem points at a register that will be passed to a | 
| -** user-defined function or returned to the user as the result of a query. | 
| -** This routine sets the pMem->type variable used by the sqlite3_value_*() | 
| -** routines. | 
| -*/ | 
| -void sqlite3VdbeMemStoreType(Mem *pMem){ | 
| -  int flags = pMem->flags; | 
| -  if( flags & MEM_Null ){ | 
| -    pMem->type = SQLITE_NULL; | 
| -  } | 
| -  else if( flags & MEM_Int ){ | 
| -    pMem->type = SQLITE_INTEGER; | 
| -  } | 
| -  else if( flags & MEM_Real ){ | 
| -    pMem->type = SQLITE_FLOAT; | 
| -  } | 
| -  else if( flags & MEM_Str ){ | 
| -    pMem->type = SQLITE_TEXT; | 
| -  }else{ | 
| -    pMem->type = SQLITE_BLOB; | 
| -  } | 
| -} | 
| +/* Return true if the cursor was opened using the OP_OpenSorter opcode. */ | 
| +#define isSorter(x) ((x)->pSorter!=0) | 
|  | 
| /* | 
| ** Allocate VdbeCursor number iCur.  Return a pointer to it.  Return NULL | 
| @@ -189,7 +175,7 @@ static VdbeCursor *allocateCursor( | 
| Vdbe *p,              /* The virtual machine */ | 
| int iCur,             /* Index of the new VdbeCursor */ | 
| int nField,           /* Number of fields in the table or index */ | 
| -  int iDb,              /* When database the cursor belongs to, or -1 */ | 
| +  int iDb,              /* Database the cursor belongs to, or -1 */ | 
| int isBtreeCursor     /* True for B-Tree.  False for pseudo-table or vtab */ | 
| ){ | 
| /* Find the memory cell that will be used to store the blob of memory | 
| @@ -215,26 +201,23 @@ static VdbeCursor *allocateCursor( | 
| int nByte; | 
| VdbeCursor *pCx = 0; | 
| nByte = | 
| -      ROUND8(sizeof(VdbeCursor)) + | 
| -      (isBtreeCursor?sqlite3BtreeCursorSize():0) + | 
| -      2*nField*sizeof(u32); | 
| +      ROUND8(sizeof(VdbeCursor)) + 2*sizeof(u32)*nField + | 
| +      (isBtreeCursor?sqlite3BtreeCursorSize():0); | 
|  | 
| assert( iCur<p->nCursor ); | 
| if( p->apCsr[iCur] ){ | 
| sqlite3VdbeFreeCursor(p, p->apCsr[iCur]); | 
| p->apCsr[iCur] = 0; | 
| } | 
| -  if( SQLITE_OK==sqlite3VdbeMemGrow(pMem, nByte, 0) ){ | 
| +  if( SQLITE_OK==sqlite3VdbeMemClearAndResize(pMem, nByte) ){ | 
| p->apCsr[iCur] = pCx = (VdbeCursor*)pMem->z; | 
| memset(pCx, 0, sizeof(VdbeCursor)); | 
| pCx->iDb = iDb; | 
| pCx->nField = nField; | 
| -    if( nField ){ | 
| -      pCx->aType = (u32 *)&pMem->z[ROUND8(sizeof(VdbeCursor))]; | 
| -    } | 
| +    pCx->aOffset = &pCx->aType[nField]; | 
| if( isBtreeCursor ){ | 
| pCx->pCursor = (BtCursor*) | 
| -          &pMem->z[ROUND8(sizeof(VdbeCursor))+2*nField*sizeof(u32)]; | 
| +          &pMem->z[ROUND8(sizeof(VdbeCursor))+2*sizeof(u32)*nField]; | 
| sqlite3BtreeCursorZero(pCx->pCursor); | 
| } | 
| } | 
| @@ -246,21 +229,29 @@ static VdbeCursor *allocateCursor( | 
| ** do so without loss of information.  In other words, if the string | 
| ** looks like a number, convert it into a number.  If it does not | 
| ** look like a number, leave it alone. | 
| -*/ | 
| -static void applyNumericAffinity(Mem *pRec){ | 
| -  if( (pRec->flags & (MEM_Real|MEM_Int))==0 ){ | 
| -    double rValue; | 
| -    i64 iValue; | 
| -    u8 enc = pRec->enc; | 
| -    if( (pRec->flags&MEM_Str)==0 ) return; | 
| -    if( sqlite3AtoF(pRec->z, &rValue, pRec->n, enc)==0 ) return; | 
| -    if( 0==sqlite3Atoi64(pRec->z, &iValue, pRec->n, enc) ){ | 
| -      pRec->u.i = iValue; | 
| -      pRec->flags |= MEM_Int; | 
| -    }else{ | 
| -      pRec->r = rValue; | 
| -      pRec->flags |= MEM_Real; | 
| -    } | 
| +** | 
| +** If the bTryForInt flag is true, then extra effort is made to give | 
| +** an integer representation.  Strings that look like floating point | 
| +** values but which have no fractional component (example: '48.00') | 
| +** will have a MEM_Int representation when bTryForInt is true. | 
| +** | 
| +** If bTryForInt is false, then if the input string contains a decimal | 
| +** point or exponential notation, the result is only MEM_Real, even | 
| +** if there is an exact integer representation of the quantity. | 
| +*/ | 
| +static void applyNumericAffinity(Mem *pRec, int bTryForInt){ | 
| +  double rValue; | 
| +  i64 iValue; | 
| +  u8 enc = pRec->enc; | 
| +  assert( (pRec->flags & (MEM_Str|MEM_Int|MEM_Real))==MEM_Str ); | 
| +  if( sqlite3AtoF(pRec->z, &rValue, pRec->n, enc)==0 ) return; | 
| +  if( 0==sqlite3Atoi64(pRec->z, &iValue, pRec->n, enc) ){ | 
| +    pRec->u.i = iValue; | 
| +    pRec->flags |= MEM_Int; | 
| +  }else{ | 
| +    pRec->u.r = rValue; | 
| +    pRec->flags |= MEM_Real; | 
| +    if( bTryForInt ) sqlite3VdbeIntegerAffinity(pRec); | 
| } | 
| } | 
|  | 
| @@ -287,21 +278,23 @@ static void applyAffinity( | 
| char affinity,      /* The affinity to be applied */ | 
| u8 enc              /* Use this text encoding */ | 
| ){ | 
| -  if( affinity==SQLITE_AFF_TEXT ){ | 
| +  if( affinity>=SQLITE_AFF_NUMERIC ){ | 
| +    assert( affinity==SQLITE_AFF_INTEGER || affinity==SQLITE_AFF_REAL | 
| +             || affinity==SQLITE_AFF_NUMERIC ); | 
| +    if( (pRec->flags & MEM_Int)==0 ){ | 
| +      if( (pRec->flags & MEM_Real)==0 ){ | 
| +        if( pRec->flags & MEM_Str ) applyNumericAffinity(pRec,1); | 
| +      }else{ | 
| +        sqlite3VdbeIntegerAffinity(pRec); | 
| +      } | 
| +    } | 
| +  }else if( affinity==SQLITE_AFF_TEXT ){ | 
| /* Only attempt the conversion to TEXT if there is an integer or real | 
| ** representation (blob and NULL do not get converted) but no string | 
| ** representation. | 
| */ | 
| if( 0==(pRec->flags&MEM_Str) && (pRec->flags&(MEM_Real|MEM_Int)) ){ | 
| -      sqlite3VdbeMemStringify(pRec, enc); | 
| -    } | 
| -    pRec->flags &= ~(MEM_Real|MEM_Int); | 
| -  }else if( affinity!=SQLITE_AFF_NONE ){ | 
| -    assert( affinity==SQLITE_AFF_INTEGER || affinity==SQLITE_AFF_REAL | 
| -             || affinity==SQLITE_AFF_NUMERIC ); | 
| -    applyNumericAffinity(pRec); | 
| -    if( pRec->flags & MEM_Real ){ | 
| -      sqlite3VdbeIntegerAffinity(pRec); | 
| +      sqlite3VdbeMemStringify(pRec, enc, 1); | 
| } | 
| } | 
| } | 
| @@ -313,12 +306,13 @@ static void applyAffinity( | 
| ** loss of information and return the revised type of the argument. | 
| */ | 
| int sqlite3_value_numeric_type(sqlite3_value *pVal){ | 
| -  Mem *pMem = (Mem*)pVal; | 
| -  if( pMem->type==SQLITE_TEXT ){ | 
| -    applyNumericAffinity(pMem); | 
| -    sqlite3VdbeMemStoreType(pMem); | 
| +  int eType = sqlite3_value_type(pVal); | 
| +  if( eType==SQLITE_TEXT ){ | 
| +    Mem *pMem = (Mem*)pVal; | 
| +    applyNumericAffinity(pMem, 0); | 
| +    eType = sqlite3_value_type(pVal); | 
| } | 
| -  return pMem->type; | 
| +  return eType; | 
| } | 
|  | 
| /* | 
| @@ -333,6 +327,41 @@ void sqlite3ValueApplyAffinity( | 
| applyAffinity((Mem *)pVal, affinity, enc); | 
| } | 
|  | 
| +/* | 
| +** pMem currently only holds a string type (or maybe a BLOB that we can | 
| +** interpret as a string if we want to).  Compute its corresponding | 
| +** numeric type, if has one.  Set the pMem->u.r and pMem->u.i fields | 
| +** accordingly. | 
| +*/ | 
| +static u16 SQLITE_NOINLINE computeNumericType(Mem *pMem){ | 
| +  assert( (pMem->flags & (MEM_Int|MEM_Real))==0 ); | 
| +  assert( (pMem->flags & (MEM_Str|MEM_Blob))!=0 ); | 
| +  if( sqlite3AtoF(pMem->z, &pMem->u.r, pMem->n, pMem->enc)==0 ){ | 
| +    return 0; | 
| +  } | 
| +  if( sqlite3Atoi64(pMem->z, &pMem->u.i, pMem->n, pMem->enc)==SQLITE_OK ){ | 
| +    return MEM_Int; | 
| +  } | 
| +  return MEM_Real; | 
| +} | 
| + | 
| +/* | 
| +** Return the numeric type for pMem, either MEM_Int or MEM_Real or both or | 
| +** none. | 
| +** | 
| +** Unlike applyNumericAffinity(), this routine does not modify pMem->flags. | 
| +** But it does set pMem->u.r and pMem->u.i appropriately. | 
| +*/ | 
| +static u16 numericType(Mem *pMem){ | 
| +  if( pMem->flags & (MEM_Int|MEM_Real) ){ | 
| +    return pMem->flags & (MEM_Int|MEM_Real); | 
| +  } | 
| +  if( pMem->flags & (MEM_Str|MEM_Blob) ){ | 
| +    return computeNumericType(pMem); | 
| +  } | 
| +  return 0; | 
| +} | 
| + | 
| #ifdef SQLITE_DEBUG | 
| /* | 
| ** Write a nice string representation of the contents of cell pMem | 
| @@ -420,35 +449,36 @@ void sqlite3VdbeMemPrettyPrint(Mem *pMem, char *zBuf){ | 
| /* | 
| ** Print the value of a register for tracing purposes: | 
| */ | 
| -static void memTracePrint(FILE *out, Mem *p){ | 
| -  if( p->flags & MEM_Null ){ | 
| -    fprintf(out, " NULL"); | 
| +static void memTracePrint(Mem *p){ | 
| +  if( p->flags & MEM_Undefined ){ | 
| +    printf(" undefined"); | 
| +  }else if( p->flags & MEM_Null ){ | 
| +    printf(" NULL"); | 
| }else if( (p->flags & (MEM_Int|MEM_Str))==(MEM_Int|MEM_Str) ){ | 
| -    fprintf(out, " si:%lld", p->u.i); | 
| +    printf(" si:%lld", p->u.i); | 
| }else if( p->flags & MEM_Int ){ | 
| -    fprintf(out, " i:%lld", p->u.i); | 
| +    printf(" i:%lld", p->u.i); | 
| #ifndef SQLITE_OMIT_FLOATING_POINT | 
| }else if( p->flags & MEM_Real ){ | 
| -    fprintf(out, " r:%g", p->r); | 
| +    printf(" r:%g", p->u.r); | 
| #endif | 
| }else if( p->flags & MEM_RowSet ){ | 
| -    fprintf(out, " (rowset)"); | 
| +    printf(" (rowset)"); | 
| }else{ | 
| char zBuf[200]; | 
| sqlite3VdbeMemPrettyPrint(p, zBuf); | 
| -    fprintf(out, " "); | 
| -    fprintf(out, "%s", zBuf); | 
| +    printf(" %s", zBuf); | 
| } | 
| } | 
| -static void registerTrace(FILE *out, int iReg, Mem *p){ | 
| -  fprintf(out, "REG[%d] = ", iReg); | 
| -  memTracePrint(out, p); | 
| -  fprintf(out, "\n"); | 
| +static void registerTrace(int iReg, Mem *p){ | 
| +  printf("REG[%d] = ", iReg); | 
| +  memTracePrint(p); | 
| +  printf("\n"); | 
| } | 
| #endif | 
|  | 
| #ifdef SQLITE_DEBUG | 
| -#  define REGISTER_TRACE(R,M) if(p->trace)registerTrace(p->trace,R,M) | 
| +#  define REGISTER_TRACE(R,M) if(db->flags&SQLITE_VdbeTrace)registerTrace(R,M) | 
| #else | 
| #  define REGISTER_TRACE(R,M) | 
| #endif | 
| @@ -464,20 +494,6 @@ static void registerTrace(FILE *out, int iReg, Mem *p){ | 
|  | 
| #endif | 
|  | 
| -/* | 
| -** The CHECK_FOR_INTERRUPT macro defined here looks to see if the | 
| -** sqlite3_interrupt() routine has been called.  If it has been, then | 
| -** processing of the VDBE program is interrupted. | 
| -** | 
| -** This macro added to every instruction that does a jump in order to | 
| -** implement a loop.  This test used to be on every single instruction, | 
| -** but that meant we more testing that we needed.  By only testing the | 
| -** flag on jump instructions, we get a (small) speed improvement. | 
| -*/ | 
| -#define CHECK_FOR_INTERRUPT \ | 
| -   if( db->u1.isInterrupted ) goto abort_due_to_interrupt; | 
| - | 
| - | 
| #ifndef NDEBUG | 
| /* | 
| ** This function is only called from within an assert() expression. It | 
| @@ -498,50 +514,10 @@ static int checkSavepointCount(sqlite3 *db){ | 
| } | 
| #endif | 
|  | 
| -/* | 
| -** Transfer error message text from an sqlite3_vtab.zErrMsg (text stored | 
| -** in memory obtained from sqlite3_malloc) into a Vdbe.zErrMsg (text stored | 
| -** in memory obtained from sqlite3DbMalloc). | 
| -*/ | 
| -static void importVtabErrMsg(Vdbe *p, sqlite3_vtab *pVtab){ | 
| -  sqlite3 *db = p->db; | 
| -  sqlite3DbFree(db, p->zErrMsg); | 
| -  p->zErrMsg = sqlite3DbStrDup(db, pVtab->zErrMsg); | 
| -  sqlite3_free(pVtab->zErrMsg); | 
| -  pVtab->zErrMsg = 0; | 
| -} | 
| - | 
|  | 
| /* | 
| -** Execute as much of a VDBE program as we can then return. | 
| -** | 
| -** sqlite3VdbeMakeReady() must be called before this routine in order to | 
| -** close the program with a final OP_Halt and to set up the callbacks | 
| -** and the error message pointer. | 
| -** | 
| -** Whenever a row or result data is available, this routine will either | 
| -** invoke the result callback (if there is one) or return with | 
| -** SQLITE_ROW. | 
| -** | 
| -** If an attempt is made to open a locked database, then this routine | 
| -** will either invoke the busy callback (if there is one) or it will | 
| -** return SQLITE_BUSY. | 
| -** | 
| -** If an error occurs, an error message is written to memory obtained | 
| -** from sqlite3_malloc() and p->zErrMsg is made to point to that memory. | 
| -** The error code is stored in p->rc and this routine returns SQLITE_ERROR. | 
| -** | 
| -** If the callback ever returns non-zero, then the program exits | 
| -** immediately.  There will be no error message but the p->rc field is | 
| -** set to SQLITE_ABORT and this routine will return SQLITE_ERROR. | 
| -** | 
| -** A memory allocation error causes p->rc to be set to SQLITE_NOMEM and this | 
| -** routine to return SQLITE_ERROR. | 
| -** | 
| -** Other fatal errors return SQLITE_ERROR. | 
| -** | 
| -** After this routine has finished, sqlite3VdbeFinalize() should be | 
| -** used to clean up the mess that was left behind. | 
| +** Execute as much of a VDBE program as we can. | 
| +** This is the core of sqlite3_step(). | 
| */ | 
| int sqlite3VdbeExec( | 
| Vdbe *p                    /* The VDBE */ | 
| @@ -553,20 +529,20 @@ int sqlite3VdbeExec( | 
| sqlite3 *db = p->db;       /* The database */ | 
| u8 resetSchemaOnFault = 0; /* Reset schema after an error if positive */ | 
| u8 encoding = ENC(db);     /* The database encoding */ | 
| +  int iCompare = 0;          /* Result of last OP_Compare operation */ | 
| +  unsigned nVmStep = 0;      /* Number of virtual machine steps */ | 
| #ifndef SQLITE_OMIT_PROGRESS_CALLBACK | 
| -  int checkProgress;         /* True if progress callbacks are enabled */ | 
| -  int nProgressOps = 0;      /* Opcodes executed since progress callback. */ | 
| +  unsigned nProgressLimit = 0;/* Invoke xProgress() when nVmStep reaches this */ | 
| #endif | 
| Mem *aMem = p->aMem;       /* Copy of p->aMem */ | 
| Mem *pIn1 = 0;             /* 1st input operand */ | 
| Mem *pIn2 = 0;             /* 2nd input operand */ | 
| Mem *pIn3 = 0;             /* 3rd input operand */ | 
| Mem *pOut = 0;             /* Output operand */ | 
| -  int iCompare = 0;          /* Result of last OP_Compare operation */ | 
| int *aPermute = 0;         /* Permutation of columns for OP_Compare */ | 
| +  i64 lastRowid = db->lastRowid;  /* Saved value of the last insert ROWID */ | 
| #ifdef VDBE_PROFILE | 
| u64 start;                 /* CPU clock count at start of opcode */ | 
| -  int origPc;                /* Program counter at start of opcode */ | 
| #endif | 
| /*** INSERT STACK UNION HERE ***/ | 
|  | 
| @@ -578,24 +554,49 @@ int sqlite3VdbeExec( | 
| goto no_mem; | 
| } | 
| assert( p->rc==SQLITE_OK || p->rc==SQLITE_BUSY ); | 
| +  assert( p->bIsReader || p->readOnly!=0 ); | 
| p->rc = SQLITE_OK; | 
| +  p->iCurrentTime = 0; | 
| assert( p->explain==0 ); | 
| p->pResultSet = 0; | 
| db->busyHandler.nBusy = 0; | 
| -  CHECK_FOR_INTERRUPT; | 
| +  if( db->u1.isInterrupted ) goto abort_due_to_interrupt; | 
| sqlite3VdbeIOTraceSql(p); | 
| #ifndef SQLITE_OMIT_PROGRESS_CALLBACK | 
| -  checkProgress = db->xProgress!=0; | 
| +  if( db->xProgress ){ | 
| +    assert( 0 < db->nProgressOps ); | 
| +    nProgressLimit = (unsigned)p->aCounter[SQLITE_STMTSTATUS_VM_STEP]; | 
| +    if( nProgressLimit==0 ){ | 
| +      nProgressLimit = db->nProgressOps; | 
| +    }else{ | 
| +      nProgressLimit %= (unsigned)db->nProgressOps; | 
| +    } | 
| +  } | 
| #endif | 
| #ifdef SQLITE_DEBUG | 
| sqlite3BeginBenignMalloc(); | 
| -  if( p->pc==0  && (p->db->flags & SQLITE_VdbeListing)!=0 ){ | 
| +  if( p->pc==0 | 
| +   && (p->db->flags & (SQLITE_VdbeListing|SQLITE_VdbeEQP|SQLITE_VdbeTrace))!=0 | 
| +  ){ | 
| int i; | 
| -    printf("VDBE Program Listing:\n"); | 
| +    int once = 1; | 
| sqlite3VdbePrintSql(p); | 
| -    for(i=0; i<p->nOp; i++){ | 
| -      sqlite3VdbePrintOp(stdout, i, &aOp[i]); | 
| +    if( p->db->flags & SQLITE_VdbeListing ){ | 
| +      printf("VDBE Program Listing:\n"); | 
| +      for(i=0; i<p->nOp; i++){ | 
| +        sqlite3VdbePrintOp(stdout, i, &aOp[i]); | 
| +      } | 
| +    } | 
| +    if( p->db->flags & SQLITE_VdbeEQP ){ | 
| +      for(i=0; i<p->nOp; i++){ | 
| +        if( aOp[i].opcode==OP_Explain ){ | 
| +          if( once ) printf("VDBE Query Plan:\n"); | 
| +          printf("%s\n", aOp[i].p4.z); | 
| +          once = 0; | 
| +        } | 
| +      } | 
| } | 
| +    if( p->db->flags & SQLITE_VdbeTrace )  printf("VDBE Trace:\n"); | 
| } | 
| sqlite3EndBenignMalloc(); | 
| #endif | 
| @@ -603,20 +604,16 @@ int sqlite3VdbeExec( | 
| assert( pc>=0 && pc<p->nOp ); | 
| if( db->mallocFailed ) goto no_mem; | 
| #ifdef VDBE_PROFILE | 
| -    origPc = pc; | 
| start = sqlite3Hwtime(); | 
| #endif | 
| +    nVmStep++; | 
| pOp = &aOp[pc]; | 
|  | 
| /* Only allow tracing if SQLITE_DEBUG is defined. | 
| */ | 
| #ifdef SQLITE_DEBUG | 
| -    if( p->trace ){ | 
| -      if( pc==0 ){ | 
| -        printf("VDBE Execution Trace:\n"); | 
| -        sqlite3VdbePrintSql(p); | 
| -      } | 
| -      sqlite3VdbePrintOp(p->trace, pc, pOp); | 
| +    if( db->flags & SQLITE_VdbeTrace ){ | 
| +      sqlite3VdbePrintOp(stdout, pc, pOp); | 
| } | 
| #endif | 
|  | 
| @@ -633,28 +630,7 @@ int sqlite3VdbeExec( | 
| } | 
| #endif | 
|  | 
| -#ifndef SQLITE_OMIT_PROGRESS_CALLBACK | 
| -    /* Call the progress callback if it is configured and the required number | 
| -    ** of VDBE ops have been executed (either since this invocation of | 
| -    ** sqlite3VdbeExec() or since last time the progress callback was called). | 
| -    ** If the progress callback returns non-zero, exit the virtual machine with | 
| -    ** a return code SQLITE_ABORT. | 
| -    */ | 
| -    if( checkProgress ){ | 
| -      if( db->nProgressOps==nProgressOps ){ | 
| -        int prc; | 
| -        prc = db->xProgress(db->pProgressArg); | 
| -        if( prc!=0 ){ | 
| -          rc = SQLITE_INTERRUPT; | 
| -          goto vdbe_error_halt; | 
| -        } | 
| -        nProgressOps = 0; | 
| -      } | 
| -      nProgressOps++; | 
| -    } | 
| -#endif | 
| - | 
| -    /* On any opcode with the "out2-prerelase" tag, free any | 
| +    /* On any opcode with the "out2-prerelease" tag, free any | 
| ** external allocations out of mem[p2] and set mem[p2] to be | 
| ** an undefined integer.  Opcodes will either fill in the integer | 
| ** value or convert mem[p2] to a different type. | 
| @@ -662,10 +638,10 @@ int sqlite3VdbeExec( | 
| assert( pOp->opflags==sqlite3OpcodeProperty[pOp->opcode] ); | 
| if( pOp->opflags & OPFLG_OUT2_PRERELEASE ){ | 
| assert( pOp->p2>0 ); | 
| -      assert( pOp->p2<=p->nMem ); | 
| +      assert( pOp->p2<=(p->nMem-p->nCursor) ); | 
| pOut = &aMem[pOp->p2]; | 
| memAboutToChange(p, pOut); | 
| -      sqlite3VdbeMemReleaseExternal(pOut); | 
| +      if( VdbeMemDynamic(pOut) ) sqlite3VdbeMemSetNull(pOut); | 
| pOut->flags = MEM_Int; | 
| } | 
|  | 
| @@ -673,30 +649,33 @@ int sqlite3VdbeExec( | 
| #ifdef SQLITE_DEBUG | 
| if( (pOp->opflags & OPFLG_IN1)!=0 ){ | 
| assert( pOp->p1>0 ); | 
| -      assert( pOp->p1<=p->nMem ); | 
| +      assert( pOp->p1<=(p->nMem-p->nCursor) ); | 
| assert( memIsValid(&aMem[pOp->p1]) ); | 
| +      assert( sqlite3VdbeCheckMemInvariants(&aMem[pOp->p1]) ); | 
| REGISTER_TRACE(pOp->p1, &aMem[pOp->p1]); | 
| } | 
| if( (pOp->opflags & OPFLG_IN2)!=0 ){ | 
| assert( pOp->p2>0 ); | 
| -      assert( pOp->p2<=p->nMem ); | 
| +      assert( pOp->p2<=(p->nMem-p->nCursor) ); | 
| assert( memIsValid(&aMem[pOp->p2]) ); | 
| +      assert( sqlite3VdbeCheckMemInvariants(&aMem[pOp->p2]) ); | 
| REGISTER_TRACE(pOp->p2, &aMem[pOp->p2]); | 
| } | 
| if( (pOp->opflags & OPFLG_IN3)!=0 ){ | 
| assert( pOp->p3>0 ); | 
| -      assert( pOp->p3<=p->nMem ); | 
| +      assert( pOp->p3<=(p->nMem-p->nCursor) ); | 
| assert( memIsValid(&aMem[pOp->p3]) ); | 
| +      assert( sqlite3VdbeCheckMemInvariants(&aMem[pOp->p3]) ); | 
| REGISTER_TRACE(pOp->p3, &aMem[pOp->p3]); | 
| } | 
| if( (pOp->opflags & OPFLG_OUT2)!=0 ){ | 
| assert( pOp->p2>0 ); | 
| -      assert( pOp->p2<=p->nMem ); | 
| +      assert( pOp->p2<=(p->nMem-p->nCursor) ); | 
| memAboutToChange(p, &aMem[pOp->p2]); | 
| } | 
| if( (pOp->opflags & OPFLG_OUT3)!=0 ){ | 
| assert( pOp->p3>0 ); | 
| -      assert( pOp->p3<=p->nMem ); | 
| +      assert( pOp->p3<=(p->nMem-p->nCursor) ); | 
| memAboutToChange(p, &aMem[pOp->p3]); | 
| } | 
| #endif | 
| @@ -744,10 +723,44 @@ int sqlite3VdbeExec( | 
| ** The next instruction executed will be | 
| ** the one at index P2 from the beginning of | 
| ** the program. | 
| +** | 
| +** The P1 parameter is not actually used by this opcode.  However, it | 
| +** is sometimes set to 1 instead of 0 as a hint to the command-line shell | 
| +** that this Goto is the bottom of a loop and that the lines from P2 down | 
| +** to the current line should be indented for EXPLAIN output. | 
| */ | 
| case OP_Goto: {             /* jump */ | 
| -  CHECK_FOR_INTERRUPT; | 
| pc = pOp->p2 - 1; | 
| + | 
| +  /* Opcodes that are used as the bottom of a loop (OP_Next, OP_Prev, | 
| +  ** OP_VNext, OP_RowSetNext, or OP_SorterNext) all jump here upon | 
| +  ** completion.  Check to see if sqlite3_interrupt() has been called | 
| +  ** or if the progress callback needs to be invoked. | 
| +  ** | 
| +  ** This code uses unstructured "goto" statements and does not look clean. | 
| +  ** But that is not due to sloppy coding habits. The code is written this | 
| +  ** way for performance, to avoid having to run the interrupt and progress | 
| +  ** checks on every opcode.  This helps sqlite3_step() to run about 1.5% | 
| +  ** faster according to "valgrind --tool=cachegrind" */ | 
| +check_for_interrupt: | 
| +  if( db->u1.isInterrupted ) goto abort_due_to_interrupt; | 
| +#ifndef SQLITE_OMIT_PROGRESS_CALLBACK | 
| +  /* Call the progress callback if it is configured and the required number | 
| +  ** of VDBE ops have been executed (either since this invocation of | 
| +  ** sqlite3VdbeExec() or since last time the progress callback was called). | 
| +  ** If the progress callback returns non-zero, exit the virtual machine with | 
| +  ** a return code SQLITE_ABORT. | 
| +  */ | 
| +  if( db->xProgress!=0 && nVmStep>=nProgressLimit ){ | 
| +    assert( db->nProgressOps!=0 ); | 
| +    nProgressLimit = nVmStep + db->nProgressOps - (nVmStep%db->nProgressOps); | 
| +    if( db->xProgress(db->pProgressArg) ){ | 
| +      rc = SQLITE_INTERRUPT; | 
| +      goto vdbe_error_halt; | 
| +    } | 
| +  } | 
| +#endif | 
| + | 
| break; | 
| } | 
|  | 
| @@ -756,9 +769,10 @@ case OP_Goto: {             /* jump */ | 
| ** Write the current address onto register P1 | 
| ** and then jump to address P2. | 
| */ | 
| -case OP_Gosub: {            /* jump, in1 */ | 
| +case OP_Gosub: {            /* jump */ | 
| +  assert( pOp->p1>0 && pOp->p1<=(p->nMem-p->nCursor) ); | 
| pIn1 = &aMem[pOp->p1]; | 
| -  assert( (pIn1->flags & MEM_Dyn)==0 ); | 
| +  assert( VdbeMemDynamic(pIn1)==0 ); | 
| memAboutToChange(p, pIn1); | 
| pIn1->flags = MEM_Int; | 
| pIn1->u.i = pc; | 
| @@ -769,23 +783,78 @@ case OP_Gosub: {            /* jump, in1 */ | 
|  | 
| /* Opcode:  Return P1 * * * * | 
| ** | 
| -** Jump to the next instruction after the address in register P1. | 
| +** Jump to the next instruction after the address in register P1.  After | 
| +** the jump, register P1 becomes undefined. | 
| */ | 
| case OP_Return: {           /* in1 */ | 
| pIn1 = &aMem[pOp->p1]; | 
| -  assert( pIn1->flags & MEM_Int ); | 
| +  assert( pIn1->flags==MEM_Int ); | 
| pc = (int)pIn1->u.i; | 
| +  pIn1->flags = MEM_Undefined; | 
| +  break; | 
| +} | 
| + | 
| +/* Opcode: InitCoroutine P1 P2 P3 * * | 
| +** | 
| +** Set up register P1 so that it will Yield to the coroutine | 
| +** located at address P3. | 
| +** | 
| +** If P2!=0 then the coroutine implementation immediately follows | 
| +** this opcode.  So jump over the coroutine implementation to | 
| +** address P2. | 
| +** | 
| +** See also: EndCoroutine | 
| +*/ | 
| +case OP_InitCoroutine: {     /* jump */ | 
| +  assert( pOp->p1>0 &&  pOp->p1<=(p->nMem-p->nCursor) ); | 
| +  assert( pOp->p2>=0 && pOp->p2<p->nOp ); | 
| +  assert( pOp->p3>=0 && pOp->p3<p->nOp ); | 
| +  pOut = &aMem[pOp->p1]; | 
| +  assert( !VdbeMemDynamic(pOut) ); | 
| +  pOut->u.i = pOp->p3 - 1; | 
| +  pOut->flags = MEM_Int; | 
| +  if( pOp->p2 ) pc = pOp->p2 - 1; | 
| +  break; | 
| +} | 
| + | 
| +/* Opcode:  EndCoroutine P1 * * * * | 
| +** | 
| +** The instruction at the address in register P1 is a Yield. | 
| +** Jump to the P2 parameter of that Yield. | 
| +** After the jump, register P1 becomes undefined. | 
| +** | 
| +** See also: InitCoroutine | 
| +*/ | 
| +case OP_EndCoroutine: {           /* in1 */ | 
| +  VdbeOp *pCaller; | 
| +  pIn1 = &aMem[pOp->p1]; | 
| +  assert( pIn1->flags==MEM_Int ); | 
| +  assert( pIn1->u.i>=0 && pIn1->u.i<p->nOp ); | 
| +  pCaller = &aOp[pIn1->u.i]; | 
| +  assert( pCaller->opcode==OP_Yield ); | 
| +  assert( pCaller->p2>=0 && pCaller->p2<p->nOp ); | 
| +  pc = pCaller->p2 - 1; | 
| +  pIn1->flags = MEM_Undefined; | 
| break; | 
| } | 
|  | 
| -/* Opcode:  Yield P1 * * * * | 
| +/* Opcode:  Yield P1 P2 * * * | 
| ** | 
| -** Swap the program counter with the value in register P1. | 
| +** Swap the program counter with the value in register P1.  This | 
| +** has the effect of yielding to a coroutine. | 
| +** | 
| +** If the coroutine that is launched by this instruction ends with | 
| +** Yield or Return then continue to the next instruction.  But if | 
| +** the coroutine launched by this instruction ends with | 
| +** EndCoroutine, then jump to P2 rather than continuing with the | 
| +** next instruction. | 
| +** | 
| +** See also: InitCoroutine | 
| */ | 
| -case OP_Yield: {            /* in1 */ | 
| +case OP_Yield: {            /* in1, jump */ | 
| int pcDest; | 
| pIn1 = &aMem[pOp->p1]; | 
| -  assert( (pIn1->flags & MEM_Dyn)==0 ); | 
| +  assert( VdbeMemDynamic(pIn1)==0 ); | 
| pIn1->flags = MEM_Int; | 
| pcDest = (int)pIn1->u.i; | 
| pIn1->u.i = pc; | 
| @@ -794,11 +863,13 @@ case OP_Yield: {            /* in1 */ | 
| break; | 
| } | 
|  | 
| -/* Opcode:  HaltIfNull  P1 P2 P3 P4 * | 
| +/* Opcode:  HaltIfNull  P1 P2 P3 P4 P5 | 
| +** Synopsis:  if r[P3]=null halt | 
| ** | 
| -** Check the value in register P3.  If is is NULL then Halt using | 
| +** Check the value in register P3.  If it is NULL then Halt using | 
| ** parameter P1, P2, and P4 as if this were a Halt instruction.  If the | 
| ** value in register P3 is not NULL, then this routine is a no-op. | 
| +** The P5 parameter should be 1. | 
| */ | 
| case OP_HaltIfNull: {      /* in3 */ | 
| pIn3 = &aMem[pOp->p3]; | 
| @@ -806,7 +877,7 @@ case OP_HaltIfNull: {      /* in3 */ | 
| /* Fall through into OP_Halt */ | 
| } | 
|  | 
| -/* Opcode:  Halt P1 P2 * P4 * | 
| +/* Opcode:  Halt P1 P2 * P4 P5 | 
| ** | 
| ** Exit immediately.  All open cursors, etc are closed | 
| ** automatically. | 
| @@ -821,11 +892,25 @@ case OP_HaltIfNull: {      /* in3 */ | 
| ** | 
| ** If P4 is not null then it is an error message string. | 
| ** | 
| +** P5 is a value between 0 and 4, inclusive, that modifies the P4 string. | 
| +** | 
| +**    0:  (no change) | 
| +**    1:  NOT NULL contraint failed: P4 | 
| +**    2:  UNIQUE constraint failed: P4 | 
| +**    3:  CHECK constraint failed: P4 | 
| +**    4:  FOREIGN KEY constraint failed: P4 | 
| +** | 
| +** If P5 is not zero and P4 is NULL, then everything after the ":" is | 
| +** omitted. | 
| +** | 
| ** There is an implied "Halt 0 0 0" instruction inserted at the very end of | 
| ** every program.  So a jump past the last instruction of the program | 
| ** is the same as executing Halt. | 
| */ | 
| case OP_Halt: { | 
| +  const char *zType; | 
| +  const char *zLogFmt; | 
| + | 
| if( pOp->p1==SQLITE_OK && p->pFrame ){ | 
| /* Halt the sub-program. Return control to the parent frame. */ | 
| VdbeFrame *pFrame = p->pFrame; | 
| @@ -833,6 +918,7 @@ case OP_Halt: { | 
| p->nFrame--; | 
| sqlite3VdbeSetChanges(db, p->nChange); | 
| pc = sqlite3VdbeFrameRestore(pFrame); | 
| +    lastRowid = db->lastRowid; | 
| if( pOp->p2==OE_Ignore ){ | 
| /* Instruction pc is the OP_Program that invoked the sub-program | 
| ** currently being halted. If the p2 instruction of this OP_Halt | 
| @@ -845,32 +931,48 @@ case OP_Halt: { | 
| aMem = p->aMem; | 
| break; | 
| } | 
| - | 
| p->rc = pOp->p1; | 
| p->errorAction = (u8)pOp->p2; | 
| p->pc = pc; | 
| -  if( pOp->p4.z ){ | 
| -    assert( p->rc!=SQLITE_OK ); | 
| -    sqlite3SetString(&p->zErrMsg, db, "%s", pOp->p4.z); | 
| -    testcase( sqlite3GlobalConfig.xLog!=0 ); | 
| -    sqlite3_log(pOp->p1, "abort at %d in [%s]: %s", pc, p->zSql, pOp->p4.z); | 
| -  }else if( p->rc ){ | 
| -    testcase( sqlite3GlobalConfig.xLog!=0 ); | 
| -    sqlite3_log(pOp->p1, "constraint failed at %d in [%s]", pc, p->zSql); | 
| +  if( p->rc ){ | 
| +    if( pOp->p5 ){ | 
| +      static const char * const azType[] = { "NOT NULL", "UNIQUE", "CHECK", | 
| +                                             "FOREIGN KEY" }; | 
| +      assert( pOp->p5>=1 && pOp->p5<=4 ); | 
| +      testcase( pOp->p5==1 ); | 
| +      testcase( pOp->p5==2 ); | 
| +      testcase( pOp->p5==3 ); | 
| +      testcase( pOp->p5==4 ); | 
| +      zType = azType[pOp->p5-1]; | 
| +    }else{ | 
| +      zType = 0; | 
| +    } | 
| +    assert( zType!=0 || pOp->p4.z!=0 ); | 
| +    zLogFmt = "abort at %d in [%s]: %s"; | 
| +    if( zType && pOp->p4.z ){ | 
| +      sqlite3SetString(&p->zErrMsg, db, "%s constraint failed: %s", | 
| +                       zType, pOp->p4.z); | 
| +    }else if( pOp->p4.z ){ | 
| +      sqlite3SetString(&p->zErrMsg, db, "%s", pOp->p4.z); | 
| +    }else{ | 
| +      sqlite3SetString(&p->zErrMsg, db, "%s constraint failed", zType); | 
| +    } | 
| +    sqlite3_log(pOp->p1, zLogFmt, pc, p->zSql, p->zErrMsg); | 
| } | 
| rc = sqlite3VdbeHalt(p); | 
| assert( rc==SQLITE_BUSY || rc==SQLITE_OK || rc==SQLITE_ERROR ); | 
| if( rc==SQLITE_BUSY ){ | 
| p->rc = rc = SQLITE_BUSY; | 
| }else{ | 
| -    assert( rc==SQLITE_OK || p->rc==SQLITE_CONSTRAINT ); | 
| -    assert( rc==SQLITE_OK || db->nDeferredCons>0 ); | 
| +    assert( rc==SQLITE_OK || (p->rc&0xff)==SQLITE_CONSTRAINT ); | 
| +    assert( rc==SQLITE_OK || db->nDeferredCons>0 || db->nDeferredImmCons>0 ); | 
| rc = p->rc ? SQLITE_ERROR : SQLITE_DONE; | 
| } | 
| goto vdbe_return; | 
| } | 
|  | 
| /* Opcode: Integer P1 P2 * * * | 
| +** Synopsis: r[P2]=P1 | 
| ** | 
| ** The 32-bit integer value P1 is written into register P2. | 
| */ | 
| @@ -880,6 +982,7 @@ case OP_Integer: {         /* out2-prerelease */ | 
| } | 
|  | 
| /* Opcode: Int64 * P2 * P4 * | 
| +** Synopsis: r[P2]=P4 | 
| ** | 
| ** P4 is a pointer to a 64-bit integer value. | 
| ** Write that value into register P2. | 
| @@ -892,6 +995,7 @@ case OP_Int64: {           /* out2-prerelease */ | 
|  | 
| #ifndef SQLITE_OMIT_FLOATING_POINT | 
| /* Opcode: Real * P2 * P4 * | 
| +** Synopsis: r[P2]=P4 | 
| ** | 
| ** P4 is a pointer to a 64-bit floating point value. | 
| ** Write that value into register P2. | 
| @@ -899,15 +1003,18 @@ case OP_Int64: {           /* out2-prerelease */ | 
| case OP_Real: {            /* same as TK_FLOAT, out2-prerelease */ | 
| pOut->flags = MEM_Real; | 
| assert( !sqlite3IsNaN(*pOp->p4.pReal) ); | 
| -  pOut->r = *pOp->p4.pReal; | 
| +  pOut->u.r = *pOp->p4.pReal; | 
| break; | 
| } | 
| #endif | 
|  | 
| /* Opcode: String8 * P2 * P4 * | 
| +** Synopsis: r[P2]='P4' | 
| ** | 
| ** P4 points to a nul terminated UTF-8 string. This opcode is transformed | 
| -** into an OP_String before it is executed for the first time. | 
| +** into a String before it is executed for the first time.  During | 
| +** this transformation, the length of string P4 is computed and stored | 
| +** as the P1 parameter. | 
| */ | 
| case OP_String8: {         /* same as TK_STRING, out2-prerelease */ | 
| assert( pOp->p4.z!=0 ); | 
| @@ -919,11 +1026,10 @@ case OP_String8: {         /* same as TK_STRING, out2-prerelease */ | 
| rc = sqlite3VdbeMemSetStr(pOut, pOp->p4.z, -1, SQLITE_UTF8, SQLITE_STATIC); | 
| if( rc==SQLITE_TOOBIG ) goto too_big; | 
| if( SQLITE_OK!=sqlite3VdbeChangeEncoding(pOut, encoding) ) goto no_mem; | 
| -    assert( pOut->zMalloc==pOut->z ); | 
| -    assert( pOut->flags & MEM_Dyn ); | 
| -    pOut->zMalloc = 0; | 
| +    assert( pOut->szMalloc>0 && pOut->zMalloc==pOut->z ); | 
| +    assert( VdbeMemDynamic(pOut)==0 ); | 
| +    pOut->szMalloc = 0; | 
| pOut->flags |= MEM_Static; | 
| -    pOut->flags &= ~MEM_Dyn; | 
| if( pOp->p4type==P4_DYNAMIC ){ | 
| sqlite3DbFree(db, pOp->p4.z); | 
| } | 
| @@ -939,6 +1045,7 @@ case OP_String8: {         /* same as TK_STRING, out2-prerelease */ | 
| } | 
|  | 
| /* Opcode: String P1 P2 * P4 * | 
| +** Synopsis: r[P2]='P4' (len=P1) | 
| ** | 
| ** The string value P4 of length P1 (bytes) is stored in register P2. | 
| */ | 
| @@ -952,17 +1059,51 @@ case OP_String: {          /* out2-prerelease */ | 
| break; | 
| } | 
|  | 
| -/* Opcode: Null * P2 * * * | 
| +/* Opcode: Null P1 P2 P3 * * | 
| +** Synopsis:  r[P2..P3]=NULL | 
| ** | 
| -** Write a NULL into register P2. | 
| +** Write a NULL into registers P2.  If P3 greater than P2, then also write | 
| +** NULL into register P3 and every register in between P2 and P3.  If P3 | 
| +** is less than P2 (typically P3 is zero) then only register P2 is | 
| +** set to NULL. | 
| +** | 
| +** If the P1 value is non-zero, then also set the MEM_Cleared flag so that | 
| +** NULL values will not compare equal even if SQLITE_NULLEQ is set on | 
| +** OP_Ne or OP_Eq. | 
| */ | 
| case OP_Null: {           /* out2-prerelease */ | 
| -  pOut->flags = MEM_Null; | 
| +  int cnt; | 
| +  u16 nullFlag; | 
| +  cnt = pOp->p3-pOp->p2; | 
| +  assert( pOp->p3<=(p->nMem-p->nCursor) ); | 
| +  pOut->flags = nullFlag = pOp->p1 ? (MEM_Null|MEM_Cleared) : MEM_Null; | 
| +  while( cnt>0 ){ | 
| +    pOut++; | 
| +    memAboutToChange(p, pOut); | 
| +    sqlite3VdbeMemSetNull(pOut); | 
| +    pOut->flags = nullFlag; | 
| +    cnt--; | 
| +  } | 
| break; | 
| } | 
|  | 
| +/* Opcode: SoftNull P1 * * * * | 
| +** Synopsis:  r[P1]=NULL | 
| +** | 
| +** Set register P1 to have the value NULL as seen by the OP_MakeRecord | 
| +** instruction, but do not free any string or blob memory associated with | 
| +** the register, so that if the value was a string or blob that was | 
| +** previously copied using OP_SCopy, the copies will continue to be valid. | 
| +*/ | 
| +case OP_SoftNull: { | 
| +  assert( pOp->p1>0 && pOp->p1<=(p->nMem-p->nCursor) ); | 
| +  pOut = &aMem[pOp->p1]; | 
| +  pOut->flags = (pOut->flags|MEM_Null)&~MEM_Undefined; | 
| +  break; | 
| +} | 
|  | 
| -/* Opcode: Blob P1 P2 * P4 | 
| +/* Opcode: Blob P1 P2 * P4 * | 
| +** Synopsis: r[P2]=P4 (len=P1) | 
| ** | 
| ** P4 points to a blob of data P1 bytes long.  Store this | 
| ** blob in register P2. | 
| @@ -976,16 +1117,18 @@ case OP_Blob: {                /* out2-prerelease */ | 
| } | 
|  | 
| /* Opcode: Variable P1 P2 * P4 * | 
| +** Synopsis: r[P2]=parameter(P1,P4) | 
| ** | 
| ** Transfer the values of bound parameter P1 into register P2 | 
| ** | 
| -** If the parameter is named, then its name appears in P4 and P3==1. | 
| +** If the parameter is named, then its name appears in P4. | 
| ** The P4 value is used by sqlite3_bind_parameter_name(). | 
| */ | 
| case OP_Variable: {            /* out2-prerelease */ | 
| Mem *pVar;       /* Value being transferred */ | 
|  | 
| assert( pOp->p1>0 && pOp->p1<=p->nVar ); | 
| +  assert( pOp->p4.z==0 || pOp->p4.z==p->azVar[pOp->p1-1] ); | 
| pVar = &p->aVar[pOp->p1 - 1]; | 
| if( sqlite3VdbeMemTooBig(pVar) ){ | 
| goto too_big; | 
| @@ -996,14 +1139,15 @@ case OP_Variable: {            /* out2-prerelease */ | 
| } | 
|  | 
| /* Opcode: Move P1 P2 P3 * * | 
| +** Synopsis:  r[P2@P3]=r[P1@P3] | 
| ** | 
| -** Move the values in register P1..P1+P3-1 over into | 
| -** registers P2..P2+P3-1.  Registers P1..P1+P1-1 are | 
| +** Move the P3 values in register P1..P1+P3-1 over into | 
| +** registers P2..P2+P3-1.  Registers P1..P1+P3-1 are | 
| ** left holding a NULL.  It is an error for register ranges | 
| -** P1..P1+P3-1 and P2..P2+P3-1 to overlap. | 
| +** P1..P1+P3-1 and P2..P2+P3-1 to overlap.  It is an error | 
| +** for P3 to be less than 1. | 
| */ | 
| case OP_Move: { | 
| -  char *zMalloc;   /* Holding variable for allocated memory */ | 
| int n;           /* Number of registers left to copy */ | 
| int p1;          /* Register to copy from */ | 
| int p2;          /* Register to copy to */ | 
| @@ -1016,40 +1160,55 @@ case OP_Move: { | 
|  | 
| pIn1 = &aMem[p1]; | 
| pOut = &aMem[p2]; | 
| -  while( n-- ){ | 
| -    assert( pOut<=&aMem[p->nMem] ); | 
| -    assert( pIn1<=&aMem[p->nMem] ); | 
| +  do{ | 
| +    assert( pOut<=&aMem[(p->nMem-p->nCursor)] ); | 
| +    assert( pIn1<=&aMem[(p->nMem-p->nCursor)] ); | 
| assert( memIsValid(pIn1) ); | 
| memAboutToChange(p, pOut); | 
| -    zMalloc = pOut->zMalloc; | 
| -    pOut->zMalloc = 0; | 
| sqlite3VdbeMemMove(pOut, pIn1); | 
| -    pIn1->zMalloc = zMalloc; | 
| +#ifdef SQLITE_DEBUG | 
| +    if( pOut->pScopyFrom>=&aMem[p1] && pOut->pScopyFrom<&aMem[p1+pOp->p3] ){ | 
| +      pOut->pScopyFrom += p1 - pOp->p2; | 
| +    } | 
| +#endif | 
| REGISTER_TRACE(p2++, pOut); | 
| pIn1++; | 
| pOut++; | 
| -  } | 
| +  }while( --n ); | 
| break; | 
| } | 
|  | 
| -/* Opcode: Copy P1 P2 * * * | 
| +/* Opcode: Copy P1 P2 P3 * * | 
| +** Synopsis: r[P2@P3+1]=r[P1@P3+1] | 
| ** | 
| -** Make a copy of register P1 into register P2. | 
| +** Make a copy of registers P1..P1+P3 into registers P2..P2+P3. | 
| ** | 
| ** This instruction makes a deep copy of the value.  A duplicate | 
| ** is made of any string or blob constant.  See also OP_SCopy. | 
| */ | 
| -case OP_Copy: {             /* in1, out2 */ | 
| +case OP_Copy: { | 
| +  int n; | 
| + | 
| +  n = pOp->p3; | 
| pIn1 = &aMem[pOp->p1]; | 
| pOut = &aMem[pOp->p2]; | 
| assert( pOut!=pIn1 ); | 
| -  sqlite3VdbeMemShallowCopy(pOut, pIn1, MEM_Ephem); | 
| -  Deephemeralize(pOut); | 
| -  REGISTER_TRACE(pOp->p2, pOut); | 
| +  while( 1 ){ | 
| +    sqlite3VdbeMemShallowCopy(pOut, pIn1, MEM_Ephem); | 
| +    Deephemeralize(pOut); | 
| +#ifdef SQLITE_DEBUG | 
| +    pOut->pScopyFrom = 0; | 
| +#endif | 
| +    REGISTER_TRACE(pOp->p2+pOp->p3-n, pOut); | 
| +    if( (n--)==0 ) break; | 
| +    pOut++; | 
| +    pIn1++; | 
| +  } | 
| break; | 
| } | 
|  | 
| /* Opcode: SCopy P1 P2 * * * | 
| +** Synopsis: r[P2]=r[P1] | 
| ** | 
| ** Make a shallow copy of register P1 into register P2. | 
| ** | 
| @@ -1061,7 +1220,7 @@ case OP_Copy: {             /* in1, out2 */ | 
| ** during the lifetime of the copy.  Use OP_Copy to make a complete | 
| ** copy. | 
| */ | 
| -case OP_SCopy: {            /* in1, out2 */ | 
| +case OP_SCopy: {            /* out2 */ | 
| pIn1 = &aMem[pOp->p1]; | 
| pOut = &aMem[pOp->p2]; | 
| assert( pOut!=pIn1 ); | 
| @@ -1069,24 +1228,36 @@ case OP_SCopy: {            /* in1, out2 */ | 
| #ifdef SQLITE_DEBUG | 
| if( pOut->pScopyFrom==0 ) pOut->pScopyFrom = pIn1; | 
| #endif | 
| -  REGISTER_TRACE(pOp->p2, pOut); | 
| break; | 
| } | 
|  | 
| /* Opcode: ResultRow P1 P2 * * * | 
| +** Synopsis:  output=r[P1@P2] | 
| ** | 
| ** The registers P1 through P1+P2-1 contain a single row of | 
| ** results. This opcode causes the sqlite3_step() call to terminate | 
| ** with an SQLITE_ROW return code and it sets up the sqlite3_stmt | 
| -** structure to provide access to the top P1 values as the result | 
| -** row. | 
| +** structure to provide access to the r(P1)..r(P1+P2-1) values as | 
| +** the result row. | 
| */ | 
| case OP_ResultRow: { | 
| Mem *pMem; | 
| int i; | 
| assert( p->nResColumn==pOp->p2 ); | 
| assert( pOp->p1>0 ); | 
| -  assert( pOp->p1+pOp->p2<=p->nMem+1 ); | 
| +  assert( pOp->p1+pOp->p2<=(p->nMem-p->nCursor)+1 ); | 
| + | 
| +#ifndef SQLITE_OMIT_PROGRESS_CALLBACK | 
| +  /* Run the progress counter just before returning. | 
| +  */ | 
| +  if( db->xProgress!=0 | 
| +   && nVmStep>=nProgressLimit | 
| +   && db->xProgress(db->pProgressArg)!=0 | 
| +  ){ | 
| +    rc = SQLITE_INTERRUPT; | 
| +    goto vdbe_error_halt; | 
| +  } | 
| +#endif | 
|  | 
| /* If this statement has violated immediate foreign key constraints, do | 
| ** not return the number of rows modified. And do not RELEASE the statement | 
| @@ -1123,7 +1294,7 @@ case OP_ResultRow: { | 
|  | 
| /* Make sure the results of the current row are \000 terminated | 
| ** and have an assigned type.  The results are de-ephemeralized as | 
| -  ** as side effect. | 
| +  ** a side effect. | 
| */ | 
| pMem = p->pResultSet = &aMem[pOp->p1]; | 
| for(i=0; i<pOp->p2; i++){ | 
| @@ -1132,7 +1303,6 @@ case OP_ResultRow: { | 
| assert( (pMem[i].flags & MEM_Ephem)==0 | 
| || (pMem[i].flags & (MEM_Str|MEM_Blob))==0 ); | 
| sqlite3VdbeMemNulTerminate(&pMem[i]); | 
| -    sqlite3VdbeMemStoreType(&pMem[i]); | 
| REGISTER_TRACE(pOp->p1+i, &pMem[i]); | 
| } | 
| if( db->mallocFailed ) goto no_mem; | 
| @@ -1145,6 +1315,7 @@ case OP_ResultRow: { | 
| } | 
|  | 
| /* Opcode: Concat P1 P2 P3 * * | 
| +** Synopsis: r[P3]=r[P2]+r[P1] | 
| ** | 
| ** Add the text in register P1 onto the end of the text in | 
| ** register P2 and store the result in register P3. | 
| @@ -1174,15 +1345,15 @@ case OP_Concat: {           /* same as TK_CONCAT, in1, in2, out3 */ | 
| if( nByte>db->aLimit[SQLITE_LIMIT_LENGTH] ){ | 
| goto too_big; | 
| } | 
| -  MemSetTypeFlag(pOut, MEM_Str); | 
| if( sqlite3VdbeMemGrow(pOut, (int)nByte+2, pOut==pIn2) ){ | 
| goto no_mem; | 
| } | 
| +  MemSetTypeFlag(pOut, MEM_Str); | 
| if( pOut!=pIn2 ){ | 
| memcpy(pOut->z, pIn2->z, pIn2->n); | 
| } | 
| memcpy(&pOut->z[pIn2->n], pIn1->z, pIn1->n); | 
| -  pOut->z[nByte] = 0; | 
| +  pOut->z[nByte]=0; | 
| pOut->z[nByte+1] = 0; | 
| pOut->flags |= MEM_Term; | 
| pOut->n = (int)nByte; | 
| @@ -1192,12 +1363,14 @@ case OP_Concat: {           /* same as TK_CONCAT, in1, in2, out3 */ | 
| } | 
|  | 
| /* Opcode: Add P1 P2 P3 * * | 
| +** Synopsis:  r[P3]=r[P1]+r[P2] | 
| ** | 
| ** Add the value in register P1 to the value in register P2 | 
| ** and store the result in register P3. | 
| ** If either input is NULL, the result is NULL. | 
| */ | 
| /* Opcode: Multiply P1 P2 P3 * * | 
| +** Synopsis:  r[P3]=r[P1]*r[P2] | 
| ** | 
| ** | 
| ** Multiply the value in register P1 by the value in register P2 | 
| @@ -1205,12 +1378,14 @@ case OP_Concat: {           /* same as TK_CONCAT, in1, in2, out3 */ | 
| ** If either input is NULL, the result is NULL. | 
| */ | 
| /* Opcode: Subtract P1 P2 P3 * * | 
| +** Synopsis:  r[P3]=r[P2]-r[P1] | 
| ** | 
| ** Subtract the value in register P1 from the value in register P2 | 
| ** and store the result in register P3. | 
| ** If either input is NULL, the result is NULL. | 
| */ | 
| /* Opcode: Divide P1 P2 P3 * * | 
| +** Synopsis:  r[P3]=r[P2]/r[P1] | 
| ** | 
| ** Divide the value in register P1 by the value in register P2 | 
| ** and store the result in register P3 (P3=P2/P1). If the value in | 
| @@ -1218,10 +1393,11 @@ case OP_Concat: {           /* same as TK_CONCAT, in1, in2, out3 */ | 
| ** NULL, the result is NULL. | 
| */ | 
| /* Opcode: Remainder P1 P2 P3 * * | 
| +** Synopsis:  r[P3]=r[P2]%r[P1] | 
| ** | 
| -** Compute the remainder after integer division of the value in | 
| -** register P1 by the value in register P2 and store the result in P3. | 
| -** If the value in register P2 is zero the result is NULL. | 
| +** Compute the remainder after integer register P2 is divided by | 
| +** register P1 and store the result in register P3. | 
| +** If the value in register P1 is zero the result is NULL. | 
| ** If either operand is NULL, the result is NULL. | 
| */ | 
| case OP_Add:                   /* same as TK_PLUS, in1, in2, out3 */ | 
| @@ -1229,22 +1405,26 @@ case OP_Subtract:              /* same as TK_MINUS, in1, in2, out3 */ | 
| case OP_Multiply:              /* same as TK_STAR, in1, in2, out3 */ | 
| case OP_Divide:                /* same as TK_SLASH, in1, in2, out3 */ | 
| case OP_Remainder: {           /* same as TK_REM, in1, in2, out3 */ | 
| -  int flags;      /* Combined MEM_* flags from both inputs */ | 
| +  char bIntint;   /* Started out as two integer operands */ | 
| +  u16 flags;      /* Combined MEM_* flags from both inputs */ | 
| +  u16 type1;      /* Numeric type of left operand */ | 
| +  u16 type2;      /* Numeric type of right operand */ | 
| i64 iA;         /* Integer value of left operand */ | 
| i64 iB;         /* Integer value of right operand */ | 
| double rA;      /* Real value of left operand */ | 
| double rB;      /* Real value of right operand */ | 
|  | 
| pIn1 = &aMem[pOp->p1]; | 
| -  applyNumericAffinity(pIn1); | 
| +  type1 = numericType(pIn1); | 
| pIn2 = &aMem[pOp->p2]; | 
| -  applyNumericAffinity(pIn2); | 
| +  type2 = numericType(pIn2); | 
| pOut = &aMem[pOp->p3]; | 
| flags = pIn1->flags | pIn2->flags; | 
| if( (flags & MEM_Null)!=0 ) goto arithmetic_result_is_null; | 
| -  if( (pIn1->flags & pIn2->flags & MEM_Int)==MEM_Int ){ | 
| +  if( (type1 & type2 & MEM_Int)!=0 ){ | 
| iA = pIn1->u.i; | 
| iB = pIn2->u.i; | 
| +    bIntint = 1; | 
| switch( pOp->opcode ){ | 
| case OP_Add:       if( sqlite3AddInt64(&iB,iA) ) goto fp_math;  break; | 
| case OP_Subtract:  if( sqlite3SubInt64(&iB,iA) ) goto fp_math;  break; | 
| @@ -1265,6 +1445,7 @@ case OP_Remainder: {           /* same as TK_REM, in1, in2, out3 */ | 
| pOut->u.i = iB; | 
| MemSetTypeFlag(pOut, MEM_Int); | 
| }else{ | 
| +    bIntint = 0; | 
| fp_math: | 
| rA = sqlite3VdbeRealValue(pIn1); | 
| rB = sqlite3VdbeRealValue(pIn2); | 
| @@ -1294,9 +1475,9 @@ fp_math: | 
| if( sqlite3IsNaN(rB) ){ | 
| goto arithmetic_result_is_null; | 
| } | 
| -    pOut->r = rB; | 
| +    pOut->u.r = rB; | 
| MemSetTypeFlag(pOut, MEM_Real); | 
| -    if( (flags & MEM_Real)==0 ){ | 
| +    if( ((type1|type2)&MEM_Real)==0 && !bIntint ){ | 
| sqlite3VdbeIntegerAffinity(pOut); | 
| } | 
| #endif | 
| @@ -1308,23 +1489,31 @@ arithmetic_result_is_null: | 
| break; | 
| } | 
|  | 
| -/* Opcode: CollSeq * * P4 | 
| +/* Opcode: CollSeq P1 * * P4 | 
| ** | 
| ** P4 is a pointer to a CollSeq struct. If the next call to a user function | 
| ** or aggregate calls sqlite3GetFuncCollSeq(), this collation sequence will | 
| ** be returned. This is used by the built-in min(), max() and nullif() | 
| ** functions. | 
| ** | 
| +** If P1 is not zero, then it is a register that a subsequent min() or | 
| +** max() aggregate will set to 1 if the current row is not the minimum or | 
| +** maximum.  The P1 register is initialized to 0 by this instruction. | 
| +** | 
| ** The interface used by the implementation of the aforementioned functions | 
| ** to retrieve the collation sequence set by this opcode is not available | 
| ** publicly, only to user functions defined in func.c. | 
| */ | 
| case OP_CollSeq: { | 
| assert( pOp->p4type==P4_COLLSEQ ); | 
| +  if( pOp->p1 ){ | 
| +    sqlite3VdbeMemSetInt64(&aMem[pOp->p1], 0); | 
| +  } | 
| break; | 
| } | 
|  | 
| /* Opcode: Function P1 P2 P3 P4 P5 | 
| +** Synopsis: r[P3]=func(r[P2@P5]) | 
| ** | 
| ** Invoke a user function (P4 is a pointer to a Function structure that | 
| ** defines the function) with P5 arguments taken from register P2 and | 
| @@ -1350,108 +1539,66 @@ case OP_Function: { | 
| n = pOp->p5; | 
| apVal = p->apArg; | 
| assert( apVal || n==0 ); | 
| -  assert( pOp->p3>0 && pOp->p3<=p->nMem ); | 
| -  pOut = &aMem[pOp->p3]; | 
| -  memAboutToChange(p, pOut); | 
| +  assert( pOp->p3>0 && pOp->p3<=(p->nMem-p->nCursor) ); | 
| +  ctx.pOut = &aMem[pOp->p3]; | 
| +  memAboutToChange(p, ctx.pOut); | 
|  | 
| -  assert( n==0 || (pOp->p2>0 && pOp->p2+n<=p->nMem+1) ); | 
| +  assert( n==0 || (pOp->p2>0 && pOp->p2+n<=(p->nMem-p->nCursor)+1) ); | 
| assert( pOp->p3<pOp->p2 || pOp->p3>=pOp->p2+n ); | 
| pArg = &aMem[pOp->p2]; | 
| for(i=0; i<n; i++, pArg++){ | 
| assert( memIsValid(pArg) ); | 
| apVal[i] = pArg; | 
| Deephemeralize(pArg); | 
| -    sqlite3VdbeMemStoreType(pArg); | 
| REGISTER_TRACE(pOp->p2+i, pArg); | 
| } | 
|  | 
| -  assert( pOp->p4type==P4_FUNCDEF || pOp->p4type==P4_VDBEFUNC ); | 
| -  if( pOp->p4type==P4_FUNCDEF ){ | 
| -    ctx.pFunc = pOp->p4.pFunc; | 
| -    ctx.pVdbeFunc = 0; | 
| -  }else{ | 
| -    ctx.pVdbeFunc = (VdbeFunc*)pOp->p4.pVdbeFunc; | 
| -    ctx.pFunc = ctx.pVdbeFunc->pFunc; | 
| -  } | 
| - | 
| -  ctx.s.flags = MEM_Null; | 
| -  ctx.s.db = db; | 
| -  ctx.s.xDel = 0; | 
| -  ctx.s.zMalloc = 0; | 
| - | 
| -  /* The output cell may already have a buffer allocated. Move | 
| -  ** the pointer to ctx.s so in case the user-function can use | 
| -  ** the already allocated buffer instead of allocating a new one. | 
| -  */ | 
| -  sqlite3VdbeMemMove(&ctx.s, pOut); | 
| -  MemSetTypeFlag(&ctx.s, MEM_Null); | 
| - | 
| -  ctx.isError = 0; | 
| -  if( ctx.pFunc->flags & SQLITE_FUNC_NEEDCOLL ){ | 
| -    assert( pOp>aOp ); | 
| -    assert( pOp[-1].p4type==P4_COLLSEQ ); | 
| -    assert( pOp[-1].opcode==OP_CollSeq ); | 
| -    ctx.pColl = pOp[-1].p4.pColl; | 
| -  } | 
| +  assert( pOp->p4type==P4_FUNCDEF ); | 
| +  ctx.pFunc = pOp->p4.pFunc; | 
| +  ctx.iOp = pc; | 
| +  ctx.pVdbe = p; | 
| +  MemSetTypeFlag(ctx.pOut, MEM_Null); | 
| +  ctx.fErrorOrAux = 0; | 
| +  db->lastRowid = lastRowid; | 
| (*ctx.pFunc->xFunc)(&ctx, n, apVal); /* IMP: R-24505-23230 */ | 
| -  if( db->mallocFailed ){ | 
| -    /* Even though a malloc() has failed, the implementation of the | 
| -    ** user function may have called an sqlite3_result_XXX() function | 
| -    ** to return a value. The following call releases any resources | 
| -    ** associated with such a value. | 
| -    */ | 
| -    sqlite3VdbeMemRelease(&ctx.s); | 
| -    goto no_mem; | 
| -  } | 
| - | 
| -  /* If any auxiliary data functions have been called by this user function, | 
| -  ** immediately call the destructor for any non-static values. | 
| -  */ | 
| -  if( ctx.pVdbeFunc ){ | 
| -    sqlite3VdbeDeleteAuxData(ctx.pVdbeFunc, pOp->p1); | 
| -    pOp->p4.pVdbeFunc = ctx.pVdbeFunc; | 
| -    pOp->p4type = P4_VDBEFUNC; | 
| -  } | 
| +  lastRowid = db->lastRowid;  /* Remember rowid changes made by xFunc */ | 
|  | 
| /* If the function returned an error, throw an exception */ | 
| -  if( ctx.isError ){ | 
| -    sqlite3SetString(&p->zErrMsg, db, "%s", sqlite3_value_text(&ctx.s)); | 
| -    rc = ctx.isError; | 
| +  if( ctx.fErrorOrAux ){ | 
| +    if( ctx.isError ){ | 
| +      sqlite3SetString(&p->zErrMsg, db, "%s", sqlite3_value_text(ctx.pOut)); | 
| +      rc = ctx.isError; | 
| +    } | 
| +    sqlite3VdbeDeleteAuxData(p, pc, pOp->p1); | 
| } | 
|  | 
| /* Copy the result of the function into register P3 */ | 
| -  sqlite3VdbeChangeEncoding(&ctx.s, encoding); | 
| -  sqlite3VdbeMemMove(pOut, &ctx.s); | 
| -  if( sqlite3VdbeMemTooBig(pOut) ){ | 
| +  sqlite3VdbeChangeEncoding(ctx.pOut, encoding); | 
| +  if( sqlite3VdbeMemTooBig(ctx.pOut) ){ | 
| goto too_big; | 
| } | 
|  | 
| -#if 0 | 
| -  /* The app-defined function has done something that as caused this | 
| -  ** statement to expire.  (Perhaps the function called sqlite3_exec() | 
| -  ** with a CREATE TABLE statement.) | 
| -  */ | 
| -  if( p->expired ) rc = SQLITE_ABORT; | 
| -#endif | 
| - | 
| -  REGISTER_TRACE(pOp->p3, pOut); | 
| -  UPDATE_MAX_BLOBSIZE(pOut); | 
| +  REGISTER_TRACE(pOp->p3, ctx.pOut); | 
| +  UPDATE_MAX_BLOBSIZE(ctx.pOut); | 
| break; | 
| } | 
|  | 
| /* Opcode: BitAnd P1 P2 P3 * * | 
| +** Synopsis:  r[P3]=r[P1]&r[P2] | 
| ** | 
| ** Take the bit-wise AND of the values in register P1 and P2 and | 
| ** store the result in register P3. | 
| ** If either input is NULL, the result is NULL. | 
| */ | 
| /* Opcode: BitOr P1 P2 P3 * * | 
| +** Synopsis:  r[P3]=r[P1]|r[P2] | 
| ** | 
| ** Take the bit-wise OR of the values in register P1 and P2 and | 
| ** store the result in register P3. | 
| ** If either input is NULL, the result is NULL. | 
| */ | 
| /* Opcode: ShiftLeft P1 P2 P3 * * | 
| +** Synopsis:  r[P3]=r[P2]<<r[P1] | 
| ** | 
| ** Shift the integer value in register P2 to the left by the | 
| ** number of bits specified by the integer in register P1. | 
| @@ -1459,6 +1606,7 @@ case OP_Function: { | 
| ** If either input is NULL, the result is NULL. | 
| */ | 
| /* Opcode: ShiftRight P1 P2 P3 * * | 
| +** Synopsis:  r[P3]=r[P2]>>r[P1] | 
| ** | 
| ** Shift the integer value in register P2 to the right by the | 
| ** number of bits specified by the integer in register P1. | 
| @@ -1518,6 +1666,7 @@ case OP_ShiftRight: {           /* same as TK_RSHIFT, in1, in2, out3 */ | 
| } | 
|  | 
| /* Opcode: AddImm  P1 P2 * * * | 
| +** Synopsis:  r[P1]=r[P1]+P2 | 
| ** | 
| ** Add the constant P2 to the value in register P1. | 
| ** The result is always an integer. | 
| @@ -1541,17 +1690,20 @@ case OP_AddImm: {            /* in1 */ | 
| */ | 
| case OP_MustBeInt: {            /* jump, in1 */ | 
| pIn1 = &aMem[pOp->p1]; | 
| -  applyAffinity(pIn1, SQLITE_AFF_NUMERIC, encoding); | 
| if( (pIn1->flags & MEM_Int)==0 ){ | 
| -    if( pOp->p2==0 ){ | 
| -      rc = SQLITE_MISMATCH; | 
| -      goto abort_due_to_error; | 
| -    }else{ | 
| -      pc = pOp->p2 - 1; | 
| +    applyAffinity(pIn1, SQLITE_AFF_NUMERIC, encoding); | 
| +    VdbeBranchTaken((pIn1->flags&MEM_Int)==0, 2); | 
| +    if( (pIn1->flags & MEM_Int)==0 ){ | 
| +      if( pOp->p2==0 ){ | 
| +        rc = SQLITE_MISMATCH; | 
| +        goto abort_due_to_error; | 
| +      }else{ | 
| +        pc = pOp->p2 - 1; | 
| +        break; | 
| +      } | 
| } | 
| -  }else{ | 
| -    MemSetTypeFlag(pIn1, MEM_Int); | 
| } | 
| +  MemSetTypeFlag(pIn1, MEM_Int); | 
| break; | 
| } | 
|  | 
| @@ -1575,107 +1727,39 @@ case OP_RealAffinity: {                  /* in1 */ | 
| #endif | 
|  | 
| #ifndef SQLITE_OMIT_CAST | 
| -/* Opcode: ToText P1 * * * * | 
| +/* Opcode: Cast P1 P2 * * * | 
| +** Synopsis: affinity(r[P1]) | 
| ** | 
| -** Force the value in register P1 to be text. | 
| -** If the value is numeric, convert it to a string using the | 
| -** equivalent of printf().  Blob values are unchanged and | 
| -** are afterwards simply interpreted as text. | 
| +** Force the value in register P1 to be the type defined by P2. | 
| +** | 
| +** <ul> | 
| +** <li value="97"> TEXT | 
| +** <li value="98"> BLOB | 
| +** <li value="99"> NUMERIC | 
| +** <li value="100"> INTEGER | 
| +** <li value="101"> REAL | 
| +** </ul> | 
| ** | 
| ** A NULL value is not changed by this routine.  It remains NULL. | 
| */ | 
| -case OP_ToText: {                  /* same as TK_TO_TEXT, in1 */ | 
| +case OP_Cast: {                  /* in1 */ | 
| +  assert( pOp->p2>=SQLITE_AFF_NONE && pOp->p2<=SQLITE_AFF_REAL ); | 
| +  testcase( pOp->p2==SQLITE_AFF_TEXT ); | 
| +  testcase( pOp->p2==SQLITE_AFF_NONE ); | 
| +  testcase( pOp->p2==SQLITE_AFF_NUMERIC ); | 
| +  testcase( pOp->p2==SQLITE_AFF_INTEGER ); | 
| +  testcase( pOp->p2==SQLITE_AFF_REAL ); | 
| pIn1 = &aMem[pOp->p1]; | 
| memAboutToChange(p, pIn1); | 
| -  if( pIn1->flags & MEM_Null ) break; | 
| -  assert( MEM_Str==(MEM_Blob>>3) ); | 
| -  pIn1->flags |= (pIn1->flags&MEM_Blob)>>3; | 
| -  applyAffinity(pIn1, SQLITE_AFF_TEXT, encoding); | 
| rc = ExpandBlob(pIn1); | 
| -  assert( pIn1->flags & MEM_Str || db->mallocFailed ); | 
| -  pIn1->flags &= ~(MEM_Int|MEM_Real|MEM_Blob|MEM_Zero); | 
| -  UPDATE_MAX_BLOBSIZE(pIn1); | 
| -  break; | 
| -} | 
| - | 
| -/* Opcode: ToBlob P1 * * * * | 
| -** | 
| -** Force the value in register P1 to be a BLOB. | 
| -** If the value is numeric, convert it to a string first. | 
| -** Strings are simply reinterpreted as blobs with no change | 
| -** to the underlying data. | 
| -** | 
| -** A NULL value is not changed by this routine.  It remains NULL. | 
| -*/ | 
| -case OP_ToBlob: {                  /* same as TK_TO_BLOB, in1 */ | 
| -  pIn1 = &aMem[pOp->p1]; | 
| -  if( pIn1->flags & MEM_Null ) break; | 
| -  if( (pIn1->flags & MEM_Blob)==0 ){ | 
| -    applyAffinity(pIn1, SQLITE_AFF_TEXT, encoding); | 
| -    assert( pIn1->flags & MEM_Str || db->mallocFailed ); | 
| -    MemSetTypeFlag(pIn1, MEM_Blob); | 
| -  }else{ | 
| -    pIn1->flags &= ~(MEM_TypeMask&~MEM_Blob); | 
| -  } | 
| +  sqlite3VdbeMemCast(pIn1, pOp->p2, encoding); | 
| UPDATE_MAX_BLOBSIZE(pIn1); | 
| break; | 
| } | 
| - | 
| -/* Opcode: ToNumeric P1 * * * * | 
| -** | 
| -** Force the value in register P1 to be numeric (either an | 
| -** integer or a floating-point number.) | 
| -** If the value is text or blob, try to convert it to an using the | 
| -** equivalent of atoi() or atof() and store 0 if no such conversion | 
| -** is possible. | 
| -** | 
| -** A NULL value is not changed by this routine.  It remains NULL. | 
| -*/ | 
| -case OP_ToNumeric: {                  /* same as TK_TO_NUMERIC, in1 */ | 
| -  pIn1 = &aMem[pOp->p1]; | 
| -  sqlite3VdbeMemNumerify(pIn1); | 
| -  break; | 
| -} | 
| #endif /* SQLITE_OMIT_CAST */ | 
|  | 
| -/* Opcode: ToInt P1 * * * * | 
| -** | 
| -** Force the value in register P1 to be an integer.  If | 
| -** The value is currently a real number, drop its fractional part. | 
| -** If the value is text or blob, try to convert it to an integer using the | 
| -** equivalent of atoi() and store 0 if no such conversion is possible. | 
| -** | 
| -** A NULL value is not changed by this routine.  It remains NULL. | 
| -*/ | 
| -case OP_ToInt: {                  /* same as TK_TO_INT, in1 */ | 
| -  pIn1 = &aMem[pOp->p1]; | 
| -  if( (pIn1->flags & MEM_Null)==0 ){ | 
| -    sqlite3VdbeMemIntegerify(pIn1); | 
| -  } | 
| -  break; | 
| -} | 
| - | 
| -#if !defined(SQLITE_OMIT_CAST) && !defined(SQLITE_OMIT_FLOATING_POINT) | 
| -/* Opcode: ToReal P1 * * * * | 
| -** | 
| -** Force the value in register P1 to be a floating point number. | 
| -** If The value is currently an integer, convert it. | 
| -** If the value is text or blob, try to convert it to an integer using the | 
| -** equivalent of atoi() and store 0.0 if no such conversion is possible. | 
| -** | 
| -** A NULL value is not changed by this routine.  It remains NULL. | 
| -*/ | 
| -case OP_ToReal: {                  /* same as TK_TO_REAL, in1 */ | 
| -  pIn1 = &aMem[pOp->p1]; | 
| -  memAboutToChange(p, pIn1); | 
| -  if( (pIn1->flags & MEM_Null)==0 ){ | 
| -    sqlite3VdbeMemRealify(pIn1); | 
| -  } | 
| -  break; | 
| -} | 
| -#endif /* !defined(SQLITE_OMIT_CAST) && !defined(SQLITE_OMIT_FLOATING_POINT) */ | 
| - | 
| /* Opcode: Lt P1 P2 P3 P4 P5 | 
| +** Synopsis: if r[P1]<r[P3] goto P2 | 
| ** | 
| ** Compare the values in register P1 and P3.  If reg(P3)<reg(P1) then | 
| ** jump to address P2. | 
| @@ -1704,8 +1788,13 @@ case OP_ToReal: {                  /* same as TK_TO_REAL, in1 */ | 
| ** | 
| ** If the SQLITE_STOREP2 bit of P5 is set, then do not jump.  Instead, | 
| ** store a boolean result (either 0, or 1, or NULL) in register P2. | 
| +** | 
| +** If the SQLITE_NULLEQ bit is set in P5, then NULL values are considered | 
| +** equal to one another, provided that they do not have their MEM_Cleared | 
| +** bit set. | 
| */ | 
| /* Opcode: Ne P1 P2 P3 P4 P5 | 
| +** Synopsis: if r[P1]!=r[P3] goto P2 | 
| ** | 
| ** This works just like the Lt opcode except that the jump is taken if | 
| ** the operands in registers P1 and P3 are not equal.  See the Lt opcode for | 
| @@ -1714,10 +1803,11 @@ case OP_ToReal: {                  /* same as TK_TO_REAL, in1 */ | 
| ** If SQLITE_NULLEQ is set in P5 then the result of comparison is always either | 
| ** true or false and is never NULL.  If both operands are NULL then the result | 
| ** of comparison is false.  If either operand is NULL then the result is true. | 
| -** If neither operand is NULL the the result is the same as it would be if | 
| +** If neither operand is NULL the result is the same as it would be if | 
| ** the SQLITE_NULLEQ flag were omitted from P5. | 
| */ | 
| /* Opcode: Eq P1 P2 P3 P4 P5 | 
| +** Synopsis: if r[P1]==r[P3] goto P2 | 
| ** | 
| ** This works just like the Lt opcode except that the jump is taken if | 
| ** the operands in registers P1 and P3 are equal. | 
| @@ -1726,22 +1816,25 @@ case OP_ToReal: {                  /* same as TK_TO_REAL, in1 */ | 
| ** If SQLITE_NULLEQ is set in P5 then the result of comparison is always either | 
| ** true or false and is never NULL.  If both operands are NULL then the result | 
| ** of comparison is true.  If either operand is NULL then the result is false. | 
| -** If neither operand is NULL the the result is the same as it would be if | 
| +** If neither operand is NULL the result is the same as it would be if | 
| ** the SQLITE_NULLEQ flag were omitted from P5. | 
| */ | 
| /* Opcode: Le P1 P2 P3 P4 P5 | 
| +** Synopsis: if r[P1]<=r[P3] goto P2 | 
| ** | 
| ** This works just like the Lt opcode except that the jump is taken if | 
| ** the content of register P3 is less than or equal to the content of | 
| ** register P1.  See the Lt opcode for additional information. | 
| */ | 
| /* Opcode: Gt P1 P2 P3 P4 P5 | 
| +** Synopsis: if r[P1]>r[P3] goto P2 | 
| ** | 
| ** This works just like the Lt opcode except that the jump is taken if | 
| ** the content of register P3 is greater than the content of | 
| ** register P1.  See the Lt opcode for additional information. | 
| */ | 
| /* Opcode: Ge P1 P2 P3 P4 P5 | 
| +** Synopsis: if r[P1]>=r[P3] goto P2 | 
| ** | 
| ** This works just like the Lt opcode except that the jump is taken if | 
| ** the content of register P3 is greater than or equal to the content of | 
| @@ -1762,7 +1855,7 @@ case OP_Ge: {             /* same as TK_GE, jump, in1, in3 */ | 
| pIn3 = &aMem[pOp->p3]; | 
| flags1 = pIn1->flags; | 
| flags3 = pIn3->flags; | 
| -  if( (pIn1->flags | pIn3->flags)&MEM_Null ){ | 
| +  if( (flags1 | flags3)&MEM_Null ){ | 
| /* One or both operands are NULL */ | 
| if( pOp->p5 & SQLITE_NULLEQ ){ | 
| /* If SQLITE_NULLEQ is set (which will only happen if the operator is | 
| @@ -1770,7 +1863,16 @@ case OP_Ge: {             /* same as TK_GE, jump, in1, in3 */ | 
| ** or not both operands are null. | 
| */ | 
| assert( pOp->opcode==OP_Eq || pOp->opcode==OP_Ne ); | 
| -      res = (pIn1->flags & pIn3->flags & MEM_Null)==0; | 
| +      assert( (flags1 & MEM_Cleared)==0 ); | 
| +      assert( (pOp->p5 & SQLITE_JUMPIFNULL)==0 ); | 
| +      if( (flags1&MEM_Null)!=0 | 
| +       && (flags3&MEM_Null)!=0 | 
| +       && (flags3&MEM_Cleared)==0 | 
| +      ){ | 
| +        res = 0;  /* Results are equal */ | 
| +      }else{ | 
| +        res = 1;  /* Results are not equal */ | 
| +      } | 
| }else{ | 
| /* SQLITE_NULLEQ is clear and at least one operand is NULL, | 
| ** then the result is always NULL. | 
| @@ -1780,23 +1882,46 @@ case OP_Ge: {             /* same as TK_GE, jump, in1, in3 */ | 
| pOut = &aMem[pOp->p2]; | 
| MemSetTypeFlag(pOut, MEM_Null); | 
| REGISTER_TRACE(pOp->p2, pOut); | 
| -      }else if( pOp->p5 & SQLITE_JUMPIFNULL ){ | 
| -        pc = pOp->p2-1; | 
| +      }else{ | 
| +        VdbeBranchTaken(2,3); | 
| +        if( pOp->p5 & SQLITE_JUMPIFNULL ){ | 
| +          pc = pOp->p2-1; | 
| +        } | 
| } | 
| break; | 
| } | 
| }else{ | 
| /* Neither operand is NULL.  Do a comparison. */ | 
| affinity = pOp->p5 & SQLITE_AFF_MASK; | 
| -    if( affinity ){ | 
| -      applyAffinity(pIn1, affinity, encoding); | 
| -      applyAffinity(pIn3, affinity, encoding); | 
| -      if( db->mallocFailed ) goto no_mem; | 
| +    if( affinity>=SQLITE_AFF_NUMERIC ){ | 
| +      if( (pIn1->flags & (MEM_Int|MEM_Real|MEM_Str))==MEM_Str ){ | 
| +        applyNumericAffinity(pIn1,0); | 
| +      } | 
| +      if( (pIn3->flags & (MEM_Int|MEM_Real|MEM_Str))==MEM_Str ){ | 
| +        applyNumericAffinity(pIn3,0); | 
| +      } | 
| +    }else if( affinity==SQLITE_AFF_TEXT ){ | 
| +      if( (pIn1->flags & MEM_Str)==0 && (pIn1->flags & (MEM_Int|MEM_Real))!=0 ){ | 
| +        testcase( pIn1->flags & MEM_Int ); | 
| +        testcase( pIn1->flags & MEM_Real ); | 
| +        sqlite3VdbeMemStringify(pIn1, encoding, 1); | 
| +      } | 
| +      if( (pIn3->flags & MEM_Str)==0 && (pIn3->flags & (MEM_Int|MEM_Real))!=0 ){ | 
| +        testcase( pIn3->flags & MEM_Int ); | 
| +        testcase( pIn3->flags & MEM_Real ); | 
| +        sqlite3VdbeMemStringify(pIn3, encoding, 1); | 
| +      } | 
| } | 
| - | 
| assert( pOp->p4type==P4_COLLSEQ || pOp->p4.pColl==0 ); | 
| -    ExpandBlob(pIn1); | 
| -    ExpandBlob(pIn3); | 
| +    if( pIn1->flags & MEM_Zero ){ | 
| +      sqlite3VdbeMemExpandBlob(pIn1); | 
| +      flags1 &= ~MEM_Zero; | 
| +    } | 
| +    if( pIn3->flags & MEM_Zero ){ | 
| +      sqlite3VdbeMemExpandBlob(pIn3); | 
| +      flags3 &= ~MEM_Zero; | 
| +    } | 
| +    if( db->mallocFailed ) goto no_mem; | 
| res = sqlite3MemCompare(pIn3, pIn1, pOp->p4.pColl); | 
| } | 
| switch( pOp->opcode ){ | 
| @@ -1814,13 +1939,15 @@ case OP_Ge: {             /* same as TK_GE, jump, in1, in3 */ | 
| MemSetTypeFlag(pOut, MEM_Int); | 
| pOut->u.i = res; | 
| REGISTER_TRACE(pOp->p2, pOut); | 
| -  }else if( res ){ | 
| -    pc = pOp->p2-1; | 
| +  }else{ | 
| +    VdbeBranchTaken(res!=0, (pOp->p5 & SQLITE_NULLEQ)?2:3); | 
| +    if( res ){ | 
| +      pc = pOp->p2-1; | 
| +    } | 
| } | 
| - | 
| /* Undo any changes made by applyAffinity() to the input registers. */ | 
| -  pIn1->flags = (pIn1->flags&~MEM_TypeMask) | (flags1&MEM_TypeMask); | 
| -  pIn3->flags = (pIn3->flags&~MEM_TypeMask) | (flags3&MEM_TypeMask); | 
| +  pIn1->flags = flags1; | 
| +  pIn3->flags = flags3; | 
| break; | 
| } | 
|  | 
| @@ -1829,9 +1956,9 @@ case OP_Ge: {             /* same as TK_GE, jump, in1, in3 */ | 
| ** Set the permutation used by the OP_Compare operator to be the array | 
| ** of integers in P4. | 
| ** | 
| -** The permutation is only valid until the next OP_Permutation, OP_Compare, | 
| -** OP_Halt, or OP_ResultRow.  Typically the OP_Permutation should occur | 
| -** immediately prior to the OP_Compare. | 
| +** The permutation is only valid until the next OP_Compare that has | 
| +** the OPFLAG_PERMUTE bit set in P5. Typically the OP_Permutation should | 
| +** occur immediately prior to the OP_Compare. | 
| */ | 
| case OP_Permutation: { | 
| assert( pOp->p4type==P4_INTARRAY ); | 
| @@ -1840,12 +1967,18 @@ case OP_Permutation: { | 
| break; | 
| } | 
|  | 
| -/* Opcode: Compare P1 P2 P3 P4 * | 
| +/* Opcode: Compare P1 P2 P3 P4 P5 | 
| +** Synopsis: r[P1@P3] <-> r[P2@P3] | 
| ** | 
| ** Compare two vectors of registers in reg(P1)..reg(P1+P3-1) (call this | 
| ** vector "A") and in reg(P2)..reg(P2+P3-1) ("B").  Save the result of | 
| ** the comparison for use by the next OP_Jump instruct. | 
| ** | 
| +** If P5 has the OPFLAG_PERMUTE bit set, then the order of comparison is | 
| +** determined by the most recent OP_Permutation operator.  If the | 
| +** OPFLAG_PERMUTE bit is clear, then register are compared in sequential | 
| +** order. | 
| +** | 
| ** P4 is a KeyInfo structure that defines collating sequences and sort | 
| ** orders for the comparison.  The permutation applies to registers | 
| ** only.  The KeyInfo elements are used sequentially. | 
| @@ -1864,6 +1997,7 @@ case OP_Compare: { | 
| CollSeq *pColl;    /* Collating sequence to use on this term */ | 
| int bRev;          /* True for DESCENDING sort order */ | 
|  | 
| +  if( (pOp->p5 & OPFLAG_PERMUTE)==0 ) aPermute = 0; | 
| n = pOp->p3; | 
| pKeyInfo = pOp->p4.pKeyInfo; | 
| assert( n>0 ); | 
| @@ -1874,11 +2008,11 @@ case OP_Compare: { | 
| if( aPermute ){ | 
| int k, mx = 0; | 
| for(k=0; k<n; k++) if( aPermute[k]>mx ) mx = aPermute[k]; | 
| -    assert( p1>0 && p1+mx<=p->nMem+1 ); | 
| -    assert( p2>0 && p2+mx<=p->nMem+1 ); | 
| +    assert( p1>0 && p1+mx<=(p->nMem-p->nCursor)+1 ); | 
| +    assert( p2>0 && p2+mx<=(p->nMem-p->nCursor)+1 ); | 
| }else{ | 
| -    assert( p1>0 && p1+n<=p->nMem+1 ); | 
| -    assert( p2>0 && p2+n<=p->nMem+1 ); | 
| +    assert( p1>0 && p1+n<=(p->nMem-p->nCursor)+1 ); | 
| +    assert( p2>0 && p2+n<=(p->nMem-p->nCursor)+1 ); | 
| } | 
| #endif /* SQLITE_DEBUG */ | 
| for(i=0; i<n; i++){ | 
| @@ -1908,16 +2042,17 @@ case OP_Compare: { | 
| */ | 
| case OP_Jump: {             /* jump */ | 
| if( iCompare<0 ){ | 
| -    pc = pOp->p1 - 1; | 
| +    pc = pOp->p1 - 1;  VdbeBranchTaken(0,3); | 
| }else if( iCompare==0 ){ | 
| -    pc = pOp->p2 - 1; | 
| +    pc = pOp->p2 - 1;  VdbeBranchTaken(1,3); | 
| }else{ | 
| -    pc = pOp->p3 - 1; | 
| +    pc = pOp->p3 - 1;  VdbeBranchTaken(2,3); | 
| } | 
| break; | 
| } | 
|  | 
| /* Opcode: And P1 P2 P3 * * | 
| +** Synopsis: r[P3]=(r[P1] && r[P2]) | 
| ** | 
| ** Take the logical AND of the values in registers P1 and P2 and | 
| ** write the result into register P3. | 
| @@ -1927,6 +2062,7 @@ case OP_Jump: {             /* jump */ | 
| ** a NULL output. | 
| */ | 
| /* Opcode: Or P1 P2 P3 * * | 
| +** Synopsis: r[P3]=(r[P1] || r[P2]) | 
| ** | 
| ** Take the logical OR of the values in register P1 and P2 and | 
| ** store the answer in register P3. | 
| @@ -1970,6 +2106,7 @@ case OP_Or: {             /* same as TK_OR, in1, in2, out3 */ | 
| } | 
|  | 
| /* Opcode: Not P1 P2 * * * | 
| +** Synopsis: r[P2]= !r[P1] | 
| ** | 
| ** Interpret the value in register P1 as a boolean value.  Store the | 
| ** boolean complement in register P2.  If the value in register P1 is | 
| @@ -1978,15 +2115,16 @@ case OP_Or: {             /* same as TK_OR, in1, in2, out3 */ | 
| case OP_Not: {                /* same as TK_NOT, in1, out2 */ | 
| pIn1 = &aMem[pOp->p1]; | 
| pOut = &aMem[pOp->p2]; | 
| -  if( pIn1->flags & MEM_Null ){ | 
| -    sqlite3VdbeMemSetNull(pOut); | 
| -  }else{ | 
| -    sqlite3VdbeMemSetInt64(pOut, !sqlite3VdbeIntValue(pIn1)); | 
| +  sqlite3VdbeMemSetNull(pOut); | 
| +  if( (pIn1->flags & MEM_Null)==0 ){ | 
| +    pOut->flags = MEM_Int; | 
| +    pOut->u.i = !sqlite3VdbeIntValue(pIn1); | 
| } | 
| break; | 
| } | 
|  | 
| /* Opcode: BitNot P1 P2 * * * | 
| +** Synopsis: r[P1]= ~r[P1] | 
| ** | 
| ** Interpret the content of register P1 as an integer.  Store the | 
| ** ones-complement of the P1 value into register P2.  If P1 holds | 
| @@ -1995,25 +2133,47 @@ case OP_Not: {                /* same as TK_NOT, in1, out2 */ | 
| case OP_BitNot: {             /* same as TK_BITNOT, in1, out2 */ | 
| pIn1 = &aMem[pOp->p1]; | 
| pOut = &aMem[pOp->p2]; | 
| -  if( pIn1->flags & MEM_Null ){ | 
| -    sqlite3VdbeMemSetNull(pOut); | 
| +  sqlite3VdbeMemSetNull(pOut); | 
| +  if( (pIn1->flags & MEM_Null)==0 ){ | 
| +    pOut->flags = MEM_Int; | 
| +    pOut->u.i = ~sqlite3VdbeIntValue(pIn1); | 
| +  } | 
| +  break; | 
| +} | 
| + | 
| +/* Opcode: Once P1 P2 * * * | 
| +** | 
| +** Check the "once" flag number P1. If it is set, jump to instruction P2. | 
| +** Otherwise, set the flag and fall through to the next instruction. | 
| +** In other words, this opcode causes all following opcodes up through P2 | 
| +** (but not including P2) to run just once and to be skipped on subsequent | 
| +** times through the loop. | 
| +** | 
| +** All "once" flags are initially cleared whenever a prepared statement | 
| +** first begins to run. | 
| +*/ | 
| +case OP_Once: {             /* jump */ | 
| +  assert( pOp->p1<p->nOnceFlag ); | 
| +  VdbeBranchTaken(p->aOnceFlag[pOp->p1]!=0, 2); | 
| +  if( p->aOnceFlag[pOp->p1] ){ | 
| +    pc = pOp->p2-1; | 
| }else{ | 
| -    sqlite3VdbeMemSetInt64(pOut, ~sqlite3VdbeIntValue(pIn1)); | 
| +    p->aOnceFlag[pOp->p1] = 1; | 
| } | 
| break; | 
| } | 
|  | 
| /* Opcode: If P1 P2 P3 * * | 
| ** | 
| -** Jump to P2 if the value in register P1 is true.  The value is | 
| +** Jump to P2 if the value in register P1 is true.  The value | 
| ** is considered true if it is numeric and non-zero.  If the value | 
| -** in P1 is NULL then take the jump if P3 is true. | 
| +** in P1 is NULL then take the jump if and only if P3 is non-zero. | 
| */ | 
| /* Opcode: IfNot P1 P2 P3 * * | 
| ** | 
| -** Jump to P2 if the value in register P1 is False.  The value is | 
| -** is considered true if it has a numeric value of zero.  If the value | 
| -** in P1 is NULL then take the jump if P3 is true. | 
| +** Jump to P2 if the value in register P1 is False.  The value | 
| +** is considered false if it has a numeric value of zero.  If the value | 
| +** in P1 is NULL then take the jump if and only if P3 is non-zero. | 
| */ | 
| case OP_If:                 /* jump, in1 */ | 
| case OP_IfNot: {            /* jump, in1 */ | 
| @@ -2029,6 +2189,7 @@ case OP_IfNot: {            /* jump, in1 */ | 
| #endif | 
| if( pOp->opcode==OP_IfNot ) c = !c; | 
| } | 
| +  VdbeBranchTaken(c!=0, 2); | 
| if( c ){ | 
| pc = pOp->p2-1; | 
| } | 
| @@ -2036,11 +2197,13 @@ case OP_IfNot: {            /* jump, in1 */ | 
| } | 
|  | 
| /* Opcode: IsNull P1 P2 * * * | 
| +** Synopsis:  if r[P1]==NULL goto P2 | 
| ** | 
| ** Jump to P2 if the value in register P1 is NULL. | 
| */ | 
| case OP_IsNull: {            /* same as TK_ISNULL, jump, in1 */ | 
| pIn1 = &aMem[pOp->p1]; | 
| +  VdbeBranchTaken( (pIn1->flags & MEM_Null)!=0, 2); | 
| if( (pIn1->flags & MEM_Null)!=0 ){ | 
| pc = pOp->p2 - 1; | 
| } | 
| @@ -2048,11 +2211,13 @@ case OP_IsNull: {            /* same as TK_ISNULL, jump, in1 */ | 
| } | 
|  | 
| /* Opcode: NotNull P1 P2 * * * | 
| +** Synopsis: if r[P1]!=NULL goto P2 | 
| ** | 
| ** Jump to P2 if the value in register P1 is not NULL. | 
| */ | 
| case OP_NotNull: {            /* same as TK_NOTNULL, jump, in1 */ | 
| pIn1 = &aMem[pOp->p1]; | 
| +  VdbeBranchTaken( (pIn1->flags & MEM_Null)==0, 2); | 
| if( (pIn1->flags & MEM_Null)==0 ){ | 
| pc = pOp->p2 - 1; | 
| } | 
| @@ -2060,6 +2225,7 @@ case OP_NotNull: {            /* same as TK_NOTNULL, jump, in1 */ | 
| } | 
|  | 
| /* Opcode: Column P1 P2 P3 P4 P5 | 
| +** Synopsis:  r[P3]=PX | 
| ** | 
| ** Interpret the data that cursor P1 points to as a structure built using | 
| ** the MakeRecord instruction.  (See the MakeRecord opcode for additional | 
| @@ -2077,149 +2243,96 @@ case OP_NotNull: {            /* same as TK_NOTNULL, jump, in1 */ | 
| ** then the cache of the cursor is reset prior to extracting the column. | 
| ** The first OP_Column against a pseudo-table after the value of the content | 
| ** register has changed should have this bit set. | 
| +** | 
| +** If the OPFLAG_LENGTHARG and OPFLAG_TYPEOFARG bits are set on P5 when | 
| +** the result is guaranteed to only be used as the argument of a length() | 
| +** or typeof() function, respectively.  The loading of large blobs can be | 
| +** skipped for length() and all content loading can be skipped for typeof(). | 
| */ | 
| case OP_Column: { | 
| -  u32 payloadSize;   /* Number of bytes in the record */ | 
| i64 payloadSize64; /* Number of bytes in the record */ | 
| -  int p1;            /* P1 value of the opcode */ | 
| int p2;            /* column number to retrieve */ | 
| VdbeCursor *pC;    /* The VDBE cursor */ | 
| -  char *zRec;        /* Pointer to complete record-data */ | 
| BtCursor *pCrsr;   /* The BTree cursor */ | 
| -  u32 *aType;        /* aType[i] holds the numeric type of the i-th column */ | 
| u32 *aOffset;      /* aOffset[i] is offset to start of data for i-th column */ | 
| -  int nField;        /* number of fields in the record */ | 
| int len;           /* The length of the serialized data for the column */ | 
| int i;             /* Loop counter */ | 
| -  char *zData;       /* Part of the record being decoded */ | 
| Mem *pDest;        /* Where to write the extracted value */ | 
| Mem sMem;          /* For storing the record being decoded */ | 
| -  u8 *zIdx;          /* Index into header */ | 
| -  u8 *zEndHdr;       /* Pointer to first byte after the header */ | 
| +  const u8 *zData;   /* Part of the record being decoded */ | 
| +  const u8 *zHdr;    /* Next unparsed byte of the header */ | 
| +  const u8 *zEndHdr; /* Pointer to first byte after the header */ | 
| u32 offset;        /* Offset into the data */ | 
| u32 szField;       /* Number of bytes in the content of a field */ | 
| -  int szHdr;         /* Size of the header size field at start of record */ | 
| -  int avail;         /* Number of bytes of available data */ | 
| +  u32 avail;         /* Number of bytes of available data */ | 
| +  u32 t;             /* A type code from the record header */ | 
| +  u16 fx;            /* pDest->flags value */ | 
| Mem *pReg;         /* PseudoTable input register */ | 
|  | 
| - | 
| -  p1 = pOp->p1; | 
| p2 = pOp->p2; | 
| -  pC = 0; | 
| -  memset(&sMem, 0, sizeof(sMem)); | 
| -  assert( p1<p->nCursor ); | 
| -  assert( pOp->p3>0 && pOp->p3<=p->nMem ); | 
| +  assert( pOp->p3>0 && pOp->p3<=(p->nMem-p->nCursor) ); | 
| pDest = &aMem[pOp->p3]; | 
| memAboutToChange(p, pDest); | 
| -  MemSetTypeFlag(pDest, MEM_Null); | 
| -  zRec = 0; | 
| - | 
| -  /* This block sets the variable payloadSize to be the total number of | 
| -  ** bytes in the record. | 
| -  ** | 
| -  ** zRec is set to be the complete text of the record if it is available. | 
| -  ** The complete record text is always available for pseudo-tables | 
| -  ** If the record is stored in a cursor, the complete record text | 
| -  ** might be available in the  pC->aRow cache.  Or it might not be. | 
| -  ** If the data is unavailable,  zRec is set to NULL. | 
| -  ** | 
| -  ** We also compute the number of columns in the record.  For cursors, | 
| -  ** the number of columns is stored in the VdbeCursor.nField element. | 
| -  */ | 
| -  pC = p->apCsr[p1]; | 
| +  assert( pOp->p1>=0 && pOp->p1<p->nCursor ); | 
| +  pC = p->apCsr[pOp->p1]; | 
| assert( pC!=0 ); | 
| +  assert( p2<pC->nField ); | 
| +  aOffset = pC->aOffset; | 
| #ifndef SQLITE_OMIT_VIRTUALTABLE | 
| -  assert( pC->pVtabCursor==0 ); | 
| +  assert( pC->pVtabCursor==0 ); /* OP_Column never called on virtual table */ | 
| #endif | 
| pCrsr = pC->pCursor; | 
| -  if( pCrsr!=0 ){ | 
| -    /* The record is stored in a B-Tree */ | 
| -    rc = sqlite3VdbeCursorMoveto(pC); | 
| -    if( rc ) goto abort_due_to_error; | 
| -    if( pC->nullRow ){ | 
| -      payloadSize = 0; | 
| -    }else if( pC->cacheStatus==p->cacheCtr ){ | 
| -      payloadSize = pC->payloadSize; | 
| -      zRec = (char*)pC->aRow; | 
| -    }else if( pC->isIndex ){ | 
| -      assert( sqlite3BtreeCursorIsValid(pCrsr) ); | 
| -      rc = sqlite3BtreeKeySize(pCrsr, &payloadSize64); | 
| -      assert( rc==SQLITE_OK );   /* True because of CursorMoveto() call above */ | 
| -      /* sqlite3BtreeParseCellPtr() uses getVarint32() to extract the | 
| -      ** payload size, so it is impossible for payloadSize64 to be | 
| -      ** larger than 32 bits. */ | 
| -      assert( (payloadSize64 & SQLITE_MAX_U32)==(u64)payloadSize64 ); | 
| -      payloadSize = (u32)payloadSize64; | 
| -    }else{ | 
| -      assert( sqlite3BtreeCursorIsValid(pCrsr) ); | 
| -      rc = sqlite3BtreeDataSize(pCrsr, &payloadSize); | 
| -      assert( rc==SQLITE_OK );   /* DataSize() cannot fail */ | 
| -    } | 
| -  }else if( pC->pseudoTableReg>0 ){ | 
| -    pReg = &aMem[pC->pseudoTableReg]; | 
| -    assert( pReg->flags & MEM_Blob ); | 
| -    assert( memIsValid(pReg) ); | 
| -    payloadSize = pReg->n; | 
| -    zRec = pReg->z; | 
| -    pC->cacheStatus = (pOp->p5&OPFLAG_CLEARCACHE) ? CACHE_STALE : p->cacheCtr; | 
| -    assert( payloadSize==0 || zRec!=0 ); | 
| -  }else{ | 
| -    /* Consider the row to be NULL */ | 
| -    payloadSize = 0; | 
| -  } | 
| - | 
| -  /* If payloadSize is 0, then just store a NULL */ | 
| -  if( payloadSize==0 ){ | 
| -    assert( pDest->flags&MEM_Null ); | 
| -    goto op_column_out; | 
| -  } | 
| -  assert( db->aLimit[SQLITE_LIMIT_LENGTH]>=0 ); | 
| -  if( payloadSize > (u32)db->aLimit[SQLITE_LIMIT_LENGTH] ){ | 
| -    goto too_big; | 
| -  } | 
| - | 
| -  nField = pC->nField; | 
| -  assert( p2<nField ); | 
| - | 
| -  /* Read and parse the table header.  Store the results of the parse | 
| -  ** into the record header cache fields of the cursor. | 
| -  */ | 
| -  aType = pC->aType; | 
| -  if( pC->cacheStatus==p->cacheCtr ){ | 
| -    aOffset = pC->aOffset; | 
| -  }else{ | 
| -    assert(aType); | 
| -    avail = 0; | 
| -    pC->aOffset = aOffset = &aType[nField]; | 
| -    pC->payloadSize = payloadSize; | 
| -    pC->cacheStatus = p->cacheCtr; | 
| +  assert( pCrsr!=0 || pC->pseudoTableReg>0 ); /* pCrsr NULL on PseudoTables */ | 
| +  assert( pCrsr!=0 || pC->nullRow );          /* pC->nullRow on PseudoTables */ | 
|  | 
| -    /* Figure out how many bytes are in the header */ | 
| -    if( zRec ){ | 
| -      zData = zRec; | 
| +  /* If the cursor cache is stale, bring it up-to-date */ | 
| +  rc = sqlite3VdbeCursorMoveto(pC); | 
| +  if( rc ) goto abort_due_to_error; | 
| +  if( pC->cacheStatus!=p->cacheCtr ){ | 
| +    if( pC->nullRow ){ | 
| +      if( pCrsr==0 ){ | 
| +        assert( pC->pseudoTableReg>0 ); | 
| +        pReg = &aMem[pC->pseudoTableReg]; | 
| +        assert( pReg->flags & MEM_Blob ); | 
| +        assert( memIsValid(pReg) ); | 
| +        pC->payloadSize = pC->szRow = avail = pReg->n; | 
| +        pC->aRow = (u8*)pReg->z; | 
| +      }else{ | 
| +        sqlite3VdbeMemSetNull(pDest); | 
| +        goto op_column_out; | 
| +      } | 
| }else{ | 
| -      if( pC->isIndex ){ | 
| -        zData = (char*)sqlite3BtreeKeyFetch(pCrsr, &avail); | 
| +      assert( pCrsr ); | 
| +      if( pC->isTable==0 ){ | 
| +        assert( sqlite3BtreeCursorIsValid(pCrsr) ); | 
| +        VVA_ONLY(rc =) sqlite3BtreeKeySize(pCrsr, &payloadSize64); | 
| +        assert( rc==SQLITE_OK ); /* True because of CursorMoveto() call above */ | 
| +        /* sqlite3BtreeParseCellPtr() uses getVarint32() to extract the | 
| +        ** payload size, so it is impossible for payloadSize64 to be | 
| +        ** larger than 32 bits. */ | 
| +        assert( (payloadSize64 & SQLITE_MAX_U32)==(u64)payloadSize64 ); | 
| +        pC->aRow = sqlite3BtreeKeyFetch(pCrsr, &avail); | 
| +        pC->payloadSize = (u32)payloadSize64; | 
| }else{ | 
| -        zData = (char*)sqlite3BtreeDataFetch(pCrsr, &avail); | 
| +        assert( sqlite3BtreeCursorIsValid(pCrsr) ); | 
| +        VVA_ONLY(rc =) sqlite3BtreeDataSize(pCrsr, &pC->payloadSize); | 
| +        assert( rc==SQLITE_OK );   /* DataSize() cannot fail */ | 
| +        pC->aRow = sqlite3BtreeDataFetch(pCrsr, &avail); | 
| } | 
| -      /* If KeyFetch()/DataFetch() managed to get the entire payload, | 
| -      ** save the payload in the pC->aRow cache.  That will save us from | 
| -      ** having to make additional calls to fetch the content portion of | 
| -      ** the record. | 
| -      */ | 
| -      assert( avail>=0 ); | 
| -      if( payloadSize <= (u32)avail ){ | 
| -        zRec = zData; | 
| -        pC->aRow = (u8*)zData; | 
| +      assert( avail<=65536 );  /* Maximum page size is 64KiB */ | 
| +      if( pC->payloadSize <= (u32)avail ){ | 
| +        pC->szRow = pC->payloadSize; | 
| }else{ | 
| -        pC->aRow = 0; | 
| +        pC->szRow = avail; | 
| +      } | 
| +      if( pC->payloadSize > (u32)db->aLimit[SQLITE_LIMIT_LENGTH] ){ | 
| +        goto too_big; | 
| } | 
| } | 
| -    /* The following assert is true in all cases accept when | 
| -    ** the database file has been corrupted externally. | 
| -    **    assert( zRec!=0 || avail>=payloadSize || avail>=9 ); */ | 
| -    szHdr = getVarint32((u8*)zData, offset); | 
| +    pC->cacheStatus = p->cacheCtr; | 
| +    pC->iHdrOffset = getVarint32(pC->aRow, offset); | 
| +    pC->nHdrParsed = 0; | 
| +    aOffset[0] = offset; | 
|  | 
| /* Make sure a corrupt database has not given us an oversize header. | 
| ** Do this now to avoid an oversize memory allocation. | 
| @@ -2230,140 +2343,174 @@ case OP_Column: { | 
| ** 3-byte type for each of the maximum of 32768 columns plus three | 
| ** extra bytes for the header length itself.  32768*3 + 3 = 98307. | 
| */ | 
| -    if( offset > 98307 ){ | 
| +    if( offset > 98307 || offset > pC->payloadSize ){ | 
| rc = SQLITE_CORRUPT_BKPT; | 
| -      goto op_column_out; | 
| +      goto op_column_error; | 
| } | 
|  | 
| -    /* Compute in len the number of bytes of data we need to read in order | 
| -    ** to get nField type values.  offset is an upper bound on this.  But | 
| -    ** nField might be significantly less than the true number of columns | 
| -    ** in the table, and in that case, 5*nField+3 might be smaller than offset. | 
| -    ** We want to minimize len in order to limit the size of the memory | 
| -    ** allocation, especially if a corrupt database file has caused offset | 
| -    ** to be oversized. Offset is limited to 98307 above.  But 98307 might | 
| -    ** still exceed Robson memory allocation limits on some configurations. | 
| -    ** On systems that cannot tolerate large memory allocations, nField*5+3 | 
| -    ** will likely be much smaller since nField will likely be less than | 
| -    ** 20 or so.  This insures that Robson memory allocation limits are | 
| -    ** not exceeded even for corrupt database files. | 
| -    */ | 
| -    len = nField*5 + 3; | 
| -    if( len > (int)offset ) len = (int)offset; | 
| - | 
| -    /* The KeyFetch() or DataFetch() above are fast and will get the entire | 
| -    ** record header in most cases.  But they will fail to get the complete | 
| -    ** record header if the record header does not fit on a single page | 
| -    ** in the B-Tree.  When that happens, use sqlite3VdbeMemFromBtree() to | 
| -    ** acquire the complete header text. | 
| -    */ | 
| -    if( !zRec && avail<len ){ | 
| -      sMem.flags = 0; | 
| -      sMem.db = 0; | 
| -      rc = sqlite3VdbeMemFromBtree(pCrsr, 0, len, pC->isIndex, &sMem); | 
| -      if( rc!=SQLITE_OK ){ | 
| -        goto op_column_out; | 
| -      } | 
| -      zData = sMem.z; | 
| +    if( avail<offset ){ | 
| +      /* pC->aRow does not have to hold the entire row, but it does at least | 
| +      ** need to cover the header of the record.  If pC->aRow does not contain | 
| +      ** the complete header, then set it to zero, forcing the header to be | 
| +      ** dynamically allocated. */ | 
| +      pC->aRow = 0; | 
| +      pC->szRow = 0; | 
| } | 
| -    zEndHdr = (u8 *)&zData[len]; | 
| -    zIdx = (u8 *)&zData[szHdr]; | 
|  | 
| -    /* Scan the header and use it to fill in the aType[] and aOffset[] | 
| -    ** arrays.  aType[i] will contain the type integer for the i-th | 
| -    ** column and aOffset[i] will contain the offset from the beginning | 
| -    ** of the record to the start of the data for the i-th column | 
| +    /* The following goto is an optimization.  It can be omitted and | 
| +    ** everything will still work.  But OP_Column is measurably faster | 
| +    ** by skipping the subsequent conditional, which is always true. | 
| */ | 
| -    for(i=0; i<nField; i++){ | 
| -      if( zIdx<zEndHdr ){ | 
| -        aOffset[i] = offset; | 
| -        zIdx += getVarint32(zIdx, aType[i]); | 
| -        szField = sqlite3VdbeSerialTypeLen(aType[i]); | 
| +    assert( pC->nHdrParsed<=p2 );         /* Conditional skipped */ | 
| +    goto op_column_read_header; | 
| +  } | 
| + | 
| +  /* Make sure at least the first p2+1 entries of the header have been | 
| +  ** parsed and valid information is in aOffset[] and pC->aType[]. | 
| +  */ | 
| +  if( pC->nHdrParsed<=p2 ){ | 
| +    /* If there is more header available for parsing in the record, try | 
| +    ** to extract additional fields up through the p2+1-th field | 
| +    */ | 
| +    op_column_read_header: | 
| +    if( pC->iHdrOffset<aOffset[0] ){ | 
| +      /* Make sure zData points to enough of the record to cover the header. */ | 
| +      if( pC->aRow==0 ){ | 
| +        memset(&sMem, 0, sizeof(sMem)); | 
| +        rc = sqlite3VdbeMemFromBtree(pCrsr, 0, aOffset[0], | 
| +                                     !pC->isTable, &sMem); | 
| +        if( rc!=SQLITE_OK ){ | 
| +          goto op_column_error; | 
| +        } | 
| +        zData = (u8*)sMem.z; | 
| +      }else{ | 
| +        zData = pC->aRow; | 
| +      } | 
| + | 
| +      /* Fill in pC->aType[i] and aOffset[i] values through the p2-th field. */ | 
| +      i = pC->nHdrParsed; | 
| +      offset = aOffset[i]; | 
| +      zHdr = zData + pC->iHdrOffset; | 
| +      zEndHdr = zData + aOffset[0]; | 
| +      assert( i<=p2 && zHdr<zEndHdr ); | 
| +      do{ | 
| +        if( zHdr[0]<0x80 ){ | 
| +          t = zHdr[0]; | 
| +          zHdr++; | 
| +        }else{ | 
| +          zHdr += sqlite3GetVarint32(zHdr, &t); | 
| +        } | 
| +        pC->aType[i] = t; | 
| +        szField = sqlite3VdbeSerialTypeLen(t); | 
| offset += szField; | 
| if( offset<szField ){  /* True if offset overflows */ | 
| -          zIdx = &zEndHdr[1];  /* Forces SQLITE_CORRUPT return below */ | 
| +          zHdr = &zEndHdr[1];  /* Forces SQLITE_CORRUPT return below */ | 
| break; | 
| } | 
| -      }else{ | 
| -        /* If i is less that nField, then there are less fields in this | 
| -        ** record than SetNumColumns indicated there are columns in the | 
| -        ** table. Set the offset for any extra columns not present in | 
| -        ** the record to 0. This tells code below to store a NULL | 
| -        ** instead of deserializing a value from the record. | 
| -        */ | 
| -        aOffset[i] = 0; | 
| +        i++; | 
| +        aOffset[i] = offset; | 
| +      }while( i<=p2 && zHdr<zEndHdr ); | 
| +      pC->nHdrParsed = i; | 
| +      pC->iHdrOffset = (u32)(zHdr - zData); | 
| +      if( pC->aRow==0 ){ | 
| +        sqlite3VdbeMemRelease(&sMem); | 
| +        sMem.flags = MEM_Null; | 
| +      } | 
| + | 
| +      /* The record is corrupt if any of the following are true: | 
| +      ** (1) the bytes of the header extend past the declared header size | 
| +      **          (zHdr>zEndHdr) | 
| +      ** (2) the entire header was used but not all data was used | 
| +      **          (zHdr==zEndHdr && offset!=pC->payloadSize) | 
| +      ** (3) the end of the data extends beyond the end of the record. | 
| +      **          (offset > pC->payloadSize) | 
| +      */ | 
| +      if( (zHdr>=zEndHdr && (zHdr>zEndHdr || offset!=pC->payloadSize)) | 
| +       || (offset > pC->payloadSize) | 
| +      ){ | 
| +        rc = SQLITE_CORRUPT_BKPT; | 
| +        goto op_column_error; | 
| } | 
| } | 
| -    sqlite3VdbeMemRelease(&sMem); | 
| -    sMem.flags = MEM_Null; | 
| - | 
| -    /* If we have read more header data than was contained in the header, | 
| -    ** or if the end of the last field appears to be past the end of the | 
| -    ** record, or if the end of the last field appears to be before the end | 
| -    ** of the record (when all fields present), then we must be dealing | 
| -    ** with a corrupt database. | 
| + | 
| +    /* If after trying to extra new entries from the header, nHdrParsed is | 
| +    ** still not up to p2, that means that the record has fewer than p2 | 
| +    ** columns.  So the result will be either the default value or a NULL. | 
| */ | 
| -    if( (zIdx > zEndHdr) || (offset > payloadSize) | 
| -         || (zIdx==zEndHdr && offset!=payloadSize) ){ | 
| -      rc = SQLITE_CORRUPT_BKPT; | 
| +    if( pC->nHdrParsed<=p2 ){ | 
| +      if( pOp->p4type==P4_MEM ){ | 
| +        sqlite3VdbeMemShallowCopy(pDest, pOp->p4.pMem, MEM_Static); | 
| +      }else{ | 
| +        sqlite3VdbeMemSetNull(pDest); | 
| +      } | 
| goto op_column_out; | 
| } | 
| } | 
|  | 
| -  /* Get the column information. If aOffset[p2] is non-zero, then | 
| -  ** deserialize the value from the record. If aOffset[p2] is zero, | 
| -  ** then there are not enough fields in the record to satisfy the | 
| -  ** request.  In this case, set the value NULL or to P4 if P4 is | 
| -  ** a pointer to a Mem object. | 
| +  /* Extract the content for the p2+1-th column.  Control can only | 
| +  ** reach this point if aOffset[p2], aOffset[p2+1], and pC->aType[p2] are | 
| +  ** all valid. | 
| */ | 
| -  if( aOffset[p2] ){ | 
| -    assert( rc==SQLITE_OK ); | 
| -    if( zRec ){ | 
| -      sqlite3VdbeMemReleaseExternal(pDest); | 
| -      sqlite3VdbeSerialGet((u8 *)&zRec[aOffset[p2]], aType[p2], pDest); | 
| +  assert( p2<pC->nHdrParsed ); | 
| +  assert( rc==SQLITE_OK ); | 
| +  assert( sqlite3VdbeCheckMemInvariants(pDest) ); | 
| +  if( VdbeMemDynamic(pDest) ) sqlite3VdbeMemSetNull(pDest); | 
| +  t = pC->aType[p2]; | 
| +  if( pC->szRow>=aOffset[p2+1] ){ | 
| +    /* This is the common case where the desired content fits on the original | 
| +    ** page - where the content is not on an overflow page */ | 
| +    sqlite3VdbeSerialGet(pC->aRow+aOffset[p2], t, pDest); | 
| +  }else{ | 
| +    /* This branch happens only when content is on overflow pages */ | 
| +    if( ((pOp->p5 & (OPFLAG_LENGTHARG|OPFLAG_TYPEOFARG))!=0 | 
| +          && ((t>=12 && (t&1)==0) || (pOp->p5 & OPFLAG_TYPEOFARG)!=0)) | 
| +     || (len = sqlite3VdbeSerialTypeLen(t))==0 | 
| +    ){ | 
| +      /* Content is irrelevant for | 
| +      **    1. the typeof() function, | 
| +      **    2. the length(X) function if X is a blob, and | 
| +      **    3. if the content length is zero. | 
| +      ** So we might as well use bogus content rather than reading | 
| +      ** content from disk.  NULL will work for the value for strings | 
| +      ** and blobs and whatever is in the payloadSize64 variable | 
| +      ** will work for everything else. */ | 
| +      sqlite3VdbeSerialGet(t<=13 ? (u8*)&payloadSize64 : 0, t, pDest); | 
| }else{ | 
| -      len = sqlite3VdbeSerialTypeLen(aType[p2]); | 
| -      sqlite3VdbeMemMove(&sMem, pDest); | 
| -      rc = sqlite3VdbeMemFromBtree(pCrsr, aOffset[p2], len, pC->isIndex, &sMem); | 
| +      rc = sqlite3VdbeMemFromBtree(pCrsr, aOffset[p2], len, !pC->isTable, | 
| +                                   pDest); | 
| if( rc!=SQLITE_OK ){ | 
| -        goto op_column_out; | 
| +        goto op_column_error; | 
| } | 
| -      zData = sMem.z; | 
| -      sqlite3VdbeSerialGet((u8*)zData, aType[p2], pDest); | 
| -    } | 
| -    pDest->enc = encoding; | 
| -  }else{ | 
| -    if( pOp->p4type==P4_MEM ){ | 
| -      sqlite3VdbeMemShallowCopy(pDest, pOp->p4.pMem, MEM_Static); | 
| -    }else{ | 
| -      assert( pDest->flags&MEM_Null ); | 
| +      sqlite3VdbeSerialGet((const u8*)pDest->z, t, pDest); | 
| +      pDest->flags &= ~MEM_Ephem; | 
| } | 
| } | 
| - | 
| -  /* If we dynamically allocated space to hold the data (in the | 
| -  ** sqlite3VdbeMemFromBtree() call above) then transfer control of that | 
| -  ** dynamically allocated space over to the pDest structure. | 
| -  ** This prevents a memory copy. | 
| -  */ | 
| -  if( sMem.zMalloc ){ | 
| -    assert( sMem.z==sMem.zMalloc ); | 
| -    assert( !(pDest->flags & MEM_Dyn) ); | 
| -    assert( !(pDest->flags & (MEM_Blob|MEM_Str)) || pDest->z==sMem.z ); | 
| -    pDest->flags &= ~(MEM_Ephem|MEM_Static); | 
| -    pDest->flags |= MEM_Term; | 
| -    pDest->z = sMem.z; | 
| -    pDest->zMalloc = sMem.zMalloc; | 
| -  } | 
| - | 
| -  rc = sqlite3VdbeMemMakeWriteable(pDest); | 
| +  pDest->enc = encoding; | 
|  | 
| op_column_out: | 
| +  /* If the column value is an ephemeral string, go ahead and persist | 
| +  ** that string in case the cursor moves before the column value is | 
| +  ** used.  The following code does the equivalent of Deephemeralize() | 
| +  ** but does it faster. */ | 
| +  if( (pDest->flags & MEM_Ephem)!=0 && pDest->z ){ | 
| +    fx = pDest->flags & (MEM_Str|MEM_Blob); | 
| +    assert( fx!=0 ); | 
| +    zData = (const u8*)pDest->z; | 
| +    len = pDest->n; | 
| +    if( sqlite3VdbeMemClearAndResize(pDest, len+2) ) goto no_mem; | 
| +    memcpy(pDest->z, zData, len); | 
| +    pDest->z[len] = 0; | 
| +    pDest->z[len+1] = 0; | 
| +    pDest->flags = fx|MEM_Term; | 
| +  } | 
| +op_column_error: | 
| UPDATE_MAX_BLOBSIZE(pDest); | 
| REGISTER_TRACE(pOp->p3, pDest); | 
| break; | 
| } | 
|  | 
| /* Opcode: Affinity P1 P2 * P4 * | 
| +** Synopsis: affinity(r[P1@P2]) | 
| ** | 
| ** Apply affinities to a range of P2 registers starting with P1. | 
| ** | 
| @@ -2380,9 +2527,8 @@ case OP_Affinity: { | 
| assert( zAffinity[pOp->p2]==0 ); | 
| pIn1 = &aMem[pOp->p1]; | 
| while( (cAff = *(zAffinity++))!=0 ){ | 
| -    assert( pIn1 <= &p->aMem[p->nMem] ); | 
| +    assert( pIn1 <= &p->aMem[(p->nMem-p->nCursor)] ); | 
| assert( memIsValid(pIn1) ); | 
| -    ExpandBlob(pIn1); | 
| applyAffinity(pIn1, cAff, encoding); | 
| pIn1++; | 
| } | 
| @@ -2390,6 +2536,7 @@ case OP_Affinity: { | 
| } | 
|  | 
| /* Opcode: MakeRecord P1 P2 P3 P4 * | 
| +** Synopsis: r[P3]=mkrec(r[P1@P2]) | 
| ** | 
| ** Convert P2 registers beginning with P1 into the [record format] | 
| ** use as a data record in a database table or as a key | 
| @@ -2418,7 +2565,8 @@ case OP_MakeRecord: { | 
| int nField;            /* Number of fields in the record */ | 
| char *zAffinity;       /* The affinity string for the record */ | 
| int file_format;       /* File format to use for encoding */ | 
| -  int i;                 /* Space used in zNewRecord[] */ | 
| +  int i;                 /* Space used in zNewRecord[] header */ | 
| +  int j;                 /* Space used in zNewRecord[] content */ | 
| int len;               /* Length of a field */ | 
|  | 
| /* Assuming the record contains N fields, the record format looks | 
| @@ -2429,7 +2577,7 @@ case OP_MakeRecord: { | 
| ** ------------------------------------------------------------------------ | 
| ** | 
| ** Data(0) is taken from register P1.  Data(1) comes from register P1+1 | 
| -  ** and so froth. | 
| +  ** and so forth. | 
| ** | 
| ** Each type field is a varint representing the serial type of the | 
| ** corresponding data element (see sqlite3VdbeSerialType()). The | 
| @@ -2441,7 +2589,7 @@ case OP_MakeRecord: { | 
| nZero = 0;         /* Number of zero bytes at the end of the record */ | 
| nField = pOp->p1; | 
| zAffinity = pOp->p4.z; | 
| -  assert( nField>0 && pOp->p2>0 && pOp->p2+nField<=p->nMem+1 ); | 
| +  assert( nField>0 && pOp->p2>0 && pOp->p2+nField<=(p->nMem-p->nCursor)+1 ); | 
| pData0 = &aMem[nField]; | 
| nField = pOp->p2; | 
| pLast = &pData0[nField-1]; | 
| @@ -2452,36 +2600,52 @@ case OP_MakeRecord: { | 
| pOut = &aMem[pOp->p3]; | 
| memAboutToChange(p, pOut); | 
|  | 
| +  /* Apply the requested affinity to all inputs | 
| +  */ | 
| +  assert( pData0<=pLast ); | 
| +  if( zAffinity ){ | 
| +    pRec = pData0; | 
| +    do{ | 
| +      applyAffinity(pRec++, *(zAffinity++), encoding); | 
| +      assert( zAffinity[0]==0 || pRec<=pLast ); | 
| +    }while( zAffinity[0] ); | 
| +  } | 
| + | 
| /* Loop through the elements that will make up the record to figure | 
| ** out how much space is required for the new record. | 
| */ | 
| -  for(pRec=pData0; pRec<=pLast; pRec++){ | 
| +  pRec = pLast; | 
| +  do{ | 
| assert( memIsValid(pRec) ); | 
| -    if( zAffinity ){ | 
| -      applyAffinity(pRec, zAffinity[pRec-pData0], encoding); | 
| -    } | 
| -    if( pRec->flags&MEM_Zero && pRec->n>0 ){ | 
| -      sqlite3VdbeMemExpandBlob(pRec); | 
| -    } | 
| -    serial_type = sqlite3VdbeSerialType(pRec, file_format); | 
| +    pRec->uTemp = serial_type = sqlite3VdbeSerialType(pRec, file_format); | 
| len = sqlite3VdbeSerialTypeLen(serial_type); | 
| -    nData += len; | 
| -    nHdr += sqlite3VarintLen(serial_type); | 
| if( pRec->flags & MEM_Zero ){ | 
| -      /* Only pure zero-filled BLOBs can be input to this Opcode. | 
| -      ** We do not allow blobs with a prefix and a zero-filled tail. */ | 
| -      nZero += pRec->u.nZero; | 
| -    }else if( len ){ | 
| -      nZero = 0; | 
| +      if( nData ){ | 
| +        sqlite3VdbeMemExpandBlob(pRec); | 
| +      }else{ | 
| +        nZero += pRec->u.nZero; | 
| +        len -= pRec->u.nZero; | 
| +      } | 
| } | 
| -  } | 
| +    nData += len; | 
| +    testcase( serial_type==127 ); | 
| +    testcase( serial_type==128 ); | 
| +    nHdr += serial_type<=127 ? 1 : sqlite3VarintLen(serial_type); | 
| +  }while( (--pRec)>=pData0 ); | 
|  | 
| /* Add the initial header varint and total the size */ | 
| -  nHdr += nVarint = sqlite3VarintLen(nHdr); | 
| -  if( nVarint<sqlite3VarintLen(nHdr) ){ | 
| -    nHdr++; | 
| +  testcase( nHdr==126 ); | 
| +  testcase( nHdr==127 ); | 
| +  if( nHdr<=126 ){ | 
| +    /* The common case */ | 
| +    nHdr += 1; | 
| +  }else{ | 
| +    /* Rare case of a really large header */ | 
| +    nVarint = sqlite3VarintLen(nHdr); | 
| +    nHdr += nVarint; | 
| +    if( nVarint<sqlite3VarintLen(nHdr) ) nHdr++; | 
| } | 
| -  nByte = nHdr+nData-nZero; | 
| +  nByte = nHdr+nData; | 
| if( nByte>db->aLimit[SQLITE_LIMIT_LENGTH] ){ | 
| goto too_big; | 
| } | 
| @@ -2489,28 +2653,29 @@ case OP_MakeRecord: { | 
| /* Make sure the output register has a buffer large enough to store | 
| ** the new record. The output register (pOp->p3) is not allowed to | 
| ** be one of the input registers (because the following call to | 
| -  ** sqlite3VdbeMemGrow() could clobber the value before it is used). | 
| +  ** sqlite3VdbeMemClearAndResize() could clobber the value before it is used). | 
| */ | 
| -  if( sqlite3VdbeMemGrow(pOut, (int)nByte, 0) ){ | 
| +  if( sqlite3VdbeMemClearAndResize(pOut, (int)nByte) ){ | 
| goto no_mem; | 
| } | 
| zNewRecord = (u8 *)pOut->z; | 
|  | 
| /* Write the record */ | 
| i = putVarint32(zNewRecord, nHdr); | 
| -  for(pRec=pData0; pRec<=pLast; pRec++){ | 
| -    serial_type = sqlite3VdbeSerialType(pRec, file_format); | 
| -    i += putVarint32(&zNewRecord[i], serial_type);      /* serial type */ | 
| -  } | 
| -  for(pRec=pData0; pRec<=pLast; pRec++){  /* serial data */ | 
| -    i += sqlite3VdbeSerialPut(&zNewRecord[i], (int)(nByte-i), pRec,file_format); | 
| -  } | 
| -  assert( i==nByte ); | 
| - | 
| -  assert( pOp->p3>0 && pOp->p3<=p->nMem ); | 
| +  j = nHdr; | 
| +  assert( pData0<=pLast ); | 
| +  pRec = pData0; | 
| +  do{ | 
| +    serial_type = pRec->uTemp; | 
| +    i += putVarint32(&zNewRecord[i], serial_type);            /* serial type */ | 
| +    j += sqlite3VdbeSerialPut(&zNewRecord[j], pRec, serial_type); /* content */ | 
| +  }while( (++pRec)<=pLast ); | 
| +  assert( i==nHdr ); | 
| +  assert( j==nByte ); | 
| + | 
| +  assert( pOp->p3>0 && pOp->p3<=(p->nMem-p->nCursor) ); | 
| pOut->n = (int)nByte; | 
| -  pOut->flags = MEM_Blob | MEM_Dyn; | 
| -  pOut->xDel = 0; | 
| +  pOut->flags = MEM_Blob; | 
| if( nZero ){ | 
| pOut->u.nZero = nZero; | 
| pOut->flags |= MEM_Zero; | 
| @@ -2522,6 +2687,7 @@ case OP_MakeRecord: { | 
| } | 
|  | 
| /* Opcode: Count P1 P2 * * * | 
| +** Synopsis: r[P2]=count() | 
| ** | 
| ** Store the number of entries (an integer value) in the table or index | 
| ** opened by cursor P1 in register P2 | 
| @@ -2532,11 +2698,9 @@ case OP_Count: {         /* out2-prerelease */ | 
| BtCursor *pCrsr; | 
|  | 
| pCrsr = p->apCsr[pOp->p1]->pCursor; | 
| -  if( pCrsr ){ | 
| -    rc = sqlite3BtreeCount(pCrsr, &nEntry); | 
| -  }else{ | 
| -    nEntry = 0; | 
| -  } | 
| +  assert( pCrsr ); | 
| +  nEntry = 0;  /* Not needed.  Only used to silence a warning. */ | 
| +  rc = sqlite3BtreeCount(pCrsr, &nEntry); | 
| pOut->u.i = nEntry; | 
| break; | 
| } | 
| @@ -2568,9 +2732,10 @@ case OP_Savepoint: { | 
| assert( p1==SAVEPOINT_BEGIN||p1==SAVEPOINT_RELEASE||p1==SAVEPOINT_ROLLBACK ); | 
| assert( db->pSavepoint || db->isTransactionSavepoint==0 ); | 
| assert( checkSavepointCount(db) ); | 
| +  assert( p->bIsReader ); | 
|  | 
| if( p1==SAVEPOINT_BEGIN ){ | 
| -    if( db->writeVdbeCnt>0 ){ | 
| +    if( db->nVdbeWrite>0 ){ | 
| /* A new savepoint cannot be created if there are active write | 
| ** statements (i.e. open read/write incremental blob handles). | 
| */ | 
| @@ -2580,6 +2745,17 @@ case OP_Savepoint: { | 
| }else{ | 
| nName = sqlite3Strlen30(zName); | 
|  | 
| +#ifndef SQLITE_OMIT_VIRTUALTABLE | 
| +      /* This call is Ok even if this savepoint is actually a transaction | 
| +      ** savepoint (and therefore should not prompt xSavepoint()) callbacks. | 
| +      ** If this is a transaction savepoint being opened, it is guaranteed | 
| +      ** that the db->aVTrans[] array is empty.  */ | 
| +      assert( db->autoCommit==0 || db->nVTrans==0 ); | 
| +      rc = sqlite3VtabSavepoint(db, SAVEPOINT_BEGIN, | 
| +                                db->nStatement+db->nSavepoint); | 
| +      if( rc!=SQLITE_OK ) goto abort_due_to_error; | 
| +#endif | 
| + | 
| /* Create a new savepoint structure. */ | 
| pNew = sqlite3DbMallocRaw(db, sizeof(Savepoint)+nName+1); | 
| if( pNew ){ | 
| @@ -2599,6 +2775,7 @@ case OP_Savepoint: { | 
| pNew->pNext = db->pSavepoint; | 
| db->pSavepoint = pNew; | 
| pNew->nDeferredCons = db->nDeferredCons; | 
| +        pNew->nDeferredImmCons = db->nDeferredImmCons; | 
| } | 
| } | 
| }else{ | 
| @@ -2616,16 +2793,12 @@ case OP_Savepoint: { | 
| if( !pSavepoint ){ | 
| sqlite3SetString(&p->zErrMsg, db, "no such savepoint: %s", zName); | 
| rc = SQLITE_ERROR; | 
| -    }else if( | 
| -        db->writeVdbeCnt>0 || (p1==SAVEPOINT_ROLLBACK && db->activeVdbeCnt>1) | 
| -    ){ | 
| +    }else if( db->nVdbeWrite>0 && p1==SAVEPOINT_RELEASE ){ | 
| /* It is not possible to release (commit) a savepoint if there are | 
| -      ** active write statements. It is not possible to rollback a savepoint | 
| -      ** if there are any active statements at all. | 
| +      ** active write statements. | 
| */ | 
| sqlite3SetString(&p->zErrMsg, db, | 
| -        "cannot %s savepoint - SQL statements in progress", | 
| -        (p1==SAVEPOINT_ROLLBACK ? "rollback": "release") | 
| +        "cannot release savepoint - SQL statements in progress" | 
| ); | 
| rc = SQLITE_BUSY; | 
| }else{ | 
| @@ -2649,16 +2822,28 @@ case OP_Savepoint: { | 
| db->isTransactionSavepoint = 0; | 
| rc = p->rc; | 
| }else{ | 
| +        int isSchemaChange; | 
| iSavepoint = db->nSavepoint - iSavepoint - 1; | 
| +        if( p1==SAVEPOINT_ROLLBACK ){ | 
| +          isSchemaChange = (db->flags & SQLITE_InternChanges)!=0; | 
| +          for(ii=0; ii<db->nDb; ii++){ | 
| +            rc = sqlite3BtreeTripAllCursors(db->aDb[ii].pBt, | 
| +                                       SQLITE_ABORT_ROLLBACK, | 
| +                                       isSchemaChange==0); | 
| +            if( rc!=SQLITE_OK ) goto abort_due_to_error; | 
| +          } | 
| +        }else{ | 
| +          isSchemaChange = 0; | 
| +        } | 
| for(ii=0; ii<db->nDb; ii++){ | 
| rc = sqlite3BtreeSavepoint(db->aDb[ii].pBt, p1, iSavepoint); | 
| if( rc!=SQLITE_OK ){ | 
| goto abort_due_to_error; | 
| } | 
| } | 
| -        if( p1==SAVEPOINT_ROLLBACK && (db->flags&SQLITE_InternChanges)!=0 ){ | 
| +        if( isSchemaChange ){ | 
| sqlite3ExpirePreparedStatements(db); | 
| -          sqlite3ResetInternalSchema(db, -1); | 
| +          sqlite3ResetAllSchemasOfConnection(db); | 
| db->flags = (db->flags | SQLITE_InternChanges); | 
| } | 
| } | 
| @@ -2685,6 +2870,12 @@ case OP_Savepoint: { | 
| } | 
| }else{ | 
| db->nDeferredCons = pSavepoint->nDeferredCons; | 
| +        db->nDeferredImmCons = pSavepoint->nDeferredImmCons; | 
| +      } | 
| + | 
| +      if( !isTransaction ){ | 
| +        rc = sqlite3VtabSavepoint(db, p1, iSavepoint); | 
| +        if( rc!=SQLITE_OK ) goto abort_due_to_error; | 
| } | 
| } | 
| } | 
| @@ -2711,9 +2902,11 @@ case OP_AutoCommit: { | 
| turnOnAC = desiredAutoCommit && !db->autoCommit; | 
| assert( desiredAutoCommit==1 || desiredAutoCommit==0 ); | 
| assert( desiredAutoCommit==1 || iRollback==0 ); | 
| -  assert( db->activeVdbeCnt>0 );  /* At least this one VM is active */ | 
| +  assert( db->nVdbeActive>0 );  /* At least this one VM is active */ | 
| +  assert( p->bIsReader ); | 
|  | 
| -  if( turnOnAC && iRollback && db->activeVdbeCnt>1 ){ | 
| +#if 0 | 
| +  if( turnOnAC && iRollback && db->nVdbeActive>1 ){ | 
| /* If this instruction implements a ROLLBACK and other VMs are | 
| ** still running, and a transaction is active, return an error indicating | 
| ** that the other VMs must complete first. | 
| @@ -2721,7 +2914,9 @@ case OP_AutoCommit: { | 
| sqlite3SetString(&p->zErrMsg, db, "cannot rollback transaction - " | 
| "SQL statements in progress"); | 
| rc = SQLITE_BUSY; | 
| -  }else if( turnOnAC && !iRollback && db->writeVdbeCnt>0 ){ | 
| +  }else | 
| +#endif | 
| +  if( turnOnAC && !iRollback && db->nVdbeWrite>0 ){ | 
| /* If this instruction implements a COMMIT and other VMs are writing | 
| ** return an error indicating that the other VMs must complete first. | 
| */ | 
| @@ -2731,7 +2926,7 @@ case OP_AutoCommit: { | 
| }else if( desiredAutoCommit!=db->autoCommit ){ | 
| if( iRollback ){ | 
| assert( desiredAutoCommit==1 ); | 
| -      sqlite3RollbackAll(db); | 
| +      sqlite3RollbackAll(db, SQLITE_ABORT_ROLLBACK); | 
| db->autoCommit = 1; | 
| }else if( (rc = sqlite3VdbeCheckFk(p, 1))!=SQLITE_OK ){ | 
| goto vdbe_return; | 
| @@ -2763,42 +2958,53 @@ case OP_AutoCommit: { | 
| break; | 
| } | 
|  | 
| -/* Opcode: Transaction P1 P2 * * * | 
| +/* Opcode: Transaction P1 P2 P3 P4 P5 | 
| ** | 
| -** Begin a transaction.  The transaction ends when a Commit or Rollback | 
| -** opcode is encountered.  Depending on the ON CONFLICT setting, the | 
| -** transaction might also be rolled back if an error is encountered. | 
| +** Begin a transaction on database P1 if a transaction is not already | 
| +** active. | 
| +** If P2 is non-zero, then a write-transaction is started, or if a | 
| +** read-transaction is already active, it is upgraded to a write-transaction. | 
| +** If P2 is zero, then a read-transaction is started. | 
| ** | 
| ** P1 is the index of the database file on which the transaction is | 
| ** started.  Index 0 is the main database file and index 1 is the | 
| ** file used for temporary tables.  Indices of 2 or more are used for | 
| ** attached databases. | 
| ** | 
| -** If P2 is non-zero, then a write-transaction is started.  A RESERVED lock is | 
| -** obtained on the database file when a write-transaction is started.  No | 
| -** other process can start another write transaction while this transaction is | 
| -** underway.  Starting a write transaction also creates a rollback journal. A | 
| -** write transaction must be started before any changes can be made to the | 
| -** database.  If P2 is 2 or greater then an EXCLUSIVE lock is also obtained | 
| -** on the file. | 
| -** | 
| ** If a write-transaction is started and the Vdbe.usesStmtJournal flag is | 
| ** true (this flag is set if the Vdbe may modify more than one row and may | 
| ** throw an ABORT exception), a statement transaction may also be opened. | 
| ** More specifically, a statement transaction is opened iff the database | 
| ** connection is currently not in autocommit mode, or if there are other | 
| -** active statements. A statement transaction allows the affects of this | 
| +** active statements. A statement transaction allows the changes made by this | 
| ** VDBE to be rolled back after an error without having to roll back the | 
| ** entire transaction. If no error is encountered, the statement transaction | 
| ** will automatically commit when the VDBE halts. | 
| ** | 
| -** If P2 is zero, then a read-lock is obtained on the database file. | 
| +** If P5!=0 then this opcode also checks the schema cookie against P3 | 
| +** and the schema generation counter against P4. | 
| +** The cookie changes its value whenever the database schema changes. | 
| +** This operation is used to detect when that the cookie has changed | 
| +** and that the current process needs to reread the schema.  If the schema | 
| +** cookie in P3 differs from the schema cookie in the database header or | 
| +** if the schema generation counter in P4 differs from the current | 
| +** generation counter, then an SQLITE_SCHEMA error is raised and execution | 
| +** halts.  The sqlite3_step() wrapper function might then reprepare the | 
| +** statement and rerun it from the beginning. | 
| */ | 
| case OP_Transaction: { | 
| Btree *pBt; | 
| +  int iMeta; | 
| +  int iGen; | 
|  | 
| +  assert( p->bIsReader ); | 
| +  assert( p->readOnly==0 || pOp->p2==0 ); | 
| assert( pOp->p1>=0 && pOp->p1<db->nDb ); | 
| -  assert( (p->btreeMask & (((yDbMask)1)<<pOp->p1))!=0 ); | 
| +  assert( DbMaskTest(p->btreeMask, pOp->p1) ); | 
| +  if( pOp->p2 && (db->flags & SQLITE_QueryOnly)!=0 ){ | 
| +    rc = SQLITE_READONLY; | 
| +    goto abort_due_to_error; | 
| +  } | 
| pBt = db->aDb[pOp->p1].pBt; | 
|  | 
| if( pBt ){ | 
| @@ -2813,7 +3019,7 @@ case OP_Transaction: { | 
| } | 
|  | 
| if( pOp->p2 && p->usesStmtJournal | 
| -     && (db->autoCommit==0 || db->activeVdbeCnt>1) | 
| +     && (db->autoCommit==0 || db->nVdbeRead>1) | 
| ){ | 
| assert( sqlite3BtreeIsInTrans(pBt) ); | 
| if( p->iStatement==0 ){ | 
| @@ -2821,13 +3027,47 @@ case OP_Transaction: { | 
| db->nStatement++; | 
| p->iStatement = db->nSavepoint + db->nStatement; | 
| } | 
| -      rc = sqlite3BtreeBeginStmt(pBt, p->iStatement); | 
| + | 
| +      rc = sqlite3VtabSavepoint(db, SAVEPOINT_BEGIN, p->iStatement-1); | 
| +      if( rc==SQLITE_OK ){ | 
| +        rc = sqlite3BtreeBeginStmt(pBt, p->iStatement); | 
| +      } | 
|  | 
| /* Store the current value of the database handles deferred constraint | 
| ** counter. If the statement transaction needs to be rolled back, | 
| ** the value of this counter needs to be restored too.  */ | 
| p->nStmtDefCons = db->nDeferredCons; | 
| +      p->nStmtDefImmCons = db->nDeferredImmCons; | 
| +    } | 
| + | 
| +    /* Gather the schema version number for checking */ | 
| +    sqlite3BtreeGetMeta(pBt, BTREE_SCHEMA_VERSION, (u32 *)&iMeta); | 
| +    iGen = db->aDb[pOp->p1].pSchema->iGeneration; | 
| +  }else{ | 
| +    iGen = iMeta = 0; | 
| +  } | 
| +  assert( pOp->p5==0 || pOp->p4type==P4_INT32 ); | 
| +  if( pOp->p5 && (iMeta!=pOp->p3 || iGen!=pOp->p4.i) ){ | 
| +    sqlite3DbFree(db, p->zErrMsg); | 
| +    p->zErrMsg = sqlite3DbStrDup(db, "database schema has changed"); | 
| +    /* If the schema-cookie from the database file matches the cookie | 
| +    ** stored with the in-memory representation of the schema, do | 
| +    ** not reload the schema from the database file. | 
| +    ** | 
| +    ** If virtual-tables are in use, this is not just an optimization. | 
| +    ** Often, v-tables store their data in other SQLite tables, which | 
| +    ** are queried from within xNext() and other v-table methods using | 
| +    ** prepared queries. If such a query is out-of-date, we do not want to | 
| +    ** discard the database schema, as the user code implementing the | 
| +    ** v-table would have to be ready for the sqlite3_vtab structure itself | 
| +    ** to be invalidated whenever sqlite3_step() is called from within | 
| +    ** a v-table method. | 
| +    */ | 
| +    if( db->aDb[pOp->p1].pSchema->schema_cookie!=iMeta ){ | 
| +      sqlite3ResetOneSchema(db, pOp->p1); | 
| } | 
| +    p->expired = 1; | 
| +    rc = SQLITE_SCHEMA; | 
| } | 
| break; | 
| } | 
| @@ -2849,12 +3089,13 @@ case OP_ReadCookie: {               /* out2-prerelease */ | 
| int iDb; | 
| int iCookie; | 
|  | 
| +  assert( p->bIsReader ); | 
| iDb = pOp->p1; | 
| iCookie = pOp->p3; | 
| assert( pOp->p3<SQLITE_N_BTREE_META ); | 
| assert( iDb>=0 && iDb<db->nDb ); | 
| assert( db->aDb[iDb].pBt!=0 ); | 
| -  assert( (p->btreeMask & (((yDbMask)1)<<iDb))!=0 ); | 
| +  assert( DbMaskTest(p->btreeMask, iDb) ); | 
|  | 
| sqlite3BtreeGetMeta(db->aDb[iDb].pBt, iCookie, (u32 *)&iMeta); | 
| pOut->u.i = iMeta; | 
| @@ -2875,7 +3116,8 @@ case OP_SetCookie: {       /* in3 */ | 
| Db *pDb; | 
| assert( pOp->p2<SQLITE_N_BTREE_META ); | 
| assert( pOp->p1>=0 && pOp->p1<db->nDb ); | 
| -  assert( (p->btreeMask & (((yDbMask)1)<<pOp->p1))!=0 ); | 
| +  assert( DbMaskTest(p->btreeMask, pOp->p1) ); | 
| +  assert( p->readOnly==0 ); | 
| pDb = &db->aDb[pOp->p1]; | 
| assert( pDb->pBt!=0 ); | 
| assert( sqlite3SchemaMutexHeld(db, pOp->p1, 0) ); | 
| @@ -2900,66 +3142,8 @@ case OP_SetCookie: {       /* in3 */ | 
| break; | 
| } | 
|  | 
| -/* Opcode: VerifyCookie P1 P2 P3 * * | 
| -** | 
| -** Check the value of global database parameter number 0 (the | 
| -** schema version) and make sure it is equal to P2 and that the | 
| -** generation counter on the local schema parse equals P3. | 
| -** | 
| -** P1 is the database number which is 0 for the main database file | 
| -** and 1 for the file holding temporary tables and some higher number | 
| -** for auxiliary databases. | 
| -** | 
| -** The cookie changes its value whenever the database schema changes. | 
| -** This operation is used to detect when that the cookie has changed | 
| -** and that the current process needs to reread the schema. | 
| -** | 
| -** Either a transaction needs to have been started or an OP_Open needs | 
| -** to be executed (to establish a read lock) before this opcode is | 
| -** invoked. | 
| -*/ | 
| -case OP_VerifyCookie: { | 
| -  int iMeta; | 
| -  int iGen; | 
| -  Btree *pBt; | 
| - | 
| -  assert( pOp->p1>=0 && pOp->p1<db->nDb ); | 
| -  assert( (p->btreeMask & (((yDbMask)1)<<pOp->p1))!=0 ); | 
| -  assert( sqlite3SchemaMutexHeld(db, pOp->p1, 0) ); | 
| -  pBt = db->aDb[pOp->p1].pBt; | 
| -  if( pBt ){ | 
| -    sqlite3BtreeGetMeta(pBt, BTREE_SCHEMA_VERSION, (u32 *)&iMeta); | 
| -    iGen = db->aDb[pOp->p1].pSchema->iGeneration; | 
| -  }else{ | 
| -    iGen = iMeta = 0; | 
| -  } | 
| -  if( iMeta!=pOp->p2 || iGen!=pOp->p3 ){ | 
| -    sqlite3DbFree(db, p->zErrMsg); | 
| -    p->zErrMsg = sqlite3DbStrDup(db, "database schema has changed"); | 
| -    /* If the schema-cookie from the database file matches the cookie | 
| -    ** stored with the in-memory representation of the schema, do | 
| -    ** not reload the schema from the database file. | 
| -    ** | 
| -    ** If virtual-tables are in use, this is not just an optimization. | 
| -    ** Often, v-tables store their data in other SQLite tables, which | 
| -    ** are queried from within xNext() and other v-table methods using | 
| -    ** prepared queries. If such a query is out-of-date, we do not want to | 
| -    ** discard the database schema, as the user code implementing the | 
| -    ** v-table would have to be ready for the sqlite3_vtab structure itself | 
| -    ** to be invalidated whenever sqlite3_step() is called from within | 
| -    ** a v-table method. | 
| -    */ | 
| -    if( db->aDb[pOp->p1].pSchema->schema_cookie!=iMeta ){ | 
| -      sqlite3ResetInternalSchema(db, pOp->p1); | 
| -    } | 
| - | 
| -    p->expired = 1; | 
| -    rc = SQLITE_SCHEMA; | 
| -  } | 
| -  break; | 
| -} | 
| - | 
| /* Opcode: OpenRead P1 P2 P3 P4 P5 | 
| +** Synopsis: root=P2 iDb=P3 | 
| ** | 
| ** Open a read-only cursor for the database table whose root page is | 
| ** P2 in a database file.  The database file is determined by P3. | 
| @@ -2987,9 +3171,24 @@ case OP_VerifyCookie: { | 
| ** sequence of the index being opened. Otherwise, if P4 is an integer | 
| ** value, it is set to the number of columns in the table. | 
| ** | 
| -** See also OpenWrite. | 
| +** See also: OpenWrite, ReopenIdx | 
| +*/ | 
| +/* Opcode: ReopenIdx P1 P2 P3 P4 P5 | 
| +** Synopsis: root=P2 iDb=P3 | 
| +** | 
| +** The ReopenIdx opcode works exactly like ReadOpen except that it first | 
| +** checks to see if the cursor on P1 is already open with a root page | 
| +** number of P2 and if it is this opcode becomes a no-op.  In other words, | 
| +** if the cursor is already open, do not reopen it. | 
| +** | 
| +** The ReopenIdx opcode may only be used with P5==0 and with P4 being | 
| +** a P4_KEYINFO object.  Furthermore, the P3 value must be the same as | 
| +** every other ReopenIdx or OpenRead for the same cursor number. | 
| +** | 
| +** See the OpenRead opcode documentation for additional information. | 
| */ | 
| /* Opcode: OpenWrite P1 P2 P3 P4 P5 | 
| +** Synopsis: root=P2 iDb=P3 | 
| ** | 
| ** Open a read/write cursor named P1 on the table or index whose root | 
| ** page is P2.  Or if P5!=0 use the content of register P2 to find the | 
| @@ -3008,6 +3207,19 @@ case OP_VerifyCookie: { | 
| ** | 
| ** See also OpenRead. | 
| */ | 
| +case OP_ReopenIdx: { | 
| +  VdbeCursor *pCur; | 
| + | 
| +  assert( pOp->p5==0 ); | 
| +  assert( pOp->p4type==P4_KEYINFO ); | 
| +  pCur = p->apCsr[pOp->p1]; | 
| +  if( pCur && pCur->pgnoRoot==(u32)pOp->p2 ){ | 
| +    assert( pCur->iDb==pOp->p3 );      /* Guaranteed by the code generator */ | 
| +    break; | 
| +  } | 
| +  /* If the cursor is not currently open or is open on a different | 
| +  ** index, then fall through into OP_OpenRead to force a reopen */ | 
| +} | 
| case OP_OpenRead: | 
| case OP_OpenWrite: { | 
| int nField; | 
| @@ -3019,8 +3231,14 @@ case OP_OpenWrite: { | 
| VdbeCursor *pCur; | 
| Db *pDb; | 
|  | 
| +  assert( (pOp->p5&(OPFLAG_P2ISREG|OPFLAG_BULKCSR))==pOp->p5 ); | 
| +  assert( pOp->opcode==OP_OpenWrite || pOp->p5==0 ); | 
| +  assert( p->bIsReader ); | 
| +  assert( pOp->opcode==OP_OpenRead || pOp->opcode==OP_ReopenIdx | 
| +          || p->readOnly==0 ); | 
| + | 
| if( p->expired ){ | 
| -    rc = SQLITE_ABORT; | 
| +    rc = SQLITE_ABORT_ROLLBACK; | 
| break; | 
| } | 
|  | 
| @@ -3029,7 +3247,7 @@ case OP_OpenWrite: { | 
| p2 = pOp->p2; | 
| iDb = pOp->p3; | 
| assert( iDb>=0 && iDb<db->nDb ); | 
| -  assert( (p->btreeMask & (((yDbMask)1)<<iDb))!=0 ); | 
| +  assert( DbMaskTest(p->btreeMask, iDb) ); | 
| pDb = &db->aDb[iDb]; | 
| pX = pDb->pBt; | 
| assert( pX!=0 ); | 
| @@ -3042,9 +3260,9 @@ case OP_OpenWrite: { | 
| }else{ | 
| wrFlag = 0; | 
| } | 
| -  if( pOp->p5 ){ | 
| +  if( pOp->p5 & OPFLAG_P2ISREG ){ | 
| assert( p2>0 ); | 
| -    assert( p2<=p->nMem ); | 
| +    assert( p2<=(p->nMem-p->nCursor) ); | 
| pIn2 = &aMem[p2]; | 
| assert( memIsValid(pIn2) ); | 
| assert( (pIn2->flags & MEM_Int)!=0 ); | 
| @@ -3061,39 +3279,35 @@ case OP_OpenWrite: { | 
| } | 
| if( pOp->p4type==P4_KEYINFO ){ | 
| pKeyInfo = pOp->p4.pKeyInfo; | 
| -    pKeyInfo->enc = ENC(p->db); | 
| -    nField = pKeyInfo->nField+1; | 
| +    assert( pKeyInfo->enc==ENC(db) ); | 
| +    assert( pKeyInfo->db==db ); | 
| +    nField = pKeyInfo->nField+pKeyInfo->nXField; | 
| }else if( pOp->p4type==P4_INT32 ){ | 
| nField = pOp->p4.i; | 
| } | 
| assert( pOp->p1>=0 ); | 
| +  assert( nField>=0 ); | 
| +  testcase( nField==0 );  /* Table with INTEGER PRIMARY KEY and nothing else */ | 
| pCur = allocateCursor(p, pOp->p1, nField, iDb, 1); | 
| if( pCur==0 ) goto no_mem; | 
| pCur->nullRow = 1; | 
| pCur->isOrdered = 1; | 
| +  pCur->pgnoRoot = p2; | 
| rc = sqlite3BtreeCursor(pX, p2, wrFlag, pKeyInfo, pCur->pCursor); | 
| pCur->pKeyInfo = pKeyInfo; | 
| +  assert( OPFLAG_BULKCSR==BTREE_BULKLOAD ); | 
| +  sqlite3BtreeCursorHints(pCur->pCursor, (pOp->p5 & OPFLAG_BULKCSR)); | 
|  | 
| -  /* Since it performs no memory allocation or IO, the only values that | 
| -  ** sqlite3BtreeCursor() may return are SQLITE_EMPTY and SQLITE_OK. | 
| -  ** SQLITE_EMPTY is only returned when attempting to open the table | 
| -  ** rooted at page 1 of a zero-byte database.  */ | 
| -  assert( rc==SQLITE_EMPTY || rc==SQLITE_OK ); | 
| -  if( rc==SQLITE_EMPTY ){ | 
| -    pCur->pCursor = 0; | 
| -    rc = SQLITE_OK; | 
| -  } | 
| - | 
| -  /* Set the VdbeCursor.isTable and isIndex variables. Previous versions of | 
| +  /* Set the VdbeCursor.isTable variable. Previous versions of | 
| ** SQLite used to check if the root-page flags were sane at this point | 
| ** and report database corruption if they were not, but this check has | 
| ** since moved into the btree layer.  */ | 
| pCur->isTable = pOp->p4type!=P4_KEYINFO; | 
| -  pCur->isIndex = !pCur->isTable; | 
| break; | 
| } | 
|  | 
| -/* Opcode: OpenEphemeral P1 P2 * P4 * | 
| +/* Opcode: OpenEphemeral P1 P2 * P4 P5 | 
| +** Synopsis: nColumn=P2 | 
| ** | 
| ** Open a new cursor P1 to a transient table. | 
| ** The cursor is always opened read/write even if | 
| @@ -3105,13 +3319,13 @@ case OP_OpenWrite: { | 
| ** if P4 is not 0.  If P4 is not NULL, it points to a KeyInfo structure | 
| ** that defines the format of keys in the index. | 
| ** | 
| -** This opcode was once called OpenTemp.  But that created | 
| -** confusion because the term "temp table", might refer either | 
| -** to a TEMP table at the SQL level, or to a table opened by | 
| -** this opcode.  Then this opcode was call OpenVirtual.  But | 
| -** that created confusion with the whole virtual-table idea. | 
| +** The P5 parameter can be a mask of the BTREE_* flags defined | 
| +** in btree.h.  These flags control aspects of the operation of | 
| +** the btree.  The BTREE_OMIT_JOURNAL and BTREE_SINGLE flags are | 
| +** added automatically. | 
| */ | 
| /* Opcode: OpenAutoindex P1 P2 * P4 * | 
| +** Synopsis: nColumn=P2 | 
| ** | 
| ** This opcode works the same as OP_OpenEphemeral.  It has a | 
| ** different name to distinguish its use.  Tables created using | 
| @@ -3121,18 +3335,21 @@ case OP_OpenWrite: { | 
| case OP_OpenAutoindex: | 
| case OP_OpenEphemeral: { | 
| VdbeCursor *pCx; | 
| +  KeyInfo *pKeyInfo; | 
| + | 
| static const int vfsFlags = | 
| SQLITE_OPEN_READWRITE | | 
| SQLITE_OPEN_CREATE | | 
| SQLITE_OPEN_EXCLUSIVE | | 
| SQLITE_OPEN_DELETEONCLOSE | | 
| SQLITE_OPEN_TRANSIENT_DB; | 
| - | 
| assert( pOp->p1>=0 ); | 
| +  assert( pOp->p2>=0 ); | 
| pCx = allocateCursor(p, pOp->p1, pOp->p2, -1, 1); | 
| if( pCx==0 ) goto no_mem; | 
| pCx->nullRow = 1; | 
| -  rc = sqlite3BtreeOpen(0, db, &pCx->pBt, | 
| +  pCx->isEphemeral = 1; | 
| +  rc = sqlite3BtreeOpen(db->pVfs, 0, db, &pCx->pBt, | 
| BTREE_OMIT_JOURNAL | BTREE_SINGLE | pOp->p5, vfsFlags); | 
| if( rc==SQLITE_OK ){ | 
| rc = sqlite3BtreeBeginTrans(pCx->pBt, 1); | 
| @@ -3143,16 +3360,16 @@ case OP_OpenEphemeral: { | 
| ** opening it. If a transient table is required, just use the | 
| ** automatically created table with root-page 1 (an BLOB_INTKEY table). | 
| */ | 
| -    if( pOp->p4.pKeyInfo ){ | 
| +    if( (pKeyInfo = pOp->p4.pKeyInfo)!=0 ){ | 
| int pgno; | 
| assert( pOp->p4type==P4_KEYINFO ); | 
| -      rc = sqlite3BtreeCreateTable(pCx->pBt, &pgno, BTREE_BLOBKEY); | 
| +      rc = sqlite3BtreeCreateTable(pCx->pBt, &pgno, BTREE_BLOBKEY | pOp->p5); | 
| if( rc==SQLITE_OK ){ | 
| assert( pgno==MASTER_ROOT+1 ); | 
| -        rc = sqlite3BtreeCursor(pCx->pBt, pgno, 1, | 
| -                                (KeyInfo*)pOp->p4.z, pCx->pCursor); | 
| -        pCx->pKeyInfo = pOp->p4.pKeyInfo; | 
| -        pCx->pKeyInfo->enc = ENC(p->db); | 
| +        assert( pKeyInfo->db==db ); | 
| +        assert( pKeyInfo->enc==ENC(db) ); | 
| +        pCx->pKeyInfo = pKeyInfo; | 
| +        rc = sqlite3BtreeCursor(pCx->pBt, pgno, 1, pKeyInfo, pCx->pCursor); | 
| } | 
| pCx->isTable = 0; | 
| }else{ | 
| @@ -3161,14 +3378,56 @@ case OP_OpenEphemeral: { | 
| } | 
| } | 
| pCx->isOrdered = (pOp->p5!=BTREE_UNORDERED); | 
| -  pCx->isIndex = !pCx->isTable; | 
| +  break; | 
| +} | 
| + | 
| +/* Opcode: SorterOpen P1 P2 P3 P4 * | 
| +** | 
| +** This opcode works like OP_OpenEphemeral except that it opens | 
| +** a transient index that is specifically designed to sort large | 
| +** tables using an external merge-sort algorithm. | 
| +** | 
| +** If argument P3 is non-zero, then it indicates that the sorter may | 
| +** assume that a stable sort considering the first P3 fields of each | 
| +** key is sufficient to produce the required results. | 
| +*/ | 
| +case OP_SorterOpen: { | 
| +  VdbeCursor *pCx; | 
| + | 
| +  assert( pOp->p1>=0 ); | 
| +  assert( pOp->p2>=0 ); | 
| +  pCx = allocateCursor(p, pOp->p1, pOp->p2, -1, 1); | 
| +  if( pCx==0 ) goto no_mem; | 
| +  pCx->pKeyInfo = pOp->p4.pKeyInfo; | 
| +  assert( pCx->pKeyInfo->db==db ); | 
| +  assert( pCx->pKeyInfo->enc==ENC(db) ); | 
| +  rc = sqlite3VdbeSorterInit(db, pOp->p3, pCx); | 
| +  break; | 
| +} | 
| + | 
| +/* Opcode: SequenceTest P1 P2 * * * | 
| +** Synopsis: if( cursor[P1].ctr++ ) pc = P2 | 
| +** | 
| +** P1 is a sorter cursor. If the sequence counter is currently zero, jump | 
| +** to P2. Regardless of whether or not the jump is taken, increment the | 
| +** the sequence value. | 
| +*/ | 
| +case OP_SequenceTest: { | 
| +  VdbeCursor *pC; | 
| +  assert( pOp->p1>=0 && pOp->p1<p->nCursor ); | 
| +  pC = p->apCsr[pOp->p1]; | 
| +  assert( pC->pSorter ); | 
| +  if( (pC->seqCount++)==0 ){ | 
| +    pc = pOp->p2 - 1; | 
| +  } | 
| break; | 
| } | 
|  | 
| /* Opcode: OpenPseudo P1 P2 P3 * * | 
| +** Synopsis: P3 columns in r[P2] | 
| ** | 
| ** Open a new cursor that points to a fake table that contains a single | 
| -** row of data.  The content of that one row in the content of memory | 
| +** row of data.  The content of that one row is the content of memory | 
| ** register P2.  In other words, cursor P1 becomes an alias for the | 
| ** MEM_Blob content contained in register P2. | 
| ** | 
| @@ -3184,12 +3443,13 @@ case OP_OpenPseudo: { | 
| VdbeCursor *pCx; | 
|  | 
| assert( pOp->p1>=0 ); | 
| +  assert( pOp->p3>=0 ); | 
| pCx = allocateCursor(p, pOp->p1, pOp->p3, -1, 0); | 
| if( pCx==0 ) goto no_mem; | 
| pCx->nullRow = 1; | 
| pCx->pseudoTableReg = pOp->p2; | 
| pCx->isTable = 1; | 
| -  pCx->isIndex = 0; | 
| +  assert( pOp->p5==0 ); | 
| break; | 
| } | 
|  | 
| @@ -3205,7 +3465,8 @@ case OP_Close: { | 
| break; | 
| } | 
|  | 
| -/* Opcode: SeekGe P1 P2 P3 P4 * | 
| +/* Opcode: SeekGE P1 P2 P3 P4 * | 
| +** Synopsis: key=r[P3@P4] | 
| ** | 
| ** If cursor P1 refers to an SQL table (B-Tree that uses integer keys), | 
| ** use the value in register P3 as the key.  If cursor P1 refers | 
| @@ -3216,9 +3477,14 @@ case OP_Close: { | 
| ** is greater than or equal to the key value. If there are no records | 
| ** greater than or equal to the key and P2 is not zero, then jump to P2. | 
| ** | 
| -** See also: Found, NotFound, Distinct, SeekLt, SeekGt, SeekLe | 
| +** This opcode leaves the cursor configured to move in forward order, | 
| +** from the beginning toward the end.  In other words, the cursor is | 
| +** configured to use Next, not Prev. | 
| +** | 
| +** See also: Found, NotFound, SeekLt, SeekGt, SeekLe | 
| */ | 
| -/* Opcode: SeekGt P1 P2 P3 P4 * | 
| +/* Opcode: SeekGT P1 P2 P3 P4 * | 
| +** Synopsis: key=r[P3@P4] | 
| ** | 
| ** If cursor P1 refers to an SQL table (B-Tree that uses integer keys), | 
| ** use the value in register P3 as a key. If cursor P1 refers | 
| @@ -3229,9 +3495,14 @@ case OP_Close: { | 
| ** is greater than the key value. If there are no records greater than | 
| ** the key and P2 is not zero, then jump to P2. | 
| ** | 
| -** See also: Found, NotFound, Distinct, SeekLt, SeekGe, SeekLe | 
| +** This opcode leaves the cursor configured to move in forward order, | 
| +** from the beginning toward the end.  In other words, the cursor is | 
| +** configured to use Next, not Prev. | 
| +** | 
| +** See also: Found, NotFound, SeekLt, SeekGe, SeekLe | 
| */ | 
| -/* Opcode: SeekLt P1 P2 P3 P4 * | 
| +/* Opcode: SeekLT P1 P2 P3 P4 * | 
| +** Synopsis: key=r[P3@P4] | 
| ** | 
| ** If cursor P1 refers to an SQL table (B-Tree that uses integer keys), | 
| ** use the value in register P3 as a key. If cursor P1 refers | 
| @@ -3242,9 +3513,14 @@ case OP_Close: { | 
| ** is less than the key value. If there are no records less than | 
| ** the key and P2 is not zero, then jump to P2. | 
| ** | 
| -** See also: Found, NotFound, Distinct, SeekGt, SeekGe, SeekLe | 
| +** This opcode leaves the cursor configured to move in reverse order, | 
| +** from the end toward the beginning.  In other words, the cursor is | 
| +** configured to use Prev, not Next. | 
| +** | 
| +** See also: Found, NotFound, SeekGt, SeekGe, SeekLe | 
| */ | 
| -/* Opcode: SeekLe P1 P2 P3 P4 * | 
| +/* Opcode: SeekLE P1 P2 P3 P4 * | 
| +** Synopsis: key=r[P3@P4] | 
| ** | 
| ** If cursor P1 refers to an SQL table (B-Tree that uses integer keys), | 
| ** use the value in register P3 as a key. If cursor P1 refers | 
| @@ -3255,12 +3531,16 @@ case OP_Close: { | 
| ** is less than or equal to the key value. If there are no records | 
| ** less than or equal to the key and P2 is not zero, then jump to P2. | 
| ** | 
| -** See also: Found, NotFound, Distinct, SeekGt, SeekGe, SeekLt | 
| +** This opcode leaves the cursor configured to move in reverse order, | 
| +** from the end toward the beginning.  In other words, the cursor is | 
| +** configured to use Prev, not Next. | 
| +** | 
| +** See also: Found, NotFound, SeekGt, SeekGe, SeekLt | 
| */ | 
| -case OP_SeekLt:         /* jump, in3 */ | 
| -case OP_SeekLe:         /* jump, in3 */ | 
| -case OP_SeekGe:         /* jump, in3 */ | 
| -case OP_SeekGt: {       /* jump, in3 */ | 
| +case OP_SeekLT:         /* jump, in3 */ | 
| +case OP_SeekLE:         /* jump, in3 */ | 
| +case OP_SeekGE:         /* jump, in3 */ | 
| +case OP_SeekGT: {       /* jump, in3 */ | 
| int res; | 
| int oc; | 
| VdbeCursor *pC; | 
| @@ -3273,143 +3553,130 @@ case OP_SeekGt: {       /* jump, in3 */ | 
| pC = p->apCsr[pOp->p1]; | 
| assert( pC!=0 ); | 
| assert( pC->pseudoTableReg==0 ); | 
| -  assert( OP_SeekLe == OP_SeekLt+1 ); | 
| -  assert( OP_SeekGe == OP_SeekLt+2 ); | 
| -  assert( OP_SeekGt == OP_SeekLt+3 ); | 
| +  assert( OP_SeekLE == OP_SeekLT+1 ); | 
| +  assert( OP_SeekGE == OP_SeekLT+2 ); | 
| +  assert( OP_SeekGT == OP_SeekLT+3 ); | 
| assert( pC->isOrdered ); | 
| -  if( pC->pCursor!=0 ){ | 
| -    oc = pOp->opcode; | 
| -    pC->nullRow = 0; | 
| -    if( pC->isTable ){ | 
| -      /* The input value in P3 might be of any type: integer, real, string, | 
| -      ** blob, or NULL.  But it needs to be an integer before we can do | 
| -      ** the seek, so covert it. */ | 
| -      pIn3 = &aMem[pOp->p3]; | 
| -      applyNumericAffinity(pIn3); | 
| -      iKey = sqlite3VdbeIntValue(pIn3); | 
| -      pC->rowidIsValid = 0; | 
| - | 
| -      /* If the P3 value could not be converted into an integer without | 
| -      ** loss of information, then special processing is required... */ | 
| -      if( (pIn3->flags & MEM_Int)==0 ){ | 
| -        if( (pIn3->flags & MEM_Real)==0 ){ | 
| -          /* If the P3 value cannot be converted into any kind of a number, | 
| -          ** then the seek is not possible, so jump to P2 */ | 
| -          pc = pOp->p2 - 1; | 
| -          break; | 
| -        } | 
| -        /* If we reach this point, then the P3 value must be a floating | 
| -        ** point number. */ | 
| -        assert( (pIn3->flags & MEM_Real)!=0 ); | 
| - | 
| -        if( iKey==SMALLEST_INT64 && (pIn3->r<(double)iKey || pIn3->r>0) ){ | 
| -          /* The P3 value is too large in magnitude to be expressed as an | 
| -          ** integer. */ | 
| -          res = 1; | 
| -          if( pIn3->r<0 ){ | 
| -            if( oc>=OP_SeekGe ){  assert( oc==OP_SeekGe || oc==OP_SeekGt ); | 
| -              rc = sqlite3BtreeFirst(pC->pCursor, &res); | 
| -              if( rc!=SQLITE_OK ) goto abort_due_to_error; | 
| -            } | 
| -          }else{ | 
| -            if( oc<=OP_SeekLe ){  assert( oc==OP_SeekLt || oc==OP_SeekLe ); | 
| -              rc = sqlite3BtreeLast(pC->pCursor, &res); | 
| -              if( rc!=SQLITE_OK ) goto abort_due_to_error; | 
| -            } | 
| -          } | 
| -          if( res ){ | 
| -            pc = pOp->p2 - 1; | 
| -          } | 
| -          break; | 
| -        }else if( oc==OP_SeekLt || oc==OP_SeekGe ){ | 
| -          /* Use the ceiling() function to convert real->int */ | 
| -          if( pIn3->r > (double)iKey ) iKey++; | 
| -        }else{ | 
| -          /* Use the floor() function to convert real->int */ | 
| -          assert( oc==OP_SeekLe || oc==OP_SeekGt ); | 
| -          if( pIn3->r < (double)iKey ) iKey--; | 
| -        } | 
| -      } | 
| -      rc = sqlite3BtreeMovetoUnpacked(pC->pCursor, 0, (u64)iKey, 0, &res); | 
| -      if( rc!=SQLITE_OK ){ | 
| -        goto abort_due_to_error; | 
| -      } | 
| -      if( res==0 ){ | 
| -        pC->rowidIsValid = 1; | 
| -        pC->lastRowid = iKey; | 
| +  assert( pC->pCursor!=0 ); | 
| +  oc = pOp->opcode; | 
| +  pC->nullRow = 0; | 
| +#ifdef SQLITE_DEBUG | 
| +  pC->seekOp = pOp->opcode; | 
| +#endif | 
| +  if( pC->isTable ){ | 
| +    /* The input value in P3 might be of any type: integer, real, string, | 
| +    ** blob, or NULL.  But it needs to be an integer before we can do | 
| +    ** the seek, so convert it. */ | 
| +    pIn3 = &aMem[pOp->p3]; | 
| +    if( (pIn3->flags & (MEM_Int|MEM_Real|MEM_Str))==MEM_Str ){ | 
| +      applyNumericAffinity(pIn3, 0); | 
| +    } | 
| +    iKey = sqlite3VdbeIntValue(pIn3); | 
| + | 
| +    /* If the P3 value could not be converted into an integer without | 
| +    ** loss of information, then special processing is required... */ | 
| +    if( (pIn3->flags & MEM_Int)==0 ){ | 
| +      if( (pIn3->flags & MEM_Real)==0 ){ | 
| +        /* If the P3 value cannot be converted into any kind of a number, | 
| +        ** then the seek is not possible, so jump to P2 */ | 
| +        pc = pOp->p2 - 1;  VdbeBranchTaken(1,2); | 
| +        break; | 
| } | 
| -    }else{ | 
| -      nField = pOp->p4.i; | 
| -      assert( pOp->p4type==P4_INT32 ); | 
| -      assert( nField>0 ); | 
| -      r.pKeyInfo = pC->pKeyInfo; | 
| -      r.nField = (u16)nField; | 
| - | 
| -      /* The next line of code computes as follows, only faster: | 
| -      **   if( oc==OP_SeekGt || oc==OP_SeekLe ){ | 
| -      **     r.flags = UNPACKED_INCRKEY; | 
| -      **   }else{ | 
| -      **     r.flags = 0; | 
| -      **   } | 
| + | 
| +      /* If the approximation iKey is larger than the actual real search | 
| +      ** term, substitute >= for > and < for <=. e.g. if the search term | 
| +      ** is 4.9 and the integer approximation 5: | 
| +      ** | 
| +      **        (x >  4.9)    ->     (x >= 5) | 
| +      **        (x <= 4.9)    ->     (x <  5) | 
| */ | 
| -      r.flags = (u16)(UNPACKED_INCRKEY * (1 & (oc - OP_SeekLt))); | 
| -      assert( oc!=OP_SeekGt || r.flags==UNPACKED_INCRKEY ); | 
| -      assert( oc!=OP_SeekLe || r.flags==UNPACKED_INCRKEY ); | 
| -      assert( oc!=OP_SeekGe || r.flags==0 ); | 
| -      assert( oc!=OP_SeekLt || r.flags==0 ); | 
| +      if( pIn3->u.r<(double)iKey ){ | 
| +        assert( OP_SeekGE==(OP_SeekGT-1) ); | 
| +        assert( OP_SeekLT==(OP_SeekLE-1) ); | 
| +        assert( (OP_SeekLE & 0x0001)==(OP_SeekGT & 0x0001) ); | 
| +        if( (oc & 0x0001)==(OP_SeekGT & 0x0001) ) oc--; | 
| +      } | 
| + | 
| +      /* If the approximation iKey is smaller than the actual real search | 
| +      ** term, substitute <= for < and > for >=.  */ | 
| +      else if( pIn3->u.r>(double)iKey ){ | 
| +        assert( OP_SeekLE==(OP_SeekLT+1) ); | 
| +        assert( OP_SeekGT==(OP_SeekGE+1) ); | 
| +        assert( (OP_SeekLT & 0x0001)==(OP_SeekGE & 0x0001) ); | 
| +        if( (oc & 0x0001)==(OP_SeekLT & 0x0001) ) oc++; | 
| +      } | 
| +    } | 
| +    rc = sqlite3BtreeMovetoUnpacked(pC->pCursor, 0, (u64)iKey, 0, &res); | 
| +    pC->movetoTarget = iKey;  /* Used by OP_Delete */ | 
| +    if( rc!=SQLITE_OK ){ | 
| +      goto abort_due_to_error; | 
| +    } | 
| +  }else{ | 
| +    nField = pOp->p4.i; | 
| +    assert( pOp->p4type==P4_INT32 ); | 
| +    assert( nField>0 ); | 
| +    r.pKeyInfo = pC->pKeyInfo; | 
| +    r.nField = (u16)nField; | 
| + | 
| +    /* The next line of code computes as follows, only faster: | 
| +    **   if( oc==OP_SeekGT || oc==OP_SeekLE ){ | 
| +    **     r.default_rc = -1; | 
| +    **   }else{ | 
| +    **     r.default_rc = +1; | 
| +    **   } | 
| +    */ | 
| +    r.default_rc = ((1 & (oc - OP_SeekLT)) ? -1 : +1); | 
| +    assert( oc!=OP_SeekGT || r.default_rc==-1 ); | 
| +    assert( oc!=OP_SeekLE || r.default_rc==-1 ); | 
| +    assert( oc!=OP_SeekGE || r.default_rc==+1 ); | 
| +    assert( oc!=OP_SeekLT || r.default_rc==+1 ); | 
|  | 
| -      r.aMem = &aMem[pOp->p3]; | 
| +    r.aMem = &aMem[pOp->p3]; | 
| #ifdef SQLITE_DEBUG | 
| -      { int i; for(i=0; i<r.nField; i++) assert( memIsValid(&r.aMem[i]) ); } | 
| +    { int i; for(i=0; i<r.nField; i++) assert( memIsValid(&r.aMem[i]) ); } | 
| #endif | 
| -      ExpandBlob(r.aMem); | 
| -      rc = sqlite3BtreeMovetoUnpacked(pC->pCursor, &r, 0, 0, &res); | 
| -      if( rc!=SQLITE_OK ){ | 
| -        goto abort_due_to_error; | 
| -      } | 
| -      pC->rowidIsValid = 0; | 
| +    ExpandBlob(r.aMem); | 
| +    rc = sqlite3BtreeMovetoUnpacked(pC->pCursor, &r, 0, 0, &res); | 
| +    if( rc!=SQLITE_OK ){ | 
| +      goto abort_due_to_error; | 
| } | 
| -    pC->deferredMoveto = 0; | 
| -    pC->cacheStatus = CACHE_STALE; | 
| +  } | 
| +  pC->deferredMoveto = 0; | 
| +  pC->cacheStatus = CACHE_STALE; | 
| #ifdef SQLITE_TEST | 
| -    sqlite3_search_count++; | 
| +  sqlite3_search_count++; | 
| #endif | 
| -    if( oc>=OP_SeekGe ){  assert( oc==OP_SeekGe || oc==OP_SeekGt ); | 
| -      if( res<0 || (res==0 && oc==OP_SeekGt) ){ | 
| -        rc = sqlite3BtreeNext(pC->pCursor, &res); | 
| -        if( rc!=SQLITE_OK ) goto abort_due_to_error; | 
| -        pC->rowidIsValid = 0; | 
| -      }else{ | 
| -        res = 0; | 
| -      } | 
| +  if( oc>=OP_SeekGE ){  assert( oc==OP_SeekGE || oc==OP_SeekGT ); | 
| +    if( res<0 || (res==0 && oc==OP_SeekGT) ){ | 
| +      res = 0; | 
| +      rc = sqlite3BtreeNext(pC->pCursor, &res); | 
| +      if( rc!=SQLITE_OK ) goto abort_due_to_error; | 
| }else{ | 
| -      assert( oc==OP_SeekLt || oc==OP_SeekLe ); | 
| -      if( res>0 || (res==0 && oc==OP_SeekLt) ){ | 
| -        rc = sqlite3BtreePrevious(pC->pCursor, &res); | 
| -        if( rc!=SQLITE_OK ) goto abort_due_to_error; | 
| -        pC->rowidIsValid = 0; | 
| -      }else{ | 
| -        /* res might be negative because the table is empty.  Check to | 
| -        ** see if this is the case. | 
| -        */ | 
| -        res = sqlite3BtreeEof(pC->pCursor); | 
| -      } | 
| -    } | 
| -    assert( pOp->p2>0 ); | 
| -    if( res ){ | 
| -      pc = pOp->p2 - 1; | 
| +      res = 0; | 
| } | 
| }else{ | 
| -    /* This happens when attempting to open the sqlite3_master table | 
| -    ** for read access returns SQLITE_EMPTY. In this case always | 
| -    ** take the jump (since there are no records in the table). | 
| -    */ | 
| +    assert( oc==OP_SeekLT || oc==OP_SeekLE ); | 
| +    if( res>0 || (res==0 && oc==OP_SeekLT) ){ | 
| +      res = 0; | 
| +      rc = sqlite3BtreePrevious(pC->pCursor, &res); | 
| +      if( rc!=SQLITE_OK ) goto abort_due_to_error; | 
| +    }else{ | 
| +      /* res might be negative because the table is empty.  Check to | 
| +      ** see if this is the case. | 
| +      */ | 
| +      res = sqlite3BtreeEof(pC->pCursor); | 
| +    } | 
| +  } | 
| +  assert( pOp->p2>0 ); | 
| +  VdbeBranchTaken(res!=0,2); | 
| +  if( res ){ | 
| pc = pOp->p2 - 1; | 
| } | 
| break; | 
| } | 
|  | 
| /* Opcode: Seek P1 P2 * * * | 
| +** Synopsis:  intkey=r[P2] | 
| ** | 
| ** P1 is an open table cursor and P2 is a rowid integer.  Arrange | 
| ** for P1 to move so that it points to the rowid given by P2. | 
| @@ -3424,19 +3691,18 @@ case OP_Seek: {    /* in2 */ | 
| assert( pOp->p1>=0 && pOp->p1<p->nCursor ); | 
| pC = p->apCsr[pOp->p1]; | 
| assert( pC!=0 ); | 
| -  if( ALWAYS(pC->pCursor!=0) ){ | 
| -    assert( pC->isTable ); | 
| -    pC->nullRow = 0; | 
| -    pIn2 = &aMem[pOp->p2]; | 
| -    pC->movetoTarget = sqlite3VdbeIntValue(pIn2); | 
| -    pC->rowidIsValid = 0; | 
| -    pC->deferredMoveto = 1; | 
| -  } | 
| +  assert( pC->pCursor!=0 ); | 
| +  assert( pC->isTable ); | 
| +  pC->nullRow = 0; | 
| +  pIn2 = &aMem[pOp->p2]; | 
| +  pC->movetoTarget = sqlite3VdbeIntValue(pIn2); | 
| +  pC->deferredMoveto = 1; | 
| break; | 
| } | 
|  | 
|  | 
| /* Opcode: Found P1 P2 P3 P4 * | 
| +** Synopsis: key=r[P3@P4] | 
| ** | 
| ** If P4==0 then register P3 holds a blob constructed by MakeRecord.  If | 
| ** P4>0 then register P3 is the first of P4 registers that form an unpacked | 
| @@ -3445,8 +3711,15 @@ case OP_Seek: {    /* in2 */ | 
| ** Cursor P1 is on an index btree.  If the record identified by P3 and P4 | 
| ** is a prefix of any entry in P1 then a jump is made to P2 and | 
| ** P1 is left pointing at the matching entry. | 
| +** | 
| +** This operation leaves the cursor in a state where it can be | 
| +** advanced in the forward direction.  The Next instruction will work, | 
| +** but not the Prev instruction. | 
| +** | 
| +** See also: NotFound, NoConflict, NotExists. SeekGe | 
| */ | 
| /* Opcode: NotFound P1 P2 P3 P4 * | 
| +** Synopsis: key=r[P3@P4] | 
| ** | 
| ** If P4==0 then register P3 holds a blob constructed by MakeRecord.  If | 
| ** P4>0 then register P3 is the first of P4 registers that form an unpacked | 
| @@ -3458,168 +3731,134 @@ case OP_Seek: {    /* in2 */ | 
| ** falls through to the next instruction and P1 is left pointing at the | 
| ** matching entry. | 
| ** | 
| -** See also: Found, NotExists, IsUnique | 
| +** This operation leaves the cursor in a state where it cannot be | 
| +** advanced in either direction.  In other words, the Next and Prev | 
| +** opcodes do not work after this operation. | 
| +** | 
| +** See also: Found, NotExists, NoConflict | 
| +*/ | 
| +/* Opcode: NoConflict P1 P2 P3 P4 * | 
| +** Synopsis: key=r[P3@P4] | 
| +** | 
| +** If P4==0 then register P3 holds a blob constructed by MakeRecord.  If | 
| +** P4>0 then register P3 is the first of P4 registers that form an unpacked | 
| +** record. | 
| +** | 
| +** Cursor P1 is on an index btree.  If the record identified by P3 and P4 | 
| +** contains any NULL value, jump immediately to P2.  If all terms of the | 
| +** record are not-NULL then a check is done to determine if any row in the | 
| +** P1 index btree has a matching key prefix.  If there are no matches, jump | 
| +** immediately to P2.  If there is a match, fall through and leave the P1 | 
| +** cursor pointing to the matching row. | 
| +** | 
| +** This opcode is similar to OP_NotFound with the exceptions that the | 
| +** branch is always taken if any part of the search key input is NULL. | 
| +** | 
| +** This operation leaves the cursor in a state where it cannot be | 
| +** advanced in either direction.  In other words, the Next and Prev | 
| +** opcodes do not work after this operation. | 
| +** | 
| +** See also: NotFound, Found, NotExists | 
| */ | 
| +case OP_NoConflict:     /* jump, in3 */ | 
| case OP_NotFound:       /* jump, in3 */ | 
| case OP_Found: {        /* jump, in3 */ | 
| int alreadyExists; | 
| +  int ii; | 
| VdbeCursor *pC; | 
| int res; | 
| +  char *pFree; | 
| UnpackedRecord *pIdxKey; | 
| UnpackedRecord r; | 
| -  char aTempRec[ROUND8(sizeof(UnpackedRecord)) + sizeof(Mem)*3 + 7]; | 
| +  char aTempRec[ROUND8(sizeof(UnpackedRecord)) + sizeof(Mem)*4 + 7]; | 
|  | 
| #ifdef SQLITE_TEST | 
| -  sqlite3_found_count++; | 
| +  if( pOp->opcode!=OP_NoConflict ) sqlite3_found_count++; | 
| #endif | 
|  | 
| -  alreadyExists = 0; | 
| assert( pOp->p1>=0 && pOp->p1<p->nCursor ); | 
| assert( pOp->p4type==P4_INT32 ); | 
| pC = p->apCsr[pOp->p1]; | 
| assert( pC!=0 ); | 
| +#ifdef SQLITE_DEBUG | 
| +  pC->seekOp = pOp->opcode; | 
| +#endif | 
| pIn3 = &aMem[pOp->p3]; | 
| -  if( ALWAYS(pC->pCursor!=0) ){ | 
| - | 
| -    assert( pC->isTable==0 ); | 
| -    if( pOp->p4.i>0 ){ | 
| -      r.pKeyInfo = pC->pKeyInfo; | 
| -      r.nField = (u16)pOp->p4.i; | 
| -      r.aMem = pIn3; | 
| +  assert( pC->pCursor!=0 ); | 
| +  assert( pC->isTable==0 ); | 
| +  pFree = 0;  /* Not needed.  Only used to suppress a compiler warning. */ | 
| +  if( pOp->p4.i>0 ){ | 
| +    r.pKeyInfo = pC->pKeyInfo; | 
| +    r.nField = (u16)pOp->p4.i; | 
| +    r.aMem = pIn3; | 
| +    for(ii=0; ii<r.nField; ii++){ | 
| +      assert( memIsValid(&r.aMem[ii]) ); | 
| +      ExpandBlob(&r.aMem[ii]); | 
| #ifdef SQLITE_DEBUG | 
| -      { int i; for(i=0; i<r.nField; i++) assert( memIsValid(&r.aMem[i]) ); } | 
| +      if( ii ) REGISTER_TRACE(pOp->p3+ii, &r.aMem[ii]); | 
| #endif | 
| -      r.flags = UNPACKED_PREFIX_MATCH; | 
| -      pIdxKey = &r; | 
| -    }else{ | 
| -      assert( pIn3->flags & MEM_Blob ); | 
| -      assert( (pIn3->flags & MEM_Zero)==0 );  /* zeroblobs already expanded */ | 
| -      pIdxKey = sqlite3VdbeRecordUnpack(pC->pKeyInfo, pIn3->n, pIn3->z, | 
| -                                        aTempRec, sizeof(aTempRec)); | 
| -      if( pIdxKey==0 ){ | 
| -        goto no_mem; | 
| -      } | 
| -      pIdxKey->flags |= UNPACKED_PREFIX_MATCH; | 
| } | 
| -    rc = sqlite3BtreeMovetoUnpacked(pC->pCursor, pIdxKey, 0, 0, &res); | 
| -    if( pOp->p4.i==0 ){ | 
| -      sqlite3VdbeDeleteUnpackedRecord(pIdxKey); | 
| -    } | 
| -    if( rc!=SQLITE_OK ){ | 
| -      break; | 
| +    pIdxKey = &r; | 
| +  }else{ | 
| +    pIdxKey = sqlite3VdbeAllocUnpackedRecord( | 
| +        pC->pKeyInfo, aTempRec, sizeof(aTempRec), &pFree | 
| +    ); | 
| +    if( pIdxKey==0 ) goto no_mem; | 
| +    assert( pIn3->flags & MEM_Blob ); | 
| +    assert( (pIn3->flags & MEM_Zero)==0 );  /* zeroblobs already expanded */ | 
| +    sqlite3VdbeRecordUnpack(pC->pKeyInfo, pIn3->n, pIn3->z, pIdxKey); | 
| +  } | 
| +  pIdxKey->default_rc = 0; | 
| +  if( pOp->opcode==OP_NoConflict ){ | 
| +    /* For the OP_NoConflict opcode, take the jump if any of the | 
| +    ** input fields are NULL, since any key with a NULL will not | 
| +    ** conflict */ | 
| +    for(ii=0; ii<r.nField; ii++){ | 
| +      if( r.aMem[ii].flags & MEM_Null ){ | 
| +        pc = pOp->p2 - 1; VdbeBranchTaken(1,2); | 
| +        break; | 
| +      } | 
| } | 
| -    alreadyExists = (res==0); | 
| -    pC->deferredMoveto = 0; | 
| -    pC->cacheStatus = CACHE_STALE; | 
| } | 
| -  if( pOp->opcode==OP_Found ){ | 
| -    if( alreadyExists ) pc = pOp->p2 - 1; | 
| -  }else{ | 
| -    if( !alreadyExists ) pc = pOp->p2 - 1; | 
| +  rc = sqlite3BtreeMovetoUnpacked(pC->pCursor, pIdxKey, 0, 0, &res); | 
| +  if( pOp->p4.i==0 ){ | 
| +    sqlite3DbFree(db, pFree); | 
| } | 
| -  break; | 
| -} | 
| - | 
| -/* Opcode: IsUnique P1 P2 P3 P4 * | 
| -** | 
| -** Cursor P1 is open on an index b-tree - that is to say, a btree which | 
| -** no data and where the key are records generated by OP_MakeRecord with | 
| -** the list field being the integer ROWID of the entry that the index | 
| -** entry refers to. | 
| -** | 
| -** The P3 register contains an integer record number. Call this record | 
| -** number R. Register P4 is the first in a set of N contiguous registers | 
| -** that make up an unpacked index key that can be used with cursor P1. | 
| -** The value of N can be inferred from the cursor. N includes the rowid | 
| -** value appended to the end of the index record. This rowid value may | 
| -** or may not be the same as R. | 
| -** | 
| -** If any of the N registers beginning with register P4 contains a NULL | 
| -** value, jump immediately to P2. | 
| -** | 
| -** Otherwise, this instruction checks if cursor P1 contains an entry | 
| -** where the first (N-1) fields match but the rowid value at the end | 
| -** of the index entry is not R. If there is no such entry, control jumps | 
| -** to instruction P2. Otherwise, the rowid of the conflicting index | 
| -** entry is copied to register P3 and control falls through to the next | 
| -** instruction. | 
| -** | 
| -** See also: NotFound, NotExists, Found | 
| -*/ | 
| -case OP_IsUnique: {        /* jump, in3 */ | 
| -  u16 ii; | 
| -  VdbeCursor *pCx; | 
| -  BtCursor *pCrsr; | 
| -  u16 nField; | 
| -  Mem *aMx; | 
| -  UnpackedRecord r;                  /* B-Tree index search key */ | 
| -  i64 R;                             /* Rowid stored in register P3 */ | 
| - | 
| -  pIn3 = &aMem[pOp->p3]; | 
| -  aMx = &aMem[pOp->p4.i]; | 
| -  /* Assert that the values of parameters P1 and P4 are in range. */ | 
| -  assert( pOp->p4type==P4_INT32 ); | 
| -  assert( pOp->p4.i>0 && pOp->p4.i<=p->nMem ); | 
| -  assert( pOp->p1>=0 && pOp->p1<p->nCursor ); | 
| - | 
| -  /* Find the index cursor. */ | 
| -  pCx = p->apCsr[pOp->p1]; | 
| -  assert( pCx->deferredMoveto==0 ); | 
| -  pCx->seekResult = 0; | 
| -  pCx->cacheStatus = CACHE_STALE; | 
| -  pCrsr = pCx->pCursor; | 
| - | 
| -  /* If any of the values are NULL, take the jump. */ | 
| -  nField = pCx->pKeyInfo->nField; | 
| -  for(ii=0; ii<nField; ii++){ | 
| -    if( aMx[ii].flags & MEM_Null ){ | 
| -      pc = pOp->p2 - 1; | 
| -      pCrsr = 0; | 
| -      break; | 
| -    } | 
| +  if( rc!=SQLITE_OK ){ | 
| +    break; | 
| } | 
| -  assert( (aMx[nField].flags & MEM_Null)==0 ); | 
| - | 
| -  if( pCrsr!=0 ){ | 
| -    /* Populate the index search key. */ | 
| -    r.pKeyInfo = pCx->pKeyInfo; | 
| -    r.nField = nField + 1; | 
| -    r.flags = UNPACKED_PREFIX_SEARCH; | 
| -    r.aMem = aMx; | 
| -#ifdef SQLITE_DEBUG | 
| -    { int i; for(i=0; i<r.nField; i++) assert( memIsValid(&r.aMem[i]) ); } | 
| -#endif | 
| - | 
| -    /* Extract the value of R from register P3. */ | 
| -    sqlite3VdbeMemIntegerify(pIn3); | 
| -    R = pIn3->u.i; | 
| - | 
| -    /* Search the B-Tree index. If no conflicting record is found, jump | 
| -    ** to P2. Otherwise, copy the rowid of the conflicting record to | 
| -    ** register P3 and fall through to the next instruction.  */ | 
| -    rc = sqlite3BtreeMovetoUnpacked(pCrsr, &r, 0, 0, &pCx->seekResult); | 
| -    if( (r.flags & UNPACKED_PREFIX_SEARCH) || r.rowid==R ){ | 
| -      pc = pOp->p2 - 1; | 
| -    }else{ | 
| -      pIn3->u.i = r.rowid; | 
| -    } | 
| +  pC->seekResult = res; | 
| +  alreadyExists = (res==0); | 
| +  pC->nullRow = 1-alreadyExists; | 
| +  pC->deferredMoveto = 0; | 
| +  pC->cacheStatus = CACHE_STALE; | 
| +  if( pOp->opcode==OP_Found ){ | 
| +    VdbeBranchTaken(alreadyExists!=0,2); | 
| +    if( alreadyExists ) pc = pOp->p2 - 1; | 
| +  }else{ | 
| +    VdbeBranchTaken(alreadyExists==0,2); | 
| +    if( !alreadyExists ) pc = pOp->p2 - 1; | 
| } | 
| break; | 
| } | 
|  | 
| /* Opcode: NotExists P1 P2 P3 * * | 
| +** Synopsis: intkey=r[P3] | 
| ** | 
| -** Use the content of register P3 as a integer key.  If a record | 
| -** with that key does not exist in table of P1, then jump to P2. | 
| -** If the record does exist, then fall through.  The cursor is left | 
| -** pointing to the record if it exists. | 
| +** P1 is the index of a cursor open on an SQL table btree (with integer | 
| +** keys).  P3 is an integer rowid.  If P1 does not contain a record with | 
| +** rowid P3 then jump immediately to P2.  If P1 does contain a record | 
| +** with rowid P3 then leave the cursor pointing at that record and fall | 
| +** through to the next instruction. | 
| ** | 
| -** The difference between this operation and NotFound is that this | 
| -** operation assumes the key is an integer and that P1 is a table whereas | 
| -** NotFound assumes key is a blob constructed from MakeRecord and | 
| -** P1 is an index. | 
| +** The OP_NotFound opcode performs the same operation on index btrees | 
| +** (with arbitrary multi-value keys). | 
| ** | 
| -** See also: Found, NotFound, IsUnique | 
| +** This opcode leaves the cursor in a state where it cannot be advanced | 
| +** in either direction.  In other words, the Next and Prev opcodes will | 
| +** not work following this opcode. | 
| +** | 
| +** See also: Found, NotFound, NoConflict | 
| */ | 
| case OP_NotExists: {        /* jump, in3 */ | 
| VdbeCursor *pC; | 
| @@ -3632,35 +3871,30 @@ case OP_NotExists: {        /* jump, in3 */ | 
| assert( pOp->p1>=0 && pOp->p1<p->nCursor ); | 
| pC = p->apCsr[pOp->p1]; | 
| assert( pC!=0 ); | 
| +#ifdef SQLITE_DEBUG | 
| +  pC->seekOp = 0; | 
| +#endif | 
| assert( pC->isTable ); | 
| assert( pC->pseudoTableReg==0 ); | 
| pCrsr = pC->pCursor; | 
| -  if( pCrsr!=0 ){ | 
| -    res = 0; | 
| -    iKey = pIn3->u.i; | 
| -    rc = sqlite3BtreeMovetoUnpacked(pCrsr, 0, iKey, 0, &res); | 
| -    pC->lastRowid = pIn3->u.i; | 
| -    pC->rowidIsValid = res==0 ?1:0; | 
| -    pC->nullRow = 0; | 
| -    pC->cacheStatus = CACHE_STALE; | 
| -    pC->deferredMoveto = 0; | 
| -    if( res!=0 ){ | 
| -      pc = pOp->p2 - 1; | 
| -      assert( pC->rowidIsValid==0 ); | 
| -    } | 
| -    pC->seekResult = res; | 
| -  }else{ | 
| -    /* This happens when an attempt to open a read cursor on the | 
| -    ** sqlite_master table returns SQLITE_EMPTY. | 
| -    */ | 
| +  assert( pCrsr!=0 ); | 
| +  res = 0; | 
| +  iKey = pIn3->u.i; | 
| +  rc = sqlite3BtreeMovetoUnpacked(pCrsr, 0, iKey, 0, &res); | 
| +  pC->movetoTarget = iKey;  /* Used by OP_Delete */ | 
| +  pC->nullRow = 0; | 
| +  pC->cacheStatus = CACHE_STALE; | 
| +  pC->deferredMoveto = 0; | 
| +  VdbeBranchTaken(res!=0,2); | 
| +  if( res!=0 ){ | 
| pc = pOp->p2 - 1; | 
| -    assert( pC->rowidIsValid==0 ); | 
| -    pC->seekResult = 0; | 
| } | 
| +  pC->seekResult = res; | 
| break; | 
| } | 
|  | 
| /* Opcode: Sequence P1 P2 * * * | 
| +** Synopsis: r[P2]=cursor[P1].ctr++ | 
| ** | 
| ** Find the next available sequence number for cursor P1. | 
| ** Write the sequence number into register P2. | 
| @@ -3676,6 +3910,7 @@ case OP_Sequence: {           /* out2-prerelease */ | 
|  | 
|  | 
| /* Opcode: NewRowid P1 P2 P3 * * | 
| +** Synopsis: r[P2]=rowid | 
| ** | 
| ** Get a new integer record number (a.k.a "rowid") used as the key to a table. | 
| ** The record number is not previously used as a key in the database | 
| @@ -3685,7 +3920,7 @@ case OP_Sequence: {           /* out2-prerelease */ | 
| ** If P3>0 then P3 is a register in the root frame of this VDBE that holds | 
| ** the largest previously generated record number. No new record numbers are | 
| ** allowed to be less than this value. When this value reaches its maximum, | 
| -** a SQLITE_FULL error is generated. The P3 register is updated with the ' | 
| +** an SQLITE_FULL error is generated. The P3 register is updated with the ' | 
| ** generated record number. This P3 mechanism is used to help implement the | 
| ** AUTOINCREMENT feature. | 
| */ | 
| @@ -3731,59 +3966,54 @@ case OP_NewRowid: {           /* out2-prerelease */ | 
| #endif | 
|  | 
| if( !pC->useRandomRowid ){ | 
| -      v = sqlite3BtreeGetCachedRowid(pC->pCursor); | 
| -      if( v==0 ){ | 
| -        rc = sqlite3BtreeLast(pC->pCursor, &res); | 
| -        if( rc!=SQLITE_OK ){ | 
| -          goto abort_due_to_error; | 
| -        } | 
| -        if( res ){ | 
| -          v = 1;   /* IMP: R-61914-48074 */ | 
| +      rc = sqlite3BtreeLast(pC->pCursor, &res); | 
| +      if( rc!=SQLITE_OK ){ | 
| +        goto abort_due_to_error; | 
| +      } | 
| +      if( res ){ | 
| +        v = 1;   /* IMP: R-61914-48074 */ | 
| +      }else{ | 
| +        assert( sqlite3BtreeCursorIsValid(pC->pCursor) ); | 
| +        rc = sqlite3BtreeKeySize(pC->pCursor, &v); | 
| +        assert( rc==SQLITE_OK );   /* Cannot fail following BtreeLast() */ | 
| +        if( v>=MAX_ROWID ){ | 
| +          pC->useRandomRowid = 1; | 
| }else{ | 
| -          assert( sqlite3BtreeCursorIsValid(pC->pCursor) ); | 
| -          rc = sqlite3BtreeKeySize(pC->pCursor, &v); | 
| -          assert( rc==SQLITE_OK );   /* Cannot fail following BtreeLast() */ | 
| -          if( v==MAX_ROWID ){ | 
| -            pC->useRandomRowid = 1; | 
| -          }else{ | 
| -            v++;   /* IMP: R-29538-34987 */ | 
| -          } | 
| +          v++;   /* IMP: R-29538-34987 */ | 
| } | 
| } | 
| +    } | 
|  | 
| #ifndef SQLITE_OMIT_AUTOINCREMENT | 
| -      if( pOp->p3 ){ | 
| +    if( pOp->p3 ){ | 
| +      /* Assert that P3 is a valid memory cell. */ | 
| +      assert( pOp->p3>0 ); | 
| +      if( p->pFrame ){ | 
| +        for(pFrame=p->pFrame; pFrame->pParent; pFrame=pFrame->pParent); | 
| /* Assert that P3 is a valid memory cell. */ | 
| -        assert( pOp->p3>0 ); | 
| -        if( p->pFrame ){ | 
| -          for(pFrame=p->pFrame; pFrame->pParent; pFrame=pFrame->pParent); | 
| -          /* Assert that P3 is a valid memory cell. */ | 
| -          assert( pOp->p3<=pFrame->nMem ); | 
| -          pMem = &pFrame->aMem[pOp->p3]; | 
| -        }else{ | 
| -          /* Assert that P3 is a valid memory cell. */ | 
| -          assert( pOp->p3<=p->nMem ); | 
| -          pMem = &aMem[pOp->p3]; | 
| -          memAboutToChange(p, pMem); | 
| -        } | 
| -        assert( memIsValid(pMem) ); | 
| - | 
| -        REGISTER_TRACE(pOp->p3, pMem); | 
| -        sqlite3VdbeMemIntegerify(pMem); | 
| -        assert( (pMem->flags & MEM_Int)!=0 );  /* mem(P3) holds an integer */ | 
| -        if( pMem->u.i==MAX_ROWID || pC->useRandomRowid ){ | 
| -          rc = SQLITE_FULL;   /* IMP: R-12275-61338 */ | 
| -          goto abort_due_to_error; | 
| -        } | 
| -        if( v<pMem->u.i+1 ){ | 
| -          v = pMem->u.i + 1; | 
| -        } | 
| -        pMem->u.i = v; | 
| +        assert( pOp->p3<=pFrame->nMem ); | 
| +        pMem = &pFrame->aMem[pOp->p3]; | 
| +      }else{ | 
| +        /* Assert that P3 is a valid memory cell. */ | 
| +        assert( pOp->p3<=(p->nMem-p->nCursor) ); | 
| +        pMem = &aMem[pOp->p3]; | 
| +        memAboutToChange(p, pMem); | 
| } | 
| -#endif | 
| +      assert( memIsValid(pMem) ); | 
|  | 
| -      sqlite3BtreeSetCachedRowid(pC->pCursor, v<MAX_ROWID ? v+1 : 0); | 
| +      REGISTER_TRACE(pOp->p3, pMem); | 
| +      sqlite3VdbeMemIntegerify(pMem); | 
| +      assert( (pMem->flags & MEM_Int)!=0 );  /* mem(P3) holds an integer */ | 
| +      if( pMem->u.i==MAX_ROWID || pC->useRandomRowid ){ | 
| +        rc = SQLITE_FULL;   /* IMP: R-12275-61338 */ | 
| +        goto abort_due_to_error; | 
| +      } | 
| +      if( v<pMem->u.i+1 ){ | 
| +        v = pMem->u.i + 1; | 
| +      } | 
| +      pMem->u.i = v; | 
| } | 
| +#endif | 
| if( pC->useRandomRowid ){ | 
| /* IMPLEMENTATION-OF: R-07677-41881 If the largest ROWID is equal to the | 
| ** largest possible integer (9223372036854775807) then the database | 
| @@ -3791,32 +4021,20 @@ case OP_NewRowid: {           /* out2-prerelease */ | 
| ** it finds one that is not previously used. */ | 
| assert( pOp->p3==0 );  /* We cannot be in random rowid mode if this is | 
| ** an AUTOINCREMENT table. */ | 
| -      /* on the first attempt, simply do one more than previous */ | 
| -      v = db->lastRowid; | 
| -      v &= (MAX_ROWID>>1); /* ensure doesn't go negative */ | 
| -      v++; /* ensure non-zero */ | 
| cnt = 0; | 
| -      while(   ((rc = sqlite3BtreeMovetoUnpacked(pC->pCursor, 0, (u64)v, | 
| +      do{ | 
| +        sqlite3_randomness(sizeof(v), &v); | 
| +        v &= (MAX_ROWID>>1); v++;  /* Ensure that v is greater than zero */ | 
| +      }while(  ((rc = sqlite3BtreeMovetoUnpacked(pC->pCursor, 0, (u64)v, | 
| 0, &res))==SQLITE_OK) | 
| && (res==0) | 
| -            && (++cnt<100)){ | 
| -        /* collision - try another random rowid */ | 
| -        sqlite3_randomness(sizeof(v), &v); | 
| -        if( cnt<5 ){ | 
| -          /* try "small" random rowids for the initial attempts */ | 
| -          v &= 0xffffff; | 
| -        }else{ | 
| -          v &= (MAX_ROWID>>1); /* ensure doesn't go negative */ | 
| -        } | 
| -        v++; /* ensure non-zero */ | 
| -      } | 
| +            && (++cnt<100)); | 
| if( rc==SQLITE_OK && res==0 ){ | 
| rc = SQLITE_FULL;   /* IMP: R-38219-53002 */ | 
| goto abort_due_to_error; | 
| } | 
| assert( v>0 );  /* EV: R-40812-03570 */ | 
| } | 
| -    pC->rowidIsValid = 0; | 
| pC->deferredMoveto = 0; | 
| pC->cacheStatus = CACHE_STALE; | 
| } | 
| @@ -3825,6 +4043,7 @@ case OP_NewRowid: {           /* out2-prerelease */ | 
| } | 
|  | 
| /* Opcode: Insert P1 P2 P3 P4 P5 | 
| +** Synopsis: intkey=r[P3] data=r[P2] | 
| ** | 
| ** Write an entry into the table of cursor P1.  A new entry is | 
| ** created if it doesn't already exist or the data for an existing | 
| @@ -3864,6 +4083,7 @@ case OP_NewRowid: {           /* out2-prerelease */ | 
| ** for indices is OP_IdxInsert. | 
| */ | 
| /* Opcode: InsertInt P1 P2 P3 P4 P5 | 
| +** Synopsis:  intkey=P3 data=r[P2] | 
| ** | 
| ** This works exactly like OP_Insert except that the key is the | 
| ** integer value P3, not the value of the integer stored in register P3. | 
| @@ -3902,7 +4122,7 @@ case OP_InsertInt: { | 
| } | 
|  | 
| if( pOp->p5 & OPFLAG_NCHANGE ) p->nChange++; | 
| -  if( pOp->p5 & OPFLAG_LASTROWID ) db->lastRowid = iKey; | 
| +  if( pOp->p5 & OPFLAG_LASTROWID ) db->lastRowid = lastRowid = iKey; | 
| if( pData->flags & MEM_Null ){ | 
| pData->z = 0; | 
| pData->n = 0; | 
| @@ -3915,12 +4135,10 @@ case OP_InsertInt: { | 
| }else{ | 
| nZero = 0; | 
| } | 
| -  sqlite3BtreeSetCachedRowid(pC->pCursor, 0); | 
| rc = sqlite3BtreeInsert(pC->pCursor, 0, iKey, | 
| pData->z, pData->n, nZero, | 
| -                          pOp->p5 & OPFLAG_APPEND, seekResult | 
| +                          (pOp->p5 & OPFLAG_APPEND)!=0, seekResult | 
| ); | 
| -  pC->rowidIsValid = 0; | 
| pC->deferredMoveto = 0; | 
| pC->cacheStatus = CACHE_STALE; | 
|  | 
| @@ -3943,7 +4161,7 @@ case OP_InsertInt: { | 
| ** The cursor will be left pointing at either the next or the previous | 
| ** record in the table. If it is left pointing at the next record, then | 
| ** the next Next instruction will be a no-op.  Hence it is OK to delete | 
| -** a record from within an Next loop. | 
| +** a record from within a Next loop. | 
| ** | 
| ** If the OPFLAG_NCHANGE flag of P2 is set, then the row change count is | 
| ** incremented (otherwise not). | 
| @@ -3957,44 +4175,32 @@ case OP_InsertInt: { | 
| ** using OP_NotFound prior to invoking this opcode. | 
| */ | 
| case OP_Delete: { | 
| -  i64 iKey; | 
| VdbeCursor *pC; | 
|  | 
| -  iKey = 0; | 
| assert( pOp->p1>=0 && pOp->p1<p->nCursor ); | 
| pC = p->apCsr[pOp->p1]; | 
| assert( pC!=0 ); | 
| assert( pC->pCursor!=0 );  /* Only valid for real tables, no pseudotables */ | 
| - | 
| -  /* If the update-hook will be invoked, set iKey to the rowid of the | 
| -  ** row being deleted. | 
| -  */ | 
| -  if( db->xUpdateCallback && pOp->p4.z ){ | 
| -    assert( pC->isTable ); | 
| -    assert( pC->rowidIsValid );  /* lastRowid set by previous OP_NotFound */ | 
| -    iKey = pC->lastRowid; | 
| -  } | 
| - | 
| -  /* The OP_Delete opcode always follows an OP_NotExists or OP_Last or | 
| -  ** OP_Column on the same table without any intervening operations that | 
| -  ** might move or invalidate the cursor.  Hence cursor pC is always pointing | 
| -  ** to the row to be deleted and the sqlite3VdbeCursorMoveto() operation | 
| -  ** below is always a no-op and cannot fail.  We will run it anyhow, though, | 
| -  ** to guard against future changes to the code generator. | 
| -  **/ | 
| assert( pC->deferredMoveto==0 ); | 
| -  rc = sqlite3VdbeCursorMoveto(pC); | 
| -  if( NEVER(rc!=SQLITE_OK) ) goto abort_due_to_error; | 
|  | 
| -  sqlite3BtreeSetCachedRowid(pC->pCursor, 0); | 
| +#ifdef SQLITE_DEBUG | 
| +  /* The seek operation that positioned the cursor prior to OP_Delete will | 
| +  ** have also set the pC->movetoTarget field to the rowid of the row that | 
| +  ** is being deleted */ | 
| +  if( pOp->p4.z && pC->isTable ){ | 
| +    i64 iKey = 0; | 
| +    sqlite3BtreeKeySize(pC->pCursor, &iKey); | 
| +    assert( pC->movetoTarget==iKey ); | 
| +  } | 
| +#endif | 
| + | 
| rc = sqlite3BtreeDelete(pC->pCursor); | 
| pC->cacheStatus = CACHE_STALE; | 
|  | 
| /* Invoke the update-hook if required. */ | 
| -  if( rc==SQLITE_OK && db->xUpdateCallback && pOp->p4.z ){ | 
| -    const char *zDb = db->aDb[pC->iDb].zName; | 
| -    const char *zTbl = pOp->p4.z; | 
| -    db->xUpdateCallback(db->pUpdateArg, SQLITE_DELETE, zDb, zTbl, iKey); | 
| +  if( rc==SQLITE_OK && db->xUpdateCallback && pOp->p4.z && pC->isTable ){ | 
| +    db->xUpdateCallback(db->pUpdateArg, SQLITE_DELETE, | 
| +                        db->aDb[pC->iDb].zName, pOp->p4.z, pC->movetoTarget); | 
| assert( pC->iDb>=0 ); | 
| } | 
| if( pOp->p2 & OPFLAG_NCHANGE ) p->nChange++; | 
| @@ -4013,7 +4219,67 @@ case OP_ResetCount: { | 
| break; | 
| } | 
|  | 
| +/* Opcode: SorterCompare P1 P2 P3 P4 | 
| +** Synopsis:  if key(P1)!=trim(r[P3],P4) goto P2 | 
| +** | 
| +** P1 is a sorter cursor. This instruction compares a prefix of the | 
| +** record blob in register P3 against a prefix of the entry that | 
| +** the sorter cursor currently points to.  Only the first P4 fields | 
| +** of r[P3] and the sorter record are compared. | 
| +** | 
| +** If either P3 or the sorter contains a NULL in one of their significant | 
| +** fields (not counting the P4 fields at the end which are ignored) then | 
| +** the comparison is assumed to be equal. | 
| +** | 
| +** Fall through to next instruction if the two records compare equal to | 
| +** each other.  Jump to P2 if they are different. | 
| +*/ | 
| +case OP_SorterCompare: { | 
| +  VdbeCursor *pC; | 
| +  int res; | 
| +  int nKeyCol; | 
| + | 
| +  pC = p->apCsr[pOp->p1]; | 
| +  assert( isSorter(pC) ); | 
| +  assert( pOp->p4type==P4_INT32 ); | 
| +  pIn3 = &aMem[pOp->p3]; | 
| +  nKeyCol = pOp->p4.i; | 
| +  res = 0; | 
| +  rc = sqlite3VdbeSorterCompare(pC, pIn3, nKeyCol, &res); | 
| +  VdbeBranchTaken(res!=0,2); | 
| +  if( res ){ | 
| +    pc = pOp->p2-1; | 
| +  } | 
| +  break; | 
| +}; | 
| + | 
| +/* Opcode: SorterData P1 P2 P3 * * | 
| +** Synopsis: r[P2]=data | 
| +** | 
| +** Write into register P2 the current sorter data for sorter cursor P1. | 
| +** Then clear the column header cache on cursor P3. | 
| +** | 
| +** This opcode is normally use to move a record out of the sorter and into | 
| +** a register that is the source for a pseudo-table cursor created using | 
| +** OpenPseudo.  That pseudo-table cursor is the one that is identified by | 
| +** parameter P3.  Clearing the P3 column cache as part of this opcode saves | 
| +** us from having to issue a separate NullRow instruction to clear that cache. | 
| +*/ | 
| +case OP_SorterData: { | 
| +  VdbeCursor *pC; | 
| + | 
| +  pOut = &aMem[pOp->p2]; | 
| +  pC = p->apCsr[pOp->p1]; | 
| +  assert( isSorter(pC) ); | 
| +  rc = sqlite3VdbeSorterRowkey(pC, pOut); | 
| +  assert( rc!=SQLITE_OK || (pOut->flags & MEM_Blob) ); | 
| +  assert( pOp->p1>=0 && pOp->p1<p->nCursor ); | 
| +  p->apCsr[pOp->p3]->cacheStatus = CACHE_STALE; | 
| +  break; | 
| +} | 
| + | 
| /* Opcode: RowData P1 P2 * * * | 
| +** Synopsis: r[P2]=data | 
| ** | 
| ** Write into register P2 the complete row data for cursor P1. | 
| ** There is no interpretation of the data. | 
| @@ -4024,10 +4290,11 @@ case OP_ResetCount: { | 
| ** of a real table, not a pseudo-table. | 
| */ | 
| /* Opcode: RowKey P1 P2 * * * | 
| +** Synopsis: r[P2]=key | 
| ** | 
| ** Write into register P2 the complete row key for cursor P1. | 
| ** There is no interpretation of the data. | 
| -** The key is copied onto the P3 register exactly as | 
| +** The key is copied onto the P2 register exactly as | 
| ** it is found in the database file. | 
| ** | 
| ** If the P1 cursor must be pointing to a valid row (not a NULL row) | 
| @@ -4046,55 +4313,63 @@ case OP_RowData: { | 
| /* Note that RowKey and RowData are really exactly the same instruction */ | 
| assert( pOp->p1>=0 && pOp->p1<p->nCursor ); | 
| pC = p->apCsr[pOp->p1]; | 
| -  assert( pC->isTable || pOp->opcode==OP_RowKey ); | 
| -  assert( pC->isIndex || pOp->opcode==OP_RowData ); | 
| +  assert( isSorter(pC)==0 ); | 
| +  assert( pC->isTable || pOp->opcode!=OP_RowData ); | 
| +  assert( pC->isTable==0 || pOp->opcode==OP_RowData ); | 
| assert( pC!=0 ); | 
| assert( pC->nullRow==0 ); | 
| assert( pC->pseudoTableReg==0 ); | 
| assert( pC->pCursor!=0 ); | 
| pCrsr = pC->pCursor; | 
| -  assert( sqlite3BtreeCursorIsValid(pCrsr) ); | 
|  | 
| /* The OP_RowKey and OP_RowData opcodes always follow OP_NotExists or | 
| ** OP_Rewind/Op_Next with no intervening instructions that might invalidate | 
| -  ** the cursor.  Hence the following sqlite3VdbeCursorMoveto() call is always | 
| -  ** a no-op and can never fail.  But we leave it in place as a safety. | 
| +  ** the cursor.  If this where not the case, on of the following assert()s | 
| +  ** would fail.  Should this ever change (because of changes in the code | 
| +  ** generator) then the fix would be to insert a call to | 
| +  ** sqlite3VdbeCursorMoveto(). | 
| */ | 
| assert( pC->deferredMoveto==0 ); | 
| +  assert( sqlite3BtreeCursorIsValid(pCrsr) ); | 
| +#if 0  /* Not required due to the previous to assert() statements */ | 
| rc = sqlite3VdbeCursorMoveto(pC); | 
| -  if( NEVER(rc!=SQLITE_OK) ) goto abort_due_to_error; | 
| +  if( rc!=SQLITE_OK ) goto abort_due_to_error; | 
| +#endif | 
|  | 
| -  if( pC->isIndex ){ | 
| +  if( pC->isTable==0 ){ | 
| assert( !pC->isTable ); | 
| -    rc = sqlite3BtreeKeySize(pCrsr, &n64); | 
| +    VVA_ONLY(rc =) sqlite3BtreeKeySize(pCrsr, &n64); | 
| assert( rc==SQLITE_OK );    /* True because of CursorMoveto() call above */ | 
| if( n64>db->aLimit[SQLITE_LIMIT_LENGTH] ){ | 
| goto too_big; | 
| } | 
| n = (u32)n64; | 
| }else{ | 
| -    rc = sqlite3BtreeDataSize(pCrsr, &n); | 
| +    VVA_ONLY(rc =) sqlite3BtreeDataSize(pCrsr, &n); | 
| assert( rc==SQLITE_OK );    /* DataSize() cannot fail */ | 
| if( n>(u32)db->aLimit[SQLITE_LIMIT_LENGTH] ){ | 
| goto too_big; | 
| } | 
| } | 
| -  if( sqlite3VdbeMemGrow(pOut, n, 0) ){ | 
| +  testcase( n==0 ); | 
| +  if( sqlite3VdbeMemClearAndResize(pOut, MAX(n,32)) ){ | 
| goto no_mem; | 
| } | 
| pOut->n = n; | 
| MemSetTypeFlag(pOut, MEM_Blob); | 
| -  if( pC->isIndex ){ | 
| +  if( pC->isTable==0 ){ | 
| rc = sqlite3BtreeKey(pCrsr, 0, n, pOut->z); | 
| }else{ | 
| rc = sqlite3BtreeData(pCrsr, 0, n, pOut->z); | 
| } | 
| pOut->enc = SQLITE_UTF8;  /* In case the blob is ever cast to text */ | 
| UPDATE_MAX_BLOBSIZE(pOut); | 
| +  REGISTER_TRACE(pOp->p2, pOut); | 
| break; | 
| } | 
|  | 
| /* Opcode: Rowid P1 P2 * * * | 
| +** Synopsis: r[P2]=rowid | 
| ** | 
| ** Store in register P2 an integer which is the key of the table entry that | 
| ** P1 is currently point to. | 
| @@ -4112,7 +4387,7 @@ case OP_Rowid: {                 /* out2-prerelease */ | 
| assert( pOp->p1>=0 && pOp->p1<p->nCursor ); | 
| pC = p->apCsr[pOp->p1]; | 
| assert( pC!=0 ); | 
| -  assert( pC->pseudoTableReg==0 ); | 
| +  assert( pC->pseudoTableReg==0 || pC->nullRow ); | 
| if( pC->nullRow ){ | 
| pOut->flags = MEM_Null; | 
| break; | 
| @@ -4124,18 +4399,18 @@ case OP_Rowid: {                 /* out2-prerelease */ | 
| pModule = pVtab->pModule; | 
| assert( pModule->xRowid ); | 
| rc = pModule->xRowid(pC->pVtabCursor, &v); | 
| -    importVtabErrMsg(p, pVtab); | 
| +    sqlite3VtabImportErrmsg(p, pVtab); | 
| #endif /* SQLITE_OMIT_VIRTUALTABLE */ | 
| }else{ | 
| assert( pC->pCursor!=0 ); | 
| -    rc = sqlite3VdbeCursorMoveto(pC); | 
| +    rc = sqlite3VdbeCursorRestore(pC); | 
| if( rc ) goto abort_due_to_error; | 
| -    if( pC->rowidIsValid ){ | 
| -      v = pC->lastRowid; | 
| -    }else{ | 
| -      rc = sqlite3BtreeKeySize(pC->pCursor, &v); | 
| -      assert( rc==SQLITE_OK );  /* Always so because of CursorMoveto() above */ | 
| +    if( pC->nullRow ){ | 
| +      pOut->flags = MEM_Null; | 
| +      break; | 
| } | 
| +    rc = sqlite3BtreeKeySize(pC->pCursor, &v); | 
| +    assert( rc==SQLITE_OK );  /* Always so because of CursorRestore() above */ | 
| } | 
| pOut->u.i = v; | 
| break; | 
| @@ -4154,7 +4429,7 @@ case OP_NullRow: { | 
| pC = p->apCsr[pOp->p1]; | 
| assert( pC!=0 ); | 
| pC->nullRow = 1; | 
| -  pC->rowidIsValid = 0; | 
| +  pC->cacheStatus = CACHE_STALE; | 
| if( pC->pCursor ){ | 
| sqlite3BtreeClearCursor(pC->pCursor); | 
| } | 
| @@ -4163,11 +4438,15 @@ case OP_NullRow: { | 
|  | 
| /* Opcode: Last P1 P2 * * * | 
| ** | 
| -** The next use of the Rowid or Column or Next instruction for P1 | 
| +** The next use of the Rowid or Column or Prev instruction for P1 | 
| ** will refer to the last entry in the database table or index. | 
| ** If the table or index is empty and P2>0, then jump immediately to P2. | 
| ** If P2 is 0 or if the table or index is not empty, fall through | 
| ** to the following instruction. | 
| +** | 
| +** This opcode leaves the cursor configured to move in reverse order, | 
| +** from the end toward the beginning.  In other words, the cursor is | 
| +** configured to use Prev, not Next. | 
| */ | 
| case OP_Last: {        /* jump */ | 
| VdbeCursor *pC; | 
| @@ -4178,17 +4457,18 @@ case OP_Last: {        /* jump */ | 
| pC = p->apCsr[pOp->p1]; | 
| assert( pC!=0 ); | 
| pCrsr = pC->pCursor; | 
| -  if( pCrsr==0 ){ | 
| -    res = 1; | 
| -  }else{ | 
| -    rc = sqlite3BtreeLast(pCrsr, &res); | 
| -  } | 
| +  res = 0; | 
| +  assert( pCrsr!=0 ); | 
| +  rc = sqlite3BtreeLast(pCrsr, &res); | 
| pC->nullRow = (u8)res; | 
| pC->deferredMoveto = 0; | 
| -  pC->rowidIsValid = 0; | 
| pC->cacheStatus = CACHE_STALE; | 
| -  if( pOp->p2>0 && res ){ | 
| -    pc = pOp->p2 - 1; | 
| +#ifdef SQLITE_DEBUG | 
| +  pC->seekOp = OP_Last; | 
| +#endif | 
| +  if( pOp->p2>0 ){ | 
| +    VdbeBranchTaken(res!=0,2); | 
| +    if( res ) pc = pOp->p2 - 1; | 
| } | 
| break; | 
| } | 
| @@ -4206,12 +4486,13 @@ case OP_Last: {        /* jump */ | 
| ** regression tests can determine whether or not the optimizer is | 
| ** correctly optimizing out sorts. | 
| */ | 
| +case OP_SorterSort:    /* jump */ | 
| case OP_Sort: {        /* jump */ | 
| #ifdef SQLITE_TEST | 
| sqlite3_sort_count++; | 
| sqlite3_search_count--; | 
| #endif | 
| -  p->aCounter[SQLITE_STMTSTATUS_SORT-1]++; | 
| +  p->aCounter[SQLITE_STMTSTATUS_SORT]++; | 
| /* Fall through into OP_Rewind */ | 
| } | 
| /* Opcode: Rewind P1 P2 * * * | 
| @@ -4221,6 +4502,10 @@ case OP_Sort: {        /* jump */ | 
| ** If the table or index is empty and P2>0, then jump immediately to P2. | 
| ** If P2 is 0 or if the table or index is not empty, fall through | 
| ** to the following instruction. | 
| +** | 
| +** This opcode leaves the cursor configured to move in forward order, | 
| +** from the beginning toward the end.  In other words, the cursor is | 
| +** configured to use Next, not Prev. | 
| */ | 
| case OP_Rewind: {        /* jump */ | 
| VdbeCursor *pC; | 
| @@ -4230,95 +4515,169 @@ case OP_Rewind: {        /* jump */ | 
| assert( pOp->p1>=0 && pOp->p1<p->nCursor ); | 
| pC = p->apCsr[pOp->p1]; | 
| assert( pC!=0 ); | 
| +  assert( isSorter(pC)==(pOp->opcode==OP_SorterSort) ); | 
| res = 1; | 
| -  if( (pCrsr = pC->pCursor)!=0 ){ | 
| +#ifdef SQLITE_DEBUG | 
| +  pC->seekOp = OP_Rewind; | 
| +#endif | 
| +  if( isSorter(pC) ){ | 
| +    rc = sqlite3VdbeSorterRewind(pC, &res); | 
| +  }else{ | 
| +    pCrsr = pC->pCursor; | 
| +    assert( pCrsr ); | 
| rc = sqlite3BtreeFirst(pCrsr, &res); | 
| -    pC->atFirst = res==0 ?1:0; | 
| pC->deferredMoveto = 0; | 
| pC->cacheStatus = CACHE_STALE; | 
| -    pC->rowidIsValid = 0; | 
| } | 
| pC->nullRow = (u8)res; | 
| assert( pOp->p2>0 && pOp->p2<p->nOp ); | 
| +  VdbeBranchTaken(res!=0,2); | 
| if( res ){ | 
| pc = pOp->p2 - 1; | 
| } | 
| break; | 
| } | 
|  | 
| -/* Opcode: Next P1 P2 * * P5 | 
| +/* Opcode: Next P1 P2 P3 P4 P5 | 
| ** | 
| ** Advance cursor P1 so that it points to the next key/data pair in its | 
| ** table or index.  If there are no more key/value pairs then fall through | 
| ** to the following instruction.  But if the cursor advance was successful, | 
| ** jump immediately to P2. | 
| ** | 
| -** The P1 cursor must be for a real table, not a pseudo-table. | 
| +** The Next opcode is only valid following an SeekGT, SeekGE, or | 
| +** OP_Rewind opcode used to position the cursor.  Next is not allowed | 
| +** to follow SeekLT, SeekLE, or OP_Last. | 
| +** | 
| +** The P1 cursor must be for a real table, not a pseudo-table.  P1 must have | 
| +** been opened prior to this opcode or the program will segfault. | 
| +** | 
| +** The P3 value is a hint to the btree implementation. If P3==1, that | 
| +** means P1 is an SQL index and that this instruction could have been | 
| +** omitted if that index had been unique.  P3 is usually 0.  P3 is | 
| +** always either 0 or 1. | 
| +** | 
| +** P4 is always of type P4_ADVANCE. The function pointer points to | 
| +** sqlite3BtreeNext(). | 
| ** | 
| ** If P5 is positive and the jump is taken, then event counter | 
| ** number P5-1 in the prepared statement is incremented. | 
| ** | 
| -** See also: Prev | 
| +** See also: Prev, NextIfOpen | 
| +*/ | 
| +/* Opcode: NextIfOpen P1 P2 P3 P4 P5 | 
| +** | 
| +** This opcode works just like Next except that if cursor P1 is not | 
| +** open it behaves a no-op. | 
| */ | 
| -/* Opcode: Prev P1 P2 * * P5 | 
| +/* Opcode: Prev P1 P2 P3 P4 P5 | 
| ** | 
| ** Back up cursor P1 so that it points to the previous key/data pair in its | 
| ** table or index.  If there is no previous key/value pairs then fall through | 
| ** to the following instruction.  But if the cursor backup was successful, | 
| ** jump immediately to P2. | 
| ** | 
| -** The P1 cursor must be for a real table, not a pseudo-table. | 
| +** | 
| +** The Prev opcode is only valid following an SeekLT, SeekLE, or | 
| +** OP_Last opcode used to position the cursor.  Prev is not allowed | 
| +** to follow SeekGT, SeekGE, or OP_Rewind. | 
| +** | 
| +** The P1 cursor must be for a real table, not a pseudo-table.  If P1 is | 
| +** not open then the behavior is undefined. | 
| +** | 
| +** The P3 value is a hint to the btree implementation. If P3==1, that | 
| +** means P1 is an SQL index and that this instruction could have been | 
| +** omitted if that index had been unique.  P3 is usually 0.  P3 is | 
| +** always either 0 or 1. | 
| +** | 
| +** P4 is always of type P4_ADVANCE. The function pointer points to | 
| +** sqlite3BtreePrevious(). | 
| ** | 
| ** If P5 is positive and the jump is taken, then event counter | 
| ** number P5-1 in the prepared statement is incremented. | 
| */ | 
| -case OP_Prev:          /* jump */ | 
| -case OP_Next: {        /* jump */ | 
| +/* Opcode: PrevIfOpen P1 P2 P3 P4 P5 | 
| +** | 
| +** This opcode works just like Prev except that if cursor P1 is not | 
| +** open it behaves a no-op. | 
| +*/ | 
| +case OP_SorterNext: {  /* jump */ | 
| VdbeCursor *pC; | 
| -  BtCursor *pCrsr; | 
| int res; | 
|  | 
| -  CHECK_FOR_INTERRUPT; | 
| +  pC = p->apCsr[pOp->p1]; | 
| +  assert( isSorter(pC) ); | 
| +  res = 0; | 
| +  rc = sqlite3VdbeSorterNext(db, pC, &res); | 
| +  goto next_tail; | 
| +case OP_PrevIfOpen:    /* jump */ | 
| +case OP_NextIfOpen:    /* jump */ | 
| +  if( p->apCsr[pOp->p1]==0 ) break; | 
| +  /* Fall through */ | 
| +case OP_Prev:          /* jump */ | 
| +case OP_Next:          /* jump */ | 
| assert( pOp->p1>=0 && pOp->p1<p->nCursor ); | 
| -  assert( pOp->p5<=ArraySize(p->aCounter) ); | 
| +  assert( pOp->p5<ArraySize(p->aCounter) ); | 
| pC = p->apCsr[pOp->p1]; | 
| -  if( pC==0 ){ | 
| -    break;  /* See ticket #2273 */ | 
| -  } | 
| -  pCrsr = pC->pCursor; | 
| -  if( pCrsr==0 ){ | 
| -    pC->nullRow = 1; | 
| -    break; | 
| -  } | 
| -  res = 1; | 
| +  res = pOp->p3; | 
| +  assert( pC!=0 ); | 
| assert( pC->deferredMoveto==0 ); | 
| -  rc = pOp->opcode==OP_Next ? sqlite3BtreeNext(pCrsr, &res) : | 
| -                              sqlite3BtreePrevious(pCrsr, &res); | 
| -  pC->nullRow = (u8)res; | 
| +  assert( pC->pCursor ); | 
| +  assert( res==0 || (res==1 && pC->isTable==0) ); | 
| +  testcase( res==1 ); | 
| +  assert( pOp->opcode!=OP_Next || pOp->p4.xAdvance==sqlite3BtreeNext ); | 
| +  assert( pOp->opcode!=OP_Prev || pOp->p4.xAdvance==sqlite3BtreePrevious ); | 
| +  assert( pOp->opcode!=OP_NextIfOpen || pOp->p4.xAdvance==sqlite3BtreeNext ); | 
| +  assert( pOp->opcode!=OP_PrevIfOpen || pOp->p4.xAdvance==sqlite3BtreePrevious); | 
| + | 
| +  /* The Next opcode is only used after SeekGT, SeekGE, and Rewind. | 
| +  ** The Prev opcode is only used after SeekLT, SeekLE, and Last. */ | 
| +  assert( pOp->opcode!=OP_Next || pOp->opcode!=OP_NextIfOpen | 
| +       || pC->seekOp==OP_SeekGT || pC->seekOp==OP_SeekGE | 
| +       || pC->seekOp==OP_Rewind || pC->seekOp==OP_Found); | 
| +  assert( pOp->opcode!=OP_Prev || pOp->opcode!=OP_PrevIfOpen | 
| +       || pC->seekOp==OP_SeekLT || pC->seekOp==OP_SeekLE | 
| +       || pC->seekOp==OP_Last ); | 
| + | 
| +  rc = pOp->p4.xAdvance(pC->pCursor, &res); | 
| +next_tail: | 
| pC->cacheStatus = CACHE_STALE; | 
| +  VdbeBranchTaken(res==0,2); | 
| if( res==0 ){ | 
| +    pC->nullRow = 0; | 
| pc = pOp->p2 - 1; | 
| -    if( pOp->p5 ) p->aCounter[pOp->p5-1]++; | 
| +    p->aCounter[pOp->p5]++; | 
| #ifdef SQLITE_TEST | 
| sqlite3_search_count++; | 
| #endif | 
| +  }else{ | 
| +    pC->nullRow = 1; | 
| } | 
| -  pC->rowidIsValid = 0; | 
| -  break; | 
| +  goto check_for_interrupt; | 
| } | 
|  | 
| /* Opcode: IdxInsert P1 P2 P3 * P5 | 
| +** Synopsis: key=r[P2] | 
| ** | 
| -** Register P2 holds a SQL index key made using the | 
| +** Register P2 holds an SQL index key made using the | 
| ** MakeRecord instructions.  This opcode writes that key | 
| ** into the index P1.  Data for the entry is nil. | 
| ** | 
| ** P3 is a flag that provides a hint to the b-tree layer that this | 
| ** insert is likely to be an append. | 
| ** | 
| +** If P5 has the OPFLAG_NCHANGE bit set, then the change counter is | 
| +** incremented by this instruction.  If the OPFLAG_NCHANGE bit is clear, | 
| +** then the change counter is unchanged. | 
| +** | 
| +** If P5 has the OPFLAG_USESEEKRESULT bit set, then the cursor must have | 
| +** just done a seek to the spot where the new entry is to be inserted. | 
| +** This flag avoids doing an extra seek. | 
| +** | 
| ** This instruction only works for indices.  The equivalent instruction | 
| ** for tables is OP_Insert. | 
| */ | 
| +case OP_SorterInsert:       /* in2 */ | 
| case OP_IdxInsert: {        /* in2 */ | 
| VdbeCursor *pC; | 
| BtCursor *pCrsr; | 
| @@ -4328,18 +4687,23 @@ case OP_IdxInsert: {        /* in2 */ | 
| assert( pOp->p1>=0 && pOp->p1<p->nCursor ); | 
| pC = p->apCsr[pOp->p1]; | 
| assert( pC!=0 ); | 
| +  assert( isSorter(pC)==(pOp->opcode==OP_SorterInsert) ); | 
| pIn2 = &aMem[pOp->p2]; | 
| assert( pIn2->flags & MEM_Blob ); | 
| pCrsr = pC->pCursor; | 
| -  if( ALWAYS(pCrsr!=0) ){ | 
| -    assert( pC->isTable==0 ); | 
| -    rc = ExpandBlob(pIn2); | 
| -    if( rc==SQLITE_OK ){ | 
| +  if( pOp->p5 & OPFLAG_NCHANGE ) p->nChange++; | 
| +  assert( pCrsr!=0 ); | 
| +  assert( pC->isTable==0 ); | 
| +  rc = ExpandBlob(pIn2); | 
| +  if( rc==SQLITE_OK ){ | 
| +    if( isSorter(pC) ){ | 
| +      rc = sqlite3VdbeSorterWrite(pC, pIn2); | 
| +    }else{ | 
| nKey = pIn2->n; | 
| zKey = pIn2->z; | 
| rc = sqlite3BtreeInsert(pCrsr, zKey, nKey, "", 0, 0, pOp->p3, | 
| ((pOp->p5 & OPFLAG_USESEEKRESULT) ? pC->seekResult : 0) | 
| -      ); | 
| +          ); | 
| assert( pC->deferredMoveto==0 ); | 
| pC->cacheStatus = CACHE_STALE; | 
| } | 
| @@ -4348,6 +4712,7 @@ case OP_IdxInsert: {        /* in2 */ | 
| } | 
|  | 
| /* Opcode: IdxDelete P1 P2 P3 * * | 
| +** Synopsis: key=r[P2@P3] | 
| ** | 
| ** The content of P3 registers starting at register P2 form | 
| ** an unpacked index key. This opcode removes that entry from the | 
| @@ -4360,30 +4725,31 @@ case OP_IdxDelete: { | 
| UnpackedRecord r; | 
|  | 
| assert( pOp->p3>0 ); | 
| -  assert( pOp->p2>0 && pOp->p2+pOp->p3<=p->nMem+1 ); | 
| +  assert( pOp->p2>0 && pOp->p2+pOp->p3<=(p->nMem-p->nCursor)+1 ); | 
| assert( pOp->p1>=0 && pOp->p1<p->nCursor ); | 
| pC = p->apCsr[pOp->p1]; | 
| assert( pC!=0 ); | 
| pCrsr = pC->pCursor; | 
| -  if( ALWAYS(pCrsr!=0) ){ | 
| -    r.pKeyInfo = pC->pKeyInfo; | 
| -    r.nField = (u16)pOp->p3; | 
| -    r.flags = 0; | 
| -    r.aMem = &aMem[pOp->p2]; | 
| +  assert( pCrsr!=0 ); | 
| +  assert( pOp->p5==0 ); | 
| +  r.pKeyInfo = pC->pKeyInfo; | 
| +  r.nField = (u16)pOp->p3; | 
| +  r.default_rc = 0; | 
| +  r.aMem = &aMem[pOp->p2]; | 
| #ifdef SQLITE_DEBUG | 
| -    { int i; for(i=0; i<r.nField; i++) assert( memIsValid(&r.aMem[i]) ); } | 
| +  { int i; for(i=0; i<r.nField; i++) assert( memIsValid(&r.aMem[i]) ); } | 
| #endif | 
| -    rc = sqlite3BtreeMovetoUnpacked(pCrsr, &r, 0, 0, &res); | 
| -    if( rc==SQLITE_OK && res==0 ){ | 
| -      rc = sqlite3BtreeDelete(pCrsr); | 
| -    } | 
| -    assert( pC->deferredMoveto==0 ); | 
| -    pC->cacheStatus = CACHE_STALE; | 
| +  rc = sqlite3BtreeMovetoUnpacked(pCrsr, &r, 0, 0, &res); | 
| +  if( rc==SQLITE_OK && res==0 ){ | 
| +    rc = sqlite3BtreeDelete(pCrsr); | 
| } | 
| +  assert( pC->deferredMoveto==0 ); | 
| +  pC->cacheStatus = CACHE_STALE; | 
| break; | 
| } | 
|  | 
| /* Opcode: IdxRowid P1 P2 * * * | 
| +** Synopsis: r[P2]=rowid | 
| ** | 
| ** Write into register P2 an integer which is the last entry in the record at | 
| ** the end of the index key pointed to by cursor P1.  This integer should be | 
| @@ -4400,52 +4766,78 @@ case OP_IdxRowid: {              /* out2-prerelease */ | 
| pC = p->apCsr[pOp->p1]; | 
| assert( pC!=0 ); | 
| pCrsr = pC->pCursor; | 
| +  assert( pCrsr!=0 ); | 
| pOut->flags = MEM_Null; | 
| -  if( ALWAYS(pCrsr!=0) ){ | 
| -    rc = sqlite3VdbeCursorMoveto(pC); | 
| -    if( NEVER(rc) ) goto abort_due_to_error; | 
| -    assert( pC->deferredMoveto==0 ); | 
| -    assert( pC->isTable==0 ); | 
| -    if( !pC->nullRow ){ | 
| -      rc = sqlite3VdbeIdxRowid(db, pCrsr, &rowid); | 
| -      if( rc!=SQLITE_OK ){ | 
| -        goto abort_due_to_error; | 
| -      } | 
| -      pOut->u.i = rowid; | 
| -      pOut->flags = MEM_Int; | 
| +  assert( pC->isTable==0 ); | 
| +  assert( pC->deferredMoveto==0 ); | 
| + | 
| +  /* sqlite3VbeCursorRestore() can only fail if the record has been deleted | 
| +  ** out from under the cursor.  That will never happend for an IdxRowid | 
| +  ** opcode, hence the NEVER() arround the check of the return value. | 
| +  */ | 
| +  rc = sqlite3VdbeCursorRestore(pC); | 
| +  if( NEVER(rc!=SQLITE_OK) ) goto abort_due_to_error; | 
| + | 
| +  if( !pC->nullRow ){ | 
| +    rowid = 0;  /* Not needed.  Only used to silence a warning. */ | 
| +    rc = sqlite3VdbeIdxRowid(db, pCrsr, &rowid); | 
| +    if( rc!=SQLITE_OK ){ | 
| +      goto abort_due_to_error; | 
| } | 
| +    pOut->u.i = rowid; | 
| +    pOut->flags = MEM_Int; | 
| } | 
| break; | 
| } | 
|  | 
| /* Opcode: IdxGE P1 P2 P3 P4 P5 | 
| +** Synopsis: key=r[P3@P4] | 
| ** | 
| ** The P4 register values beginning with P3 form an unpacked index | 
| -** key that omits the ROWID.  Compare this key value against the index | 
| -** that P1 is currently pointing to, ignoring the ROWID on the P1 index. | 
| +** key that omits the PRIMARY KEY.  Compare this key value against the index | 
| +** that P1 is currently pointing to, ignoring the PRIMARY KEY or ROWID | 
| +** fields at the end. | 
| ** | 
| ** If the P1 index entry is greater than or equal to the key value | 
| ** then jump to P2.  Otherwise fall through to the next instruction. | 
| +*/ | 
| +/* Opcode: IdxGT P1 P2 P3 P4 P5 | 
| +** Synopsis: key=r[P3@P4] | 
| +** | 
| +** The P4 register values beginning with P3 form an unpacked index | 
| +** key that omits the PRIMARY KEY.  Compare this key value against the index | 
| +** that P1 is currently pointing to, ignoring the PRIMARY KEY or ROWID | 
| +** fields at the end. | 
| ** | 
| -** If P5 is non-zero then the key value is increased by an epsilon | 
| -** prior to the comparison.  This make the opcode work like IdxGT except | 
| -** that if the key from register P3 is a prefix of the key in the cursor, | 
| -** the result is false whereas it would be true with IdxGT. | 
| +** If the P1 index entry is greater than the key value | 
| +** then jump to P2.  Otherwise fall through to the next instruction. | 
| */ | 
| /* Opcode: IdxLT P1 P2 P3 P4 P5 | 
| +** Synopsis: key=r[P3@P4] | 
| ** | 
| ** The P4 register values beginning with P3 form an unpacked index | 
| -** key that omits the ROWID.  Compare this key value against the index | 
| -** that P1 is currently pointing to, ignoring the ROWID on the P1 index. | 
| +** key that omits the PRIMARY KEY or ROWID.  Compare this key value against | 
| +** the index that P1 is currently pointing to, ignoring the PRIMARY KEY or | 
| +** ROWID on the P1 index. | 
| ** | 
| ** If the P1 index entry is less than the key value then jump to P2. | 
| ** Otherwise fall through to the next instruction. | 
| +*/ | 
| +/* Opcode: IdxLE P1 P2 P3 P4 P5 | 
| +** Synopsis: key=r[P3@P4] | 
| +** | 
| +** The P4 register values beginning with P3 form an unpacked index | 
| +** key that omits the PRIMARY KEY or ROWID.  Compare this key value against | 
| +** the index that P1 is currently pointing to, ignoring the PRIMARY KEY or | 
| +** ROWID on the P1 index. | 
| ** | 
| -** If P5 is non-zero then the key value is increased by an epsilon prior | 
| -** to the comparison.  This makes the opcode work like IdxLE. | 
| +** If the P1 index entry is less than or equal to the key value then jump | 
| +** to P2. Otherwise fall through to the next instruction. | 
| */ | 
| +case OP_IdxLE:          /* jump */ | 
| +case OP_IdxGT:          /* jump */ | 
| case OP_IdxLT:          /* jump */ | 
| -case OP_IdxGE: {        /* jump */ | 
| +case OP_IdxGE:  {       /* jump */ | 
| VdbeCursor *pC; | 
| int res; | 
| UnpackedRecord r; | 
| @@ -4454,31 +4846,36 @@ case OP_IdxGE: {        /* jump */ | 
| pC = p->apCsr[pOp->p1]; | 
| assert( pC!=0 ); | 
| assert( pC->isOrdered ); | 
| -  if( ALWAYS(pC->pCursor!=0) ){ | 
| -    assert( pC->deferredMoveto==0 ); | 
| -    assert( pOp->p5==0 || pOp->p5==1 ); | 
| -    assert( pOp->p4type==P4_INT32 ); | 
| -    r.pKeyInfo = pC->pKeyInfo; | 
| -    r.nField = (u16)pOp->p4.i; | 
| -    if( pOp->p5 ){ | 
| -      r.flags = UNPACKED_INCRKEY | UNPACKED_IGNORE_ROWID; | 
| -    }else{ | 
| -      r.flags = UNPACKED_IGNORE_ROWID; | 
| -    } | 
| -    r.aMem = &aMem[pOp->p3]; | 
| +  assert( pC->pCursor!=0); | 
| +  assert( pC->deferredMoveto==0 ); | 
| +  assert( pOp->p5==0 || pOp->p5==1 ); | 
| +  assert( pOp->p4type==P4_INT32 ); | 
| +  r.pKeyInfo = pC->pKeyInfo; | 
| +  r.nField = (u16)pOp->p4.i; | 
| +  if( pOp->opcode<OP_IdxLT ){ | 
| +    assert( pOp->opcode==OP_IdxLE || pOp->opcode==OP_IdxGT ); | 
| +    r.default_rc = -1; | 
| +  }else{ | 
| +    assert( pOp->opcode==OP_IdxGE || pOp->opcode==OP_IdxLT ); | 
| +    r.default_rc = 0; | 
| +  } | 
| +  r.aMem = &aMem[pOp->p3]; | 
| #ifdef SQLITE_DEBUG | 
| -    { int i; for(i=0; i<r.nField; i++) assert( memIsValid(&r.aMem[i]) ); } | 
| +  { int i; for(i=0; i<r.nField; i++) assert( memIsValid(&r.aMem[i]) ); } | 
| #endif | 
| -    rc = sqlite3VdbeIdxKeyCompare(pC, &r, &res); | 
| -    if( pOp->opcode==OP_IdxLT ){ | 
| -      res = -res; | 
| -    }else{ | 
| -      assert( pOp->opcode==OP_IdxGE ); | 
| -      res++; | 
| -    } | 
| -    if( res>0 ){ | 
| -      pc = pOp->p2 - 1 ; | 
| -    } | 
| +  res = 0;  /* Not needed.  Only used to silence a warning. */ | 
| +  rc = sqlite3VdbeIdxKeyCompare(db, pC, &r, &res); | 
| +  assert( (OP_IdxLE&1)==(OP_IdxLT&1) && (OP_IdxGE&1)==(OP_IdxGT&1) ); | 
| +  if( (pOp->opcode&1)==(OP_IdxLT&1) ){ | 
| +    assert( pOp->opcode==OP_IdxLE || pOp->opcode==OP_IdxLT ); | 
| +    res = -res; | 
| +  }else{ | 
| +    assert( pOp->opcode==OP_IdxGE || pOp->opcode==OP_IdxGT ); | 
| +    res++; | 
| +  } | 
| +  VdbeBranchTaken(res>0,2); | 
| +  if( res>0 ){ | 
| +    pc = pOp->p2 - 1 ; | 
| } | 
| break; | 
| } | 
| @@ -4508,15 +4905,19 @@ case OP_Destroy: {     /* out2-prerelease */ | 
| int iCnt; | 
| Vdbe *pVdbe; | 
| int iDb; | 
| + | 
| +  assert( p->readOnly==0 ); | 
| #ifndef SQLITE_OMIT_VIRTUALTABLE | 
| iCnt = 0; | 
| for(pVdbe=db->pVdbe; pVdbe; pVdbe = pVdbe->pNext){ | 
| -    if( pVdbe->magic==VDBE_MAGIC_RUN && pVdbe->inVtabMethod<2 && pVdbe->pc>=0 ){ | 
| +    if( pVdbe->magic==VDBE_MAGIC_RUN && pVdbe->bIsReader | 
| +     && pVdbe->inVtabMethod<2 && pVdbe->pc>=0 | 
| +    ){ | 
| iCnt++; | 
| } | 
| } | 
| #else | 
| -  iCnt = db->activeVdbeCnt; | 
| +  iCnt = db->nVdbeRead; | 
| #endif | 
| pOut->flags = MEM_Null; | 
| if( iCnt>1 ){ | 
| @@ -4525,7 +4926,8 @@ case OP_Destroy: {     /* out2-prerelease */ | 
| }else{ | 
| iDb = pOp->p3; | 
| assert( iCnt==1 ); | 
| -    assert( (p->btreeMask & (((yDbMask)1)<<iDb))!=0 ); | 
| +    assert( DbMaskTest(p->btreeMask, iDb) ); | 
| +    iMoved = 0;  /* Not needed.  Only to silence a warning. */ | 
| rc = sqlite3BtreeDropTable(db->aDb[iDb].pBt, pOp->p1, &iMoved); | 
| pOut->flags = MEM_Int; | 
| pOut->u.i = iMoved; | 
| @@ -4563,7 +4965,8 @@ case OP_Clear: { | 
| int nChange; | 
|  | 
| nChange = 0; | 
| -  assert( (p->btreeMask & (((yDbMask)1)<<pOp->p2))!=0 ); | 
| +  assert( p->readOnly==0 ); | 
| +  assert( DbMaskTest(p->btreeMask, pOp->p2) ); | 
| rc = sqlite3BtreeClearTable( | 
| db->aDb[pOp->p2].pBt, pOp->p1, (pOp->p3 ? &nChange : 0) | 
| ); | 
| @@ -4578,7 +4981,31 @@ case OP_Clear: { | 
| break; | 
| } | 
|  | 
| +/* Opcode: ResetSorter P1 * * * * | 
| +** | 
| +** Delete all contents from the ephemeral table or sorter | 
| +** that is open on cursor P1. | 
| +** | 
| +** This opcode only works for cursors used for sorting and | 
| +** opened with OP_OpenEphemeral or OP_SorterOpen. | 
| +*/ | 
| +case OP_ResetSorter: { | 
| +  VdbeCursor *pC; | 
| + | 
| +  assert( pOp->p1>=0 && pOp->p1<p->nCursor ); | 
| +  pC = p->apCsr[pOp->p1]; | 
| +  assert( pC!=0 ); | 
| +  if( pC->pSorter ){ | 
| +    sqlite3VdbeSorterReset(db, pC->pSorter); | 
| +  }else{ | 
| +    assert( pC->isEphemeral ); | 
| +    rc = sqlite3BtreeClearTableOfCursor(pC->pCursor); | 
| +  } | 
| +  break; | 
| +} | 
| + | 
| /* Opcode: CreateTable P1 P2 * * * | 
| +** Synopsis: r[P2]=root iDb=P1 | 
| ** | 
| ** Allocate a new table in the main database file if P1==0 or in the | 
| ** auxiliary database file if P1==1 or in an attached database if | 
| @@ -4592,6 +5019,7 @@ case OP_Clear: { | 
| ** See also: CreateIndex | 
| */ | 
| /* Opcode: CreateIndex P1 P2 * * * | 
| +** Synopsis: r[P2]=root iDb=P1 | 
| ** | 
| ** Allocate a new index in the main database file if P1==0 or in the | 
| ** auxiliary database file if P1==1 or in an attached database if | 
| @@ -4608,7 +5036,8 @@ case OP_CreateTable: {          /* out2-prerelease */ | 
|  | 
| pgno = 0; | 
| assert( pOp->p1>=0 && pOp->p1<db->nDb ); | 
| -  assert( (p->btreeMask & (((yDbMask)1)<<pOp->p1))!=0 ); | 
| +  assert( DbMaskTest(p->btreeMask, pOp->p1) ); | 
| +  assert( p->readOnly==0 ); | 
| pDb = &db->aDb[pOp->p1]; | 
| assert( pDb->pBt!=0 ); | 
| if( pOp->opcode==OP_CreateTable ){ | 
| @@ -4670,6 +5099,7 @@ case OP_ParseSchema: { | 
| db->init.busy = 0; | 
| } | 
| } | 
| +  if( rc ) sqlite3ResetAllSchemasOfConnection(db); | 
| if( rc==SQLITE_NOMEM ){ | 
| goto no_mem; | 
| } | 
| @@ -4694,7 +5124,8 @@ case OP_LoadAnalysis: { | 
| ** | 
| ** Remove the internal (in-memory) data structures that describe | 
| ** the table named P4 in database P1.  This is called after a table | 
| -** is dropped in order to keep the internal representation of the | 
| +** is dropped from disk (using the Destroy opcode) in order to keep | 
| +** the internal representation of the | 
| ** schema consistent with what is on disk. | 
| */ | 
| case OP_DropTable: { | 
| @@ -4706,7 +5137,8 @@ case OP_DropTable: { | 
| ** | 
| ** Remove the internal (in-memory) data structures that describe | 
| ** the index named P4 in database P1.  This is called after an index | 
| -** is dropped in order to keep the internal representation of the | 
| +** is dropped from disk (using the Destroy opcode) | 
| +** in order to keep the internal representation of the | 
| ** schema consistent with what is on disk. | 
| */ | 
| case OP_DropIndex: { | 
| @@ -4718,7 +5150,8 @@ case OP_DropIndex: { | 
| ** | 
| ** Remove the internal (in-memory) data structures that describe | 
| ** the trigger named P4 in database P1.  This is called after a trigger | 
| -** is dropped in order to keep the internal representation of the | 
| +** is dropped from disk (using the Destroy opcode) in order to keep | 
| +** the internal representation of the | 
| ** schema consistent with what is on disk. | 
| */ | 
| case OP_DropTrigger: { | 
| @@ -4755,12 +5188,13 @@ case OP_IntegrityCk: { | 
| int nErr;       /* Number of errors reported */ | 
| char *z;        /* Text of the error report */ | 
| Mem *pnErr;     /* Register keeping track of errors remaining */ | 
| - | 
| + | 
| +  assert( p->bIsReader ); | 
| nRoot = pOp->p2; | 
| assert( nRoot>0 ); | 
| aRoot = sqlite3DbMallocRaw(db, sizeof(int)*(nRoot+1) ); | 
| if( aRoot==0 ) goto no_mem; | 
| -  assert( pOp->p3>0 && pOp->p3<=p->nMem ); | 
| +  assert( pOp->p3>0 && pOp->p3<=(p->nMem-p->nCursor) ); | 
| pnErr = &aMem[pOp->p3]; | 
| assert( (pnErr->flags & MEM_Int)!=0 ); | 
| assert( (pnErr->flags & (MEM_Str|MEM_Blob))==0 ); | 
| @@ -4770,7 +5204,7 @@ case OP_IntegrityCk: { | 
| } | 
| aRoot[j] = 0; | 
| assert( pOp->p5<db->nDb ); | 
| -  assert( (p->btreeMask & (((yDbMask)1)<<pOp->p5))!=0 ); | 
| +  assert( DbMaskTest(p->btreeMask, pOp->p5) ); | 
| z = sqlite3BtreeIntegrityCheck(db->aDb[pOp->p5].pBt, aRoot, nRoot, | 
| (int)pnErr->u.i, &nErr); | 
| sqlite3DbFree(db, aRoot); | 
| @@ -4790,6 +5224,7 @@ case OP_IntegrityCk: { | 
| #endif /* SQLITE_OMIT_INTEGRITY_CHECK */ | 
|  | 
| /* Opcode: RowSetAdd P1 P2 * * * | 
| +** Synopsis:  rowset(P1)=r[P2] | 
| ** | 
| ** Insert the integer value held by register P2 into a boolean index | 
| ** held in register P1. | 
| @@ -4809,6 +5244,7 @@ case OP_RowSetAdd: {       /* in1, in2 */ | 
| } | 
|  | 
| /* Opcode: RowSetRead P1 P2 P3 * * | 
| +** Synopsis:  r[P3]=rowset(P1) | 
| ** | 
| ** Extract the smallest value from boolean index P1 and put that value into | 
| ** register P3.  Or, if boolean index P1 is initially empty, leave P3 | 
| @@ -4816,7 +5252,7 @@ case OP_RowSetAdd: {       /* in1, in2 */ | 
| */ | 
| case OP_RowSetRead: {       /* jump, in1, out3 */ | 
| i64 val; | 
| -  CHECK_FOR_INTERRUPT; | 
| + | 
| pIn1 = &aMem[pOp->p1]; | 
| if( (pIn1->flags & MEM_RowSet)==0 | 
| || sqlite3RowSetNext(pIn1->u.pRowSet, &val)==0 | 
| @@ -4824,14 +5260,17 @@ case OP_RowSetRead: {       /* jump, in1, out3 */ | 
| /* The boolean index is empty */ | 
| sqlite3VdbeMemSetNull(pIn1); | 
| pc = pOp->p2 - 1; | 
| +    VdbeBranchTaken(1,2); | 
| }else{ | 
| /* A value was pulled from the index */ | 
| sqlite3VdbeMemSetInt64(&aMem[pOp->p3], val); | 
| +    VdbeBranchTaken(0,2); | 
| } | 
| -  break; | 
| +  goto check_for_interrupt; | 
| } | 
|  | 
| /* Opcode: RowSetTest P1 P2 P3 P4 | 
| +** Synopsis: if r[P3] in rowset(P1) goto P2 | 
| ** | 
| ** Register P3 is assumed to hold a 64-bit integer value. If register P1 | 
| ** contains a RowSet object and that RowSet object contains | 
| @@ -4874,9 +5313,8 @@ case OP_RowSetTest: {                     /* jump, in1, in3 */ | 
| assert( pOp->p4type==P4_INT32 ); | 
| assert( iSet==-1 || iSet>=0 ); | 
| if( iSet ){ | 
| -    exists = sqlite3RowSetTest(pIn1->u.pRowSet, | 
| -                               (u8)(iSet>=0 ? iSet & 0xf : 0xff), | 
| -                               pIn3->u.i); | 
| +    exists = sqlite3RowSetTest(pIn1->u.pRowSet, iSet, pIn3->u.i); | 
| +    VdbeBranchTaken(exists!=0,2); | 
| if( exists ){ | 
| pc = pOp->p2 - 1; | 
| break; | 
| @@ -4891,7 +5329,7 @@ case OP_RowSetTest: {                     /* jump, in1, in3 */ | 
|  | 
| #ifndef SQLITE_OMIT_TRIGGER | 
|  | 
| -/* Opcode: Program P1 P2 P3 P4 * | 
| +/* Opcode: Program P1 P2 P3 P4 P5 | 
| ** | 
| ** Execute the trigger program passed as P4 (type P4_SUBPROGRAM). | 
| ** | 
| @@ -4903,6 +5341,8 @@ case OP_RowSetTest: {                     /* jump, in1, in3 */ | 
| ** memory required by the sub-vdbe at runtime. | 
| ** | 
| ** P4 is a pointer to the VM containing the trigger program. | 
| +** | 
| +** If P5 is non-zero, then recursive program invocation is enabled. | 
| */ | 
| case OP_Program: {        /* jump */ | 
| int nMem;               /* Number of memory registers for sub-program */ | 
| @@ -4916,7 +5356,6 @@ case OP_Program: {        /* jump */ | 
|  | 
| pProgram = pOp->p4.pProgram; | 
| pRt = &aMem[pOp->p3]; | 
| -  assert( memIsValid(pRt) ); | 
| assert( pProgram->nOp>0 ); | 
|  | 
| /* If the p5 flag is clear, then recursive invocation of triggers is | 
| @@ -4955,7 +5394,8 @@ case OP_Program: {        /* jump */ | 
| nMem = pProgram->nMem + pProgram->nCsr; | 
| nByte = ROUND8(sizeof(VdbeFrame)) | 
| + nMem * sizeof(Mem) | 
| -              + pProgram->nCsr * sizeof(VdbeCursor *); | 
| +              + pProgram->nCsr * sizeof(VdbeCursor *) | 
| +              + pProgram->nOnce * sizeof(u8); | 
| pFrame = sqlite3DbMallocZero(db, nByte); | 
| if( !pFrame ){ | 
| goto no_mem; | 
| @@ -4975,10 +5415,12 @@ case OP_Program: {        /* jump */ | 
| pFrame->aOp = p->aOp; | 
| pFrame->nOp = p->nOp; | 
| pFrame->token = pProgram->token; | 
| +    pFrame->aOnceFlag = p->aOnceFlag; | 
| +    pFrame->nOnceFlag = p->nOnceFlag; | 
|  | 
| pEnd = &VdbeFrameMem(pFrame)[pFrame->nChildMem]; | 
| for(pMem=VdbeFrameMem(pFrame); pMem!=pEnd; pMem++){ | 
| -      pMem->flags = MEM_Null; | 
| +      pMem->flags = MEM_Undefined; | 
| pMem->db = db; | 
| } | 
| }else{ | 
| @@ -4990,7 +5432,7 @@ case OP_Program: {        /* jump */ | 
|  | 
| p->nFrame++; | 
| pFrame->pParent = p->pFrame; | 
| -  pFrame->lastRowid = db->lastRowid; | 
| +  pFrame->lastRowid = lastRowid; | 
| pFrame->nChange = p->nChange; | 
| p->nChange = 0; | 
| p->pFrame = pFrame; | 
| @@ -5000,7 +5442,10 @@ case OP_Program: {        /* jump */ | 
| p->apCsr = (VdbeCursor **)&aMem[p->nMem+1]; | 
| p->aOp = aOp = pProgram->aOp; | 
| p->nOp = pProgram->nOp; | 
| +  p->aOnceFlag = (u8 *)&p->apCsr[p->nCursor]; | 
| +  p->nOnceFlag = pProgram->nOnce; | 
| pc = -1; | 
| +  memset(p->aOnceFlag, 0, p->nOnceFlag); | 
|  | 
| break; | 
| } | 
| @@ -5030,6 +5475,7 @@ case OP_Param: {           /* out2-prerelease */ | 
|  | 
| #ifndef SQLITE_OMIT_FOREIGN_KEY | 
| /* Opcode: FkCounter P1 P2 * * * | 
| +** Synopsis: fkctr[P1]+=P2 | 
| ** | 
| ** Increment a "constraint counter" by P2 (P2 may be negative or positive). | 
| ** If P1 is non-zero, the database constraint counter is incremented | 
| @@ -5037,7 +5483,9 @@ case OP_Param: {           /* out2-prerelease */ | 
| ** statement counter is incremented (immediate foreign key constraints). | 
| */ | 
| case OP_FkCounter: { | 
| -  if( pOp->p1 ){ | 
| +  if( db->flags & SQLITE_DeferFKs ){ | 
| +    db->nDeferredImmCons += pOp->p2; | 
| +  }else if( pOp->p1 ){ | 
| db->nDeferredCons += pOp->p2; | 
| }else{ | 
| p->nFkConstraint += pOp->p2; | 
| @@ -5046,6 +5494,7 @@ case OP_FkCounter: { | 
| } | 
|  | 
| /* Opcode: FkIfZero P1 P2 * * * | 
| +** Synopsis: if fkctr[P1]==0 goto P2 | 
| ** | 
| ** This opcode tests if a foreign key constraint-counter is currently zero. | 
| ** If so, jump to instruction P2. Otherwise, fall through to the next | 
| @@ -5058,9 +5507,11 @@ case OP_FkCounter: { | 
| */ | 
| case OP_FkIfZero: {         /* jump */ | 
| if( pOp->p1 ){ | 
| -    if( db->nDeferredCons==0 ) pc = pOp->p2-1; | 
| +    VdbeBranchTaken(db->nDeferredCons==0 && db->nDeferredImmCons==0, 2); | 
| +    if( db->nDeferredCons==0 && db->nDeferredImmCons==0 ) pc = pOp->p2-1; | 
| }else{ | 
| -    if( p->nFkConstraint==0 ) pc = pOp->p2-1; | 
| +    VdbeBranchTaken(p->nFkConstraint==0 && db->nDeferredImmCons==0, 2); | 
| +    if( p->nFkConstraint==0 && db->nDeferredImmCons==0 ) pc = pOp->p2-1; | 
| } | 
| break; | 
| } | 
| @@ -5068,6 +5519,7 @@ case OP_FkIfZero: {         /* jump */ | 
|  | 
| #ifndef SQLITE_OMIT_AUTOINCREMENT | 
| /* Opcode: MemMax P1 P2 * * * | 
| +** Synopsis: r[P1]=max(r[P1],r[P2]) | 
| ** | 
| ** P1 is a register in the root frame of this VM (the root frame is | 
| ** different from the current frame if this instruction is being executed | 
| @@ -5078,7 +5530,6 @@ case OP_FkIfZero: {         /* jump */ | 
| ** an integer. | 
| */ | 
| case OP_MemMax: {        /* in2 */ | 
| -  Mem *pIn1; | 
| VdbeFrame *pFrame; | 
| if( p->pFrame ){ | 
| for(pFrame=p->pFrame; pFrame->pParent; pFrame=pFrame->pParent); | 
| @@ -5098,6 +5549,7 @@ case OP_MemMax: {        /* in2 */ | 
| #endif /* SQLITE_OMIT_AUTOINCREMENT */ | 
|  | 
| /* Opcode: IfPos P1 P2 * * * | 
| +** Synopsis: if r[P1]>0 goto P2 | 
| ** | 
| ** If the value of register P1 is 1 or greater, jump to P2. | 
| ** | 
| @@ -5107,22 +5559,24 @@ case OP_MemMax: {        /* in2 */ | 
| case OP_IfPos: {        /* jump, in1 */ | 
| pIn1 = &aMem[pOp->p1]; | 
| assert( pIn1->flags&MEM_Int ); | 
| +  VdbeBranchTaken( pIn1->u.i>0, 2); | 
| if( pIn1->u.i>0 ){ | 
| pc = pOp->p2 - 1; | 
| } | 
| break; | 
| } | 
|  | 
| -/* Opcode: IfNeg P1 P2 * * * | 
| -** | 
| -** If the value of register P1 is less than zero, jump to P2. | 
| +/* Opcode: IfNeg P1 P2 P3 * * | 
| +** Synopsis: r[P1]+=P3, if r[P1]<0 goto P2 | 
| ** | 
| -** It is illegal to use this instruction on a register that does | 
| -** not contain an integer.  An assertion fault will result if you try. | 
| +** Register P1 must contain an integer.  Add literal P3 to the value in | 
| +** register P1 then if the value of register P1 is less than zero, jump to P2. | 
| */ | 
| case OP_IfNeg: {        /* jump, in1 */ | 
| pIn1 = &aMem[pOp->p1]; | 
| assert( pIn1->flags&MEM_Int ); | 
| +  pIn1->u.i += pOp->p3; | 
| +  VdbeBranchTaken(pIn1->u.i<0, 2); | 
| if( pIn1->u.i<0 ){ | 
| pc = pOp->p2 - 1; | 
| } | 
| @@ -5130,17 +5584,16 @@ case OP_IfNeg: {        /* jump, in1 */ | 
| } | 
|  | 
| /* Opcode: IfZero P1 P2 P3 * * | 
| +** Synopsis: r[P1]+=P3, if r[P1]==0 goto P2 | 
| ** | 
| ** The register P1 must contain an integer.  Add literal P3 to the | 
| ** value in register P1.  If the result is exactly 0, jump to P2. | 
| -** | 
| -** It is illegal to use this instruction on a register that does | 
| -** not contain an integer.  An assertion fault will result if you try. | 
| */ | 
| case OP_IfZero: {        /* jump, in1 */ | 
| pIn1 = &aMem[pOp->p1]; | 
| assert( pIn1->flags&MEM_Int ); | 
| pIn1->u.i += pOp->p3; | 
| +  VdbeBranchTaken(pIn1->u.i==0, 2); | 
| if( pIn1->u.i==0 ){ | 
| pc = pOp->p2 - 1; | 
| } | 
| @@ -5148,6 +5601,7 @@ case OP_IfZero: {        /* jump, in1 */ | 
| } | 
|  | 
| /* Opcode: AggStep * P2 P3 P4 P5 | 
| +** Synopsis: accum=r[P3] step(r[P2@P5]) | 
| ** | 
| ** Execute the step function for an aggregate.  The | 
| ** function has P5 arguments.   P4 is a pointer to the FuncDef | 
| @@ -5162,6 +5616,7 @@ case OP_AggStep: { | 
| int i; | 
| Mem *pMem; | 
| Mem *pRec; | 
| +  Mem t; | 
| sqlite3_context ctx; | 
| sqlite3_value **apVal; | 
|  | 
| @@ -5174,37 +5629,33 @@ case OP_AggStep: { | 
| assert( memIsValid(pRec) ); | 
| apVal[i] = pRec; | 
| memAboutToChange(p, pRec); | 
| -    sqlite3VdbeMemStoreType(pRec); | 
| } | 
| ctx.pFunc = pOp->p4.pFunc; | 
| -  assert( pOp->p3>0 && pOp->p3<=p->nMem ); | 
| +  assert( pOp->p3>0 && pOp->p3<=(p->nMem-p->nCursor) ); | 
| ctx.pMem = pMem = &aMem[pOp->p3]; | 
| pMem->n++; | 
| -  ctx.s.flags = MEM_Null; | 
| -  ctx.s.z = 0; | 
| -  ctx.s.zMalloc = 0; | 
| -  ctx.s.xDel = 0; | 
| -  ctx.s.db = db; | 
| +  sqlite3VdbeMemInit(&t, db, MEM_Null); | 
| +  ctx.pOut = &t; | 
| ctx.isError = 0; | 
| -  ctx.pColl = 0; | 
| -  if( ctx.pFunc->flags & SQLITE_FUNC_NEEDCOLL ){ | 
| -    assert( pOp>p->aOp ); | 
| -    assert( pOp[-1].p4type==P4_COLLSEQ ); | 
| -    assert( pOp[-1].opcode==OP_CollSeq ); | 
| -    ctx.pColl = pOp[-1].p4.pColl; | 
| -  } | 
| +  ctx.pVdbe = p; | 
| +  ctx.iOp = pc; | 
| +  ctx.skipFlag = 0; | 
| (ctx.pFunc->xStep)(&ctx, n, apVal); /* IMP: R-24505-23230 */ | 
| if( ctx.isError ){ | 
| -    sqlite3SetString(&p->zErrMsg, db, "%s", sqlite3_value_text(&ctx.s)); | 
| +    sqlite3SetString(&p->zErrMsg, db, "%s", sqlite3_value_text(&t)); | 
| rc = ctx.isError; | 
| } | 
| - | 
| -  sqlite3VdbeMemRelease(&ctx.s); | 
| - | 
| +  if( ctx.skipFlag ){ | 
| +    assert( pOp[-1].opcode==OP_CollSeq ); | 
| +    i = pOp[-1].p1; | 
| +    if( i ) sqlite3VdbeMemSetInt64(&aMem[i], 1); | 
| +  } | 
| +  sqlite3VdbeMemRelease(&t); | 
| break; | 
| } | 
|  | 
| /* Opcode: AggFinal P1 P2 * P4 * | 
| +** Synopsis: accum=r[P1] N=P2 | 
| ** | 
| ** Execute the finalizer function for an aggregate.  P1 is | 
| ** the memory location that is the accumulator for the aggregate. | 
| @@ -5218,7 +5669,7 @@ case OP_AggStep: { | 
| */ | 
| case OP_AggFinal: { | 
| Mem *pMem; | 
| -  assert( pOp->p1>0 && pOp->p1<=p->nMem ); | 
| +  assert( pOp->p1>0 && pOp->p1<=(p->nMem-p->nCursor) ); | 
| pMem = &aMem[pOp->p1]; | 
| assert( (pMem->flags & ~(MEM_Null|MEM_Agg))==0 ); | 
| rc = sqlite3VdbeMemFinalize(pMem, pOp->p4.pFunc); | 
| @@ -5250,6 +5701,7 @@ case OP_Checkpoint: { | 
| int aRes[3];                    /* Results */ | 
| Mem *pMem;                      /* Write results here */ | 
|  | 
| +  assert( p->readOnly==0 ); | 
| aRes[0] = 0; | 
| aRes[1] = aRes[2] = -1; | 
| assert( pOp->p2==SQLITE_CHECKPOINT_PASSIVE | 
| @@ -5269,7 +5721,7 @@ case OP_Checkpoint: { | 
| #endif | 
|  | 
| #ifndef SQLITE_OMIT_PRAGMA | 
| -/* Opcode: JournalMode P1 P2 P3 * P5 | 
| +/* Opcode: JournalMode P1 P2 P3 * * | 
| ** | 
| ** Change the journal mode of database P1 to P3. P3 must be one of the | 
| ** PAGER_JOURNALMODE_XXX values. If changing between the various rollback | 
| @@ -5285,7 +5737,9 @@ case OP_JournalMode: {    /* out2-prerelease */ | 
| Pager *pPager;                  /* Pager associated with pBt */ | 
| int eNew;                       /* New journal mode */ | 
| int eOld;                       /* The old journal mode */ | 
| +#ifndef SQLITE_OMIT_WAL | 
| const char *zFilename;          /* Name of database file for pPager */ | 
| +#endif | 
|  | 
| eNew = pOp->p3; | 
| assert( eNew==PAGER_JOURNALMODE_DELETE | 
| @@ -5297,6 +5751,7 @@ case OP_JournalMode: {    /* out2-prerelease */ | 
| || eNew==PAGER_JOURNALMODE_QUERY | 
| ); | 
| assert( pOp->p1>=0 && pOp->p1<db->nDb ); | 
| +  assert( p->readOnly==0 ); | 
|  | 
| pBt = db->aDb[pOp->p1].pBt; | 
| pPager = sqlite3BtreePager(pBt); | 
| @@ -5305,13 +5760,13 @@ case OP_JournalMode: {    /* out2-prerelease */ | 
| if( !sqlite3PagerOkToChangeJournalMode(pPager) ) eNew = eOld; | 
|  | 
| #ifndef SQLITE_OMIT_WAL | 
| -  zFilename = sqlite3PagerFilename(pPager); | 
| +  zFilename = sqlite3PagerFilename(pPager, 1); | 
|  | 
| /* Do not allow a transition to journal_mode=WAL for a database | 
| ** in temporary storage or if the VFS does not support shared memory | 
| */ | 
| if( eNew==PAGER_JOURNALMODE_WAL | 
| -   && (zFilename[0]==0                         /* Temp file */ | 
| +   && (sqlite3Strlen30(zFilename)==0           /* Temp file */ | 
| || !sqlite3PagerWalSupported(pPager))   /* No shared-memory support */ | 
| ){ | 
| eNew = eOld; | 
| @@ -5320,7 +5775,7 @@ case OP_JournalMode: {    /* out2-prerelease */ | 
| if( (eNew!=eOld) | 
| && (eOld==PAGER_JOURNALMODE_WAL || eNew==PAGER_JOURNALMODE_WAL) | 
| ){ | 
| -    if( !db->autoCommit || db->activeVdbeCnt>1 ){ | 
| +    if( !db->autoCommit || db->nVdbeRead>1 ){ | 
| rc = SQLITE_ERROR; | 
| sqlite3SetString(&p->zErrMsg, db, | 
| "cannot change %s wal mode from within a transaction", | 
| @@ -5379,6 +5834,7 @@ case OP_JournalMode: {    /* out2-prerelease */ | 
| ** a transaction. | 
| */ | 
| case OP_Vacuum: { | 
| +  assert( p->readOnly==0 ); | 
| rc = sqlite3RunVacuum(&p->zErrMsg, db); | 
| break; | 
| } | 
| @@ -5395,9 +5851,11 @@ case OP_IncrVacuum: {        /* jump */ | 
| Btree *pBt; | 
|  | 
| assert( pOp->p1>=0 && pOp->p1<db->nDb ); | 
| -  assert( (p->btreeMask & (((yDbMask)1)<<pOp->p1))!=0 ); | 
| +  assert( DbMaskTest(p->btreeMask, pOp->p1) ); | 
| +  assert( p->readOnly==0 ); | 
| pBt = db->aDb[pOp->p1].pBt; | 
| rc = sqlite3BtreeIncrVacuum(pBt); | 
| +  VdbeBranchTaken(rc==SQLITE_DONE,2); | 
| if( rc==SQLITE_DONE ){ | 
| pc = pOp->p2 - 1; | 
| rc = SQLITE_OK; | 
| @@ -5408,12 +5866,13 @@ case OP_IncrVacuum: {        /* jump */ | 
|  | 
| /* Opcode: Expire P1 * * * * | 
| ** | 
| -** Cause precompiled statements to become expired. An expired statement | 
| -** fails with an error code of SQLITE_SCHEMA if it is ever executed | 
| -** (via sqlite3_step()). | 
| +** Cause precompiled statements to expire.  When an expired statement | 
| +** is executed using sqlite3_step() it will either automatically | 
| +** reprepare itself (if it was originally created using sqlite3_prepare_v2()) | 
| +** or it will fail with SQLITE_SCHEMA. | 
| ** | 
| ** If P1 is 0, then all SQL statements become expired. If P1 is non-zero, | 
| -** then only the currently executing statement is affected. | 
| +** then only the currently executing statement is expired. | 
| */ | 
| case OP_Expire: { | 
| if( !pOp->p1 ){ | 
| @@ -5426,6 +5885,7 @@ case OP_Expire: { | 
|  | 
| #ifndef SQLITE_OMIT_SHARED_CACHE | 
| /* Opcode: TableLock P1 P2 P3 P4 * | 
| +** Synopsis: iDb=P1 root=P2 write=P3 | 
| ** | 
| ** Obtain a lock on a particular table. This instruction is only used when | 
| ** the shared-cache feature is enabled. | 
| @@ -5444,7 +5904,7 @@ case OP_TableLock: { | 
| if( isWriteLock || 0==(db->flags&SQLITE_ReadUncommitted) ){ | 
| int p1 = pOp->p1; | 
| assert( p1>=0 && p1<db->nDb ); | 
| -    assert( (p->btreeMask & (((yDbMask)1)<<p1))!=0 ); | 
| +    assert( DbMaskTest(p->btreeMask, p1) ); | 
| assert( isWriteLock==0 || isWriteLock==1 ); | 
| rc = sqlite3BtreeLockTable(db->aDb[p1].pBt, pOp->p2, isWriteLock); | 
| if( (rc&0xFF)==SQLITE_LOCKED ){ | 
| @@ -5470,7 +5930,7 @@ case OP_VBegin: { | 
| VTable *pVTab; | 
| pVTab = pOp->p4.pVtab; | 
| rc = sqlite3VtabBegin(db, pVTab); | 
| -  if( pVTab ) importVtabErrMsg(p, pVTab->pVtab); | 
| +  if( pVTab ) sqlite3VtabImportErrmsg(p, pVTab->pVtab); | 
| break; | 
| } | 
| #endif /* SQLITE_OMIT_VIRTUALTABLE */ | 
| @@ -5514,22 +5974,22 @@ case OP_VOpen: { | 
| sqlite3_vtab *pVtab; | 
| sqlite3_module *pModule; | 
|  | 
| +  assert( p->bIsReader ); | 
| pCur = 0; | 
| pVtabCursor = 0; | 
| pVtab = pOp->p4.pVtab->pVtab; | 
| pModule = (sqlite3_module *)pVtab->pModule; | 
| assert(pVtab && pModule); | 
| rc = pModule->xOpen(pVtab, &pVtabCursor); | 
| -  importVtabErrMsg(p, pVtab); | 
| +  sqlite3VtabImportErrmsg(p, pVtab); | 
| if( SQLITE_OK==rc ){ | 
| /* Initialize sqlite3_vtab_cursor base class */ | 
| pVtabCursor->pVtab = pVtab; | 
|  | 
| -    /* Initialise vdbe cursor object */ | 
| +    /* Initialize vdbe cursor object */ | 
| pCur = allocateCursor(p, pOp->p1, 0, -1, 0); | 
| if( pCur ){ | 
| pCur->pVtabCursor = pVtabCursor; | 
| -      pCur->pModule = pVtabCursor->pVtab->pModule; | 
| }else{ | 
| db->mallocFailed = 1; | 
| pModule->xClose(pVtabCursor); | 
| @@ -5541,6 +6001,7 @@ case OP_VOpen: { | 
|  | 
| #ifndef SQLITE_OMIT_VIRTUALTABLE | 
| /* Opcode: VFilter P1 P2 P3 P4 * | 
| +** Synopsis: iplan=r[P3] zplan='P4' | 
| ** | 
| ** P1 is a cursor opened using VOpen.  P2 is an address to jump to if | 
| ** the filtered result set is empty. | 
| @@ -5592,17 +6053,16 @@ case OP_VFilter: {   /* jump */ | 
| apArg = p->apArg; | 
| for(i = 0; i<nArg; i++){ | 
| apArg[i] = &pArgc[i+1]; | 
| -      sqlite3VdbeMemStoreType(apArg[i]); | 
| } | 
|  | 
| p->inVtabMethod = 1; | 
| rc = pModule->xFilter(pVtabCursor, iQuery, pOp->p4.z, nArg, apArg); | 
| p->inVtabMethod = 0; | 
| -    importVtabErrMsg(p, pVtab); | 
| +    sqlite3VtabImportErrmsg(p, pVtab); | 
| if( rc==SQLITE_OK ){ | 
| res = pModule->xEof(pVtabCursor); | 
| } | 
| - | 
| +    VdbeBranchTaken(res!=0,2); | 
| if( res ){ | 
| pc = pOp->p2 - 1; | 
| } | 
| @@ -5615,6 +6075,7 @@ case OP_VFilter: {   /* jump */ | 
|  | 
| #ifndef SQLITE_OMIT_VIRTUALTABLE | 
| /* Opcode: VColumn P1 P2 P3 * * | 
| +** Synopsis: r[P3]=vcolumn(P2) | 
| ** | 
| ** Store the value of the P2-th column of | 
| ** the row of the virtual-table that the | 
| @@ -5628,7 +6089,7 @@ case OP_VColumn: { | 
|  | 
| VdbeCursor *pCur = p->apCsr[pOp->p1]; | 
| assert( pCur->pVtabCursor ); | 
| -  assert( pOp->p3>0 && pOp->p3<=p->nMem ); | 
| +  assert( pOp->p3>0 && pOp->p3<=(p->nMem-p->nCursor) ); | 
| pDest = &aMem[pOp->p3]; | 
| memAboutToChange(p, pDest); | 
| if( pCur->nullRow ){ | 
| @@ -5639,27 +6100,14 @@ case OP_VColumn: { | 
| pModule = pVtab->pModule; | 
| assert( pModule->xColumn ); | 
| memset(&sContext, 0, sizeof(sContext)); | 
| - | 
| -  /* The output cell may already have a buffer allocated. Move | 
| -  ** the current contents to sContext.s so in case the user-function | 
| -  ** can use the already allocated buffer instead of allocating a | 
| -  ** new one. | 
| -  */ | 
| -  sqlite3VdbeMemMove(&sContext.s, pDest); | 
| -  MemSetTypeFlag(&sContext.s, MEM_Null); | 
| - | 
| +  sContext.pOut = pDest; | 
| +  MemSetTypeFlag(pDest, MEM_Null); | 
| rc = pModule->xColumn(pCur->pVtabCursor, &sContext, pOp->p2); | 
| -  importVtabErrMsg(p, pVtab); | 
| +  sqlite3VtabImportErrmsg(p, pVtab); | 
| if( sContext.isError ){ | 
| rc = sContext.isError; | 
| } | 
| - | 
| -  /* Copy the result of the function to the P3 register. We | 
| -  ** do this regardless of whether or not an error occurred to ensure any | 
| -  ** dynamic allocation in sContext.s (a Mem struct) is  released. | 
| -  */ | 
| -  sqlite3VdbeChangeEncoding(&sContext.s, encoding); | 
| -  sqlite3VdbeMemMove(pDest, &sContext.s); | 
| +  sqlite3VdbeChangeEncoding(pDest, encoding); | 
| REGISTER_TRACE(pOp->p3, pDest); | 
| UPDATE_MAX_BLOBSIZE(pDest); | 
|  | 
| @@ -5702,16 +6150,16 @@ case OP_VNext: {   /* jump */ | 
| p->inVtabMethod = 1; | 
| rc = pModule->xNext(pCur->pVtabCursor); | 
| p->inVtabMethod = 0; | 
| -  importVtabErrMsg(p, pVtab); | 
| +  sqlite3VtabImportErrmsg(p, pVtab); | 
| if( rc==SQLITE_OK ){ | 
| res = pModule->xEof(pCur->pVtabCursor); | 
| } | 
| - | 
| +  VdbeBranchTaken(!res,2); | 
| if( !res ){ | 
| /* If there is data, jump to P2 */ | 
| pc = pOp->p2 - 1; | 
| } | 
| -  break; | 
| +  goto check_for_interrupt; | 
| } | 
| #endif /* SQLITE_OMIT_VIRTUALTABLE */ | 
|  | 
| @@ -5730,18 +6178,25 @@ case OP_VRename: { | 
| pName = &aMem[pOp->p1]; | 
| assert( pVtab->pModule->xRename ); | 
| assert( memIsValid(pName) ); | 
| +  assert( p->readOnly==0 ); | 
| REGISTER_TRACE(pOp->p1, pName); | 
| assert( pName->flags & MEM_Str ); | 
| -  rc = pVtab->pModule->xRename(pVtab, pName->z); | 
| -  importVtabErrMsg(p, pVtab); | 
| -  p->expired = 0; | 
| - | 
| +  testcase( pName->enc==SQLITE_UTF8 ); | 
| +  testcase( pName->enc==SQLITE_UTF16BE ); | 
| +  testcase( pName->enc==SQLITE_UTF16LE ); | 
| +  rc = sqlite3VdbeChangeEncoding(pName, SQLITE_UTF8); | 
| +  if( rc==SQLITE_OK ){ | 
| +    rc = pVtab->pModule->xRename(pVtab, pName->z); | 
| +    sqlite3VtabImportErrmsg(p, pVtab); | 
| +    p->expired = 0; | 
| +  } | 
| break; | 
| } | 
| #endif | 
|  | 
| #ifndef SQLITE_OMIT_VIRTUALTABLE | 
| -/* Opcode: VUpdate P1 P2 P3 P4 * | 
| +/* Opcode: VUpdate P1 P2 P3 P4 P5 | 
| +** Synopsis: data=r[P3@P2] | 
| ** | 
| ** P4 is a pointer to a virtual table object, an sqlite3_vtab structure. | 
| ** This opcode invokes the corresponding xUpdate method. P2 values | 
| @@ -5763,6 +6218,9 @@ case OP_VRename: { | 
| ** P1 is a boolean flag. If it is set to true and the xUpdate call | 
| ** is successful, then the value returned by sqlite3_last_insert_rowid() | 
| ** is set to the value of the rowid for the row just inserted. | 
| +** | 
| +** P5 is the error actions (OE_Replace, OE_Fail, OE_Ignore, etc) to | 
| +** apply in the case of a constraint failure on an insert or update. | 
| */ | 
| case OP_VUpdate: { | 
| sqlite3_vtab *pVtab; | 
| @@ -5773,27 +6231,41 @@ case OP_VUpdate: { | 
| Mem **apArg; | 
| Mem *pX; | 
|  | 
| +  assert( pOp->p2==1        || pOp->p5==OE_Fail   || pOp->p5==OE_Rollback | 
| +       || pOp->p5==OE_Abort || pOp->p5==OE_Ignore || pOp->p5==OE_Replace | 
| +  ); | 
| +  assert( p->readOnly==0 ); | 
| pVtab = pOp->p4.pVtab->pVtab; | 
| pModule = (sqlite3_module *)pVtab->pModule; | 
| nArg = pOp->p2; | 
| assert( pOp->p4type==P4_VTAB ); | 
| if( ALWAYS(pModule->xUpdate) ){ | 
| +    u8 vtabOnConflict = db->vtabOnConflict; | 
| apArg = p->apArg; | 
| pX = &aMem[pOp->p3]; | 
| for(i=0; i<nArg; i++){ | 
| assert( memIsValid(pX) ); | 
| memAboutToChange(p, pX); | 
| -      sqlite3VdbeMemStoreType(pX); | 
| apArg[i] = pX; | 
| pX++; | 
| } | 
| +    db->vtabOnConflict = pOp->p5; | 
| rc = pModule->xUpdate(pVtab, nArg, apArg, &rowid); | 
| -    importVtabErrMsg(p, pVtab); | 
| +    db->vtabOnConflict = vtabOnConflict; | 
| +    sqlite3VtabImportErrmsg(p, pVtab); | 
| if( rc==SQLITE_OK && pOp->p1 ){ | 
| assert( nArg>1 && apArg[0] && (apArg[0]->flags&MEM_Null) ); | 
| -      db->lastRowid = rowid; | 
| +      db->lastRowid = lastRowid = rowid; | 
| +    } | 
| +    if( (rc&0xff)==SQLITE_CONSTRAINT && pOp->p4.pVtab->bConstraint ){ | 
| +      if( pOp->p5==OE_Ignore ){ | 
| +        rc = SQLITE_OK; | 
| +      }else{ | 
| +        p->errorAction = ((pOp->p5==OE_Replace) ? OE_Abort : pOp->p5); | 
| +      } | 
| +    }else{ | 
| +      p->nChange++; | 
| } | 
| -    p->nChange++; | 
| } | 
| break; | 
| } | 
| @@ -5836,31 +6308,54 @@ case OP_MaxPgcnt: {            /* out2-prerelease */ | 
| #endif | 
|  | 
|  | 
| -#ifndef SQLITE_OMIT_TRACE | 
| -/* Opcode: Trace * * * P4 * | 
| +/* Opcode: Init * P2 * P4 * | 
| +** Synopsis:  Start at P2 | 
| +** | 
| +** Programs contain a single instance of this opcode as the very first | 
| +** opcode. | 
| ** | 
| ** If tracing is enabled (by the sqlite3_trace()) interface, then | 
| ** the UTF-8 string contained in P4 is emitted on the trace callback. | 
| +** Or if P4 is blank, use the string returned by sqlite3_sql(). | 
| +** | 
| +** If P2 is not zero, jump to instruction P2. | 
| */ | 
| -case OP_Trace: { | 
| +case OP_Init: {          /* jump */ | 
| char *zTrace; | 
| +  char *z; | 
|  | 
| +  if( pOp->p2 ){ | 
| +    pc = pOp->p2 - 1; | 
| +  } | 
| +#ifndef SQLITE_OMIT_TRACE | 
| +  if( db->xTrace | 
| +   && !p->doingRerun | 
| +   && (zTrace = (pOp->p4.z ? pOp->p4.z : p->zSql))!=0 | 
| +  ){ | 
| +    z = sqlite3VdbeExpandSql(p, zTrace); | 
| +    db->xTrace(db->pTraceArg, z); | 
| +    sqlite3DbFree(db, z); | 
| +  } | 
| +#ifdef SQLITE_USE_FCNTL_TRACE | 
| zTrace = (pOp->p4.z ? pOp->p4.z : p->zSql); | 
| if( zTrace ){ | 
| -    if( db->xTrace ){ | 
| -      char *z = sqlite3VdbeExpandSql(p, zTrace); | 
| -      db->xTrace(db->pTraceArg, z); | 
| -      sqlite3DbFree(db, z); | 
| +    int i; | 
| +    for(i=0; i<db->nDb; i++){ | 
| +      if( DbMaskTest(p->btreeMask, i)==0 ) continue; | 
| +      sqlite3_file_control(db, db->aDb[i].zName, SQLITE_FCNTL_TRACE, zTrace); | 
| } | 
| +  } | 
| +#endif /* SQLITE_USE_FCNTL_TRACE */ | 
| #ifdef SQLITE_DEBUG | 
| -    if( (db->flags & SQLITE_SqlTrace)!=0 ){ | 
| -      sqlite3DebugPrintf("SQL-trace: %s\n", zTrace); | 
| -    } | 
| -#endif /* SQLITE_DEBUG */ | 
| +  if( (db->flags & SQLITE_SqlTrace)!=0 | 
| +   && (zTrace = (pOp->p4.z ? pOp->p4.z : p->zSql))!=0 | 
| +  ){ | 
| +    sqlite3DebugPrintf("SQL-trace: %s\n", zTrace); | 
| } | 
| +#endif /* SQLITE_DEBUG */ | 
| +#endif /* SQLITE_OMIT_TRACE */ | 
| break; | 
| } | 
| -#endif | 
|  | 
|  | 
| /* Opcode: Noop * * * * * | 
| @@ -5889,13 +6384,9 @@ default: {          /* This is really OP_Noop and OP_Explain */ | 
|  | 
| #ifdef VDBE_PROFILE | 
| { | 
| -      u64 elapsed = sqlite3Hwtime() - start; | 
| -      pOp->cycles += elapsed; | 
| +      u64 endTime = sqlite3Hwtime(); | 
| +      if( endTime>start ) pOp->cycles += endTime - start; | 
| pOp->cnt++; | 
| -#if 0 | 
| -        fprintf(stdout, "%10llu ", elapsed); | 
| -        sqlite3VdbePrintOp(stdout, origPc, &aOp[origPc]); | 
| -#endif | 
| } | 
| #endif | 
|  | 
| @@ -5908,13 +6399,13 @@ default: {          /* This is really OP_Noop and OP_Explain */ | 
| assert( pc>=-1 && pc<p->nOp ); | 
|  | 
| #ifdef SQLITE_DEBUG | 
| -    if( p->trace ){ | 
| -      if( rc!=0 ) fprintf(p->trace,"rc=%d\n",rc); | 
| +    if( db->flags & SQLITE_VdbeTrace ){ | 
| +      if( rc!=0 ) printf("rc=%d\n",rc); | 
| if( pOp->opflags & (OPFLG_OUT2_PRERELEASE|OPFLG_OUT2) ){ | 
| -        registerTrace(p->trace, pOp->p2, &aMem[pOp->p2]); | 
| +        registerTrace(pOp->p2, &aMem[pOp->p2]); | 
| } | 
| if( pOp->opflags & OPFLG_OUT3 ){ | 
| -        registerTrace(p->trace, pOp->p3, &aMem[pOp->p3]); | 
| +        registerTrace(pOp->p3, &aMem[pOp->p3]); | 
| } | 
| } | 
| #endif  /* SQLITE_DEBUG */ | 
| @@ -5934,13 +6425,16 @@ vdbe_error_halt: | 
| if( rc==SQLITE_IOERR_NOMEM ) db->mallocFailed = 1; | 
| rc = SQLITE_ERROR; | 
| if( resetSchemaOnFault>0 ){ | 
| -    sqlite3ResetInternalSchema(db, resetSchemaOnFault-1); | 
| +    sqlite3ResetOneSchema(db, resetSchemaOnFault-1); | 
| } | 
|  | 
| /* This is the only way out of this procedure.  We have to | 
| ** release the mutexes on btrees that were acquired at the | 
| ** top. */ | 
| vdbe_return: | 
| +  db->lastRowid = lastRowid; | 
| +  testcase( nVmStep>0 ); | 
| +  p->aCounter[SQLITE_STMTSTATUS_VM_STEP] += (int)nVmStep; | 
| sqlite3VdbeLeave(p); | 
| return rc; | 
|  | 
|  |