AryaWu/sqlite
0
1/*2** 2001 September 153**4** The author disclaims copyright to this source code. In place of5** 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 parser13** in order to generate code for DELETE FROM statements.14*/15#include "sqliteInt.h"16 17/*18** While a SrcList can in general represent multiple tables and subqueries19** (as in the FROM clause of a SELECT statement) in this case it contains20** the name of a single table, as one might find in an INSERT, DELETE,21** or UPDATE statement. Look up that table in the symbol table and22** return a pointer. Set an error message and return NULL if the table23** name is not found or if any other error occurs.24**25** The following fields are initialized appropriate in pSrc:26**27** pSrc->a[0].spTab Pointer to the Table object28** pSrc->a[0].u2.pIBIndex Pointer to the INDEXED BY index, if there is one29**30*/31Table *sqlite3SrcListLookup(Parse *pParse, SrcList *pSrc){32 SrcItem *pItem = pSrc->a;33 Table *pTab;34 assert( pItem && pSrc->nSrc>=1 );35 pTab = sqlite3LocateTableItem(pParse, 0, pItem);36 if( pItem->pSTab ) sqlite3DeleteTable(pParse->db, pItem->pSTab);37 pItem->pSTab = pTab;38 pItem->fg.notCte = 1;39 if( pTab ){40 pTab->nTabRef++;41 if( pItem->fg.isIndexedBy && sqlite3IndexedByLookup(pParse, pItem) ){42 pTab = 0;43 }44 }45 return pTab;46}47 48/* Generate byte-code that will report the number of rows modified49** by a DELETE, INSERT, or UPDATE statement.50*/51void sqlite3CodeChangeCount(Vdbe *v, int regCounter, const char *zColName){52 sqlite3VdbeAddOp0(v, OP_FkCheck);53 sqlite3VdbeAddOp2(v, OP_ResultRow, regCounter, 1);54 sqlite3VdbeSetNumCols(v, 1);55 sqlite3VdbeSetColName(v, 0, COLNAME_NAME, zColName, SQLITE_STATIC);56}57 58/* Return true if table pTab is read-only.59**60** A table is read-only if any of the following are true:61**62** 1) It is a virtual table and no implementation of the xUpdate method63** has been provided64**65** 2) A trigger is currently being coded and the table is a virtual table66** that is SQLITE_VTAB_DIRECTONLY or if PRAGMA trusted_schema=OFF and67** the table is not SQLITE_VTAB_INNOCUOUS.68**69** 3) It is a system table (i.e. sqlite_schema), this call is not70** part of a nested parse and writable_schema pragma has not71** been specified72**73** 4) The table is a shadow table, the database connection is in74** defensive mode, and the current sqlite3_prepare()75** is for a top-level SQL statement.76*/77static int vtabIsReadOnly(Parse *pParse, Table *pTab){78 assert( IsVirtual(pTab) );79 if( sqlite3GetVTable(pParse->db, pTab)->pMod->pModule->xUpdate==0 ){80 return 1;81 }82 83 /* Within triggers:84 ** * Do not allow DELETE, INSERT, or UPDATE of SQLITE_VTAB_DIRECTONLY85 ** virtual tables86 ** * Only allow DELETE, INSERT, or UPDATE of non-SQLITE_VTAB_INNOCUOUS87 ** virtual tables if PRAGMA trusted_schema=ON.88 */89 if( pParse->pToplevel!=090 && pTab->u.vtab.p->eVtabRisk >91 ((pParse->db->flags & SQLITE_TrustedSchema)!=0)92 ){93 sqlite3ErrorMsg(pParse, "unsafe use of virtual table \"%s\"",94 pTab->zName);95 }96 return 0;97}98static int tabIsReadOnly(Parse *pParse, Table *pTab){99 sqlite3 *db;100 if( IsVirtual(pTab) ){101 return vtabIsReadOnly(pParse, pTab);102 }103 if( (pTab->tabFlags & (TF_Readonly|TF_Shadow))==0 ) return 0;104 db = pParse->db;105 if( (pTab->tabFlags & TF_Readonly)!=0 ){106 return sqlite3WritableSchema(db)==0 && pParse->nested==0;107 }108 assert( pTab->tabFlags & TF_Shadow );109 return sqlite3ReadOnlyShadowTables(db);110}111 112/*113** Check to make sure the given table is writable.114**115** If pTab is not writable -> generate an error message and return 1.116** If pTab is writable but other errors have occurred -> return 1.117** If pTab is writable and no prior errors -> return 0;118*/119int sqlite3IsReadOnly(Parse *pParse, Table *pTab, Trigger *pTrigger){120 if( tabIsReadOnly(pParse, pTab) ){121 sqlite3ErrorMsg(pParse, "table %s may not be modified", pTab->zName);122 return 1;123 }124#ifndef SQLITE_OMIT_VIEW125 if( IsView(pTab)126 && (pTrigger==0 || (pTrigger->bReturning && pTrigger->pNext==0))127 ){128 sqlite3ErrorMsg(pParse,"cannot modify %s because it is a view",pTab->zName);129 return 1;130 }131#endif132 return 0;133}134 135 136#if !defined(SQLITE_OMIT_VIEW) && !defined(SQLITE_OMIT_TRIGGER)137/*138** Evaluate a view and store its result in an ephemeral table. The139** pWhere argument is an optional WHERE clause that restricts the140** set of rows in the view that are to be added to the ephemeral table.141*/142void sqlite3MaterializeView(143 Parse *pParse, /* Parsing context */144 Table *pView, /* View definition */145 Expr *pWhere, /* Optional WHERE clause to be added */146 ExprList *pOrderBy, /* Optional ORDER BY clause */147 Expr *pLimit, /* Optional LIMIT clause */148 int iCur /* Cursor number for ephemeral table */149){150 SelectDest dest;151 Select *pSel;152 SrcList *pFrom;153 sqlite3 *db = pParse->db;154 int iDb = sqlite3SchemaToIndex(db, pView->pSchema);155 pWhere = sqlite3ExprDup(db, pWhere, 0);156 pFrom = sqlite3SrcListAppend(pParse, 0, 0, 0);157 if( pFrom ){158 assert( pFrom->nSrc==1 );159 pFrom->a[0].zName = sqlite3DbStrDup(db, pView->zName);160 assert( pFrom->a[0].fg.fixedSchema==0 && pFrom->a[0].fg.isSubquery==0 );161 pFrom->a[0].u4.zDatabase = sqlite3DbStrDup(db, db->aDb[iDb].zDbSName);162 assert( pFrom->a[0].fg.isUsing==0 );163 assert( pFrom->a[0].u3.pOn==0 );164 }165 pSel = sqlite3SelectNew(pParse, 0, pFrom, pWhere, 0, 0, pOrderBy,166 SF_IncludeHidden, pLimit);167 sqlite3SelectDestInit(&dest, SRT_EphemTab, iCur);168 sqlite3Select(pParse, pSel, &dest);169 sqlite3SelectDelete(db, pSel);170}171#endif /* !defined(SQLITE_OMIT_VIEW) && !defined(SQLITE_OMIT_TRIGGER) */172 173#if defined(SQLITE_ENABLE_UPDATE_DELETE_LIMIT) && !defined(SQLITE_OMIT_SUBQUERY)174/*175** Generate an expression tree to implement the WHERE, ORDER BY,176** and LIMIT/OFFSET portion of DELETE and UPDATE statements.177**178** DELETE FROM table_wxyz WHERE a<5 ORDER BY a LIMIT 1;179** \__________________________/180** pLimitWhere (pInClause)181*/182Expr *sqlite3LimitWhere(183 Parse *pParse, /* The parser context */184 SrcList *pSrc, /* the FROM clause -- which tables to scan */185 Expr *pWhere, /* The WHERE clause. May be null */186 ExprList *pOrderBy, /* The ORDER BY clause. May be null */187 Expr *pLimit, /* The LIMIT clause. May be null */188 char *zStmtType /* Either DELETE or UPDATE. For err msgs. */189){190 sqlite3 *db = pParse->db;191 Expr *pLhs = NULL; /* LHS of IN(SELECT...) operator */192 Expr *pInClause = NULL; /* WHERE rowid IN ( select ) */193 ExprList *pEList = NULL; /* Expression list containing only pSelectRowid*/194 SrcList *pSelectSrc = NULL; /* SELECT rowid FROM x ... (dup of pSrc) */195 Select *pSelect = NULL; /* Complete SELECT tree */196 Table *pTab;197 198 /* Check that there isn't an ORDER BY without a LIMIT clause.199 */200 if( pOrderBy && pLimit==0 ) {201 sqlite3ErrorMsg(pParse, "ORDER BY without LIMIT on %s", zStmtType);202 sqlite3ExprDelete(pParse->db, pWhere);203 sqlite3ExprListDelete(pParse->db, pOrderBy);204 return 0;205 }206 207 /* We only need to generate a select expression if there208 ** is a limit/offset term to enforce.209 */210 if( pLimit == 0 ) {211 return pWhere;212 }213 214 /* Generate a select expression tree to enforce the limit/offset215 ** term for the DELETE or UPDATE statement. For example:216 ** DELETE FROM table_a WHERE col1=1 ORDER BY col2 LIMIT 1 OFFSET 1217 ** becomes:218 ** DELETE FROM table_a WHERE rowid IN (219 ** SELECT rowid FROM table_a WHERE col1=1 ORDER BY col2 LIMIT 1 OFFSET 1220 ** );221 */222 223 pTab = pSrc->a[0].pSTab;224 if( HasRowid(pTab) ){225 pLhs = sqlite3PExpr(pParse, TK_ROW, 0, 0);226 pEList = sqlite3ExprListAppend(227 pParse, 0, sqlite3PExpr(pParse, TK_ROW, 0, 0)228 );229 }else{230 Index *pPk = sqlite3PrimaryKeyIndex(pTab);231 assert( pPk!=0 );232 assert( pPk->nKeyCol>=1 );233 if( pPk->nKeyCol==1 ){234 const char *zName;235 assert( pPk->aiColumn[0]>=0 && pPk->aiColumn[0]<pTab->nCol );236 zName = pTab->aCol[pPk->aiColumn[0]].zCnName;237 pLhs = sqlite3Expr(db, TK_ID, zName);238 pEList = sqlite3ExprListAppend(pParse, 0, sqlite3Expr(db, TK_ID, zName));239 }else{240 int i;241 for(i=0; i<pPk->nKeyCol; i++){242 Expr *p;243 assert( pPk->aiColumn[i]>=0 && pPk->aiColumn[i]<pTab->nCol );244 p = sqlite3Expr(db, TK_ID, pTab->aCol[pPk->aiColumn[i]].zCnName);245 pEList = sqlite3ExprListAppend(pParse, pEList, p);246 }247 pLhs = sqlite3PExpr(pParse, TK_VECTOR, 0, 0);248 if( pLhs ){249 pLhs->x.pList = sqlite3ExprListDup(db, pEList, 0);250 }251 }252 }253 254 /* duplicate the FROM clause as it is needed by both the DELETE/UPDATE tree255 ** and the SELECT subtree. */256 pSrc->a[0].pSTab = 0;257 pSelectSrc = sqlite3SrcListDup(db, pSrc, 0);258 pSrc->a[0].pSTab = pTab;259 if( pSrc->a[0].fg.isIndexedBy ){260 assert( pSrc->a[0].fg.isCte==0 );261 pSrc->a[0].u2.pIBIndex = 0;262 pSrc->a[0].fg.isIndexedBy = 0;263 sqlite3DbFree(db, pSrc->a[0].u1.zIndexedBy);264 }else if( pSrc->a[0].fg.isCte ){265 pSrc->a[0].u2.pCteUse->nUse++;266 }267 268 /* generate the SELECT expression tree. */269 pSelect = sqlite3SelectNew(pParse, pEList, pSelectSrc, pWhere, 0 ,0,270 pOrderBy,0,pLimit271 );272 273 /* now generate the new WHERE rowid IN clause for the DELETE/UPDATE */274 pInClause = sqlite3PExpr(pParse, TK_IN, pLhs, 0);275 sqlite3PExprAddSelect(pParse, pInClause, pSelect);276 return pInClause;277}278#endif /* defined(SQLITE_ENABLE_UPDATE_DELETE_LIMIT) */279 /* && !defined(SQLITE_OMIT_SUBQUERY) */280 281/*282** Generate code for a DELETE FROM statement.283**284** DELETE FROM table_wxyz WHERE a<5 AND b NOT NULL;285** \________/ \________________/286** pTabList pWhere287*/288void sqlite3DeleteFrom(289 Parse *pParse, /* The parser context */290 SrcList *pTabList, /* The table from which we should delete things */291 Expr *pWhere, /* The WHERE clause. May be null */292 ExprList *pOrderBy, /* ORDER BY clause. May be null */293 Expr *pLimit /* LIMIT clause. May be null */294){295 Vdbe *v; /* The virtual database engine */296 Table *pTab; /* The table from which records will be deleted */297 int i; /* Loop counter */298 WhereInfo *pWInfo; /* Information about the WHERE clause */299 Index *pIdx; /* For looping over indices of the table */300 int iTabCur; /* Cursor number for the table */301 int iDataCur = 0; /* VDBE cursor for the canonical data source */302 int iIdxCur = 0; /* Cursor number of the first index */303 int nIdx; /* Number of indices */304 sqlite3 *db; /* Main database structure */305 AuthContext sContext; /* Authorization context */306 NameContext sNC; /* Name context to resolve expressions in */307 int iDb; /* Database number */308 int memCnt = 0; /* Memory cell used for change counting */309 int rcauth; /* Value returned by authorization callback */310 int eOnePass; /* ONEPASS_OFF or _SINGLE or _MULTI */311 int aiCurOnePass[2]; /* The write cursors opened by WHERE_ONEPASS */312 u8 *aToOpen = 0; /* Open cursor iTabCur+j if aToOpen[j] is true */313 Index *pPk; /* The PRIMARY KEY index on the table */314 int iPk = 0; /* First of nPk registers holding PRIMARY KEY value */315 i16 nPk = 1; /* Number of columns in the PRIMARY KEY */316 int iKey; /* Memory cell holding key of row to be deleted */317 i16 nKey; /* Number of memory cells in the row key */318 int iEphCur = 0; /* Ephemeral table holding all primary key values */319 int iRowSet = 0; /* Register for rowset of rows to delete */320 int addrBypass = 0; /* Address of jump over the delete logic */321 int addrLoop = 0; /* Top of the delete loop */322 int addrEphOpen = 0; /* Instruction to open the Ephemeral table */323 int bComplex; /* True if there are triggers or FKs or324 ** subqueries in the WHERE clause */325 326#ifndef SQLITE_OMIT_TRIGGER327 int isView; /* True if attempting to delete from a view */328 Trigger *pTrigger; /* List of table triggers, if required */329#endif330 331 memset(&sContext, 0, sizeof(sContext));332 db = pParse->db;333 assert( db->pParse==pParse );334 if( pParse->nErr ){335 goto delete_from_cleanup;336 }337 assert( db->mallocFailed==0 );338 assert( pTabList->nSrc==1 );339 340 /* Locate the table which we want to delete. This table has to be341 ** put in an SrcList structure because some of the subroutines we342 ** will be calling are designed to work with multiple tables and expect343 ** an SrcList* parameter instead of just a Table* parameter.344 */345 pTab = sqlite3SrcListLookup(pParse, pTabList);346 if( pTab==0 ) goto delete_from_cleanup;347 348 /* Figure out if we have any triggers and if the table being349 ** deleted from is a view350 */351#ifndef SQLITE_OMIT_TRIGGER352 pTrigger = sqlite3TriggersExist(pParse, pTab, TK_DELETE, 0, 0);353 isView = IsView(pTab);354#else355# define pTrigger 0356# define isView 0357#endif358 bComplex = pTrigger || sqlite3FkRequired(pParse, pTab, 0, 0);359#ifdef SQLITE_OMIT_VIEW360# undef isView361# define isView 0362#endif363 364#if TREETRACE_ENABLED365 if( sqlite3TreeTrace & 0x10000 ){366 sqlite3TreeViewLine(0, "In sqlite3Delete() at %s:%d", __FILE__, __LINE__);367 sqlite3TreeViewDelete(pParse->pWith, pTabList, pWhere,368 pOrderBy, pLimit, pTrigger);369 }370#endif371 372#ifdef SQLITE_ENABLE_UPDATE_DELETE_LIMIT373 if( !isView ){374 pWhere = sqlite3LimitWhere(375 pParse, pTabList, pWhere, pOrderBy, pLimit, "DELETE"376 );377 pOrderBy = 0;378 pLimit = 0;379 }380#endif381 382 /* If pTab is really a view, make sure it has been initialized.383 */384 if( sqlite3ViewGetColumnNames(pParse, pTab) ){385 goto delete_from_cleanup;386 }387 388 if( sqlite3IsReadOnly(pParse, pTab, pTrigger) ){389 goto delete_from_cleanup;390 }391 iDb = sqlite3SchemaToIndex(db, pTab->pSchema);392 assert( iDb<db->nDb );393 rcauth = sqlite3AuthCheck(pParse, SQLITE_DELETE, pTab->zName, 0,394 db->aDb[iDb].zDbSName);395 assert( rcauth==SQLITE_OK || rcauth==SQLITE_DENY || rcauth==SQLITE_IGNORE );396 if( rcauth==SQLITE_DENY ){397 goto delete_from_cleanup;398 }399 assert(!isView || pTrigger);400 401 /* Assign cursor numbers to the table and all its indices.402 */403 assert( pTabList->nSrc==1 );404 iTabCur = pTabList->a[0].iCursor = pParse->nTab++;405 for(nIdx=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, nIdx++){406 pParse->nTab++;407 }408 409 /* Start the view context410 */411 if( isView ){412 sqlite3AuthContextPush(pParse, &sContext, pTab->zName);413 }414 415 /* Begin generating code.416 */417 v = sqlite3GetVdbe(pParse);418 if( v==0 ){419 goto delete_from_cleanup;420 }421 if( pParse->nested==0 ) sqlite3VdbeCountChanges(v);422 sqlite3BeginWriteOperation(pParse, bComplex, iDb);423 424 /* If we are trying to delete from a view, realize that view into425 ** an ephemeral table.426 */427#if !defined(SQLITE_OMIT_VIEW) && !defined(SQLITE_OMIT_TRIGGER)428 if( isView ){429 sqlite3MaterializeView(pParse, pTab,430 pWhere, pOrderBy, pLimit, iTabCur431 );432 iDataCur = iIdxCur = iTabCur;433 pOrderBy = 0;434 pLimit = 0;435 }436#endif437 438 /* Resolve the column names in the WHERE clause.439 */440 memset(&sNC, 0, sizeof(sNC));441 sNC.pParse = pParse;442 sNC.pSrcList = pTabList;443 if( sqlite3ResolveExprNames(&sNC, pWhere) ){444 goto delete_from_cleanup;445 }446 447 /* Initialize the counter of the number of rows deleted, if448 ** we are counting rows.449 */450 if( (db->flags & SQLITE_CountRows)!=0451 && !pParse->nested452 && !pParse->pTriggerTab453 && !pParse->bReturning454 ){455 memCnt = ++pParse->nMem;456 sqlite3VdbeAddOp2(v, OP_Integer, 0, memCnt);457 }458 459#ifndef SQLITE_OMIT_TRUNCATE_OPTIMIZATION460 /* Special case: A DELETE without a WHERE clause deletes everything.461 ** It is easier just to erase the whole table. Prior to version 3.6.5,462 ** this optimization caused the row change count (the value returned by463 ** API function sqlite3_count_changes) to be set incorrectly.464 **465 ** The "rcauth==SQLITE_OK" terms is the466 ** IMPLEMENTATION-OF: R-17228-37124 If the action code is SQLITE_DELETE and467 ** the callback returns SQLITE_IGNORE then the DELETE operation proceeds but468 ** the truncate optimization is disabled and all rows are deleted469 ** individually.470 */471 if( rcauth==SQLITE_OK472 && pWhere==0473 && !bComplex474 && !IsVirtual(pTab)475#ifdef SQLITE_ENABLE_PREUPDATE_HOOK476 && db->xPreUpdateCallback==0477#endif478 ){479 assert( !isView );480 sqlite3TableLock(pParse, iDb, pTab->tnum, 1, pTab->zName);481 if( HasRowid(pTab) ){482 sqlite3VdbeAddOp4(v, OP_Clear, pTab->tnum, iDb, memCnt ? memCnt : -1,483 pTab->zName, P4_STATIC);484 }485 for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){486 assert( pIdx->pSchema==pTab->pSchema );487 if( IsPrimaryKeyIndex(pIdx) && !HasRowid(pTab) ){488 sqlite3VdbeAddOp3(v, OP_Clear, pIdx->tnum, iDb, memCnt ? memCnt : -1);489 }else{490 sqlite3VdbeAddOp2(v, OP_Clear, pIdx->tnum, iDb);491 }492 }493 }else494#endif /* SQLITE_OMIT_TRUNCATE_OPTIMIZATION */495 {496 u16 wcf = WHERE_ONEPASS_DESIRED|WHERE_DUPLICATES_OK;497 if( sNC.ncFlags & NC_Subquery ) bComplex = 1;498 wcf |= (bComplex ? 0 : WHERE_ONEPASS_MULTIROW);499 if( HasRowid(pTab) ){500 /* For a rowid table, initialize the RowSet to an empty set */501 pPk = 0;502 assert( nPk==1 );503 iRowSet = ++pParse->nMem;504 sqlite3VdbeAddOp2(v, OP_Null, 0, iRowSet);505 }else{506 /* For a WITHOUT ROWID table, create an ephemeral table used to507 ** hold all primary keys for rows to be deleted. */508 pPk = sqlite3PrimaryKeyIndex(pTab);509 assert( pPk!=0 );510 nPk = pPk->nKeyCol;511 iPk = pParse->nMem+1;512 pParse->nMem += nPk;513 iEphCur = pParse->nTab++;514 addrEphOpen = sqlite3VdbeAddOp2(v, OP_OpenEphemeral, iEphCur, nPk);515 sqlite3VdbeSetP4KeyInfo(pParse, pPk);516 }517 518 /* Construct a query to find the rowid or primary key for every row519 ** to be deleted, based on the WHERE clause. Set variable eOnePass520 ** to indicate the strategy used to implement this delete:521 **522 ** ONEPASS_OFF: Two-pass approach - use a FIFO for rowids/PK values.523 ** ONEPASS_SINGLE: One-pass approach - at most one row deleted.524 ** ONEPASS_MULTI: One-pass approach - any number of rows may be deleted.525 */526 pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, 0, 0,0,wcf,iTabCur+1);527 if( pWInfo==0 ) goto delete_from_cleanup;528 eOnePass = sqlite3WhereOkOnePass(pWInfo, aiCurOnePass);529 assert( IsVirtual(pTab)==0 || eOnePass!=ONEPASS_MULTI );530 assert( IsVirtual(pTab) || bComplex || eOnePass!=ONEPASS_OFF531 || OptimizationDisabled(db, SQLITE_OnePass) );532 if( eOnePass!=ONEPASS_SINGLE ) sqlite3MultiWrite(pParse);533 if( sqlite3WhereUsesDeferredSeek(pWInfo) ){534 sqlite3VdbeAddOp1(v, OP_FinishSeek, iTabCur);535 }536 537 /* Keep track of the number of rows to be deleted */538 if( memCnt ){539 sqlite3VdbeAddOp2(v, OP_AddImm, memCnt, 1);540 }541 542 /* Extract the rowid or primary key for the current row */543 if( pPk ){544 for(i=0; i<nPk; i++){545 assert( pPk->aiColumn[i]>=0 );546 sqlite3ExprCodeGetColumnOfTable(v, pTab, iTabCur,547 pPk->aiColumn[i], iPk+i);548 }549 iKey = iPk;550 }else{551 iKey = ++pParse->nMem;552 sqlite3ExprCodeGetColumnOfTable(v, pTab, iTabCur, -1, iKey);553 }554 555 if( eOnePass!=ONEPASS_OFF ){556 /* For ONEPASS, no need to store the rowid/primary-key. There is only557 ** one, so just keep it in its register(s) and fall through to the558 ** delete code. */559 nKey = nPk; /* OP_Found will use an unpacked key */560 aToOpen = sqlite3DbMallocRawNN(db, nIdx+2);561 if( aToOpen==0 ){562 sqlite3WhereEnd(pWInfo);563 goto delete_from_cleanup;564 }565 memset(aToOpen, 1, nIdx+1);566 aToOpen[nIdx+1] = 0;567 if( aiCurOnePass[0]>=0 ) aToOpen[aiCurOnePass[0]-iTabCur] = 0;568 if( aiCurOnePass[1]>=0 ) aToOpen[aiCurOnePass[1]-iTabCur] = 0;569 if( addrEphOpen ) sqlite3VdbeChangeToNoop(v, addrEphOpen);570 addrBypass = sqlite3VdbeMakeLabel(pParse);571 }else{572 if( pPk ){573 /* Add the PK key for this row to the temporary table */574 iKey = ++pParse->nMem;575 nKey = 0; /* Zero tells OP_Found to use a composite key */576 sqlite3VdbeAddOp4(v, OP_MakeRecord, iPk, nPk, iKey,577 sqlite3IndexAffinityStr(pParse->db, pPk), nPk);578 sqlite3VdbeAddOp4Int(v, OP_IdxInsert, iEphCur, iKey, iPk, nPk);579 }else{580 /* Add the rowid of the row to be deleted to the RowSet */581 nKey = 1; /* OP_DeferredSeek always uses a single rowid */582 sqlite3VdbeAddOp2(v, OP_RowSetAdd, iRowSet, iKey);583 }584 sqlite3WhereEnd(pWInfo);585 }586 587 /* Unless this is a view, open cursors for the table we are588 ** deleting from and all its indices. If this is a view, then the589 ** only effect this statement has is to fire the INSTEAD OF590 ** triggers.591 */592 if( !isView ){593 int iAddrOnce = 0;594 if( eOnePass==ONEPASS_MULTI ){595 iAddrOnce = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v);596 }597 testcase( IsVirtual(pTab) );598 sqlite3OpenTableAndIndices(pParse, pTab, OP_OpenWrite, OPFLAG_FORDELETE,599 iTabCur, aToOpen, &iDataCur, &iIdxCur);600 assert( pPk || IsVirtual(pTab) || iDataCur==iTabCur );601 assert( pPk || IsVirtual(pTab) || iIdxCur==iDataCur+1 );602 if( eOnePass==ONEPASS_MULTI ){603 sqlite3VdbeJumpHereOrPopInst(v, iAddrOnce);604 }605 }606 607 /* Set up a loop over the rowids/primary-keys that were found in the608 ** where-clause loop above.609 */610 if( eOnePass!=ONEPASS_OFF ){611 assert( nKey==nPk ); /* OP_Found will use an unpacked key */612 if( !IsVirtual(pTab) && aToOpen[iDataCur-iTabCur] ){613 assert( pPk!=0 || IsView(pTab) );614 sqlite3VdbeAddOp4Int(v, OP_NotFound, iDataCur, addrBypass, iKey, nKey);615 VdbeCoverage(v);616 }617 }else if( pPk ){618 addrLoop = sqlite3VdbeAddOp1(v, OP_Rewind, iEphCur); VdbeCoverage(v);619 if( IsVirtual(pTab) ){620 sqlite3VdbeAddOp3(v, OP_Column, iEphCur, 0, iKey);621 }else{622 sqlite3VdbeAddOp2(v, OP_RowData, iEphCur, iKey);623 }624 assert( nKey==0 ); /* OP_Found will use a composite key */625 }else{626 addrLoop = sqlite3VdbeAddOp3(v, OP_RowSetRead, iRowSet, 0, iKey);627 VdbeCoverage(v);628 assert( nKey==1 );629 } 630 631 /* Delete the row */632#ifndef SQLITE_OMIT_VIRTUALTABLE633 if( IsVirtual(pTab) ){634 const char *pVTab = (const char *)sqlite3GetVTable(db, pTab);635 sqlite3VtabMakeWritable(pParse, pTab);636 assert( eOnePass==ONEPASS_OFF || eOnePass==ONEPASS_SINGLE );637 sqlite3MayAbort(pParse);638 if( eOnePass==ONEPASS_SINGLE ){639 sqlite3VdbeAddOp1(v, OP_Close, iTabCur);640 if( sqlite3IsToplevel(pParse) ){641 pParse->isMultiWrite = 0;642 }643 }644 sqlite3VdbeAddOp4(v, OP_VUpdate, 0, 1, iKey, pVTab, P4_VTAB);645 sqlite3VdbeChangeP5(v, OE_Abort);646 }else647#endif648 {649 int count = (pParse->nested==0); /* True to count changes */650 sqlite3GenerateRowDelete(pParse, pTab, pTrigger, iDataCur, iIdxCur,651 iKey, nKey, count, OE_Default, eOnePass, aiCurOnePass[1]);652 }653 654 /* End of the loop over all rowids/primary-keys. */655 if( eOnePass!=ONEPASS_OFF ){656 sqlite3VdbeResolveLabel(v, addrBypass);657 sqlite3WhereEnd(pWInfo);658 }else if( pPk ){659 sqlite3VdbeAddOp2(v, OP_Next, iEphCur, addrLoop+1); VdbeCoverage(v);660 sqlite3VdbeJumpHere(v, addrLoop);661 }else{662 sqlite3VdbeGoto(v, addrLoop);663 sqlite3VdbeJumpHere(v, addrLoop);664 } 665 } /* End non-truncate path */666 667 /* Update the sqlite_sequence table by storing the content of the668 ** maximum rowid counter values recorded while inserting into669 ** autoincrement tables.670 */671 if( pParse->nested==0 && pParse->pTriggerTab==0 ){672 sqlite3AutoincrementEnd(pParse);673 }674 675 /* Return the number of rows that were deleted. If this routine is676 ** generating code because of a call to sqlite3NestedParse(), do not677 ** invoke the callback function.678 */679 if( memCnt ){680 sqlite3CodeChangeCount(v, memCnt, "rows deleted");681 }682 683delete_from_cleanup:684 sqlite3AuthContextPop(&sContext);685 sqlite3SrcListDelete(db, pTabList);686 sqlite3ExprDelete(db, pWhere);687#if defined(SQLITE_ENABLE_UPDATE_DELETE_LIMIT)688 sqlite3ExprListDelete(db, pOrderBy);689 sqlite3ExprDelete(db, pLimit);690#endif691 if( aToOpen ) sqlite3DbNNFreeNN(db, aToOpen);692 return;693}694/* Make sure "isView" and other macros defined above are undefined. Otherwise695** they may interfere with compilation of other functions in this file696** (or in another file, if this file becomes part of the amalgamation). */697#ifdef isView698 #undef isView699#endif700#ifdef pTrigger701 #undef pTrigger702#endif703 704/*705** This routine generates VDBE code that causes a single row of a706** single table to be deleted. Both the original table entry and707** all indices are removed.708**709** Preconditions:710**711** 1. iDataCur is an open cursor on the btree that is the canonical data712** store for the table. (This will be either the table itself,713** in the case of a rowid table, or the PRIMARY KEY index in the case714** of a WITHOUT ROWID table.)715**716** 2. Read/write cursors for all indices of pTab must be open as717** cursor number iIdxCur+i for the i-th index.718**719** 3. The primary key for the row to be deleted must be stored in a720** sequence of nPk memory cells starting at iPk. If nPk==0 that means721** that a search record formed from OP_MakeRecord is contained in the722** single memory location iPk.723**724** eMode:725** Parameter eMode may be passed either ONEPASS_OFF (0), ONEPASS_SINGLE, or726** ONEPASS_MULTI. If eMode is not ONEPASS_OFF, then the cursor727** iDataCur already points to the row to delete. If eMode is ONEPASS_OFF728** then this function must seek iDataCur to the entry identified by iPk729** and nPk before reading from it.730**731** If eMode is ONEPASS_MULTI, then this call is being made as part732** of a ONEPASS delete that affects multiple rows. In this case, if733** iIdxNoSeek is a valid cursor number (>=0) and is not the same as734** iDataCur, then its position should be preserved following the delete735** operation. Or, if iIdxNoSeek is not a valid cursor number, the736** position of iDataCur should be preserved instead.737**738** iIdxNoSeek:739** If iIdxNoSeek is a valid cursor number (>=0) not equal to iDataCur,740** then it identifies an index cursor (from within array of cursors741** starting at iIdxCur) that already points to the index entry to be deleted.742** Except, this optimization is disabled if there are BEFORE triggers since743** the trigger body might have moved the cursor.744*/745void sqlite3GenerateRowDelete(746 Parse *pParse, /* Parsing context */747 Table *pTab, /* Table containing the row to be deleted */748 Trigger *pTrigger, /* List of triggers to (potentially) fire */749 int iDataCur, /* Cursor from which column data is extracted */750 int iIdxCur, /* First index cursor */751 int iPk, /* First memory cell containing the PRIMARY KEY */752 i16 nPk, /* Number of PRIMARY KEY memory cells */753 u8 count, /* If non-zero, increment the row change counter */754 u8 onconf, /* Default ON CONFLICT policy for triggers */755 u8 eMode, /* ONEPASS_OFF, _SINGLE, or _MULTI. See above */756 int iIdxNoSeek /* Cursor number of cursor that does not need seeking */757){758 Vdbe *v = pParse->pVdbe; /* Vdbe */759 int iOld = 0; /* First register in OLD.* array */760 int iLabel; /* Label resolved to end of generated code */761 u8 opSeek; /* Seek opcode */762 763 /* Vdbe is guaranteed to have been allocated by this stage. */764 assert( v );765 VdbeModuleComment((v, "BEGIN: GenRowDel(%d,%d,%d,%d)",766 iDataCur, iIdxCur, iPk, (int)nPk));767 768 /* Seek cursor iCur to the row to delete. If this row no longer exists769 ** (this can happen if a trigger program has already deleted it), do770 ** not attempt to delete it or fire any DELETE triggers. */771 iLabel = sqlite3VdbeMakeLabel(pParse);772 opSeek = HasRowid(pTab) ? OP_NotExists : OP_NotFound;773 if( eMode==ONEPASS_OFF ){774 sqlite3VdbeAddOp4Int(v, opSeek, iDataCur, iLabel, iPk, nPk);775 VdbeCoverageIf(v, opSeek==OP_NotExists);776 VdbeCoverageIf(v, opSeek==OP_NotFound);777 }778 779 /* If there are any triggers to fire, allocate a range of registers to780 ** use for the old.* references in the triggers. */781 if( sqlite3FkRequired(pParse, pTab, 0, 0) || pTrigger ){782 u32 mask; /* Mask of OLD.* columns in use */783 int iCol; /* Iterator used while populating OLD.* */784 int addrStart; /* Start of BEFORE trigger programs */785 786 /* TODO: Could use temporary registers here. Also could attempt to787 ** avoid copying the contents of the rowid register. */788 mask = sqlite3TriggerColmask(789 pParse, pTrigger, 0, 0, TRIGGER_BEFORE|TRIGGER_AFTER, pTab, onconf790 );791 mask |= sqlite3FkOldmask(pParse, pTab);792 iOld = pParse->nMem+1;793 pParse->nMem += (1 + pTab->nCol);794 795 /* Populate the OLD.* pseudo-table register array. These values will be796 ** used by any BEFORE and AFTER triggers that exist. */797 sqlite3VdbeAddOp2(v, OP_Copy, iPk, iOld);798 for(iCol=0; iCol<pTab->nCol; iCol++){799 testcase( mask!=0xffffffff && iCol==31 );800 testcase( mask!=0xffffffff && iCol==32 );801 if( mask==0xffffffff || (iCol<=31 && (mask & MASKBIT32(iCol))!=0) ){802 int kk = sqlite3TableColumnToStorage(pTab, iCol);803 sqlite3ExprCodeGetColumnOfTable(v, pTab, iDataCur, iCol, iOld+kk+1);804 }805 }806 807 /* Invoke BEFORE DELETE trigger programs. */808 addrStart = sqlite3VdbeCurrentAddr(v);809 sqlite3CodeRowTrigger(pParse, pTrigger,810 TK_DELETE, 0, TRIGGER_BEFORE, pTab, iOld, onconf, iLabel811 );812 813 /* If any BEFORE triggers were coded, then seek the cursor to the814 ** row to be deleted again. It may be that the BEFORE triggers moved815 ** the cursor or already deleted the row that the cursor was816 ** pointing to.817 **818 ** Also disable the iIdxNoSeek optimization since the BEFORE trigger819 ** may have moved that cursor.820 */821 if( addrStart<sqlite3VdbeCurrentAddr(v) ){822 sqlite3VdbeAddOp4Int(v, opSeek, iDataCur, iLabel, iPk, nPk);823 VdbeCoverageIf(v, opSeek==OP_NotExists);824 VdbeCoverageIf(v, opSeek==OP_NotFound);825 testcase( iIdxNoSeek>=0 );826 iIdxNoSeek = -1;827 }828 829 /* Do FK processing. This call checks that any FK constraints that830 ** refer to this table (i.e. constraints attached to other tables)831 ** are not violated by deleting this row. */832 sqlite3FkCheck(pParse, pTab, iOld, 0, 0, 0);833 }834 835 /* Delete the index and table entries. Skip this step if pTab is really836 ** a view (in which case the only effect of the DELETE statement is to837 ** fire the INSTEAD OF triggers). 838 **839 ** If variable 'count' is non-zero, then this OP_Delete instruction should840 ** invoke the update-hook. The pre-update-hook, on the other hand should841 ** be invoked unless table pTab is a system table. The difference is that842 ** the update-hook is not invoked for rows removed by REPLACE, but the843 ** pre-update-hook is.844 */845 if( !IsView(pTab) ){846 u8 p5 = 0;847 sqlite3GenerateRowIndexDelete(pParse, pTab, iDataCur, iIdxCur,0,iIdxNoSeek);848 sqlite3VdbeAddOp2(v, OP_Delete, iDataCur, (count?OPFLAG_NCHANGE:0));849 if( pParse->nested==0 || 0==sqlite3_stricmp(pTab->zName, "sqlite_stat1") ){850 sqlite3VdbeAppendP4(v, (char*)pTab, P4_TABLE);851 }852 if( eMode!=ONEPASS_OFF ){853 sqlite3VdbeChangeP5(v, OPFLAG_AUXDELETE);854 }855 if( iIdxNoSeek>=0 && iIdxNoSeek!=iDataCur ){856 sqlite3VdbeAddOp1(v, OP_Delete, iIdxNoSeek);857 }858 if( eMode==ONEPASS_MULTI ) p5 |= OPFLAG_SAVEPOSITION;859 sqlite3VdbeChangeP5(v, p5);860 }861 862 /* Do any ON CASCADE, SET NULL or SET DEFAULT operations required to863 ** handle rows (possibly in other tables) that refer via a foreign key864 ** to the row just deleted. */865 sqlite3FkActions(pParse, pTab, 0, iOld, 0, 0);866 867 /* Invoke AFTER DELETE trigger programs. */868 if( pTrigger ){869 sqlite3CodeRowTrigger(pParse, pTrigger,870 TK_DELETE, 0, TRIGGER_AFTER, pTab, iOld, onconf, iLabel871 );872 }873 874 /* Jump here if the row had already been deleted before any BEFORE875 ** trigger programs were invoked. Or if a trigger program throws a876 ** RAISE(IGNORE) exception. */877 sqlite3VdbeResolveLabel(v, iLabel);878 VdbeModuleComment((v, "END: GenRowDel()"));879}880 881/*882** This routine generates VDBE code that causes the deletion of all883** index entries associated with a single row of a single table, pTab884**885** Preconditions:886**887** 1. A read/write cursor "iDataCur" must be open on the canonical storage888** btree for the table pTab. (This will be either the table itself889** for rowid tables or to the primary key index for WITHOUT ROWID890** tables.)891**892** 2. Read/write cursors for all indices of pTab must be open as893** cursor number iIdxCur+i for the i-th index. (The pTab->pIndex894** index is the 0-th index.)895**896** 3. The "iDataCur" cursor must be already be positioned on the row897** that is to be deleted.898*/899void sqlite3GenerateRowIndexDelete(900 Parse *pParse, /* Parsing and code generating context */901 Table *pTab, /* Table containing the row to be deleted */902 int iDataCur, /* Cursor of table holding data. */903 int iIdxCur, /* First index cursor */904 int *aRegIdx, /* Only delete if aRegIdx!=0 && aRegIdx[i]>0 */905 int iIdxNoSeek /* Do not delete from this cursor */906){907 int i; /* Index loop counter */908 int r1 = -1; /* Register holding an index key */909 int iPartIdxLabel; /* Jump destination for skipping partial index entries */910 Index *pIdx; /* Current index */911 Index *pPrior = 0; /* Prior index */912 Vdbe *v; /* The prepared statement under construction */913 Index *pPk; /* PRIMARY KEY index, or NULL for rowid tables */914 915 v = pParse->pVdbe;916 pPk = HasRowid(pTab) ? 0 : sqlite3PrimaryKeyIndex(pTab);917 for(i=0, pIdx=pTab->pIndex; pIdx; i++, pIdx=pIdx->pNext){918 assert( iIdxCur+i!=iDataCur || pPk==pIdx );919 if( aRegIdx!=0 && aRegIdx[i]==0 ) continue;920 if( pIdx==pPk ) continue;921 if( iIdxCur+i==iIdxNoSeek ) continue;922 VdbeModuleComment((v, "GenRowIdxDel for %s", pIdx->zName));923 r1 = sqlite3GenerateIndexKey(pParse, pIdx, iDataCur, 0, 1,924 &iPartIdxLabel, pPrior, r1);925 sqlite3VdbeAddOp3(v, OP_IdxDelete, iIdxCur+i, r1,926 pIdx->uniqNotNull ? pIdx->nKeyCol : pIdx->nColumn);927 sqlite3VdbeChangeP5(v, 1); /* Cause IdxDelete to error if no entry found */928 sqlite3ResolvePartIdxLabel(pParse, iPartIdxLabel);929 pPrior = pIdx;930 }931}932 933/*934** Generate code that will assemble an index key and stores it in register935** regOut. The key with be for index pIdx which is an index on pTab.936** iCur is the index of a cursor open on the pTab table and pointing to937** the entry that needs indexing. If pTab is a WITHOUT ROWID table, then938** iCur must be the cursor of the PRIMARY KEY index.939**940** Return a register number which is the first in a block of941** registers that holds the elements of the index key. The942** block of registers has already been deallocated by the time943** this routine returns.944**945** If *piPartIdxLabel is not NULL, fill it in with a label and jump946** to that label if pIdx is a partial index that should be skipped.947** The label should be resolved using sqlite3ResolvePartIdxLabel().948** A partial index should be skipped if its WHERE clause evaluates949** to false or null. If pIdx is not a partial index, *piPartIdxLabel950** will be set to zero which is an empty label that is ignored by951** sqlite3ResolvePartIdxLabel().952**953** The pPrior and regPrior parameters are used to implement a cache to954** avoid unnecessary register loads. If pPrior is not NULL, then it is955** a pointer to a different index for which an index key has just been956** computed into register regPrior. If the current pIdx index is generating957** its key into the same sequence of registers and if pPrior and pIdx share958** a column in common, then the register corresponding to that column already959** holds the correct value and the loading of that register is skipped.960** This optimization is helpful when doing a DELETE or an INTEGRITY_CHECK961** on a table with multiple indices, and especially with the ROWID or962** PRIMARY KEY columns of the index.963*/964int sqlite3GenerateIndexKey(965 Parse *pParse, /* Parsing context */966 Index *pIdx, /* The index for which to generate a key */967 int iDataCur, /* Cursor number from which to take column data */968 int regOut, /* Put the new key into this register if not 0 */969 int prefixOnly, /* Compute only a unique prefix of the key */970 int *piPartIdxLabel, /* OUT: Jump to this label to skip partial index */971 Index *pPrior, /* Previously generated index key */972 int regPrior /* Register holding previous generated key */973){974 Vdbe *v = pParse->pVdbe;975 int j;976 int regBase;977 int nCol;978 979 if( piPartIdxLabel ){980 if( pIdx->pPartIdxWhere ){981 *piPartIdxLabel = sqlite3VdbeMakeLabel(pParse);982 pParse->iSelfTab = iDataCur + 1;983 sqlite3ExprIfFalseDup(pParse, pIdx->pPartIdxWhere, *piPartIdxLabel,984 SQLITE_JUMPIFNULL);985 pParse->iSelfTab = 0;986 pPrior = 0; /* Ticket a9efb42811fa41ee 2019-11-02;987 ** pPartIdxWhere may have corrupted regPrior registers */988 }else{989 *piPartIdxLabel = 0;990 }991 }992 nCol = (prefixOnly && pIdx->uniqNotNull) ? pIdx->nKeyCol : pIdx->nColumn;993 regBase = sqlite3GetTempRange(pParse, nCol);994 if( pPrior && (regBase!=regPrior || pPrior->pPartIdxWhere) ) pPrior = 0;995 for(j=0; j<nCol; j++){996 if( pPrior997 && pPrior->aiColumn[j]==pIdx->aiColumn[j]998 && pPrior->aiColumn[j]!=XN_EXPR999 ){1000 /* This column was already computed by the previous index */1001 continue;1002 }1003 sqlite3ExprCodeLoadIndexColumn(pParse, pIdx, iDataCur, j, regBase+j);1004 if( pIdx->aiColumn[j]>=0 ){1005 /* If the column affinity is REAL but the number is an integer, then it1006 ** might be stored in the table as an integer (using a compact1007 ** representation) then converted to REAL by an OP_RealAffinity opcode.1008 ** But we are getting ready to store this value back into an index, where1009 ** it should be converted by to INTEGER again. So omit the1010 ** OP_RealAffinity opcode if it is present */1011 sqlite3VdbeDeletePriorOpcode(v, OP_RealAffinity);1012 }1013 }1014 if( regOut ){1015 sqlite3VdbeAddOp3(v, OP_MakeRecord, regBase, nCol, regOut);1016 }1017 sqlite3ReleaseTempRange(pParse, regBase, nCol);1018 return regBase;1019}1020 1021/*1022** If a prior call to sqlite3GenerateIndexKey() generated a jump-over label1023** because it was a partial index, then this routine should be called to1024** resolve that label.1025*/1026void sqlite3ResolvePartIdxLabel(Parse *pParse, int iLabel){1027 if( iLabel ){1028 sqlite3VdbeResolveLabel(pParse->pVdbe, iLabel);1029 }1030}1031 