Team Ai
Modelpublic

AryaWu/sqlite

sourceHugging Faceupdated 10mo agoView on Hugging Face
0likes
delete.c1031 linesDownload Raw Back to src
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