Index: ext/misc/stmts.c
==================================================================
--- ext/misc/stmts.c
+++ ext/misc/stmts.c
@@ -90,24 +90,27 @@
){
stmts_vtab *pNew;
int rc;
/* Column numbers */
-#define STMTS_COLUMN_PTR 0 /* Numeric value of the statement pointer */
-#define STMTS_COLUMN_SQL 1 /* SQL for the statement */
-#define STMTS_COLUMN_NCOL 2 /* Number of result columns */
-#define STMTS_COLUMN_RO 3 /* True if read-only */
-#define STMTS_COLUMN_BUSY 4 /* True if currently busy */
-#define STMTS_COLUMN_NSCAN 5 /* SQLITE_STMTSTATUS_FULLSCAN_STEP */
-#define STMTS_COLUMN_NSORT 6 /* SQLITE_STMTSTATUS_SORT */
-#define STMTS_COLUMN_NAIDX 7 /* SQLITE_STMTSTATUS_AUTOINDEX */
-#define STMTS_COLUMN_NSTEP 8 /* SQLITE_STMTSTATUS_VM_STEP */
-#define STMTS_COLUMN_MEM 9 /* SQLITE_STMTSTATUS_MEMUSED */
+#define STMTS_COLUMN_PTR 0 /* Numeric value of the statement pointer */
+#define STMTS_COLUMN_SQL 1 /* SQL for the statement */
+#define STMTS_COLUMN_NCOL 2 /* Number of result columns */
+#define STMTS_COLUMN_RO 3 /* True if read-only */
+#define STMTS_COLUMN_BUSY 4 /* True if currently busy */
+#define STMTS_COLUMN_NSCAN 5 /* SQLITE_STMTSTATUS_FULLSCAN_STEP */
+#define STMTS_COLUMN_NSORT 6 /* SQLITE_STMTSTATUS_SORT */
+#define STMTS_COLUMN_NAIDX 7 /* SQLITE_STMTSTATUS_AUTOINDEX */
+#define STMTS_COLUMN_NSTEP 8 /* SQLITE_STMTSTATUS_VM_STEP */
+#define STMTS_COLUMN_REPREP 9 /* SQLITE_STMTSTATUS_REPREPARE */
+#define STMTS_COLUMN_RUN 10 /* SQLITE_STMTSTATUS_RUN */
+#define STMTS_COLUMN_MEM 11 /* SQLITE_STMTSTATUS_MEMUSED */
rc = sqlite3_declare_vtab(db,
- "CREATE TABLE x(ptr,sql,ncol,ro,busy,nscan,nsort,naidx,nstep,mem)");
+ "CREATE TABLE x(ptr,sql,ncol,ro,busy,nscan,nsort,naidx,nstep,"
+ "reprep,run,mem)");
if( rc==SQLITE_OK ){
pNew = sqlite3_malloc( sizeof(*pNew) );
*ppVtab = (sqlite3_vtab*)pNew;
if( pNew==0 ) return SQLITE_NOMEM;
memset(pNew, 0, sizeof(*pNew));
@@ -184,16 +187,22 @@
break;
}
case STMTS_COLUMN_BUSY: {
sqlite3_result_int(ctx, sqlite3_stmt_busy(pCur->pStmt));
break;
+ }
+ case STMTS_COLUMN_MEM: {
+ i = SQLITE_STMTSTATUS_MEMUSED +
+ STMTS_COLUMN_NSCAN - SQLITE_STMTSTATUS_FULLSCAN_STEP;
+ /* Fall thru */
}
case STMTS_COLUMN_NSCAN:
case STMTS_COLUMN_NSORT:
case STMTS_COLUMN_NAIDX:
case STMTS_COLUMN_NSTEP:
- case STMTS_COLUMN_MEM: {
+ case STMTS_COLUMN_REPREP:
+ case STMTS_COLUMN_RUN: {
sqlite3_result_int(ctx, sqlite3_stmt_status(pCur->pStmt,
i-STMTS_COLUMN_NSCAN+SQLITE_STMTSTATUS_FULLSCAN_STEP, 0));
break;
}
}
Index: src/sqlite.h.in
==================================================================
--- src/sqlite.h.in
+++ src/sqlite.h.in
@@ -7145,10 +7145,22 @@
** 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.
+**
+** [[SQLITE_STMTSTATUS_REPREPARE]]
SQLITE_STMTSTATUS_REPREPARE
+** ^This is the number of times that the prepare statement has been
+** automatically regenerated due to schema changes or change to
+** [bound parameters] that might affect the query plan.
+**
+** [[SQLITE_STMTSTATUS_RUN]] SQLITE_STMTSTATUS_RUN
+** ^This is the number of times that the prepared statement has
+** been run. A single "run" for the purposes of this counter is one
+** or more calls to [sqlite3_step()] followed by a call to [sqlite3_reset()].
+** The counter is incremented on the first [sqlite3_step()] call of each
+** cycle.
**
** [[SQLITE_STMTSTATUS_MEMUSED]] SQLITE_STMTSTATUS_MEMUSED
** ^This is the approximate number of bytes of heap memory
** used to store the prepared statement. ^This value is not actually
** a counter, and so the resetFlg parameter to sqlite3_stmt_status()
@@ -7158,11 +7170,13 @@
*/
#define SQLITE_STMTSTATUS_FULLSCAN_STEP 1
#define SQLITE_STMTSTATUS_SORT 2
#define SQLITE_STMTSTATUS_AUTOINDEX 3
#define SQLITE_STMTSTATUS_VM_STEP 4
-#define SQLITE_STMTSTATUS_MEMUSED 5
+#define SQLITE_STMTSTATUS_REPREPARE 5
+#define SQLITE_STMTSTATUS_RUN 6
+#define SQLITE_STMTSTATUS_MEMUSED 99
/*
** 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
@@ -2137,10 +2137,13 @@
} 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 },
+ { "SQLITE_STMTSTATUS_REPREPARE", SQLITE_STMTSTATUS_REPREPARE },
+ { "SQLITE_STMTSTATUS_RUN", SQLITE_STMTSTATUS_RUN },
+ { "SQLITE_STMTSTATUS_MEMUSED", SQLITE_STMTSTATUS_MEMUSED },
};
if( objc!=4 ){
Tcl_WrongNumArgs(interp, 1, objv, "STMT PARAMETER RESETFLAG");
return TCL_ERROR;
}
Index: src/vdbe.c
==================================================================
--- src/vdbe.c
+++ src/vdbe.c
@@ -7077,10 +7077,11 @@
if( p->aOp[i].opcode==OP_Once ) p->aOp[i].p1 = 0;
}
pOp->p1 = 0;
}
pOp->p1++;
+ p->aCounter[SQLITE_STMTSTATUS_RUN]++;
goto jump_to_p2;
}
#ifdef SQLITE_ENABLE_CURSOR_HINTS
/* Opcode: CursorHint P1 * * P4 *
Index: src/vdbeInt.h
==================================================================
--- src/vdbeInt.h
+++ src/vdbeInt.h
@@ -391,11 +391,11 @@
bft readOnly:1; /* True for statements that do not write */
bft bIsReader:1; /* True for statements that read */
bft isPrepareV2:1; /* True if prepared with prepare_v2() */
yDbMask btreeMask; /* Bitmask of db->aDb[] entries referenced */
yDbMask lockMask; /* Subset of btreeMask that requires a lock */
- u32 aCounter[5]; /* Counters used by sqlite3_stmt_status() */
+ u32 aCounter[7]; /* Counters used by sqlite3_stmt_status() */
char *zSql; /* Text of the SQL statement that generated this */
void *pFree; /* Free this when deleting the vdbe */
VdbeFrame *pFrame; /* Parent frame */
VdbeFrame *pDelFrame; /* List of frame objects to free on VM reset */
int nFrame; /* Number of frames in pFrame list */
Index: src/vdbeaux.c
==================================================================
--- src/vdbeaux.c
+++ src/vdbeaux.c
@@ -85,10 +85,13 @@
zTmp = pA->zSql;
pA->zSql = pB->zSql;
pB->zSql = zTmp;
pB->isPrepareV2 = pA->isPrepareV2;
pB->expmask = pA->expmask;
+ memcpy(pB->aCounter, pA->aCounter, sizeof(pB->aCounter));
+ pB->aCounter[SQLITE_STMTSTATUS_REPREPARE]++;
+
}
/*
** Resize the Vdbe.aOp array so that it is at least nOp elements larger
** than its current size. nOp is guaranteed to be less than or equal