/ Check-in [58cc257a]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Improvements to the DELETE code generator for the one-pass case. Avoid some OP_Goto instructions. Read content from the index cursor if the index cursor is valid and was used to locate the row that is to be deleted.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | one-writable-btree
Files: files | file ages | folders
SHA1:58cc257aeb3ce75b8d3811b568cb8a677f6730a2
User & Date: drh 2015-01-29 15:53:19
Context
2015-01-29
15:53
Improvements to the DELETE code generator for the one-pass case. Avoid some OP_Goto instructions. Read content from the index cursor if the index cursor is valid and was used to locate the row that is to be deleted. Closed-Leaf check-in: 58cc257a user: drh tags: one-writable-btree
14:48
Avoid overlength command lines in Makefile.msc when using TOP= with a large directory name. check-in: 0cdd59bf user: drh tags: one-writable-btree
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/delete.c.

   243    243     i16 nPk = 1;           /* Number of columns in the PRIMARY KEY */
   244    244     int iKey;              /* Memory cell holding key of row to be deleted */
   245    245     i16 nKey;              /* Number of memory cells in the row key */
   246    246     int iEphCur = 0;       /* Ephemeral table holding all primary key values */
   247    247     int iRowSet = 0;       /* Register for rowset of rows to delete */
   248    248     int addrBypass = 0;    /* Address of jump over the delete logic */
   249    249     int addrLoop = 0;      /* Top of the delete loop */
   250         -  int addrDelete = 0;    /* Jump directly to the delete logic */
   251    250     int addrEphOpen = 0;   /* Instruction to open the Ephemeral table */
   252    251    
   253    252   #ifndef SQLITE_OMIT_TRIGGER
   254    253     int isView;                  /* True if attempting to delete from a view */
   255    254     Trigger *pTrigger;           /* List of table triggers, if required */
   256    255   #endif
   257    256   
................................................................................
   433    432           goto delete_from_cleanup;
   434    433         }
   435    434         memset(aToOpen, 1, nIdx+1);
   436    435         aToOpen[nIdx+1] = 0;
   437    436         if( aiCurOnePass[0]>=0 ) aToOpen[aiCurOnePass[0]-iTabCur] = 0;
   438    437         if( aiCurOnePass[1]>=0 ) aToOpen[aiCurOnePass[1]-iTabCur] = 0;
   439    438         if( addrEphOpen ) sqlite3VdbeChangeToNoop(v, addrEphOpen);
   440         -      addrDelete = sqlite3VdbeAddOp0(v, OP_Goto); /* Jump to DELETE logic */
   441    439       }else if( pPk ){
   442    440         /* Construct a composite key for the row to be deleted and remember it */
   443    441         iKey = ++pParse->nMem;
   444    442         nKey = 0;   /* Zero tells OP_Found to use a composite key */
   445    443         sqlite3VdbeAddOp4(v, OP_MakeRecord, iPk, nPk, iKey,
   446    444                           sqlite3IndexAffinityStr(v, pPk), nPk);
   447    445         sqlite3VdbeAddOp2(v, OP_IdxInsert, iEphCur, iKey);
   448    446       }else{
   449    447         /* Get the rowid of the row to be deleted and remember it in the RowSet */
   450    448         nKey = 1;  /* OP_Seek always uses a single rowid */
   451    449         sqlite3VdbeAddOp2(v, OP_RowSetAdd, iRowSet, iKey);
   452    450       }
   453    451     
   454         -    /* End of the WHERE loop */
   455         -    sqlite3WhereEnd(pWInfo);
          452  +    /* End of the WHERE loop. */
   456    453       if( okOnePass ){
   457         -      /* Bypass the delete logic below if the WHERE loop found zero rows */
   458    454         addrBypass = sqlite3VdbeMakeLabel(v);
   459         -      sqlite3VdbeAddOp2(v, OP_Goto, 0, addrBypass);
   460         -      sqlite3VdbeJumpHere(v, addrDelete);
          455  +    }else{
          456  +      sqlite3WhereEnd(pWInfo);
   461    457       }
   462    458     
   463    459       /* Unless this is a view, open cursors for the table we are 
   464    460       ** deleting from and all its indices. If this is a view, then the
   465    461       ** only effect this statement has is to fire the INSTEAD OF 
   466    462       ** triggers.
   467    463       */
................................................................................
   509    505         int count = (pParse->nested==0);    /* True to count changes */
   510    506         sqlite3GenerateRowDelete(pParse, pTab, pTrigger, iDataCur, iIdxCur,
   511    507                                  iKey, nKey, count, OE_Default, okOnePass);
   512    508       }
   513    509     
   514    510       /* End of the loop over all rowids/primary-keys. */
   515    511       if( okOnePass ){
          512  +      sqlite3WhereEnd(pWInfo);
   516    513         sqlite3VdbeResolveLabel(v, addrBypass);
   517    514       }else if( pPk ){
   518    515         sqlite3VdbeAddOp2(v, OP_Next, iEphCur, addrLoop+1); VdbeCoverage(v);
   519    516         sqlite3VdbeJumpHere(v, addrLoop);
   520    517       }else{
   521    518         sqlite3VdbeAddOp2(v, OP_Goto, 0, addrLoop);
   522    519         sqlite3VdbeJumpHere(v, addrLoop);

Changes to src/vdbe.c.

  4187   4187   case OP_Delete: {
  4188   4188     VdbeCursor *pC;
  4189   4189   
  4190   4190     assert( pOp->p1>=0 && pOp->p1<p->nCursor );
  4191   4191     pC = p->apCsr[pOp->p1];
  4192   4192     assert( pC!=0 );
  4193   4193     assert( pC->pCursor!=0 );  /* Only valid for real tables, no pseudotables */
  4194         -  assert( pC->deferredMoveto==0 );
         4194  +  rc = sqlite3VdbeCursorMoveto(pC);
         4195  +  if( rc ) goto abort_due_to_error;
  4195   4196   
  4196   4197   #ifdef SQLITE_DEBUG
  4197   4198     /* The seek operation that positioned the cursor prior to OP_Delete will
  4198   4199     ** have also set the pC->movetoTarget field to the rowid of the row that
  4199   4200     ** is being deleted */
  4200   4201     if( pOp->p4.z && pC->isTable ){
  4201   4202       i64 iKey = 0;