Annotation of embedaddon/sqlite3/src/delete.c, revision 1.1.1.1

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

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>