/ Check-in [751915cb]
Login
SQLite training in Houston TX on 2019-11-05 (details)
Part of the 2019 Tcl Conference

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Enhance the command-line shell to be in auto-explain mode by default. It is no longer necessary to use the ".explain" command to put the shell into a mode where the EXPLAIN output is formatted nicely. That now happens automatically.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 751915cb7e4981661a40dc5e4d029ab27434c2d9
User & Date: drh 2016-02-09 20:11:14
Context
2016-02-09
20:31
In the shell, use the appropriate string constant instead of a literal new-line. check-in: 61951b15 user: mistachkin tags: trunk
20:11
Enhance the command-line shell to be in auto-explain mode by default. It is no longer necessary to use the ".explain" command to put the shell into a mode where the EXPLAIN output is formatted nicely. That now happens automatically. check-in: 751915cb user: drh tags: trunk
20:04
Improved auto-detection of EXPLAIN output in the shell. Closed-Leaf check-in: 6c6d7a6e user: drh tags: auto-explain
18:28
Fix MSVC makefile options that enable control-flow guard. check-in: 51b6823f user: mistachkin tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/shell.c.

   588    588   ** State information about the database connection is contained in an
   589    589   ** instance of the following structure.
   590    590   */
   591    591   typedef struct ShellState ShellState;
   592    592   struct ShellState {
   593    593     sqlite3 *db;           /* The database */
   594    594     int echoOn;            /* True to echo input commands */
          595  +  int autoExplain;       /* Automatically turn on .explain mode */
   595    596     int autoEQP;           /* Run EXPLAIN QUERY PLAN prior to seach SQL stmt */
   596    597     int statsOn;           /* True to display memory stats before each finalize */
   597    598     int scanstatsOn;       /* True to display scan stats before each finalize */
   598    599     int countChanges;      /* True to display change counts */
   599    600     int backslashOn;       /* Resolve C-style \x escapes in SQL input text */
   600    601     int outCount;          /* Revert to stdout when reaching zero */
   601    602     int cnt;               /* Number of records displayed so far */
   602    603     FILE *out;             /* Write results here */
   603    604     FILE *traceOut;        /* Output for sqlite3_trace() */
   604    605     int nErr;              /* Number of errors seen */
   605    606     int mode;              /* An output mode setting */
          607  +  int cMode;             /* temporary output mode for the current query */
          608  +  int normalMode;        /* Output mode before ".explain on" */
   606    609     int writableSchema;    /* True if PRAGMA writable_schema=ON */
   607    610     int showHeader;        /* True to show column names in List or Column mode */
   608    611     unsigned shellFlgs;    /* Various flags */
   609    612     char *zDestTable;      /* Name of destination table when MODE_Insert */
   610    613     char colSeparator[20]; /* Column separator character for several modes */
   611    614     char rowSeparator[20]; /* Row separator character for MODE_Ascii */
   612    615     int colWidth[100];     /* Requested width of each column when in column mode*/
   613    616     int actualWidth[100];  /* Actual width of each column */
   614    617     char nullValue[20];    /* The text to print when a NULL comes back from
   615    618                            ** the database */
   616         -  SavedModeInfo normalMode;/* Holds the mode just before .explain ON */
   617    619     char outfile[FILENAME_MAX]; /* Filename for *out */
   618    620     const char *zDbFilename;    /* name of the database file */
   619    621     char *zFreeOnClose;         /* Filename to free when closing */
   620    622     const char *zVfs;           /* Name of VFS to use */
   621    623     sqlite3_stmt *pStmt;   /* Current statement if any. */
   622    624     FILE *pLog;            /* Write log output here */
   623    625     int *aiIndent;         /* Array of indents used in MODE_Explain */
................................................................................
   878    880     char **azArg,    /* Text of each result column */
   879    881     char **azCol,    /* Column names */
   880    882     int *aiType      /* Column types */
   881    883   ){
   882    884     int i;
   883    885     ShellState *p = (ShellState*)pArg;
   884    886   
   885         -  switch( p->mode ){
          887  +  switch( p->cMode ){
   886    888       case MODE_Line: {
   887    889         int w = 5;
   888    890         if( azArg==0 ) break;
   889    891         for(i=0; i<nArg; i++){
   890    892           int len = strlen30(azCol[i] ? azCol[i] : "");
   891    893           if( len>w ) w = len;
   892    894         }
................................................................................
   895    897           utf8_printf(p->out,"%*s = %s%s", w, azCol[i],
   896    898                   azArg[i] ? azArg[i] : p->nullValue, p->rowSeparator);
   897    899         }
   898    900         break;
   899    901       }
   900    902       case MODE_Explain:
   901    903       case MODE_Column: {
          904  +      static const int aExplainWidths[] = {4, 13, 4, 4, 4, 13, 2, 13};
          905  +      const int *colWidth;
          906  +      int showHdr;
          907  +      char *rowSep;
          908  +      if( p->cMode==MODE_Column ){
          909  +        colWidth = p->colWidth;
          910  +        showHdr = p->showHeader;
          911  +        rowSep = p->rowSeparator;
          912  +      }else{
          913  +        colWidth = aExplainWidths;
          914  +        showHdr = 1;
          915  +        rowSep = "\n";
          916  +      }
   902    917         if( p->cnt++==0 ){
   903    918           for(i=0; i<nArg; i++){
   904    919             int w, n;
   905    920             if( i<ArraySize(p->colWidth) ){
   906         -            w = p->colWidth[i];
          921  +            w = colWidth[i];
   907    922             }else{
   908    923               w = 0;
   909    924             }
   910    925             if( w==0 ){
   911    926               w = strlen30(azCol[i] ? azCol[i] : "");
   912    927               if( w<10 ) w = 10;
   913    928               n = strlen30(azArg && azArg[i] ? azArg[i] : p->nullValue);
   914    929               if( w<n ) w = n;
   915    930             }
   916    931             if( i<ArraySize(p->actualWidth) ){
   917    932               p->actualWidth[i] = w;
   918    933             }
   919         -          if( p->showHeader ){
          934  +          if( showHdr ){
   920    935               if( w<0 ){
   921    936                 utf8_printf(p->out,"%*.*s%s",-w,-w,azCol[i],
   922         -                      i==nArg-1 ? p->rowSeparator : "  ");
          937  +                      i==nArg-1 ? rowSep : "  ");
   923    938               }else{
   924    939                 utf8_printf(p->out,"%-*.*s%s",w,w,azCol[i],
   925         -                      i==nArg-1 ? p->rowSeparator : "  ");
          940  +                      i==nArg-1 ? rowSep : "  ");
   926    941               }
   927    942             }
   928    943           }
   929         -        if( p->showHeader ){
          944  +        if( showHdr ){
   930    945             for(i=0; i<nArg; i++){
   931    946               int w;
   932    947               if( i<ArraySize(p->actualWidth) ){
   933    948                  w = p->actualWidth[i];
   934    949                  if( w<0 ) w = -w;
   935    950               }else{
   936    951                  w = 10;
   937    952               }
   938    953               utf8_printf(p->out,"%-*.*s%s",w,w,
   939    954                      "----------------------------------------------------------"
   940    955                      "----------------------------------------------------------",
   941         -                    i==nArg-1 ? p->rowSeparator : "  ");
          956  +                    i==nArg-1 ? rowSep : "  ");
   942    957             }
   943    958           }
   944    959         }
   945    960         if( azArg==0 ) break;
   946    961         for(i=0; i<nArg; i++){
   947    962           int w;
   948    963           if( i<ArraySize(p->actualWidth) ){
   949    964              w = p->actualWidth[i];
   950    965           }else{
   951    966              w = 10;
   952    967           }
   953         -        if( p->mode==MODE_Explain && azArg[i] && strlen30(azArg[i])>w ){
          968  +        if( p->cMode==MODE_Explain && azArg[i] && strlen30(azArg[i])>w ){
   954    969             w = strlen30(azArg[i]);
   955    970           }
   956    971           if( i==1 && p->aiIndent && p->pStmt ){
   957    972             if( p->iIndent<p->nIndent ){
   958    973               utf8_printf(p->out, "%*.s", p->aiIndent[p->iIndent], "");
   959    974             }
   960    975             p->iIndent++;
   961    976           }
   962    977           if( w<0 ){
   963    978             utf8_printf(p->out,"%*.*s%s",-w,-w,
   964    979                 azArg[i] ? azArg[i] : p->nullValue,
   965         -              i==nArg-1 ? p->rowSeparator : "  ");
          980  +              i==nArg-1 ? rowSep : "  ");
   966    981           }else{
   967    982             utf8_printf(p->out,"%-*.*s%s",w,w,
   968    983                 azArg[i] ? azArg[i] : p->nullValue,
   969         -              i==nArg-1 ? p->rowSeparator : "  ");
          984  +              i==nArg-1 ? rowSep : "  ");
   970    985           }
   971    986         }
   972    987         break;
   973    988       }
   974    989       case MODE_Semi:
   975    990       case MODE_List: {
   976    991         if( p->cnt++==0 && p->showHeader ){
................................................................................
   982    997         if( azArg==0 ) break;
   983    998         for(i=0; i<nArg; i++){
   984    999           char *z = azArg[i];
   985   1000           if( z==0 ) z = p->nullValue;
   986   1001           utf8_printf(p->out, "%s", z);
   987   1002           if( i<nArg-1 ){
   988   1003             utf8_printf(p->out, "%s", p->colSeparator);
   989         -        }else if( p->mode==MODE_Semi ){
         1004  +        }else if( p->cMode==MODE_Semi ){
   990   1005             utf8_printf(p->out, ";%s", p->rowSeparator);
   991   1006           }else{
   992   1007             utf8_printf(p->out, "%s", p->rowSeparator);
   993   1008           }
   994   1009         }
   995   1010         break;
   996   1011       }
................................................................................
  1487   1502                              "NextIfOpen", "PrevIfOpen", 0 };
  1488   1503     const char *azYield[] = { "Yield", "SeekLT", "SeekGT", "RowSetRead",
  1489   1504                               "Rewind", 0 };
  1490   1505     const char *azGoto[] = { "Goto", 0 };
  1491   1506   
  1492   1507     /* Try to figure out if this is really an EXPLAIN statement. If this
  1493   1508     ** cannot be verified, return early.  */
         1509  +  if( sqlite3_column_count(pSql)!=8 ){
         1510  +    p->cMode = p->mode;
         1511  +    return;
         1512  +  }
  1494   1513     zSql = sqlite3_sql(pSql);
  1495   1514     if( zSql==0 ) return;
  1496   1515     for(z=zSql; *z==' ' || *z=='\t' || *z=='\n' || *z=='\f' || *z=='\r'; z++);
  1497         -  if( sqlite3_strnicmp(z, "explain", 7) ) return;
         1516  +  if( sqlite3_strnicmp(z, "explain", 7) ){
         1517  +    p->cMode = p->mode;
         1518  +    return;
         1519  +  }
  1498   1520   
  1499   1521     for(iOp=0; SQLITE_ROW==sqlite3_step(pSql); iOp++){
  1500   1522       int i;
  1501   1523       int iAddr = sqlite3_column_int(pSql, 0);
  1502   1524       const char *zOp = (const char*)sqlite3_column_text(pSql, 1);
  1503   1525   
  1504   1526       /* Set p2 to the P2 field of the current opcode. Then, assuming that
................................................................................
  1507   1529       ** the current instruction is part of a sub-program generated by an
  1508   1530       ** SQL trigger or foreign key.  */
  1509   1531       int p2 = sqlite3_column_int(pSql, 3);
  1510   1532       int p2op = (p2 + (iOp-iAddr));
  1511   1533   
  1512   1534       /* Grow the p->aiIndent array as required */
  1513   1535       if( iOp>=nAlloc ){
         1536  +      if( iOp==0 ){
         1537  +        /* Do further verfication that this is explain output.  Abort if
         1538  +        ** it is not */
         1539  +        static const char *explainCols[] = {
         1540  +           "addr", "opcode", "p1", "p2", "p3", "p4", "p5", "comment" };
         1541  +        int jj;
         1542  +        for(jj=0; jj<ArraySize(explainCols); jj++){
         1543  +          if( strcmp(sqlite3_column_name(pSql,jj),explainCols[jj])!=0 ){
         1544  +            p->cMode = p->mode;
         1545  +            sqlite3_reset(pSql);
         1546  +            return;
         1547  +          }
         1548  +        }
         1549  +      }
  1514   1550         nAlloc += 100;
  1515   1551         p->aiIndent = (int*)sqlite3_realloc64(p->aiIndent, nAlloc*sizeof(int));
  1516   1552         abYield = (int*)sqlite3_realloc64(abYield, nAlloc*sizeof(int));
  1517   1553       }
  1518   1554       abYield[iOp] = str_in_array(zOp, azYield);
  1519   1555       p->aiIndent[iOp] = 0;
  1520   1556       p->nIndent = iOp+1;
................................................................................
  1610   1646               utf8_printf(pArg->out,"%s\n", sqlite3_column_text(pExplain, 3));
  1611   1647             }
  1612   1648           }
  1613   1649           sqlite3_finalize(pExplain);
  1614   1650           sqlite3_free(zEQP);
  1615   1651         }
  1616   1652   
  1617         -      /* If the shell is currently in ".explain" mode, gather the extra
  1618         -      ** data required to add indents to the output.*/
  1619         -      if( pArg && pArg->mode==MODE_Explain ){
  1620         -        explain_data_prepare(pArg, pStmt);
         1653  +      if( pArg ){
         1654  +        pArg->cMode = pArg->mode;
         1655  +        if( pArg->autoExplain
         1656  +         && sqlite3_column_count(pStmt)==8
         1657  +         && sqlite3_strlike("%EXPLAIN%", sqlite3_sql(pStmt),0)==0
         1658  +        ){
         1659  +          pArg->cMode = MODE_Explain;
         1660  +        }
         1661  +      
         1662  +        /* If the shell is currently in ".explain" mode, gather the extra
         1663  +        ** data required to add indents to the output.*/
         1664  +        if( pArg->cMode==MODE_Explain ){
         1665  +          explain_data_prepare(pArg, pStmt);
         1666  +        }
  1621   1667         }
  1622   1668   
  1623   1669         /* perform the first step.  this will tell us if we
  1624   1670         ** have a result set or not and how wide it is.
  1625   1671         */
  1626   1672         rc = sqlite3_step(pStmt);
  1627   1673         /* if we have a result set... */
................................................................................
  1643   1689               for(i=0; i<nCol; i++){
  1644   1690                 azCols[i] = (char *)sqlite3_column_name(pStmt, i);
  1645   1691               }
  1646   1692               do{
  1647   1693                 /* extract the data and data types */
  1648   1694                 for(i=0; i<nCol; i++){
  1649   1695                   aiTypes[i] = x = sqlite3_column_type(pStmt, i);
  1650         -                if( x==SQLITE_BLOB && pArg && pArg->mode==MODE_Insert ){
         1696  +                if( x==SQLITE_BLOB && pArg && pArg->cMode==MODE_Insert ){
  1651   1697                     azVals[i] = "";
  1652   1698                   }else{
  1653   1699                     azVals[i] = (char*)sqlite3_column_text(pStmt, i);
  1654   1700                   }
  1655   1701                   if( !azVals[i] && (aiTypes[i]!=SQLITE_NULL) ){
  1656   1702                     rc = SQLITE_NOMEM;
  1657   1703                     break; /* from for */
................................................................................
  1863   1909     ".dbinfo ?DB?           Show status information about the database\n"
  1864   1910     ".dump ?TABLE? ...      Dump the database in an SQL text format\n"
  1865   1911     "                         If TABLE specified, only dump tables matching\n"
  1866   1912     "                         LIKE pattern TABLE.\n"
  1867   1913     ".echo on|off           Turn command echo on or off\n"
  1868   1914     ".eqp on|off            Enable or disable automatic EXPLAIN QUERY PLAN\n"
  1869   1915     ".exit                  Exit this program\n"
  1870         -  ".explain ?on|off?      Turn output mode suitable for EXPLAIN on or off.\n"
  1871         -  "                         With no args, it turns EXPLAIN on.\n"
         1916  +  ".explain ?on|off|auto? Turn EXPLAIN output mode on or off or to automatic\n"
  1872   1917     ".fullschema            Show schema and the content of sqlite_stat tables\n"
  1873   1918     ".headers on|off        Turn display of headers on or off\n"
  1874   1919     ".help                  Show this message\n"
  1875   1920     ".import FILE TABLE     Import data from FILE into TABLE\n"
  1876   1921     ".indexes ?TABLE?       Show names of all indexes\n"
  1877   1922     "                         If TABLE specified, only show indexes for tables\n"
  1878   1923     "                         matching LIKE pattern TABLE.\n"
................................................................................
  2851   2896   
  2852   2897     if( c=='d' && n>1 && strncmp(azArg[0], "databases", n)==0 ){
  2853   2898       ShellState data;
  2854   2899       char *zErrMsg = 0;
  2855   2900       open_db(p, 0);
  2856   2901       memcpy(&data, p, sizeof(data));
  2857   2902       data.showHeader = 1;
  2858         -    data.mode = MODE_Column;
         2903  +    data.cMode = data.mode = MODE_Column;
  2859   2904       data.colWidth[0] = 3;
  2860   2905       data.colWidth[1] = 15;
  2861   2906       data.colWidth[2] = 58;
  2862   2907       data.cnt = 0;
  2863   2908       sqlite3_exec(p->db, "PRAGMA database_list; ", callback, &data, &zErrMsg);
  2864   2909       if( zErrMsg ){
  2865   2910         utf8_printf(stderr,"Error: %s\n", zErrMsg);
................................................................................
  2946   2991   
  2947   2992     if( c=='e' && strncmp(azArg[0], "exit", n)==0 ){
  2948   2993       if( nArg>1 && (rc = (int)integerValue(azArg[1]))!=0 ) exit(rc);
  2949   2994       rc = 2;
  2950   2995     }else
  2951   2996   
  2952   2997     if( c=='e' && strncmp(azArg[0], "explain", n)==0 ){
  2953         -    int val = nArg>=2 ? booleanValue(azArg[1]) : 1;
  2954         -    if(val == 1) {
  2955         -      if(!p->normalMode.valid) {
  2956         -        p->normalMode.valid = 1;
  2957         -        p->normalMode.mode = p->mode;
  2958         -        p->normalMode.showHeader = p->showHeader;
  2959         -        memcpy(p->normalMode.colWidth,p->colWidth,sizeof(p->colWidth));
         2998  +    int val = 1;
         2999  +    if( nArg>=2 ){
         3000  +      if( strcmp(azArg[1],"auto")==0 ){
         3001  +        val = 99;
         3002  +      }else{
         3003  +        val =  booleanValue(azArg[1]);
  2960   3004         }
  2961         -      /* We could put this code under the !p->explainValid
  2962         -      ** condition so that it does not execute if we are already in
  2963         -      ** explain mode. However, always executing it allows us an easy
  2964         -      ** was to reset to explain mode in case the user previously
  2965         -      ** did an .explain followed by a .width, .mode or .header
  2966         -      ** command.
  2967         -      */
         3005  +    }
         3006  +    if( val==1 && p->mode!=MODE_Explain ){
         3007  +      p->normalMode = p->mode;
  2968   3008         p->mode = MODE_Explain;
  2969         -      p->showHeader = 1;
  2970         -      memset(p->colWidth,0,sizeof(p->colWidth));
  2971         -      p->colWidth[0] = 4;                  /* addr */
  2972         -      p->colWidth[1] = 13;                 /* opcode */
  2973         -      p->colWidth[2] = 4;                  /* P1 */
  2974         -      p->colWidth[3] = 4;                  /* P2 */
  2975         -      p->colWidth[4] = 4;                  /* P3 */
  2976         -      p->colWidth[5] = 13;                 /* P4 */
  2977         -      p->colWidth[6] = 2;                  /* P5 */
  2978         -      p->colWidth[7] = 13;                  /* Comment */
  2979         -    }else if (p->normalMode.valid) {
  2980         -      p->normalMode.valid = 0;
  2981         -      p->mode = p->normalMode.mode;
  2982         -      p->showHeader = p->normalMode.showHeader;
  2983         -      memcpy(p->colWidth,p->normalMode.colWidth,sizeof(p->colWidth));
         3009  +      p->autoExplain = 0;
         3010  +    }else if( val==0 ){
         3011  +      if( p->mode==MODE_Explain ) p->mode = p->normalMode;
         3012  +      p->autoExplain = 0;
         3013  +    }else if( val==99 ){
         3014  +      if( p->mode==MODE_Explain ) p->mode = p->normalMode;
         3015  +      p->autoExplain = 1;
  2984   3016       }
  2985   3017     }else
  2986   3018   
  2987   3019     if( c=='f' && strncmp(azArg[0], "fullschema", n)==0 ){
  2988   3020       ShellState data;
  2989   3021       char *zErrMsg = 0;
  2990   3022       int doStats = 0;
................................................................................
  2992   3024         raw_printf(stderr, "Usage: .fullschema\n");
  2993   3025         rc = 1;
  2994   3026         goto meta_command_exit;
  2995   3027       }
  2996   3028       open_db(p, 0);
  2997   3029       memcpy(&data, p, sizeof(data));
  2998   3030       data.showHeader = 0;
  2999         -    data.mode = MODE_Semi;
         3031  +    data.cMode = data.mode = MODE_Semi;
  3000   3032       rc = sqlite3_exec(p->db,
  3001   3033          "SELECT sql FROM"
  3002   3034          "  (SELECT sql sql, type type, tbl_name tbl_name, name name, rowid x"
  3003   3035          "     FROM sqlite_master UNION ALL"
  3004   3036          "   SELECT sql, type, tbl_name, name, rowid FROM sqlite_temp_master) "
  3005   3037          "WHERE type!='meta' AND sql NOTNULL AND name NOT LIKE 'sqlite_%' "
  3006   3038          "ORDER BY rowid",
................................................................................
  3017   3049       }
  3018   3050       if( doStats==0 ){
  3019   3051         raw_printf(p->out, "/* No STAT tables available */\n");
  3020   3052       }else{
  3021   3053         raw_printf(p->out, "ANALYZE sqlite_master;\n");
  3022   3054         sqlite3_exec(p->db, "SELECT 'ANALYZE sqlite_master'",
  3023   3055                      callback, &data, &zErrMsg);
  3024         -      data.mode = MODE_Insert;
         3056  +      data.cMode = data.mode = MODE_Insert;
  3025   3057         data.zDestTable = "sqlite_stat1";
  3026   3058         shell_exec(p->db, "SELECT * FROM sqlite_stat1",
  3027   3059                    shell_callback, &data,&zErrMsg);
  3028   3060         data.zDestTable = "sqlite_stat3";
  3029   3061         shell_exec(p->db, "SELECT * FROM sqlite_stat3",
  3030   3062                    shell_callback, &data,&zErrMsg);
  3031   3063         data.zDestTable = "sqlite_stat4";
................................................................................
  3249   3281     if( c=='i' && (strncmp(azArg[0], "indices", n)==0
  3250   3282                    || strncmp(azArg[0], "indexes", n)==0) ){
  3251   3283       ShellState data;
  3252   3284       char *zErrMsg = 0;
  3253   3285       open_db(p, 0);
  3254   3286       memcpy(&data, p, sizeof(data));
  3255   3287       data.showHeader = 0;
  3256         -    data.mode = MODE_List;
         3288  +    data.cMode = data.mode = MODE_List;
  3257   3289       if( nArg==1 ){
  3258   3290         rc = sqlite3_exec(p->db,
  3259   3291           "SELECT name FROM sqlite_master "
  3260   3292           "WHERE type='index' AND name NOT LIKE 'sqlite_%' "
  3261   3293           "UNION ALL "
  3262   3294           "SELECT name FROM sqlite_temp_master "
  3263   3295           "WHERE type='index' "
................................................................................
  3435   3467         sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Unit);
  3436   3468         sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_Record);
  3437   3469       }else {
  3438   3470         raw_printf(stderr, "Error: mode should be one of: "
  3439   3471            "ascii column csv html insert line list tabs tcl\n");
  3440   3472         rc = 1;
  3441   3473       }
         3474  +    p->cMode = p->mode;
  3442   3475     }else
  3443   3476   
  3444   3477     if( c=='n' && strncmp(azArg[0], "nullvalue", n)==0 ){
  3445   3478       if( nArg==2 ){
  3446   3479         sqlite3_snprintf(sizeof(p->nullValue), p->nullValue,
  3447   3480                          "%.*s", (int)ArraySize(p->nullValue)-1, azArg[1]);
  3448   3481       }else{
................................................................................
  3624   3657   
  3625   3658     if( c=='s' && strncmp(azArg[0], "schema", n)==0 ){
  3626   3659       ShellState data;
  3627   3660       char *zErrMsg = 0;
  3628   3661       open_db(p, 0);
  3629   3662       memcpy(&data, p, sizeof(data));
  3630   3663       data.showHeader = 0;
  3631         -    data.mode = MODE_Semi;
         3664  +    data.cMode = data.mode = MODE_Semi;
  3632   3665       if( nArg==2 ){
  3633   3666         int i;
  3634   3667         for(i=0; azArg[1][i]; i++) azArg[1][i] = ToLower(azArg[1][i]);
  3635   3668         if( strcmp(azArg[1],"sqlite_master")==0 ){
  3636   3669           char *new_argv[2], *new_colv[2];
  3637   3670           new_argv[0] = "CREATE TABLE sqlite_master (\n"
  3638   3671                         "  type text,\n"
................................................................................
  3772   3805       if( nArg!=1 ){
  3773   3806         raw_printf(stderr, "Usage: .show\n");
  3774   3807         rc = 1;
  3775   3808         goto meta_command_exit;
  3776   3809       }
  3777   3810       utf8_printf(p->out, "%12.12s: %s\n","echo", p->echoOn ? "on" : "off");
  3778   3811       utf8_printf(p->out, "%12.12s: %s\n","eqp", p->autoEQP ? "on" : "off");
  3779         -    utf8_printf(p->out,"%9.9s: %s\n","explain",p->normalMode.valid?"on":"off");
         3812  +    utf8_printf(p->out, "%12.12s: %s\n","explain",
         3813  +         p->mode==MODE_Explain ? "on" : p->autoExplain ? "auto" : "off");
  3780   3814       utf8_printf(p->out,"%12.12s: %s\n","headers", p->showHeader ? "on" : "off");
  3781   3815       utf8_printf(p->out, "%12.12s: %s\n","mode", modeDescr[p->mode]);
  3782   3816       utf8_printf(p->out, "%12.12s: ", "nullvalue");
  3783   3817         output_c_string(p->out, p->nullValue);
  3784   3818         raw_printf(p->out, "\n");
  3785   3819       utf8_printf(p->out,"%12.12s: %s\n","output",
  3786   3820               strlen30(p->outfile) ? p->outfile : "stdout");
................................................................................
  4571   4605   }
  4572   4606   
  4573   4607   /*
  4574   4608   ** Initialize the state information in data
  4575   4609   */
  4576   4610   static void main_init(ShellState *data) {
  4577   4611     memset(data, 0, sizeof(*data));
  4578         -  data->mode = MODE_List;
         4612  +  data->normalMode = data->cMode = data->mode = MODE_List;
         4613  +  data->autoExplain = 1;
  4579   4614     memcpy(data->colSeparator,SEP_Column, 2);
  4580   4615     memcpy(data->rowSeparator,SEP_Row, 2);
  4581   4616     data->showHeader = 0;
  4582   4617     data->shellFlgs = SHFLG_Lookaside;
  4583   4618     sqlite3_config(SQLITE_CONFIG_URI, 1);
  4584   4619     sqlite3_config(SQLITE_CONFIG_LOG, shellLog, data);
  4585   4620     sqlite3_config(SQLITE_CONFIG_MULTITHREAD);
................................................................................
  4904   4939           }
  4905   4940         }
  4906   4941       }else{
  4907   4942         utf8_printf(stderr,"%s: Error: unknown option: %s\n", Argv0, z);
  4908   4943         raw_printf(stderr,"Use -help for a list of options.\n");
  4909   4944         return 1;
  4910   4945       }
         4946  +    data.cMode = data.mode;
  4911   4947     }
  4912   4948   
  4913   4949     if( !readStdin ){
  4914   4950       /* Run all arguments that do not begin with '-' as if they were separate
  4915   4951       ** command-line inputs, except for the argToSkip argument which contains
  4916   4952       ** the database filename.
  4917   4953       */