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