| 2 |      1 | /*
 | 
|  |      2 | ** 2001 September 15
 | 
|  |      3 | **
 | 
|  |      4 | ** The author disclaims copyright to this source code.  In place of
 | 
|  |      5 | ** a legal notice, here is a blessing:
 | 
|  |      6 | **
 | 
|  |      7 | **    May you do good and not evil.
 | 
|  |      8 | **    May you find forgiveness for yourself and forgive others.
 | 
|  |      9 | **    May you share freely, never taking more than you give.
 | 
|  |     10 | **
 | 
|  |     11 | *************************************************************************
 | 
|  |     12 | ** This file contains C code routines that are called by the parser
 | 
|  |     13 | ** in order to generate code for DELETE FROM statements.
 | 
|  |     14 | **
 | 
|  |     15 | ** $Id: delete.cpp 1282 2008-11-13 09:31:33Z LarsPson $
 | 
|  |     16 | */
 | 
|  |     17 | #include "sqliteInt.h"
 | 
|  |     18 | 
 | 
|  |     19 | /*
 | 
|  |     20 | ** Look up every table that is named in pSrc.  If any table is not found,
 | 
|  |     21 | ** add an error message to pParse->zErrMsg and return NULL.  If all tables
 | 
|  |     22 | ** are found, return a pointer to the last table.
 | 
|  |     23 | */
 | 
|  |     24 | Table *sqlite3SrcListLookup(Parse *pParse, SrcList *pSrc){
 | 
|  |     25 |   Table *pTab = 0;
 | 
|  |     26 |   int i;
 | 
|  |     27 |   SrcList::SrcList_item *pItem;
 | 
|  |     28 |   for(i=0, pItem=pSrc->a; i<pSrc->nSrc; i++, pItem++){
 | 
|  |     29 |     pTab = sqlite3LocateTable(pParse, pItem->zName, pItem->zDatabase);
 | 
|  |     30 |     sqlite3DeleteTable(pItem->pTab);
 | 
|  |     31 |     pItem->pTab = pTab;
 | 
|  |     32 |     if( pTab ){
 | 
|  |     33 |       pTab->nRef++;
 | 
|  |     34 |     }
 | 
|  |     35 |   }
 | 
|  |     36 |   return pTab;
 | 
|  |     37 | }
 | 
|  |     38 | 
 | 
|  |     39 | /*
 | 
|  |     40 | ** Check to make sure the given table is writable.  If it is not
 | 
|  |     41 | ** writable, generate an error message and return 1.  If it is
 | 
|  |     42 | ** writable return 0;
 | 
|  |     43 | */
 | 
|  |     44 | int sqlite3IsReadOnly(Parse *pParse, Table *pTab, int viewOk){
 | 
|  |     45 |   if( (pTab->readOnly && (pParse->db->flags & SQLITE_WriteSchema)==0
 | 
|  |     46 |         && pParse->nested==0) 
 | 
|  |     47 | #ifndef SQLITE_OMIT_VIRTUALTABLE
 | 
|  |     48 |       || (pTab->pMod && pTab->pMod->pModule->xUpdate==0)
 | 
|  |     49 | #endif
 | 
|  |     50 |   ){
 | 
|  |     51 |     sqlite3ErrorMsg(pParse, "table %s may not be modified", pTab->zName);
 | 
|  |     52 |     return 1;
 | 
|  |     53 |   }
 | 
|  |     54 | #ifndef SQLITE_OMIT_VIEW
 | 
|  |     55 |   if( !viewOk && pTab->pSelect ){
 | 
|  |     56 |     sqlite3ErrorMsg(pParse,"cannot modify %s because it is a view",pTab->zName);
 | 
|  |     57 |     return 1;
 | 
|  |     58 |   }
 | 
|  |     59 | #endif
 | 
|  |     60 |   return 0;
 | 
|  |     61 | }
 | 
|  |     62 | 
 | 
|  |     63 | /*
 | 
|  |     64 | ** Generate code that will open a table for reading.
 | 
|  |     65 | */
 | 
|  |     66 | void sqlite3OpenTable(
 | 
|  |     67 |   Parse *p,       /* Generate code into this VDBE */
 | 
|  |     68 |   int iCur,       /* The cursor number of the table */
 | 
|  |     69 |   int iDb,        /* The database index in sqlite3.aDb[] */
 | 
|  |     70 |   Table *pTab,    /* The table to be opened */
 | 
|  |     71 |   int opcode      /* OP_OpenRead or OP_OpenWrite */
 | 
|  |     72 | ){
 | 
|  |     73 |   Vdbe *v;
 | 
|  |     74 |   if( IsVirtual(pTab) ) return;
 | 
|  |     75 |   v = sqlite3GetVdbe(p);
 | 
|  |     76 |   assert( opcode==OP_OpenWrite || opcode==OP_OpenRead );
 | 
|  |     77 |   sqlite3TableLock(p, iDb, pTab->tnum, (opcode==OP_OpenWrite), pTab->zName);
 | 
|  |     78 |   sqlite3VdbeAddOp(v, OP_Integer, iDb, 0);
 | 
|  |     79 |   VdbeComment((v, "# %s", pTab->zName));
 | 
|  |     80 |   sqlite3VdbeAddOp(v, opcode, iCur, pTab->tnum);
 | 
|  |     81 |   sqlite3VdbeAddOp(v, OP_SetNumColumns, iCur, pTab->nCol);
 | 
|  |     82 | }
 | 
|  |     83 | 
 | 
|  |     84 | 
 | 
|  |     85 | /*
 | 
|  |     86 | ** Generate code for a DELETE FROM statement.
 | 
|  |     87 | **
 | 
|  |     88 | **     DELETE FROM table_wxyz WHERE a<5 AND b NOT NULL;
 | 
|  |     89 | **                 \________/       \________________/
 | 
|  |     90 | **                  pTabList              pWhere
 | 
|  |     91 | */
 | 
|  |     92 | void sqlite3DeleteFrom(
 | 
|  |     93 |   Parse *pParse,         /* The parser context */
 | 
|  |     94 |   SrcList *pTabList,     /* The table from which we should delete things */
 | 
|  |     95 |   Expr *pWhere           /* The WHERE clause.  May be null */
 | 
|  |     96 | ){
 | 
|  |     97 |   Vdbe *v;               /* The virtual database engine */
 | 
|  |     98 |   Table *pTab;           /* The table from which records will be deleted */
 | 
|  |     99 |   const char *zDb;       /* Name of database holding pTab */
 | 
|  |    100 |   int end, addr = 0;     /* A couple addresses of generated code */
 | 
|  |    101 |   int i;                 /* Loop counter */
 | 
|  |    102 |   WhereInfo *pWInfo;     /* Information about the WHERE clause */
 | 
|  |    103 |   Index *pIdx;           /* For looping over indices of the table */
 | 
|  |    104 |   int iCur;              /* VDBE Cursor number for pTab */
 | 
|  |    105 |   sqlite3 *db;           /* Main database structure */
 | 
|  |    106 |   AuthContext sContext;  /* Authorization context */
 | 
|  |    107 |   int oldIdx = -1;       /* Cursor for the OLD table of AFTER triggers */
 | 
|  |    108 |   NameContext sNC;       /* Name context to resolve expressions in */
 | 
|  |    109 |   int iDb;               /* Database number */
 | 
|  |    110 |   int memCnt = 0;        /* Memory cell used for change counting */
 | 
|  |    111 | 
 | 
|  |    112 | #ifndef SQLITE_OMIT_TRIGGER
 | 
|  |    113 |   int isView;                  /* True if attempting to delete from a view */
 | 
|  |    114 |   int triggers_exist = 0;      /* True if any triggers exist */
 | 
|  |    115 | #endif
 | 
|  |    116 | 
 | 
|  |    117 |   sContext.pParse = 0;
 | 
|  |    118 |   db = pParse->db;
 | 
|  |    119 |   if( pParse->nErr || db->mallocFailed ){
 | 
|  |    120 |     goto delete_from_cleanup;
 | 
|  |    121 |   }
 | 
|  |    122 |   assert( pTabList->nSrc==1 );
 | 
|  |    123 | 
 | 
|  |    124 |   /* Locate the table which we want to delete.  This table has to be
 | 
|  |    125 |   ** put in an SrcList structure because some of the subroutines we
 | 
|  |    126 |   ** will be calling are designed to work with multiple tables and expect
 | 
|  |    127 |   ** an SrcList* parameter instead of just a Table* parameter.
 | 
|  |    128 |   */
 | 
|  |    129 |   pTab = sqlite3SrcListLookup(pParse, pTabList);
 | 
|  |    130 |   if( pTab==0 )  goto delete_from_cleanup;
 | 
|  |    131 | 
 | 
|  |    132 |   /* Figure out if we have any triggers and if the table being
 | 
|  |    133 |   ** deleted from is a view
 | 
|  |    134 |   */
 | 
|  |    135 | #ifndef SQLITE_OMIT_TRIGGER
 | 
|  |    136 |   triggers_exist = sqlite3TriggersExist(pParse, pTab, TK_DELETE, 0);
 | 
|  |    137 |   isView = pTab->pSelect!=0;
 | 
|  |    138 | #else
 | 
|  |    139 | # define triggers_exist 0
 | 
|  |    140 | # define isView 0
 | 
|  |    141 | #endif
 | 
|  |    142 | #ifdef SQLITE_OMIT_VIEW
 | 
|  |    143 | # undef isView
 | 
|  |    144 | # define isView 0
 | 
|  |    145 | #endif
 | 
|  |    146 | 
 | 
|  |    147 |   if( sqlite3IsReadOnly(pParse, pTab, triggers_exist) ){
 | 
|  |    148 |     goto delete_from_cleanup;
 | 
|  |    149 |   }
 | 
|  |    150 |   iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
 | 
|  |    151 |   assert( iDb<db->nDb );
 | 
|  |    152 |   zDb = db->aDb[iDb].zName;
 | 
|  |    153 |   if( sqlite3AuthCheck(pParse, SQLITE_DELETE, pTab->zName, 0, zDb) ){
 | 
|  |    154 |     goto delete_from_cleanup;
 | 
|  |    155 |   }
 | 
|  |    156 | 
 | 
|  |    157 |   /* If pTab is really a view, make sure it has been initialized.
 | 
|  |    158 |   */
 | 
|  |    159 |   if( sqlite3ViewGetColumnNames(pParse, pTab) ){
 | 
|  |    160 |     goto delete_from_cleanup;
 | 
|  |    161 |   }
 | 
|  |    162 | 
 | 
|  |    163 |   /* Allocate a cursor used to store the old.* data for a trigger.
 | 
|  |    164 |   */
 | 
|  |    165 |   if( triggers_exist ){ 
 | 
|  |    166 |     oldIdx = pParse->nTab++;
 | 
|  |    167 |   }
 | 
|  |    168 | 
 | 
|  |    169 |   /* Resolve the column names in the WHERE clause.
 | 
|  |    170 |   */
 | 
|  |    171 |   assert( pTabList->nSrc==1 );
 | 
|  |    172 |   iCur = pTabList->a[0].iCursor = pParse->nTab++;
 | 
|  |    173 |   memset(&sNC, 0, sizeof(sNC));
 | 
|  |    174 |   sNC.pParse = pParse;
 | 
|  |    175 |   sNC.pSrcList = pTabList;
 | 
|  |    176 |   if( sqlite3ExprResolveNames(&sNC, pWhere) ){
 | 
|  |    177 |     goto delete_from_cleanup;
 | 
|  |    178 |   }
 | 
|  |    179 | 
 | 
|  |    180 |   /* Start the view context
 | 
|  |    181 |   */
 | 
|  |    182 |   if( isView ){
 | 
|  |    183 |     sqlite3AuthContextPush(pParse, &sContext, pTab->zName);
 | 
|  |    184 |   }
 | 
|  |    185 | 
 | 
|  |    186 |   /* Begin generating code.
 | 
|  |    187 |   */
 | 
|  |    188 |   v = sqlite3GetVdbe(pParse);
 | 
|  |    189 |   if( v==0 ){
 | 
|  |    190 |     goto delete_from_cleanup;
 | 
|  |    191 |   }
 | 
|  |    192 |   if( pParse->nested==0 ) sqlite3VdbeCountChanges(v);
 | 
|  |    193 |   sqlite3BeginWriteOperation(pParse, triggers_exist, iDb);
 | 
|  |    194 | 
 | 
|  |    195 |   /* If we are trying to delete from a view, realize that view into
 | 
|  |    196 |   ** a ephemeral table.
 | 
|  |    197 |   */
 | 
|  |    198 |   if( isView ){
 | 
|  |    199 |     Select *pView = sqlite3SelectDup(db, pTab->pSelect);
 | 
|  |    200 |     sqlite3Select(pParse, pView, SRT_EphemTab, iCur, 0, 0, 0, 0);
 | 
|  |    201 |     sqlite3SelectDelete(pView);
 | 
|  |    202 |   }
 | 
|  |    203 | 
 | 
|  |    204 |   /* Initialize the counter of the number of rows deleted, if
 | 
|  |    205 |   ** we are counting rows.
 | 
|  |    206 |   */
 | 
|  |    207 |   if( db->flags & SQLITE_CountRows ){
 | 
|  |    208 |     memCnt = pParse->nMem++;
 | 
|  |    209 |     sqlite3VdbeAddOp(v, OP_MemInt, 0, memCnt);
 | 
|  |    210 |   }
 | 
|  |    211 | 
 | 
|  |    212 |   /* Special case: A DELETE without a WHERE clause deletes everything.
 | 
|  |    213 |   ** It is easier just to erase the whole table.  Note, however, that
 | 
|  |    214 |   ** this means that the row change count will be incorrect.
 | 
|  |    215 |   */
 | 
|  |    216 |   if( pWhere==0 && !triggers_exist && !IsVirtual(pTab) ){
 | 
|  |    217 |     if( db->flags & SQLITE_CountRows ){
 | 
|  |    218 |       /* If counting rows deleted, just count the total number of
 | 
|  |    219 |       ** entries in the table. */
 | 
|  |    220 |       int addr2;
 | 
|  |    221 |       if( !isView ){
 | 
|  |    222 |         sqlite3OpenTable(pParse, iCur, iDb, pTab, OP_OpenRead);
 | 
|  |    223 |       }
 | 
|  |    224 |       sqlite3VdbeAddOp(v, OP_Rewind, iCur, sqlite3VdbeCurrentAddr(v)+2);
 | 
|  |    225 |       addr2 = sqlite3VdbeAddOp(v, OP_MemIncr, 1, memCnt);
 | 
|  |    226 |       sqlite3VdbeAddOp(v, OP_Next, iCur, addr2);
 | 
|  |    227 |       sqlite3VdbeAddOp(v, OP_Close, iCur, 0);
 | 
|  |    228 |     }
 | 
|  |    229 |     if( !isView ){
 | 
|  |    230 |       sqlite3VdbeAddOp(v, OP_Clear, pTab->tnum, iDb);
 | 
|  |    231 |       if( !pParse->nested ){
 | 
|  |    232 |         sqlite3VdbeChangeP3(v, -1, pTab->zName, P3_STATIC);
 | 
|  |    233 |       }
 | 
|  |    234 |       for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
 | 
|  |    235 |         assert( pIdx->pSchema==pTab->pSchema );
 | 
|  |    236 |         sqlite3VdbeAddOp(v, OP_Clear, pIdx->tnum, iDb);
 | 
|  |    237 |       }
 | 
|  |    238 |     }
 | 
|  |    239 |   } 
 | 
|  |    240 |   /* The usual case: There is a WHERE clause so we have to scan through
 | 
|  |    241 |   ** the table and pick which records to delete.
 | 
|  |    242 |   */
 | 
|  |    243 |   else{
 | 
|  |    244 |     /* Begin the database scan
 | 
|  |    245 |     */
 | 
|  |    246 |     pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, 0);
 | 
|  |    247 |     if( pWInfo==0 ) goto delete_from_cleanup;
 | 
|  |    248 | 
 | 
|  |    249 |     /* Remember the rowid of every item to be deleted.
 | 
|  |    250 |     */
 | 
|  |    251 |     sqlite3VdbeAddOp(v, IsVirtual(pTab) ? OP_VRowid : OP_Rowid, iCur, 0);
 | 
|  |    252 |     sqlite3VdbeAddOp(v, OP_FifoWrite, 0, 0);
 | 
|  |    253 |     if( db->flags & SQLITE_CountRows ){
 | 
|  |    254 |       sqlite3VdbeAddOp(v, OP_MemIncr, 1, memCnt);
 | 
|  |    255 |     }
 | 
|  |    256 | 
 | 
|  |    257 |     /* End the database scan loop.
 | 
|  |    258 |     */
 | 
|  |    259 |     sqlite3WhereEnd(pWInfo);
 | 
|  |    260 | 
 | 
|  |    261 |     /* Open the pseudo-table used to store OLD if there are triggers.
 | 
|  |    262 |     */
 | 
|  |    263 |     if( triggers_exist ){
 | 
|  |    264 |       sqlite3VdbeAddOp(v, OP_OpenPseudo, oldIdx, 0);
 | 
|  |    265 |       sqlite3VdbeAddOp(v, OP_SetNumColumns, oldIdx, pTab->nCol);
 | 
|  |    266 |     }
 | 
|  |    267 | 
 | 
|  |    268 |     /* Delete every item whose key was written to the list during the
 | 
|  |    269 |     ** database scan.  We have to delete items after the scan is complete
 | 
|  |    270 |     ** because deleting an item can change the scan order.
 | 
|  |    271 |     */
 | 
|  |    272 |     end = sqlite3VdbeMakeLabel(v);
 | 
|  |    273 | 
 | 
|  |    274 |     /* This is the beginning of the delete loop when there are
 | 
|  |    275 |     ** row triggers.
 | 
|  |    276 |     */
 | 
|  |    277 |     if( triggers_exist ){
 | 
|  |    278 |       int mem1 = pParse->nMem++;
 | 
|  |    279 |       addr = sqlite3VdbeAddOp(v, OP_FifoRead, 0, end);
 | 
|  |    280 |       sqlite3VdbeAddOp(v, OP_StackDepth, -1, 0);
 | 
|  |    281 |       sqlite3VdbeAddOp(v, OP_MemStore, mem1, 0);
 | 
|  |    282 |       if( !isView ){
 | 
|  |    283 |         sqlite3OpenTable(pParse, iCur, iDb, pTab, OP_OpenRead);
 | 
|  |    284 |       }
 | 
|  |    285 |       sqlite3VdbeAddOp(v, OP_NotExists, iCur, addr);
 | 
|  |    286 |       sqlite3VdbeAddOp(v, OP_Rowid, iCur, 0);
 | 
|  |    287 |       sqlite3VdbeAddOp(v, OP_RowData, iCur, 0);
 | 
|  |    288 |       sqlite3VdbeAddOp(v, OP_Insert, oldIdx, 0);
 | 
|  |    289 |       if( !isView ){
 | 
|  |    290 |         sqlite3VdbeAddOp(v, OP_Close, iCur, 0);
 | 
|  |    291 |       }
 | 
|  |    292 | 
 | 
|  |    293 |       (void)sqlite3CodeRowTrigger(pParse, TK_DELETE, 0, TRIGGER_BEFORE, pTab,
 | 
|  |    294 |           -1, oldIdx, (pParse->trigStack)?pParse->trigStack->orconf:OE_Default,
 | 
|  |    295 |           addr);
 | 
|  |    296 |       if( !isView ){
 | 
|  |    297 |         sqlite3VdbeAddOp(v, OP_MemLoad, mem1, 0);
 | 
|  |    298 |       }
 | 
|  |    299 |     }
 | 
|  |    300 | 
 | 
|  |    301 |     if( !isView ){
 | 
|  |    302 |       /* Open cursors for the table we are deleting from and all its
 | 
|  |    303 |       ** indices.  If there are row triggers, this happens inside the
 | 
|  |    304 |       ** OP_FifoRead loop because the cursor have to all be closed
 | 
|  |    305 |       ** before the trigger fires.  If there are no row triggers, the
 | 
|  |    306 |       ** cursors are opened only once on the outside the loop.
 | 
|  |    307 |       */
 | 
|  |    308 |       sqlite3OpenTableAndIndices(pParse, pTab, iCur, OP_OpenWrite);
 | 
|  |    309 | 
 | 
|  |    310 |       /* This is the beginning of the delete loop when there are no
 | 
|  |    311 |       ** row triggers */
 | 
|  |    312 |       if( !triggers_exist ){ 
 | 
|  |    313 |         addr = sqlite3VdbeAddOp(v, OP_FifoRead, 0, end);
 | 
|  |    314 |         sqlite3VdbeAddOp(v, OP_StackDepth, -1, 0);
 | 
|  |    315 |       }
 | 
|  |    316 | 
 | 
|  |    317 |       /* Delete the row */
 | 
|  |    318 | #ifndef SQLITE_OMIT_VIRTUALTABLE
 | 
|  |    319 |       if( IsVirtual(pTab) ){
 | 
|  |    320 |         pParse->pVirtualLock = pTab;
 | 
|  |    321 |         sqlite3VdbeOp3(v, OP_VUpdate, 0, 1, (const char*)pTab->pVtab, P3_VTAB);
 | 
|  |    322 |       }else
 | 
|  |    323 | #endif
 | 
|  |    324 |       {
 | 
|  |    325 |         sqlite3GenerateRowDelete(db, v, pTab, iCur, pParse->nested==0);
 | 
|  |    326 |       }
 | 
|  |    327 |     }
 | 
|  |    328 | 
 | 
|  |    329 |     /* If there are row triggers, close all cursors then invoke
 | 
|  |    330 |     ** the AFTER triggers
 | 
|  |    331 |     */
 | 
|  |    332 |     if( triggers_exist ){
 | 
|  |    333 |       if( !isView ){
 | 
|  |    334 |         for(i=1, pIdx=pTab->pIndex; pIdx; i++, pIdx=pIdx->pNext){
 | 
|  |    335 |           sqlite3VdbeAddOp(v, OP_Close, iCur + i, pIdx->tnum);
 | 
|  |    336 |         }
 | 
|  |    337 |         sqlite3VdbeAddOp(v, OP_Close, iCur, 0);
 | 
|  |    338 |       }
 | 
|  |    339 |       (void)sqlite3CodeRowTrigger(pParse, TK_DELETE, 0, TRIGGER_AFTER, pTab, -1,
 | 
|  |    340 |           oldIdx, (pParse->trigStack)?pParse->trigStack->orconf:OE_Default,
 | 
|  |    341 |           addr);
 | 
|  |    342 |     }
 | 
|  |    343 | 
 | 
|  |    344 |     /* End of the delete loop */
 | 
|  |    345 |     sqlite3VdbeAddOp(v, OP_Goto, 0, addr);
 | 
|  |    346 |     sqlite3VdbeResolveLabel(v, end);
 | 
|  |    347 | 
 | 
|  |    348 |     /* Close the cursors after the loop if there are no row triggers */
 | 
|  |    349 |     if( !triggers_exist && !IsVirtual(pTab) ){
 | 
|  |    350 |       for(i=1, pIdx=pTab->pIndex; pIdx; i++, pIdx=pIdx->pNext){
 | 
|  |    351 |         sqlite3VdbeAddOp(v, OP_Close, iCur + i, pIdx->tnum);
 | 
|  |    352 |       }
 | 
|  |    353 |       sqlite3VdbeAddOp(v, OP_Close, iCur, 0);
 | 
|  |    354 |     }
 | 
|  |    355 |   }
 | 
|  |    356 | 
 | 
|  |    357 |   /*
 | 
|  |    358 |   ** Return the number of rows that were deleted. If this routine is 
 | 
|  |    359 |   ** generating code because of a call to sqlite3NestedParse(), do not
 | 
|  |    360 |   ** invoke the callback function.
 | 
|  |    361 |   */
 | 
|  |    362 |   if( db->flags & SQLITE_CountRows && pParse->nested==0 && !pParse->trigStack ){
 | 
|  |    363 |     sqlite3VdbeAddOp(v, OP_MemLoad, memCnt, 0);
 | 
|  |    364 |     sqlite3VdbeAddOp(v, OP_Callback, 1, 0);
 | 
|  |    365 |     sqlite3VdbeSetNumCols(v, 1);
 | 
|  |    366 |     sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "rows deleted", P3_STATIC);
 | 
|  |    367 |   }
 | 
|  |    368 | 
 | 
|  |    369 | delete_from_cleanup:
 | 
|  |    370 |   sqlite3AuthContextPop(&sContext);
 | 
|  |    371 |   sqlite3SrcListDelete(pTabList);
 | 
|  |    372 |   sqlite3ExprDelete(pWhere);
 | 
|  |    373 |   return;
 | 
|  |    374 | }
 | 
|  |    375 | 
 | 
|  |    376 | /*
 | 
|  |    377 | ** This routine generates VDBE code that causes a single row of a
 | 
|  |    378 | ** single table to be deleted.
 | 
|  |    379 | **
 | 
|  |    380 | ** The VDBE must be in a particular state when this routine is called.
 | 
|  |    381 | ** These are the requirements:
 | 
|  |    382 | **
 | 
|  |    383 | **   1.  A read/write cursor pointing to pTab, the table containing the row
 | 
|  |    384 | **       to be deleted, must be opened as cursor number "base".
 | 
|  |    385 | **
 | 
|  |    386 | **   2.  Read/write cursors for all indices of pTab must be open as
 | 
|  |    387 | **       cursor number base+i for the i-th index.
 | 
|  |    388 | **
 | 
|  |    389 | **   3.  The record number of the row to be deleted must be on the top
 | 
|  |    390 | **       of the stack.
 | 
|  |    391 | **
 | 
|  |    392 | ** This routine pops the top of the stack to remove the record number
 | 
|  |    393 | ** and then generates code to remove both the table record and all index
 | 
|  |    394 | ** entries that point to that record.
 | 
|  |    395 | */
 | 
|  |    396 | void sqlite3GenerateRowDelete(
 | 
|  |    397 |   sqlite3 *db,       /* The database containing the index */
 | 
|  |    398 |   Vdbe *v,           /* Generate code into this VDBE */
 | 
|  |    399 |   Table *pTab,       /* Table containing the row to be deleted */
 | 
|  |    400 |   int iCur,          /* Cursor number for the table */
 | 
|  |    401 |   int count          /* Increment the row change counter */
 | 
|  |    402 | ){
 | 
|  |    403 |   int addr;
 | 
|  |    404 |   addr = sqlite3VdbeAddOp(v, OP_NotExists, iCur, 0);
 | 
|  |    405 |   sqlite3GenerateRowIndexDelete(v, pTab, iCur, 0);
 | 
|  |    406 |   sqlite3VdbeAddOp(v, OP_Delete, iCur, (count?OPFLAG_NCHANGE:0));
 | 
|  |    407 |   if( count ){
 | 
|  |    408 |     sqlite3VdbeChangeP3(v, -1, pTab->zName, P3_STATIC);
 | 
|  |    409 |   }
 | 
|  |    410 |   sqlite3VdbeJumpHere(v, addr);
 | 
|  |    411 | }
 | 
|  |    412 | 
 | 
|  |    413 | /*
 | 
|  |    414 | ** This routine generates VDBE code that causes the deletion of all
 | 
|  |    415 | ** index entries associated with a single row of a single table.
 | 
|  |    416 | **
 | 
|  |    417 | ** The VDBE must be in a particular state when this routine is called.
 | 
|  |    418 | ** These are the requirements:
 | 
|  |    419 | **
 | 
|  |    420 | **   1.  A read/write cursor pointing to pTab, the table containing the row
 | 
|  |    421 | **       to be deleted, must be opened as cursor number "iCur".
 | 
|  |    422 | **
 | 
|  |    423 | **   2.  Read/write cursors for all indices of pTab must be open as
 | 
|  |    424 | **       cursor number iCur+i for the i-th index.
 | 
|  |    425 | **
 | 
|  |    426 | **   3.  The "iCur" cursor must be pointing to the row that is to be
 | 
|  |    427 | **       deleted.
 | 
|  |    428 | */
 | 
|  |    429 | void sqlite3GenerateRowIndexDelete(
 | 
|  |    430 |   Vdbe *v,           /* Generate code into this VDBE */
 | 
|  |    431 |   Table *pTab,       /* Table containing the row to be deleted */
 | 
|  |    432 |   int iCur,          /* Cursor number for the table */
 | 
|  |    433 |   char *aIdxUsed     /* Only delete if aIdxUsed!=0 && aIdxUsed[i]!=0 */
 | 
|  |    434 | ){
 | 
|  |    435 |   int i;
 | 
|  |    436 |   Index *pIdx;
 | 
|  |    437 | 
 | 
|  |    438 |   for(i=1, pIdx=pTab->pIndex; pIdx; i++, pIdx=pIdx->pNext){
 | 
|  |    439 |     if( aIdxUsed!=0 && aIdxUsed[i-1]==0 ) continue;
 | 
|  |    440 |     sqlite3GenerateIndexKey(v, pIdx, iCur);
 | 
|  |    441 |     sqlite3VdbeAddOp(v, OP_IdxDelete, iCur+i, 0);
 | 
|  |    442 |   }
 | 
|  |    443 | }
 | 
|  |    444 | 
 | 
|  |    445 | /*
 | 
|  |    446 | ** Generate code that will assemble an index key and put it on the top
 | 
|  |    447 | ** of the tack.  The key with be for index pIdx which is an index on pTab.
 | 
|  |    448 | ** iCur is the index of a cursor open on the pTab table and pointing to
 | 
|  |    449 | ** the entry that needs indexing.
 | 
|  |    450 | */
 | 
|  |    451 | void sqlite3GenerateIndexKey(
 | 
|  |    452 |   Vdbe *v,           /* Generate code into this VDBE */
 | 
|  |    453 |   Index *pIdx,       /* The index for which to generate a key */
 | 
|  |    454 |   int iCur           /* Cursor number for the pIdx->pTable table */
 | 
|  |    455 | ){
 | 
|  |    456 |   int j;
 | 
|  |    457 |   Table *pTab = pIdx->pTable;
 | 
|  |    458 | 
 | 
|  |    459 |   sqlite3VdbeAddOp(v, OP_Rowid, iCur, 0);
 | 
|  |    460 |   for(j=0; j<pIdx->nColumn; j++){
 | 
|  |    461 |     int idx = pIdx->aiColumn[j];
 | 
|  |    462 |     if( idx==pTab->iPKey ){
 | 
|  |    463 |       sqlite3VdbeAddOp(v, OP_Dup, j, 0);
 | 
|  |    464 |     }else{
 | 
|  |    465 |       sqlite3VdbeAddOp(v, OP_Column, iCur, idx);
 | 
|  |    466 |       sqlite3ColumnDefault(v, pTab, idx);
 | 
|  |    467 |     }
 | 
|  |    468 |   }
 | 
|  |    469 |   sqlite3VdbeAddOp(v, OP_MakeIdxRec, pIdx->nColumn, 0);
 | 
|  |    470 |   sqlite3IndexAffinityStr(v, pIdx);
 | 
|  |    471 | }
 |