]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Fixes to autoExplain
authordrh <>
Mon, 10 Nov 2025 00:18:36 +0000 (00:18 +0000)
committerdrh <>
Mon, 10 Nov 2025 00:18:36 +0000 (00:18 +0000)
FossilOrigin-Name: 38e4171697057437fc9f70f8734c7f557b91da47804ff10b3d2481802377222f

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

index b4b736e5881a5f5e13dd1b5ed6d4b347e6b67633..dc300e06088224e9ade44ce23befb9e779d5412d 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Enforce\smxRowHeight\sin\scolumnar\slayouts.\s\sCode\sclean-up.\s\sMinimum\scolumn\swith\nis\s2\sif\sthere\sis\swrapping,\sin\scase\sthere\sare\sdouble-wide\scharacters.
-D 2025-11-09T17:25:23.259
+C Fixes\sto\sautoExplain
+D 2025-11-10T00:18:36.008
 F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x
 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
@@ -735,7 +735,7 @@ F src/random.c 606b00941a1d7dd09c381d3279a058d771f406c5213c9932bbd93d5587be4b9c
 F src/resolve.c 5616fbcf3b833c7c705b24371828215ad0925d0c0073216c4f153348d5753f0a
 F src/rowset.c 8432130e6c344b3401a8874c3cb49fefe6873fec593294de077afea2dce5ec97
 F src/select.c ba9cd07ffa3277883c1986085f6ddc4320f4d35d5f212ab58df79a7ecc1a576a
-F src/shell.c.in 5318466b78c1f33d4b65aa6dc5e41fca52d7d146254bf0b0d49a1237f3b72c15
+F src/shell.c.in 22b8fd9c35f3e47029ea601adba3dff7ca0e53508e7e9e7f25d18ecbd0e6123f
 F src/sqlite.h.in 43f60117ce68847b9d4e7fa43c2ac42bb324185e66b924d3114b24d4037fc263
 F src/sqlite3.rc 015537e6ac1eec6c7050e17b616c2ffe6f70fca241835a84a4f0d5937383c479
 F src/sqlite3ext.h 7f236ca1b175ffe03316d974ef57df79b3938466c28d2f95caef5e08c57f3a52
@@ -1601,7 +1601,7 @@ F test/sharedA.test 64bdd21216dda2c6a3bd3475348ccdc108160f34682c97f2f51c19fc0e21
 F test/sharedB.test 1a84863d7a2204e0d42f2e1606577c5e92e4473fa37ea0f5bdf829e4bf8ee707
 F test/shared_err.test 32634e404a3317eeb94abc7a099c556a346fdb8fb3858dbe222a4cbb8926a939
 F test/sharedlock.test 5ede3c37439067c43b0198f580fd374ebf15d304
-F test/shell1.test 25c90db401a323ab65c299728446ca6042388acdca3b4883a48e10e8aeda61ec
+F test/shell1.test 49c6ebb23d41b1171a3fac7b19a9091b98966a736cd632103d409e59310916ce
 F test/shell2.test d8da6a06dcce1d8f04f776f918d4d57c28ddc28c54f3a44f95429794892e3a91
 F test/shell3.test 603b448e917537cf77be0f265c05c6f63bc677c63a533c8e96aae923b56f4a0e
 F test/shell4.test 03593fa7908a55f255916ffeda707cdf55680c777736e3da62b1d78cde0d684d
@@ -2173,8 +2173,8 @@ F tool/version-info.c 33d0390ef484b3b1cb685d59362be891ea162123cea181cb8e6d2cf6dd
 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7
 F tool/warnings.sh d924598cf2f55a4ecbc2aeb055c10bd5f48114793e7ba25f9585435da29e7e98
 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
-P 37bd136ae842c8f8110c10b0834c804a8af133ce0caff492f37bd567a56ac6c6
-R b230166f53990d22a4280416c83ac02d
+P 0ee8fc00af4c82da0d597c65dd3d8590c71ea78d8f4a29653bbb21668c6c530d
+R 1b83fc1fe906411e336c745260017220
 U drh
-Z 545297433252d44682281bbfa2a0dfdd
+Z b43f3bd2ed19eeb9e0c51dc01284fe35
 # Remove this line to create a well-formed Fossil manifest.
index 3637576ac8ab5fea503b512a5c34ea8c76bf544b..e66ecc9645765345cf1a453fb2e94a6ca244f34b 100644 (file)
@@ -1 +1 @@
-0ee8fc00af4c82da0d597c65dd3d8590c71ea78d8f4a29653bbb21668c6c530d
+38e4171697057437fc9f70f8734c7f557b91da47804ff10b3d2481802377222f
index 34df6faaa40ad9dab9642fdca0660fdca460a675..e64736e6ef6693a7314680bc50b143debc569c4b 100644 (file)
@@ -3006,11 +3006,9 @@ static int shell_exec(
       break;
     }
   }
-  if( sqlite3_stmt_isexplain(pStmt) ){
-    eStyle = QRF_STYLE_Auto;
-  }else if( pArg->cMode>=0
-         && pArg->cMode<ArraySize(aQrfStyle)
-         && aQrfStyle[pArg->cMode]<100
+  if( pArg->cMode>=0
+   && pArg->cMode<ArraySize(aQrfStyle)
+   && aQrfStyle[pArg->cMode]<100
   ){
     eStyle = aQrfStyle[pArg->cMode];
   }else{
@@ -3032,6 +3030,7 @@ static int shell_exec(
         *pzErrMsg = save_err_msg(db, "in prepare", rc, zSql);
       }
     }else{
+      int isExplain;
       if( !pStmt ){
         /* this happens for a comment or white-space */
         zSql = zLeftover;
@@ -3047,9 +3046,10 @@ static int shell_exec(
         pArg->pStmt = pStmt;
         pArg->cnt = 0;
       }
-
+     
       /* Show the EXPLAIN QUERY PLAN if .eqp is on */
-      if( pArg && pArg->autoEQP && sqlite3_stmt_isexplain(pStmt)==0 ){
+      isExplain = sqlite3_stmt_isexplain(pStmt);
+      if( pArg && pArg->autoEQP && isExplain==0 ){
         int triggerEQP = 0;
         disable_debug_trace_modes();
         sqlite3_db_config(db, SQLITE_DBCONFIG_TRIGGER_EQP, -1, &triggerEQP);
@@ -3069,7 +3069,10 @@ static int shell_exec(
       }
 
       bind_prepared_stmt(pArg, pStmt);
-      if( eStyle<100 ){
+      if( isExplain && pArg->autoExplain ){
+        spec.eStyle = isExplain==1 ? QRF_STYLE_Explain : QRF_STYLE_Eqp;
+        sqlite3_format_query_result(pStmt, &spec, pzErrMsg);
+      }else if( eStyle<100 ){
         spec.eStyle = eStyle;
         sqlite3_format_query_result(pStmt, &spec, pzErrMsg);
       }else{
@@ -7611,8 +7614,13 @@ static int do_meta_command(char *zLine, ShellState *p){
   /* The ".explain" command is automatic now.  It is largely pointless.  It
   ** retained purely for backwards compatibility */
   if( c=='e' && cli_strncmp(azArg[0], "explain", n)==0 ){
-    eputz("EXPLAIN output formatting is now automatic. "
-          "\".explain\" is pointless.\n");
+    if( nArg>=2 ){
+      if( cli_strcmp(azArg[1],"auto")==0 ){
+        p->autoExplain = 1;
+      }else{
+        p->autoExplain = booleanValue(azArg[1]);
+      }
+    }
   }else
 
 #if !defined(SQLITE_OMIT_VIRTUALTABLE) && !defined(SQLITE_OMIT_AUTHORIZATION)
@@ -9878,6 +9886,8 @@ static int do_meta_command(char *zLine, ShellState *p){
     sqlite3_fprintf(p->out, "%12.12s: %s\n","echo",
           azBool[ShellHasFlag(p, SHFLG_Echo)]);
     sqlite3_fprintf(p->out, "%12.12s: %s\n","eqp", azBool[p->autoEQP&3]);
+    sqlite3_fprintf(p->out, "%12.12s: %s\n","explain",
+                             p->autoExplain ? "auto" : "off");
     sqlite3_fprintf(p->out, "%12.12s: %s\n","headers",
           azBool[p->showHeader!=0]);
     if( p->mode==MODE_Column
index efe80430bd4ee73b45d2b7c8fd7ae4eeddc773ca..9a69aa767c4f59e16b54500e9d99726f65abb81a 100644 (file)
@@ -208,6 +208,12 @@ do_test shell1-2.2.1 {
 do_test shell1-2.2.2 {
   catchcmd "test.db" ".\'foo OFF"
 } {1 {Error: unknown command or invalid arguments:  "foo OFF". Enter ".help" for help}}
+do_test shell1-2.2.3 {
+  catchcmd "test.db" ".explain \"OFF"
+} {0 {}}
+do_test shell1-2.2.4 {
+  catchcmd "test.db" ".explain \'OFF"
+} {0 {}}
 do_test shell1-2.2.5 {
   catchcmd "test.db" ".mode \"insert FOO"
 } {1 {Error: mode should be one of: ascii box column csv html insert json line list markdown qbox quote table tabs tcl}}
@@ -215,6 +221,29 @@ do_test shell1-2.2.6 {
   catchcmd "test.db" ".mode \'insert FOO"
 } {1 {Error: mode should be one of: ascii box column csv html insert json line list markdown qbox quote table tabs tcl}}
 
+# check multiple tokens, and quoted tokens
+do_test shell1-2.3.1 {
+  catchcmd "test.db" ".explain 1"
+} {0 {}}
+do_test shell1-2.3.2 {
+  catchcmd "test.db" ".explain on"
+} {0 {}}
+do_test shell1-2.3.3 {
+  catchcmd "test.db" ".explain \"1 2 3\""
+} {1 {ERROR: Not a boolean value: "1 2 3". Assuming "no".}}
+do_test shell1-2.3.4 {
+  catchcmd "test.db" ".explain \"OFF\""
+} {0 {}}
+do_test shell1-2.3.5 {
+  catchcmd "test.db" ".\'explain\' \'OFF\'"
+} {0 {}}
+do_test shell1-2.3.6 {
+  catchcmd "test.db" ".explain \'OFF\'"
+} {0 {}}
+do_test shell1-2.3.7 {
+  catchcmd "test.db" ".\'explain\' \'OFF\'"
+} {0 {}}
+
 # check quoted args are unquoted
 do_test shell1-2.4.1 {
   catchcmd "test.db" ".mode FOO"
@@ -319,6 +348,22 @@ do_test shell1-3.6.1 {
   catchcmd "test.db" ".exit"
 } {0 {}}
 
+# .explain ON|OFF        Turn output mode suitable for EXPLAIN on or off.
+do_test shell1-3.7.1 {
+  catchcmd "test.db" ".explain"
+  # explain is the exception to the booleans.  without an option, it turns it on.
+} {0 {}}
+do_test shell1-3.7.2 {
+  catchcmd "test.db" ".explain ON"
+} {0 {}}
+do_test shell1-3.7.3 {
+  catchcmd "test.db" ".explain OFF"
+} {0 {}}
+do_test shell1-3.7.4 {
+  # extra arguments ignored
+  catchcmd "test.db" ".explain OFF BAD"
+} {0 {}}
+
 # .header(s) ON|OFF      Turn display of headers on or off
 do_test shell1-3.9.1 {
   catchcmd "test.db" ".header"
@@ -599,6 +644,7 @@ do_test shell1-3.22.4 {
 do_test shell1-3.23.1 {
   set res [catchcmd "test.db" ".show"]
   list [regexp {echo:} $res] \
+       [regexp {explain:} $res] \
        [regexp {headers:} $res] \
        [regexp {mode:} $res] \
        [regexp {nullvalue:} $res] \
@@ -607,7 +653,7 @@ do_test shell1-3.23.1 {
        [regexp {rowseparator:} $res] \
        [regexp {stats:} $res] \
        [regexp {width:} $res]
-} {1 1 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"