From: drh Date: Tue, 7 Oct 2008 23:46:38 +0000 (+0000) Subject: Add the experimental sqlite3_stmt_status() interface. (CVS 5781) X-Git-Tag: version-3.6.10~396 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=d1d384888bc542531c94a4ade5e444764d67f404;p=thirdparty%2Fsqlite.git Add the experimental sqlite3_stmt_status() interface. (CVS 5781) FossilOrigin-Name: de473efb35ffdf9a8222a70a84dfd7d3198c87c1 --- diff --git a/manifest b/manifest index 992f8c36fe..7732defd17 100644 --- 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 diff --git a/manifest.uuid b/manifest.uuid index a5944010a1..b9343c1c0d 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -79df72ee836db91647913055ba6cf55558679b01 \ No newline at end of file +de473efb35ffdf9a8222a70a84dfd7d3198c87c1 \ No newline at end of file diff --git a/src/sqlite.h.in b/src/sqlite.h.in index 69748f00d6..114c2e3d18 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -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} -** 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} @@ -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} +** CAPI3REF: Database Connection Status {H17500} +** 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} ** 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} +** 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} +** 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: +** +**
+**
SQLITE_STMTSTATUS_FULLSCAN_STEP
+**
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.
+** +**
SQLITE_STMTSTATUS_SORT
+**
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.
+** +**
+*/ +#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. diff --git a/src/sqliteInt.h b/src/sqliteInt.h index d97ccb8dd4..82c26b3fa1 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -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 { diff --git a/src/tclsqlite.c b/src/tclsqlite.c index 03f45b5434..6230330bce 100644 --- a/src/tclsqlite.c +++ b/src/tclsqlite.c @@ -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 @@ -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 ** diff --git a/src/test1.c b/src/test1.c index c54173e8d0..378b90811c 100644 --- a/src/test1.c +++ b/src/test1.c @@ -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) ){ + 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 }, diff --git a/src/vdbe.c b/src/vdbe.c index 38fc0964b0..6b9faf7e5e 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -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 @@ -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 diff --git a/src/vdbeInt.h b/src/vdbeInt.h index f910e4be1f..c4c1e22b5a 100644 --- a/src/vdbeInt.h +++ b/src/vdbeInt.h @@ -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 diff --git a/src/vdbeapi.c b/src/vdbeapi.c index 5ec1a34b57..f7b989a344 100644 --- a/src/vdbeapi.c +++ b/src/vdbeapi.c @@ -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; +} diff --git a/src/where.c b/src/where.c index afb61b4ce3..fb7b3f90ad 100644 --- a/src/where.c +++ b/src/where.c @@ -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; diff --git a/test/where.test b/test/where.test index 874a2b31d7..4437ff0a65 100644 --- a/test/where.test +++ b/test/where.test @@ -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 } diff --git a/test/where2.test b/test/where2.test index ae7c7a3b27..3ddc6c033e 100644 --- a/test/where2.test +++ b/test/where2.test @@ -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 }