Index: src/shell.c
==================================================================
--- src/shell.c
+++ src/shell.c
@@ -1107,10 +1107,12 @@
fprintf(pArg->out, "Fullscan Steps: %d\n", iCur);
iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_SORT, bReset);
fprintf(pArg->out, "Sort Operations: %d\n", iCur);
iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_AUTOINDEX, bReset);
fprintf(pArg->out, "Autoindex Inserts: %d\n", iCur);
+ iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_VM_STEP, bReset);
+ fprintf(pArg->out, "Virtual Machine Steps: %d\n", iCur);
}
return 0;
}
Index: src/sqlite.h.in
==================================================================
--- src/sqlite.h.in
+++ src/sqlite.h.in
@@ -6301,15 +6301,25 @@
**
^This is the number of rows inserted into transient indices that
** were created automatically in order to help joins run faster.
** A non-zero value in this counter may indicate an opportunity to
** improvement performance by adding permanent indices that do not
** need to be reinitialized each time the statement is run.
+**
+** [[SQLITE_STMTSTATUS_VM_STEP]] SQLITE_STMTSTATUS_VM_STEP
+** ^This is the number of virtual machine operations executed
+** by the prepared statement if that number is less than or equal
+** to 2147483647. The number of virtual machine operations can be
+** used as a proxy for the total work done by the prepared statement.
+** If the number of virtual machine operations exceeds 2147483647
+** then the value returned by this statement status code is undefined.
+**
**
*/
#define SQLITE_STMTSTATUS_FULLSCAN_STEP 1
#define SQLITE_STMTSTATUS_SORT 2
#define SQLITE_STMTSTATUS_AUTOINDEX 3
+#define SQLITE_STMTSTATUS_VM_STEP 4
/*
** CAPI3REF: Custom Page Cache Object
**
** The sqlite3_pcache type is opaque. It is implemented by
Index: src/test1.c
==================================================================
--- src/test1.c
+++ src/test1.c
@@ -2216,10 +2216,11 @@
int op;
} aOp[] = {
{ "SQLITE_STMTSTATUS_FULLSCAN_STEP", SQLITE_STMTSTATUS_FULLSCAN_STEP },
{ "SQLITE_STMTSTATUS_SORT", SQLITE_STMTSTATUS_SORT },
{ "SQLITE_STMTSTATUS_AUTOINDEX", SQLITE_STMTSTATUS_AUTOINDEX },
+ { "SQLITE_STMTSTATUS_VM_STEP", SQLITE_STMTSTATUS_VM_STEP },
};
if( objc!=4 ){
Tcl_WrongNumArgs(interp, 1, objv, "STMT PARAMETER RESETFLAG");
return TCL_ERROR;
}
Index: src/vdbe.c
==================================================================
--- src/vdbe.c
+++ src/vdbe.c
@@ -554,16 +554,17 @@
u8 encoding = ENC(db); /* The database encoding */
#ifndef SQLITE_OMIT_PROGRESS_CALLBACK
int checkProgress; /* True if progress callbacks are enabled */
int nProgressOps = 0; /* Opcodes executed since progress callback. */
#endif
+ int iCompare = 0; /* Result of last OP_Compare operation */
+ unsigned nVmStep = 0; /* Number of virtual machine steps */
Mem *aMem = p->aMem; /* Copy of p->aMem */
Mem *pIn1 = 0; /* 1st input operand */
Mem *pIn2 = 0; /* 2nd input operand */
Mem *pIn3 = 0; /* 3rd input operand */
Mem *pOut = 0; /* Output operand */
- int iCompare = 0; /* Result of last OP_Compare operation */
int *aPermute = 0; /* Permutation of columns for OP_Compare */
i64 lastRowid = db->lastRowid; /* Saved value of the last insert ROWID */
#ifdef VDBE_PROFILE
u64 start; /* CPU clock count at start of opcode */
int origPc; /* Program counter at start of opcode */
@@ -604,10 +605,11 @@
if( db->mallocFailed ) goto no_mem;
#ifdef VDBE_PROFILE
origPc = pc;
start = sqlite3Hwtime();
#endif
+ nVmStep++;
pOp = &aOp[pc];
/* Only allow tracing if SQLITE_DEBUG is defined.
*/
#ifdef SQLITE_DEBUG
@@ -6198,10 +6200,11 @@
/* This is the only way out of this procedure. We have to
** release the mutexes on btrees that were acquired at the
** top. */
vdbe_return:
db->lastRowid = lastRowid;
+ p->aCounter[SQLITE_STMTSTATUS_VM_STEP-1] += (int)nVmStep;
sqlite3VdbeLeave(p);
return rc;
/* Jump to here if a string or blob larger than SQLITE_MAX_LENGTH
** is encountered.
Index: src/vdbeInt.h
==================================================================
--- src/vdbeInt.h
+++ src/vdbeInt.h
@@ -342,11 +342,11 @@
bft doingRerun:1; /* True if rerunning after an auto-reprepare */
int nChange; /* Number of db changes made since last reset */
yDbMask btreeMask; /* Bitmask of db->aDb[] entries referenced */
yDbMask lockMask; /* Subset of btreeMask that requires a lock */
int iStatement; /* Statement number (or 0 if has not opened stmt) */
- int aCounter[3]; /* Counters used by sqlite3_stmt_status() */
+ int aCounter[4]; /* Counters used by sqlite3_stmt_status() */
#ifndef SQLITE_OMIT_TRACE
i64 startTime; /* Time when query started - used for profiling */
#endif
i64 nFkConstraint; /* Number of imm. FK constraints this VM */
i64 nStmtDefCons; /* Number of def. constraints when stmt started */