-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
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
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
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
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
-79df72ee836db91647913055ba6cf55558679b01
\ No newline at end of file
+de473efb35ffdf9a8222a70a84dfd7d3198c87c1
\ No newline at end of file
** 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_
*/
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>
#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()].
*/
#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.
*************************************************************************
** 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_
#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
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 {
** 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>
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 {
"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,
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 */
}
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;
** 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
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
**
** 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"
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
**
{ "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 },
** 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>
sqlite3_sort_count++;
sqlite3_search_count--;
#endif
+ p->aCounter[SQLITE_STMTSTATUS_SORT-1]++;
/* Fall through into OP_Rewind */
}
/* Opcode: Rewind P1 P2 * * *
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
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
** 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_
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
** 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"
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;
+}
** 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"
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);
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;
# 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
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}
# 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
}
# 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
# 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
}