]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Add the experimental sqlite3_stmt_status() interface. (CVS 5781)
authordrh <drh@noemail.net>
Tue, 7 Oct 2008 23:46:38 +0000 (23:46 +0000)
committerdrh <drh@noemail.net>
Tue, 7 Oct 2008 23:46:38 +0000 (23:46 +0000)
FossilOrigin-Name: de473efb35ffdf9a8222a70a84dfd7d3198c87c1

12 files changed:
manifest
manifest.uuid
src/sqlite.h.in
src/sqliteInt.h
src/tclsqlite.c
src/test1.c
src/vdbe.c
src/vdbeInt.h
src/vdbeapi.c
src/where.c
test/where.test
test/where2.test

index 992f8c36feb49c34d089091ae7c63379e228e521..7732defd17d13c5f5607d98b5a13a0f4793eda40 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Raise\sthe\shard\supper\sbound\son\sSQLITE_MAX_FUNCTION_ARG\sto\s1000\sfrom\s100.\nThe\sdefault\supper\sbound\sis\sstill\s100,\sbut\sit\scan\snow\sbe\sraised\sas\shigh\nas\s1000\sat\scompile-time.\s(CVS\s5780)
-D 2008-10-07T19:53:14
+C Add\sthe\sexperimental\ssqlite3_stmt_status()\sinterface.\s(CVS\s5781)
+D 2008-10-07T23:46:38
 F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0
 F Makefile.in 7fc26e087207e7a4a7723583dbd7997477af3b13
 F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654
@@ -150,14 +150,14 @@ F src/random.c a87afbd598aa877e23ac676ee92fd8ee5c786a51
 F src/resolve.c 1971ff6996f1a73303339acf7f1de8497546045d
 F src/select.c d910d7350df0d918e22286c5bfd39d4ea68ec813
 F src/shell.c d83b578a8ccdd3e0e7fef4388a0887ce9f810967
-F src/sqlite.h.in ea235b37a691b32e7941baa70fb0afaf6377dbb4
+F src/sqlite.h.in f2640167eca2e9273ec5ea97b37155344290bd2a
 F src/sqlite3ext.h 1e3887c9bd3ae66cb599e922824b04cd0d0f2c3e
-F src/sqliteInt.h 0d6bac3e25f0f37bac0efa4ed115d226c9252ba5
+F src/sqliteInt.h 3f38b600c978698014fdda68d29ca5f3792ad717
 F src/sqliteLimit.h f435e728c6b620ef7312814d660a81f9356eb5c8
 F src/status.c 237b193efae0cf6ac3f0817a208de6c6c6ef6d76
 F src/table.c 22744786199c9195720c15a7a42cb97b2e2728d8
-F src/tclsqlite.c 6a7eeff5afd8f5f10fcb7fd7806e56c725dd2b07
-F src/test1.c fed7656affe3bc687043bb76d13650a40cb21aef
+F src/tclsqlite.c d8057cf17cc092a4bcf02e68b25a47dd3b443d34
+F src/test1.c 96331afde5bd2f64ed638c30cd9a4fea27e2bffa
 F src/test2.c 897528183edf2839c2a3c991d415905db56f1240
 F src/test3.c e85b7ce5c28c3ce7fbdbf7f98e1467b19786c62b
 F src/test4.c 41056378671e7b00e6305fa9ac6fa27e6f96f406
@@ -190,17 +190,17 @@ F src/update.c 206fffc877379affe3a9b42c78e478ea0874c9fe
 F src/utf.c c63e6f69082f85c19ab88d62dedaf91d71ac1a50
 F src/util.c afe659ccc05d1f8af9e8631dabfec3ee3a7144af
 F src/vacuum.c fd77433d0c26d3ff1eb96eab017a1787ac5aa642
-F src/vdbe.c b1c79e640b23e4e592f02719d70910ded09e4037
+F src/vdbe.c 374961d5ac5fe91a1e0acf4ed5519531574b69c6
 F src/vdbe.h 41c99aaad9167c1b5431993db446de74b2f71fc3
-F src/vdbeInt.h b48c74d86a9fb62b707a3186ccca76bb32f1c6be
-F src/vdbeapi.c 8f194355e0270f236838d5b2a3af3ae3572adf44
+F src/vdbeInt.h a20f479ec3bf41c61b0c2bd5176a9bad6b2a07ef
+F src/vdbeapi.c fd2c286cee63a146d5110c11c0aa2bf3a9ebe220
 F src/vdbeaux.c 20a7d109c95e32beee7891fba828c63e419af26c
 F src/vdbeblob.c b0dcebfafedcf9c0addc7901ad98f6f986c08935
 F src/vdbefifo.c 20fda2a7c4c0bcee1b90eb7e545fefcdbf2e1de7
 F src/vdbemem.c ead88713b852576e2a924bc4ae696964bfbaec0a
 F src/vtab.c 527c180e9c5fca417c9167d02af4b5039f892b4b
 F src/walker.c 488c2660e13224ff70c0c82761118efb547f8f0d
-F src/where.c da2a0e132d642acc6afc4df2fe31ecd6f963c035
+F src/where.c 53d495de5fec2d95678b4af29dab022df90c141d
 F tclinstaller.tcl 4356d9d94d2b5ed5e68f9f0c80c4df3048dd7617
 F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2
 F test/alias.test c321c114a8a31a33e3cbda910fa39949f5d9dcb2
@@ -610,8 +610,8 @@ F test/vtabC.test 9f2d9eb84bf65e606d6616f20977c5a32a11f548
 F test/vtab_alter.test 3a299749fee97ca3d53bd55717f536e4a2284856
 F test/vtab_err.test 0d4d8eb4def1d053ac7c5050df3024fd47a3fbd8
 F test/vtab_shared.test c19b2555b807ef2ee014c882cdda5bc8d84fcf48
-F test/where.test 7dcfe573d4a5c6c4b7670271d02c006f2c7414b8
-F test/where2.test 7012c0ad022a54430dd22c98288d3f4d6599dbcf
+F test/where.test 12396f15d8bf7a5763aa26129e071cdb441f600c
+F test/where2.test e446f55417f434929522d87164cd1473d54f10e2
 F test/where3.test 97d3936e6a443b968f1a61cdcc0f673252000e94
 F test/where4.test e9b9e2f2f98f00379e6031db6a6fca29bae782a2
 F test/where5.test fdf66f96d29a064b63eb543e28da4dfdccd81ad2
@@ -641,7 +641,7 @@ F tool/speedtest16.c c8a9c793df96db7e4933f0852abb7a03d48f2e81
 F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff
 F tool/speedtest8.c 1dbced29de5f59ba2ebf877edcadf171540374d1
 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
-P 02a12eb1cfe9307c66556105a1a99d657cc01ab5
-R 5472677a4096378b94ede8934c9bcd72
+P 79df72ee836db91647913055ba6cf55558679b01
+R d426461dcb923755279eeb7df7038b4a
 U drh
-Z a3cb5746d8ce1de551ab384e92396b35
+Z 4b26af34158fc50efdf02ed1356ecdbc
index a5944010a1740859baa55c7b724460d516f50b19..b9343c1c0dede09cf526b0f3007f01c89453085e 100644 (file)
@@ -1 +1 @@
-79df72ee836db91647913055ba6cf55558679b01
\ No newline at end of file
+de473efb35ffdf9a8222a70a84dfd7d3198c87c1
\ No newline at end of file
index 69748f00d670ad75315beff9b58c9c1bf882b8ea..114c2e3d1879ff092a6ff66fe1bcd642381cf992 100644 (file)
@@ -30,7 +30,7 @@
 ** the version number) and changes its name to "sqlite3.h" as
 ** part of the build process.
 **
-** @(#) $Id: sqlite.h.in,v 1.400 2008/10/02 14:33:57 drh Exp $
+** @(#) $Id: sqlite.h.in,v 1.401 2008/10/07 23:46:38 drh Exp $
 */
 #ifndef _SQLITE3_H_
 #define _SQLITE3_H_
@@ -6216,29 +6216,6 @@ int sqlite3_test_control(int op, ...);
 */
 SQLITE_EXPERIMENTAL int sqlite3_status(int op, int *pCurrent, int *pHighwater, int resetFlag);
 
-/*
-** CAPI3REF: Database Connection Status {H17201} <S60200>
-** EXPERIMENTAL
-**
-** This interface is used to retrieve runtime status information 
-** about a single [database connection].  The first argument is the
-** database connection object to be interrogated.  The second argument
-** is the parameter to interrogate.  Currently, the only allowed value
-** for the second parameter is [SQLITE_DBSTATUS_LOOKASIDE_USED].
-** Additional options will likely appear in future releases of SQLite.
-**
-** The current value of the request parameter is written into *pCur
-** and the highest instantaneous value is written into *pHiwtr.  If
-** the resetFlg is true, then the highest instantaneous value is
-** reset back down to the current value.
-**
-** See also: [sqlite3_status()].
-*/
-SQLITE_EXPERIMENTAL int sqlite3_db_status(sqlite3*, int op, int *pCur, int *pHiwtr, int resetFlg);
-
-
-int sqlite3_wsd_init(int N, int J);
-void *sqlite3_wsd_find(void *K, int L);
 
 /*
 ** CAPI3REF: Status Parameters {H17250} <H17200>
@@ -6328,7 +6305,27 @@ void *sqlite3_wsd_find(void *K, int L);
 #define SQLITE_STATUS_SCRATCH_SIZE         8
 
 /*
-** CAPI3REF: Status Parameters for database connections {H17275} <H17200>
+** CAPI3REF: Database Connection Status {H17500} <S60200>
+** EXPERIMENTAL
+**
+** This interface is used to retrieve runtime status information 
+** about a single [database connection].  The first argument is the
+** database connection object to be interrogated.  The second argument
+** is the parameter to interrogate.  Currently, the only allowed value
+** for the second parameter is [SQLITE_DBSTATUS_LOOKASIDE_USED].
+** Additional options will likely appear in future releases of SQLite.
+**
+** The current value of the requested parameter is written into *pCur
+** and the highest instantaneous value is written into *pHiwtr.  If
+** the resetFlg is true, then the highest instantaneous value is
+** reset back down to the current value.
+**
+** See also: [sqlite3_status()] and [sqlite3_stmt_status()].
+*/
+SQLITE_EXPERIMENTAL int sqlite3_db_status(sqlite3*, int op, int *pCur, int *pHiwtr, int resetFlg);
+
+/*
+** CAPI3REF: Status Parameters for database connections {H17520} <H17500>
 ** EXPERIMENTAL
 **
 ** Status verbs for [sqlite3_db_status()].
@@ -6341,6 +6338,58 @@ void *sqlite3_wsd_find(void *K, int L);
 */
 #define SQLITE_DBSTATUS_LOOKASIDE_USED     0
 
+
+/*
+** CAPI3REF: Prepared Statement Status {H17550} <S60200>
+** EXPERIMENTAL
+**
+** Each prepared statement maintains various
+** [SQLITE_STMTSTATUS_SORT | counters] that measure the number
+** of times it has performed specific operations.  These counters can
+** be used to monitor the performance characteristics of the prepared
+** statements.  For example, if the number of table steps greatly exceeds
+** the number of table searches or result rows, that would tend to indicate
+** that the prepared statement is using a full table scan rather than
+** an index.  
+**
+** This interface is used to retrieve and reset counter values from
+** a [prepared statement].  The first argument is the prepared statement
+** object to be interrogated.  The second argument
+** is an integer code for a specific [SQLITE_STMTSTATUS_SORT | counter]
+** to be interrogated. 
+** The current value of the requested counter is returned.
+** If the resetFlg is true, then the counter is reset to zero after this
+** interface call returns.
+**
+** See also: [sqlite3_status()] and [sqlite3_db_status()].
+*/
+SQLITE_EXPERIMENTAL int sqlite3_stmt_status(sqlite3_stmt*, int op,int resetFlg);
+
+/*
+** CAPI3REF: Status Parameters for prepared statements {H17570} <H17550>
+** EXPERIMENTAL
+**
+** These preprocessor macros define integer codes that name counter
+** values associated with the [sqlite3_stmt_status()] interface.
+** The meanings of the various counters are as follows:
+**
+** <dl>
+** <dt>SQLITE_STMTSTATUS_FULLSCAN_STEP</dt>
+** <dd>This is the number of times that SQLite has stepped forward in
+** a table as part of a full table scan.  Large numbers for this counter
+** may indicate opportunities for performance improvement through 
+** careful use of indices.</dd>
+**
+** <dt>SQLITE_STMTSTATUS_SORT</dt>
+** <dd>This is the number of sort operations that have occurred.
+** A non-zero value in this counter may indicate an opportunity to
+** improvement performance through careful use of indices.</dd>
+**
+** </dl>
+*/
+#define SQLITE_STMTSTATUS_FULLSCAN_STEP     1
+#define SQLITE_STMTSTATUS_SORT              2
+
 /*
 ** Undo the hack that converts floating point types to integer for
 ** builds on processors without floating point support.
index d97ccb8dd434a84bf258a267b27439269c09d1db..82c26b3fa1e42855c35b97c204eaf9e0ef40961d 100644 (file)
@@ -11,7 +11,7 @@
 *************************************************************************
 ** Internal interface definitions for SQLite.
 **
-** @(#) $Id: sqliteInt.h,v 1.778 2008/10/07 19:53:14 drh Exp $
+** @(#) $Id: sqliteInt.h,v 1.779 2008/10/07 23:46:38 drh Exp $
 */
 #ifndef _SQLITEINT_H_
 #define _SQLITEINT_H_
@@ -469,6 +469,8 @@ struct BusyHandler {
   #define SQLITE_WSD const
   #define GLOBAL(t,v) (*(t*)sqlite3_wsd_find((void*)&(v), sizeof(v)))
   #define sqlite3GlobalConfig GLOBAL(struct Sqlite3Config, sqlite3Config)
+  int sqlite3_wsd_init(int N, int J);
+  void *sqlite3_wsd_find(void *K, int L);
 #else
   #define SQLITE_WSD 
   #define GLOBAL(t,v) v
@@ -1496,7 +1498,7 @@ struct WhereLevel {
   int nxt;              /* Jump here to start the next IN combination */
   int cont;             /* Jump here to continue with the next loop cycle */
   int top;              /* First instruction of interior of the loop */
-  int op, p1, p2;       /* Opcode used to terminate the loop */
+  int op, p1, p2, p5;   /* Opcode used to terminate the loop */
   int nEq;              /* Number of == or IN constraints on this loop */
   int nIn;              /* Number of IN operators constraining this loop */
   struct InLoop {
index 03f45b5434326989136d1a07a70d87ea8e44188d..6230330bce72b6dda200df6540fddc26000e39c6 100644 (file)
@@ -12,7 +12,7 @@
 ** A TCL Interface to SQLite.  Append this file to sqlite3.c and
 ** compile the whole thing to build a TCL-enabled version of SQLite.
 **
-** $Id: tclsqlite.c,v 1.226 2008/09/23 10:12:15 drh Exp $
+** $Id: tclsqlite.c,v 1.227 2008/10/07 23:46:38 drh Exp $
 */
 #include "tcl.h"
 #include <errno.h>
@@ -117,6 +117,7 @@ struct SqliteDb {
   int maxStmt;               /* The next maximum number of stmtList */
   int nStmt;                 /* Number of statements in stmtList */
   IncrblobChannel *pIncrblob;/* Linked list of open incrblob channels */
+  int nStep, nSort;          /* Statistics for most recent operation */
 };
 
 struct IncrblobChannel {
@@ -977,9 +978,9 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){
     "incrblob",           "interrupt",         "last_insert_rowid",
     "nullvalue",          "onecolumn",         "profile",
     "progress",           "rekey",             "rollback_hook",
-    "timeout",            "total_changes",     "trace",
-    "transaction",        "update_hook",       "version",
-    0                    
+    "status",             "timeout",           "total_changes",
+    "trace",              "transaction",       "update_hook",
+    "version",            0                    
   };
   enum DB_enum {
     DB_AUTHORIZER,        DB_BUSY,             DB_CACHE,
@@ -990,8 +991,9 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){
     DB_INCRBLOB,          DB_INTERRUPT,        DB_LAST_INSERT_ROWID,
     DB_NULLVALUE,         DB_ONECOLUMN,        DB_PROFILE,
     DB_PROGRESS,          DB_REKEY,            DB_ROLLBACK_HOOK,
-    DB_TIMEOUT,           DB_TOTAL_CHANGES,    DB_TRACE,
-    DB_TRANSACTION,       DB_UPDATE_HOOK,      DB_VERSION
+    DB_STATUS,            DB_TIMEOUT,          DB_TOTAL_CHANGES,
+    DB_TRACE,             DB_TRANSACTION,      DB_UPDATE_HOOK, 
+    DB_VERSION
   };
   /* don't leave trailing commas on DB_enum, it confuses the AIX xlc compiler */
 
@@ -1760,6 +1762,10 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){
         }
   
         if( pScript ){
+          pDb->nStep = sqlite3_stmt_status(pStmt, 
+                                  SQLITE_STMTSTATUS_FULLSCAN_STEP, 0);
+          pDb->nSort = sqlite3_stmt_status(pStmt,
+                                  SQLITE_STMTSTATUS_SORT, 0);
           rc = Tcl_EvalObjEx(interp, pScript, 0);
           if( rc==TCL_CONTINUE ){
             rc = TCL_OK;
@@ -1798,6 +1804,10 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){
       ** flush the statement cache and try the statement again.
       */
       rc2 = sqlite3_reset(pStmt);
+      pDb->nStep = sqlite3_stmt_status(pStmt, 
+                                  SQLITE_STMTSTATUS_FULLSCAN_STEP, 1);
+      pDb->nSort = sqlite3_stmt_status(pStmt,
+                                  SQLITE_STMTSTATUS_SORT, 1);
       if( SQLITE_OK!=rc2 ){
         /* If a run-time error occurs, report the error and stop reading
         ** the SQL
@@ -2126,6 +2136,34 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){
     break;
   }
 
+  /*
+  **     $db status (step|sort)
+  **
+  ** Display SQLITE_STMTSTATUS_FULLSCAN_STEP or 
+  ** SQLITE_STMTSTATUS_SORT for the most recent eval.
+  */
+  case DB_STATUS: {
+    int ms;
+    int v;
+    const char *zOp;
+    if( objc!=3 ){
+      Tcl_WrongNumArgs(interp, 2, objv, "(step|sort)");
+      return TCL_ERROR;
+    }
+    zOp = Tcl_GetString(objv[2]);
+    if( strcmp(zOp, "step")==0 ){
+      v = pDb->nStep;
+    }else if( strcmp(zOp, "sort")==0 ){
+      v = pDb->nSort;
+    }else{
+      Tcl_AppendResult(interp, "bad argument: should be step or sort", 
+            (char*)0);
+      return TCL_ERROR;
+    }
+    Tcl_SetObjResult(interp, Tcl_NewIntObj(v));
+    break;
+  }
+  
   /*
   **     $db timeout MILLESECONDS
   **
index c54173e8d0b5a8a822000f3e80f025cd37708bf3..378b90811c6f6067147f62569007042d9c2f49e8 100644 (file)
@@ -13,7 +13,7 @@
 ** is not included in the SQLite library.  It is used for automated
 ** testing of the SQLite library.
 **
-** $Id: test1.c,v 1.326 2008/10/02 14:49:02 danielk1977 Exp $
+** $Id: test1.c,v 1.327 2008/10/07 23:46:38 drh Exp $
 */
 #include "sqliteInt.h"
 #include "tcl.h"
@@ -1912,6 +1912,50 @@ static int test_finalize(
   return TCL_OK;
 }
 
+/*
+** Usage:  sqlite3_stmt_status  STMT  CODE  RESETFLAG
+**
+** Get the value of a status counter from a statement.
+*/
+static int test_stmt_status(
+  void * clientData,
+  Tcl_Interp *interp,
+  int objc,
+  Tcl_Obj *CONST objv[]
+){
+  int iValue;
+  int i, op, resetFlag;
+  const char *zOpName;
+  sqlite3_stmt *pStmt;
+
+  static const struct {
+    const char *zName;
+    int op;
+  } aOp[] = {
+    { "SQLITE_STMTSTATUS_FULLSCAN_STEP",   SQLITE_STMTSTATUS_FULLSCAN_STEP   },
+    { "SQLITE_STMTSTATUS_SORT",            SQLITE_STMTSTATUS_SORT            },
+  };
+  if( objc!=4 ){
+    Tcl_WrongNumArgs(interp, 1, objv, "STMT PARAMETER RESETFLAG");
+    return TCL_ERROR;
+  }
+  if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR;
+  zOpName = Tcl_GetString(objv[2]);
+  for(i=0; i<ArraySize(aOp); i++){
+    if( strcmp(aOp[i].zName, zOpName)==0 ){
+      op = aOp[i].op;
+      break;
+    }
+  }
+  if( i>=ArraySize(aOp) ){
+    if( Tcl_GetIntFromObj(interp, objv[2], &op) ) return TCL_ERROR;
+  }
+  if( Tcl_GetBooleanFromObj(interp, objv[3], &resetFlag) ) return TCL_ERROR;
+  iValue = sqlite3_stmt_status(pStmt, op, resetFlag);
+  Tcl_SetObjResult(interp, Tcl_NewIntObj(iValue));
+  return TCL_OK;
+}
+
 /*
 ** Usage:  sqlite3_next_stmt  DB  STMT
 **
@@ -4623,6 +4667,7 @@ int Sqlitetest1_Init(Tcl_Interp *interp){
      { "sqlite3_prepare_tkt3134",       test_prepare_tkt3134, 0},
      { "sqlite3_prepare16_v2",          test_prepare16_v2  ,0 },
      { "sqlite3_finalize",              test_finalize      ,0 },
+     { "sqlite3_stmt_status",           test_stmt_status   ,0 },
      { "sqlite3_reset",                 test_reset         ,0 },
      { "sqlite3_expired",               test_expired       ,0 },
      { "sqlite3_transfer_bindings",     test_transfer_bind ,0 },
index 38fc0964b0567962368b15c7d842493e7e9c9861..6b9faf7e5efb6624fd776bcb25dd18f8de2e8018 100644 (file)
@@ -43,7 +43,7 @@
 ** in this file for details.  If in doubt, do not deviate from existing
 ** commenting and indentation practices when changing or adding code.
 **
-** $Id: vdbe.c,v 1.780 2008/10/07 19:53:14 drh Exp $
+** $Id: vdbe.c,v 1.781 2008/10/07 23:46:38 drh Exp $
 */
 #include "sqliteInt.h"
 #include <ctype.h>
@@ -3742,6 +3742,7 @@ case OP_Sort: {        /* jump */
   sqlite3_sort_count++;
   sqlite3_search_count--;
 #endif
+  p->aCounter[SQLITE_STMTSTATUS_SORT-1]++;
   /* Fall through into OP_Rewind */
 }
 /* Opcode: Rewind P1 P2 * * *
@@ -3819,6 +3820,7 @@ case OP_Next: {        /* jump */
   pC->cacheStatus = CACHE_STALE;
   if( res==0 ){
     pc = pOp->p2 - 1;
+    if( pOp->p5 ) p->aCounter[pOp->p5-1]++;
 #ifdef SQLITE_TEST
     sqlite3_search_count++;
 #endif
@@ -3860,7 +3862,7 @@ case OP_IdxInsert: {        /* in2 */
   break;
 }
 
-/* Opcode: IdxDeleteM P1 P2 P3 * *
+/* Opcode: IdxDelete P1 P2 P3 * *
 **
 ** The content of P3 registers starting at register P2 form
 ** an unpacked index key. This opcode removes that entry from the 
index f910e4be1f66337b0f0e50c91e7fdf0680e9bd6f..c4c1e22b5ab3611c3835087bbe6c2d42f5da1202 100644 (file)
@@ -15,7 +15,7 @@
 ** 6000 lines long) it was split up into several smaller files and
 ** this header information was factored out.
 **
-** $Id: vdbeInt.h,v 1.154 2008/08/13 19:11:48 drh Exp $
+** $Id: vdbeInt.h,v 1.155 2008/10/07 23:46:38 drh Exp $
 */
 #ifndef _VDBEINT_H_
 #define _VDBEINT_H_
@@ -323,10 +323,11 @@ struct Vdbe {
   i64 startTime;          /* Time when query started - used for profiling */
   int btreeMask;          /* Bitmask of db->aDb[] entries referenced */
   BtreeMutexArray aMutex; /* An array of Btree used here and needing locks */
+  int aCounter[2];        /* Counters used by sqlite3_stmt_status() */
   int nSql;             /* Number of bytes in zSql */
   char *zSql;           /* Text of the SQL statement that generated this */
 #ifdef SQLITE_DEBUG
-  FILE *trace;        /* Write an execution trace here, if not NULL */
+  FILE *trace;          /* Write an execution trace here, if not NULL */
 #endif
   int openedStatement;  /* True if this VM has opened a statement journal */
 #ifdef SQLITE_SSE
index 5ec1a34b57e8f4b3e47613a5b57d034e784bb790..f7b989a3445ff8c73a1d2540a7f455b1ce9d94b1 100644 (file)
@@ -13,7 +13,7 @@
 ** This file contains code use to implement APIs that are part of the
 ** VDBE.
 **
-** $Id: vdbeapi.c,v 1.144 2008/10/07 15:25:49 drh Exp $
+** $Id: vdbeapi.c,v 1.145 2008/10/07 23:46:38 drh Exp $
 */
 #include "sqliteInt.h"
 #include "vdbeInt.h"
@@ -1285,3 +1285,13 @@ sqlite3_stmt *sqlite3_next_stmt(sqlite3 *pDb, sqlite3_stmt *pStmt){
   sqlite3_mutex_leave(pDb->mutex);
   return pNext;
 }
+
+/*
+** Return the value of a status counter for a prepared statement
+*/
+int sqlite3_stmt_status(sqlite3_stmt *pStmt, int op, int resetFlag){
+  Vdbe *pVdbe = (Vdbe*)pStmt;
+  int v = pVdbe->aCounter[op-1];
+  if( resetFlag ) pVdbe->aCounter[op-1] = 0;
+  return v;
+}
index afb61b4ce3b249a86d5f287314139738f4f3ed2d..fb7b3f90adf3ff882b54d924acea5401dc27d958 100644 (file)
@@ -16,7 +16,7 @@
 ** so is applicable.  Because this module is responsible for selecting
 ** indices, you might also think of this module as the "query optimizer".
 **
-** $Id: where.c,v 1.324 2008/10/06 05:32:19 danielk1977 Exp $
+** $Id: where.c,v 1.325 2008/10/07 23:46:38 drh Exp $
 */
 #include "sqliteInt.h"
 
@@ -2710,6 +2710,7 @@ WhereInfo *sqlite3WhereBegin(
       pLevel->op = OP_Next;
       pLevel->p1 = iCur;
       pLevel->p2 = 1 + sqlite3VdbeAddOp2(v, OP_Rewind, iCur, brk);
+      pLevel->p5 = SQLITE_STMTSTATUS_FULLSCAN_STEP;
     }
     notReady &= ~getMask(&maskSet, iCur);
 
@@ -2835,6 +2836,7 @@ void sqlite3WhereEnd(WhereInfo *pWInfo){
     sqlite3VdbeResolveLabel(v, pLevel->cont);
     if( pLevel->op!=OP_Noop ){
       sqlite3VdbeAddOp2(v, pLevel->op, pLevel->p1, pLevel->p2);
+      sqlite3VdbeChangeP5(v, pLevel->p5);
     }
     if( pLevel->nIn ){
       struct InLoop *pIn;
index 874a2b31d7a062e9519a18acf41233c5fe977a85..4437ff0a65a4d76debe7ce74b98e5cd2a73c8944 100644 (file)
@@ -11,7 +11,7 @@
 # This file implements regression tests for SQLite library.  The
 # focus of this file is testing the use of indices in WHERE clases.
 #
-# $Id: where.test,v 1.48 2008/10/01 08:43:03 danielk1977 Exp $
+# $Id: where.test,v 1.49 2008/10/07 23:46:38 drh Exp $
 
 set testdir [file dirname $argv0]
 source $testdir/tester.tcl
@@ -69,11 +69,26 @@ do_test where-1.1.2 {
   set sqlite_query_plan
 } {t1 i1w}
 do_test where-1.1.3 {
+  db status step
+} {0}
+do_test where-1.1.4 {
+  db eval {SELECT x, y, w FROM t1 WHERE +w=10}
+} {3 121 10}
+do_test where-1.1.5 {
+  db status step
+} {99}
+do_test where-1.1.6 {
+  set sqlite_query_plan
+} {t1 {}}
+do_test where-1.1.7 {
   count {SELECT x, y, w AS abc FROM t1 WHERE abc=10}
 } {3 121 10 3}
-do_test where-1.1.4 {
+do_test where-1.1.8 {
   set sqlite_query_plan
 } {t1 i1w}
+do_test where-1.1.9 {
+  db status step
+} {0}
 do_test where-1.2.1 {
   count {SELECT x, y, w FROM t1 WHERE w=11}
 } {3 144 11 3}
@@ -447,9 +462,8 @@ ifcapable subquery {
 # occurring as expected.
 #
 proc cksort {sql} {
-  set ::sqlite_sort_count 0
   set data [execsql $sql]
-  if {$::sqlite_sort_count} {set x sort} {set x nosort}
+  if {[db status sort]} {set x sort} {set x nosort}
   lappend data $x
   return $data
 }
index ae7c7a3b272176079a138d4e837bb00f7cb1f21b..3ddc6c033e89ea3b79fa4e0510924e7460fbcd27 100644 (file)
@@ -12,7 +12,7 @@
 # focus of this file is testing the use of indices in WHERE clauses
 # based on recent changes to the optimizer.
 #
-# $Id: where2.test,v 1.13 2007/12/10 05:03:48 danielk1977 Exp $
+# $Id: where2.test,v 1.14 2008/10/07 23:46:39 drh Exp $
 
 set testdir [file dirname $argv0]
 source $testdir/tester.tcl
@@ -58,9 +58,8 @@ proc count sql {
 # occurring as expected.
 #
 proc cksort {sql} {
-  set ::sqlite_sort_count 0
   set data [execsql $sql]
-  if {$::sqlite_sort_count} {set x sort} {set x nosort}
+  if {[db status sort]} {set x sort} {set x nosort}
   lappend data $x
   return $data
 }