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