| Index: third_party/sqlite/src/src/vdbeaux.c
 | 
| diff --git a/third_party/sqlite/src/src/vdbeaux.c b/third_party/sqlite/src/src/vdbeaux.c
 | 
| index dbbb2a6ccb1c0e75f0f2b9f3b1298fb1e78b6971..68f6a5acc84196d391e7c6ac0e75200c542d995d 100644
 | 
| --- a/third_party/sqlite/src/src/vdbeaux.c
 | 
| +++ b/third_party/sqlite/src/src/vdbeaux.c
 | 
| @@ -21,8 +21,9 @@
 | 
|  Vdbe *sqlite3VdbeCreate(Parse *pParse){
 | 
|    sqlite3 *db = pParse->db;
 | 
|    Vdbe *p;
 | 
| -  p = sqlite3DbMallocZero(db, sizeof(Vdbe) );
 | 
| +  p = sqlite3DbMallocRawNN(db, sizeof(Vdbe) );
 | 
|    if( p==0 ) return 0;
 | 
| +  memset(&p->aOp, 0, sizeof(Vdbe)-offsetof(Vdbe,aOp));
 | 
|    p->db = db;
 | 
|    if( db->pVdbe ){
 | 
|      db->pVdbe->pPrev = p;
 | 
| @@ -65,19 +66,12 @@ void sqlite3VdbeSetSql(Vdbe *p, const char *z, int n, int isPrepareV2){
 | 
|  }
 | 
|  
 | 
|  /*
 | 
| -** Return the SQL associated with a prepared statement
 | 
| -*/
 | 
| -const char *sqlite3_sql(sqlite3_stmt *pStmt){
 | 
| -  Vdbe *p = (Vdbe *)pStmt;
 | 
| -  return p ? p->zSql : 0;
 | 
| -}
 | 
| -
 | 
| -/*
 | 
|  ** Swap all content between two VDBE structures.
 | 
|  */
 | 
|  void sqlite3VdbeSwap(Vdbe *pA, Vdbe *pB){
 | 
|    Vdbe tmp, *pTmp;
 | 
|    char *zTmp;
 | 
| +  assert( pA->db==pB->db );
 | 
|    tmp = *pA;
 | 
|    *pA = *pB;
 | 
|    *pB = tmp;
 | 
| @@ -129,7 +123,7 @@ static int growOpArray(Vdbe *v, int nOp){
 | 
|      p->nOpAlloc = p->szOpAlloc/sizeof(Op);
 | 
|      v->aOp = pNew;
 | 
|    }
 | 
| -  return (pNew ? SQLITE_OK : SQLITE_NOMEM);
 | 
| +  return (pNew ? SQLITE_OK : SQLITE_NOMEM_BKPT);
 | 
|  }
 | 
|  
 | 
|  #ifdef SQLITE_DEBUG
 | 
| @@ -171,7 +165,7 @@ int sqlite3VdbeAddOp3(Vdbe *p, int op, int p1, int p2, int p3){
 | 
|  
 | 
|    i = p->nOp;
 | 
|    assert( p->magic==VDBE_MAGIC_INIT );
 | 
| -  assert( op>0 && op<0xff );
 | 
| +  assert( op>=0 && op<0xff );
 | 
|    if( p->pParse->nOpAlloc<=i ){
 | 
|      return growOp3(p, op, p1, p2, p3);
 | 
|    }
 | 
| @@ -191,9 +185,8 @@ int sqlite3VdbeAddOp3(Vdbe *p, int op, int p1, int p2, int p3){
 | 
|    if( p->db->flags & SQLITE_VdbeAddopTrace ){
 | 
|      int jj, kk;
 | 
|      Parse *pParse = p->pParse;
 | 
| -    for(jj=kk=0; jj<SQLITE_N_COLCACHE; jj++){
 | 
| +    for(jj=kk=0; jj<pParse->nColCache; jj++){
 | 
|        struct yColCache *x = pParse->aColCache + jj;
 | 
| -      if( x->iLevel>pParse->iCacheLevel || x->iReg==0 ) continue;
 | 
|        printf(" r[%d]={%d:%d}", x->iReg, x->iTable, x->iColumn);
 | 
|        kk++;
 | 
|      }
 | 
| @@ -250,8 +243,7 @@ void sqlite3VdbeMultiLoad(Vdbe *p, int iDest, const char *zTypes, ...){
 | 
|    for(i=0; (c = zTypes[i])!=0; i++){
 | 
|      if( c=='s' ){
 | 
|        const char *z = va_arg(ap, const char*);
 | 
| -      int addr = sqlite3VdbeAddOp2(p, z==0 ? OP_Null : OP_String8, 0, iDest++);
 | 
| -      if( z ) sqlite3VdbeChangeP4(p, addr, z, 0);
 | 
| +      sqlite3VdbeAddOp4(p, z==0 ? OP_Null : OP_String8, 0, iDest++, 0, z, 0);
 | 
|      }else{
 | 
|        assert( c=='i' );
 | 
|        sqlite3VdbeAddOp2(p, OP_Integer, va_arg(ap, int), iDest++);
 | 
| @@ -290,7 +282,7 @@ int sqlite3VdbeAddOp4Dup8(
 | 
|    const u8 *zP4,      /* The P4 operand */
 | 
|    int p4type          /* P4 operand type */
 | 
|  ){
 | 
| -  char *p4copy = sqlite3DbMallocRaw(sqlite3VdbeDb(p), 8);
 | 
| +  char *p4copy = sqlite3DbMallocRawNN(sqlite3VdbeDb(p), 8);
 | 
|    if( p4copy ) memcpy(p4copy, zP4, 8);
 | 
|    return sqlite3VdbeAddOp4(p, op, p1, p2, p3, p4copy, p4type);
 | 
|  }
 | 
| @@ -305,8 +297,7 @@ int sqlite3VdbeAddOp4Dup8(
 | 
|  */
 | 
|  void sqlite3VdbeAddParseSchemaOp(Vdbe *p, int iDb, char *zWhere){
 | 
|    int j;
 | 
| -  int addr = sqlite3VdbeAddOp3(p, OP_ParseSchema, iDb, 0, 0);
 | 
| -  sqlite3VdbeChangeP4(p, addr, zWhere, P4_DYNAMIC);
 | 
| +  sqlite3VdbeAddOp4(p, OP_ParseSchema, iDb, 0, 0, zWhere, P4_DYNAMIC);
 | 
|    for(j=0; j<p->db->nDb; j++) sqlite3VdbeUsesBtree(p, j);
 | 
|  }
 | 
|  
 | 
| @@ -322,10 +313,29 @@ int sqlite3VdbeAddOp4Int(
 | 
|    int p4              /* The P4 operand as an integer */
 | 
|  ){
 | 
|    int addr = sqlite3VdbeAddOp3(p, op, p1, p2, p3);
 | 
| -  sqlite3VdbeChangeP4(p, addr, SQLITE_INT_TO_PTR(p4), P4_INT32);
 | 
| +  if( p->db->mallocFailed==0 ){
 | 
| +    VdbeOp *pOp = &p->aOp[addr];
 | 
| +    pOp->p4type = P4_INT32;
 | 
| +    pOp->p4.i = p4;
 | 
| +  }
 | 
|    return addr;
 | 
|  }
 | 
|  
 | 
| +/* Insert the end of a co-routine
 | 
| +*/
 | 
| +void sqlite3VdbeEndCoroutine(Vdbe *v, int regYield){
 | 
| +  sqlite3VdbeAddOp1(v, OP_EndCoroutine, regYield);
 | 
| +
 | 
| +  /* Clear the temporary register cache, thereby ensuring that each
 | 
| +  ** co-routine has its own independent set of registers, because co-routines
 | 
| +  ** might expect their registers to be preserved across an OP_Yield, and
 | 
| +  ** that could cause problems if two or more co-routines are using the same
 | 
| +  ** temporary register.
 | 
| +  */
 | 
| +  v->pParse->nTempReg = 0;
 | 
| +  v->pParse->nRangeReg = 0;
 | 
| +}
 | 
| +
 | 
|  /*
 | 
|  ** Create a new symbolic label for an instruction that has yet to be
 | 
|  ** coded.  The symbolic label is really just a negative number.  The
 | 
| @@ -368,7 +378,6 @@ void sqlite3VdbeResolveLabel(Vdbe *v, int x){
 | 
|    if( p->aLabel ){
 | 
|      p->aLabel[j] = v->nOp;
 | 
|    }
 | 
| -  p->iFixedOp = v->nOp - 1;
 | 
|  }
 | 
|  
 | 
|  /*
 | 
| @@ -378,6 +387,13 @@ void sqlite3VdbeRunOnlyOnce(Vdbe *p){
 | 
|    p->runOnlyOnce = 1;
 | 
|  }
 | 
|  
 | 
| +/*
 | 
| +** Mark the VDBE as one that can only be run multiple times.
 | 
| +*/
 | 
| +void sqlite3VdbeReusable(Vdbe *p){
 | 
| +  p->runOnlyOnce = 0;
 | 
| +}
 | 
| +
 | 
|  #ifdef SQLITE_DEBUG /* sqlite3AssertMayAbort() logic */
 | 
|  
 | 
|  /*
 | 
| @@ -524,73 +540,84 @@ int sqlite3VdbeAssertMayAbort(Vdbe *v, int mayAbort){
 | 
|  ** (4) Initialize the p4.xAdvance pointer on opcodes that use it.
 | 
|  **
 | 
|  ** (5) Reclaim the memory allocated for storing labels.
 | 
| +**
 | 
| +** This routine will only function correctly if the mkopcodeh.tcl generator
 | 
| +** script numbers the opcodes correctly.  Changes to this routine must be
 | 
| +** coordinated with changes to mkopcodeh.tcl.
 | 
|  */
 | 
|  static void resolveP2Values(Vdbe *p, int *pMaxFuncArgs){
 | 
| -  int i;
 | 
|    int nMaxArgs = *pMaxFuncArgs;
 | 
|    Op *pOp;
 | 
|    Parse *pParse = p->pParse;
 | 
|    int *aLabel = pParse->aLabel;
 | 
|    p->readOnly = 1;
 | 
|    p->bIsReader = 0;
 | 
| -  for(pOp=p->aOp, i=p->nOp-1; i>=0; i--, pOp++){
 | 
| -    u8 opcode = pOp->opcode;
 | 
| -
 | 
| -    /* NOTE: Be sure to update mkopcodeh.awk when adding or removing
 | 
| -    ** cases from this switch! */
 | 
| -    switch( opcode ){
 | 
| -      case OP_Transaction: {
 | 
| -        if( pOp->p2!=0 ) p->readOnly = 0;
 | 
| -        /* fall thru */
 | 
| -      }
 | 
| -      case OP_AutoCommit:
 | 
| -      case OP_Savepoint: {
 | 
| -        p->bIsReader = 1;
 | 
| -        break;
 | 
| -      }
 | 
| +  pOp = &p->aOp[p->nOp-1];
 | 
| +  while(1){
 | 
| +
 | 
| +    /* Only JUMP opcodes and the short list of special opcodes in the switch
 | 
| +    ** below need to be considered.  The mkopcodeh.tcl generator script groups
 | 
| +    ** all these opcodes together near the front of the opcode list.  Skip
 | 
| +    ** any opcode that does not need processing by virtual of the fact that
 | 
| +    ** it is larger than SQLITE_MX_JUMP_OPCODE, as a performance optimization.
 | 
| +    */
 | 
| +    if( pOp->opcode<=SQLITE_MX_JUMP_OPCODE ){
 | 
| +      /* NOTE: Be sure to update mkopcodeh.tcl when adding or removing
 | 
| +      ** cases from this switch! */
 | 
| +      switch( pOp->opcode ){
 | 
| +        case OP_Transaction: {
 | 
| +          if( pOp->p2!=0 ) p->readOnly = 0;
 | 
| +          /* fall thru */
 | 
| +        }
 | 
| +        case OP_AutoCommit:
 | 
| +        case OP_Savepoint: {
 | 
| +          p->bIsReader = 1;
 | 
| +          break;
 | 
| +        }
 | 
|  #ifndef SQLITE_OMIT_WAL
 | 
| -      case OP_Checkpoint:
 | 
| +        case OP_Checkpoint:
 | 
|  #endif
 | 
| -      case OP_Vacuum:
 | 
| -      case OP_JournalMode: {
 | 
| -        p->readOnly = 0;
 | 
| -        p->bIsReader = 1;
 | 
| -        break;
 | 
| -      }
 | 
| +        case OP_Vacuum:
 | 
| +        case OP_JournalMode: {
 | 
| +          p->readOnly = 0;
 | 
| +          p->bIsReader = 1;
 | 
| +          break;
 | 
| +        }
 | 
|  #ifndef SQLITE_OMIT_VIRTUALTABLE
 | 
| -      case OP_VUpdate: {
 | 
| -        if( pOp->p2>nMaxArgs ) nMaxArgs = pOp->p2;
 | 
| -        break;
 | 
| -      }
 | 
| -      case OP_VFilter: {
 | 
| -        int n;
 | 
| -        assert( p->nOp - i >= 3 );
 | 
| -        assert( pOp[-1].opcode==OP_Integer );
 | 
| -        n = pOp[-1].p1;
 | 
| -        if( n>nMaxArgs ) nMaxArgs = n;
 | 
| -        break;
 | 
| -      }
 | 
| +        case OP_VUpdate: {
 | 
| +          if( pOp->p2>nMaxArgs ) nMaxArgs = pOp->p2;
 | 
| +          break;
 | 
| +        }
 | 
| +        case OP_VFilter: {
 | 
| +          int n;
 | 
| +          assert( (pOp - p->aOp) >= 3 );
 | 
| +          assert( pOp[-1].opcode==OP_Integer );
 | 
| +          n = pOp[-1].p1;
 | 
| +          if( n>nMaxArgs ) nMaxArgs = n;
 | 
| +          break;
 | 
| +        }
 | 
|  #endif
 | 
| -      case OP_Next:
 | 
| -      case OP_NextIfOpen:
 | 
| -      case OP_SorterNext: {
 | 
| -        pOp->p4.xAdvance = sqlite3BtreeNext;
 | 
| -        pOp->p4type = P4_ADVANCE;
 | 
| -        break;
 | 
| +        case OP_Next:
 | 
| +        case OP_NextIfOpen:
 | 
| +        case OP_SorterNext: {
 | 
| +          pOp->p4.xAdvance = sqlite3BtreeNext;
 | 
| +          pOp->p4type = P4_ADVANCE;
 | 
| +          break;
 | 
| +        }
 | 
| +        case OP_Prev:
 | 
| +        case OP_PrevIfOpen: {
 | 
| +          pOp->p4.xAdvance = sqlite3BtreePrevious;
 | 
| +          pOp->p4type = P4_ADVANCE;
 | 
| +          break;
 | 
| +        }
 | 
|        }
 | 
| -      case OP_Prev:
 | 
| -      case OP_PrevIfOpen: {
 | 
| -        pOp->p4.xAdvance = sqlite3BtreePrevious;
 | 
| -        pOp->p4type = P4_ADVANCE;
 | 
| -        break;
 | 
| +      if( (sqlite3OpcodeProperty[pOp->opcode] & OPFLG_JUMP)!=0 && pOp->p2<0 ){
 | 
| +        assert( ADDR(pOp->p2)<pParse->nLabel );
 | 
| +        pOp->p2 = aLabel[ADDR(pOp->p2)];
 | 
|        }
 | 
|      }
 | 
| -
 | 
| -    pOp->opflags = sqlite3OpcodeProperty[opcode];
 | 
| -    if( (pOp->opflags & OPFLG_JUMP)!=0 && pOp->p2<0 ){
 | 
| -      assert( ADDR(pOp->p2)<pParse->nLabel );
 | 
| -      pOp->p2 = aLabel[ADDR(pOp->p2)];
 | 
| -    }
 | 
| +    if( pOp==p->aOp ) break;
 | 
| +    pOp--;
 | 
|    }
 | 
|    sqlite3DbFree(p->db, pParse->aLabel);
 | 
|    pParse->aLabel = 0;
 | 
| @@ -608,6 +635,36 @@ int sqlite3VdbeCurrentAddr(Vdbe *p){
 | 
|  }
 | 
|  
 | 
|  /*
 | 
| +** Verify that at least N opcode slots are available in p without
 | 
| +** having to malloc for more space (except when compiled using
 | 
| +** SQLITE_TEST_REALLOC_STRESS).  This interface is used during testing
 | 
| +** to verify that certain calls to sqlite3VdbeAddOpList() can never
 | 
| +** fail due to a OOM fault and hence that the return value from
 | 
| +** sqlite3VdbeAddOpList() will always be non-NULL.
 | 
| +*/
 | 
| +#if defined(SQLITE_DEBUG) && !defined(SQLITE_TEST_REALLOC_STRESS)
 | 
| +void sqlite3VdbeVerifyNoMallocRequired(Vdbe *p, int N){
 | 
| +  assert( p->nOp + N <= p->pParse->nOpAlloc );
 | 
| +}
 | 
| +#endif
 | 
| +
 | 
| +/*
 | 
| +** Verify that the VM passed as the only argument does not contain
 | 
| +** an OP_ResultRow opcode. Fail an assert() if it does. This is used
 | 
| +** by code in pragma.c to ensure that the implementation of certain
 | 
| +** pragmas comports with the flags specified in the mkpragmatab.tcl
 | 
| +** script.
 | 
| +*/
 | 
| +#if defined(SQLITE_DEBUG) && !defined(SQLITE_TEST_REALLOC_STRESS)
 | 
| +void sqlite3VdbeVerifyNoResultRow(Vdbe *p){
 | 
| +  int i;
 | 
| +  for(i=0; i<p->nOp; i++){
 | 
| +    assert( p->aOp[i].opcode!=OP_ResultRow );
 | 
| +  }
 | 
| +}
 | 
| +#endif
 | 
| +
 | 
| +/*
 | 
|  ** This function returns a pointer to the array of opcodes associated with
 | 
|  ** the Vdbe passed as the first argument. It is the callers responsibility
 | 
|  ** to arrange for the returned array to be eventually freed using the 
 | 
| @@ -632,24 +689,34 @@ VdbeOp *sqlite3VdbeTakeOpArray(Vdbe *p, int *pnOp, int *pnMaxArg){
 | 
|  }
 | 
|  
 | 
|  /*
 | 
| -** Add a whole list of operations to the operation stack.  Return the
 | 
| -** address of the first operation added.
 | 
| +** Add a whole list of operations to the operation stack.  Return a
 | 
| +** pointer to the first operation inserted.
 | 
| +**
 | 
| +** Non-zero P2 arguments to jump instructions are automatically adjusted
 | 
| +** so that the jump target is relative to the first operation inserted.
 | 
|  */
 | 
| -int sqlite3VdbeAddOpList(Vdbe *p, int nOp, VdbeOpList const *aOp, int iLineno){
 | 
| -  int addr, i;
 | 
| -  VdbeOp *pOut;
 | 
| +VdbeOp *sqlite3VdbeAddOpList(
 | 
| +  Vdbe *p,                     /* Add opcodes to the prepared statement */
 | 
| +  int nOp,                     /* Number of opcodes to add */
 | 
| +  VdbeOpList const *aOp,       /* The opcodes to be added */
 | 
| +  int iLineno                  /* Source-file line number of first opcode */
 | 
| +){
 | 
| +  int i;
 | 
| +  VdbeOp *pOut, *pFirst;
 | 
|    assert( nOp>0 );
 | 
|    assert( p->magic==VDBE_MAGIC_INIT );
 | 
|    if( p->nOp + nOp > p->pParse->nOpAlloc && growOpArray(p, nOp) ){
 | 
|      return 0;
 | 
|    }
 | 
| -  addr = p->nOp;
 | 
| -  pOut = &p->aOp[addr];
 | 
| +  pFirst = pOut = &p->aOp[p->nOp];
 | 
|    for(i=0; i<nOp; i++, aOp++, pOut++){
 | 
|      pOut->opcode = aOp->opcode;
 | 
|      pOut->p1 = aOp->p1;
 | 
|      pOut->p2 = aOp->p2;
 | 
|      assert( aOp->p2>=0 );
 | 
| +    if( (sqlite3OpcodeProperty[aOp->opcode] & OPFLG_JUMP)!=0 && aOp->p2>0 ){
 | 
| +      pOut->p2 += p->nOp;
 | 
| +    }
 | 
|      pOut->p3 = aOp->p3;
 | 
|      pOut->p4type = P4_NOTUSED;
 | 
|      pOut->p4.p = 0;
 | 
| @@ -664,12 +731,12 @@ int sqlite3VdbeAddOpList(Vdbe *p, int nOp, VdbeOpList const *aOp, int iLineno){
 | 
|  #endif
 | 
|  #ifdef SQLITE_DEBUG
 | 
|      if( p->db->flags & SQLITE_VdbeAddopTrace ){
 | 
| -      sqlite3VdbePrintOp(0, i+addr, &p->aOp[i+addr]);
 | 
| +      sqlite3VdbePrintOp(0, i+p->nOp, &p->aOp[i+p->nOp]);
 | 
|      }
 | 
|  #endif
 | 
|    }
 | 
|    p->nOp += nOp;
 | 
| -  return addr;
 | 
| +  return pFirst;
 | 
|  }
 | 
|  
 | 
|  #if defined(SQLITE_ENABLE_STMT_SCANSTATUS)
 | 
| @@ -716,8 +783,9 @@ void sqlite3VdbeChangeP2(Vdbe *p, u32 addr, int val){
 | 
|  void sqlite3VdbeChangeP3(Vdbe *p, u32 addr, int val){
 | 
|    sqlite3VdbeGetOp(p,addr)->p3 = val;
 | 
|  }
 | 
| -void sqlite3VdbeChangeP5(Vdbe *p, u8 p5){
 | 
| -  sqlite3VdbeGetOp(p,-1)->p5 = p5;
 | 
| +void sqlite3VdbeChangeP5(Vdbe *p, u16 p5){
 | 
| +  assert( p->nOp>0 || p->db->mallocFailed );
 | 
| +  if( p->nOp>0 ) p->aOp[p->nOp-1].p5 = p5;
 | 
|  }
 | 
|  
 | 
|  /*
 | 
| @@ -725,7 +793,6 @@ void sqlite3VdbeChangeP5(Vdbe *p, u8 p5){
 | 
|  ** the address of the next instruction to be coded.
 | 
|  */
 | 
|  void sqlite3VdbeJumpHere(Vdbe *p, int addr){
 | 
| -  p->pParse->iFixedOp = p->nOp - 1;
 | 
|    sqlite3VdbeChangeP2(p, addr, p->nOp);
 | 
|  }
 | 
|  
 | 
| @@ -735,7 +802,7 @@ void sqlite3VdbeJumpHere(Vdbe *p, int addr){
 | 
|  ** the FuncDef is not ephermal, then do nothing.
 | 
|  */
 | 
|  static void freeEphemeralFunction(sqlite3 *db, FuncDef *pDef){
 | 
| -  if( ALWAYS(pDef) && (pDef->funcFlags & SQLITE_FUNC_EPHEM)!=0 ){
 | 
| +  if( (pDef->funcFlags & SQLITE_FUNC_EPHEM)!=0 ){
 | 
|      sqlite3DbFree(db, pDef);
 | 
|    }
 | 
|  }
 | 
| @@ -745,53 +812,53 @@ static void vdbeFreeOpArray(sqlite3 *, Op *, int);
 | 
|  /*
 | 
|  ** Delete a P4 value if necessary.
 | 
|  */
 | 
| +static SQLITE_NOINLINE void freeP4Mem(sqlite3 *db, Mem *p){
 | 
| +  if( p->szMalloc ) sqlite3DbFree(db, p->zMalloc);
 | 
| +  sqlite3DbFree(db, p);
 | 
| +}
 | 
| +static SQLITE_NOINLINE void freeP4FuncCtx(sqlite3 *db, sqlite3_context *p){
 | 
| +  freeEphemeralFunction(db, p->pFunc);
 | 
| +  sqlite3DbFree(db, p);
 | 
| +}
 | 
|  static void freeP4(sqlite3 *db, int p4type, void *p4){
 | 
| -  if( p4 ){
 | 
| -    assert( db );
 | 
| -    switch( p4type ){
 | 
| -      case P4_FUNCCTX: {
 | 
| -        freeEphemeralFunction(db, ((sqlite3_context*)p4)->pFunc);
 | 
| -        /* Fall through into the next case */
 | 
| -      }
 | 
| -      case P4_REAL:
 | 
| -      case P4_INT64:
 | 
| -      case P4_DYNAMIC:
 | 
| -      case P4_INTARRAY: {
 | 
| -        sqlite3DbFree(db, p4);
 | 
| -        break;
 | 
| -      }
 | 
| -      case P4_KEYINFO: {
 | 
| -        if( db->pnBytesFreed==0 ) sqlite3KeyInfoUnref((KeyInfo*)p4);
 | 
| -        break;
 | 
| -      }
 | 
| +  assert( db );
 | 
| +  switch( p4type ){
 | 
| +    case P4_FUNCCTX: {
 | 
| +      freeP4FuncCtx(db, (sqlite3_context*)p4);
 | 
| +      break;
 | 
| +    }
 | 
| +    case P4_REAL:
 | 
| +    case P4_INT64:
 | 
| +    case P4_DYNAMIC:
 | 
| +    case P4_INTARRAY: {
 | 
| +      sqlite3DbFree(db, p4);
 | 
| +      break;
 | 
| +    }
 | 
| +    case P4_KEYINFO: {
 | 
| +      if( db->pnBytesFreed==0 ) sqlite3KeyInfoUnref((KeyInfo*)p4);
 | 
| +      break;
 | 
| +    }
 | 
|  #ifdef SQLITE_ENABLE_CURSOR_HINTS
 | 
| -      case P4_EXPR: {
 | 
| -        sqlite3ExprDelete(db, (Expr*)p4);
 | 
| -        break;
 | 
| -      }
 | 
| +    case P4_EXPR: {
 | 
| +      sqlite3ExprDelete(db, (Expr*)p4);
 | 
| +      break;
 | 
| +    }
 | 
|  #endif
 | 
| -      case P4_MPRINTF: {
 | 
| -        if( db->pnBytesFreed==0 ) sqlite3_free(p4);
 | 
| -        break;
 | 
| -      }
 | 
| -      case P4_FUNCDEF: {
 | 
| -        freeEphemeralFunction(db, (FuncDef*)p4);
 | 
| -        break;
 | 
| -      }
 | 
| -      case P4_MEM: {
 | 
| -        if( db->pnBytesFreed==0 ){
 | 
| -          sqlite3ValueFree((sqlite3_value*)p4);
 | 
| -        }else{
 | 
| -          Mem *p = (Mem*)p4;
 | 
| -          if( p->szMalloc ) sqlite3DbFree(db, p->zMalloc);
 | 
| -          sqlite3DbFree(db, p);
 | 
| -        }
 | 
| -        break;
 | 
| -      }
 | 
| -      case P4_VTAB : {
 | 
| -        if( db->pnBytesFreed==0 ) sqlite3VtabUnlock((VTable *)p4);
 | 
| -        break;
 | 
| +    case P4_FUNCDEF: {
 | 
| +      freeEphemeralFunction(db, (FuncDef*)p4);
 | 
| +      break;
 | 
| +    }
 | 
| +    case P4_MEM: {
 | 
| +      if( db->pnBytesFreed==0 ){
 | 
| +        sqlite3ValueFree((sqlite3_value*)p4);
 | 
| +      }else{
 | 
| +        freeP4Mem(db, (Mem*)p4);
 | 
|        }
 | 
| +      break;
 | 
| +    }
 | 
| +    case P4_VTAB : {
 | 
| +      if( db->pnBytesFreed==0 ) sqlite3VtabUnlock((VTable *)p4);
 | 
| +      break;
 | 
|      }
 | 
|    }
 | 
|  }
 | 
| @@ -805,7 +872,7 @@ static void vdbeFreeOpArray(sqlite3 *db, Op *aOp, int nOp){
 | 
|    if( aOp ){
 | 
|      Op *pOp;
 | 
|      for(pOp=aOp; pOp<&aOp[nOp]; pOp++){
 | 
| -      freeP4(db, pOp->p4type, pOp->p4.p);
 | 
| +      if( pOp->p4type ) freeP4(db, pOp->p4type, pOp->p4.p);
 | 
|  #ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS
 | 
|        sqlite3DbFree(db, pOp->zComment);
 | 
|  #endif     
 | 
| @@ -827,14 +894,16 @@ void sqlite3VdbeLinkSubProgram(Vdbe *pVdbe, SubProgram *p){
 | 
|  /*
 | 
|  ** Change the opcode at addr into OP_Noop
 | 
|  */
 | 
| -void sqlite3VdbeChangeToNoop(Vdbe *p, int addr){
 | 
| -  if( addr<p->nOp ){
 | 
| -    VdbeOp *pOp = &p->aOp[addr];
 | 
| -    sqlite3 *db = p->db;
 | 
| -    freeP4(db, pOp->p4type, pOp->p4.p);
 | 
| -    memset(pOp, 0, sizeof(pOp[0]));
 | 
| -    pOp->opcode = OP_Noop;
 | 
| -  }
 | 
| +int sqlite3VdbeChangeToNoop(Vdbe *p, int addr){
 | 
| +  VdbeOp *pOp;
 | 
| +  if( p->db->mallocFailed ) return 0;
 | 
| +  assert( addr>=0 && addr<p->nOp );
 | 
| +  pOp = &p->aOp[addr];
 | 
| +  freeP4(p->db, pOp->p4type, pOp->p4.p);
 | 
| +  pOp->p4type = P4_NOTUSED;
 | 
| +  pOp->p4.z = 0;
 | 
| +  pOp->opcode = OP_Noop;
 | 
| +  return 1;
 | 
|  }
 | 
|  
 | 
|  /*
 | 
| @@ -842,9 +911,8 @@ void sqlite3VdbeChangeToNoop(Vdbe *p, int addr){
 | 
|  ** then remove it.  Return true if and only if an opcode was removed.
 | 
|  */
 | 
|  int sqlite3VdbeDeletePriorOpcode(Vdbe *p, u8 op){
 | 
| -  if( (p->nOp-1)>(p->pParse->iFixedOp) && p->aOp[p->nOp-1].opcode==op ){
 | 
| -    sqlite3VdbeChangeToNoop(p, p->nOp-1);
 | 
| -    return 1;
 | 
| +  if( p->nOp>0 && p->aOp[p->nOp-1].opcode==op ){
 | 
| +    return sqlite3VdbeChangeToNoop(p, p->nOp-1);
 | 
|    }else{
 | 
|      return 0;
 | 
|    }
 | 
| @@ -867,16 +935,34 @@ int sqlite3VdbeDeletePriorOpcode(Vdbe *p, u8 op){
 | 
|  **
 | 
|  ** If addr<0 then change P4 on the most recently inserted instruction.
 | 
|  */
 | 
| +static void SQLITE_NOINLINE vdbeChangeP4Full(
 | 
| +  Vdbe *p,
 | 
| +  Op *pOp,
 | 
| +  const char *zP4,
 | 
| +  int n
 | 
| +){
 | 
| +  if( pOp->p4type ){
 | 
| +    freeP4(p->db, pOp->p4type, pOp->p4.p);
 | 
| +    pOp->p4type = 0;
 | 
| +    pOp->p4.p = 0;
 | 
| +  }
 | 
| +  if( n<0 ){
 | 
| +    sqlite3VdbeChangeP4(p, (int)(pOp - p->aOp), zP4, n);
 | 
| +  }else{
 | 
| +    if( n==0 ) n = sqlite3Strlen30(zP4);
 | 
| +    pOp->p4.z = sqlite3DbStrNDup(p->db, zP4, n);
 | 
| +    pOp->p4type = P4_DYNAMIC;
 | 
| +  }
 | 
| +}
 | 
|  void sqlite3VdbeChangeP4(Vdbe *p, int addr, const char *zP4, int n){
 | 
|    Op *pOp;
 | 
|    sqlite3 *db;
 | 
|    assert( p!=0 );
 | 
|    db = p->db;
 | 
|    assert( p->magic==VDBE_MAGIC_INIT );
 | 
| -  if( p->aOp==0 || db->mallocFailed ){
 | 
| -    if( n!=P4_VTAB ){
 | 
| -      freeP4(db, n, (void*)*(char**)&zP4);
 | 
| -    }
 | 
| +  assert( p->aOp!=0 || db->mallocFailed );
 | 
| +  if( db->mallocFailed ){
 | 
| +    if( n!=P4_VTAB ) freeP4(db, n, (void*)*(char**)&zP4);
 | 
|      return;
 | 
|    }
 | 
|    assert( p->nOp>0 );
 | 
| @@ -885,43 +971,45 @@ void sqlite3VdbeChangeP4(Vdbe *p, int addr, const char *zP4, int n){
 | 
|      addr = p->nOp - 1;
 | 
|    }
 | 
|    pOp = &p->aOp[addr];
 | 
| -  assert( pOp->p4type==P4_NOTUSED
 | 
| -       || pOp->p4type==P4_INT32
 | 
| -       || pOp->p4type==P4_KEYINFO );
 | 
| -  freeP4(db, pOp->p4type, pOp->p4.p);
 | 
| -  pOp->p4.p = 0;
 | 
| +  if( n>=0 || pOp->p4type ){
 | 
| +    vdbeChangeP4Full(p, pOp, zP4, n);
 | 
| +    return;
 | 
| +  }
 | 
|    if( n==P4_INT32 ){
 | 
|      /* Note: this cast is safe, because the origin data point was an int
 | 
|      ** that was cast to a (const char *). */
 | 
|      pOp->p4.i = SQLITE_PTR_TO_INT(zP4);
 | 
|      pOp->p4type = P4_INT32;
 | 
| -  }else if( zP4==0 ){
 | 
| -    pOp->p4.p = 0;
 | 
| -    pOp->p4type = P4_NOTUSED;
 | 
| -  }else if( n==P4_KEYINFO ){
 | 
| -    pOp->p4.p = (void*)zP4;
 | 
| -    pOp->p4type = P4_KEYINFO;
 | 
| -#ifdef SQLITE_ENABLE_CURSOR_HINTS
 | 
| -  }else if( n==P4_EXPR ){
 | 
| -    /* Responsibility for deleting the Expr tree is handed over to the
 | 
| -    ** VDBE by this operation.  The caller should have already invoked
 | 
| -    ** sqlite3ExprDup() or whatever other routine is needed to make a 
 | 
| -    ** private copy of the tree. */
 | 
| -    pOp->p4.pExpr = (Expr*)zP4;
 | 
| -    pOp->p4type = P4_EXPR;
 | 
| -#endif
 | 
| -  }else if( n==P4_VTAB ){
 | 
| -    pOp->p4.p = (void*)zP4;
 | 
| -    pOp->p4type = P4_VTAB;
 | 
| -    sqlite3VtabLock((VTable *)zP4);
 | 
| -    assert( ((VTable *)zP4)->db==p->db );
 | 
| -  }else if( n<0 ){
 | 
| +  }else if( zP4!=0 ){
 | 
| +    assert( n<0 );
 | 
|      pOp->p4.p = (void*)zP4;
 | 
|      pOp->p4type = (signed char)n;
 | 
| +    if( n==P4_VTAB ) sqlite3VtabLock((VTable*)zP4);
 | 
| +  }
 | 
| +}
 | 
| +
 | 
| +/*
 | 
| +** Change the P4 operand of the most recently coded instruction 
 | 
| +** to the value defined by the arguments.  This is a high-speed
 | 
| +** version of sqlite3VdbeChangeP4().
 | 
| +**
 | 
| +** The P4 operand must not have been previously defined.  And the new
 | 
| +** P4 must not be P4_INT32.  Use sqlite3VdbeChangeP4() in either of
 | 
| +** those cases.
 | 
| +*/
 | 
| +void sqlite3VdbeAppendP4(Vdbe *p, void *pP4, int n){
 | 
| +  VdbeOp *pOp;
 | 
| +  assert( n!=P4_INT32 && n!=P4_VTAB );
 | 
| +  assert( n<=0 );
 | 
| +  if( p->db->mallocFailed ){
 | 
| +    freeP4(p->db, n, pP4);
 | 
|    }else{
 | 
| -    if( n==0 ) n = sqlite3Strlen30(zP4);
 | 
| -    pOp->p4.z = sqlite3DbStrNDup(p->db, zP4, n);
 | 
| -    pOp->p4type = P4_DYNAMIC;
 | 
| +    assert( pP4!=0 );
 | 
| +    assert( p->nOp>0 );
 | 
| +    pOp = &p->aOp[p->nOp-1];
 | 
| +    assert( pOp->p4type==P4_NOTUSED );
 | 
| +    pOp->p4type = n;
 | 
| +    pOp->p4.p = pP4;
 | 
|    }
 | 
|  }
 | 
|  
 | 
| @@ -931,10 +1019,11 @@ void sqlite3VdbeChangeP4(Vdbe *p, int addr, const char *zP4, int n){
 | 
|  */
 | 
|  void sqlite3VdbeSetP4KeyInfo(Parse *pParse, Index *pIdx){
 | 
|    Vdbe *v = pParse->pVdbe;
 | 
| +  KeyInfo *pKeyInfo;
 | 
|    assert( v!=0 );
 | 
|    assert( pIdx!=0 );
 | 
| -  sqlite3VdbeChangeP4(v, -1, (char*)sqlite3KeyInfoOfIndex(pParse, pIdx),
 | 
| -                      P4_KEYINFO);
 | 
| +  pKeyInfo = sqlite3KeyInfoOfIndex(pParse, pIdx);
 | 
| +  if( pKeyInfo ) sqlite3VdbeAppendP4(v, pKeyInfo, P4_KEYINFO);
 | 
|  }
 | 
|  
 | 
|  #ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS
 | 
| @@ -1046,12 +1135,21 @@ static int displayComment(
 | 
|    const char *zSynopsis;
 | 
|    int nOpName;
 | 
|    int ii, jj;
 | 
| +  char zAlt[50];
 | 
|    zOpName = sqlite3OpcodeName(pOp->opcode);
 | 
|    nOpName = sqlite3Strlen30(zOpName);
 | 
|    if( zOpName[nOpName+1] ){
 | 
|      int seenCom = 0;
 | 
|      char c;
 | 
|      zSynopsis = zOpName += nOpName + 1;
 | 
| +    if( strncmp(zSynopsis,"IF ",3)==0 ){
 | 
| +      if( pOp->p5 & SQLITE_STOREP2 ){
 | 
| +        sqlite3_snprintf(sizeof(zAlt), zAlt, "r[P2] = (%s)", zSynopsis+3);
 | 
| +      }else{
 | 
| +        sqlite3_snprintf(sizeof(zAlt), zAlt, "if %s goto P2", zSynopsis+3);
 | 
| +      }
 | 
| +      zSynopsis = zAlt;
 | 
| +    }
 | 
|      for(ii=jj=0; jj<nTemp-1 && (c = zSynopsis[ii])!=0; ii++){
 | 
|        if( c=='P' ){
 | 
|          c = zSynopsis[++ii];
 | 
| @@ -1105,28 +1203,27 @@ static int displayComment(
 | 
|  ** Translate the P4.pExpr value for an OP_CursorHint opcode into text
 | 
|  ** that can be displayed in the P4 column of EXPLAIN output.
 | 
|  */
 | 
| -static int displayP4Expr(int nTemp, char *zTemp, Expr *pExpr){
 | 
| +static void displayP4Expr(StrAccum *p, Expr *pExpr){
 | 
|    const char *zOp = 0;
 | 
| -  int n;
 | 
|    switch( pExpr->op ){
 | 
|      case TK_STRING:
 | 
| -      sqlite3_snprintf(nTemp, zTemp, "%Q", pExpr->u.zToken);
 | 
| +      sqlite3XPrintf(p, "%Q", pExpr->u.zToken);
 | 
|        break;
 | 
|      case TK_INTEGER:
 | 
| -      sqlite3_snprintf(nTemp, zTemp, "%d", pExpr->u.iValue);
 | 
| +      sqlite3XPrintf(p, "%d", pExpr->u.iValue);
 | 
|        break;
 | 
|      case TK_NULL:
 | 
| -      sqlite3_snprintf(nTemp, zTemp, "NULL");
 | 
| +      sqlite3XPrintf(p, "NULL");
 | 
|        break;
 | 
|      case TK_REGISTER: {
 | 
| -      sqlite3_snprintf(nTemp, zTemp, "r[%d]", pExpr->iTable);
 | 
| +      sqlite3XPrintf(p, "r[%d]", pExpr->iTable);
 | 
|        break;
 | 
|      }
 | 
|      case TK_COLUMN: {
 | 
|        if( pExpr->iColumn<0 ){
 | 
| -        sqlite3_snprintf(nTemp, zTemp, "rowid");
 | 
| +        sqlite3XPrintf(p, "rowid");
 | 
|        }else{
 | 
| -        sqlite3_snprintf(nTemp, zTemp, "c%d", (int)pExpr->iColumn);
 | 
| +        sqlite3XPrintf(p, "c%d", (int)pExpr->iColumn);
 | 
|        }
 | 
|        break;
 | 
|      }
 | 
| @@ -1158,21 +1255,19 @@ static int displayP4Expr(int nTemp, char *zTemp, Expr *pExpr){
 | 
|      case TK_NOTNULL: zOp = "NOTNULL"; break;
 | 
|  
 | 
|      default:
 | 
| -      sqlite3_snprintf(nTemp, zTemp, "%s", "expr");
 | 
| +      sqlite3XPrintf(p, "%s", "expr");
 | 
|        break;
 | 
|    }
 | 
|  
 | 
|    if( zOp ){
 | 
| -    sqlite3_snprintf(nTemp, zTemp, "%s(", zOp);
 | 
| -    n = sqlite3Strlen30(zTemp);
 | 
| -    n += displayP4Expr(nTemp-n, zTemp+n, pExpr->pLeft);
 | 
| -    if( n<nTemp-1 && pExpr->pRight ){
 | 
| -      zTemp[n++] = ',';
 | 
| -      n += displayP4Expr(nTemp-n, zTemp+n, pExpr->pRight);
 | 
| -    }
 | 
| -    sqlite3_snprintf(nTemp-n, zTemp+n, ")");
 | 
| +    sqlite3XPrintf(p, "%s(", zOp);
 | 
| +    displayP4Expr(p, pExpr->pLeft);
 | 
| +    if( pExpr->pRight ){
 | 
| +      sqlite3StrAccumAppend(p, ",", 1);
 | 
| +      displayP4Expr(p, pExpr->pRight);
 | 
| +    }
 | 
| +    sqlite3StrAccumAppend(p, ")", 1);
 | 
|    }
 | 
| -  return sqlite3Strlen30(zTemp);
 | 
|  }
 | 
|  #endif /* VDBE_DISPLAY_P4 && defined(SQLITE_ENABLE_CURSOR_HINTS) */
 | 
|  
 | 
| @@ -1184,72 +1279,57 @@ static int displayP4Expr(int nTemp, char *zTemp, Expr *pExpr){
 | 
|  */
 | 
|  static char *displayP4(Op *pOp, char *zTemp, int nTemp){
 | 
|    char *zP4 = zTemp;
 | 
| +  StrAccum x;
 | 
|    assert( nTemp>=20 );
 | 
| +  sqlite3StrAccumInit(&x, 0, zTemp, nTemp, 0);
 | 
|    switch( pOp->p4type ){
 | 
|      case P4_KEYINFO: {
 | 
| -      int i, j;
 | 
| +      int j;
 | 
|        KeyInfo *pKeyInfo = pOp->p4.pKeyInfo;
 | 
|        assert( pKeyInfo->aSortOrder!=0 );
 | 
| -      sqlite3_snprintf(nTemp, zTemp, "k(%d", pKeyInfo->nField);
 | 
| -      i = sqlite3Strlen30(zTemp);
 | 
| +      sqlite3XPrintf(&x, "k(%d", pKeyInfo->nField);
 | 
|        for(j=0; j<pKeyInfo->nField; j++){
 | 
|          CollSeq *pColl = pKeyInfo->aColl[j];
 | 
| -        const char *zColl = pColl ? pColl->zName : "nil";
 | 
| -        int n = sqlite3Strlen30(zColl);
 | 
| -        if( n==6 && memcmp(zColl,"BINARY",6)==0 ){
 | 
| -          zColl = "B";
 | 
| -          n = 1;
 | 
| -        }
 | 
| -        if( i+n>nTemp-7 ){
 | 
| -          memcpy(&zTemp[i],",...",4);
 | 
| -          i += 4;
 | 
| -          break;
 | 
| -        }
 | 
| -        zTemp[i++] = ',';
 | 
| -        if( pKeyInfo->aSortOrder[j] ){
 | 
| -          zTemp[i++] = '-';
 | 
| -        }
 | 
| -        memcpy(&zTemp[i], zColl, n+1);
 | 
| -        i += n;
 | 
| +        const char *zColl = pColl ? pColl->zName : "";
 | 
| +        if( strcmp(zColl, "BINARY")==0 ) zColl = "B";
 | 
| +        sqlite3XPrintf(&x, ",%s%s", pKeyInfo->aSortOrder[j] ? "-" : "", zColl);
 | 
|        }
 | 
| -      zTemp[i++] = ')';
 | 
| -      zTemp[i] = 0;
 | 
| -      assert( i<nTemp );
 | 
| +      sqlite3StrAccumAppend(&x, ")", 1);
 | 
|        break;
 | 
|      }
 | 
|  #ifdef SQLITE_ENABLE_CURSOR_HINTS
 | 
|      case P4_EXPR: {
 | 
| -      displayP4Expr(nTemp, zTemp, pOp->p4.pExpr);
 | 
| +      displayP4Expr(&x, pOp->p4.pExpr);
 | 
|        break;
 | 
|      }
 | 
|  #endif
 | 
|      case P4_COLLSEQ: {
 | 
|        CollSeq *pColl = pOp->p4.pColl;
 | 
| -      sqlite3_snprintf(nTemp, zTemp, "(%.20s)", pColl->zName);
 | 
| +      sqlite3XPrintf(&x, "(%.20s)", pColl->zName);
 | 
|        break;
 | 
|      }
 | 
|      case P4_FUNCDEF: {
 | 
|        FuncDef *pDef = pOp->p4.pFunc;
 | 
| -      sqlite3_snprintf(nTemp, zTemp, "%s(%d)", pDef->zName, pDef->nArg);
 | 
| +      sqlite3XPrintf(&x, "%s(%d)", pDef->zName, pDef->nArg);
 | 
|        break;
 | 
|      }
 | 
| -#ifdef SQLITE_DEBUG
 | 
| +#if defined(SQLITE_DEBUG) || defined(VDBE_PROFILE)
 | 
|      case P4_FUNCCTX: {
 | 
|        FuncDef *pDef = pOp->p4.pCtx->pFunc;
 | 
| -      sqlite3_snprintf(nTemp, zTemp, "%s(%d)", pDef->zName, pDef->nArg);
 | 
| +      sqlite3XPrintf(&x, "%s(%d)", pDef->zName, pDef->nArg);
 | 
|        break;
 | 
|      }
 | 
|  #endif
 | 
|      case P4_INT64: {
 | 
| -      sqlite3_snprintf(nTemp, zTemp, "%lld", *pOp->p4.pI64);
 | 
| +      sqlite3XPrintf(&x, "%lld", *pOp->p4.pI64);
 | 
|        break;
 | 
|      }
 | 
|      case P4_INT32: {
 | 
| -      sqlite3_snprintf(nTemp, zTemp, "%d", pOp->p4.i);
 | 
| +      sqlite3XPrintf(&x, "%d", pOp->p4.i);
 | 
|        break;
 | 
|      }
 | 
|      case P4_REAL: {
 | 
| -      sqlite3_snprintf(nTemp, zTemp, "%.16g", *pOp->p4.pReal);
 | 
| +      sqlite3XPrintf(&x, "%.16g", *pOp->p4.pReal);
 | 
|        break;
 | 
|      }
 | 
|      case P4_MEM: {
 | 
| @@ -1257,11 +1337,11 @@ static char *displayP4(Op *pOp, char *zTemp, int nTemp){
 | 
|        if( pMem->flags & MEM_Str ){
 | 
|          zP4 = pMem->z;
 | 
|        }else if( pMem->flags & MEM_Int ){
 | 
| -        sqlite3_snprintf(nTemp, zTemp, "%lld", pMem->u.i);
 | 
| +        sqlite3XPrintf(&x, "%lld", pMem->u.i);
 | 
|        }else if( pMem->flags & MEM_Real ){
 | 
| -        sqlite3_snprintf(nTemp, zTemp, "%.16g", pMem->u.r);
 | 
| +        sqlite3XPrintf(&x, "%.16g", pMem->u.r);
 | 
|        }else if( pMem->flags & MEM_Null ){
 | 
| -        sqlite3_snprintf(nTemp, zTemp, "NULL");
 | 
| +        zP4 = "NULL";
 | 
|        }else{
 | 
|          assert( pMem->flags & MEM_Blob );
 | 
|          zP4 = "(blob)";
 | 
| @@ -1271,22 +1351,34 @@ static char *displayP4(Op *pOp, char *zTemp, int nTemp){
 | 
|  #ifndef SQLITE_OMIT_VIRTUALTABLE
 | 
|      case P4_VTAB: {
 | 
|        sqlite3_vtab *pVtab = pOp->p4.pVtab->pVtab;
 | 
| -      sqlite3_snprintf(nTemp, zTemp, "vtab:%p", pVtab);
 | 
| +      sqlite3XPrintf(&x, "vtab:%p", pVtab);
 | 
|        break;
 | 
|      }
 | 
|  #endif
 | 
|      case P4_INTARRAY: {
 | 
| -      sqlite3_snprintf(nTemp, zTemp, "intarray");
 | 
| +      int i;
 | 
| +      int *ai = pOp->p4.ai;
 | 
| +      int n = ai[0];   /* The first element of an INTARRAY is always the
 | 
| +                       ** count of the number of elements to follow */
 | 
| +      for(i=1; i<n; i++){
 | 
| +        sqlite3XPrintf(&x, ",%d", ai[i]);
 | 
| +      }
 | 
| +      zTemp[0] = '[';
 | 
| +      sqlite3StrAccumAppend(&x, "]", 1);
 | 
|        break;
 | 
|      }
 | 
|      case P4_SUBPROGRAM: {
 | 
| -      sqlite3_snprintf(nTemp, zTemp, "program");
 | 
| +      sqlite3XPrintf(&x, "program");
 | 
|        break;
 | 
|      }
 | 
|      case P4_ADVANCE: {
 | 
|        zTemp[0] = 0;
 | 
|        break;
 | 
|      }
 | 
| +    case P4_TABLE: {
 | 
| +      sqlite3XPrintf(&x, "%s", pOp->p4.pTab->zName);
 | 
| +      break;
 | 
| +    }
 | 
|      default: {
 | 
|        zP4 = pOp->p4.z;
 | 
|        if( zP4==0 ){
 | 
| @@ -1295,6 +1387,7 @@ static char *displayP4(Op *pOp, char *zTemp, int nTemp){
 | 
|        }
 | 
|      }
 | 
|    }
 | 
| +  sqlite3StrAccumFinish(&x);
 | 
|    assert( zP4!=0 );
 | 
|    return zP4;
 | 
|  }
 | 
| @@ -1317,7 +1410,7 @@ void sqlite3VdbeUsesBtree(Vdbe *p, int i){
 | 
|    }
 | 
|  }
 | 
|  
 | 
| -#if !defined(SQLITE_OMIT_SHARED_CACHE) && SQLITE_THREADSAFE>0
 | 
| +#if !defined(SQLITE_OMIT_SHARED_CACHE)
 | 
|  /*
 | 
|  ** If SQLite is compiled to support shared-cache mode and to be threadsafe,
 | 
|  ** this routine obtains the mutex associated with each BtShared structure
 | 
| @@ -1408,13 +1501,27 @@ void sqlite3VdbePrintOp(FILE *pOut, int pc, Op *pOp){
 | 
|  #endif
 | 
|  
 | 
|  /*
 | 
| +** Initialize an array of N Mem element.
 | 
| +*/
 | 
| +static void initMemArray(Mem *p, int N, sqlite3 *db, u16 flags){
 | 
| +  while( (N--)>0 ){
 | 
| +    p->db = db;
 | 
| +    p->flags = flags;
 | 
| +    p->szMalloc = 0;
 | 
| +#ifdef SQLITE_DEBUG
 | 
| +    p->pScopyFrom = 0;
 | 
| +#endif
 | 
| +    p++;
 | 
| +  }
 | 
| +}
 | 
| +
 | 
| +/*
 | 
|  ** Release an array of N Mem elements
 | 
|  */
 | 
|  static void releaseMemArray(Mem *p, int N){
 | 
|    if( p && N ){
 | 
|      Mem *pEnd = &p[N];
 | 
|      sqlite3 *db = p->db;
 | 
| -    u8 malloc_failed = db->mallocFailed;
 | 
|      if( db->pnBytesFreed ){
 | 
|        do{
 | 
|          if( p->szMalloc ) sqlite3DbFree(db, p->zMalloc);
 | 
| @@ -1450,7 +1557,6 @@ static void releaseMemArray(Mem *p, int N){
 | 
|  
 | 
|        p->flags = MEM_Undefined;
 | 
|      }while( (++p)<pEnd );
 | 
| -    db->mallocFailed = malloc_failed;
 | 
|    }
 | 
|  }
 | 
|  
 | 
| @@ -1466,6 +1572,7 @@ void sqlite3VdbeFrameDelete(VdbeFrame *p){
 | 
|      sqlite3VdbeFreeCursor(p->v, apCsr[i]);
 | 
|    }
 | 
|    releaseMemArray(aMem, p->nChildMem);
 | 
| +  sqlite3VdbeDeleteAuxData(p->v->db, &p->pAuxData, -1, 0);
 | 
|    sqlite3DbFree(p->v->db, p);
 | 
|  }
 | 
|  
 | 
| @@ -1508,10 +1615,10 @@ int sqlite3VdbeList(
 | 
|    releaseMemArray(pMem, 8);
 | 
|    p->pResultSet = 0;
 | 
|  
 | 
| -  if( p->rc==SQLITE_NOMEM ){
 | 
| +  if( p->rc==SQLITE_NOMEM_BKPT ){
 | 
|      /* This happens if a malloc() inside a call to sqlite3_column_text() or
 | 
|      ** sqlite3_column_text16() failed.  */
 | 
| -    db->mallocFailed = 1;
 | 
| +    sqlite3OomFault(db);
 | 
|      return SQLITE_ERROR;
 | 
|    }
 | 
|  
 | 
| @@ -1619,6 +1726,7 @@ int sqlite3VdbeList(
 | 
|      pMem->flags = MEM_Str|MEM_Term;
 | 
|      zP4 = displayP4(pOp, pMem->z, pMem->szMalloc);
 | 
|      if( zP4!=pMem->z ){
 | 
| +      pMem->n = 0;
 | 
|        sqlite3VdbeMemSetStr(pMem, zP4, -1, SQLITE_UTF8, 0);
 | 
|      }else{
 | 
|        assert( pMem->z!=0 );
 | 
| @@ -1709,41 +1817,43 @@ void sqlite3VdbeIOTraceSql(Vdbe *p){
 | 
|  }
 | 
|  #endif /* !SQLITE_OMIT_TRACE && SQLITE_ENABLE_IOTRACE */
 | 
|  
 | 
| -/*
 | 
| -** Allocate space from a fixed size buffer and return a pointer to
 | 
| -** that space.  If insufficient space is available, return NULL.
 | 
| -**
 | 
| -** The pBuf parameter is the initial value of a pointer which will
 | 
| -** receive the new memory.  pBuf is normally NULL.  If pBuf is not
 | 
| -** NULL, it means that memory space has already been allocated and that
 | 
| -** this routine should not allocate any new memory.  When pBuf is not
 | 
| -** NULL simply return pBuf.  Only allocate new memory space when pBuf
 | 
| -** is NULL.
 | 
| -**
 | 
| -** nByte is the number of bytes of space needed.
 | 
| +/* An instance of this object describes bulk memory available for use
 | 
| +** by subcomponents of a prepared statement.  Space is allocated out
 | 
| +** of a ReusableSpace object by the allocSpace() routine below.
 | 
| +*/
 | 
| +struct ReusableSpace {
 | 
| +  u8 *pSpace;          /* Available memory */
 | 
| +  int nFree;           /* Bytes of available memory */
 | 
| +  int nNeeded;         /* Total bytes that could not be allocated */
 | 
| +};
 | 
| +
 | 
| +/* Try to allocate nByte bytes of 8-byte aligned bulk memory for pBuf
 | 
| +** from the ReusableSpace object.  Return a pointer to the allocated
 | 
| +** memory on success.  If insufficient memory is available in the
 | 
| +** ReusableSpace object, increase the ReusableSpace.nNeeded
 | 
| +** value by the amount needed and return NULL.
 | 
|  **
 | 
| -** pFrom points to *pnFrom bytes of available space.  New space is allocated
 | 
| -** from the end of the pFrom buffer and *pnFrom is decremented.
 | 
| +** If pBuf is not initially NULL, that means that the memory has already
 | 
| +** been allocated by a prior call to this routine, so just return a copy
 | 
| +** of pBuf and leave ReusableSpace unchanged.
 | 
|  **
 | 
| -** *pnNeeded is a counter of the number of bytes of space that have failed
 | 
| -** to allocate.  If there is insufficient space in pFrom to satisfy the
 | 
| -** request, then increment *pnNeeded by the amount of the request.
 | 
| +** This allocator is employed to repurpose unused slots at the end of the
 | 
| +** opcode array of prepared state for other memory needs of the prepared
 | 
| +** statement.
 | 
|  */
 | 
|  static void *allocSpace(
 | 
| -  void *pBuf,          /* Where return pointer will be stored */
 | 
| -  int nByte,           /* Number of bytes to allocate */
 | 
| -  u8 *pFrom,           /* Memory available for allocation */
 | 
| -  int *pnFrom,         /* IN/OUT: Space available at pFrom */
 | 
| -  int *pnNeeded        /* If allocation cannot be made, increment *pnByte */
 | 
| +  struct ReusableSpace *p,  /* Bulk memory available for allocation */
 | 
| +  void *pBuf,               /* Pointer to a prior allocation */
 | 
| +  int nByte                 /* Bytes of memory needed */
 | 
|  ){
 | 
| -  assert( EIGHT_BYTE_ALIGNMENT(pFrom) );
 | 
| +  assert( EIGHT_BYTE_ALIGNMENT(p->pSpace) );
 | 
|    if( pBuf==0 ){
 | 
|      nByte = ROUND8(nByte);
 | 
| -    if( nByte <= *pnFrom ){
 | 
| -      *pnFrom -= nByte;
 | 
| -      pBuf = &pFrom[*pnFrom];
 | 
| +    if( nByte <= p->nFree ){
 | 
| +      p->nFree -= nByte;
 | 
| +      pBuf = &p->pSpace[p->nFree];
 | 
|      }else{
 | 
| -      *pnNeeded += nByte;
 | 
| +      p->nNeeded += nByte;
 | 
|      }
 | 
|    }
 | 
|    assert( EIGHT_BYTE_ALIGNMENT(pBuf) );
 | 
| @@ -1759,7 +1869,7 @@ void sqlite3VdbeRewind(Vdbe *p){
 | 
|    int i;
 | 
|  #endif
 | 
|    assert( p!=0 );
 | 
| -  assert( p->magic==VDBE_MAGIC_INIT );
 | 
| +  assert( p->magic==VDBE_MAGIC_INIT || p->magic==VDBE_MAGIC_RESET );
 | 
|  
 | 
|    /* There should be at least one opcode.
 | 
|    */
 | 
| @@ -1769,14 +1879,13 @@ void sqlite3VdbeRewind(Vdbe *p){
 | 
|    p->magic = VDBE_MAGIC_RUN;
 | 
|  
 | 
|  #ifdef SQLITE_DEBUG
 | 
| -  for(i=1; i<p->nMem; i++){
 | 
| +  for(i=0; i<p->nMem; i++){
 | 
|      assert( p->aMem[i].db==p->db );
 | 
|    }
 | 
|  #endif
 | 
|    p->pc = -1;
 | 
|    p->rc = SQLITE_OK;
 | 
|    p->errorAction = OE_Abort;
 | 
| -  p->magic = VDBE_MAGIC_RUN;
 | 
|    p->nChange = 0;
 | 
|    p->cacheCtr = 1;
 | 
|    p->minWriteFileFormat = 255;
 | 
| @@ -1817,11 +1926,8 @@ void sqlite3VdbeMakeReady(
 | 
|    int nMem;                      /* Number of VM memory registers */
 | 
|    int nCursor;                   /* Number of cursors required */
 | 
|    int nArg;                      /* Number of arguments in subprograms */
 | 
| -  int nOnce;                     /* Number of OP_Once instructions */
 | 
|    int n;                         /* Loop counter */
 | 
| -  int nFree;                     /* Available free space */
 | 
| -  u8 *zCsr;                      /* Memory available for allocation */
 | 
| -  int nByte;                     /* How much extra memory is needed */
 | 
| +  struct ReusableSpace x;        /* Reusable bulk memory */
 | 
|  
 | 
|    assert( p!=0 );
 | 
|    assert( p->nOp>0 );
 | 
| @@ -1834,35 +1940,25 @@ void sqlite3VdbeMakeReady(
 | 
|    nMem = pParse->nMem;
 | 
|    nCursor = pParse->nTab;
 | 
|    nArg = pParse->nMaxArg;
 | 
| -  nOnce = pParse->nOnce;
 | 
| -  if( nOnce==0 ) nOnce = 1; /* Ensure at least one byte in p->aOnceFlag[] */
 | 
|    
 | 
| -  /* For each cursor required, also allocate a memory cell. Memory
 | 
| -  ** cells (nMem+1-nCursor)..nMem, inclusive, will never be used by
 | 
| -  ** the vdbe program. Instead they are used to allocate space for
 | 
| -  ** VdbeCursor/BtCursor structures. The blob of memory associated with 
 | 
| -  ** cursor 0 is stored in memory cell nMem. Memory cell (nMem-1)
 | 
| -  ** stores the blob of memory associated with cursor 1, etc.
 | 
| -  **
 | 
| +  /* Each cursor uses a memory cell.  The first cursor (cursor 0) can
 | 
| +  ** use aMem[0] which is not otherwise used by the VDBE program.  Allocate
 | 
| +  ** space at the end of aMem[] for cursors 1 and greater.
 | 
|    ** See also: allocateCursor().
 | 
|    */
 | 
|    nMem += nCursor;
 | 
| +  if( nCursor==0 && nMem>0 ) nMem++;  /* Space for aMem[0] even if not used */
 | 
|  
 | 
| -  /* zCsr will initially point to nFree bytes of unused space at the
 | 
| -  ** end of the opcode array, p->aOp.  The computation of nFree is
 | 
| -  ** conservative - it might be smaller than the true number of free
 | 
| -  ** bytes, but never larger.  nFree must be a multiple of 8 - it is
 | 
| -  ** rounded down if is not.
 | 
| +  /* Figure out how much reusable memory is available at the end of the
 | 
| +  ** opcode array.  This extra memory will be reallocated for other elements
 | 
| +  ** of the prepared statement.
 | 
|    */
 | 
| -  n = ROUND8(sizeof(Op)*p->nOp);              /* Bytes of opcode space used */
 | 
| -  zCsr = &((u8*)p->aOp)[n];                   /* Unused opcode space */
 | 
| -  assert( EIGHT_BYTE_ALIGNMENT(zCsr) );
 | 
| -  nFree = ROUNDDOWN8(pParse->szOpAlloc - n);  /* Bytes of unused space */
 | 
| -  assert( nFree>=0 );
 | 
| -  if( nFree>0 ){
 | 
| -    memset(zCsr, 0, nFree);
 | 
| -    assert( EIGHT_BYTE_ALIGNMENT(&zCsr[nFree]) );
 | 
| -  }
 | 
| +  n = ROUND8(sizeof(Op)*p->nOp);              /* Bytes of opcode memory used */
 | 
| +  x.pSpace = &((u8*)p->aOp)[n];               /* Unused opcode memory */
 | 
| +  assert( EIGHT_BYTE_ALIGNMENT(x.pSpace) );
 | 
| +  x.nFree = ROUNDDOWN8(pParse->szOpAlloc - n);  /* Bytes of unused memory */
 | 
| +  assert( x.nFree>=0 );
 | 
| +  assert( EIGHT_BYTE_ALIGNMENT(&x.pSpace[x.nFree]) );
 | 
|  
 | 
|    resolveP2Values(p, &nArg);
 | 
|    p->usesStmtJournal = (u8)(pParse->isMultiWrite && pParse->mayAbort);
 | 
| @@ -1871,58 +1967,48 @@ void sqlite3VdbeMakeReady(
 | 
|    }
 | 
|    p->expired = 0;
 | 
|  
 | 
| -  /* Memory for registers, parameters, cursor, etc, is allocated in two
 | 
| -  ** passes.  On the first pass, we try to reuse unused space at the 
 | 
| +  /* Memory for registers, parameters, cursor, etc, is allocated in one or two
 | 
| +  ** passes.  On the first pass, we try to reuse unused memory at the 
 | 
|    ** end of the opcode array.  If we are unable to satisfy all memory
 | 
|    ** requirements by reusing the opcode array tail, then the second
 | 
| -  ** pass will fill in the rest using a fresh allocation.  
 | 
| +  ** pass will fill in the remainder using a fresh memory allocation.  
 | 
|    **
 | 
|    ** This two-pass approach that reuses as much memory as possible from
 | 
| -  ** the leftover space at the end of the opcode array can significantly
 | 
| +  ** the leftover memory at the end of the opcode array.  This can significantly
 | 
|    ** reduce the amount of memory held by a prepared statement.
 | 
|    */
 | 
|    do {
 | 
| -    nByte = 0;
 | 
| -    p->aMem = allocSpace(p->aMem, nMem*sizeof(Mem), zCsr, &nFree, &nByte);
 | 
| -    p->aVar = allocSpace(p->aVar, nVar*sizeof(Mem), zCsr, &nFree, &nByte);
 | 
| -    p->apArg = allocSpace(p->apArg, nArg*sizeof(Mem*), zCsr, &nFree, &nByte);
 | 
| -    p->azVar = allocSpace(p->azVar, nVar*sizeof(char*), zCsr, &nFree, &nByte);
 | 
| -    p->apCsr = allocSpace(p->apCsr, nCursor*sizeof(VdbeCursor*),
 | 
| -                          zCsr, &nFree, &nByte);
 | 
| -    p->aOnceFlag = allocSpace(p->aOnceFlag, nOnce, zCsr, &nFree, &nByte);
 | 
| +    x.nNeeded = 0;
 | 
| +    p->aMem = allocSpace(&x, p->aMem, nMem*sizeof(Mem));
 | 
| +    p->aVar = allocSpace(&x, p->aVar, nVar*sizeof(Mem));
 | 
| +    p->apArg = allocSpace(&x, p->apArg, nArg*sizeof(Mem*));
 | 
| +    p->apCsr = allocSpace(&x, p->apCsr, nCursor*sizeof(VdbeCursor*));
 | 
|  #ifdef SQLITE_ENABLE_STMT_SCANSTATUS
 | 
| -    p->anExec = allocSpace(p->anExec, p->nOp*sizeof(i64), zCsr, &nFree, &nByte);
 | 
| +    p->anExec = allocSpace(&x, p->anExec, p->nOp*sizeof(i64));
 | 
|  #endif
 | 
| -    if( nByte ){
 | 
| -      p->pFree = sqlite3DbMallocZero(db, nByte);
 | 
| -    }
 | 
| -    zCsr = p->pFree;
 | 
| -    nFree = nByte;
 | 
| -  }while( nByte && !db->mallocFailed );
 | 
| +    if( x.nNeeded==0 ) break;
 | 
| +    x.pSpace = p->pFree = sqlite3DbMallocRawNN(db, x.nNeeded);
 | 
| +    x.nFree = x.nNeeded;
 | 
| +  }while( !db->mallocFailed );
 | 
|  
 | 
| -  p->nCursor = nCursor;
 | 
| -  p->nOnceFlag = nOnce;
 | 
| -  if( p->aVar ){
 | 
| +  p->pVList = pParse->pVList;
 | 
| +  pParse->pVList =  0;
 | 
| +  p->explain = pParse->explain;
 | 
| +  if( db->mallocFailed ){
 | 
| +    p->nVar = 0;
 | 
| +    p->nCursor = 0;
 | 
| +    p->nMem = 0;
 | 
| +  }else{
 | 
| +    p->nCursor = nCursor;
 | 
|      p->nVar = (ynVar)nVar;
 | 
| -    for(n=0; n<nVar; n++){
 | 
| -      p->aVar[n].flags = MEM_Null;
 | 
| -      p->aVar[n].db = db;
 | 
| -    }
 | 
| -  }
 | 
| -  if( p->azVar && pParse->nzVar>0 ){
 | 
| -    p->nzVar = pParse->nzVar;
 | 
| -    memcpy(p->azVar, pParse->azVar, p->nzVar*sizeof(p->azVar[0]));
 | 
| -    memset(pParse->azVar, 0, pParse->nzVar*sizeof(pParse->azVar[0]));
 | 
| -  }
 | 
| -  if( p->aMem ){
 | 
| -    p->aMem--;                      /* aMem[] goes from 1..nMem */
 | 
| -    p->nMem = nMem;                 /*       not from 0..nMem-1 */
 | 
| -    for(n=1; n<=nMem; n++){
 | 
| -      p->aMem[n].flags = MEM_Undefined;
 | 
| -      p->aMem[n].db = db;
 | 
| -    }
 | 
| +    initMemArray(p->aVar, nVar, db, MEM_Null);
 | 
| +    p->nMem = nMem;
 | 
| +    initMemArray(p->aMem, nMem, db, MEM_Undefined);
 | 
| +    memset(p->apCsr, 0, nCursor*sizeof(VdbeCursor*));
 | 
| +#ifdef SQLITE_ENABLE_STMT_SCANSTATUS
 | 
| +    memset(p->anExec, 0, p->nOp*sizeof(i64));
 | 
| +#endif
 | 
|    }
 | 
| -  p->explain = pParse->explain;
 | 
|    sqlite3VdbeRewind(p);
 | 
|  }
 | 
|  
 | 
| @@ -1934,15 +2020,15 @@ void sqlite3VdbeFreeCursor(Vdbe *p, VdbeCursor *pCx){
 | 
|    if( pCx==0 ){
 | 
|      return;
 | 
|    }
 | 
| -  assert( pCx->pBt==0 || pCx->eCurType==CURTYPE_BTREE );
 | 
| +  assert( pCx->pBtx==0 || pCx->eCurType==CURTYPE_BTREE );
 | 
|    switch( pCx->eCurType ){
 | 
|      case CURTYPE_SORTER: {
 | 
|        sqlite3VdbeSorterClose(p->db, pCx);
 | 
|        break;
 | 
|      }
 | 
|      case CURTYPE_BTREE: {
 | 
| -      if( pCx->pBt ){
 | 
| -        sqlite3BtreeClose(pCx->pBt);
 | 
| +      if( pCx->pBtx ){
 | 
| +        sqlite3BtreeClose(pCx->pBtx);
 | 
|          /* The pCx->pCursor will be close automatically, if it exists, by
 | 
|          ** the call above. */
 | 
|        }else{
 | 
| @@ -1991,8 +2077,6 @@ int sqlite3VdbeFrameRestore(VdbeFrame *pFrame){
 | 
|  #ifdef SQLITE_ENABLE_STMT_SCANSTATUS
 | 
|    v->anExec = pFrame->anExec;
 | 
|  #endif
 | 
| -  v->aOnceFlag = pFrame->aOnceFlag;
 | 
| -  v->nOnceFlag = pFrame->nOnceFlag;
 | 
|    v->aOp = pFrame->aOp;
 | 
|    v->nOp = pFrame->nOp;
 | 
|    v->aMem = pFrame->aMem;
 | 
| @@ -2002,6 +2086,9 @@ int sqlite3VdbeFrameRestore(VdbeFrame *pFrame){
 | 
|    v->db->lastRowid = pFrame->lastRowid;
 | 
|    v->nChange = pFrame->nChange;
 | 
|    v->db->nChange = pFrame->nDbChange;
 | 
| +  sqlite3VdbeDeleteAuxData(v->db, &v->pAuxData, -1, 0);
 | 
| +  v->pAuxData = pFrame->pAuxData;
 | 
| +  pFrame->pAuxData = 0;
 | 
|    return pFrame->pc;
 | 
|  }
 | 
|  
 | 
| @@ -2024,7 +2111,7 @@ static void closeAllCursors(Vdbe *p){
 | 
|    assert( p->nFrame==0 );
 | 
|    closeCursorsInFrame(p);
 | 
|    if( p->aMem ){
 | 
| -    releaseMemArray(&p->aMem[1], p->nMem);
 | 
| +    releaseMemArray(p->aMem, p->nMem);
 | 
|    }
 | 
|    while( p->pDelFrame ){
 | 
|      VdbeFrame *pDel = p->pDelFrame;
 | 
| @@ -2033,7 +2120,7 @@ static void closeAllCursors(Vdbe *p){
 | 
|    }
 | 
|  
 | 
|    /* Delete any auxdata allocations made by the VM */
 | 
| -  if( p->pAuxData ) sqlite3VdbeDeleteAuxData(p, -1, 0);
 | 
| +  if( p->pAuxData ) sqlite3VdbeDeleteAuxData(p->db, &p->pAuxData, -1, 0);
 | 
|    assert( p->pAuxData==0 );
 | 
|  }
 | 
|  
 | 
| @@ -2049,7 +2136,7 @@ static void Cleanup(Vdbe *p){
 | 
|    int i;
 | 
|    if( p->apCsr ) for(i=0; i<p->nCursor; i++) assert( p->apCsr[i]==0 );
 | 
|    if( p->aMem ){
 | 
| -    for(i=1; i<=p->nMem; i++) assert( p->aMem[i].flags==MEM_Undefined );
 | 
| +    for(i=0; i<p->nMem; i++) assert( p->aMem[i].flags==MEM_Undefined );
 | 
|    }
 | 
|  #endif
 | 
|  
 | 
| @@ -2073,13 +2160,9 @@ void sqlite3VdbeSetNumCols(Vdbe *p, int nResColumn){
 | 
|    sqlite3DbFree(db, p->aColName);
 | 
|    n = nResColumn*COLNAME_N;
 | 
|    p->nResColumn = (u16)nResColumn;
 | 
| -  p->aColName = pColName = (Mem*)sqlite3DbMallocZero(db, sizeof(Mem)*n );
 | 
| +  p->aColName = pColName = (Mem*)sqlite3DbMallocRawNN(db, sizeof(Mem)*n );
 | 
|    if( p->aColName==0 ) return;
 | 
| -  while( n-- > 0 ){
 | 
| -    pColName->flags = MEM_Null;
 | 
| -    pColName->db = p->db;
 | 
| -    pColName++;
 | 
| -  }
 | 
| +  initMemArray(p->aColName, n, p->db, MEM_Null);
 | 
|  }
 | 
|  
 | 
|  /*
 | 
| @@ -2105,7 +2188,7 @@ int sqlite3VdbeSetColName(
 | 
|    assert( var<COLNAME_N );
 | 
|    if( p->db->mallocFailed ){
 | 
|      assert( !zName || xDel!=SQLITE_DYNAMIC );
 | 
| -    return SQLITE_NOMEM;
 | 
| +    return SQLITE_NOMEM_BKPT;
 | 
|    }
 | 
|    assert( p->aColName!=0 );
 | 
|    pColName = &(p->aColName[idx+var*p->nResColumn]);
 | 
| @@ -2122,7 +2205,9 @@ int sqlite3VdbeSetColName(
 | 
|  */
 | 
|  static int vdbeCommit(sqlite3 *db, Vdbe *p){
 | 
|    int i;
 | 
| -  int nTrans = 0;  /* Number of databases with an active write-transaction */
 | 
| +  int nTrans = 0;  /* Number of databases with an active write-transaction
 | 
| +                   ** that are candidates for a two-phase commit using a
 | 
| +                   ** master-journal */
 | 
|    int rc = SQLITE_OK;
 | 
|    int needXcommit = 0;
 | 
|  
 | 
| @@ -2150,10 +2235,28 @@ static int vdbeCommit(sqlite3 *db, Vdbe *p){
 | 
|    for(i=0; rc==SQLITE_OK && i<db->nDb; i++){ 
 | 
|      Btree *pBt = db->aDb[i].pBt;
 | 
|      if( sqlite3BtreeIsInTrans(pBt) ){
 | 
| +      /* Whether or not a database might need a master journal depends upon
 | 
| +      ** its journal mode (among other things).  This matrix determines which
 | 
| +      ** journal modes use a master journal and which do not */
 | 
| +      static const u8 aMJNeeded[] = {
 | 
| +        /* DELETE   */  1,
 | 
| +        /* PERSIST   */ 1,
 | 
| +        /* OFF       */ 0,
 | 
| +        /* TRUNCATE  */ 1,
 | 
| +        /* MEMORY    */ 0,
 | 
| +        /* WAL       */ 0
 | 
| +      };
 | 
| +      Pager *pPager;   /* Pager associated with pBt */
 | 
|        needXcommit = 1;
 | 
| -      if( i!=1 ) nTrans++;
 | 
|        sqlite3BtreeEnter(pBt);
 | 
| -      rc = sqlite3PagerExclusiveLock(sqlite3BtreePager(pBt));
 | 
| +      pPager = sqlite3BtreePager(pBt);
 | 
| +      if( db->aDb[i].safety_level!=PAGER_SYNCHRONOUS_OFF
 | 
| +       && aMJNeeded[sqlite3PagerGetJournalMode(pPager)]
 | 
| +      ){ 
 | 
| +        assert( i!=1 );
 | 
| +        nTrans++;
 | 
| +      }
 | 
| +      rc = sqlite3PagerExclusiveLock(pPager);
 | 
|        sqlite3BtreeLeave(pBt);
 | 
|      }
 | 
|    }
 | 
| @@ -2211,7 +2314,6 @@ static int vdbeCommit(sqlite3 *db, Vdbe *p){
 | 
|  #ifndef SQLITE_OMIT_DISKIO
 | 
|    else{
 | 
|      sqlite3_vfs *pVfs = db->pVfs;
 | 
| -    int needSync = 0;
 | 
|      char *zMaster = 0;   /* File-name for the master journal */
 | 
|      char const *zMainFile = sqlite3BtreeGetFilename(db->aDb[0].pBt);
 | 
|      sqlite3_file *pMaster = 0;
 | 
| @@ -2223,7 +2325,7 @@ static int vdbeCommit(sqlite3 *db, Vdbe *p){
 | 
|      /* Select a master journal file name */
 | 
|      nMainFile = sqlite3Strlen30(zMainFile);
 | 
|      zMaster = sqlite3MPrintf(db, "%s-mjXXXXXX9XXz", zMainFile);
 | 
| -    if( zMaster==0 ) return SQLITE_NOMEM;
 | 
| +    if( zMaster==0 ) return SQLITE_NOMEM_BKPT;
 | 
|      do {
 | 
|        u32 iRandom;
 | 
|        if( retryCount ){
 | 
| @@ -2271,9 +2373,6 @@ static int vdbeCommit(sqlite3 *db, Vdbe *p){
 | 
|            continue;  /* Ignore TEMP and :memory: databases */
 | 
|          }
 | 
|          assert( zFile[0]!=0 );
 | 
| -        if( !needSync && !sqlite3BtreeSyncDisabled(pBt) ){
 | 
| -          needSync = 1;
 | 
| -        }
 | 
|          rc = sqlite3OsWrite(pMaster, zFile, sqlite3Strlen30(zFile)+1, offset);
 | 
|          offset += sqlite3Strlen30(zFile)+1;
 | 
|          if( rc!=SQLITE_OK ){
 | 
| @@ -2288,8 +2387,7 @@ static int vdbeCommit(sqlite3 *db, Vdbe *p){
 | 
|      /* Sync the master journal file. If the IOCAP_SEQUENTIAL device
 | 
|      ** flag is set this is not required.
 | 
|      */
 | 
| -    if( needSync 
 | 
| -     && 0==(sqlite3OsDeviceCharacteristics(pMaster)&SQLITE_IOCAP_SEQUENTIAL)
 | 
| +    if( 0==(sqlite3OsDeviceCharacteristics(pMaster)&SQLITE_IOCAP_SEQUENTIAL)
 | 
|       && SQLITE_OK!=(rc = sqlite3OsSync(pMaster, SQLITE_SYNC_NORMAL))
 | 
|      ){
 | 
|        sqlite3OsCloseFree(pMaster);
 | 
| @@ -2325,7 +2423,7 @@ static int vdbeCommit(sqlite3 *db, Vdbe *p){
 | 
|      ** doing this the directory is synced again before any individual
 | 
|      ** transaction files are deleted.
 | 
|      */
 | 
| -    rc = sqlite3OsDelete(pVfs, zMaster, needSync);
 | 
| +    rc = sqlite3OsDelete(pVfs, zMaster, 1);
 | 
|      sqlite3DbFree(db, zMaster);
 | 
|      zMaster = 0;
 | 
|      if( rc ){
 | 
| @@ -2399,60 +2497,59 @@ static void checkActiveVdbeCnt(sqlite3 *db){
 | 
|  ** If an IO error occurs, an SQLITE_IOERR_XXX error code is returned. 
 | 
|  ** Otherwise SQLITE_OK.
 | 
|  */
 | 
| -int sqlite3VdbeCloseStatement(Vdbe *p, int eOp){
 | 
| +static SQLITE_NOINLINE int vdbeCloseStatement(Vdbe *p, int eOp){
 | 
|    sqlite3 *const db = p->db;
 | 
|    int rc = SQLITE_OK;
 | 
| +  int i;
 | 
| +  const int iSavepoint = p->iStatement-1;
 | 
|  
 | 
| -  /* If p->iStatement is greater than zero, then this Vdbe opened a 
 | 
| -  ** statement transaction that should be closed here. The only exception
 | 
| -  ** is that an IO error may have occurred, causing an emergency rollback.
 | 
| -  ** In this case (db->nStatement==0), and there is nothing to do.
 | 
| -  */
 | 
| -  if( db->nStatement && p->iStatement ){
 | 
| -    int i;
 | 
| -    const int iSavepoint = p->iStatement-1;
 | 
| -
 | 
| -    assert( eOp==SAVEPOINT_ROLLBACK || eOp==SAVEPOINT_RELEASE);
 | 
| -    assert( db->nStatement>0 );
 | 
| -    assert( p->iStatement==(db->nStatement+db->nSavepoint) );
 | 
| -
 | 
| -    for(i=0; i<db->nDb; i++){ 
 | 
| -      int rc2 = SQLITE_OK;
 | 
| -      Btree *pBt = db->aDb[i].pBt;
 | 
| -      if( pBt ){
 | 
| -        if( eOp==SAVEPOINT_ROLLBACK ){
 | 
| -          rc2 = sqlite3BtreeSavepoint(pBt, SAVEPOINT_ROLLBACK, iSavepoint);
 | 
| -        }
 | 
| -        if( rc2==SQLITE_OK ){
 | 
| -          rc2 = sqlite3BtreeSavepoint(pBt, SAVEPOINT_RELEASE, iSavepoint);
 | 
| -        }
 | 
| -        if( rc==SQLITE_OK ){
 | 
| -          rc = rc2;
 | 
| -        }
 | 
| -      }
 | 
| -    }
 | 
| -    db->nStatement--;
 | 
| -    p->iStatement = 0;
 | 
| +  assert( eOp==SAVEPOINT_ROLLBACK || eOp==SAVEPOINT_RELEASE);
 | 
| +  assert( db->nStatement>0 );
 | 
| +  assert( p->iStatement==(db->nStatement+db->nSavepoint) );
 | 
|  
 | 
| -    if( rc==SQLITE_OK ){
 | 
| +  for(i=0; i<db->nDb; i++){ 
 | 
| +    int rc2 = SQLITE_OK;
 | 
| +    Btree *pBt = db->aDb[i].pBt;
 | 
| +    if( pBt ){
 | 
|        if( eOp==SAVEPOINT_ROLLBACK ){
 | 
| -        rc = sqlite3VtabSavepoint(db, SAVEPOINT_ROLLBACK, iSavepoint);
 | 
| +        rc2 = sqlite3BtreeSavepoint(pBt, SAVEPOINT_ROLLBACK, iSavepoint);
 | 
| +      }
 | 
| +      if( rc2==SQLITE_OK ){
 | 
| +        rc2 = sqlite3BtreeSavepoint(pBt, SAVEPOINT_RELEASE, iSavepoint);
 | 
|        }
 | 
|        if( rc==SQLITE_OK ){
 | 
| -        rc = sqlite3VtabSavepoint(db, SAVEPOINT_RELEASE, iSavepoint);
 | 
| +        rc = rc2;
 | 
|        }
 | 
|      }
 | 
| +  }
 | 
| +  db->nStatement--;
 | 
| +  p->iStatement = 0;
 | 
|  
 | 
| -    /* If the statement transaction is being rolled back, also restore the 
 | 
| -    ** database handles deferred constraint counter to the value it had when 
 | 
| -    ** the statement transaction was opened.  */
 | 
| +  if( rc==SQLITE_OK ){
 | 
|      if( eOp==SAVEPOINT_ROLLBACK ){
 | 
| -      db->nDeferredCons = p->nStmtDefCons;
 | 
| -      db->nDeferredImmCons = p->nStmtDefImmCons;
 | 
| +      rc = sqlite3VtabSavepoint(db, SAVEPOINT_ROLLBACK, iSavepoint);
 | 
|      }
 | 
| +    if( rc==SQLITE_OK ){
 | 
| +      rc = sqlite3VtabSavepoint(db, SAVEPOINT_RELEASE, iSavepoint);
 | 
| +    }
 | 
| +  }
 | 
| +
 | 
| +  /* If the statement transaction is being rolled back, also restore the 
 | 
| +  ** database handles deferred constraint counter to the value it had when 
 | 
| +  ** the statement transaction was opened.  */
 | 
| +  if( eOp==SAVEPOINT_ROLLBACK ){
 | 
| +    db->nDeferredCons = p->nStmtDefCons;
 | 
| +    db->nDeferredImmCons = p->nStmtDefImmCons;
 | 
|    }
 | 
|    return rc;
 | 
|  }
 | 
| +int sqlite3VdbeCloseStatement(Vdbe *p, int eOp){
 | 
| +  if( p->db->nStatement && p->iStatement ){
 | 
| +    return vdbeCloseStatement(p, eOp);
 | 
| +  }
 | 
| +  return SQLITE_OK;
 | 
| +}
 | 
| +
 | 
|  
 | 
|  /*
 | 
|  ** This function is called when a transaction opened by the database 
 | 
| @@ -2512,10 +2609,9 @@ int sqlite3VdbeHalt(Vdbe *p){
 | 
|    ** one, or the complete transaction if there is no statement transaction.
 | 
|    */
 | 
|  
 | 
| -  if( p->db->mallocFailed ){
 | 
| -    p->rc = SQLITE_NOMEM;
 | 
| +  if( db->mallocFailed ){
 | 
| +    p->rc = SQLITE_NOMEM_BKPT;
 | 
|    }
 | 
| -  if( p->aOnceFlag ) memset(p->aOnceFlag, 0, p->nOnceFlag);
 | 
|    closeAllCursors(p);
 | 
|    if( p->magic!=VDBE_MAGIC_RUN ){
 | 
|      return SQLITE_OK;
 | 
| @@ -2673,8 +2769,8 @@ int sqlite3VdbeHalt(Vdbe *p){
 | 
|    }
 | 
|    p->magic = VDBE_MAGIC_HALT;
 | 
|    checkActiveVdbeCnt(db);
 | 
| -  if( p->db->mallocFailed ){
 | 
| -    p->rc = SQLITE_NOMEM;
 | 
| +  if( db->mallocFailed ){
 | 
| +    p->rc = SQLITE_NOMEM_BKPT;
 | 
|    }
 | 
|  
 | 
|    /* If the auto-commit flag is set to true, then any locks that were held
 | 
| @@ -2710,12 +2806,12 @@ int sqlite3VdbeTransferError(Vdbe *p){
 | 
|    sqlite3 *db = p->db;
 | 
|    int rc = p->rc;
 | 
|    if( p->zErrMsg ){
 | 
| -    u8 mallocFailed = db->mallocFailed;
 | 
| +    db->bBenignMalloc++;
 | 
|      sqlite3BeginBenignMalloc();
 | 
|      if( db->pErr==0 ) db->pErr = sqlite3ValueNew(db);
 | 
|      sqlite3ValueSetStr(db->pErr, -1, p->zErrMsg, SQLITE_UTF8, SQLITE_TRANSIENT);
 | 
|      sqlite3EndBenignMalloc();
 | 
| -    db->mallocFailed = mallocFailed;
 | 
| +    db->bBenignMalloc--;
 | 
|      db->errCode = rc;
 | 
|    }else{
 | 
|      sqlite3Error(db, rc);
 | 
| @@ -2827,7 +2923,7 @@ int sqlite3VdbeReset(Vdbe *p){
 | 
|    }
 | 
|  #endif
 | 
|    p->iCurrentTime = 0;
 | 
| -  p->magic = VDBE_MAGIC_INIT;
 | 
| +  p->magic = VDBE_MAGIC_RESET;
 | 
|    return p->rc & db->errMask;
 | 
|  }
 | 
|   
 | 
| @@ -2861,8 +2957,7 @@ int sqlite3VdbeFinalize(Vdbe *p){
 | 
|  **    * the corresponding bit in argument mask is clear (where the first
 | 
|  **      function parameter corresponds to bit 0 etc.).
 | 
|  */
 | 
| -void sqlite3VdbeDeleteAuxData(Vdbe *pVdbe, int iOp, int mask){
 | 
| -  AuxData **pp = &pVdbe->pAuxData;
 | 
| +void sqlite3VdbeDeleteAuxData(sqlite3 *db, AuxData **pp, int iOp, int mask){
 | 
|    while( *pp ){
 | 
|      AuxData *pAux = *pp;
 | 
|      if( (iOp<0)
 | 
| @@ -2873,7 +2968,7 @@ void sqlite3VdbeDeleteAuxData(Vdbe *pVdbe, int iOp, int mask){
 | 
|          pAux->xDelete(pAux->pAux);
 | 
|        }
 | 
|        *pp = pAux->pNext;
 | 
| -      sqlite3DbFree(pVdbe->db, pAux);
 | 
| +      sqlite3DbFree(db, pAux);
 | 
|      }else{
 | 
|        pp= &pAux->pNext;
 | 
|      }
 | 
| @@ -2890,25 +2985,29 @@ void sqlite3VdbeDeleteAuxData(Vdbe *pVdbe, int iOp, int mask){
 | 
|  */
 | 
|  void sqlite3VdbeClearObject(sqlite3 *db, Vdbe *p){
 | 
|    SubProgram *pSub, *pNext;
 | 
| -  int i;
 | 
|    assert( p->db==0 || p->db==db );
 | 
| -  releaseMemArray(p->aVar, p->nVar);
 | 
|    releaseMemArray(p->aColName, p->nResColumn*COLNAME_N);
 | 
|    for(pSub=p->pProgram; pSub; pSub=pNext){
 | 
|      pNext = pSub->pNext;
 | 
|      vdbeFreeOpArray(db, pSub->aOp, pSub->nOp);
 | 
|      sqlite3DbFree(db, pSub);
 | 
|    }
 | 
| -  for(i=p->nzVar-1; i>=0; i--) sqlite3DbFree(db, p->azVar[i]);
 | 
| +  if( p->magic!=VDBE_MAGIC_INIT ){
 | 
| +    releaseMemArray(p->aVar, p->nVar);
 | 
| +    sqlite3DbFree(db, p->pVList);
 | 
| +    sqlite3DbFree(db, p->pFree);
 | 
| +  }
 | 
|    vdbeFreeOpArray(db, p->aOp, p->nOp);
 | 
|    sqlite3DbFree(db, p->aColName);
 | 
|    sqlite3DbFree(db, p->zSql);
 | 
| -  sqlite3DbFree(db, p->pFree);
 | 
|  #ifdef SQLITE_ENABLE_STMT_SCANSTATUS
 | 
| -  for(i=0; i<p->nScan; i++){
 | 
| -    sqlite3DbFree(db, p->aScan[i].zName);
 | 
| +  {
 | 
| +    int i;
 | 
| +    for(i=0; i<p->nScan; i++){
 | 
| +      sqlite3DbFree(db, p->aScan[i].zName);
 | 
| +    }
 | 
| +    sqlite3DbFree(db, p->aScan);
 | 
|    }
 | 
| -  sqlite3DbFree(db, p->aScan);
 | 
|  #endif
 | 
|  }
 | 
|  
 | 
| @@ -3003,9 +3102,16 @@ int sqlite3VdbeCursorRestore(VdbeCursor *p){
 | 
|  ** If the cursor is already pointing to the correct row and that row has
 | 
|  ** not been deleted out from under the cursor, then this routine is a no-op.
 | 
|  */
 | 
| -int sqlite3VdbeCursorMoveto(VdbeCursor *p){
 | 
| +int sqlite3VdbeCursorMoveto(VdbeCursor **pp, int *piCol){
 | 
| +  VdbeCursor *p = *pp;
 | 
|    if( p->eCurType==CURTYPE_BTREE ){
 | 
|      if( p->deferredMoveto ){
 | 
| +      int iMap;
 | 
| +      if( p->aAltMap && (iMap = p->aAltMap[1+*piCol])>0 ){
 | 
| +        *pp = p->pAltCursor;
 | 
| +        *piCol = iMap - 1;
 | 
| +        return SQLITE_OK;
 | 
| +      }
 | 
|        return handleDeferredMoveto(p);
 | 
|      }
 | 
|      if( sqlite3BtreeCursorHasMoved(p->uc.pCursor) ){
 | 
| @@ -3402,30 +3508,13 @@ u32 sqlite3VdbeSerialGet(
 | 
|  ** If an OOM error occurs, NULL is returned.
 | 
|  */
 | 
|  UnpackedRecord *sqlite3VdbeAllocUnpackedRecord(
 | 
| -  KeyInfo *pKeyInfo,              /* Description of the record */
 | 
| -  char *pSpace,                   /* Unaligned space available */
 | 
| -  int szSpace,                    /* Size of pSpace[] in bytes */
 | 
| -  char **ppFree                   /* OUT: Caller should free this pointer */
 | 
| +  KeyInfo *pKeyInfo               /* Description of the record */
 | 
|  ){
 | 
|    UnpackedRecord *p;              /* Unpacked record to return */
 | 
| -  int nOff;                       /* Increment pSpace by nOff to align it */
 | 
|    int nByte;                      /* Number of bytes required for *p */
 | 
| -
 | 
| -  /* We want to shift the pointer pSpace up such that it is 8-byte aligned.
 | 
| -  ** Thus, we need to calculate a value, nOff, between 0 and 7, to shift 
 | 
| -  ** it by.  If pSpace is already 8-byte aligned, nOff should be zero.
 | 
| -  */
 | 
| -  nOff = (8 - (SQLITE_PTR_TO_INT(pSpace) & 7)) & 7;
 | 
|    nByte = ROUND8(sizeof(UnpackedRecord)) + sizeof(Mem)*(pKeyInfo->nField+1);
 | 
| -  if( nByte>szSpace+nOff ){
 | 
| -    p = (UnpackedRecord *)sqlite3DbMallocRaw(pKeyInfo->db, nByte);
 | 
| -    *ppFree = (char *)p;
 | 
| -    if( !p ) return 0;
 | 
| -  }else{
 | 
| -    p = (UnpackedRecord*)&pSpace[nOff];
 | 
| -    *ppFree = 0;
 | 
| -  }
 | 
| -
 | 
| +  p = (UnpackedRecord *)sqlite3DbMallocRaw(pKeyInfo->db, nByte);
 | 
| +  if( !p ) return 0;
 | 
|    p->aMem = (Mem*)&((char*)p)[ROUND8(sizeof(UnpackedRecord))];
 | 
|    assert( pKeyInfo->aSortOrder!=0 );
 | 
|    p->pKeyInfo = pKeyInfo;
 | 
| @@ -3464,6 +3553,7 @@ void sqlite3VdbeRecordUnpack(
 | 
|      pMem->db = pKeyInfo->db;
 | 
|      /* pMem->flags = 0; // sqlite3VdbeSerialGet() will set this for us */
 | 
|      pMem->szMalloc = 0;
 | 
| +    pMem->z = 0;
 | 
|      d += sqlite3VdbeSerialGet(&aKey[d], serial_type, pMem);
 | 
|      pMem++;
 | 
|      if( (++u)>=p->nField ) break;
 | 
| @@ -3644,22 +3734,56 @@ static int vdbeCompareMemString(
 | 
|      v2 = sqlite3ValueText((sqlite3_value*)&c2, pColl->enc);
 | 
|      n2 = v2==0 ? 0 : c2.n;
 | 
|      rc = pColl->xCmp(pColl->pUser, n1, v1, n2, v2);
 | 
| +    if( (v1==0 || v2==0) && prcErr ) *prcErr = SQLITE_NOMEM_BKPT;
 | 
|      sqlite3VdbeMemRelease(&c1);
 | 
|      sqlite3VdbeMemRelease(&c2);
 | 
| -    if( (v1==0 || v2==0) && prcErr ) *prcErr = SQLITE_NOMEM;
 | 
|      return rc;
 | 
|    }
 | 
|  }
 | 
|  
 | 
|  /*
 | 
| +** The input pBlob is guaranteed to be a Blob that is not marked
 | 
| +** with MEM_Zero.  Return true if it could be a zero-blob.
 | 
| +*/
 | 
| +static int isAllZero(const char *z, int n){
 | 
| +  int i;
 | 
| +  for(i=0; i<n; i++){
 | 
| +    if( z[i] ) return 0;
 | 
| +  }
 | 
| +  return 1;
 | 
| +}
 | 
| +
 | 
| +/*
 | 
|  ** Compare two blobs.  Return negative, zero, or positive if the first
 | 
|  ** is less than, equal to, or greater than the second, respectively.
 | 
|  ** If one blob is a prefix of the other, then the shorter is the lessor.
 | 
|  */
 | 
|  static SQLITE_NOINLINE int sqlite3BlobCompare(const Mem *pB1, const Mem *pB2){
 | 
| -  int c = memcmp(pB1->z, pB2->z, pB1->n>pB2->n ? pB2->n : pB1->n);
 | 
| +  int c;
 | 
| +  int n1 = pB1->n;
 | 
| +  int n2 = pB2->n;
 | 
| +
 | 
| +  /* It is possible to have a Blob value that has some non-zero content
 | 
| +  ** followed by zero content.  But that only comes up for Blobs formed
 | 
| +  ** by the OP_MakeRecord opcode, and such Blobs never get passed into
 | 
| +  ** sqlite3MemCompare(). */
 | 
| +  assert( (pB1->flags & MEM_Zero)==0 || n1==0 );
 | 
| +  assert( (pB2->flags & MEM_Zero)==0 || n2==0 );
 | 
| +
 | 
| +  if( (pB1->flags|pB2->flags) & MEM_Zero ){
 | 
| +    if( pB1->flags & pB2->flags & MEM_Zero ){
 | 
| +      return pB1->u.nZero - pB2->u.nZero;
 | 
| +    }else if( pB1->flags & MEM_Zero ){
 | 
| +      if( !isAllZero(pB2->z, pB2->n) ) return -1;
 | 
| +      return pB1->u.nZero - n2;
 | 
| +    }else{
 | 
| +      if( !isAllZero(pB1->z, pB1->n) ) return +1;
 | 
| +      return n1 - pB2->u.nZero;
 | 
| +    }
 | 
| +  }
 | 
| +  c = memcmp(pB1->z, pB2->z, n1>n2 ? n2 : n1);
 | 
|    if( c ) return c;
 | 
| -  return pB1->n - pB2->n;
 | 
| +  return n1 - n2;
 | 
|  }
 | 
|  
 | 
|  /*
 | 
| @@ -3965,6 +4089,7 @@ int sqlite3VdbeRecordCompareWithSkip(
 | 
|  
 | 
|      /* RHS is a blob */
 | 
|      else if( pRhs->flags & MEM_Blob ){
 | 
| +      assert( (pRhs->flags & MEM_Zero)==0 || pRhs->n==0 );
 | 
|        getVarint32(&aKey1[idx1], serial_type);
 | 
|        testcase( serial_type==12 );
 | 
|        if( serial_type<12 || (serial_type & 0x01) ){
 | 
| @@ -3976,6 +4101,12 @@ int sqlite3VdbeRecordCompareWithSkip(
 | 
|          if( (d1+nStr) > (unsigned)nKey1 ){
 | 
|            pPKey2->errCode = (u8)SQLITE_CORRUPT_BKPT;
 | 
|            return 0;                /* Corruption */
 | 
| +        }else if( pRhs->flags & MEM_Zero ){
 | 
| +          if( !isAllZero((const char*)&aKey1[d1],nStr) ){
 | 
| +            rc = 1;
 | 
| +          }else{
 | 
| +            rc = nStr - pRhs->u.nZero;
 | 
| +          }
 | 
|          }else{
 | 
|            int nCmp = MIN(nStr, pRhs->n);
 | 
|            rc = memcmp(&aKey1[d1], pRhs->z, nCmp);
 | 
| @@ -4046,7 +4177,7 @@ static int vdbeRecordCompareInt(
 | 
|    int res;
 | 
|    u32 y;
 | 
|    u64 x;
 | 
| -  i64 v = pPKey2->aMem[0].u.i;
 | 
| +  i64 v;
 | 
|    i64 lhs;
 | 
|  
 | 
|    vdbeAssertFieldCountWithinLimits(nKey1, pKey1, pPKey2->pKeyInfo);
 | 
| @@ -4105,6 +4236,7 @@ static int vdbeRecordCompareInt(
 | 
|        return sqlite3VdbeRecordCompare(nKey1, pKey1, pPKey2);
 | 
|    }
 | 
|  
 | 
| +  v = pPKey2->aMem[0].u.i;
 | 
|    if( v>lhs ){
 | 
|      res = pPKey2->r1;
 | 
|    }else if( v<lhs ){
 | 
| @@ -4251,13 +4383,12 @@ int sqlite3VdbeIdxRowid(sqlite3 *db, BtCursor *pCur, i64 *rowid){
 | 
|    ** this code can safely assume that nCellKey is 32-bits  
 | 
|    */
 | 
|    assert( sqlite3BtreeCursorIsValid(pCur) );
 | 
| -  VVA_ONLY(rc =) sqlite3BtreeKeySize(pCur, &nCellKey);
 | 
| -  assert( rc==SQLITE_OK );     /* pCur is always valid so KeySize cannot fail */
 | 
| +  nCellKey = sqlite3BtreePayloadSize(pCur);
 | 
|    assert( (nCellKey & SQLITE_MAX_U32)==(u64)nCellKey );
 | 
|  
 | 
|    /* Read in the complete content of the index entry */
 | 
|    sqlite3VdbeMemInit(&m, db, 0);
 | 
| -  rc = sqlite3VdbeMemFromBtree(pCur, 0, (u32)nCellKey, 1, &m);
 | 
| +  rc = sqlite3VdbeMemFromBtree(pCur, 0, (u32)nCellKey, &m);
 | 
|    if( rc ){
 | 
|      return rc;
 | 
|    }
 | 
| @@ -4329,8 +4460,7 @@ int sqlite3VdbeIdxKeyCompare(
 | 
|    assert( pC->eCurType==CURTYPE_BTREE );
 | 
|    pCur = pC->uc.pCursor;
 | 
|    assert( sqlite3BtreeCursorIsValid(pCur) );
 | 
| -  VVA_ONLY(rc =) sqlite3BtreeKeySize(pCur, &nCellKey);
 | 
| -  assert( rc==SQLITE_OK );    /* pCur is always valid so KeySize cannot fail */
 | 
| +  nCellKey = sqlite3BtreePayloadSize(pCur);
 | 
|    /* nCellKey will always be between 0 and 0xffffffff because of the way
 | 
|    ** that btreeParseCellPtr() and sqlite3GetVarint32() are implemented */
 | 
|    if( nCellKey<=0 || nCellKey>0x7fffffff ){
 | 
| @@ -4338,7 +4468,7 @@ int sqlite3VdbeIdxKeyCompare(
 | 
|      return SQLITE_CORRUPT_BKPT;
 | 
|    }
 | 
|    sqlite3VdbeMemInit(&m, db, 0);
 | 
| -  rc = sqlite3VdbeMemFromBtree(pCur, 0, (u32)nCellKey, 1, &m);
 | 
| +  rc = sqlite3VdbeMemFromBtree(pCur, 0, (u32)nCellKey, &m);
 | 
|    if( rc ){
 | 
|      return rc;
 | 
|    }
 | 
| @@ -4434,10 +4564,101 @@ void sqlite3VdbeSetVarmask(Vdbe *v, int iVar){
 | 
|  ** in memory obtained from sqlite3DbMalloc).
 | 
|  */
 | 
|  void sqlite3VtabImportErrmsg(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;
 | 
| +  if( pVtab->zErrMsg ){
 | 
| +    sqlite3 *db = p->db;
 | 
| +    sqlite3DbFree(db, p->zErrMsg);
 | 
| +    p->zErrMsg = sqlite3DbStrDup(db, pVtab->zErrMsg);
 | 
| +    sqlite3_free(pVtab->zErrMsg);
 | 
| +    pVtab->zErrMsg = 0;
 | 
| +  }
 | 
|  }
 | 
|  #endif /* SQLITE_OMIT_VIRTUALTABLE */
 | 
| +
 | 
| +#ifdef SQLITE_ENABLE_PREUPDATE_HOOK
 | 
| +
 | 
| +/*
 | 
| +** If the second argument is not NULL, release any allocations associated 
 | 
| +** with the memory cells in the p->aMem[] array. Also free the UnpackedRecord
 | 
| +** structure itself, using sqlite3DbFree().
 | 
| +**
 | 
| +** This function is used to free UnpackedRecord structures allocated by
 | 
| +** the vdbeUnpackRecord() function found in vdbeapi.c.
 | 
| +*/
 | 
| +static void vdbeFreeUnpacked(sqlite3 *db, int nField, UnpackedRecord *p){
 | 
| +  if( p ){
 | 
| +    int i;
 | 
| +    for(i=0; i<nField; i++){
 | 
| +      Mem *pMem = &p->aMem[i];
 | 
| +      if( pMem->zMalloc ) sqlite3VdbeMemRelease(pMem);
 | 
| +    }
 | 
| +    sqlite3DbFree(db, p);
 | 
| +  }
 | 
| +}
 | 
| +#endif /* SQLITE_ENABLE_PREUPDATE_HOOK */
 | 
| +
 | 
| +#ifdef SQLITE_ENABLE_PREUPDATE_HOOK
 | 
| +/*
 | 
| +** Invoke the pre-update hook. If this is an UPDATE or DELETE pre-update call,
 | 
| +** then cursor passed as the second argument should point to the row about
 | 
| +** to be update or deleted. If the application calls sqlite3_preupdate_old(),
 | 
| +** the required value will be read from the row the cursor points to.
 | 
| +*/
 | 
| +void sqlite3VdbePreUpdateHook(
 | 
| +  Vdbe *v,                        /* Vdbe pre-update hook is invoked by */
 | 
| +  VdbeCursor *pCsr,               /* Cursor to grab old.* values from */
 | 
| +  int op,                         /* SQLITE_INSERT, UPDATE or DELETE */
 | 
| +  const char *zDb,                /* Database name */
 | 
| +  Table *pTab,                    /* Modified table */
 | 
| +  i64 iKey1,                      /* Initial key value */
 | 
| +  int iReg                        /* Register for new.* record */
 | 
| +){
 | 
| +  sqlite3 *db = v->db;
 | 
| +  i64 iKey2;
 | 
| +  PreUpdate preupdate;
 | 
| +  const char *zTbl = pTab->zName;
 | 
| +  static const u8 fakeSortOrder = 0;
 | 
| +
 | 
| +  assert( db->pPreUpdate==0 );
 | 
| +  memset(&preupdate, 0, sizeof(PreUpdate));
 | 
| +  if( HasRowid(pTab)==0 ){
 | 
| +    iKey1 = iKey2 = 0;
 | 
| +    preupdate.pPk = sqlite3PrimaryKeyIndex(pTab);
 | 
| +  }else{
 | 
| +    if( op==SQLITE_UPDATE ){
 | 
| +      iKey2 = v->aMem[iReg].u.i;
 | 
| +    }else{
 | 
| +      iKey2 = iKey1;
 | 
| +    }
 | 
| +  }
 | 
| +
 | 
| +  assert( pCsr->nField==pTab->nCol 
 | 
| +       || (pCsr->nField==pTab->nCol+1 && op==SQLITE_DELETE && iReg==-1)
 | 
| +  );
 | 
| +
 | 
| +  preupdate.v = v;
 | 
| +  preupdate.pCsr = pCsr;
 | 
| +  preupdate.op = op;
 | 
| +  preupdate.iNewReg = iReg;
 | 
| +  preupdate.keyinfo.db = db;
 | 
| +  preupdate.keyinfo.enc = ENC(db);
 | 
| +  preupdate.keyinfo.nField = pTab->nCol;
 | 
| +  preupdate.keyinfo.aSortOrder = (u8*)&fakeSortOrder;
 | 
| +  preupdate.iKey1 = iKey1;
 | 
| +  preupdate.iKey2 = iKey2;
 | 
| +  preupdate.pTab = pTab;
 | 
| +
 | 
| +  db->pPreUpdate = &preupdate;
 | 
| +  db->xPreUpdateCallback(db->pPreUpdateArg, db, op, zDb, zTbl, iKey1, iKey2);
 | 
| +  db->pPreUpdate = 0;
 | 
| +  sqlite3DbFree(db, preupdate.aRecord);
 | 
| +  vdbeFreeUnpacked(db, preupdate.keyinfo.nField+1, preupdate.pUnpacked);
 | 
| +  vdbeFreeUnpacked(db, preupdate.keyinfo.nField+1, preupdate.pNewUnpacked);
 | 
| +  if( preupdate.aNew ){
 | 
| +    int i;
 | 
| +    for(i=0; i<pCsr->nField; i++){
 | 
| +      sqlite3VdbeMemRelease(&preupdate.aNew[i]);
 | 
| +    }
 | 
| +    sqlite3DbFree(db, preupdate.aNew);
 | 
| +  }
 | 
| +}
 | 
| +#endif /* SQLITE_ENABLE_PREUPDATE_HOOK */
 | 
| 
 |