diff options
Diffstat (limited to 'src/vdbe.c')
-rw-r--r-- | src/vdbe.c | 38 |
1 files changed, 21 insertions, 17 deletions
diff --git a/src/vdbe.c b/src/vdbe.c index c354d3e27..2c9edf897 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -565,7 +565,7 @@ int sqlite3VdbeExec( int iCompare = 0; /* Result of last OP_Compare operation */ unsigned nVmStep = 0; /* Number of virtual machine steps */ #ifndef SQLITE_OMIT_PROGRESS_CALLBACK - unsigned nProgressOps = 0; /* nVmStep at last progress callback. */ + unsigned nProgressLimit; /* Invoke xProgress() when nVmStep reaches this */ #endif Mem *aMem = p->aMem; /* Copy of p->aMem */ Mem *pIn1 = 0; /* 1st input operand */ @@ -595,6 +595,17 @@ int sqlite3VdbeExec( db->busyHandler.nBusy = 0; CHECK_FOR_INTERRUPT; sqlite3VdbeIOTraceSql(p); +#ifndef SQLITE_OMIT_PROGRESS_CALLBACK + if( db->xProgress ){ + assert( 0 < db->nProgressOps ); + nProgressLimit = (unsigned)p->aCounter[SQLITE_STMTSTATUS_VM_STEP-1]; + if( nProgressLimit==0 ){ + nProgressLimit = db->nProgressOps; + }else{ + nProgressLimit %= (unsigned)db->nProgressOps; + } + } +#endif #ifdef SQLITE_DEBUG sqlite3BeginBenignMalloc(); if( p->pc==0 && (p->db->flags & SQLITE_VdbeListing)!=0 ){ @@ -755,14 +766,16 @@ check_for_interrupt: ** If the progress callback returns non-zero, exit the virtual machine with ** a return code SQLITE_ABORT. */ - if( db->xProgress!=0 && (nVmStep - nProgressOps)>=db->nProgressOps ){ + if( db->xProgress!=0 && nVmStep>=nProgressLimit ){ int prc; prc = db->xProgress(db->pProgressArg); if( prc!=0 ){ rc = SQLITE_INTERRUPT; goto vdbe_error_halt; } - nProgressOps = nVmStep; + if( db->xProgress!=0 ){ + nProgressLimit = nVmStep + db->nProgressOps - (nVmStep%db->nProgressOps); + } } #endif @@ -1430,19 +1443,14 @@ case OP_Function: { REGISTER_TRACE(pOp->p2+i, pArg); } - assert( pOp->p4type==P4_FUNCDEF || pOp->p4type==P4_VDBEFUNC ); - if( pOp->p4type==P4_FUNCDEF ){ - ctx.pFunc = pOp->p4.pFunc; - ctx.pVdbeFunc = 0; - }else{ - ctx.pVdbeFunc = (VdbeFunc*)pOp->p4.pVdbeFunc; - ctx.pFunc = ctx.pVdbeFunc->pFunc; - } - + assert( pOp->p4type==P4_FUNCDEF ); + ctx.pFunc = pOp->p4.pFunc; ctx.s.flags = MEM_Null; ctx.s.db = db; ctx.s.xDel = 0; ctx.s.zMalloc = 0; + ctx.iOp = pc; + ctx.pVdbe = p; /* The output cell may already have a buffer allocated. Move ** the pointer to ctx.s so in case the user-function can use @@ -1465,11 +1473,7 @@ case OP_Function: { /* If any auxiliary data functions have been called by this user function, ** immediately call the destructor for any non-static values. */ - if( ctx.pVdbeFunc ){ - sqlite3VdbeDeleteAuxData(ctx.pVdbeFunc, pOp->p1); - pOp->p4.pVdbeFunc = ctx.pVdbeFunc; - pOp->p4type = P4_VDBEFUNC; - } + sqlite3VdbeDeleteAuxData(p, pc, pOp->p1); if( db->mallocFailed ){ /* Even though a malloc() has failed, the implementation of the |