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.c,v 1.201 2009/05/01 21:13:37 drh Exp $ 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 struct SrcList_item *pItem = pSrc->a; 26 Table *pTab; 27 assert( pItem && pSrc->nSrc==1 ); 28 pTab = sqlite3LocateTable(pParse, 0, pItem->zName, pItem->zDatabase); 29 sqlite3DeleteTable(pItem->pTab); 30 pItem->pTab = pTab; 31 if( pTab ){ 32 pTab->nRef++; 33 } 34 if( sqlite3IndexedByLookup(pParse, pItem) ){ 35 pTab = 0; 36 } 37 return pTab; 38 } 39 40 /* 41 ** Check to make sure the given table is writable. If it is not 42 ** writable, generate an error message and return 1. If it is 43 ** writable return 0; 44 */ 45 int sqlite3IsReadOnly(Parse *pParse, Table *pTab, int viewOk){ 46 if( ((pTab->tabFlags & TF_Readonly)!=0 47 && (pParse->db->flags & SQLITE_WriteSchema)==0 48 && pParse->nested==0) 49 #ifndef SQLITE_OMIT_VIRTUALTABLE 50 || (pTab->pMod && pTab->pMod->pModule->xUpdate==0) 51 #endif 52 ){ 53 sqlite3ErrorMsg(pParse, "table %s may not be modified", pTab->zName); 54 return 1; 55 } 56 #ifndef SQLITE_OMIT_VIEW 57 if( !viewOk && pTab->pSelect ){ 58 sqlite3ErrorMsg(pParse,"cannot modify %s because it is a view",pTab->zName); 59 return 1; 60 } 61 #endif 62 return 0; 63 } 64 65 66 #if !defined(SQLITE_OMIT_VIEW) && !defined(SQLITE_OMIT_TRIGGER) 67 /* 68 ** Evaluate a view and store its result in an ephemeral table. The 69 ** pWhere argument is an optional WHERE clause that restricts the 70 ** set of rows in the view that are to be added to the ephemeral table. 71 */ 72 void sqlite3MaterializeView( 73 Parse *pParse, /* Parsing context */ 74 Table *pView, /* View definition */ 75 Expr *pWhere, /* Optional WHERE clause to be added */ 76 int iCur /* Cursor number for ephemerial table */ 77 ){ 78 SelectDest dest; 79 Select *pDup; 80 sqlite3 *db = pParse->db; 81 82 pDup = sqlite3SelectDup(db, pView->pSelect, 0); 83 if( pWhere ){ 84 SrcList *pFrom; 85 Token viewName; 86 87 pWhere = sqlite3ExprDup(db, pWhere, 0); 88 viewName.z = (u8*)pView->zName; 89 viewName.n = (unsigned int)sqlite3Strlen30((const char*)viewName.z); 90 viewName.quoted = 0; 91 pFrom = sqlite3SrcListAppendFromTerm(pParse, 0, 0, 0, &viewName, pDup, 0,0); 92 pDup = sqlite3SelectNew(pParse, 0, pFrom, pWhere, 0, 0, 0, 0, 0, 0); 93 } 94 sqlite3SelectDestInit(&dest, SRT_EphemTab, iCur); 95 sqlite3Select(pParse, pDup, &dest); 96 sqlite3SelectDelete(db, pDup); 97 } 98 #endif /* !defined(SQLITE_OMIT_VIEW) && !defined(SQLITE_OMIT_TRIGGER) */ 99 100 #if defined(SQLITE_ENABLE_UPDATE_DELETE_LIMIT) && !defined(SQLITE_OMIT_SUBQUERY) 101 /* 102 ** Generate an expression tree to implement the WHERE, ORDER BY, 103 ** and LIMIT/OFFSET portion of DELETE and UPDATE statements. 104 ** 105 ** DELETE FROM table_wxyz WHERE a<5 ORDER BY a LIMIT 1; 106 ** \__________________________/ 107 ** pLimitWhere (pInClause) 108 */ 109 Expr *sqlite3LimitWhere( 110 Parse *pParse, /* The parser context */ 111 SrcList *pSrc, /* the FROM clause -- which tables to scan */ 112 Expr *pWhere, /* The WHERE clause. May be null */ 113 ExprList *pOrderBy, /* The ORDER BY clause. May be null */ 114 Expr *pLimit, /* The LIMIT clause. May be null */ 115 Expr *pOffset, /* The OFFSET clause. May be null */ 116 char *zStmtType /* Either DELETE or UPDATE. For error messages. */ 117 ){ 118 Expr *pWhereRowid = NULL; /* WHERE rowid .. */ 119 Expr *pInClause = NULL; /* WHERE rowid IN ( select ) */ 120 Expr *pSelectRowid = NULL; /* SELECT rowid ... */ 121 ExprList *pEList = NULL; /* Expression list contaning only pSelectRowid */ 122 SrcList *pSelectSrc = NULL; /* SELECT rowid FROM x ... (dup of pSrc) */ 123 Select *pSelect = NULL; /* Complete SELECT tree */ 124 125 /* Check that there isn't an ORDER BY without a LIMIT clause. 126 */ 127 if( pOrderBy && (pLimit == 0) ) { 128 sqlite3ErrorMsg(pParse, "ORDER BY without LIMIT on %s", zStmtType); 129 pParse->parseError = 1; 130 goto limit_where_cleanup_2; 131 } 132 133 /* We only need to generate a select expression if there 134 ** is a limit/offset term to enforce. 135 */ 136 if( pLimit == 0 ) { 137 /* if pLimit is null, pOffset will always be null as well. */ 138 assert( pOffset == 0 ); 139 return pWhere; 140 } 141 142 /* Generate a select expression tree to enforce the limit/offset 143 ** term for the DELETE or UPDATE statement. For example: 144 ** DELETE FROM table_a WHERE col1=1 ORDER BY col2 LIMIT 1 OFFSET 1 145 ** becomes: 146 ** DELETE FROM table_a WHERE rowid IN ( 147 ** SELECT rowid FROM table_a WHERE col1=1 ORDER BY col2 LIMIT 1 OFFSET 1 148 ** ); 149 */ 150 151 pSelectRowid = sqlite3Expr(pParse->db, TK_ROW, 0, 0, 0); 152 if( pSelectRowid == 0 ) goto limit_where_cleanup_2; 153 pEList = sqlite3ExprListAppend(pParse, 0, pSelectRowid, 0); 154 if( pEList == 0 ) goto limit_where_cleanup_2; 155 156 /* duplicate the FROM clause as it is needed by both the DELETE/UPDATE tree 157 ** and the SELECT subtree. */ 158 pSelectSrc = sqlite3SrcListDup(pParse->db, pSrc, 0); 159 if( pSelectSrc == 0 ) { 160 sqlite3ExprListDelete(pParse->db, pEList); 161 goto limit_where_cleanup_2; 162 } 163 164 /* generate the SELECT expression tree. */ 165 pSelect = sqlite3SelectNew(pParse,pEList,pSelectSrc,pWhere,0,0, 166 pOrderBy,0,pLimit,pOffset); 167 if( pSelect == 0 ) return 0; 168 169 /* now generate the new WHERE rowid IN clause for the DELETE/UDPATE */ 170 pWhereRowid = sqlite3Expr(pParse->db, TK_ROW, 0, 0, 0); 171 if( pWhereRowid == 0 ) goto limit_where_cleanup_1; 172 pInClause = sqlite3PExpr(pParse, TK_IN, pWhereRowid, 0, 0); 173 if( pInClause == 0 ) goto limit_where_cleanup_1; 174 175 pInClause->x.pSelect = pSelect; 176 pInClause->flags |= EP_xIsSelect; 177 sqlite3ExprSetHeight(pParse, pInClause); 178 return pInClause; 179 180 /* something went wrong. clean up anything allocated. */ 181 limit_where_cleanup_1: 182 sqlite3SelectDelete(pParse->db, pSelect); 183 return 0; 184 185 limit_where_cleanup_2: 186 sqlite3ExprDelete(pParse->db, pWhere); 187 sqlite3ExprListDelete(pParse->db, pOrderBy); 188 sqlite3ExprDelete(pParse->db, pLimit); 189 sqlite3ExprDelete(pParse->db, pOffset); 190 return 0; 191 } 192 #endif /* defined(SQLITE_ENABLE_UPDATE_DELETE_LIMIT) && !defined(SQLITE_OMIT_SUBQUERY) */ 193 194 /* 195 ** Generate code for a DELETE FROM statement. 196 ** 197 ** DELETE FROM table_wxyz WHERE a<5 AND b NOT NULL; 198 ** \________/ \________________/ 199 ** pTabList pWhere 200 */ 201 void sqlite3DeleteFrom( 202 Parse *pParse, /* The parser context */ 203 SrcList *pTabList, /* The table from which we should delete things */ 204 Expr *pWhere /* The WHERE clause. May be null */ 205 ){ 206 Vdbe *v; /* The virtual database engine */ 207 Table *pTab; /* The table from which records will be deleted */ 208 const char *zDb; /* Name of database holding pTab */ 209 int end, addr = 0; /* A couple addresses of generated code */ 210 int i; /* Loop counter */ 211 WhereInfo *pWInfo; /* Information about the WHERE clause */ 212 Index *pIdx; /* For looping over indices of the table */ 213 int iCur; /* VDBE Cursor number for pTab */ 214 sqlite3 *db; /* Main database structure */ 215 AuthContext sContext; /* Authorization context */ 216 int oldIdx = -1; /* Cursor for the OLD table of AFTER triggers */ 217 NameContext sNC; /* Name context to resolve expressions in */ 218 int iDb; /* Database number */ 219 int memCnt = -1; /* Memory cell used for change counting */ 220 int rcauth; /* Value returned by authorization callback */ 221 222 #ifndef SQLITE_OMIT_TRIGGER 223 int isView; /* True if attempting to delete from a view */ 224 Trigger *pTrigger; /* List of table triggers, if required */ 225 #endif 226 int iBeginAfterTrigger = 0; /* Address of after trigger program */ 227 int iEndAfterTrigger = 0; /* Exit of after trigger program */ 228 int iBeginBeforeTrigger = 0; /* Address of before trigger program */ 229 int iEndBeforeTrigger = 0; /* Exit of before trigger program */ 230 u32 old_col_mask = 0; /* Mask of OLD.* columns in use */ 231 232 sContext.pParse = 0; 233 db = pParse->db; 234 if( pParse->nErr || db->mallocFailed ){ 235 goto delete_from_cleanup; 236 } 237 assert( pTabList->nSrc==1 ); 238 239 /* Locate the table which we want to delete. This table has to be 240 ** put in an SrcList structure because some of the subroutines we 241 ** will be calling are designed to work with multiple tables and expect 242 ** an SrcList* parameter instead of just a Table* parameter. 243 */ 244 pTab = sqlite3SrcListLookup(pParse, pTabList); 245 if( pTab==0 ) goto delete_from_cleanup; 246 247 /* Figure out if we have any triggers and if the table being 248 ** deleted from is a view 249 */ 250 #ifndef SQLITE_OMIT_TRIGGER 251 pTrigger = sqlite3TriggersExist(pParse, pTab, TK_DELETE, 0, 0); 252 isView = pTab->pSelect!=0; 253 #else 254 # define pTrigger 0 255 # define isView 0 256 #endif 257 #ifdef SQLITE_OMIT_VIEW 258 # undef isView 259 # define isView 0 260 #endif 261 262 if( sqlite3IsReadOnly(pParse, pTab, (pTrigger?1:0)) ){ 263 goto delete_from_cleanup; 264 } 265 iDb = sqlite3SchemaToIndex(db, pTab->pSchema); 266 assert( iDb<db->nDb ); 267 zDb = db->aDb[iDb].zName; 268 rcauth = sqlite3AuthCheck(pParse, SQLITE_DELETE, pTab->zName, 0, zDb); 269 assert( rcauth==SQLITE_OK || rcauth==SQLITE_DENY || rcauth==SQLITE_IGNORE ); 270 if( rcauth==SQLITE_DENY ){ 271 goto delete_from_cleanup; 272 } 273 assert(!isView || pTrigger); 274 275 /* If pTab is really a view, make sure it has been initialized. 276 */ 277 if( sqlite3ViewGetColumnNames(pParse, pTab) ){ 278 goto delete_from_cleanup; 279 } 280 281 /* Allocate a cursor used to store the old.* data for a trigger. 282 */ 283 if( pTrigger ){ 284 oldIdx = pParse->nTab++; 285 } 286 287 /* Assign cursor number to the table and all its indices. 288 */ 289 assert( pTabList->nSrc==1 ); 290 iCur = pTabList->a[0].iCursor = pParse->nTab++; 291 for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){ 292 pParse->nTab++; 293 } 294 295 /* Start the view context 296 */ 297 if( isView ){ 298 sqlite3AuthContextPush(pParse, &sContext, pTab->zName); 299 } 300 301 /* Begin generating code. 302 */ 303 v = sqlite3GetVdbe(pParse); 304 if( v==0 ){ 305 goto delete_from_cleanup; 306 } 307 if( pParse->nested==0 ) sqlite3VdbeCountChanges(v); 308 sqlite3BeginWriteOperation(pParse, (pTrigger?1:0), iDb); 309 310 if( pTrigger ){ 311 int orconf = ((pParse->trigStack)?pParse->trigStack->orconf:OE_Default); 312 int iGoto = sqlite3VdbeAddOp0(v, OP_Goto); 313 addr = sqlite3VdbeMakeLabel(v); 314 315 iBeginBeforeTrigger = sqlite3VdbeCurrentAddr(v); 316 (void)sqlite3CodeRowTrigger(pParse, pTrigger, TK_DELETE, 0, 317 TRIGGER_BEFORE, pTab, -1, oldIdx, orconf, addr, &old_col_mask, 0); 318 iEndBeforeTrigger = sqlite3VdbeAddOp0(v, OP_Goto); 319 320 iBeginAfterTrigger = sqlite3VdbeCurrentAddr(v); 321 (void)sqlite3CodeRowTrigger(pParse, pTrigger, TK_DELETE, 0, 322 TRIGGER_AFTER, pTab, -1, oldIdx, orconf, addr, &old_col_mask, 0); 323 iEndAfterTrigger = sqlite3VdbeAddOp0(v, OP_Goto); 324 325 sqlite3VdbeJumpHere(v, iGoto); 326 } 327 328 /* If we are trying to delete from a view, realize that view into 329 ** a ephemeral table. 330 */ 331 #if !defined(SQLITE_OMIT_VIEW) && !defined(SQLITE_OMIT_TRIGGER) 332 if( isView ){ 333 sqlite3MaterializeView(pParse, pTab, pWhere, iCur); 334 } 335 #endif 336 337 /* Resolve the column names in the WHERE clause. 338 */ 339 memset(&sNC, 0, sizeof(sNC)); 340 sNC.pParse = pParse; 341 sNC.pSrcList = pTabList; 342 if( sqlite3ResolveExprNames(&sNC, pWhere) ){ 343 goto delete_from_cleanup; 344 } 345 346 /* Initialize the counter of the number of rows deleted, if 347 ** we are counting rows. 348 */ 349 if( db->flags & SQLITE_CountRows ){ 350 memCnt = ++pParse->nMem; 351 sqlite3VdbeAddOp2(v, OP_Integer, 0, memCnt); 352 } 353 354 #ifndef SQLITE_OMIT_TRUNCATE_OPTIMIZATION 355 /* Special case: A DELETE without a WHERE clause deletes everything. 356 ** It is easier just to erase the whole table. Note, however, that 357 ** this means that the row change count will be incorrect. 358 */ 359 if( rcauth==SQLITE_OK && pWhere==0 && !pTrigger && !IsVirtual(pTab) ){ 360 assert( !isView ); 361 sqlite3VdbeAddOp4(v, OP_Clear, pTab->tnum, iDb, memCnt, 362 pTab->zName, P4_STATIC); 363 for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){ 364 assert( pIdx->pSchema==pTab->pSchema ); 365 sqlite3VdbeAddOp2(v, OP_Clear, pIdx->tnum, iDb); 366 } 367 }else 368 #endif /* SQLITE_OMIT_TRUNCATE_OPTIMIZATION */ 369 /* The usual case: There is a WHERE clause so we have to scan through 370 ** the table and pick which records to delete. 371 */ 372 { 373 int iRowid = ++pParse->nMem; /* Used for storing rowid values. */ 374 int iRowSet = ++pParse->nMem; /* Register for rowset of rows to delete */ 375 int regRowid; /* Actual register containing rowids */ 376 377 /* Collect rowids of every row to be deleted. 378 */ 379 sqlite3VdbeAddOp2(v, OP_Null, 0, iRowSet); 380 pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere,0,WHERE_DUPLICATES_OK); 381 if( pWInfo==0 ) goto delete_from_cleanup; 382 regRowid = sqlite3ExprCodeGetColumn(pParse, pTab, -1, iCur, iRowid, 0); 383 sqlite3VdbeAddOp2(v, OP_RowSetAdd, iRowSet, regRowid); 384 if( db->flags & SQLITE_CountRows ){ 385 sqlite3VdbeAddOp2(v, OP_AddImm, memCnt, 1); 386 } 387 sqlite3WhereEnd(pWInfo); 388 389 /* Open the pseudo-table used to store OLD if there are triggers. 390 */ 391 if( pTrigger ){ 392 sqlite3VdbeAddOp3(v, OP_OpenPseudo, oldIdx, 0, pTab->nCol); 393 } 394 395 /* Delete every item whose key was written to the list during the 396 ** database scan. We have to delete items after the scan is complete 397 ** because deleting an item can change the scan order. 398 */ 399 end = sqlite3VdbeMakeLabel(v); 400 401 if( !isView ){ 402 /* Open cursors for the table we are deleting from and 403 ** all its indices. 404 */ 405 sqlite3OpenTableAndIndices(pParse, pTab, iCur, OP_OpenWrite); 406 } 407 408 /* This is the beginning of the delete loop. If a trigger encounters 409 ** an IGNORE constraint, it jumps back to here. 410 */ 411 if( pTrigger ){ 412 sqlite3VdbeResolveLabel(v, addr); 413 } 414 addr = sqlite3VdbeAddOp3(v, OP_RowSetRead, iRowSet, end, iRowid); 415 416 if( pTrigger ){ 417 int iData = ++pParse->nMem; /* For storing row data of OLD table */ 418 419 /* If the record is no longer present in the table, jump to the 420 ** next iteration of the loop through the contents of the fifo. 421 */ 422 sqlite3VdbeAddOp3(v, OP_NotExists, iCur, addr, iRowid); 423 424 /* Populate the OLD.* pseudo-table */ 425 if( old_col_mask ){ 426 sqlite3VdbeAddOp2(v, OP_RowData, iCur, iData); 427 }else{ 428 sqlite3VdbeAddOp2(v, OP_Null, 0, iData); 429 } 430 sqlite3VdbeAddOp3(v, OP_Insert, oldIdx, iData, iRowid); 431 432 /* Jump back and run the BEFORE triggers */ 433 sqlite3VdbeAddOp2(v, OP_Goto, 0, iBeginBeforeTrigger); 434 sqlite3VdbeJumpHere(v, iEndBeforeTrigger); 435 } 436 437 if( !isView ){ 438 /* Delete the row */ 439 #ifndef SQLITE_OMIT_VIRTUALTABLE 440 if( IsVirtual(pTab) ){ 441 const char *pVtab = (const char *)pTab->pVtab; 442 sqlite3VtabMakeWritable(pParse, pTab); 443 sqlite3VdbeAddOp4(v, OP_VUpdate, 0, 1, iRowid, pVtab, P4_VTAB); 444 }else 445 #endif 446 { 447 sqlite3GenerateRowDelete(pParse, pTab, iCur, iRowid, pParse->nested==0); 448 } 449 } 450 451 /* If there are row triggers, close all cursors then invoke 452 ** the AFTER triggers 453 */ 454 if( pTrigger ){ 455 /* Jump back and run the AFTER triggers */ 456 sqlite3VdbeAddOp2(v, OP_Goto, 0, iBeginAfterTrigger); 457 sqlite3VdbeJumpHere(v, iEndAfterTrigger); 458 } 459 460 /* End of the delete loop */ 461 sqlite3VdbeAddOp2(v, OP_Goto, 0, addr); 462 sqlite3VdbeResolveLabel(v, end); 463 464 /* Close the cursors after the loop if there are no row triggers */ 465 if( !isView && !IsVirtual(pTab) ){ 466 for(i=1, pIdx=pTab->pIndex; pIdx; i++, pIdx=pIdx->pNext){ 467 sqlite3VdbeAddOp2(v, OP_Close, iCur + i, pIdx->tnum); 468 } 469 sqlite3VdbeAddOp1(v, OP_Close, iCur); 470 } 471 } 472 473 /* 474 ** Return the number of rows that were deleted. If this routine is 475 ** generating code because of a call to sqlite3NestedParse(), do not 476 ** invoke the callback function. 477 */ 478 if( db->flags & SQLITE_CountRows && pParse->nested==0 && !pParse->trigStack ){ 479 sqlite3VdbeAddOp2(v, OP_ResultRow, memCnt, 1); 480 sqlite3VdbeSetNumCols(v, 1); 481 sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "rows deleted", SQLITE_STATIC); 482 } 483 484 delete_from_cleanup: 485 sqlite3AuthContextPop(&sContext); 486 sqlite3SrcListDelete(db, pTabList); 487 sqlite3ExprDelete(db, pWhere); 488 return; 489 } 490 491 /* 492 ** This routine generates VDBE code that causes a single row of a 493 ** single table to be deleted. 494 ** 495 ** The VDBE must be in a particular state when this routine is called. 496 ** These are the requirements: 497 ** 498 ** 1. A read/write cursor pointing to pTab, the table containing the row 499 ** to be deleted, must be opened as cursor number "base". 500 ** 501 ** 2. Read/write cursors for all indices of pTab must be open as 502 ** cursor number base+i for the i-th index. 503 ** 504 ** 3. The record number of the row to be deleted must be stored in 505 ** memory cell iRowid. 506 ** 507 ** This routine pops the top of the stack to remove the record number 508 ** and then generates code to remove both the table record and all index 509 ** entries that point to that record. 510 */ 511 void sqlite3GenerateRowDelete( 512 Parse *pParse, /* Parsing context */ 513 Table *pTab, /* Table containing the row to be deleted */ 514 int iCur, /* Cursor number for the table */ 515 int iRowid, /* Memory cell that contains the rowid to delete */ 516 int count /* Increment the row change counter */ 517 ){ 518 int addr; 519 Vdbe *v; 520 521 v = pParse->pVdbe; 522 addr = sqlite3VdbeAddOp3(v, OP_NotExists, iCur, 0, iRowid); 523 sqlite3GenerateRowIndexDelete(pParse, pTab, iCur, 0); 524 sqlite3VdbeAddOp2(v, OP_Delete, iCur, (count?OPFLAG_NCHANGE:0)); 525 if( count ){ 526 sqlite3VdbeChangeP4(v, -1, pTab->zName, P4_STATIC); 527 } 528 sqlite3VdbeJumpHere(v, addr); 529 } 530 531 /* 532 ** This routine generates VDBE code that causes the deletion of all 533 ** index entries associated with a single row of a single table. 534 ** 535 ** The VDBE must be in a particular state when this routine is called. 536 ** These are the requirements: 537 ** 538 ** 1. A read/write cursor pointing to pTab, the table containing the row 539 ** to be deleted, must be opened as cursor number "iCur". 540 ** 541 ** 2. Read/write cursors for all indices of pTab must be open as 542 ** cursor number iCur+i for the i-th index. 543 ** 544 ** 3. The "iCur" cursor must be pointing to the row that is to be 545 ** deleted. 546 */ 547 void sqlite3GenerateRowIndexDelete( 548 Parse *pParse, /* Parsing and code generating context */ 549 Table *pTab, /* Table containing the row to be deleted */ 550 int iCur, /* Cursor number for the table */ 551 int *aRegIdx /* Only delete if aRegIdx!=0 && aRegIdx[i]>0 */ 552 ){ 553 int i; 554 Index *pIdx; 555 int r1; 556 557 for(i=1, pIdx=pTab->pIndex; pIdx; i++, pIdx=pIdx->pNext){ 558 if( aRegIdx!=0 && aRegIdx[i-1]==0 ) continue; 559 r1 = sqlite3GenerateIndexKey(pParse, pIdx, iCur, 0, 0); 560 sqlite3VdbeAddOp3(pParse->pVdbe, OP_IdxDelete, iCur+i, r1,pIdx->nColumn+1); 561 } 562 } 563 564 /* 565 ** Generate code that will assemble an index key and put it in register 566 ** regOut. The key with be for index pIdx which is an index on pTab. 567 ** iCur is the index of a cursor open on the pTab table and pointing to 568 ** the entry that needs indexing. 569 ** 570 ** Return a register number which is the first in a block of 571 ** registers that holds the elements of the index key. The 572 ** block of registers has already been deallocated by the time 573 ** this routine returns. 574 */ 575 int sqlite3GenerateIndexKey( 576 Parse *pParse, /* Parsing context */ 577 Index *pIdx, /* The index for which to generate a key */ 578 int iCur, /* Cursor number for the pIdx->pTable table */ 579 int regOut, /* Write the new index key to this register */ 580 int doMakeRec /* Run the OP_MakeRecord instruction if true */ 581 ){ 582 Vdbe *v = pParse->pVdbe; 583 int j; 584 Table *pTab = pIdx->pTable; 585 int regBase; 586 int nCol; 587 588 nCol = pIdx->nColumn; 589 regBase = sqlite3GetTempRange(pParse, nCol+1); 590 sqlite3VdbeAddOp2(v, OP_Rowid, iCur, regBase+nCol); 591 for(j=0; j<nCol; j++){ 592 int idx = pIdx->aiColumn[j]; 593 if( idx==pTab->iPKey ){ 594 sqlite3VdbeAddOp2(v, OP_SCopy, regBase+nCol, regBase+j); 595 }else{ 596 sqlite3VdbeAddOp3(v, OP_Column, iCur, idx, regBase+j); 597 sqlite3ColumnDefault(v, pTab, idx); 598 } 599 } 600 if( doMakeRec ){ 601 sqlite3VdbeAddOp3(v, OP_MakeRecord, regBase, nCol+1, regOut); 602 sqlite3IndexAffinityStr(v, pIdx); 603 sqlite3ExprCacheAffinityChange(pParse, regBase, nCol+1); 604 } 605 sqlite3ReleaseTempRange(pParse, regBase, nCol+1); 606 return regBase; 607 } 608 609 /* Make sure "isView" gets undefined in case this file becomes part of 610 ** the amalgamation - so that subsequent files do not see isView as a 611 ** macro. */ 612 #undef isView 613