| Index: third_party/sqlite/src/src/vdbeapi.c
 | 
| diff --git a/third_party/sqlite/src/src/vdbeapi.c b/third_party/sqlite/src/src/vdbeapi.c
 | 
| index 33c6ba3b287e9a45eb9beaf6d89cda513a029cfd..6eb97f1d1ddb0ce90158d866d0a5dd9cdd3e7610 100644
 | 
| --- a/third_party/sqlite/src/src/vdbeapi.c
 | 
| +++ b/third_party/sqlite/src/src/vdbeapi.c
 | 
| @@ -60,12 +60,19 @@ static int vdbeSafetyNotNull(Vdbe *p){
 | 
|  */
 | 
|  static SQLITE_NOINLINE void invokeProfileCallback(sqlite3 *db, Vdbe *p){
 | 
|    sqlite3_int64 iNow;
 | 
| +  sqlite3_int64 iElapse;
 | 
|    assert( p->startTime>0 );
 | 
| -  assert( db->xProfile!=0 );
 | 
| +  assert( db->xProfile!=0 || (db->mTrace & SQLITE_TRACE_PROFILE)!=0 );
 | 
|    assert( db->init.busy==0 );
 | 
|    assert( p->zSql!=0 );
 | 
|    sqlite3OsCurrentTimeInt64(db->pVfs, &iNow);
 | 
| -  db->xProfile(db->pProfileArg, p->zSql, (iNow - p->startTime)*1000000);
 | 
| +  iElapse = (iNow - p->startTime)*1000000;
 | 
| +  if( db->xProfile ){
 | 
| +    db->xProfile(db->pProfileArg, p->zSql, iElapse);
 | 
| +  }
 | 
| +  if( db->mTrace & SQLITE_TRACE_PROFILE ){
 | 
| +    db->xTrace(SQLITE_TRACE_PROFILE, db->pTraceArg, p, (void*)&iElapse);
 | 
| +  }
 | 
|    p->startTime = 0;
 | 
|  }
 | 
|  /*
 | 
| @@ -162,7 +169,7 @@ int sqlite3_clear_bindings(sqlite3_stmt *pStmt){
 | 
|  const void *sqlite3_value_blob(sqlite3_value *pVal){
 | 
|    Mem *p = (Mem*)pVal;
 | 
|    if( p->flags & (MEM_Blob|MEM_Str) ){
 | 
| -    if( sqlite3VdbeMemExpandBlob(p)!=SQLITE_OK ){
 | 
| +    if( ExpandBlob(p)!=SQLITE_OK ){
 | 
|        assert( p->flags==MEM_Null && p->z==0 );
 | 
|        return 0;
 | 
|      }
 | 
| @@ -188,7 +195,8 @@ sqlite_int64 sqlite3_value_int64(sqlite3_value *pVal){
 | 
|    return sqlite3VdbeIntValue((Mem*)pVal);
 | 
|  }
 | 
|  unsigned int sqlite3_value_subtype(sqlite3_value *pVal){
 | 
| -  return ((Mem*)pVal)->eSubtype;
 | 
| +  Mem *pMem = (Mem*)pVal;
 | 
| +  return ((pMem->flags & MEM_Subtype) ? pMem->eSubtype : 0);
 | 
|  }
 | 
|  const unsigned char *sqlite3_value_text(sqlite3_value *pVal){
 | 
|    return (const unsigned char *)sqlite3ValueText(pVal, SQLITE_UTF8);
 | 
| @@ -369,8 +377,10 @@ void sqlite3_result_null(sqlite3_context *pCtx){
 | 
|    sqlite3VdbeMemSetNull(pCtx->pOut);
 | 
|  }
 | 
|  void sqlite3_result_subtype(sqlite3_context *pCtx, unsigned int eSubtype){
 | 
| -  assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
 | 
| -  pCtx->pOut->eSubtype = eSubtype & 0xff;
 | 
| +  Mem *pOut = pCtx->pOut;
 | 
| +  assert( sqlite3_mutex_held(pOut->db->mutex) );
 | 
| +  pOut->eSubtype = eSubtype & 0xff;
 | 
| +  pOut->flags |= MEM_Subtype;
 | 
|  }
 | 
|  void sqlite3_result_text(
 | 
|    sqlite3_context *pCtx, 
 | 
| @@ -468,9 +478,9 @@ void sqlite3_result_error_toobig(sqlite3_context *pCtx){
 | 
|  void sqlite3_result_error_nomem(sqlite3_context *pCtx){
 | 
|    assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
 | 
|    sqlite3VdbeMemSetNull(pCtx->pOut);
 | 
| -  pCtx->isError = SQLITE_NOMEM;
 | 
| +  pCtx->isError = SQLITE_NOMEM_BKPT;
 | 
|    pCtx->fErrorOrAux = 1;
 | 
| -  pCtx->pOut->db->mallocFailed = 1;
 | 
| +  sqlite3OomFault(pCtx->pOut->db);
 | 
|  }
 | 
|  
 | 
|  /*
 | 
| @@ -489,7 +499,7 @@ static int doWalCallbacks(sqlite3 *db){
 | 
|        nEntry = sqlite3PagerWalCallback(sqlite3BtreePager(pBt));
 | 
|        sqlite3BtreeLeave(pBt);
 | 
|        if( db->xWalCallback && nEntry>0 && rc==SQLITE_OK ){
 | 
| -        rc = db->xWalCallback(db->pWalArg, db, db->aDb[i].zName, nEntry);
 | 
| +        rc = db->xWalCallback(db->pWalArg, db, db->aDb[i].zDbSName, nEntry);
 | 
|        }
 | 
|      }
 | 
|    }
 | 
| @@ -544,7 +554,7 @@ static int sqlite3Step(Vdbe *p){
 | 
|    db = p->db;
 | 
|    if( db->mallocFailed ){
 | 
|      p->rc = SQLITE_NOMEM;
 | 
| -    return SQLITE_NOMEM;
 | 
| +    return SQLITE_NOMEM_BKPT;
 | 
|    }
 | 
|  
 | 
|    if( p->pc<=0 && p->expired ){
 | 
| @@ -566,7 +576,8 @@ static int sqlite3Step(Vdbe *p){
 | 
|      );
 | 
|  
 | 
|  #ifndef SQLITE_OMIT_TRACE
 | 
| -    if( db->xProfile && !db->init.busy && p->zSql ){
 | 
| +    if( (db->xProfile || (db->mTrace & SQLITE_TRACE_PROFILE)!=0)
 | 
| +        && !db->init.busy && p->zSql ){
 | 
|        sqlite3OsCurrentTimeInt64(db->pVfs, &p->startTime);
 | 
|      }else{
 | 
|        assert( p->startTime==0 );
 | 
| @@ -607,7 +618,7 @@ static int sqlite3Step(Vdbe *p){
 | 
|  
 | 
|    db->errCode = rc;
 | 
|    if( SQLITE_NOMEM==sqlite3ApiExit(p->db, p->rc) ){
 | 
| -    p->rc = SQLITE_NOMEM;
 | 
| +    p->rc = SQLITE_NOMEM_BKPT;
 | 
|    }
 | 
|  end_of_step:
 | 
|    /* At this point local variable rc holds the value that should be 
 | 
| @@ -674,7 +685,7 @@ int sqlite3_step(sqlite3_stmt *pStmt){
 | 
|        v->rc = rc2;
 | 
|      } else {
 | 
|        v->zErrMsg = 0;
 | 
| -      v->rc = rc = SQLITE_NOMEM;
 | 
| +      v->rc = rc = SQLITE_NOMEM_BKPT;
 | 
|      }
 | 
|    }
 | 
|    rc = sqlite3ApiExit(db, rc);
 | 
| @@ -779,7 +790,7 @@ static SQLITE_NOINLINE void *createAggContext(sqlite3_context *p, int nByte){
 | 
|  ** same context that was returned on prior calls.
 | 
|  */
 | 
|  void *sqlite3_aggregate_context(sqlite3_context *p, int nByte){
 | 
| -  assert( p && p->pFunc && p->pFunc->xStep );
 | 
| +  assert( p && p->pFunc && p->pFunc->xFinalize );
 | 
|    assert( sqlite3_mutex_held(p->pOut->db->mutex) );
 | 
|    testcase( nByte<0 );
 | 
|    if( (p->pMem->flags & MEM_Agg)==0 ){
 | 
| @@ -870,7 +881,7 @@ failed:
 | 
|  ** context.
 | 
|  */
 | 
|  int sqlite3_aggregate_count(sqlite3_context *p){
 | 
| -  assert( p && p->pMem && p->pFunc && p->pFunc->xStep );
 | 
| +  assert( p && p->pMem && p->pFunc && p->pFunc->xFinalize );
 | 
|    return p->pMem->n;
 | 
|  }
 | 
|  #endif
 | 
| @@ -941,14 +952,13 @@ static Mem *columnMem(sqlite3_stmt *pStmt, int i){
 | 
|    Mem *pOut;
 | 
|  
 | 
|    pVm = (Vdbe *)pStmt;
 | 
| -  if( pVm && pVm->pResultSet!=0 && i<pVm->nResColumn && i>=0 ){
 | 
| -    sqlite3_mutex_enter(pVm->db->mutex);
 | 
| +  if( pVm==0 ) return (Mem*)columnNullValue();
 | 
| +  assert( pVm->db );
 | 
| +  sqlite3_mutex_enter(pVm->db->mutex);
 | 
| +  if( pVm->pResultSet!=0 && i<pVm->nResColumn && i>=0 ){
 | 
|      pOut = &pVm->pResultSet[i];
 | 
|    }else{
 | 
| -    if( pVm && ALWAYS(pVm->db) ){
 | 
| -      sqlite3_mutex_enter(pVm->db->mutex);
 | 
| -      sqlite3Error(pVm->db, SQLITE_RANGE);
 | 
| -    }
 | 
| +    sqlite3Error(pVm->db, SQLITE_RANGE);
 | 
|      pOut = (Mem*)columnNullValue();
 | 
|    }
 | 
|    return pOut;
 | 
| @@ -981,6 +991,8 @@ static void columnMallocFailure(sqlite3_stmt *pStmt)
 | 
|    */
 | 
|    Vdbe *p = (Vdbe *)pStmt;
 | 
|    if( p ){
 | 
| +    assert( p->db!=0 );
 | 
| +    assert( sqlite3_mutex_held(p->db->mutex) );
 | 
|      p->rc = sqlite3ApiExit(p->db, p->rc);
 | 
|      sqlite3_mutex_leave(p->db->mutex);
 | 
|    }
 | 
| @@ -1098,7 +1110,7 @@ static const void *columnName(
 | 
|      ** is the case, clear the mallocFailed flag and return NULL.
 | 
|      */
 | 
|      if( db->mallocFailed ){
 | 
| -      db->mallocFailed = 0;
 | 
| +      sqlite3OomClear(db);
 | 
|        ret = 0;
 | 
|      }
 | 
|      sqlite3_mutex_leave(db->mutex);
 | 
| @@ -1298,6 +1310,9 @@ int sqlite3_bind_blob(
 | 
|    int nData, 
 | 
|    void (*xDel)(void*)
 | 
|  ){
 | 
| +#ifdef SQLITE_ENABLE_API_ARMOR
 | 
| +  if( nData<0 ) return SQLITE_MISUSE_BKPT;
 | 
| +#endif
 | 
|    return bindText(pStmt, i, zData, nData, xDel, 0);
 | 
|  }
 | 
|  int sqlite3_bind_blob64(
 | 
| @@ -1455,10 +1470,8 @@ int sqlite3_bind_parameter_count(sqlite3_stmt *pStmt){
 | 
|  */
 | 
|  const char *sqlite3_bind_parameter_name(sqlite3_stmt *pStmt, int i){
 | 
|    Vdbe *p = (Vdbe*)pStmt;
 | 
| -  if( p==0 || i<1 || i>p->nzVar ){
 | 
| -    return 0;
 | 
| -  }
 | 
| -  return p->azVar[i-1];
 | 
| +  if( p==0 ) return 0;
 | 
| +  return sqlite3VListNumToName(p->pVList, i);
 | 
|  }
 | 
|  
 | 
|  /*
 | 
| @@ -1467,19 +1480,8 @@ const char *sqlite3_bind_parameter_name(sqlite3_stmt *pStmt, int i){
 | 
|  ** return 0.
 | 
|  */
 | 
|  int sqlite3VdbeParameterIndex(Vdbe *p, const char *zName, int nName){
 | 
| -  int i;
 | 
| -  if( p==0 ){
 | 
| -    return 0;
 | 
| -  }
 | 
| -  if( zName ){
 | 
| -    for(i=0; i<p->nzVar; i++){
 | 
| -      const char *z = p->azVar[i];
 | 
| -      if( z && strncmp(z,zName,nName)==0 && z[nName]==0 ){
 | 
| -        return i+1;
 | 
| -      }
 | 
| -    }
 | 
| -  }
 | 
| -  return 0;
 | 
| +  if( p==0 || zName==0 ) return 0;
 | 
| +  return sqlite3VListNameToNum(p->pVList, zName, nName);
 | 
|  }
 | 
|  int sqlite3_bind_parameter_index(sqlite3_stmt *pStmt, const char *zName){
 | 
|    return sqlite3VdbeParameterIndex((Vdbe*)pStmt, zName, sqlite3Strlen30(zName));
 | 
| @@ -1554,7 +1556,7 @@ int sqlite3_stmt_readonly(sqlite3_stmt *pStmt){
 | 
|  */
 | 
|  int sqlite3_stmt_busy(sqlite3_stmt *pStmt){
 | 
|    Vdbe *v = (Vdbe*)pStmt;
 | 
| -  return v!=0 && v->pc>=0 && v->magic==VDBE_MAGIC_RUN;
 | 
| +  return v!=0 && v->magic==VDBE_MAGIC_RUN && v->pc>=0;
 | 
|  }
 | 
|  
 | 
|  /*
 | 
| @@ -1598,6 +1600,225 @@ int sqlite3_stmt_status(sqlite3_stmt *pStmt, int op, int resetFlag){
 | 
|    return (int)v;
 | 
|  }
 | 
|  
 | 
| +/*
 | 
| +** Return the SQL associated with a prepared statement
 | 
| +*/
 | 
| +const char *sqlite3_sql(sqlite3_stmt *pStmt){
 | 
| +  Vdbe *p = (Vdbe *)pStmt;
 | 
| +  return p ? p->zSql : 0;
 | 
| +}
 | 
| +
 | 
| +/*
 | 
| +** Return the SQL associated with a prepared statement with
 | 
| +** bound parameters expanded.  Space to hold the returned string is
 | 
| +** obtained from sqlite3_malloc().  The caller is responsible for
 | 
| +** freeing the returned string by passing it to sqlite3_free().
 | 
| +**
 | 
| +** The SQLITE_TRACE_SIZE_LIMIT puts an upper bound on the size of
 | 
| +** expanded bound parameters.
 | 
| +*/
 | 
| +char *sqlite3_expanded_sql(sqlite3_stmt *pStmt){
 | 
| +#ifdef SQLITE_OMIT_TRACE
 | 
| +  return 0;
 | 
| +#else
 | 
| +  char *z = 0;
 | 
| +  const char *zSql = sqlite3_sql(pStmt);
 | 
| +  if( zSql ){
 | 
| +    Vdbe *p = (Vdbe *)pStmt;
 | 
| +    sqlite3_mutex_enter(p->db->mutex);
 | 
| +    z = sqlite3VdbeExpandSql(p, zSql);
 | 
| +    sqlite3_mutex_leave(p->db->mutex);
 | 
| +  }
 | 
| +  return z;
 | 
| +#endif
 | 
| +}
 | 
| +
 | 
| +#ifdef SQLITE_ENABLE_PREUPDATE_HOOK
 | 
| +/*
 | 
| +** Allocate and populate an UnpackedRecord structure based on the serialized
 | 
| +** record in nKey/pKey. Return a pointer to the new UnpackedRecord structure
 | 
| +** if successful, or a NULL pointer if an OOM error is encountered.
 | 
| +*/
 | 
| +static UnpackedRecord *vdbeUnpackRecord(
 | 
| +  KeyInfo *pKeyInfo, 
 | 
| +  int nKey, 
 | 
| +  const void *pKey
 | 
| +){
 | 
| +  UnpackedRecord *pRet;           /* Return value */
 | 
| +
 | 
| +  pRet = sqlite3VdbeAllocUnpackedRecord(pKeyInfo);
 | 
| +  if( pRet ){
 | 
| +    memset(pRet->aMem, 0, sizeof(Mem)*(pKeyInfo->nField+1));
 | 
| +    sqlite3VdbeRecordUnpack(pKeyInfo, nKey, pKey, pRet);
 | 
| +  }
 | 
| +  return pRet;
 | 
| +}
 | 
| +
 | 
| +/*
 | 
| +** This function is called from within a pre-update callback to retrieve
 | 
| +** a field of the row currently being updated or deleted.
 | 
| +*/
 | 
| +int sqlite3_preupdate_old(sqlite3 *db, int iIdx, sqlite3_value **ppValue){
 | 
| +  PreUpdate *p = db->pPreUpdate;
 | 
| +  Mem *pMem;
 | 
| +  int rc = SQLITE_OK;
 | 
| +
 | 
| +  /* Test that this call is being made from within an SQLITE_DELETE or
 | 
| +  ** SQLITE_UPDATE pre-update callback, and that iIdx is within range. */
 | 
| +  if( !p || p->op==SQLITE_INSERT ){
 | 
| +    rc = SQLITE_MISUSE_BKPT;
 | 
| +    goto preupdate_old_out;
 | 
| +  }
 | 
| +  if( p->pPk ){
 | 
| +    iIdx = sqlite3ColumnOfIndex(p->pPk, iIdx);
 | 
| +  }
 | 
| +  if( iIdx>=p->pCsr->nField || iIdx<0 ){
 | 
| +    rc = SQLITE_RANGE;
 | 
| +    goto preupdate_old_out;
 | 
| +  }
 | 
| +
 | 
| +  /* If the old.* record has not yet been loaded into memory, do so now. */
 | 
| +  if( p->pUnpacked==0 ){
 | 
| +    u32 nRec;
 | 
| +    u8 *aRec;
 | 
| +
 | 
| +    nRec = sqlite3BtreePayloadSize(p->pCsr->uc.pCursor);
 | 
| +    aRec = sqlite3DbMallocRaw(db, nRec);
 | 
| +    if( !aRec ) goto preupdate_old_out;
 | 
| +    rc = sqlite3BtreePayload(p->pCsr->uc.pCursor, 0, nRec, aRec);
 | 
| +    if( rc==SQLITE_OK ){
 | 
| +      p->pUnpacked = vdbeUnpackRecord(&p->keyinfo, nRec, aRec);
 | 
| +      if( !p->pUnpacked ) rc = SQLITE_NOMEM;
 | 
| +    }
 | 
| +    if( rc!=SQLITE_OK ){
 | 
| +      sqlite3DbFree(db, aRec);
 | 
| +      goto preupdate_old_out;
 | 
| +    }
 | 
| +    p->aRecord = aRec;
 | 
| +  }
 | 
| +
 | 
| +  pMem = *ppValue = &p->pUnpacked->aMem[iIdx];
 | 
| +  if( iIdx==p->pTab->iPKey ){
 | 
| +    sqlite3VdbeMemSetInt64(pMem, p->iKey1);
 | 
| +  }else if( iIdx>=p->pUnpacked->nField ){
 | 
| +    *ppValue = (sqlite3_value *)columnNullValue();
 | 
| +  }else if( p->pTab->aCol[iIdx].affinity==SQLITE_AFF_REAL ){
 | 
| +    if( pMem->flags & MEM_Int ){
 | 
| +      sqlite3VdbeMemRealify(pMem);
 | 
| +    }
 | 
| +  }
 | 
| +
 | 
| + preupdate_old_out:
 | 
| +  sqlite3Error(db, rc);
 | 
| +  return sqlite3ApiExit(db, rc);
 | 
| +}
 | 
| +#endif /* SQLITE_ENABLE_PREUPDATE_HOOK */
 | 
| +
 | 
| +#ifdef SQLITE_ENABLE_PREUPDATE_HOOK
 | 
| +/*
 | 
| +** This function is called from within a pre-update callback to retrieve
 | 
| +** the number of columns in the row being updated, deleted or inserted.
 | 
| +*/
 | 
| +int sqlite3_preupdate_count(sqlite3 *db){
 | 
| +  PreUpdate *p = db->pPreUpdate;
 | 
| +  return (p ? p->keyinfo.nField : 0);
 | 
| +}
 | 
| +#endif /* SQLITE_ENABLE_PREUPDATE_HOOK */
 | 
| +
 | 
| +#ifdef SQLITE_ENABLE_PREUPDATE_HOOK
 | 
| +/*
 | 
| +** This function is designed to be called from within a pre-update callback
 | 
| +** only. It returns zero if the change that caused the callback was made
 | 
| +** immediately by a user SQL statement. Or, if the change was made by a
 | 
| +** trigger program, it returns the number of trigger programs currently
 | 
| +** on the stack (1 for a top-level trigger, 2 for a trigger fired by a 
 | 
| +** top-level trigger etc.).
 | 
| +**
 | 
| +** For the purposes of the previous paragraph, a foreign key CASCADE, SET NULL
 | 
| +** or SET DEFAULT action is considered a trigger.
 | 
| +*/
 | 
| +int sqlite3_preupdate_depth(sqlite3 *db){
 | 
| +  PreUpdate *p = db->pPreUpdate;
 | 
| +  return (p ? p->v->nFrame : 0);
 | 
| +}
 | 
| +#endif /* SQLITE_ENABLE_PREUPDATE_HOOK */
 | 
| +
 | 
| +#ifdef SQLITE_ENABLE_PREUPDATE_HOOK
 | 
| +/*
 | 
| +** This function is called from within a pre-update callback to retrieve
 | 
| +** a field of the row currently being updated or inserted.
 | 
| +*/
 | 
| +int sqlite3_preupdate_new(sqlite3 *db, int iIdx, sqlite3_value **ppValue){
 | 
| +  PreUpdate *p = db->pPreUpdate;
 | 
| +  int rc = SQLITE_OK;
 | 
| +  Mem *pMem;
 | 
| +
 | 
| +  if( !p || p->op==SQLITE_DELETE ){
 | 
| +    rc = SQLITE_MISUSE_BKPT;
 | 
| +    goto preupdate_new_out;
 | 
| +  }
 | 
| +  if( p->pPk && p->op!=SQLITE_UPDATE ){
 | 
| +    iIdx = sqlite3ColumnOfIndex(p->pPk, iIdx);
 | 
| +  }
 | 
| +  if( iIdx>=p->pCsr->nField || iIdx<0 ){
 | 
| +    rc = SQLITE_RANGE;
 | 
| +    goto preupdate_new_out;
 | 
| +  }
 | 
| +
 | 
| +  if( p->op==SQLITE_INSERT ){
 | 
| +    /* For an INSERT, memory cell p->iNewReg contains the serialized record
 | 
| +    ** that is being inserted. Deserialize it. */
 | 
| +    UnpackedRecord *pUnpack = p->pNewUnpacked;
 | 
| +    if( !pUnpack ){
 | 
| +      Mem *pData = &p->v->aMem[p->iNewReg];
 | 
| +      rc = ExpandBlob(pData);
 | 
| +      if( rc!=SQLITE_OK ) goto preupdate_new_out;
 | 
| +      pUnpack = vdbeUnpackRecord(&p->keyinfo, pData->n, pData->z);
 | 
| +      if( !pUnpack ){
 | 
| +        rc = SQLITE_NOMEM;
 | 
| +        goto preupdate_new_out;
 | 
| +      }
 | 
| +      p->pNewUnpacked = pUnpack;
 | 
| +    }
 | 
| +    pMem = &pUnpack->aMem[iIdx];
 | 
| +    if( iIdx==p->pTab->iPKey ){
 | 
| +      sqlite3VdbeMemSetInt64(pMem, p->iKey2);
 | 
| +    }else if( iIdx>=pUnpack->nField ){
 | 
| +      pMem = (sqlite3_value *)columnNullValue();
 | 
| +    }
 | 
| +  }else{
 | 
| +    /* For an UPDATE, memory cell (p->iNewReg+1+iIdx) contains the required
 | 
| +    ** value. Make a copy of the cell contents and return a pointer to it.
 | 
| +    ** It is not safe to return a pointer to the memory cell itself as the
 | 
| +    ** caller may modify the value text encoding.
 | 
| +    */
 | 
| +    assert( p->op==SQLITE_UPDATE );
 | 
| +    if( !p->aNew ){
 | 
| +      p->aNew = (Mem *)sqlite3DbMallocZero(db, sizeof(Mem) * p->pCsr->nField);
 | 
| +      if( !p->aNew ){
 | 
| +        rc = SQLITE_NOMEM;
 | 
| +        goto preupdate_new_out;
 | 
| +      }
 | 
| +    }
 | 
| +    assert( iIdx>=0 && iIdx<p->pCsr->nField );
 | 
| +    pMem = &p->aNew[iIdx];
 | 
| +    if( pMem->flags==0 ){
 | 
| +      if( iIdx==p->pTab->iPKey ){
 | 
| +        sqlite3VdbeMemSetInt64(pMem, p->iKey2);
 | 
| +      }else{
 | 
| +        rc = sqlite3VdbeMemCopy(pMem, &p->v->aMem[p->iNewReg+1+iIdx]);
 | 
| +        if( rc!=SQLITE_OK ) goto preupdate_new_out;
 | 
| +      }
 | 
| +    }
 | 
| +  }
 | 
| +  *ppValue = pMem;
 | 
| +
 | 
| + preupdate_new_out:
 | 
| +  sqlite3Error(db, rc);
 | 
| +  return sqlite3ApiExit(db, rc);
 | 
| +}
 | 
| +#endif /* SQLITE_ENABLE_PREUPDATE_HOOK */
 | 
| +
 | 
|  #ifdef SQLITE_ENABLE_STMT_SCANSTATUS
 | 
|  /*
 | 
|  ** Return status data for a single loop within query pStmt.
 | 
| 
 |