]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Modify CLI to optionally display "stats".
authorshaneh <shaneh@noemail.net>
Wed, 28 Jul 2010 16:05:34 +0000 (16:05 +0000)
committershaneh <shaneh@noemail.net>
Wed, 28 Jul 2010 16:05:34 +0000 (16:05 +0000)
FossilOrigin-Name: 419ce0ed89d10252492b2926817259899ee74e71

manifest
manifest.uuid
src/shell.c
tool/shell1.test
tool/shell4.test [new file with mode: 0644]

index 7e759fc96671bbf7779819ef1b589e334118d17f..91347afecb6c02d8191ea2d455cc7c7bfbd4d697 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,8 +1,5 @@
------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
@@ -172,7 +169,7 @@ F src/random.c cd4a67b3953b88019f8cd4ccd81394a8ddfaba50
 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
@@ -826,9 +823,10 @@ F tool/mksqlite3internalh.tcl 7b43894e21bcb1bb39e11547ce7e38a063357e87
 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
@@ -841,14 +839,7 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff
 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
index 6e0508767219da31964154e4c71d43ba38409095..caddf9982a413967cf246434e2a90ba69538f605 100644 (file)
@@ -1 +1 @@
-07abfd5268564c18afd1074c2069d65c64f4b8eb
\ No newline at end of file
+419ce0ed89d10252492b2926817259899ee74e71
\ No newline at end of file
index 23099b94a40852b01dfa8afda9d46e2706640d02..1212d38caf2563d5c53a9cd57941e1edd8ac1800 100644 (file)
@@ -398,6 +398,7 @@ struct previous_mode_data {
 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 */
@@ -961,6 +962,86 @@ static char *save_err_msg(
   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 
@@ -1000,10 +1081,16 @@ static int shell_exec(
         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
@@ -1029,11 +1116,6 @@ static int shell_exec(
             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++){
@@ -1056,9 +1138,6 @@ static int shell_exec(
               }
             } while( SQLITE_ROW == rc );
             sqlite3_free(pData);
-            if( pArg ){
-              pArg->pStmt = NULL;
-            }
           }
         }else{
           do{
@@ -1067,6 +1146,11 @@ static int shell_exec(
         }
       }
 
+      /* 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. */
@@ -1077,6 +1161,11 @@ static int shell_exec(
       }else if( pzErrMsg ){
         *pzErrMsg = save_err_msg(db);
       }
+
+      /* clear saved stmt handle */
+      if( pArg ){
+        pArg->pStmt = NULL;
+      }
     }
   } /* end while */
 
@@ -1256,6 +1345,7 @@ static char zHelp[] =
   "                         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"
@@ -2001,6 +2091,7 @@ static int do_meta_command(char *zLine, struct callback_data *p){
     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]);
@@ -2008,6 +2099,10 @@ static int do_meta_command(char *zLine, struct callback_data *p){
     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;
@@ -2391,6 +2486,7 @@ static const char zOptions[] =
   "   -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"
 ;
@@ -2555,6 +2651,8 @@ int main(int argc, char **argv){
       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 ){
index dcdac758a9cf1e556cdbd748f42547066aeeeb00..f21601a456a23a8a2922b027188d8223d8e985c7 100644 (file)
@@ -178,6 +178,11 @@ do_test shell1-1.14.3 {
        [regexp {Error: missing argument for option: -separator} $res]
 } {1 1}
 
+# -stats               print memory stats before each finalize
+do_test shell1-1.14b.1 {
+  catchcmd "-stats test.db" "" 
+} {0 {}}
+
 # -nullvalue 'text'    set text string for NULL values
 do_test shell1-1.15.1 {
   catchcmd "-nullvalue 'x' test.db" ""
@@ -195,7 +200,7 @@ do_test shell1-1.15.3 {
 # -version             show SQLite version
 do_test shell1-1.16.1 {
   catchcmd "-version test.db" "" 
-} {0 3.7.0}
+} {0 3.7.1}
 
 #----------------------------------------------------------------------------
 # Test cases shell1-2.*: Basic "dot" command token parsing.
@@ -621,13 +626,29 @@ do_test shell1-3.23.1 {
        [regexp {nullvalue:} $res] \
        [regexp {output:} $res] \
        [regexp {separator:} $res] \
+       [regexp {stats:} $res] \
        [regexp {width:} $res]
-} {1 1 1 1 1 1 1 1}
+} {1 1 1 1 1 1 1 1 1}
 do_test shell1-3.23.2 {
   # too many arguments
   catchcmd "test.db" ".show BAD"
 } {1 {Error: unknown command or invalid arguments:  "show". Enter ".help" for help}}
 
+# .stats ON|OFF          Turn stats on or off
+do_test shell1-3.23b.1 {
+  catchcmd "test.db" ".stats"
+} {1 {Error: unknown command or invalid arguments:  "stats". Enter ".help" for help}}
+do_test shell1-3.23b.2 {
+  catchcmd "test.db" ".stats ON"
+} {0 {}}
+do_test shell1-3.23b.3 {
+  catchcmd "test.db" ".stats OFF"
+} {0 {}}
+do_test shell1-3.23b.4 {
+  # too many arguments
+  catchcmd "test.db" ".stats OFF BAD"
+} {1 {Error: unknown command or invalid arguments:  "stats". Enter ".help" for help}}
+
 # .tables ?TABLE?        List names of tables
 #                          If TABLE specified, only list tables matching
 #                          LIKE pattern TABLE.
diff --git a/tool/shell4.test b/tool/shell4.test
new file mode 100644 (file)
index 0000000..e75a4c1
--- /dev/null
@@ -0,0 +1,140 @@
+# 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"