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: |
ffda1d1e1c858abd02f0c07b906cfac5 |
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
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,