15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 2001 September 15
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** The author disclaims copyright to this source code.  In place of
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** a legal notice, here is a blessing:
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**    May you do good and not evil.
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**    May you find forgiveness for yourself and forgive others.
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**    May you share freely, never taking more than you give.
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*************************************************************************
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** This file contains C code routines that are called by the parser
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** in order to generate code for DELETE FROM statements.
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sqliteInt.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** While a SrcList can in general represent multiple tables and subqueries
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** (as in the FROM clause of a SELECT statement) in this case it contains
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** the name of a single table, as one might find in an INSERT, DELETE,
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** or UPDATE statement.  Look up that table in the symbol table and
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** return a pointer.  Set an error message and return NULL if the table
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** name is not found or if any other error occurs.
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** The following fields are initialized appropriate in pSrc:
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**    pSrc->a[0].pTab       Pointer to the Table object
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**    pSrc->a[0].pIndex     Pointer to the INDEXED BY index, if there is one
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Table *sqlite3SrcListLookup(Parse *pParse, SrcList *pSrc){
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  struct SrcList_item *pItem = pSrc->a;
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Table *pTab;
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  assert( pItem && pSrc->nSrc==1 );
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pTab = sqlite3LocateTable(pParse, 0, pItem->zName, pItem->zDatabase);
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sqlite3DeleteTable(pParse->db, pItem->pTab);
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pItem->pTab = pTab;
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( pTab ){
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    pTab->nRef++;
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( sqlite3IndexedByLookup(pParse, pItem) ){
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    pTab = 0;
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return pTab;
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Check to make sure the given table is writable.  If it is not
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** writable, generate an error message and return 1.  If it is
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** writable return 0;
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int sqlite3IsReadOnly(Parse *pParse, Table *pTab, int viewOk){
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  /* A table is not writable under the following circumstances:
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  **
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  **   1) It is a virtual table and no implementation of the xUpdate method
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  **      has been provided, or
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  **   2) It is a system table (i.e. sqlite_master), this call is not
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  **      part of a nested parse and writable_schema pragma has not
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  **      been specified.
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  **
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ** In either case leave an error message in pParse and return non-zero.
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  */
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( ( IsVirtual(pTab)
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     && sqlite3GetVTable(pParse->db, pTab)->pMod->pModule->xUpdate==0 )
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   || ( (pTab->tabFlags & TF_Readonly)!=0
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     && (pParse->db->flags & SQLITE_WriteSchema)==0
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     && pParse->nested==0 )
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ){
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sqlite3ErrorMsg(pParse, "table %s may not be modified", pTab->zName);
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return 1;
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef SQLITE_OMIT_VIEW
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( !viewOk && pTab->pSelect ){
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sqlite3ErrorMsg(pParse,"cannot modify %s because it is a view",pTab->zName);
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return 1;
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return 0;
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if !defined(SQLITE_OMIT_VIEW) && !defined(SQLITE_OMIT_TRIGGER)
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Evaluate a view and store its result in an ephemeral table.  The
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** pWhere argument is an optional WHERE clause that restricts the
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** set of rows in the view that are to be added to the ephemeral table.
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void sqlite3MaterializeView(
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Parse *pParse,       /* Parsing context */
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Table *pView,        /* View definition */
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Expr *pWhere,        /* Optional WHERE clause to be added */
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int iCur             /* Cursor number for ephemerial table */
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)){
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SelectDest dest;
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Select *pDup;
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sqlite3 *db = pParse->db;
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pDup = sqlite3SelectDup(db, pView->pSelect, 0);
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( pWhere ){
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SrcList *pFrom;
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    pWhere = sqlite3ExprDup(db, pWhere, 0);
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    pFrom = sqlite3SrcListAppend(db, 0, 0, 0);
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if( pFrom ){
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      assert( pFrom->nSrc==1 );
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      pFrom->a[0].zAlias = sqlite3DbStrDup(db, pView->zName);
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      pFrom->a[0].pSelect = pDup;
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      assert( pFrom->a[0].pOn==0 );
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      assert( pFrom->a[0].pUsing==0 );
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }else{
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      sqlite3SelectDelete(db, pDup);
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    pDup = sqlite3SelectNew(pParse, 0, pFrom, pWhere, 0, 0, 0, 0, 0, 0);
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sqlite3SelectDestInit(&dest, SRT_EphemTab, iCur);
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sqlite3Select(pParse, pDup, &dest);
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sqlite3SelectDelete(db, pDup);
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif /* !defined(SQLITE_OMIT_VIEW) && !defined(SQLITE_OMIT_TRIGGER) */
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(SQLITE_ENABLE_UPDATE_DELETE_LIMIT) && !defined(SQLITE_OMIT_SUBQUERY)
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Generate an expression tree to implement the WHERE, ORDER BY,
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** and LIMIT/OFFSET portion of DELETE and UPDATE statements.
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**     DELETE FROM table_wxyz WHERE a<5 ORDER BY a LIMIT 1;
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**                            \__________________________/
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**                               pLimitWhere (pInClause)
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Expr *sqlite3LimitWhere(
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Parse *pParse,               /* The parser context */
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SrcList *pSrc,               /* the FROM clause -- which tables to scan */
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Expr *pWhere,                /* The WHERE clause.  May be null */
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ExprList *pOrderBy,          /* The ORDER BY clause.  May be null */
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Expr *pLimit,                /* The LIMIT clause.  May be null */
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Expr *pOffset,               /* The OFFSET clause.  May be null */
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  char *zStmtType              /* Either DELETE or UPDATE.  For error messages. */
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)){
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Expr *pWhereRowid = NULL;    /* WHERE rowid .. */
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Expr *pInClause = NULL;      /* WHERE rowid IN ( select ) */
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Expr *pSelectRowid = NULL;   /* SELECT rowid ... */
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ExprList *pEList = NULL;     /* Expression list contaning only pSelectRowid */
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SrcList *pSelectSrc = NULL;  /* SELECT rowid FROM x ... (dup of pSrc) */
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Select *pSelect = NULL;      /* Complete SELECT tree */
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  /* Check that there isn't an ORDER BY without a LIMIT clause.
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  */
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( pOrderBy && (pLimit == 0) ) {
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sqlite3ErrorMsg(pParse, "ORDER BY without LIMIT on %s", zStmtType);
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    pParse->parseError = 1;
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    goto limit_where_cleanup_2;
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  /* We only need to generate a select expression if there
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ** is a limit/offset term to enforce.
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  */
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( pLimit == 0 ) {
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* if pLimit is null, pOffset will always be null as well. */
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    assert( pOffset == 0 );
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return pWhere;
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  /* Generate a select expression tree to enforce the limit/offset
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ** term for the DELETE or UPDATE statement.  For example:
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  **   DELETE FROM table_a WHERE col1=1 ORDER BY col2 LIMIT 1 OFFSET 1
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ** becomes:
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  **   DELETE FROM table_a WHERE rowid IN (
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  **     SELECT rowid FROM table_a WHERE col1=1 ORDER BY col2 LIMIT 1 OFFSET 1
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  **   );
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  */
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pSelectRowid = sqlite3PExpr(pParse, TK_ROW, 0, 0, 0);
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( pSelectRowid == 0 ) goto limit_where_cleanup_2;
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pEList = sqlite3ExprListAppend(pParse, 0, pSelectRowid);
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( pEList == 0 ) goto limit_where_cleanup_2;
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  /* duplicate the FROM clause as it is needed by both the DELETE/UPDATE tree
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ** and the SELECT subtree. */
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pSelectSrc = sqlite3SrcListDup(pParse->db, pSrc, 0);
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( pSelectSrc == 0 ) {
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sqlite3ExprListDelete(pParse->db, pEList);
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    goto limit_where_cleanup_2;
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  /* generate the SELECT expression tree. */
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pSelect = sqlite3SelectNew(pParse,pEList,pSelectSrc,pWhere,0,0,
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             pOrderBy,0,pLimit,pOffset);
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( pSelect == 0 ) return 0;
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  /* now generate the new WHERE rowid IN clause for the DELETE/UDPATE */
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pWhereRowid = sqlite3PExpr(pParse, TK_ROW, 0, 0, 0);
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( pWhereRowid == 0 ) goto limit_where_cleanup_1;
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pInClause = sqlite3PExpr(pParse, TK_IN, pWhereRowid, 0, 0);
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( pInClause == 0 ) goto limit_where_cleanup_1;
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pInClause->x.pSelect = pSelect;
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pInClause->flags |= EP_xIsSelect;
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sqlite3ExprSetHeight(pParse, pInClause);
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return pInClause;
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  /* something went wrong. clean up anything allocated. */
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)limit_where_cleanup_1:
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sqlite3SelectDelete(pParse->db, pSelect);
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return 0;
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)limit_where_cleanup_2:
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sqlite3ExprDelete(pParse->db, pWhere);
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sqlite3ExprListDelete(pParse->db, pOrderBy);
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sqlite3ExprDelete(pParse->db, pLimit);
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sqlite3ExprDelete(pParse->db, pOffset);
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return 0;
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif /* defined(SQLITE_ENABLE_UPDATE_DELETE_LIMIT) && !defined(SQLITE_OMIT_SUBQUERY) */
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Generate code for a DELETE FROM statement.
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**     DELETE FROM table_wxyz WHERE a<5 AND b NOT NULL;
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**                 \________/       \________________/
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**                  pTabList              pWhere
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void sqlite3DeleteFrom(
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Parse *pParse,         /* The parser context */
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SrcList *pTabList,     /* The table from which we should delete things */
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Expr *pWhere           /* The WHERE clause.  May be null */
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)){
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Vdbe *v;               /* The virtual database engine */
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Table *pTab;           /* The table from which records will be deleted */
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char *zDb;       /* Name of database holding pTab */
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int end, addr = 0;     /* A couple addresses of generated code */
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int i;                 /* Loop counter */
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  WhereInfo *pWInfo;     /* Information about the WHERE clause */
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Index *pIdx;           /* For looping over indices of the table */
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int iCur;              /* VDBE Cursor number for pTab */
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sqlite3 *db;           /* Main database structure */
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AuthContext sContext;  /* Authorization context */
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NameContext sNC;       /* Name context to resolve expressions in */
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int iDb;               /* Database number */
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int memCnt = -1;       /* Memory cell used for change counting */
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rcauth;            /* Value returned by authorization callback */
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef SQLITE_OMIT_TRIGGER
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int isView;                  /* True if attempting to delete from a view */
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Trigger *pTrigger;           /* List of table triggers, if required */
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  memset(&sContext, 0, sizeof(sContext));
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  db = pParse->db;
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( pParse->nErr || db->mallocFailed ){
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    goto delete_from_cleanup;
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  assert( pTabList->nSrc==1 );
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  /* Locate the table which we want to delete.  This table has to be
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ** put in an SrcList structure because some of the subroutines we
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ** will be calling are designed to work with multiple tables and expect
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ** an SrcList* parameter instead of just a Table* parameter.
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  */
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pTab = sqlite3SrcListLookup(pParse, pTabList);
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( pTab==0 )  goto delete_from_cleanup;
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  /* Figure out if we have any triggers and if the table being
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ** deleted from is a view
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  */
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef SQLITE_OMIT_TRIGGER
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pTrigger = sqlite3TriggersExist(pParse, pTab, TK_DELETE, 0, 0);
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  isView = pTab->pSelect!=0;
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# define pTrigger 0
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# define isView 0
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef SQLITE_OMIT_VIEW
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# undef isView
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# define isView 0
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  /* If pTab is really a view, make sure it has been initialized.
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  */
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( sqlite3ViewGetColumnNames(pParse, pTab) ){
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    goto delete_from_cleanup;
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( sqlite3IsReadOnly(pParse, pTab, (pTrigger?1:0)) ){
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    goto delete_from_cleanup;
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  assert( iDb<db->nDb );
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  zDb = db->aDb[iDb].zName;
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rcauth = sqlite3AuthCheck(pParse, SQLITE_DELETE, pTab->zName, 0, zDb);
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  assert( rcauth==SQLITE_OK || rcauth==SQLITE_DENY || rcauth==SQLITE_IGNORE );
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( rcauth==SQLITE_DENY ){
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    goto delete_from_cleanup;
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  assert(!isView || pTrigger);
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  /* Assign  cursor number to the table and all its indices.
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  */
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  assert( pTabList->nSrc==1 );
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  iCur = pTabList->a[0].iCursor = pParse->nTab++;
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    pParse->nTab++;
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  /* Start the view context
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  */
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( isView ){
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sqlite3AuthContextPush(pParse, &sContext, pTab->zName);
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  /* Begin generating code.
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  */
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  v = sqlite3GetVdbe(pParse);
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( v==0 ){
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    goto delete_from_cleanup;
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( pParse->nested==0 ) sqlite3VdbeCountChanges(v);
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sqlite3BeginWriteOperation(pParse, 1, iDb);
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  /* If we are trying to delete from a view, realize that view into
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ** a ephemeral table.
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  */
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if !defined(SQLITE_OMIT_VIEW) && !defined(SQLITE_OMIT_TRIGGER)
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( isView ){
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sqlite3MaterializeView(pParse, pTab, pWhere, iCur);
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  /* Resolve the column names in the WHERE clause.
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  */
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  memset(&sNC, 0, sizeof(sNC));
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sNC.pParse = pParse;
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sNC.pSrcList = pTabList;
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( sqlite3ResolveExprNames(&sNC, pWhere) ){
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    goto delete_from_cleanup;
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  /* Initialize the counter of the number of rows deleted, if
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ** we are counting rows.
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  */
3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( db->flags & SQLITE_CountRows ){
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    memCnt = ++pParse->nMem;
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sqlite3VdbeAddOp2(v, OP_Integer, 0, memCnt);
3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef SQLITE_OMIT_TRUNCATE_OPTIMIZATION
3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  /* Special case: A DELETE without a WHERE clause deletes everything.
3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ** It is easier just to erase the whole table. Prior to version 3.6.5,
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ** this optimization caused the row change count (the value returned by
3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ** API function sqlite3_count_changes) to be set incorrectly.  */
3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( rcauth==SQLITE_OK && pWhere==0 && !pTrigger && !IsVirtual(pTab)
3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   && 0==sqlite3FkRequired(pParse, pTab, 0, 0)
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ){
3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    assert( !isView );
3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sqlite3VdbeAddOp4(v, OP_Clear, pTab->tnum, iDb, memCnt,
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      pTab->zName, P4_STATIC);
3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      assert( pIdx->pSchema==pTab->pSchema );
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      sqlite3VdbeAddOp2(v, OP_Clear, pIdx->tnum, iDb);
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }else
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif /* SQLITE_OMIT_TRUNCATE_OPTIMIZATION */
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  /* The usual case: There is a WHERE clause so we have to scan through
3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ** the table and pick which records to delete.
3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  */
3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int iRowSet = ++pParse->nMem;   /* Register for rowset of rows to delete */
3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int iRowid = ++pParse->nMem;    /* Used for storing rowid values. */
3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int regRowid;                   /* Actual register containing rowids */
3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* Collect rowids of every row to be deleted.
3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    */
3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sqlite3VdbeAddOp2(v, OP_Null, 0, iRowSet);
3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere,0,WHERE_DUPLICATES_OK);
3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if( pWInfo==0 ) goto delete_from_cleanup;
3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    regRowid = sqlite3ExprCodeGetColumn(pParse, pTab, -1, iCur, iRowid);
3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sqlite3VdbeAddOp2(v, OP_RowSetAdd, iRowSet, regRowid);
3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if( db->flags & SQLITE_CountRows ){
3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      sqlite3VdbeAddOp2(v, OP_AddImm, memCnt, 1);
3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sqlite3WhereEnd(pWInfo);
3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* Delete every item whose key was written to the list during the
3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ** database scan.  We have to delete items after the scan is complete
3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ** because deleting an item can change the scan order.  */
3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    end = sqlite3VdbeMakeLabel(v);
3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* Unless this is a view, open cursors for the table we are
3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ** deleting from and all its indices. If this is a view, then the
3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ** only effect this statement has is to fire the INSTEAD OF
3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ** triggers.  */
3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if( !isView ){
3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      sqlite3OpenTableAndIndices(pParse, pTab, iCur, OP_OpenWrite);
3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    addr = sqlite3VdbeAddOp3(v, OP_RowSetRead, iRowSet, end, iRowid);
3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* Delete the row */
3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef SQLITE_OMIT_VIRTUALTABLE
4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if( IsVirtual(pTab) ){
4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const char *pVTab = (const char *)sqlite3GetVTable(db, pTab);
4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      sqlite3VtabMakeWritable(pParse, pTab);
4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      sqlite3VdbeAddOp4(v, OP_VUpdate, 0, 1, iRowid, pVTab, P4_VTAB);
4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      sqlite3MayAbort(pParse);
4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }else
4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {
4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      int count = (pParse->nested==0);    /* True to count changes */
4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      sqlite3GenerateRowDelete(pParse, pTab, iCur, iRowid, count, pTrigger, OE_Default);
4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* End of the delete loop */
4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sqlite3VdbeAddOp2(v, OP_Goto, 0, addr);
4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sqlite3VdbeResolveLabel(v, end);
4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* Close the cursors open on the table and its indexes. */
4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if( !isView && !IsVirtual(pTab) ){
4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      for(i=1, pIdx=pTab->pIndex; pIdx; i++, pIdx=pIdx->pNext){
4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        sqlite3VdbeAddOp2(v, OP_Close, iCur + i, pIdx->tnum);
4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      sqlite3VdbeAddOp1(v, OP_Close, iCur);
4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  /* Update the sqlite_sequence table by storing the content of the
4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ** maximum rowid counter values recorded while inserting into
4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ** autoincrement tables.
4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  */
4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( pParse->nested==0 && pParse->pTriggerTab==0 ){
4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sqlite3AutoincrementEnd(pParse);
4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  /* Return the number of rows that were deleted. If this routine is
4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ** generating code because of a call to sqlite3NestedParse(), do not
4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ** invoke the callback function.
4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  */
4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( (db->flags&SQLITE_CountRows) && !pParse->nested && !pParse->pTriggerTab ){
4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sqlite3VdbeAddOp2(v, OP_ResultRow, memCnt, 1);
4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sqlite3VdbeSetNumCols(v, 1);
4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "rows deleted", SQLITE_STATIC);
4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)delete_from_cleanup:
4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sqlite3AuthContextPop(&sContext);
4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sqlite3SrcListDelete(db, pTabList);
4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sqlite3ExprDelete(db, pWhere);
4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return;
4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Make sure "isView" and other macros defined above are undefined. Otherwise
4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** thely may interfere with compilation of other functions in this file
4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** (or in another file, if this file becomes part of the amalgamation).  */
4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef isView
4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #undef isView
4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef pTrigger
4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #undef pTrigger
4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** This routine generates VDBE code that causes a single row of a
4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** single table to be deleted.
4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**
4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** The VDBE must be in a particular state when this routine is called.
4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** These are the requirements:
4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**
4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**   1.  A read/write cursor pointing to pTab, the table containing the row
4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**       to be deleted, must be opened as cursor number $iCur.
4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**
4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**   2.  Read/write cursors for all indices of pTab must be open as
4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**       cursor number base+i for the i-th index.
4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**
4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**   3.  The record number of the row to be deleted must be stored in
4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**       memory cell iRowid.
4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**
4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** This routine generates code to remove both the table record and all
4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** index entries that point to that record.
4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/
4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void sqlite3GenerateRowDelete(
4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Parse *pParse,     /* Parsing context */
4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Table *pTab,       /* Table containing the row to be deleted */
4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int iCur,          /* Cursor number for the table */
4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int iRowid,        /* Memory cell that contains the rowid to delete */
4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int count,         /* If non-zero, increment the row change counter */
4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Trigger *pTrigger, /* List of triggers to (potentially) fire */
4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int onconf         /* Default ON CONFLICT policy for triggers */
4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)){
4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Vdbe *v = pParse->pVdbe;        /* Vdbe */
4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int iOld = 0;                   /* First register in OLD.* array */
4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int iLabel;                     /* Label resolved to end of generated code */
4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  /* Vdbe is guaranteed to have been allocated by this stage. */
4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  assert( v );
4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  /* Seek cursor iCur to the row to delete. If this row no longer exists
4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ** (this can happen if a trigger program has already deleted it), do
4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ** not attempt to delete it or fire any DELETE triggers.  */
4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  iLabel = sqlite3VdbeMakeLabel(v);
4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sqlite3VdbeAddOp3(v, OP_NotExists, iCur, iLabel, iRowid);
4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  /* If there are any triggers to fire, allocate a range of registers to
5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ** use for the old.* references in the triggers.  */
5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( sqlite3FkRequired(pParse, pTab, 0, 0) || pTrigger ){
5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    u32 mask;                     /* Mask of OLD.* columns in use */
5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int iCol;                     /* Iterator used while populating OLD.* */
5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* TODO: Could use temporary registers here. Also could attempt to
5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ** avoid copying the contents of the rowid register.  */
5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    mask = sqlite3TriggerColmask(
5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        pParse, pTrigger, 0, 0, TRIGGER_BEFORE|TRIGGER_AFTER, pTab, onconf
5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    );
5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    mask |= sqlite3FkOldmask(pParse, pTab);
5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    iOld = pParse->nMem+1;
5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    pParse->nMem += (1 + pTab->nCol);
5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* Populate the OLD.* pseudo-table register array. These values will be
5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ** used by any BEFORE and AFTER triggers that exist.  */
5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sqlite3VdbeAddOp2(v, OP_Copy, iRowid, iOld);
5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for(iCol=0; iCol<pTab->nCol; iCol++){
5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if( mask==0xffffffff || mask&(1<<iCol) ){
5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        sqlite3ExprCodeGetColumnOfTable(v, pTab, iCur, iCol, iOld+iCol+1);
5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* Invoke BEFORE DELETE trigger programs. */
5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sqlite3CodeRowTrigger(pParse, pTrigger,
5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TK_DELETE, 0, TRIGGER_BEFORE, pTab, iOld, onconf, iLabel
5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    );
5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* Seek the cursor to the row to be deleted again. It may be that
5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ** the BEFORE triggers coded above have already removed the row
5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ** being deleted. Do not attempt to delete the row a second time, and
5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ** do not fire AFTER triggers.  */
5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sqlite3VdbeAddOp3(v, OP_NotExists, iCur, iLabel, iRowid);
5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* Do FK processing. This call checks that any FK constraints that
5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ** refer to this table (i.e. constraints attached to other tables)
5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ** are not violated by deleting this row.  */
5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sqlite3FkCheck(pParse, pTab, iOld, 0);
5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  /* Delete the index and table entries. Skip this step if pTab is really
5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ** a view (in which case the only effect of the DELETE statement is to
5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ** fire the INSTEAD OF triggers).  */
5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( pTab->pSelect==0 ){
5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sqlite3GenerateRowIndexDelete(pParse, pTab, iCur, 0);
5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sqlite3VdbeAddOp2(v, OP_Delete, iCur, (count?OPFLAG_NCHANGE:0));
5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if( count ){
5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      sqlite3VdbeChangeP4(v, -1, pTab->zName, P4_TRANSIENT);
5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  /* Do any ON CASCADE, SET NULL or SET DEFAULT operations required to
5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ** handle rows (possibly in other tables) that refer via a foreign key
5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ** to the row just deleted. */
5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sqlite3FkActions(pParse, pTab, 0, iOld);
5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  /* Invoke AFTER DELETE trigger programs. */
5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sqlite3CodeRowTrigger(pParse, pTrigger,
5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      TK_DELETE, 0, TRIGGER_AFTER, pTab, iOld, onconf, iLabel
5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  );
5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  /* Jump here if the row had already been deleted before any BEFORE
5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ** trigger programs were invoked. Or if a trigger program throws a
5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ** RAISE(IGNORE) exception.  */
5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sqlite3VdbeResolveLabel(v, iLabel);
5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** This routine generates VDBE code that causes the deletion of all
5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** index entries associated with a single row of a single table.
5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**
5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** The VDBE must be in a particular state when this routine is called.
5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** These are the requirements:
5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**
5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**   1.  A read/write cursor pointing to pTab, the table containing the row
5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**       to be deleted, must be opened as cursor number "iCur".
5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**
5785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**   2.  Read/write cursors for all indices of pTab must be open as
5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**       cursor number iCur+i for the i-th index.
5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**
5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**   3.  The "iCur" cursor must be pointing to the row that is to be
5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**       deleted.
5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/
5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void sqlite3GenerateRowIndexDelete(
5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Parse *pParse,     /* Parsing and code generating context */
5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Table *pTab,       /* Table containing the row to be deleted */
5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int iCur,          /* Cursor number for the table */
5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int *aRegIdx       /* Only delete if aRegIdx!=0 && aRegIdx[i]>0 */
5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)){
5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int i;
5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Index *pIdx;
5925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int r1;
5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for(i=1, pIdx=pTab->pIndex; pIdx; i++, pIdx=pIdx->pNext){
5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if( aRegIdx!=0 && aRegIdx[i-1]==0 ) continue;
5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    r1 = sqlite3GenerateIndexKey(pParse, pIdx, iCur, 0, 0);
5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sqlite3VdbeAddOp3(pParse->pVdbe, OP_IdxDelete, iCur+i, r1,pIdx->nColumn+1);
5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Generate code that will assemble an index key and put it in register
6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** regOut.  The key with be for index pIdx which is an index on pTab.
6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** iCur is the index of a cursor open on the pTab table and pointing to
6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** the entry that needs indexing.
6065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**
6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Return a register number which is the first in a block of
6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** registers that holds the elements of the index key.  The
6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** block of registers has already been deallocated by the time
6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** this routine returns.
6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/
6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int sqlite3GenerateIndexKey(
6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Parse *pParse,     /* Parsing context */
6145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Index *pIdx,       /* The index for which to generate a key */
6155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int iCur,          /* Cursor number for the pIdx->pTable table */
6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int regOut,        /* Write the new index key to this register */
6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int doMakeRec      /* Run the OP_MakeRecord instruction if true */
6185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)){
6195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Vdbe *v = pParse->pVdbe;
6205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int j;
6215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Table *pTab = pIdx->pTable;
6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int regBase;
6235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int nCol;
6245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  nCol = pIdx->nColumn;
6265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  regBase = sqlite3GetTempRange(pParse, nCol+1);
6275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sqlite3VdbeAddOp2(v, OP_Rowid, iCur, regBase+nCol);
6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for(j=0; j<nCol; j++){
6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int idx = pIdx->aiColumn[j];
6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if( idx==pTab->iPKey ){
6315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      sqlite3VdbeAddOp2(v, OP_SCopy, regBase+nCol, regBase+j);
6325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }else{
6335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      sqlite3VdbeAddOp3(v, OP_Column, iCur, idx, regBase+j);
6345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      sqlite3ColumnDefault(v, pTab, idx, -1);
6355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
6365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( doMakeRec ){
6385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sqlite3VdbeAddOp3(v, OP_MakeRecord, regBase, nCol+1, regOut);
6395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sqlite3VdbeChangeP4(v, -1, sqlite3IndexAffinityStr(v, pIdx), P4_TRANSIENT);
6405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sqlite3ReleaseTempRange(pParse, regBase, nCol+1);
6425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return regBase;
6435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
644