/ Check-in [ffda1d1e]
Login

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

Overview
Comment:Add extra (somewhat inefficient) trace callbacks for triggers if SQLITE_TRACE_TRIGGER is defined.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trigger-trace
Files: files | file ages | folders
SHA1: ffda1d1e1c858abd02f0c07b906cfac5ad075498
User & Date: dan 2017-01-21 15:58:42
Context
2017-01-21
16:21
Fix problems in the previous commit. Leaf check-in: 74ad80eb user: dan tags: trigger-trace
15:58
Add extra (somewhat inefficient) trace callbacks for triggers if SQLITE_TRACE_TRIGGER is defined. check-in: ffda1d1e user: dan tags: trigger-trace
15:55
In the kvtest.c test utility, reuse the buffer into which blobs are read, rather than reallocating it for each row. This is a closer match to how other test programs work, and thus provides a better comparison. check-in: 0d1ad13a user: drh tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/shell.c.

   610    610   typedef struct ShellState ShellState;
   611    611   struct ShellState {
   612    612     sqlite3 *db;           /* The database */
   613    613     int echoOn;            /* True to echo input commands */
   614    614     int autoExplain;       /* Automatically turn on .explain mode */
   615    615     int autoEQP;           /* Run EXPLAIN QUERY PLAN prior to seach SQL stmt */
   616    616     int statsOn;           /* True to display memory stats before each finalize */
          617  +  int vmstepsOn;         /* Display VM steps before each finalize */
   617    618     int scanstatsOn;       /* True to display scan stats before each finalize */
   618    619     int countChanges;      /* True to display change counts */
   619    620     int backslashOn;       /* Resolve C-style \x escapes in SQL input text */
   620    621     int outCount;          /* Revert to stdout when reaching zero */
   621    622     int cnt;               /* Number of records displayed so far */
   622    623     FILE *out;             /* Write results here */
   623    624     FILE *traceOut;        /* Output for sqlite3_trace() */
................................................................................
  1992   1993         exec_prepared_stmt(pArg, pStmt, xCallback);
  1993   1994         explain_data_delete(pArg);
  1994   1995   
  1995   1996         /* print usage stats if stats on */
  1996   1997         if( pArg && pArg->statsOn ){
  1997   1998           display_stats(db, pArg, 0);
  1998   1999         }
         2000  +
         2001  +      if( pArg && pArg->vmstepsOn && pStmt ){
         2002  +        int iCur = sqlite3_stmt_status(pStmt, SQLITE_STMTSTATUS_VM_STEP, 0);
         2003  +        FILE *out = pArg->traceOut ? pArg->traceOut : pArg->out;
         2004  +        raw_printf(out, "VM steps: %d\n", iCur);
         2005  +      }
  1999   2006   
  2000   2007         /* print loop-counters if required */
  2001   2008         if( pArg && pArg->scanstatsOn ){
  2002   2009           display_scanstats(db, pArg);
  2003   2010         }
  2004   2011   
  2005   2012         /* Finalize the statement just executed. If this fails, save a
................................................................................
  5334   5341         sqlite3_file_control(p->db, zDbName, SQLITE_FCNTL_VFSNAME, &zVfsName);
  5335   5342         if( zVfsName ){
  5336   5343           utf8_printf(p->out, "%s\n", zVfsName);
  5337   5344           sqlite3_free(zVfsName);
  5338   5345         }
  5339   5346       }
  5340   5347     }else
         5348  +
         5349  +  if( c=='v' && strncmp(azArg[0], "vmsteps", n)==0 ){
         5350  +    if( nArg==2 ){
         5351  +      p->vmstepsOn = booleanValue(azArg[1]);
         5352  +    }else{
         5353  +      raw_printf(stderr, "Usage: .vmsteps ?on|off?\n");
         5354  +      rc = 1;
         5355  +    }
         5356  +  }else
         5357  +
  5341   5358   
  5342   5359   #if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_WHERETRACE)
  5343   5360     if( c=='w' && strncmp(azArg[0], "wheretrace", n)==0 ){
  5344   5361       sqlite3WhereTrace = nArg>=2 ? booleanValue(azArg[1]) : 0xff;
  5345   5362     }else
  5346   5363   #endif
  5347   5364   

Changes to src/vdbe.c.

   956    956     if( pOp->p1==SQLITE_OK && p->pFrame ){
   957    957       /* Halt the sub-program. Return control to the parent frame. */
   958    958       pFrame = p->pFrame;
   959    959       p->pFrame = pFrame->pParent;
   960    960       p->nFrame--;
   961    961       sqlite3VdbeSetChanges(db, p->nChange);
   962    962       pcx = sqlite3VdbeFrameRestore(pFrame);
          963  +#ifdef SQLITE_TRACE_TRIGGER
          964  +    if( (db->mTrace & SQLITE_TRACE_STMT) && aOp[0].p4.z ){
          965  +      int nNest = 0;
          966  +      VdbeFrame *pF;
          967  +      int nTotal = nVmStep - pFrame->nVmStep;
          968  +      char *zTrace;
          969  +      assert( db->xTrace );
          970  +      for(pF=p->pFrame; pF; pF=pF->pParent) nNest++;
          971  +      zTrace = sqlite3_mprintf("%.*s%s completed (VM steps: total=%d self=%d)", 
          972  +          nNest, "                                                    :",
          973  +          aOp[0].p4.z, nTotal, nVmStep - pFrame->nVmStepAdj
          974  +      );
          975  +      if( zTrace ){
          976  +        (void)db->xTrace(SQLITE_TRACE_STMT, db->pTraceArg, 0, zTrace);
          977  +        sqlite3_free(zTrace);
          978  +      }
          979  +      if( p->pFrame ){
          980  +        p->pFrame->nVmStepAdj += nTotal;
          981  +      }
          982  +    }
          983  +#endif
   963    984       lastRowid = db->lastRowid;
   964    985       if( pOp->p2==OE_Ignore ){
   965    986         /* Instruction pcx is the OP_Program that invoked the sub-program 
   966    987         ** currently being halted. If the p2 instruction of this OP_Halt
   967    988         ** instruction is set to OE_Ignore, then the sub-program is throwing
   968    989         ** an IGNORE exception. In this case jump to the address specified
   969    990         ** as the p2 of the calling OP_Program.  */
................................................................................
  5829   5850       pFrame->nCursor = p->nCursor;
  5830   5851       pFrame->aOp = p->aOp;
  5831   5852       pFrame->nOp = p->nOp;
  5832   5853       pFrame->token = pProgram->token;
  5833   5854   #ifdef SQLITE_ENABLE_STMT_SCANSTATUS
  5834   5855       pFrame->anExec = p->anExec;
  5835   5856   #endif
         5857  +#ifdef SQLITE_TRACE_TRIGGER
         5858  +    pFrame->nVmStep = nVmStep;
         5859  +    pFrame->nVmStepAdj = nVmStep;
         5860  +#endif
  5836   5861   
  5837   5862       pEnd = &VdbeFrameMem(pFrame)[pFrame->nChildMem];
  5838   5863       for(pMem=VdbeFrameMem(pFrame); pMem!=pEnd; pMem++){
  5839   5864         pMem->flags = MEM_Undefined;
  5840   5865         pMem->db = db;
  5841   5866       }
  5842   5867     }else{
................................................................................
  6885   6910   #ifndef SQLITE_OMIT_DEPRECATED
  6886   6911       if( db->mTrace & SQLITE_TRACE_LEGACY ){
  6887   6912         void (*x)(void*,const char*) = (void(*)(void*,const char*))db->xTrace;
  6888   6913         char *z = sqlite3VdbeExpandSql(p, zTrace);
  6889   6914         x(db->pTraceArg, z);
  6890   6915         sqlite3_free(z);
  6891   6916       }else
         6917  +#endif
         6918  +#ifdef SQLITE_TRACE_TRIGGER
         6919  +    if( p->pFrame ){
         6920  +      int nNest = -1;
         6921  +      VdbeFrame *pFrame;
         6922  +      for(pFrame=p->pFrame; pFrame; pFrame=pFrame->pParent) nNest++;
         6923  +      zTrace = sqlite3_mprintf("%.*s%s",
         6924  +          nNest, "                                                    :", zTrace
         6925  +      );
         6926  +      if( zTrace ){
         6927  +        (void)db->xTrace(SQLITE_TRACE_STMT, db->pTraceArg, p, zTrace);
         6928  +        sqlite3_free(zTrace);
         6929  +      }
         6930  +    }else
  6892   6931   #endif
  6893   6932       {
  6894   6933         (void)db->xTrace(SQLITE_TRACE_STMT, db->pTraceArg, p, zTrace);
  6895   6934       }
  6896   6935     }
  6897   6936   #ifdef SQLITE_USE_FCNTL_TRACE
  6898   6937     zTrace = (pOp->p4.z ? pOp->p4.z : p->zSql);

Changes to src/vdbeInt.h.

   171    171     int pc;                 /* Program Counter in parent (calling) frame */
   172    172     int nOp;                /* Size of aOp array */
   173    173     int nMem;               /* Number of entries in aMem */
   174    174     int nChildMem;          /* Number of memory cells for child frame */
   175    175     int nChildCsr;          /* Number of cursors for child frame */
   176    176     int nChange;            /* Statement changes (Vdbe.nChange)     */
   177    177     int nDbChange;          /* Value of db->nChange */
          178  +#ifdef SQLITE_TRACE_TRIGGER
          179  +  int nVmStep;            /* Value of nVmStep at start of program */
          180  +  int nVmStepAdj;         /* Adjusted for nested programs */
          181  +#endif
   178    182   };
   179    183   
   180    184   #define VdbeFrameMem(p) ((Mem *)&((u8 *)p)[ROUND8(sizeof(VdbeFrame))])
   181    185   
   182    186   /*
   183    187   ** Internally, the vdbe manipulates nearly all SQL values as Mem
   184    188   ** structures. Each Mem struct may cache multiple representations (string,