/* ** Execute the statement pStmt, either until a row of data is ready, the ** statement is completely executed or an error occurs. ** ** This routine implements the bulk of the logic behind the sqlite_step() ** API. The only thing omitted is the automatic recompile if a ** schema change has occurred. That detail is handled by the ** outer sqlite3_step() wrapper procedure. */ static int sqlite3Step(Vdbe *p){ sqlite3 *db; int rc; /* Assert that malloc() has not failed */ assert( !sqlite3MallocFailed() ); if( p==0 || p->magic!=VDBE_MAGIC_RUN ){ return SQLITE_MISUSE; } if( p->aborted ){ return SQLITE_ABORT; } if( p->pc<=0 && p->expired ){ if( p->rc==SQLITE_OK ){ p->rc = SQLITE_SCHEMA; } rc = SQLITE_ERROR; goto end_of_step; } db = p->db; if( sqlite3SafetyOn(db) ){ p->rc = SQLITE_MISUSE; return SQLITE_MISUSE; } if( p->pc<0 ){ /* If there are no other statements currently running, then ** reset the interrupt flag. This prevents a call to sqlite3_interrupt ** from interrupting a statement that has not yet started. */ if( db->activeVdbeCnt==0 ){ db->u1.isInterrupted = 0; } #ifndef SQLITE_OMIT_TRACE /* Invoke the trace callback if there is one */ if( db->xTrace && !db->init.busy ){ assert( p->nOp>0 ); assert( p->aOp[p->nOp-1].opcode==OP_Noop ); assert( p->aOp[p->nOp-1].p3!=0 ); assert( p->aOp[p->nOp-1].p3type==P3_DYNAMIC ); sqlite3SafetyOff(db); db->xTrace(db->pTraceArg, p->aOp[p->nOp-1].p3); if( sqlite3SafetyOn(db) ){ p->rc = SQLITE_MISUSE; return SQLITE_MISUSE; } } if( db->xProfile && !db->init.busy ){ double rNow; sqlite3OsCurrentTime(&rNow); p->startTime = (rNow - (int)rNow)*3600.0*24.0*1000000000.0; } #endif /* Print a copy of SQL as it is executed if the SQL_TRACE pragma is turned ** on in debugging mode. */ #ifdef SQLITE_DEBUG if( (db->flags & SQLITE_SqlTrace)!=0 ){ sqlite3DebugPrintf("SQL-trace: %s\n", p->aOp[p->nOp-1].p3); } #endif /* SQLITE_DEBUG */ db->activeVdbeCnt++; p->pc = 0; } #ifndef SQLITE_OMIT_EXPLAIN if( p->explain ){ rc = sqlite3VdbeList(p); }else #endif /* SQLITE_OMIT_EXPLAIN */ { rc = sqlite3VdbeExec(p); } if( sqlite3SafetyOff(db) ){ rc = SQLITE_MISUSE; } #ifndef SQLITE_OMIT_TRACE /* Invoke the profile callback if there is one */ if( rc!=SQLITE_ROW && db->xProfile && !db->init.busy ){ double rNow; u64 elapseTime; sqlite3OsCurrentTime(&rNow); elapseTime = (rNow - (int)rNow)*3600.0*24.0*1000000000.0 - p->startTime; assert( p->nOp>0 ); assert( p->aOp[p->nOp-1].opcode==OP_Noop ); assert( p->aOp[p->nOp-1].p3!=0 ); assert( p->aOp[p->nOp-1].p3type==P3_DYNAMIC ); db->xProfile(db->pProfileArg, p->aOp[p->nOp-1].p3, elapseTime); } #endif sqlite3Error(p->db, rc, 0); p->rc = sqlite3ApiExit(p->db, p->rc); end_of_step: assert( (rc&0xff)==rc ); if( p->zSql && (rc&0xff)<SQLITE_ROW ){ /* This behavior occurs if sqlite3_prepare_v2() was used to build ** the prepared statement. Return error codes directly */ return p->rc; }else{ /* This is for legacy sqlite3_prepare() builds and when the code ** is SQLITE_ROW or SQLITE_DONE */ return rc; } }
/* ** Execute the statement pStmt, either until a row of data is ready, the ** statement is completely executed or an error occurs. */ int sqlite3_step(sqlite3_stmt *pStmt){ Vdbe *p = (Vdbe*)pStmt; sqlite3 *db; int rc; if( p==0 || p->magic!=VDBE_MAGIC_RUN ){ return SQLITE_MISUSE; } if( p->aborted ){ return SQLITE_ABORT; } if( p->pc<=0 && p->expired ){ if( p->rc==SQLITE_OK ){ p->rc = SQLITE_SCHEMA; } return SQLITE_ERROR; } db = p->db; if( sqlite3SafetyOn(db) ){ p->rc = SQLITE_MISUSE; return SQLITE_MISUSE; } if( p->pc<0 ){ #ifndef SQLITE_OMIT_TRACE /* Invoke the trace callback if there is one */ if( db->xTrace && !db->init.busy ){ assert( p->nOp>0 ); assert( p->aOp[p->nOp-1].opcode==OP_Noop ); assert( p->aOp[p->nOp-1].p3!=0 ); assert( p->aOp[p->nOp-1].p3type==P3_DYNAMIC ); sqlite3SafetyOff(db); db->xTrace(db->pTraceArg, p->aOp[p->nOp-1].p3); if( sqlite3SafetyOn(db) ){ p->rc = SQLITE_MISUSE; return SQLITE_MISUSE; } } if( db->xProfile && !db->init.busy ){ double rNow; sqlite3OsCurrentTime(&rNow); p->startTime = (rNow - (int)rNow)*3600.0*24.0*1000000000.0; } #endif /* Print a copy of SQL as it is executed if the SQL_TRACE pragma is turned ** on in debugging mode. */ #ifdef SQLITE_DEBUG if( (db->flags & SQLITE_SqlTrace)!=0 ){ sqlite3DebugPrintf("SQL-trace: %s\n", p->aOp[p->nOp-1].p3); } #endif /* SQLITE_DEBUG */ db->activeVdbeCnt++; p->pc = 0; } #ifndef SQLITE_OMIT_EXPLAIN if( p->explain ){ rc = sqlite3VdbeList(p); }else #endif /* SQLITE_OMIT_EXPLAIN */ { rc = sqlite3VdbeExec(p); } if( sqlite3SafetyOff(db) ){ rc = SQLITE_MISUSE; } #ifndef SQLITE_OMIT_TRACE /* Invoke the profile callback if there is one */ if( rc!=SQLITE_ROW && db->xProfile && !db->init.busy ){ double rNow; u64 elapseTime; sqlite3OsCurrentTime(&rNow); elapseTime = (rNow - (int)rNow)*3600.0*24.0*1000000000.0 - p->startTime; assert( p->nOp>0 ); assert( p->aOp[p->nOp-1].opcode==OP_Noop ); assert( p->aOp[p->nOp-1].p3!=0 ); assert( p->aOp[p->nOp-1].p3type==P3_DYNAMIC ); db->xProfile(db->pProfileArg, p->aOp[p->nOp-1].p3, elapseTime); } #endif sqlite3Error(p->db, rc, p->zErrMsg ? "%s" : 0, p->zErrMsg); return rc; }