]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Get CLI conformed to revised doc for it, and take recent fixes.
authorlarrybr <larrybr@noemail.net>
Sun, 24 Apr 2022 20:00:15 +0000 (20:00 +0000)
committerlarrybr <larrybr@noemail.net>
Sun, 24 Apr 2022 20:00:15 +0000 (20:00 +0000)
FossilOrigin-Name: 60e85c7e7130724a426fab11552ed2aa8e9280f53a219c7e15e0ae0efcaded57

manifest
manifest.uuid
src/shell.c.in
test/shell1.test

index 94c6b0f3db0be6daf479253a7cece26efb686f18..4488c50091f4917ec0a722a07791fde5124ab9a6 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Get\sdocs\scaught\sup\swith\sthe\s.shxload\schange.
-D 2022-04-17T21:03:44.016
+C Get\sCLI\sconformed\sto\srevised\sdoc\sfor\sit,\sand\stake\srecent\sfixes.
+D 2022-04-24T20:00:15.974
 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
 F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
@@ -557,7 +557,7 @@ F src/random.c 097dc8b31b8fba5a9aca1697aeb9fd82078ec91be734c16bffda620ced7ab83c
 F src/resolve.c 18d99e7146852d6064559561769fcca0743eb32b14a97da6dbed373a30ee0e76
 F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92
 F src/select.c 7c106b3f36d483242b0a9c696614cd53d6f29e1ac81da6a3f0e9ea92f4211cc3
-F src/shell.c.in 80745b0842e8becc6dc6934e7c2e4d31928108285ce4d1199466042509b5fd9f
+F src/shell.c.in 6029fb2305e92ebbca8c3e531031239f310dcfad6801ddc4a57dfebd6efc87d3
 F src/shext_linkage.h 0fe0dd831eb1e77b7ae8bc37e80811546531f82b17ef998e08960646cbaf5191
 F src/sqlite.h.in 2a35f62185eb5e7ecc64a2f68442b538ce9be74f80f28a00abc24837edcf1c17
 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
@@ -1396,7 +1396,7 @@ F test/sharedA.test 49d87ec54ab640fbbc3786ee3c01de94aaa482a3a9f834ad3fe92770eb69
 F test/sharedB.test 16cc7178e20965d75278f410943109b77b2e645e
 F test/shared_err.test 32634e404a3317eeb94abc7a099c556a346fdb8fb3858dbe222a4cbb8926a939
 F test/sharedlock.test 5ede3c37439067c43b0198f580fd374ebf15d304
-F test/shell1.test 9401659c4f7319586ddd36aac15aaadff0092caa786589fc20ad069fc2cb1c74
+F test/shell1.test 87fed4b2fb33d3aa4d64552be8be8ec41b383f3f57986ff80e1a2b14370a5c5c
 F test/shell2.test fc6bb55f5ceaaffa284cb994aa00fd56f7ead09949c9db01c3846d65a76a7748
 F test/shell3.test e12fb76031b1d6dec6e778b098ab8720987cb447120abe0dd234fbae1fc05c2c
 F test/shell4.test b232688061cce531f42ec067f3b5760e31d12409e566e2ae230951036dd156f1
@@ -1954,8 +1954,10 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
 F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
 F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
-P e2c8c88b4b4f2c23c42fb1fdb86c0ade2992ce2e5d7f23b06af0e9ea3eb6a4f9
-R a001ab8d5cbb84e92f76cff880c699db
+P e21964480f68152d1c1607f75895354241ec3ea7247f1ee3c2a20c454beec919
+Q +77aed89192bdbad819ac17bf5d08728278a9b8cbbbef1d805df230caff79b417
+Q +dfd2100bc4f316825fd199b347849d1a2b941837f9eedcf36f3c3d280692b991
+R f2ef8541ab9fdfb6f43958528715f12d
 U larrybr
-Z 4d88560e97e58ace681807509ccccdb9
+Z 8c1136d387cc01bce4a929f190c32a8e
 # Remove this line to create a well-formed Fossil manifest.
index cbdb29a1826e7fa62fe5032c4242f7b19895f9fb..5e05ac9e5255ed6eb986870e67582b9855e22308 100644 (file)
@@ -1 +1 @@
-e21964480f68152d1c1607f75895354241ec3ea7247f1ee3c2a20c454beec919
\ No newline at end of file
+60e85c7e7130724a426fab11552ed2aa8e9280f53a219c7e15e0ae0efcaded57
\ No newline at end of file
index 7ada78d6ad4f79c8a6a742e33aa683b19eb2a531..a7d59fa94aa97a785e195ed4e6ec0d9ef6f245dd 100644 (file)
@@ -3602,9 +3602,17 @@ static void restore_sys_schema_protection( sqlite3 *db, DbProtectState *pPS ){
   sqlite3_db_config(db, SQLITE_DBCONFIG_DEFENSIVE, pPS->defensiveMode, 0);
 }
 
-/* Partition the temp.sqlite_parameters key namespace according to use. */
+/* Partition the temp.sqlite_parameters and main.sqlite_variables
+ * key namespace according to use.
+ */
 typedef enum {
-  PTU_Binding = 0, PTU_Script, PTU_Source, PTU_Nil
+  PTU_Binding = 0, /* Binding parameter, value to be bound */
+#define SPTU_Binding SHELL_STRINGIFY(0)
+  PTU_Script  = 1, /* A value containing shell SQL and dot-commands */
+#define SPTU_Script SHELL_STRINGIFY(1)
+  PTU_Entry   = 2, /* Value as entered for non-text binding parameters */
+#define SPTU_Entry SHELL_STRINGIFY(2)
+  PTU_Nil     = 3  /* Unspecified */
 } ParamTableUse;
 
 static ParamTableUse classify_param_name( const char *zName ){
@@ -3681,7 +3689,7 @@ static void param_table_init(sqlite3 *db){
     "CREATE TABLE IF NOT EXISTS "PARAM_TABLE_SNAME"(\n"
     "  key TEXT PRIMARY KEY,\n"
     "  value,\n"
-    "  uses INT DEFAULT (0)" /* aka PTU_Binding */
+    "  uses INT DEFAULT ("SPTU_Binding")"
     ") WITHOUT ROWID;",
     0, 0, 0);
   restore_sys_schema_protection( db, &dps );
@@ -3700,7 +3708,7 @@ static int shvars_table_init(sqlite3 *db){
     "CREATE TABLE IF NOT EXISTS "SHVAR_TABLE_SNAME"(\n"
     "  key TEXT PRIMARY KEY,\n"
     "  value,\n"
-    "  uses INT DEFAULT (0)" /* aka PTU_Binding */
+    "  uses INT DEFAULT ("SPTU_Script")"
     ") WITHOUT ROWID;",
     0, 0, 0);
   restore_sys_schema_protection( db, &dps );
@@ -3988,6 +3996,8 @@ static void exec_prepared_stmt_columnar(
   int bNextLine = 0;
   int bMultiLineRowExists = 0;
   int bw = psi->cmOpts.bWordWrap;
+  const char *zEmpty = "";
+  const char *zShowNull = psi->nullValue;
 
   rc = sqlite3_step(pStmt);
   if( rc!=SQLITE_ROW ) return;
@@ -4049,12 +4059,14 @@ static void exec_prepared_stmt_columnar(
       if( wx<0 ) wx = -wx;
       if( useNextLine ){
         uz = azNextLine[i];
+        if( uz==0 ) uz = (u8*)zEmpty;
       }else if( psi->cmOpts.bQuote ){
         sqlite3_free(azQuoted[i]);
         azQuoted[i] = quoted_column(pStmt,i);
         uz = (const unsigned char*)azQuoted[i];
       }else{
         uz = (const unsigned char*)sqlite3_column_text(pStmt,i);
+        if( uz==0 ) uz = (u8*)zShowNull;
       }
       azData[nRow*nColumn + i]
         = translateForDisplayAndDup(uz, &azNextLine[i], wx, bw);
@@ -4068,7 +4080,7 @@ static void exec_prepared_stmt_columnar(
   nTotal = nColumn*(nRow+1);
   for(i=0; i<nTotal; i++){
     z = azData[i];
-    if( z==0 ) z = psi->nullValue;
+    if( z==0 ) z = (char*)zEmpty;
     n = strlenChar(z);
     j = i%nColumn;
     if( n>psx->pHaveWidths[j] ) psx->pHaveWidths[j] = n;
@@ -4174,7 +4186,10 @@ columnar_end:
     utf8_printf(psi->out, "Interrupt\n");
   }
   nData = (nRow+1)*nColumn;
-  for(i=0; i<nData; i++) free(azData[i]);
+  for(i=0; i<nData; i++){
+    z = azData[i];
+    if( z!=zEmpty && z!=zShowNull ) free(azData[i]);
+  }
   sqlite3_free(azData);
   sqlite3_free((void*)azNextLine);
   sqlite3_free(abRowDiv);
@@ -10840,7 +10855,7 @@ static int shvar_set(sqlite3 *db, char *name, char **valBeg, char **valLim){
   char *zValue = (zValGlom==0)? *valBeg : zValGlom;
   char *zSql
     = smprintf("REPLACE INTO "SHVAR_TABLE_SNAME"(key,value,uses)"
-               "VALUES(%Q,%Q,%d);", name, zValue, PTU_Script);
+               "VALUES(%Q,%Q,"SPTU_Script");", name, zValue);
   shell_check_oom(zSql);
   rc = sqlite3_prepare_v2(db, zSql, -1, &pStmtSet, 0);
   assert(rc==SQLITE_OK);
@@ -10876,12 +10891,12 @@ static int param_set(sqlite3 *db, char cCast,
     if( zCastTo!=0 ){
       zSql = smprintf
         ( "REPLACE INTO "PARAM_TABLE_SNAME"(key,value,uses)"
-          " VALUES(%Q,CAST((%s) AS %s),%d);",
-          name, zValue, zCastTo, PTU_Binding );
+          " VALUES(%Q,CAST((%s) AS %s),"SPTU_Binding");",
+          name, zValue, zCastTo );
     }else{
       zSql = smprintf
         ( "REPLACE INTO "PARAM_TABLE_SNAME"(key,value,uses)"
-          "VALUES(%Q,(%s),%d);", name, zValue, PTU_Binding );
+          "VALUES(%Q,(%s),"SPTU_Binding");", name, zValue );
     }
     shell_check_oom(zSql);
     rc = sqlite3_prepare_v2(db, zSql, -1, &pStmtSet, 0);
@@ -10893,7 +10908,7 @@ static int param_set(sqlite3 *db, char cCast,
     pStmtSet = 0;
     zSql = smprintf
       ( "REPLACE INTO "PARAM_TABLE_SNAME"(key,value,uses)"
-        "VALUES(%Q,%Q,%d);", name, zValue, PTU_Binding );
+        "VALUES(%Q,%Q,"SPTU_Binding");", name, zValue );
     shell_check_oom(zSql);
     rc = sqlite3_prepare_v2(db, zSql, -1, &pStmtSet, 0);
     assert(rc==SQLITE_OK);
@@ -11046,7 +11061,7 @@ static void append_in_clause(sqlite3_str *pStr,
  * The .parameter command
  */
 COLLECT_HELP_TEXT[
-  ".parameter CMD ...       Manage SQL parameter bindings and scripts table",
+  ".parameter CMD ...       Manage per-DB SQL parameter bindings table",
   "   clear ?NAMES?           Erase all or only given named parameters",
 #ifndef SQLITE_NOHAVE_SYSTEM
   "   edit ?OPT? NAME ...     Use edit() to create or alter parameter NAME",
@@ -12327,17 +12342,12 @@ DISPATCHABLE_COMMAND( selftest 4 0 0 ){
 }
 
 /*****************
- * The .shell, .stats and .system commands
+ * The .shell and .system commands
  */
 CONDITION_COMMAND( shell !defined(SQLITE_NOHAVE_SYSTEM) );
 CONDITION_COMMAND( system !defined(SQLITE_NOHAVE_SYSTEM) );
 COLLECT_HELP_TEXT[
   ".shell CMD ARGS...       Run CMD ARGS... in a system shell",
-  ".stats ?ARG?             Show stats or turn stats on or off",
-  "   off                      Turn off automatic stat display",
-  "   on                       Turn on automatic stat display",
-  "   stmt                     Show statement stats",
-  "   vmstep                   Show the virtual machine step count only",
   ".system CMD ARGS...      Run CMD ARGS... in a system shell",
 ];
 
@@ -12507,6 +12517,17 @@ DISPATCHABLE_COMMAND( show ? 1 1 ){
               psi->pAuxDb->zDbFilename ? psi->pAuxDb->zDbFilename : "");
   return DCR_Ok;
 }
+
+/*****************
+ * The .stats command
+ */
+COLLECT_HELP_TEXT[
+  ".stats ?ARG?             Show stats or turn stats on or off",
+  "   off                      Turn off automatic stat display",
+  "   on                       Turn on automatic stat display",
+  "   stmt                     Show statement stats",
+  "   vmstep                   Show the virtual machine step count only",
+];
 DISPATCHABLE_COMMAND( stats ? 0 0 ){
   ShellInState *psi = ISS(p);
   if( nArg==2 ){
@@ -13370,7 +13391,7 @@ DISPATCHABLE_COMMAND( wheretrace ? 1 2 ){
 }
 
 /*****************
- * The .x .read and .eval commands
+ * The .x, .read and .eval commands
  * These are together because they share some function and implementation.
  */
 
@@ -13379,14 +13400,15 @@ COLLECT_HELP_TEXT[
   ".read FILE               Read input from FILE",
   "   If FILE begins with \"|\", it is a command that generates the input.",
   ".x ?OBJS or FLAGS?  ...  Excecute content of objects as shell input",
-  "   FLAGS can be any of {-p -s -f} specifying what subsequent arguments are.",
-  "   Arguments after -p are keys in a key/value table kept by the shell DB,",
+  "   FLAGS can be any of {-k -s -f} specifying what subsequent arguments are.",
+  "   Arguments after -k are keys in a key/value table kept by the shell DB,",
   "   for which the object content to be executed is the corresponding value.",
   "   Arguments after -f name either files (or pipes), which are to be read",
   "   and the content executed. Input pipe names begin with '|'; the rest is",
   "   an OS-shell command which can be run by the OS shell to produce output.",
   "   Arguments after -s are strings, content of which is to be executed.",
-  "   The default in effect for arguments prior to any FLAG is -p .",
+  "   The default in effect for arguments prior to any FLAG is -k .",
+  "   Arguments are executed in order until one fails.",
 ];
 
 /* Return an allocated string with trailing whitespace trimmed except
@@ -13502,11 +13524,11 @@ DISPATCHABLE_COMMAND( x ? 1 0 ){
   DotCmdRC rv = DCR_Ok;
   enum { AsVar, AsString, AsFile } evalAs = AsVar;
 
-  for( ia=1; ia < nArg; ++ia ){
+  for( ia=1; ia<nArg && nErrors==0; ++ia ){
     char *zSubmit = 0;
     const char *zOpt = azArg[ia];
     if ( *zOpt == '-' ){
-      static const char *azOpts[] = { "p", "s", "f" };
+      static const char *azOpts[] = { "k", "s", "f" };
       int io = ArraySize(azOpts);
       while( io > 0 ){
         if( optionMatch(zOpt, azOpts[--io]) ){
@@ -13527,7 +13549,8 @@ DISPATCHABLE_COMMAND( x ? 1 0 ){
           return DCR_Error;
         }
         rc = sqlite3_prepare_v2(dbs, "SELECT value FROM "SHVAR_TABLE_SNAME
-                                " WHERE key=$1 AND uses=1", -1, &pStmt, 0);
+                                " WHERE key=$1 AND uses="SPTU_Script,
+                                -1, &pStmt, 0);
         if( rc!=SQLITE_OK ){
           utf8_printf(STD_ERR, SHVAR_TABLE_SNAME" is wrongly created.\n");
           return DCR_Error;
@@ -13542,15 +13565,10 @@ DISPATCHABLE_COMMAND( x ? 1 0 ){
           const unsigned char *zValue = sqlite3_column_text(pStmt, 0);
           int nb = sqlite3_column_bytes(pStmt, 0);
           zSubmit = zPrepForEval((const char *)zValue, nb);
-          sqlite3_reset(pStmt); /* End the parameter read to unlock DB. */
+          sqlite3_reset(pStmt); /* End the script read to unlock DB. */
           if( zSubmit ){
             rv = shellEvalText(zSubmit, azArg[ia], p);
             sqlite3_free(zSubmit);
-            if( rv<DCR_ArgIxMask ){
-              nErrors += (rv & DCR_Error);
-              /* Handle DCR_Return, DCR_Exit or DCR_Abort */
-              if( rv>DCR_Error ) break;
-            }
           }else{
             continue; /* All white (or OOM), ignore. */
           }
@@ -15180,7 +15198,7 @@ static const char *zOptions =
   "   -safe                enable safe-mode\n"
   "   -separator SEP       set output column separator. Default: '|'\n"
 #if SHELL_EXTENSIONS
-  "   -shxopts BMASK       enable shell extensions and options (7 for all)\n"
+  "   -shxopts BMASK       enable shell extension features (7=all, 0=none)\n"
 #endif
 #ifdef SQLITE_ENABLE_SORTER_REFERENCES
   "   -sorterref SIZE      sorter references threshold size\n"
index cdfb94ab5a27854c6799023b9a6afa394a340d1b..54385d5c64ae02b1f0e4400ef69ecfe5a8f5f349 100644 (file)
@@ -1205,6 +1205,23 @@ do_test shell1-8.4 {
 +------------------+-----+
 | 6683623321994527 | -47 |
 +------------------+-----+}}
+do_test shell1-8.5 {
+  catchcmd ":memory: --box" {
+create table t(a text, b int);
+insert into t values ('too long for one line', 1), ('shorter', NULL);
+.header on
+.width 10 10
+.nullvalue NADA
+select * from t;}
+} {0 {┌────────────┬────────────┐
+│     a      │     b      │
+├────────────┼────────────┤
+│ too long f │ 1          │
+│ or one lin │            │
+│ e          │            │
+├────────────┼────────────┤
+│ shorter    │ NADA       │
+└────────────┴────────────┘}}
 
 #----------------------------------------------------------------------------
 # Test cases shell1-9.*: Basic test that "dot" commands and SQL intermix ok.