/ Check-in [47887ef8]
Login

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

Overview
Comment:Simplifications and clarification to update callback handling in the OP_Delete and OP_Insert opcodes.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 47887ef89ed60ddb869d65e0957c1c4b2115f169
User & Date: drh 2016-03-30 15:30:07
Context
2016-03-30
16:22
Fix typo in comment. No changes to code. check-in: 64d75cbe user: mistachkin tags: trunk
15:30
Simplifications and clarification to update callback handling in the OP_Delete and OP_Insert opcodes. check-in: 47887ef8 user: drh tags: trunk
14:26
Increase the version number to 3.13.0 on account of the new session extension. check-in: e9bcd5ac user: drh tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/sqliteInt.h.

  2923   2923   struct AuthContext {
  2924   2924     const char *zAuthContext;   /* Put saved Parse.zAuthContext here */
  2925   2925     Parse *pParse;              /* The Parse structure */
  2926   2926   };
  2927   2927   
  2928   2928   /*
  2929   2929   ** Bitfield flags for P5 value in various opcodes.
  2930         -**
  2931         -** Note that the values for ISNOOP and LENGTHARG are the same.  But as 
  2932         -** those bits are never used on the same opcode, the overlap is harmless.
  2933   2930   */
  2934   2931   #define OPFLAG_NCHANGE       0x01    /* OP_Insert: Set to update db->nChange */
  2935   2932                                        /* Also used in P2 (not P5) of OP_Delete */
  2936   2933   #define OPFLAG_EPHEM         0x01    /* OP_Column: Ephemeral output is ok */
  2937   2934   #define OPFLAG_LASTROWID     0x02    /* Set to update db->lastRowid */
  2938   2935   #define OPFLAG_ISUPDATE      0x04    /* This OP_Insert is an sql UPDATE */
  2939   2936   #define OPFLAG_APPEND        0x08    /* This is likely to be an append */
  2940   2937   #define OPFLAG_USESEEKRESULT 0x10    /* Try to avoid a seek in BtreeInsert() */
         2938  +#ifdef SQLITE_ENABLE_PREUPDATE_HOOK
  2941   2939   #define OPFLAG_ISNOOP        0x40    /* OP_Delete does pre-update-hook only */
         2940  +#endif
  2942   2941   #define OPFLAG_LENGTHARG     0x40    /* OP_Column only used for length() */
  2943   2942   #define OPFLAG_TYPEOFARG     0x80    /* OP_Column only used for typeof() */
  2944   2943   #define OPFLAG_BULKCSR       0x01    /* OP_Open** used to open bulk cursor */
  2945   2944   #define OPFLAG_SEEKEQ        0x02    /* OP_Open** cursor uses EQ seek only */
  2946   2945   #define OPFLAG_FORDELETE     0x08    /* OP_Open should use BTREE_FORDELETE */
  2947   2946   #define OPFLAG_P2ISREG       0x10    /* P2 to OP_Open** is a register number */
  2948   2947   #define OPFLAG_PERMUTE       0x01    /* OP_Compare: use the permutation */

Changes to src/vdbe.c.

  4313   4313     }
  4314   4314   
  4315   4315     if( pOp->p4type==P4_TABLE && HAS_UPDATE_HOOK(db) ){
  4316   4316       assert( pC->isTable );
  4317   4317       assert( pC->iDb>=0 );
  4318   4318       zDb = db->aDb[pC->iDb].zName;
  4319   4319       pTab = pOp->p4.pTab;
         4320  +    assert( HasRowid(pTab) );
  4320   4321       op = ((pOp->p5 & OPFLAG_ISUPDATE) ? SQLITE_UPDATE : SQLITE_INSERT);
  4321   4322     }else{
  4322   4323       pTab = 0; /* Not needed.  Silence a comiler warning. */
  4323   4324       zDb = 0;  /* Not needed.  Silence a compiler warning. */
  4324   4325     }
  4325   4326   
  4326   4327   #ifdef SQLITE_ENABLE_PREUPDATE_HOOK
  4327   4328     /* Invoke the pre-update hook, if any */
  4328   4329     if( db->xPreUpdateCallback 
  4329   4330      && pOp->p4type==P4_TABLE
  4330   4331      && !(pOp->p5 & OPFLAG_ISUPDATE)
  4331         -   && HasRowid(pTab)
  4332   4332     ){
  4333   4333       sqlite3VdbePreUpdateHook(p, pC, SQLITE_INSERT, zDb, pTab, iKey, pOp->p2);
  4334   4334     }
  4335   4335   #endif
  4336   4336   
  4337   4337     if( pOp->p5 & OPFLAG_NCHANGE ) p->nChange++;
  4338   4338     if( pOp->p5 & OPFLAG_LASTROWID ) db->lastRowid = lastRowid = iKey;
................................................................................
  4353   4353                             (pOp->p5 & OPFLAG_APPEND)!=0, seekResult
  4354   4354     );
  4355   4355     pC->deferredMoveto = 0;
  4356   4356     pC->cacheStatus = CACHE_STALE;
  4357   4357   
  4358   4358     /* Invoke the update-hook if required. */
  4359   4359     if( rc ) goto abort_due_to_error;
  4360         -  if( db->xUpdateCallback && op && HasRowid(pTab) ){
         4360  +  if( db->xUpdateCallback && op ){
  4361   4361       db->xUpdateCallback(db->pUpdateArg, op, zDb, pTab->zName, iKey);
  4362   4362     }
  4363   4363     break;
  4364   4364   }
  4365   4365   
  4366   4366   /* Opcode: Delete P1 P2 P3 P4 P5
  4367   4367   **
................................................................................
  4424   4424   #endif
  4425   4425   
  4426   4426     /* If the update-hook or pre-update-hook will be invoked, set zDb to
  4427   4427     ** the name of the db to pass as to it. Also set local pTab to a copy
  4428   4428     ** of p4.pTab. Finally, if p5 is true, indicating that this cursor was
  4429   4429     ** last moved with OP_Next or OP_Prev, not Seek or NotFound, set 
  4430   4430     ** VdbeCursor.movetoTarget to the current rowid.  */
  4431         -  if( pOp->p4.pTab && HAS_UPDATE_HOOK(db) ){
         4431  +  if( pOp->p4type==P4_TABLE && HAS_UPDATE_HOOK(db) ){
  4432   4432       assert( pC->iDb>=0 );
         4433  +    assert( pOp->p4.pTab!=0 );
  4433   4434       zDb = db->aDb[pC->iDb].zName;
  4434   4435       pTab = pOp->p4.pTab;
  4435         -    if( pOp->p5 && pC->isTable ){
         4436  +    if( (pOp->p5 & OPFLAG_SAVEPOSITION)!=0 && pC->isTable ){
  4436   4437         sqlite3BtreeKeySize(pC->uc.pCursor, &pC->movetoTarget);
  4437   4438       }
  4438   4439     }else{
  4439   4440       zDb = 0;   /* Not needed.  Silence a compiler warning. */
  4440   4441       pTab = 0;  /* Not needed.  Silence a compiler warning. */
  4441   4442     }
  4442   4443   
................................................................................
  4446   4447       assert( !(opflags & OPFLAG_ISUPDATE) || (aMem[pOp->p3].flags & MEM_Int) );
  4447   4448       sqlite3VdbePreUpdateHook(p, pC,
  4448   4449           (opflags & OPFLAG_ISUPDATE) ? SQLITE_UPDATE : SQLITE_DELETE, 
  4449   4450           zDb, pTab, pC->movetoTarget,
  4450   4451           pOp->p3
  4451   4452       );
  4452   4453     }
  4453         -#endif
  4454         -
  4455   4454     if( opflags & OPFLAG_ISNOOP ) break;
         4455  +#endif
  4456   4456    
  4457   4457     /* Only flags that can be set are SAVEPOISTION and AUXDELETE */ 
  4458   4458     assert( (pOp->p5 & ~(OPFLAG_SAVEPOSITION|OPFLAG_AUXDELETE))==0 );
  4459   4459     assert( OPFLAG_SAVEPOSITION==BTREE_SAVEPOSITION );
  4460   4460     assert( OPFLAG_AUXDELETE==BTREE_AUXDELETE );
  4461   4461   
  4462   4462   #ifdef SQLITE_DEBUG
................................................................................
  4476   4476     rc = sqlite3BtreeDelete(pC->uc.pCursor, pOp->p5);
  4477   4477     pC->cacheStatus = CACHE_STALE;
  4478   4478     if( rc ) goto abort_due_to_error;
  4479   4479   
  4480   4480     /* Invoke the update-hook if required. */
  4481   4481     if( opflags & OPFLAG_NCHANGE ){
  4482   4482       p->nChange++;
  4483         -    if( rc==SQLITE_OK && db->xUpdateCallback && HasRowid(pTab) ){
         4483  +    if( db->xUpdateCallback && HasRowid(pTab) ){
  4484   4484         db->xUpdateCallback(db->pUpdateArg, SQLITE_DELETE, zDb, pTab->zName,
  4485   4485             pC->movetoTarget);
  4486   4486         assert( pC->iDb>=0 );
  4487   4487       }
  4488   4488     }
  4489   4489   
  4490   4490     break;