extensions/sqlite/sqlite-source/update.c
changeset 3594 0a382baff180
parent 3593 f04de1a697bd
child 3595 09c38814fe7b
     1.1 --- a/extensions/sqlite/sqlite-source/update.c	Fri Aug 03 07:56:31 2012 -0400
     1.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.3 @@ -1,630 +0,0 @@
     1.4 -/*
     1.5 -** 2001 September 15
     1.6 -**
     1.7 -** The author disclaims copyright to this source code.  In place of
     1.8 -** a legal notice, here is a blessing:
     1.9 -**
    1.10 -**    May you do good and not evil.
    1.11 -**    May you find forgiveness for yourself and forgive others.
    1.12 -**    May you share freely, never taking more than you give.
    1.13 -**
    1.14 -*************************************************************************
    1.15 -** This file contains C code routines that are called by the parser
    1.16 -** to handle UPDATE statements.
    1.17 -**
    1.18 -** $Id$
    1.19 -*/
    1.20 -#include "sqliteInt.h"
    1.21 -
    1.22 -#ifndef SQLITE_OMIT_VIRTUALTABLE
    1.23 -/* Forward declaration */
    1.24 -static void updateVirtualTable(
    1.25 -  Parse *pParse,       /* The parsing context */
    1.26 -  SrcList *pSrc,       /* The virtual table to be modified */
    1.27 -  Table *pTab,         /* The virtual table */
    1.28 -  ExprList *pChanges,  /* The columns to change in the UPDATE statement */
    1.29 -  Expr *pRowidExpr,    /* Expression used to recompute the rowid */
    1.30 -  int *aXRef,          /* Mapping from columns of pTab to entries in pChanges */
    1.31 -  Expr *pWhere         /* WHERE clause of the UPDATE statement */
    1.32 -);
    1.33 -#endif /* SQLITE_OMIT_VIRTUALTABLE */
    1.34 -
    1.35 -/*
    1.36 -** The most recently coded instruction was an OP_Column to retrieve the
    1.37 -** i-th column of table pTab. This routine sets the P3 parameter of the 
    1.38 -** OP_Column to the default value, if any.
    1.39 -**
    1.40 -** The default value of a column is specified by a DEFAULT clause in the 
    1.41 -** column definition. This was either supplied by the user when the table
    1.42 -** was created, or added later to the table definition by an ALTER TABLE
    1.43 -** command. If the latter, then the row-records in the table btree on disk
    1.44 -** may not contain a value for the column and the default value, taken
    1.45 -** from the P3 parameter of the OP_Column instruction, is returned instead.
    1.46 -** If the former, then all row-records are guaranteed to include a value
    1.47 -** for the column and the P3 value is not required.
    1.48 -**
    1.49 -** Column definitions created by an ALTER TABLE command may only have 
    1.50 -** literal default values specified: a number, null or a string. (If a more
    1.51 -** complicated default expression value was provided, it is evaluated 
    1.52 -** when the ALTER TABLE is executed and one of the literal values written
    1.53 -** into the sqlite_master table.)
    1.54 -**
    1.55 -** Therefore, the P3 parameter is only required if the default value for
    1.56 -** the column is a literal number, string or null. The sqlite3ValueFromExpr()
    1.57 -** function is capable of transforming these types of expressions into
    1.58 -** sqlite3_value objects.
    1.59 -*/
    1.60 -void sqlite3ColumnDefault(Vdbe *v, Table *pTab, int i){
    1.61 -  if( pTab && !pTab->pSelect ){
    1.62 -    sqlite3_value *pValue;
    1.63 -    u8 enc = ENC(sqlite3VdbeDb(v));
    1.64 -    Column *pCol = &pTab->aCol[i];
    1.65 -    assert( i<pTab->nCol );
    1.66 -    sqlite3ValueFromExpr(sqlite3VdbeDb(v), pCol->pDflt, enc, pCol->affinity, &pValue);
    1.67 -    if( pValue ){
    1.68 -      sqlite3VdbeChangeP3(v, -1, (const char *)pValue, P3_MEM);
    1.69 -    }else{
    1.70 -      VdbeComment((v, "# %s.%s", pTab->zName, pCol->zName));
    1.71 -    }
    1.72 -  }
    1.73 -}
    1.74 -
    1.75 -/*
    1.76 -** Process an UPDATE statement.
    1.77 -**
    1.78 -**   UPDATE OR IGNORE table_wxyz SET a=b, c=d WHERE e<5 AND f NOT NULL;
    1.79 -**          \_______/ \________/     \______/       \________________/
    1.80 -*            onError   pTabList      pChanges             pWhere
    1.81 -*/
    1.82 -void sqlite3Update(
    1.83 -  Parse *pParse,         /* The parser context */
    1.84 -  SrcList *pTabList,     /* The table in which we should change things */
    1.85 -  ExprList *pChanges,    /* Things to be changed */
    1.86 -  Expr *pWhere,          /* The WHERE clause.  May be null */
    1.87 -  int onError            /* How to handle constraint errors */
    1.88 -){
    1.89 -  int i, j;              /* Loop counters */
    1.90 -  Table *pTab;           /* The table to be updated */
    1.91 -  int addr = 0;          /* VDBE instruction address of the start of the loop */
    1.92 -  WhereInfo *pWInfo;     /* Information about the WHERE clause */
    1.93 -  Vdbe *v;               /* The virtual database engine */
    1.94 -  Index *pIdx;           /* For looping over indices */
    1.95 -  int nIdx;              /* Number of indices that need updating */
    1.96 -  int nIdxTotal;         /* Total number of indices */
    1.97 -  int iCur;              /* VDBE Cursor number of pTab */
    1.98 -  sqlite3 *db;           /* The database structure */
    1.99 -  Index **apIdx = 0;     /* An array of indices that need updating too */
   1.100 -  char *aIdxUsed = 0;    /* aIdxUsed[i]==1 if the i-th index is used */
   1.101 -  int *aXRef = 0;        /* aXRef[i] is the index in pChanges->a[] of the
   1.102 -                         ** an expression for the i-th column of the table.
   1.103 -                         ** aXRef[i]==-1 if the i-th column is not changed. */
   1.104 -  int chngRowid;         /* True if the record number is being changed */
   1.105 -  Expr *pRowidExpr = 0;  /* Expression defining the new record number */
   1.106 -  int openAll = 0;       /* True if all indices need to be opened */
   1.107 -  AuthContext sContext;  /* The authorization context */
   1.108 -  NameContext sNC;       /* The name-context to resolve expressions in */
   1.109 -  int iDb;               /* Database containing the table being updated */
   1.110 -  int memCnt = 0;        /* Memory cell used for counting rows changed */
   1.111 -
   1.112 -#ifndef SQLITE_OMIT_TRIGGER
   1.113 -  int isView;                  /* Trying to update a view */
   1.114 -  int triggers_exist = 0;      /* True if any row triggers exist */
   1.115 -#endif
   1.116 -
   1.117 -  int newIdx      = -1;  /* index of trigger "new" temp table       */
   1.118 -  int oldIdx      = -1;  /* index of trigger "old" temp table       */
   1.119 -
   1.120 -  sContext.pParse = 0;
   1.121 -  db = pParse->db;
   1.122 -  if( pParse->nErr || db->mallocFailed ){
   1.123 -    goto update_cleanup;
   1.124 -  }
   1.125 -  assert( pTabList->nSrc==1 );
   1.126 -
   1.127 -  /* Locate the table which we want to update. 
   1.128 -  */
   1.129 -  pTab = sqlite3SrcListLookup(pParse, pTabList);
   1.130 -  if( pTab==0 ) goto update_cleanup;
   1.131 -  iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema);
   1.132 -
   1.133 -  /* Figure out if we have any triggers and if the table being
   1.134 -  ** updated is a view
   1.135 -  */
   1.136 -#ifndef SQLITE_OMIT_TRIGGER
   1.137 -  triggers_exist = sqlite3TriggersExist(pParse, pTab, TK_UPDATE, pChanges);
   1.138 -  isView = pTab->pSelect!=0;
   1.139 -#else
   1.140 -# define triggers_exist 0
   1.141 -# define isView 0
   1.142 -#endif
   1.143 -#ifdef SQLITE_OMIT_VIEW
   1.144 -# undef isView
   1.145 -# define isView 0
   1.146 -#endif
   1.147 -
   1.148 -  if( sqlite3IsReadOnly(pParse, pTab, triggers_exist) ){
   1.149 -    goto update_cleanup;
   1.150 -  }
   1.151 -  if( sqlite3ViewGetColumnNames(pParse, pTab) ){
   1.152 -    goto update_cleanup;
   1.153 -  }
   1.154 -  aXRef = sqlite3DbMallocRaw(db, sizeof(int) * pTab->nCol );
   1.155 -  if( aXRef==0 ) goto update_cleanup;
   1.156 -  for(i=0; i<pTab->nCol; i++) aXRef[i] = -1;
   1.157 -
   1.158 -  /* If there are FOR EACH ROW triggers, allocate cursors for the
   1.159 -  ** special OLD and NEW tables
   1.160 -  */
   1.161 -  if( triggers_exist ){
   1.162 -    newIdx = pParse->nTab++;
   1.163 -    oldIdx = pParse->nTab++;
   1.164 -  }
   1.165 -
   1.166 -  /* Allocate a cursors for the main database table and for all indices.
   1.167 -  ** The index cursors might not be used, but if they are used they
   1.168 -  ** need to occur right after the database cursor.  So go ahead and
   1.169 -  ** allocate enough space, just in case.
   1.170 -  */
   1.171 -  pTabList->a[0].iCursor = iCur = pParse->nTab++;
   1.172 -  for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
   1.173 -    pParse->nTab++;
   1.174 -  }
   1.175 -
   1.176 -  /* Initialize the name-context */
   1.177 -  memset(&sNC, 0, sizeof(sNC));
   1.178 -  sNC.pParse = pParse;
   1.179 -  sNC.pSrcList = pTabList;
   1.180 -
   1.181 -  /* Resolve the column names in all the expressions of the
   1.182 -  ** of the UPDATE statement.  Also find the column index
   1.183 -  ** for each column to be updated in the pChanges array.  For each
   1.184 -  ** column to be updated, make sure we have authorization to change
   1.185 -  ** that column.
   1.186 -  */
   1.187 -  chngRowid = 0;
   1.188 -  for(i=0; i<pChanges->nExpr; i++){
   1.189 -    if( sqlite3ExprResolveNames(&sNC, pChanges->a[i].pExpr) ){
   1.190 -      goto update_cleanup;
   1.191 -    }
   1.192 -    for(j=0; j<pTab->nCol; j++){
   1.193 -      if( sqlite3StrICmp(pTab->aCol[j].zName, pChanges->a[i].zName)==0 ){
   1.194 -        if( j==pTab->iPKey ){
   1.195 -          chngRowid = 1;
   1.196 -          pRowidExpr = pChanges->a[i].pExpr;
   1.197 -        }
   1.198 -        aXRef[j] = i;
   1.199 -        break;
   1.200 -      }
   1.201 -    }
   1.202 -    if( j>=pTab->nCol ){
   1.203 -      if( sqlite3IsRowid(pChanges->a[i].zName) ){
   1.204 -        chngRowid = 1;
   1.205 -        pRowidExpr = pChanges->a[i].pExpr;
   1.206 -      }else{
   1.207 -        sqlite3ErrorMsg(pParse, "no such column: %s", pChanges->a[i].zName);
   1.208 -        goto update_cleanup;
   1.209 -      }
   1.210 -    }
   1.211 -#ifndef SQLITE_OMIT_AUTHORIZATION
   1.212 -    {
   1.213 -      int rc;
   1.214 -      rc = sqlite3AuthCheck(pParse, SQLITE_UPDATE, pTab->zName,
   1.215 -                           pTab->aCol[j].zName, db->aDb[iDb].zName);
   1.216 -      if( rc==SQLITE_DENY ){
   1.217 -        goto update_cleanup;
   1.218 -      }else if( rc==SQLITE_IGNORE ){
   1.219 -        aXRef[j] = -1;
   1.220 -      }
   1.221 -    }
   1.222 -#endif
   1.223 -  }
   1.224 -
   1.225 -  /* Allocate memory for the array apIdx[] and fill it with pointers to every
   1.226 -  ** index that needs to be updated.  Indices only need updating if their
   1.227 -  ** key includes one of the columns named in pChanges or if the record
   1.228 -  ** number of the original table entry is changing.
   1.229 -  */
   1.230 -  for(nIdx=nIdxTotal=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, nIdxTotal++){
   1.231 -    if( chngRowid ){
   1.232 -      i = 0;
   1.233 -    }else {
   1.234 -      for(i=0; i<pIdx->nColumn; i++){
   1.235 -        if( aXRef[pIdx->aiColumn[i]]>=0 ) break;
   1.236 -      }
   1.237 -    }
   1.238 -    if( i<pIdx->nColumn ) nIdx++;
   1.239 -  }
   1.240 -  if( nIdxTotal>0 ){
   1.241 -    apIdx = sqlite3DbMallocRaw(db, sizeof(Index*) * nIdx + nIdxTotal );
   1.242 -    if( apIdx==0 ) goto update_cleanup;
   1.243 -    aIdxUsed = (char*)&apIdx[nIdx];
   1.244 -  }
   1.245 -  for(nIdx=j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){
   1.246 -    if( chngRowid ){
   1.247 -      i = 0;
   1.248 -    }else{
   1.249 -      for(i=0; i<pIdx->nColumn; i++){
   1.250 -        if( aXRef[pIdx->aiColumn[i]]>=0 ) break;
   1.251 -      }
   1.252 -    }
   1.253 -    if( i<pIdx->nColumn ){
   1.254 -      apIdx[nIdx++] = pIdx;
   1.255 -      aIdxUsed[j] = 1;
   1.256 -    }else{
   1.257 -      aIdxUsed[j] = 0;
   1.258 -    }
   1.259 -  }
   1.260 -
   1.261 -  /* Begin generating code.
   1.262 -  */
   1.263 -  v = sqlite3GetVdbe(pParse);
   1.264 -  if( v==0 ) goto update_cleanup;
   1.265 -  if( pParse->nested==0 ) sqlite3VdbeCountChanges(v);
   1.266 -  sqlite3BeginWriteOperation(pParse, 1, iDb);
   1.267 -
   1.268 -#ifndef SQLITE_OMIT_VIRTUALTABLE
   1.269 -  /* Virtual tables must be handled separately */
   1.270 -  if( IsVirtual(pTab) ){
   1.271 -    updateVirtualTable(pParse, pTabList, pTab, pChanges, pRowidExpr, aXRef,
   1.272 -                       pWhere);
   1.273 -    pWhere = 0;
   1.274 -    pTabList = 0;
   1.275 -    goto update_cleanup;
   1.276 -  }
   1.277 -#endif
   1.278 -
   1.279 -  /* Resolve the column names in all the expressions in the
   1.280 -  ** WHERE clause.
   1.281 -  */
   1.282 -  if( sqlite3ExprResolveNames(&sNC, pWhere) ){
   1.283 -    goto update_cleanup;
   1.284 -  }
   1.285 -
   1.286 -  /* Start the view context
   1.287 -  */
   1.288 -  if( isView ){
   1.289 -    sqlite3AuthContextPush(pParse, &sContext, pTab->zName);
   1.290 -  }
   1.291 -
   1.292 -  /* If we are trying to update a view, realize that view into
   1.293 -  ** a ephemeral table.
   1.294 -  */
   1.295 -  if( isView ){
   1.296 -    Select *pView;
   1.297 -    pView = sqlite3SelectDup(db, pTab->pSelect);
   1.298 -    sqlite3Select(pParse, pView, SRT_EphemTab, iCur, 0, 0, 0, 0);
   1.299 -    sqlite3SelectDelete(pView);
   1.300 -  }
   1.301 -
   1.302 -  /* Begin the database scan
   1.303 -  */
   1.304 -  pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, 0);
   1.305 -  if( pWInfo==0 ) goto update_cleanup;
   1.306 -
   1.307 -  /* Remember the rowid of every item to be updated.
   1.308 -  */
   1.309 -  sqlite3VdbeAddOp(v, IsVirtual(pTab) ? OP_VRowid : OP_Rowid, iCur, 0);
   1.310 -  sqlite3VdbeAddOp(v, OP_FifoWrite, 0, 0);
   1.311 -
   1.312 -  /* End the database scan loop.
   1.313 -  */
   1.314 -  sqlite3WhereEnd(pWInfo);
   1.315 -
   1.316 -  /* Initialize the count of updated rows
   1.317 -  */
   1.318 -  if( db->flags & SQLITE_CountRows && !pParse->trigStack ){
   1.319 -    memCnt = pParse->nMem++;
   1.320 -    sqlite3VdbeAddOp(v, OP_MemInt, 0, memCnt);
   1.321 -  }
   1.322 -
   1.323 -  if( triggers_exist ){
   1.324 -    /* Create pseudo-tables for NEW and OLD
   1.325 -    */
   1.326 -    sqlite3VdbeAddOp(v, OP_OpenPseudo, oldIdx, 0);
   1.327 -    sqlite3VdbeAddOp(v, OP_SetNumColumns, oldIdx, pTab->nCol);
   1.328 -    sqlite3VdbeAddOp(v, OP_OpenPseudo, newIdx, 0);
   1.329 -    sqlite3VdbeAddOp(v, OP_SetNumColumns, newIdx, pTab->nCol);
   1.330 -
   1.331 -    /* The top of the update loop for when there are triggers.
   1.332 -    */
   1.333 -    addr = sqlite3VdbeAddOp(v, OP_FifoRead, 0, 0);
   1.334 -
   1.335 -    if( !isView ){
   1.336 -      sqlite3VdbeAddOp(v, OP_Dup, 0, 0);
   1.337 -      sqlite3VdbeAddOp(v, OP_Dup, 0, 0);
   1.338 -      /* Open a cursor and make it point to the record that is
   1.339 -      ** being updated.
   1.340 -      */
   1.341 -      sqlite3OpenTable(pParse, iCur, iDb, pTab, OP_OpenRead);
   1.342 -    }
   1.343 -    sqlite3VdbeAddOp(v, OP_MoveGe, iCur, 0);
   1.344 -
   1.345 -    /* Generate the OLD table
   1.346 -    */
   1.347 -    sqlite3VdbeAddOp(v, OP_Rowid, iCur, 0);
   1.348 -    sqlite3VdbeAddOp(v, OP_RowData, iCur, 0);
   1.349 -    sqlite3VdbeAddOp(v, OP_Insert, oldIdx, 0);
   1.350 -
   1.351 -    /* Generate the NEW table
   1.352 -    */
   1.353 -    if( chngRowid ){
   1.354 -      sqlite3ExprCodeAndCache(pParse, pRowidExpr);
   1.355 -    }else{
   1.356 -      sqlite3VdbeAddOp(v, OP_Rowid, iCur, 0);
   1.357 -    }
   1.358 -    for(i=0; i<pTab->nCol; i++){
   1.359 -      if( i==pTab->iPKey ){
   1.360 -        sqlite3VdbeAddOp(v, OP_Null, 0, 0);
   1.361 -        continue;
   1.362 -      }
   1.363 -      j = aXRef[i];
   1.364 -      if( j<0 ){
   1.365 -        sqlite3VdbeAddOp(v, OP_Column, iCur, i);
   1.366 -        sqlite3ColumnDefault(v, pTab, i);
   1.367 -      }else{
   1.368 -        sqlite3ExprCodeAndCache(pParse, pChanges->a[j].pExpr);
   1.369 -      }
   1.370 -    }
   1.371 -    sqlite3VdbeAddOp(v, OP_MakeRecord, pTab->nCol, 0);
   1.372 -    if( !isView ){
   1.373 -      sqlite3TableAffinityStr(v, pTab);
   1.374 -    }
   1.375 -    if( pParse->nErr ) goto update_cleanup;
   1.376 -    sqlite3VdbeAddOp(v, OP_Insert, newIdx, 0);
   1.377 -    if( !isView ){
   1.378 -      sqlite3VdbeAddOp(v, OP_Close, iCur, 0);
   1.379 -    }
   1.380 -
   1.381 -    /* Fire the BEFORE and INSTEAD OF triggers
   1.382 -    */
   1.383 -    if( sqlite3CodeRowTrigger(pParse, TK_UPDATE, pChanges, TRIGGER_BEFORE, pTab,
   1.384 -          newIdx, oldIdx, onError, addr) ){
   1.385 -      goto update_cleanup;
   1.386 -    }
   1.387 -  }
   1.388 -
   1.389 -  if( !isView && !IsVirtual(pTab) ){
   1.390 -    /* 
   1.391 -    ** Open every index that needs updating.  Note that if any
   1.392 -    ** index could potentially invoke a REPLACE conflict resolution 
   1.393 -    ** action, then we need to open all indices because we might need
   1.394 -    ** to be deleting some records.
   1.395 -    */
   1.396 -    sqlite3OpenTable(pParse, iCur, iDb, pTab, OP_OpenWrite); 
   1.397 -    if( onError==OE_Replace ){
   1.398 -      openAll = 1;
   1.399 -    }else{
   1.400 -      openAll = 0;
   1.401 -      for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
   1.402 -        if( pIdx->onError==OE_Replace ){
   1.403 -          openAll = 1;
   1.404 -          break;
   1.405 -        }
   1.406 -      }
   1.407 -    }
   1.408 -    for(i=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, i++){
   1.409 -      if( openAll || aIdxUsed[i] ){
   1.410 -        KeyInfo *pKey = sqlite3IndexKeyinfo(pParse, pIdx);
   1.411 -        sqlite3VdbeAddOp(v, OP_Integer, iDb, 0);
   1.412 -        sqlite3VdbeOp3(v, OP_OpenWrite, iCur+i+1, pIdx->tnum,
   1.413 -                       (char*)pKey, P3_KEYINFO_HANDOFF);
   1.414 -        assert( pParse->nTab>iCur+i+1 );
   1.415 -      }
   1.416 -    }
   1.417 -
   1.418 -    /* Loop over every record that needs updating.  We have to load
   1.419 -    ** the old data for each record to be updated because some columns
   1.420 -    ** might not change and we will need to copy the old value.
   1.421 -    ** Also, the old data is needed to delete the old index entries.
   1.422 -    ** So make the cursor point at the old record.
   1.423 -    */
   1.424 -    if( !triggers_exist ){
   1.425 -      addr = sqlite3VdbeAddOp(v, OP_FifoRead, 0, 0);
   1.426 -      sqlite3VdbeAddOp(v, OP_Dup, 0, 0);
   1.427 -    }
   1.428 -    sqlite3VdbeAddOp(v, OP_NotExists, iCur, addr);
   1.429 -
   1.430 -    /* If the record number will change, push the record number as it
   1.431 -    ** will be after the update. (The old record number is currently
   1.432 -    ** on top of the stack.)
   1.433 -    */
   1.434 -    if( chngRowid ){
   1.435 -      sqlite3ExprCode(pParse, pRowidExpr);
   1.436 -      sqlite3VdbeAddOp(v, OP_MustBeInt, 0, 0);
   1.437 -    }
   1.438 -
   1.439 -    /* Compute new data for this record.  
   1.440 -    */
   1.441 -    for(i=0; i<pTab->nCol; i++){
   1.442 -      if( i==pTab->iPKey ){
   1.443 -        sqlite3VdbeAddOp(v, OP_Null, 0, 0);
   1.444 -        continue;
   1.445 -      }
   1.446 -      j = aXRef[i];
   1.447 -      if( j<0 ){
   1.448 -        sqlite3VdbeAddOp(v, OP_Column, iCur, i);
   1.449 -        sqlite3ColumnDefault(v, pTab, i);
   1.450 -      }else{
   1.451 -        sqlite3ExprCode(pParse, pChanges->a[j].pExpr);
   1.452 -      }
   1.453 -    }
   1.454 -
   1.455 -    /* Do constraint checks
   1.456 -    */
   1.457 -    sqlite3GenerateConstraintChecks(pParse, pTab, iCur, aIdxUsed, chngRowid, 1,
   1.458 -                                   onError, addr);
   1.459 -
   1.460 -    /* Delete the old indices for the current record.
   1.461 -    */
   1.462 -    sqlite3GenerateRowIndexDelete(v, pTab, iCur, aIdxUsed);
   1.463 -
   1.464 -    /* If changing the record number, delete the old record.
   1.465 -    */
   1.466 -    if( chngRowid ){
   1.467 -      sqlite3VdbeAddOp(v, OP_Delete, iCur, 0);
   1.468 -    }
   1.469 -
   1.470 -    /* Create the new index entries and the new record.
   1.471 -    */
   1.472 -    sqlite3CompleteInsertion(pParse, pTab, iCur, aIdxUsed, chngRowid, 1, -1, 0);
   1.473 -  }
   1.474 -
   1.475 -  /* Increment the row counter 
   1.476 -  */
   1.477 -  if( db->flags & SQLITE_CountRows && !pParse->trigStack){
   1.478 -    sqlite3VdbeAddOp(v, OP_MemIncr, 1, memCnt);
   1.479 -  }
   1.480 -
   1.481 -  /* If there are triggers, close all the cursors after each iteration
   1.482 -  ** through the loop.  The fire the after triggers.
   1.483 -  */
   1.484 -  if( triggers_exist ){
   1.485 -    if( !isView ){
   1.486 -      for(i=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, i++){
   1.487 -        if( openAll || aIdxUsed[i] )
   1.488 -          sqlite3VdbeAddOp(v, OP_Close, iCur+i+1, 0);
   1.489 -      }
   1.490 -      sqlite3VdbeAddOp(v, OP_Close, iCur, 0);
   1.491 -    }
   1.492 -    if( sqlite3CodeRowTrigger(pParse, TK_UPDATE, pChanges, TRIGGER_AFTER, pTab, 
   1.493 -          newIdx, oldIdx, onError, addr) ){
   1.494 -      goto update_cleanup;
   1.495 -    }
   1.496 -  }
   1.497 -
   1.498 -  /* Repeat the above with the next record to be updated, until
   1.499 -  ** all record selected by the WHERE clause have been updated.
   1.500 -  */
   1.501 -  sqlite3VdbeAddOp(v, OP_Goto, 0, addr);
   1.502 -  sqlite3VdbeJumpHere(v, addr);
   1.503 -
   1.504 -  /* Close all tables if there were no FOR EACH ROW triggers */
   1.505 -  if( !triggers_exist ){
   1.506 -    for(i=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, i++){
   1.507 -      if( openAll || aIdxUsed[i] ){
   1.508 -        sqlite3VdbeAddOp(v, OP_Close, iCur+i+1, 0);
   1.509 -      }
   1.510 -    }
   1.511 -    sqlite3VdbeAddOp(v, OP_Close, iCur, 0);
   1.512 -  }else{
   1.513 -    sqlite3VdbeAddOp(v, OP_Close, newIdx, 0);
   1.514 -    sqlite3VdbeAddOp(v, OP_Close, oldIdx, 0);
   1.515 -  }
   1.516 -
   1.517 -  /*
   1.518 -  ** Return the number of rows that were changed. If this routine is 
   1.519 -  ** generating code because of a call to sqlite3NestedParse(), do not
   1.520 -  ** invoke the callback function.
   1.521 -  */
   1.522 -  if( db->flags & SQLITE_CountRows && !pParse->trigStack && pParse->nested==0 ){
   1.523 -    sqlite3VdbeAddOp(v, OP_MemLoad, memCnt, 0);
   1.524 -    sqlite3VdbeAddOp(v, OP_Callback, 1, 0);
   1.525 -    sqlite3VdbeSetNumCols(v, 1);
   1.526 -    sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "rows updated", P3_STATIC);
   1.527 -  }
   1.528 -
   1.529 -update_cleanup:
   1.530 -  sqlite3AuthContextPop(&sContext);
   1.531 -  sqlite3_free(apIdx);
   1.532 -  sqlite3_free(aXRef);
   1.533 -  sqlite3SrcListDelete(pTabList);
   1.534 -  sqlite3ExprListDelete(pChanges);
   1.535 -  sqlite3ExprDelete(pWhere);
   1.536 -  return;
   1.537 -}
   1.538 -
   1.539 -#ifndef SQLITE_OMIT_VIRTUALTABLE
   1.540 -/*
   1.541 -** Generate code for an UPDATE of a virtual table.
   1.542 -**
   1.543 -** The strategy is that we create an ephemerial table that contains
   1.544 -** for each row to be changed:
   1.545 -**
   1.546 -**   (A)  The original rowid of that row.
   1.547 -**   (B)  The revised rowid for the row. (note1)
   1.548 -**   (C)  The content of every column in the row.
   1.549 -**
   1.550 -** Then we loop over this ephemeral table and for each row in
   1.551 -** the ephermeral table call VUpdate.
   1.552 -**
   1.553 -** When finished, drop the ephemeral table.
   1.554 -**
   1.555 -** (note1) Actually, if we know in advance that (A) is always the same
   1.556 -** as (B) we only store (A), then duplicate (A) when pulling
   1.557 -** it out of the ephemeral table before calling VUpdate.
   1.558 -*/
   1.559 -static void updateVirtualTable(
   1.560 -  Parse *pParse,       /* The parsing context */
   1.561 -  SrcList *pSrc,       /* The virtual table to be modified */
   1.562 -  Table *pTab,         /* The virtual table */
   1.563 -  ExprList *pChanges,  /* The columns to change in the UPDATE statement */
   1.564 -  Expr *pRowid,        /* Expression used to recompute the rowid */
   1.565 -  int *aXRef,          /* Mapping from columns of pTab to entries in pChanges */
   1.566 -  Expr *pWhere         /* WHERE clause of the UPDATE statement */
   1.567 -){
   1.568 -  Vdbe *v = pParse->pVdbe;  /* Virtual machine under construction */
   1.569 -  ExprList *pEList = 0;     /* The result set of the SELECT statement */
   1.570 -  Select *pSelect = 0;      /* The SELECT statement */
   1.571 -  Expr *pExpr;              /* Temporary expression */
   1.572 -  int ephemTab;             /* Table holding the result of the SELECT */
   1.573 -  int i;                    /* Loop counter */
   1.574 -  int addr;                 /* Address of top of loop */
   1.575 -  sqlite3 *db = pParse->db; /* Database connection */
   1.576 -
   1.577 -  /* Construct the SELECT statement that will find the new values for
   1.578 -  ** all updated rows. 
   1.579 -  */
   1.580 -  pEList = sqlite3ExprListAppend(pParse, 0, 
   1.581 -                                 sqlite3CreateIdExpr(pParse, "_rowid_"), 0);
   1.582 -  if( pRowid ){
   1.583 -    pEList = sqlite3ExprListAppend(pParse, pEList,
   1.584 -                                   sqlite3ExprDup(db, pRowid), 0);
   1.585 -  }
   1.586 -  assert( pTab->iPKey<0 );
   1.587 -  for(i=0; i<pTab->nCol; i++){
   1.588 -    if( aXRef[i]>=0 ){
   1.589 -      pExpr = sqlite3ExprDup(db, pChanges->a[aXRef[i]].pExpr);
   1.590 -    }else{
   1.591 -      pExpr = sqlite3CreateIdExpr(pParse, pTab->aCol[i].zName);
   1.592 -    }
   1.593 -    pEList = sqlite3ExprListAppend(pParse, pEList, pExpr, 0);
   1.594 -  }
   1.595 -  pSelect = sqlite3SelectNew(pParse, pEList, pSrc, pWhere, 0, 0, 0, 0, 0, 0);
   1.596 -  
   1.597 -  /* Create the ephemeral table into which the update results will
   1.598 -  ** be stored.
   1.599 -  */
   1.600 -  assert( v );
   1.601 -  ephemTab = pParse->nTab++;
   1.602 -  sqlite3VdbeAddOp(v, OP_OpenEphemeral, ephemTab, pTab->nCol+1+(pRowid!=0));
   1.603 -
   1.604 -  /* fill the ephemeral table 
   1.605 -  */
   1.606 -  sqlite3Select(pParse, pSelect, SRT_Table, ephemTab, 0, 0, 0, 0);
   1.607 -
   1.608 -  /*
   1.609 -  ** Generate code to scan the ephemeral table and call VDelete and
   1.610 -  ** VInsert
   1.611 -  */
   1.612 -  sqlite3VdbeAddOp(v, OP_Rewind, ephemTab, 0);
   1.613 -  addr = sqlite3VdbeCurrentAddr(v);
   1.614 -  sqlite3VdbeAddOp(v, OP_Column,  ephemTab, 0);
   1.615 -  if( pRowid ){
   1.616 -    sqlite3VdbeAddOp(v, OP_Column, ephemTab, 1);
   1.617 -  }else{
   1.618 -    sqlite3VdbeAddOp(v, OP_Dup, 0, 0);
   1.619 -  }
   1.620 -  for(i=0; i<pTab->nCol; i++){
   1.621 -    sqlite3VdbeAddOp(v, OP_Column, ephemTab, i+1+(pRowid!=0));
   1.622 -  }
   1.623 -  pParse->pVirtualLock = pTab;
   1.624 -  sqlite3VdbeOp3(v, OP_VUpdate, 0, pTab->nCol+2, 
   1.625 -                     (const char*)pTab->pVtab, P3_VTAB);
   1.626 -  sqlite3VdbeAddOp(v, OP_Next, ephemTab, addr);
   1.627 -  sqlite3VdbeJumpHere(v, addr-1);
   1.628 -  sqlite3VdbeAddOp(v, OP_Close, ephemTab, 0);
   1.629 -
   1.630 -  /* Cleanup */
   1.631 -  sqlite3SelectDelete(pSelect);  
   1.632 -}
   1.633 -#endif /* SQLITE_OMIT_VIRTUALTABLE */