diff options
Diffstat (limited to 'src/vdbeaux.c')
-rw-r--r-- | src/vdbeaux.c | 55 |
1 files changed, 36 insertions, 19 deletions
diff --git a/src/vdbeaux.c b/src/vdbeaux.c index fd196f37b..e7cd61f05 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -268,10 +268,6 @@ int sqlite3VdbeAddOp3(Vdbe *p, int op, int p1, int p2, int p3){ test_addop_breakpoint(i, &p->aOp[i]); } #endif -#ifdef VDBE_PROFILE - pOp->cycles = 0; - pOp->cnt = 0; -#endif #ifdef SQLITE_VDBE_COVERAGE pOp->iSrcLine = 0; #endif @@ -439,8 +435,9 @@ void sqlite3ExplainBreakpoint(const char *z1, const char *z2){ ** If the bPush flag is true, then make this opcode the parent for ** subsequent Explains until sqlite3VdbeExplainPop() is called. */ -void sqlite3VdbeExplain(Parse *pParse, u8 bPush, const char *zFmt, ...){ -#ifndef SQLITE_DEBUG +int sqlite3VdbeExplain(Parse *pParse, u8 bPush, const char *zFmt, ...){ + int addr = 0; +#if !defined(SQLITE_DEBUG) && !defined(SQLITE_ENABLE_STMT_SCANSTATUS) /* Always include the OP_Explain opcodes if SQLITE_DEBUG is defined. ** But omit them (for performance) during production builds */ if( pParse->explain==2 ) @@ -455,13 +452,15 @@ void sqlite3VdbeExplain(Parse *pParse, u8 bPush, const char *zFmt, ...){ va_end(ap); v = pParse->pVdbe; iThis = v->nOp; - sqlite3VdbeAddOp4(v, OP_Explain, iThis, pParse->addrExplain, 0, + addr = sqlite3VdbeAddOp4(v, OP_Explain, iThis, pParse->addrExplain, 0, zMsg, P4_DYNAMIC); sqlite3ExplainBreakpoint(bPush?"PUSH":"", sqlite3VdbeGetLastOp(v)->p4.z); if( bPush){ pParse->addrExplain = iThis; } + sqlite3VdbeScanStatus(v, iThis, 0, 0, 0, 0); } + return addr; } /* @@ -1119,6 +1118,7 @@ void sqlite3VdbeScanStatus( aNew = (ScanStatus*)sqlite3DbRealloc(p->db, p->aScan, nByte); if( aNew ){ ScanStatus *pNew = &aNew[p->nScan++]; + memset(pNew, 0, sizeof(ScanStatus)); pNew->addrExplain = addrExplain; pNew->addrLoop = addrLoop; pNew->addrVisit = addrVisit; @@ -1127,6 +1127,19 @@ void sqlite3VdbeScanStatus( p->aScan = aNew; } } + +void sqlite3VdbeScanStatusEnd(Vdbe *p, int addrExplain){ + ScanStatus *pScan = 0; + int ii; + for(ii=p->nScan-1; ii>=0; ii--){ + pScan = &p->aScan[ii]; + if( pScan->addrExplain==addrExplain ) break; + pScan = 0; + } + if( pScan ){ + pScan->addrEndRange = sqlite3VdbeCurrentAddr(p)-1; + } +} #endif @@ -2424,7 +2437,7 @@ static void *allocSpace( ** running it. */ void sqlite3VdbeRewind(Vdbe *p){ -#if defined(SQLITE_DEBUG) || defined(VDBE_PROFILE) +#if defined(SQLITE_DEBUG) int i; #endif assert( p!=0 ); @@ -2452,10 +2465,8 @@ void sqlite3VdbeRewind(Vdbe *p){ p->iStatement = 0; p->nFkConstraint = 0; #ifdef VDBE_PROFILE - for(i=0; i<p->nOp; i++){ - p->aOp[i].cnt = 0; - p->aOp[i].cycles = 0; - } + memset(p->anExec, 0, sizeof(i64)*p->nOp); + memset(p->anCycle, 0, sizeof(u64)*p->nOp); #endif } @@ -2563,8 +2574,9 @@ void sqlite3VdbeMakeReady( p->aVar = allocSpace(&x, 0, nVar*sizeof(Mem)); p->apArg = allocSpace(&x, 0, nArg*sizeof(Mem*)); p->apCsr = allocSpace(&x, 0, nCursor*sizeof(VdbeCursor*)); -#ifdef SQLITE_ENABLE_STMT_SCANSTATUS +#if defined(SQLITE_ENABLE_STMT_SCANSTATUS) || defined(VDBE_PROFILE) p->anExec = allocSpace(&x, 0, p->nOp*sizeof(i64)); + p->anCycle = allocSpace(&x, 0, p->nOp*sizeof(u64)); #endif if( x.nNeeded ){ x.pSpace = p->pFree = sqlite3DbMallocRawNN(db, x.nNeeded); @@ -2574,8 +2586,9 @@ void sqlite3VdbeMakeReady( p->aVar = allocSpace(&x, p->aVar, nVar*sizeof(Mem)); p->apArg = allocSpace(&x, p->apArg, nArg*sizeof(Mem*)); p->apCsr = allocSpace(&x, p->apCsr, nCursor*sizeof(VdbeCursor*)); -#ifdef SQLITE_ENABLE_STMT_SCANSTATUS +#if defined(SQLITE_ENABLE_STMT_SCANSTATUS) || defined(VDBE_PROFILE) p->anExec = allocSpace(&x, p->anExec, p->nOp*sizeof(i64)); + p->anCycle = allocSpace(&x, p->anCycle, p->nOp*sizeof(u64)); #endif } } @@ -2591,8 +2604,9 @@ void sqlite3VdbeMakeReady( p->nMem = nMem; initMemArray(p->aMem, nMem, db, MEM_Undefined); memset(p->apCsr, 0, nCursor*sizeof(VdbeCursor*)); -#ifdef SQLITE_ENABLE_STMT_SCANSTATUS +#if defined(SQLITE_ENABLE_STMT_SCANSTATUS) || defined(VDBE_PROFILE) memset(p->anExec, 0, p->nOp*sizeof(i64)); + memset(p->anCycle, 0, p->nOp*sizeof(u64)); #endif } sqlite3VdbeRewind(p); @@ -2651,8 +2665,9 @@ static void closeCursorsInFrame(Vdbe *p){ int sqlite3VdbeFrameRestore(VdbeFrame *pFrame){ Vdbe *v = pFrame->v; closeCursorsInFrame(v); -#ifdef SQLITE_ENABLE_STMT_SCANSTATUS +#if defined(SQLITE_ENABLE_STMT_SCANSTATUS) || defined(VDBE_PROFILE) v->anExec = pFrame->anExec; + v->anCycle = pFrame->anCycle; #endif v->aOp = pFrame->aOp; v->nOp = pFrame->nOp; @@ -3485,10 +3500,12 @@ int sqlite3VdbeReset(Vdbe *p){ } for(i=0; i<p->nOp; i++){ char zHdr[100]; + i64 cnt = p->anExec[i]; + i64 cycles = p->anCycle[i]; sqlite3_snprintf(sizeof(zHdr), zHdr, "%6u %12llu %8llu ", - p->aOp[i].cnt, - p->aOp[i].cycles, - p->aOp[i].cnt>0 ? p->aOp[i].cycles/p->aOp[i].cnt : 0 + cnt, + cycles, + cnt>0 ? cycles/cnt : 0 ); fprintf(out, "%s", zHdr); sqlite3VdbePrintOp(out, i, &p->aOp[i]); |