------BEGIN PGP SIGNED MESSAGE-----
-Hash: SHA1
-
-C Lookaside\smemory\sis\snot\sused\sto\sstore\sschemas.\s\sChange\sthe\nSQLITE_DBSATUS_SCHEMA_USED\sdocumentation\sto\sreflect\sthis\sfact.
-D 2010-07-28T15:52:09
+C Modify\sCLI\sto\soptionally\sdisplay\s"stats".
+D 2010-07-28T16:05:35
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
F Makefile.in ec08dc838fd8110fe24c92e5130bcd91cbb1ff2e
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
F src/resolve.c 1c0f32b64f8e3f555fe1f732f9d6f501a7f05706
F src/rowset.c 69afa95a97c524ba6faf3805e717b5b7ae85a697
F src/select.c 74fef1334bec27e606ef0b19e5c41cd0a639e69c
-F src/shell.c fd4ccdb37c3b68de0623eb938a649e0990710714
+F src/shell.c 74c82a4ecfd833900a5bacc5f32abd18b93079d1
F src/sqlite.h.in 373dedd8489ecd9dfb33d6d4378ee9f34a3c2386
F src/sqlite3ext.h 69dfb8116af51b84a029cddb3b35062354270c89
F src/sqliteInt.h a9be6badc6cd6a3c1ae54475a98661cf351ecad5
F tool/omittest.tcl 27d6f6e3b1e95aeb26a1c140e6eb57771c6d794a
F tool/opcodeDoc.awk b3a2a3d5d3075b8bd90b7afe24283efdd586659c
F tool/restore_jrnl.tcl 6957a34f8f1f0f8285e07536225ec3b292a9024a
-F tool/shell1.test a738c71bc08ea9162baee9a14b3cf9994f181921
+F tool/shell1.test 930444cadb71ce9ce78bc6cd14ec21e6b69776ea
F tool/shell2.test 5dc76b8005b465f420fed8241621da7513060ff3
F tool/shell3.test 4fad469e8003938426355afdf34155f08c587836
+F tool/shell4.test 0c82af2b7ce4e8e84565078a8690d1c46ec4e8f6
F tool/showdb.c 01c20e8181941b714fe07f72c64a7560fee17ff9
F tool/showjournal.c ec3b171be148656827c4949fbfb8ab4370822f87
F tool/showwal.c f09e5a80a293919290ec85a6a37c85a5ddcf37d9
F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224
F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f
-P dbfbdb60c00b5aeae29c85acec0ae910b82dbdba
-R db99aad6ade6f84bf548bac1cfdabd10
-U drh
-Z 87e1fd645b598e91788e82cf253f48fb
------BEGIN PGP SIGNATURE-----
-Version: GnuPG v1.4.6 (GNU/Linux)
-
-iD8DBQFMUFIsoxKgR168RlERAicpAKCHH5v5EXtY/BOEo/lp30OkqVQK0wCgisZZ
-js0Ce6xvYCx8PUpn/o0QZSQ=
-=7PD/
------END PGP SIGNATURE-----
+P 07abfd5268564c18afd1074c2069d65c64f4b8eb
+R 685d62477503a0184c458ad36031979f
+U shaneh
+Z 72eb3f2af1f8ca9f1cfbf340110562c7
struct callback_data {
sqlite3 *db; /* The database */
int echoOn; /* True to echo input commands */
+ int statsOn; /* True to display memory stats before each finalize */
int cnt; /* Number of records displayed so far */
FILE *out; /* Write results here */
int mode; /* An output mode setting */
return zErrMsg;
}
+/*
+** Display memory stats.
+*/
+static int display_stats(
+ sqlite3 *db, /* Database to query */
+ struct callback_data *pArg, /* Pointer to struct callback_data */
+ int bReset /* True to reset the stats */
+){
+ int iCur;
+ int iHiwtr;
+
+ if( pArg && pArg->out ){
+
+ iHiwtr = iCur = -1;
+ sqlite3_status(SQLITE_STATUS_MEMORY_USED, &iCur, &iHiwtr, bReset);
+ fprintf(pArg->out, "Mem Used (Excludes Scratch/Pcache): %d (max %d) bytes\n", iCur, iHiwtr);
+ iHiwtr = iCur = -1;
+ sqlite3_status(SQLITE_STATUS_MALLOC_COUNT, &iCur, &iHiwtr, bReset);
+ fprintf(pArg->out, "Number of Allocations: %d (max %d)\n", iCur, iHiwtr);
+/*
+** Not currently used by the CLI.
+** iHiwtr = iCur = -1;
+** sqlite3_status(SQLITE_STATUS_PAGECACHE_USED, &iCur, &iHiwtr, bReset);
+** fprintf(pArg->out, "Number of Pcache Pages Used: %d (max %d) pages\n", iCur, iHiwtr);
+*/
+ iHiwtr = iCur = -1;
+ sqlite3_status(SQLITE_STATUS_PAGECACHE_OVERFLOW, &iCur, &iHiwtr, bReset);
+ fprintf(pArg->out, "Number of Pcache Overflow Bytes: %d (max %d) bytes\n", iCur, iHiwtr);
+/*
+** Not currently used by the CLI.
+** iHiwtr = iCur = -1;
+** sqlite3_status(SQLITE_STATUS_SCRATCH_USED, &iCur, &iHiwtr, bReset);
+** fprintf(pArg->out, "Number of Scratch Allocations Used: %d (max %d)\n", iCur, iHiwtr);
+*/
+ iHiwtr = iCur = -1;
+ sqlite3_status(SQLITE_STATUS_SCRATCH_OVERFLOW, &iCur, &iHiwtr, bReset);
+ fprintf(pArg->out, "Number of Scratch Overflow Bytes: %d (max %d) bytes\n", iCur, iHiwtr);
+ iHiwtr = iCur = -1;
+ sqlite3_status(SQLITE_STATUS_MALLOC_SIZE, &iCur, &iHiwtr, bReset);
+ fprintf(pArg->out, "Largest Allocation: %d bytes\n", iHiwtr);
+ iHiwtr = iCur = -1;
+ sqlite3_status(SQLITE_STATUS_PAGECACHE_SIZE, &iCur, &iHiwtr, bReset);
+ fprintf(pArg->out, "Largest Pcache Allocation: %d bytes\n", iHiwtr);
+ iHiwtr = iCur = -1;
+ sqlite3_status(SQLITE_STATUS_SCRATCH_SIZE, &iCur, &iHiwtr, bReset);
+ fprintf(pArg->out, "Largest Scratch Allocation: %d bytes\n", iHiwtr);
+#ifdef YYTRACKMAXSTACKDEPTH
+ iHiwtr = iCur = -1;
+ sqlite3_status(SQLITE_STATUS_PARSER_STACK, &iCur, &iHiwtr, bReset);
+ fprintf(pArg->out, "Deepest Parser Stack: %d (max %d)\n", iCur, iHiwtr);
+#endif
+ }
+
+ if( pArg && pArg->out && db ){
+ iHiwtr = iCur = -1;
+ sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_USED, &iCur, &iHiwtr, bReset);
+ fprintf(pArg->out, "Lookaside Slots Used: %d (max %d)\n", iCur, iHiwtr);
+ iHiwtr = iCur = -1;
+ sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_USED, &iCur, &iHiwtr, bReset);
+ fprintf(pArg->out, "Pcache Heap Usage: %d bytes\n", iCur);
+ iHiwtr = iCur = -1;
+ sqlite3_db_status(db, SQLITE_DBSTATUS_SCHEMA_USED, &iCur, &iHiwtr, bReset);
+ fprintf(pArg->out, "Schema Heap Usage: %d bytes\n", iCur);
+ iHiwtr = iCur = -1;
+ sqlite3_db_status(db, SQLITE_DBSTATUS_STMT_USED, &iCur, &iHiwtr, bReset);
+ fprintf(pArg->out, "Statement Heap/Lookaside Usage: %d bytes\n", iCur);
+ }
+
+ if( pArg && pArg->out && db && pArg->pStmt ){
+ iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_FULLSCAN_STEP, bReset);
+ fprintf(pArg->out, "Fullscan Steps: %d\n", iCur);
+ iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_SORT, bReset);
+ fprintf(pArg->out, "Sort Operations: %d\n", iCur);
+ iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_AUTOINDEX, bReset);
+ fprintf(pArg->out, "Autoindex Inserts: %d\n", iCur);
+ }
+
+ return 0;
+}
+
/*
** Execute a statement or set of statements. Print
** any result rows/columns depending on the current mode
continue;
}
+ /* save off the prepared statment handle and reset row count */
+ if( pArg ){
+ pArg->pStmt = pStmt;
+ pArg->cnt = 0;
+ }
+
/* echo the sql statement if echo on */
- if( pArg->echoOn ){
+ if( pArg && pArg->echoOn ){
const char *zStmtSql = sqlite3_sql(pStmt);
- fprintf(pArg->out,"%s\n", zStmtSql ? zStmtSql : zSql);
+ fprintf(pArg->out, "%s\n", zStmtSql ? zStmtSql : zSql);
}
/* perform the first step. this will tell us if we
for(i=0; i<nCol; i++){
azCols[i] = (char *)sqlite3_column_name(pStmt, i);
}
- /* save off the prepared statment handle and reset row count */
- if( pArg ){
- pArg->pStmt = pStmt;
- pArg->cnt = 0;
- }
do{
/* extract the data and data types */
for(i=0; i<nCol; i++){
}
} while( SQLITE_ROW == rc );
sqlite3_free(pData);
- if( pArg ){
- pArg->pStmt = NULL;
- }
}
}else{
do{
}
}
+ /* print usage stats if stats on */
+ if( pArg && pArg->statsOn ){
+ display_stats(db, pArg, 0);
+ }
+
/* Finalize the statement just executed. If this fails, save a
** copy of the error message. Otherwise, set zSql to point to the
** next statement to execute. */
}else if( pzErrMsg ){
*pzErrMsg = save_err_msg(db);
}
+
+ /* clear saved stmt handle */
+ if( pArg ){
+ pArg->pStmt = NULL;
+ }
}
} /* end while */
" LIKE pattern TABLE.\n"
".separator STRING Change separator used by output mode and .import\n"
".show Show the current values for various settings\n"
+ ".stats ON|OFF Turn stats on or off\n"
".tables ?TABLE? List names of tables\n"
" If TABLE specified, only list tables matching\n"
" LIKE pattern TABLE.\n"
fprintf(p->out,"%9.9s: ", "separator");
output_c_string(p->out, p->separator);
fprintf(p->out, "\n");
+ fprintf(p->out,"%9.9s: %s\n","stats", p->statsOn ? "on" : "off");
fprintf(p->out,"%9.9s: ","width");
for (i=0;i<(int)ArraySize(p->colWidth) && p->colWidth[i] != 0;i++) {
fprintf(p->out,"%d ",p->colWidth[i]);
fprintf(p->out,"\n");
}else
+ if( c=='s' && strncmp(azArg[0], "stats", n)==0 && nArg>1 && nArg<3 ){
+ p->statsOn = booleanValue(azArg[1]);
+ }else
+
if( c=='t' && n>1 && strncmp(azArg[0], "tables", n)==0 && nArg<3 ){
char **azResult;
int nRow;
" -line set output mode to 'line'\n"
" -list set output mode to 'list'\n"
" -separator 'x' set output field separator (|)\n"
+ " -stats print memory stats before each finalize\n"
" -nullvalue 'text' set text string for NULL values\n"
" -version show SQLite version\n"
;
data.showHeader = 0;
}else if( strcmp(z,"-echo")==0 ){
data.echoOn = 1;
+ }else if( strcmp(z,"-stats")==0 ){
+ data.statsOn = 1;
}else if( strcmp(z,"-bail")==0 ){
bail_on_error = 1;
}else if( strcmp(z,"-version")==0 ){
--- /dev/null
+# 2010 July 28
+#
+# The author disclaims copyright to this source code. In place of
+# a legal notice, here is a blessing:
+#
+# May you do good and not evil.
+# May you find forgiveness for yourself and forgive others.
+# May you share freely, never taking more than you give.
+#
+#***********************************************************************
+#
+# The focus of this file is testing the CLI shell tool.
+#
+# $Id: shell4.test,v 1.7 2009/07/17 16:54:48 shaneh Exp $
+#
+
+# Test plan:
+#
+# shell4-1.*: Basic tests specific to the "stats" command.
+#
+
+package require sqlite3
+
+set CLI "./sqlite3"
+
+proc do_test {name cmd expected} {
+ puts -nonewline "$name ..."
+ set res [uplevel $cmd]
+ if {$res eq $expected} {
+ puts Ok
+ } else {
+ puts Error
+ puts " Got: $res"
+ puts " Expected: $expected"
+ exit
+ }
+}
+
+proc execsql {sql} {
+ uplevel [list db eval $sql]
+}
+
+proc catchsql {sql} {
+ set rc [catch {uplevel [list db eval $sql]} msg]
+ list $rc $msg
+}
+
+proc catchcmd {db {cmd ""}} {
+ global CLI
+ set out [open cmds.txt w]
+ puts $out $cmd
+ close $out
+ set line "exec $CLI $db < cmds.txt"
+ set rc [catch { eval $line } msg]
+ list $rc $msg
+}
+
+file delete -force test.db test.db.journal
+sqlite3 db test.db
+
+#----------------------------------------------------------------------------
+# Test cases shell4-1.*: Tests specific to the "stats" command.
+#
+
+# should default to off
+do_test shell4-1.1.1 {
+ set res [catchcmd "test.db" ".show"]
+ list [regexp {stats: off} $res]
+} {1}
+
+do_test shell4-1.1.2 {
+ set res [catchcmd "test.db" ".show"]
+ list [regexp {stats: on} $res]
+} {0}
+
+# -stats should turn it on
+do_test shell4-1.2.1 {
+ set res [catchcmd "-stats test.db" ".show"]
+ list [regexp {stats: on} $res]
+} {1}
+
+do_test shell4-1.2.2 {
+ set res [catchcmd "-stats test.db" ".show"]
+ list [regexp {stats: off} $res]
+} {0}
+
+# .stats ON|OFF Turn stats on or off
+do_test shell4-1.3.1 {
+ catchcmd "test.db" ".stats"
+} {1 {Error: unknown command or invalid arguments: "stats". Enter ".help" for help}}
+do_test shell4-1.3.2 {
+ catchcmd "test.db" ".stats ON"
+} {0 {}}
+do_test shell4-1.3.3 {
+ catchcmd "test.db" ".stats OFF"
+} {0 {}}
+do_test shell4-1.3.4 {
+ # too many arguments
+ catchcmd "test.db" ".stats OFF BAD"
+} {1 {Error: unknown command or invalid arguments: "stats". Enter ".help" for help}}
+
+# NB. whitespace is important
+do_test shell4-1.4.1 {
+ set res [catchcmd "test.db" {.show}]
+ list [regexp {stats: off} $res]
+} {1}
+
+do_test shell4-1.4.2 {
+ set res [catchcmd "test.db" {.stats ON
+.show
+}]
+ list [regexp {stats: on} $res]
+} {1}
+
+do_test shell4-1.4.3 {
+ set res [catchcmd "test.db" {.stats OFF
+.show
+}]
+ list [regexp {stats: off} $res]
+} {1}
+
+# make sure stats not present when off
+do_test shell4-1.5.1 {
+ set res [catchcmd "test.db" {SELECT 1;}]
+ list [regexp {Mem Used} $res] \
+ [regexp {Heap Usage} $res] \
+ [regexp {Autoindex Inserts} $res]
+} {0 0 0}
+
+# make sure stats are present when on
+do_test shell4-1.5.2 {
+ set res [catchcmd "test.db" {.stats ON
+SELECT 1;
+}]
+ list [regexp {Mem Used} $res] \
+ [regexp {Heap Usage} $res] \
+ [regexp {Autoindex Inserts} $res]
+} {1 1 1}
+
+puts "CLI tests completed successfully"