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