update.c

Go to the documentation of this file.
00001 /*
00002 ** 2001 September 15
00003 **
00004 ** The author disclaims copyright to this source code.  In place of
00005 ** a legal notice, here is a blessing:
00006 **
00007 **    May you do good and not evil.
00008 **    May you find forgiveness for yourself and forgive others.
00009 **    May you share freely, never taking more than you give.
00010 **
00011 *************************************************************************
00012 ** This file contains C code routines that are called by the parser
00013 ** to handle UPDATE statements.
00014 **
00015 ** $Id: update.c,v 1.186 2008/10/31 10:53:23 danielk1977 Exp $
00016 */
00017 #include "sqliteInt.h"
00018 
00019 #ifndef SQLITE_OMIT_VIRTUALTABLE
00020 /* Forward declaration */
00021 static void updateVirtualTable(
00022   Parse *pParse,       /* The parsing context */
00023   SrcList *pSrc,       /* The virtual table to be modified */
00024   Table *pTab,         /* The virtual table */
00025   ExprList *pChanges,  /* The columns to change in the UPDATE statement */
00026   Expr *pRowidExpr,    /* Expression used to recompute the rowid */
00027   int *aXRef,          /* Mapping from columns of pTab to entries in pChanges */
00028   Expr *pWhere         /* WHERE clause of the UPDATE statement */
00029 );
00030 #endif /* SQLITE_OMIT_VIRTUALTABLE */
00031 
00032 /*
00033 ** The most recently coded instruction was an OP_Column to retrieve the
00034 ** i-th column of table pTab. This routine sets the P4 parameter of the 
00035 ** OP_Column to the default value, if any.
00036 **
00037 ** The default value of a column is specified by a DEFAULT clause in the 
00038 ** column definition. This was either supplied by the user when the table
00039 ** was created, or added later to the table definition by an ALTER TABLE
00040 ** command. If the latter, then the row-records in the table btree on disk
00041 ** may not contain a value for the column and the default value, taken
00042 ** from the P4 parameter of the OP_Column instruction, is returned instead.
00043 ** If the former, then all row-records are guaranteed to include a value
00044 ** for the column and the P4 value is not required.
00045 **
00046 ** Column definitions created by an ALTER TABLE command may only have 
00047 ** literal default values specified: a number, null or a string. (If a more
00048 ** complicated default expression value was provided, it is evaluated 
00049 ** when the ALTER TABLE is executed and one of the literal values written
00050 ** into the sqlite_master table.)
00051 **
00052 ** Therefore, the P4 parameter is only required if the default value for
00053 ** the column is a literal number, string or null. The sqlite3ValueFromExpr()
00054 ** function is capable of transforming these types of expressions into
00055 ** sqlite3_value objects.
00056 */
00057 void sqlite3ColumnDefault(Vdbe *v, Table *pTab, int i){
00058   if( pTab && !pTab->pSelect ){
00059     sqlite3_value *pValue;
00060     u8 enc = ENC(sqlite3VdbeDb(v));
00061     Column *pCol = &pTab->aCol[i];
00062     VdbeComment((v, "%s.%s", pTab->zName, pCol->zName));
00063     assert( i<pTab->nCol );
00064     sqlite3ValueFromExpr(sqlite3VdbeDb(v), pCol->pDflt, enc, 
00065                          pCol->affinity, &pValue);
00066     if( pValue ){
00067       sqlite3VdbeChangeP4(v, -1, (const char *)pValue, P4_MEM);
00068     }
00069   }
00070 }
00071 
00072 /*
00073 ** Process an UPDATE statement.
00074 **
00075 **   UPDATE OR IGNORE table_wxyz SET a=b, c=d WHERE e<5 AND f NOT NULL;
00076 **          \_______/ \________/     \______/       \________________/
00077 *            onError   pTabList      pChanges             pWhere
00078 */
00079 void sqlite3Update(
00080   Parse *pParse,         /* The parser context */
00081   SrcList *pTabList,     /* The table in which we should change things */
00082   ExprList *pChanges,    /* Things to be changed */
00083   Expr *pWhere,          /* The WHERE clause.  May be null */
00084   int onError            /* How to handle constraint errors */
00085 ){
00086   int i, j;              /* Loop counters */
00087   Table *pTab;           /* The table to be updated */
00088   int addr = 0;          /* VDBE instruction address of the start of the loop */
00089   WhereInfo *pWInfo;     /* Information about the WHERE clause */
00090   Vdbe *v;               /* The virtual database engine */
00091   Index *pIdx;           /* For looping over indices */
00092   int nIdx;              /* Number of indices that need updating */
00093   int iCur;              /* VDBE Cursor number of pTab */
00094   sqlite3 *db;           /* The database structure */
00095   int *aRegIdx = 0;      /* One register assigned to each index to be updated */
00096   int *aXRef = 0;        /* aXRef[i] is the index in pChanges->a[] of the
00097                          ** an expression for the i-th column of the table.
00098                          ** aXRef[i]==-1 if the i-th column is not changed. */
00099   int chngRowid;         /* True if the record number is being changed */
00100   Expr *pRowidExpr = 0;  /* Expression defining the new record number */
00101   int openAll = 0;       /* True if all indices need to be opened */
00102   AuthContext sContext;  /* The authorization context */
00103   NameContext sNC;       /* The name-context to resolve expressions in */
00104   int iDb;               /* Database containing the table being updated */
00105   int j1;                /* Addresses of jump instructions */
00106   int okOnePass;         /* True for one-pass algorithm without the FIFO */
00107 
00108 #ifndef SQLITE_OMIT_TRIGGER
00109   int isView;                  /* Trying to update a view */
00110   int triggers_exist = 0;      /* True if any row triggers exist */
00111 #endif
00112   int iBeginAfterTrigger;      /* Address of after trigger program */
00113   int iEndAfterTrigger;        /* Exit of after trigger program */
00114   int iBeginBeforeTrigger;     /* Address of before trigger program */
00115   int iEndBeforeTrigger;       /* Exit of before trigger program */
00116   u32 old_col_mask = 0;        /* Mask of OLD.* columns in use */
00117   u32 new_col_mask = 0;        /* Mask of NEW.* columns in use */
00118 
00119   int newIdx      = -1;  /* index of trigger "new" temp table       */
00120   int oldIdx      = -1;  /* index of trigger "old" temp table       */
00121 
00122   /* Register Allocations */
00123   int regRowCount = 0;   /* A count of rows changed */
00124   int regOldRowid;       /* The old rowid */
00125   int regNewRowid;       /* The new rowid */
00126   int regData;           /* New data for the row */
00127 
00128   sContext.pParse = 0;
00129   db = pParse->db;
00130   if( pParse->nErr || db->mallocFailed ){
00131     goto update_cleanup;
00132   }
00133   assert( pTabList->nSrc==1 );
00134 
00135   /* Locate the table which we want to update. 
00136   */
00137   pTab = sqlite3SrcListLookup(pParse, pTabList);
00138   if( pTab==0 ) goto update_cleanup;
00139   iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema);
00140 
00141   /* Figure out if we have any triggers and if the table being
00142   ** updated is a view
00143   */
00144 #ifndef SQLITE_OMIT_TRIGGER
00145   triggers_exist = sqlite3TriggersExist(pParse, pTab, TK_UPDATE, pChanges);
00146   isView = pTab->pSelect!=0;
00147 #else
00148 # define triggers_exist 0
00149 # define isView 0
00150 #endif
00151 #ifdef SQLITE_OMIT_VIEW
00152 # undef isView
00153 # define isView 0
00154 #endif
00155 
00156   if( sqlite3IsReadOnly(pParse, pTab, triggers_exist) ){
00157     goto update_cleanup;
00158   }
00159   if( sqlite3ViewGetColumnNames(pParse, pTab) ){
00160     goto update_cleanup;
00161   }
00162   aXRef = sqlite3DbMallocRaw(db, sizeof(int) * pTab->nCol );
00163   if( aXRef==0 ) goto update_cleanup;
00164   for(i=0; i<pTab->nCol; i++) aXRef[i] = -1;
00165 
00166   /* If there are FOR EACH ROW triggers, allocate cursors for the
00167   ** special OLD and NEW tables
00168   */
00169   if( triggers_exist ){
00170     newIdx = pParse->nTab++;
00171     oldIdx = pParse->nTab++;
00172   }
00173 
00174   /* Allocate a cursors for the main database table and for all indices.
00175   ** The index cursors might not be used, but if they are used they
00176   ** need to occur right after the database cursor.  So go ahead and
00177   ** allocate enough space, just in case.
00178   */
00179   pTabList->a[0].iCursor = iCur = pParse->nTab++;
00180   for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
00181     pParse->nTab++;
00182   }
00183 
00184   /* Initialize the name-context */
00185   memset(&sNC, 0, sizeof(sNC));
00186   sNC.pParse = pParse;
00187   sNC.pSrcList = pTabList;
00188 
00189   /* Resolve the column names in all the expressions of the
00190   ** of the UPDATE statement.  Also find the column index
00191   ** for each column to be updated in the pChanges array.  For each
00192   ** column to be updated, make sure we have authorization to change
00193   ** that column.
00194   */
00195   chngRowid = 0;
00196   for(i=0; i<pChanges->nExpr; i++){
00197     if( sqlite3ResolveExprNames(&sNC, pChanges->a[i].pExpr) ){
00198       goto update_cleanup;
00199     }
00200     for(j=0; j<pTab->nCol; j++){
00201       if( sqlite3StrICmp(pTab->aCol[j].zName, pChanges->a[i].zName)==0 ){
00202         if( j==pTab->iPKey ){
00203           chngRowid = 1;
00204           pRowidExpr = pChanges->a[i].pExpr;
00205         }
00206         aXRef[j] = i;
00207         break;
00208       }
00209     }
00210     if( j>=pTab->nCol ){
00211       if( sqlite3IsRowid(pChanges->a[i].zName) ){
00212         chngRowid = 1;
00213         pRowidExpr = pChanges->a[i].pExpr;
00214       }else{
00215         sqlite3ErrorMsg(pParse, "no such column: %s", pChanges->a[i].zName);
00216         goto update_cleanup;
00217       }
00218     }
00219 #ifndef SQLITE_OMIT_AUTHORIZATION
00220     {
00221       int rc;
00222       rc = sqlite3AuthCheck(pParse, SQLITE_UPDATE, pTab->zName,
00223                            pTab->aCol[j].zName, db->aDb[iDb].zName);
00224       if( rc==SQLITE_DENY ){
00225         goto update_cleanup;
00226       }else if( rc==SQLITE_IGNORE ){
00227         aXRef[j] = -1;
00228       }
00229     }
00230 #endif
00231   }
00232 
00233   /* Allocate memory for the array aRegIdx[].  There is one entry in the
00234   ** array for each index associated with table being updated.  Fill in
00235   ** the value with a register number for indices that are to be used
00236   ** and with zero for unused indices.
00237   */
00238   for(nIdx=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, nIdx++){}
00239   if( nIdx>0 ){
00240     aRegIdx = sqlite3DbMallocRaw(db, sizeof(Index*) * nIdx );
00241     if( aRegIdx==0 ) goto update_cleanup;
00242   }
00243   for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){
00244     int reg;
00245     if( chngRowid ){
00246       reg = ++pParse->nMem;
00247     }else{
00248       reg = 0;
00249       for(i=0; i<pIdx->nColumn; i++){
00250         if( aXRef[pIdx->aiColumn[i]]>=0 ){
00251           reg = ++pParse->nMem;
00252           break;
00253         }
00254       }
00255     }
00256     aRegIdx[j] = reg;
00257   }
00258 
00259   /* Allocate a block of register used to store the change record
00260   ** sent to sqlite3GenerateConstraintChecks().  There are either
00261   ** one or two registers for holding the rowid.  One rowid register
00262   ** is used if chngRowid is false and two are used if chngRowid is
00263   ** true.  Following these are pTab->nCol register holding column
00264   ** data.
00265   */
00266   regOldRowid = regNewRowid = pParse->nMem + 1;
00267   pParse->nMem += pTab->nCol + 1;
00268   if( chngRowid ){
00269     regNewRowid++;
00270     pParse->nMem++;
00271   }
00272   regData = regNewRowid+1;
00273  
00274 
00275   /* Begin generating code.
00276   */
00277   v = sqlite3GetVdbe(pParse);
00278   if( v==0 ) goto update_cleanup;
00279   if( pParse->nested==0 ) sqlite3VdbeCountChanges(v);
00280   sqlite3BeginWriteOperation(pParse, 1, iDb);
00281 
00282 #ifndef SQLITE_OMIT_VIRTUALTABLE
00283   /* Virtual tables must be handled separately */
00284   if( IsVirtual(pTab) ){
00285     updateVirtualTable(pParse, pTabList, pTab, pChanges, pRowidExpr, aXRef,
00286                        pWhere);
00287     pWhere = 0;
00288     pTabList = 0;
00289     goto update_cleanup;
00290   }
00291 #endif
00292 
00293   /* Start the view context
00294   */
00295   if( isView ){
00296     sqlite3AuthContextPush(pParse, &sContext, pTab->zName);
00297   }
00298 
00299   /* Generate the code for triggers.
00300   */
00301   if( triggers_exist ){
00302     int iGoto;
00303 
00304     /* Create pseudo-tables for NEW and OLD
00305     */
00306     sqlite3VdbeAddOp2(v, OP_SetNumColumns, 0, pTab->nCol);
00307     sqlite3VdbeAddOp2(v, OP_OpenPseudo, oldIdx, 0);
00308     sqlite3VdbeAddOp2(v, OP_SetNumColumns, 0, pTab->nCol);
00309     sqlite3VdbeAddOp2(v, OP_OpenPseudo, newIdx, 0);
00310 
00311     iGoto = sqlite3VdbeAddOp2(v, OP_Goto, 0, 0);
00312     addr = sqlite3VdbeMakeLabel(v);
00313     iBeginBeforeTrigger = sqlite3VdbeCurrentAddr(v);
00314     if( sqlite3CodeRowTrigger(pParse, TK_UPDATE, pChanges, TRIGGER_BEFORE, pTab,
00315           newIdx, oldIdx, onError, addr, &old_col_mask, &new_col_mask) ){
00316       goto update_cleanup;
00317     }
00318     iEndBeforeTrigger = sqlite3VdbeAddOp2(v, OP_Goto, 0, 0);
00319     iBeginAfterTrigger = sqlite3VdbeCurrentAddr(v);
00320     if( sqlite3CodeRowTrigger(pParse, TK_UPDATE, pChanges, TRIGGER_AFTER, pTab, 
00321           newIdx, oldIdx, onError, addr, &old_col_mask, &new_col_mask) ){
00322       goto update_cleanup;
00323     }
00324     iEndAfterTrigger = sqlite3VdbeAddOp2(v, OP_Goto, 0, 0);
00325     sqlite3VdbeJumpHere(v, iGoto);
00326   }
00327 
00328   /* If we are trying to update a view, realize that view into
00329   ** a ephemeral table.
00330   */
00331 #if !defined(SQLITE_OMIT_VIEW) && !defined(SQLITE_OMIT_TRIGGER)
00332   if( isView ){
00333     sqlite3MaterializeView(pParse, pTab, pWhere, iCur);
00334   }
00335 #endif
00336 
00337   /* Resolve the column names in all the expressions in the
00338   ** WHERE clause.
00339   */
00340   if( sqlite3ResolveExprNames(&sNC, pWhere) ){
00341     goto update_cleanup;
00342   }
00343 
00344   /* Begin the database scan
00345   */
00346   sqlite3VdbeAddOp2(v, OP_Null, 0, regOldRowid);
00347   pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, 0,
00348                              WHERE_ONEPASS_DESIRED);
00349   if( pWInfo==0 ) goto update_cleanup;
00350   okOnePass = pWInfo->okOnePass;
00351 
00352   /* Remember the rowid of every item to be updated.
00353   */
00354   sqlite3VdbeAddOp2(v, IsVirtual(pTab)?OP_VRowid:OP_Rowid, iCur, regOldRowid);
00355   if( !okOnePass ) sqlite3VdbeAddOp2(v, OP_FifoWrite, regOldRowid, 0);
00356 
00357   /* End the database scan loop.
00358   */
00359   sqlite3WhereEnd(pWInfo);
00360 
00361   /* Initialize the count of updated rows
00362   */
00363   if( db->flags & SQLITE_CountRows && !pParse->trigStack ){
00364     regRowCount = ++pParse->nMem;
00365     sqlite3VdbeAddOp2(v, OP_Integer, 0, regRowCount);
00366   }
00367 
00368   if( !isView && !IsVirtual(pTab) ){
00369     /* 
00370     ** Open every index that needs updating.  Note that if any
00371     ** index could potentially invoke a REPLACE conflict resolution 
00372     ** action, then we need to open all indices because we might need
00373     ** to be deleting some records.
00374     */
00375     if( !okOnePass ) sqlite3OpenTable(pParse, iCur, iDb, pTab, OP_OpenWrite); 
00376     if( onError==OE_Replace ){
00377       openAll = 1;
00378     }else{
00379       openAll = 0;
00380       for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
00381         if( pIdx->onError==OE_Replace ){
00382           openAll = 1;
00383           break;
00384         }
00385       }
00386     }
00387     for(i=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, i++){
00388       if( openAll || aRegIdx[i]>0 ){
00389         KeyInfo *pKey = sqlite3IndexKeyinfo(pParse, pIdx);
00390         sqlite3VdbeAddOp4(v, OP_OpenWrite, iCur+i+1, pIdx->tnum, iDb,
00391                        (char*)pKey, P4_KEYINFO_HANDOFF);
00392         assert( pParse->nTab>iCur+i+1 );
00393       }
00394     }
00395   }
00396   
00397   /* Jump back to this point if a trigger encounters an IGNORE constraint. */
00398   if( triggers_exist ){
00399     sqlite3VdbeResolveLabel(v, addr);
00400   }
00401 
00402   /* Top of the update loop */
00403   if( okOnePass ){
00404     int a1 = sqlite3VdbeAddOp1(v, OP_NotNull, regOldRowid);
00405     addr = sqlite3VdbeAddOp0(v, OP_Goto);
00406     sqlite3VdbeJumpHere(v, a1);
00407   }else{
00408     addr = sqlite3VdbeAddOp2(v, OP_FifoRead, regOldRowid, 0);
00409   }
00410 
00411   if( triggers_exist ){
00412     int regRowid;
00413     int regRow;
00414     int regCols;
00415 
00416     /* Make cursor iCur point to the record that is being updated.
00417     */
00418     sqlite3VdbeAddOp3(v, OP_NotExists, iCur, addr, regOldRowid);
00419 
00420     /* Generate the OLD table
00421     */
00422     regRowid = sqlite3GetTempReg(pParse);
00423     regRow = sqlite3GetTempReg(pParse);
00424     sqlite3VdbeAddOp2(v, OP_Rowid, iCur, regRowid);
00425     if( !old_col_mask ){
00426       sqlite3VdbeAddOp2(v, OP_Null, 0, regRow);
00427     }else{
00428       sqlite3VdbeAddOp2(v, OP_RowData, iCur, regRow);
00429     }
00430     sqlite3VdbeAddOp3(v, OP_Insert, oldIdx, regRow, regRowid);
00431 
00432     /* Generate the NEW table
00433     */
00434     if( chngRowid ){
00435       sqlite3ExprCodeAndCache(pParse, pRowidExpr, regRowid);
00436       sqlite3VdbeAddOp1(v, OP_MustBeInt, regRowid);
00437     }else{
00438       sqlite3VdbeAddOp2(v, OP_Rowid, iCur, regRowid);
00439     }
00440     regCols = sqlite3GetTempRange(pParse, pTab->nCol);
00441     for(i=0; i<pTab->nCol; i++){
00442       if( i==pTab->iPKey ){
00443         sqlite3VdbeAddOp2(v, OP_Null, 0, regCols+i);
00444         continue;
00445       }
00446       j = aXRef[i];
00447       if( new_col_mask&((u32)1<<i) || new_col_mask==0xffffffff ){
00448         if( j<0 ){
00449           sqlite3VdbeAddOp3(v, OP_Column, iCur, i, regCols+i);
00450           sqlite3ColumnDefault(v, pTab, i);
00451         }else{
00452           sqlite3ExprCodeAndCache(pParse, pChanges->a[j].pExpr, regCols+i);
00453         }
00454       }else{
00455         sqlite3VdbeAddOp2(v, OP_Null, 0, regCols+i);
00456       }
00457     }
00458     sqlite3VdbeAddOp3(v, OP_MakeRecord, regCols, pTab->nCol, regRow);
00459     if( !isView ){
00460       sqlite3TableAffinityStr(v, pTab);
00461       sqlite3ExprCacheAffinityChange(pParse, regCols, pTab->nCol);
00462     }
00463     sqlite3ReleaseTempRange(pParse, regCols, pTab->nCol);
00464     /* if( pParse->nErr ) goto update_cleanup; */
00465     sqlite3VdbeAddOp3(v, OP_Insert, newIdx, regRow, regRowid);
00466     sqlite3ReleaseTempReg(pParse, regRowid);
00467     sqlite3ReleaseTempReg(pParse, regRow);
00468 
00469     sqlite3VdbeAddOp2(v, OP_Goto, 0, iBeginBeforeTrigger);
00470     sqlite3VdbeJumpHere(v, iEndBeforeTrigger);
00471   }
00472 
00473   if( !isView && !IsVirtual(pTab) ){
00474     /* Loop over every record that needs updating.  We have to load
00475     ** the old data for each record to be updated because some columns
00476     ** might not change and we will need to copy the old value.
00477     ** Also, the old data is needed to delete the old index entries.
00478     ** So make the cursor point at the old record.
00479     */
00480     sqlite3VdbeAddOp3(v, OP_NotExists, iCur, addr, regOldRowid);
00481 
00482     /* If the record number will change, push the record number as it
00483     ** will be after the update. (The old record number is currently
00484     ** on top of the stack.)
00485     */
00486     if( chngRowid ){
00487       sqlite3ExprCode(pParse, pRowidExpr, regNewRowid);
00488       sqlite3VdbeAddOp1(v, OP_MustBeInt, regNewRowid);
00489     }
00490 
00491     /* Compute new data for this record.  
00492     */
00493     for(i=0; i<pTab->nCol; i++){
00494       if( i==pTab->iPKey ){
00495         sqlite3VdbeAddOp2(v, OP_Null, 0, regData+i);
00496         continue;
00497       }
00498       j = aXRef[i];
00499       if( j<0 ){
00500         sqlite3VdbeAddOp3(v, OP_Column, iCur, i, regData+i);
00501         sqlite3ColumnDefault(v, pTab, i);
00502       }else{
00503         sqlite3ExprCode(pParse, pChanges->a[j].pExpr, regData+i);
00504       }
00505     }
00506 
00507     /* Do constraint checks
00508     */
00509     sqlite3GenerateConstraintChecks(pParse, pTab, iCur, regNewRowid,
00510                                     aRegIdx, chngRowid, 1,
00511                                     onError, addr);
00512 
00513     /* Delete the old indices for the current record.
00514     */
00515     j1 = sqlite3VdbeAddOp3(v, OP_NotExists, iCur, 0, regOldRowid);
00516     sqlite3GenerateRowIndexDelete(pParse, pTab, iCur, aRegIdx);
00517 
00518     /* If changing the record number, delete the old record.
00519     */
00520     if( chngRowid ){
00521       sqlite3VdbeAddOp2(v, OP_Delete, iCur, 0);
00522     }
00523     sqlite3VdbeJumpHere(v, j1);
00524 
00525     /* Create the new index entries and the new record.
00526     */
00527     sqlite3CompleteInsertion(pParse, pTab, iCur, regNewRowid, 
00528                              aRegIdx, chngRowid, 1, -1, 0);
00529   }
00530 
00531   /* Increment the row counter 
00532   */
00533   if( db->flags & SQLITE_CountRows && !pParse->trigStack){
00534     sqlite3VdbeAddOp2(v, OP_AddImm, regRowCount, 1);
00535   }
00536 
00537   /* If there are triggers, close all the cursors after each iteration
00538   ** through the loop.  The fire the after triggers.
00539   */
00540   if( triggers_exist ){
00541     sqlite3VdbeAddOp2(v, OP_Goto, 0, iBeginAfterTrigger);
00542     sqlite3VdbeJumpHere(v, iEndAfterTrigger);
00543   }
00544 
00545   /* Repeat the above with the next record to be updated, until
00546   ** all record selected by the WHERE clause have been updated.
00547   */
00548   sqlite3VdbeAddOp2(v, OP_Goto, 0, addr);
00549   sqlite3VdbeJumpHere(v, addr);
00550 
00551   /* Close all tables */
00552   for(i=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, i++){
00553     if( openAll || aRegIdx[i]>0 ){
00554       sqlite3VdbeAddOp2(v, OP_Close, iCur+i+1, 0);
00555     }
00556   }
00557   sqlite3VdbeAddOp2(v, OP_Close, iCur, 0);
00558   if( triggers_exist ){
00559     sqlite3VdbeAddOp2(v, OP_Close, newIdx, 0);
00560     sqlite3VdbeAddOp2(v, OP_Close, oldIdx, 0);
00561   }
00562 
00563   /*
00564   ** Return the number of rows that were changed. If this routine is 
00565   ** generating code because of a call to sqlite3NestedParse(), do not
00566   ** invoke the callback function.
00567   */
00568   if( db->flags & SQLITE_CountRows && !pParse->trigStack && pParse->nested==0 ){
00569     sqlite3VdbeAddOp2(v, OP_ResultRow, regRowCount, 1);
00570     sqlite3VdbeSetNumCols(v, 1);
00571     sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "rows updated", SQLITE_STATIC);
00572   }
00573 
00574 update_cleanup:
00575   sqlite3AuthContextPop(&sContext);
00576   sqlite3DbFree(db, aRegIdx);
00577   sqlite3DbFree(db, aXRef);
00578   sqlite3SrcListDelete(db, pTabList);
00579   sqlite3ExprListDelete(db, pChanges);
00580   sqlite3ExprDelete(db, pWhere);
00581   return;
00582 }
00583 
00584 #ifndef SQLITE_OMIT_VIRTUALTABLE
00585 /*
00586 ** Generate code for an UPDATE of a virtual table.
00587 **
00588 ** The strategy is that we create an ephemerial table that contains
00589 ** for each row to be changed:
00590 **
00591 **   (A)  The original rowid of that row.
00592 **   (B)  The revised rowid for the row. (note1)
00593 **   (C)  The content of every column in the row.
00594 **
00595 ** Then we loop over this ephemeral table and for each row in
00596 ** the ephermeral table call VUpdate.
00597 **
00598 ** When finished, drop the ephemeral table.
00599 **
00600 ** (note1) Actually, if we know in advance that (A) is always the same
00601 ** as (B) we only store (A), then duplicate (A) when pulling
00602 ** it out of the ephemeral table before calling VUpdate.
00603 */
00604 static void updateVirtualTable(
00605   Parse *pParse,       /* The parsing context */
00606   SrcList *pSrc,       /* The virtual table to be modified */
00607   Table *pTab,         /* The virtual table */
00608   ExprList *pChanges,  /* The columns to change in the UPDATE statement */
00609   Expr *pRowid,        /* Expression used to recompute the rowid */
00610   int *aXRef,          /* Mapping from columns of pTab to entries in pChanges */
00611   Expr *pWhere         /* WHERE clause of the UPDATE statement */
00612 ){
00613   Vdbe *v = pParse->pVdbe;  /* Virtual machine under construction */
00614   ExprList *pEList = 0;     /* The result set of the SELECT statement */
00615   Select *pSelect = 0;      /* The SELECT statement */
00616   Expr *pExpr;              /* Temporary expression */
00617   int ephemTab;             /* Table holding the result of the SELECT */
00618   int i;                    /* Loop counter */
00619   int addr;                 /* Address of top of loop */
00620   int iReg;                 /* First register in set passed to OP_VUpdate */
00621   sqlite3 *db = pParse->db; /* Database connection */
00622   const char *pVtab = (const char*)pTab->pVtab;
00623   SelectDest dest;
00624 
00625   /* Construct the SELECT statement that will find the new values for
00626   ** all updated rows. 
00627   */
00628   pEList = sqlite3ExprListAppend(pParse, 0, 
00629                                  sqlite3CreateIdExpr(pParse, "_rowid_"), 0);
00630   if( pRowid ){
00631     pEList = sqlite3ExprListAppend(pParse, pEList,
00632                                    sqlite3ExprDup(db, pRowid), 0);
00633   }
00634   assert( pTab->iPKey<0 );
00635   for(i=0; i<pTab->nCol; i++){
00636     if( aXRef[i]>=0 ){
00637       pExpr = sqlite3ExprDup(db, pChanges->a[aXRef[i]].pExpr);
00638     }else{
00639       pExpr = sqlite3CreateIdExpr(pParse, pTab->aCol[i].zName);
00640     }
00641     pEList = sqlite3ExprListAppend(pParse, pEList, pExpr, 0);
00642   }
00643   pSelect = sqlite3SelectNew(pParse, pEList, pSrc, pWhere, 0, 0, 0, 0, 0, 0);
00644   
00645   /* Create the ephemeral table into which the update results will
00646   ** be stored.
00647   */
00648   assert( v );
00649   ephemTab = pParse->nTab++;
00650   sqlite3VdbeAddOp2(v, OP_OpenEphemeral, ephemTab, pTab->nCol+1+(pRowid!=0));
00651 
00652   /* fill the ephemeral table 
00653   */
00654   sqlite3SelectDestInit(&dest, SRT_Table, ephemTab);
00655   sqlite3Select(pParse, pSelect, &dest);
00656 
00657   /* Generate code to scan the ephemeral table and call VUpdate. */
00658   iReg = ++pParse->nMem;
00659   pParse->nMem += pTab->nCol+1;
00660   sqlite3VdbeAddOp2(v, OP_Rewind, ephemTab, 0);
00661   addr = sqlite3VdbeCurrentAddr(v);
00662   sqlite3VdbeAddOp3(v, OP_Column,  ephemTab, 0, iReg);
00663   sqlite3VdbeAddOp3(v, OP_Column, ephemTab, (pRowid?1:0), iReg+1);
00664   for(i=0; i<pTab->nCol; i++){
00665     sqlite3VdbeAddOp3(v, OP_Column, ephemTab, i+1+(pRowid!=0), iReg+2+i);
00666   }
00667   sqlite3VtabMakeWritable(pParse, pTab);
00668   sqlite3VdbeAddOp4(v, OP_VUpdate, 0, pTab->nCol+2, iReg, pVtab, P4_VTAB);
00669   sqlite3VdbeAddOp2(v, OP_Next, ephemTab, addr);
00670   sqlite3VdbeJumpHere(v, addr-1);
00671   sqlite3VdbeAddOp2(v, OP_Close, ephemTab, 0);
00672 
00673   /* Cleanup */
00674   sqlite3SelectDelete(db, pSelect);  
00675 }
00676 #endif /* SQLITE_OMIT_VIRTUALTABLE */
00677 
00678 /* Make sure "isView" gets undefined in case this file becomes part of
00679 ** the amalgamation - so that subsequent files do not see isView as a
00680 ** macro. */
00681 #undef isView

ContextLogger2—ContextLogger2 Logger Daemon Internals—Generated on Mon May 2 13:49:57 2011 by Doxygen 1.6.1