/ Check-in [f53716ee]
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 CLI to render EXPLAIN QUERY PLAN using an ASCII-art graph. This works with ".eqp" modes and when the query begins with exactly "EXPLAIN QUERY PLAN". To see the original output format, add extra space characters in between words of the initial "EXPLAIN QUERY PLAN".
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: f53716ee2ab5a6d47a5551529aae526bb39058f4a8e11e6243b32c1ddc25a19e
User & Date: drh 2018-04-24 13:07:40
Context
2018-04-24
14:05
Do not attempt to read values from indexes-on-expressions if the index is on the RHS of a LEFT JOIN. This won't work if the index cursor points at a null-row. Fix for [7fa80496]. check-in: b8ef967a user: dan tags: trunk
13:07
Enhance the CLI to render EXPLAIN QUERY PLAN using an ASCII-art graph. This works with ".eqp" modes and when the query begins with exactly "EXPLAIN QUERY PLAN". To see the original output format, add extra space characters in between words of the initial "EXPLAIN QUERY PLAN". check-in: f53716ee user: drh tags: trunk
10:57
Fix a memory leak following failure to open an external CSV file in the csv.c extension. check-in: 526ee07d user: drh tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Show Whitespace Changes Patch

Changes to src/shell.c.in.

   431    431   /*
   432    432   ** Render output like fprintf().  This should not be used on anything that
   433    433   ** includes string formatting (e.g. "%s").
   434    434   */
   435    435   #if !defined(raw_printf)
   436    436   # define raw_printf fprintf
   437    437   #endif
          438  +
          439  +/* Indicate out-of-memory and exit. */
          440  +static void shell_out_of_memory(void){
          441  +  raw_printf(stderr,"Error: out of memory\n");
          442  +  exit(1);
          443  +}
   438    444   
   439    445   /*
   440    446   ** Write I/O traces to the following stream.
   441    447   */
   442    448   #ifdef SQLITE_ENABLE_IOTRACE
   443    449   static FILE *iotrace = 0;
   444    450   #endif
................................................................................
  1001   1007   
  1002   1008   typedef struct ExpertInfo ExpertInfo;
  1003   1009   struct ExpertInfo {
  1004   1010     sqlite3expert *pExpert;
  1005   1011     int bVerbose;
  1006   1012   };
  1007   1013   
         1014  +/* A single line in the EQP output */
         1015  +typedef struct EQPGraphRow EQPGraphRow;
         1016  +struct EQPGraphRow {
         1017  +  int iSelectId;        /* The SelectID for this row */
         1018  +  EQPGraphRow *pNext;   /* Next row in sequence */
         1019  +  char zText[1];        /* Text to display for this row */
         1020  +};
         1021  +
         1022  +/* All EQP output is collected into an instance of the following */
         1023  +typedef struct EQPGraph EQPGraph;
         1024  +struct EQPGraph {
         1025  +  EQPGraphRow *pRow;    /* Linked list of all rows of the EQP output */
         1026  +  EQPGraphRow *pLast;   /* Last element of the pRow list */
         1027  +  char zPrefix[100];    /* Graph prefix */
         1028  +};
         1029  +
  1008   1030   /*
  1009   1031   ** State information about the database connection is contained in an
  1010   1032   ** instance of the following structure.
  1011   1033   */
  1012   1034   typedef struct ShellState ShellState;
  1013   1035   struct ShellState {
  1014   1036     sqlite3 *db;           /* The database */
  1015   1037     u8 autoExplain;        /* Automatically turn on .explain mode */
  1016   1038     u8 autoEQP;            /* Run EXPLAIN QUERY PLAN prior to seach SQL stmt */
  1017   1039     u8 statsOn;            /* True to display memory stats before each finalize */
  1018   1040     u8 scanstatsOn;        /* True to display scan stats before each finalize */
  1019   1041     u8 openMode;           /* SHELL_OPEN_NORMAL, _APPENDVFS, or _ZIPFILE */
  1020   1042     u8 doXdgOpen;          /* Invoke start/open/xdg-open in output_reset() */
         1043  +  u8 nEqpLevel;          /* Depth of the EQP output graph */
         1044  +  unsigned mEqpLines;    /* Mask of veritical lines in the EQP output graph */
  1021   1045     int outCount;          /* Revert to stdout when reaching zero */
  1022   1046     int cnt;               /* Number of records displayed so far */
  1023   1047     FILE *out;             /* Write results here */
  1024   1048     FILE *traceOut;        /* Output for sqlite3_trace() */
  1025   1049     int nErr;              /* Number of errors seen */
  1026   1050     int mode;              /* An output mode setting */
  1027   1051     int modePrior;         /* Saved mode */
................................................................................
  1047   1071     char *zFreeOnClose;         /* Filename to free when closing */
  1048   1072     const char *zVfs;           /* Name of VFS to use */
  1049   1073     sqlite3_stmt *pStmt;   /* Current statement if any. */
  1050   1074     FILE *pLog;            /* Write log output here */
  1051   1075     int *aiIndent;         /* Array of indents used in MODE_Explain */
  1052   1076     int nIndent;           /* Size of array aiIndent[] */
  1053   1077     int iIndent;           /* Index of current op in aiIndent[] */
         1078  +  EQPGraph sGraph;       /* Information for the graphical EXPLAIN QUERY PLAN */
  1054   1079   #if defined(SQLITE_ENABLE_SESSION)
  1055   1080     int nSession;             /* Number of active sessions */
  1056   1081     OpenSession aSession[4];  /* Array of sessions.  [0] is in focus. */
  1057   1082   #endif
  1058   1083     ExpertInfo expert;        /* Valid if previous command was ".expert OPT..." */
  1059   1084   };
  1060   1085   
................................................................................
  1103   1128   #define MODE_Insert   5  /* Generate SQL "insert" statements */
  1104   1129   #define MODE_Quote    6  /* Quote values as for SQL */
  1105   1130   #define MODE_Tcl      7  /* Generate ANSI-C or TCL quoted elements */
  1106   1131   #define MODE_Csv      8  /* Quote strings, numbers are plain */
  1107   1132   #define MODE_Explain  9  /* Like MODE_Column, but do not truncate data */
  1108   1133   #define MODE_Ascii   10  /* Use ASCII unit and record separators (0x1F/0x1E) */
  1109   1134   #define MODE_Pretty  11  /* Pretty-print schemas */
         1135  +#define MODE_EQP     12  /* Converts EXPLAIN QUERY PLAN output into a graph */
  1110   1136   
  1111   1137   static const char *modeDescr[] = {
  1112   1138     "line",
  1113   1139     "column",
  1114   1140     "list",
  1115   1141     "semi",
  1116   1142     "html",
................................................................................
  1117   1143     "insert",
  1118   1144     "quote",
  1119   1145     "tcl",
  1120   1146     "csv",
  1121   1147     "explain",
  1122   1148     "ascii",
  1123   1149     "prettyprint",
         1150  +  "eqp"
  1124   1151   };
  1125   1152   
  1126   1153   /*
  1127   1154   ** These are the column/row/line separators used by the various
  1128   1155   ** import/export modes.
  1129   1156   */
  1130   1157   #define SEP_Column    "|"
................................................................................
  1666   1693       if( IsSpace(z[i]) ) continue;
  1667   1694       if( z[i]=='-' && z[i+1]=='-' ) return 1;
  1668   1695       return 0;
  1669   1696     }
  1670   1697     return 1;
  1671   1698   }
  1672   1699       
         1700  +/*
         1701  +** Add a new entry to the EXPLAIN QUERY PLAN data
         1702  +*/
         1703  +static void eqp_append(ShellState *p, int iSelectId, const char *zText){
         1704  +  EQPGraphRow *pNew;
         1705  +  int nText = strlen30(zText);
         1706  +  pNew = sqlite3_malloc64( sizeof(*pNew) + nText );
         1707  +  if( pNew==0 ) shell_out_of_memory();
         1708  +  pNew->iSelectId = iSelectId;
         1709  +  memcpy(pNew->zText, zText, nText+1);
         1710  +  pNew->pNext = 0;
         1711  +  if( p->sGraph.pLast ){
         1712  +    p->sGraph.pLast->pNext = pNew;
         1713  +  }else{
         1714  +    p->sGraph.pRow = pNew;
         1715  +  }
         1716  +  p->sGraph.pLast = pNew;
         1717  +}
         1718  +
         1719  +/*
         1720  +** Free and reset the EXPLAIN QUERY PLAN data that has been collected
         1721  +** in p->sGraph.
         1722  +*/
         1723  +static void eqp_reset(ShellState *p){
         1724  +  EQPGraphRow *pRow, *pNext;
         1725  +  for(pRow = p->sGraph.pRow; pRow; pRow = pNext){
         1726  +    pNext = pRow->pNext;
         1727  +    sqlite3_free(pRow);
         1728  +  }
         1729  +  memset(&p->sGraph, 0, sizeof(p->sGraph));
         1730  +}
         1731  +
         1732  +/* Return the next EXPLAIN QUERY PLAN line with iSelectId that occurs after
         1733  +** pOld, or return the first such line if pOld is NULL
         1734  +*/
         1735  +static EQPGraphRow *eqp_next_row(ShellState *p, int iSelectId, EQPGraphRow *pOld){
         1736  +  EQPGraphRow *pRow = pOld ? pOld->pNext : p->sGraph.pRow;
         1737  +  while( pRow && pRow->iSelectId!=iSelectId ) pRow = pRow->pNext;
         1738  +  return pRow;
         1739  +}
         1740  +
         1741  +/* Render a single level of the graph shell having iSelectId.  Called
         1742  +** recursively to render sublevels.
         1743  +*/
         1744  +static void eqp_render_level(ShellState *p, int iSelectId){
         1745  +  EQPGraphRow *pRow, *pNext;
         1746  +  int i;
         1747  +  int n = strlen30(p->sGraph.zPrefix);
         1748  +  char *z;
         1749  +  for(pRow = eqp_next_row(p, iSelectId, 0); pRow; pRow = pNext){
         1750  +    pNext = eqp_next_row(p, iSelectId, pRow);
         1751  +    z = pRow->zText;
         1752  +    utf8_printf(p->out, "%s%s%s\n", p->sGraph.zPrefix, pNext ? "|--" : "`--", z);
         1753  +    if( n<sizeof(p->sGraph.zPrefix)-7 && (z = strstr(z, " SUBQUER"))!=0 ){
         1754  +      memcpy(&p->sGraph.zPrefix[n], pNext ? "|  " : "   ", 4);
         1755  +      if( strncmp(z, " SUBQUERY ", 9)==0 && (i = atoi(z+10))>iSelectId ){
         1756  +        eqp_render_level(p, i);
         1757  +      }else if( strncmp(z, " SUBQUERIES ", 12)==0 ){
         1758  +        i = atoi(z+12);
         1759  +        if( i>iSelectId ){
         1760  +          utf8_printf(p->out, "%s|--SUBQUERY %d\n", p->sGraph.zPrefix, i);
         1761  +          memcpy(&p->sGraph.zPrefix[n+3],"|  ",4);
         1762  +          eqp_render_level(p, i);
         1763  +        }
         1764  +        z = strstr(z, " AND ");
         1765  +        if( z && (i = atoi(z+5))>iSelectId ){
         1766  +          p->sGraph.zPrefix[n+3] = 0;
         1767  +          utf8_printf(p->out, "%s`--SUBQUERY %d\n", p->sGraph.zPrefix, i);
         1768  +          memcpy(&p->sGraph.zPrefix[n+3],"   ",4);
         1769  +          eqp_render_level(p, i);
         1770  +        }
         1771  +      }
         1772  +      p->sGraph.zPrefix[n] = 0;
         1773  +    }
         1774  +  }
         1775  +}
         1776  +
         1777  +/*
         1778  +** Display and reset the EXPLAIN QUERY PLAN data
         1779  +*/
         1780  +static void eqp_render(ShellState *p){
         1781  +  EQPGraphRow *pRow = p->sGraph.pRow;
         1782  +  if( pRow ){
         1783  +    if( pRow->zText[0]=='-' ){
         1784  +      if( pRow->pNext==0 ){
         1785  +        eqp_reset(p);
         1786  +        return;
         1787  +      }
         1788  +      utf8_printf(p->out, "%s\n", pRow->zText+3);
         1789  +      p->sGraph.pRow = pRow->pNext;
         1790  +      sqlite3_free(pRow);
         1791  +    }else{
         1792  +      utf8_printf(p->out, "QUERY PLAN\n");
         1793  +    }
         1794  +    p->sGraph.zPrefix[0] = 0;
         1795  +    eqp_render_level(p, 0);
         1796  +    eqp_reset(p);
         1797  +  }
         1798  +}
  1673   1799   
  1674   1800   /*
  1675   1801   ** This is the callback routine that the shell
  1676   1802   ** invokes for each row of a query result.
  1677   1803   */
  1678   1804   static int shell_callback(
  1679   1805     void *pArg,
................................................................................
  2016   2142         for(i=0; i<nArg; i++){
  2017   2143           if( i>0 ) utf8_printf(p->out, "%s", p->colSeparator);
  2018   2144           utf8_printf(p->out,"%s",azArg[i] ? azArg[i] : p->nullValue);
  2019   2145         }
  2020   2146         utf8_printf(p->out, "%s", p->rowSeparator);
  2021   2147         break;
  2022   2148       }
         2149  +    case MODE_EQP: {
         2150  +      eqp_append(p, atoi(azArg[0]), azArg[3]);
         2151  +      break;
         2152  +    }
  2023   2153     }
  2024   2154     return 0;
  2025   2155   }
  2026   2156   
  2027   2157   /*
  2028   2158   ** This is the callback routine that the SQLite library
  2029   2159   ** invokes for each row of a query result.
................................................................................
  2114   2244       p->zDestTable = 0;
  2115   2245     }
  2116   2246     if( zName==0 ) return;
  2117   2247     cQuote = quoteChar(zName);
  2118   2248     n = strlen30(zName);
  2119   2249     if( cQuote ) n += n+2;
  2120   2250     z = p->zDestTable = malloc( n+1 );
  2121         -  if( z==0 ){
  2122         -    raw_printf(stderr,"Error: out of memory\n");
  2123         -    exit(1);
  2124         -  }
         2251  +  if( z==0 ) shell_out_of_memory();
  2125   2252     n = 0;
  2126   2253     if( cQuote ) z[n++] = cQuote;
  2127   2254     for(i=0; zName[i]; i++){
  2128   2255       z[n++] = zName[i];
  2129   2256       if( zName[i]==cQuote ) z[n++] = cQuote;
  2130   2257     }
  2131   2258     if( cQuote ) z[n++] = cQuote;
................................................................................
  2857   2984           if( pArg->autoEQP>=AUTOEQP_trigger ){
  2858   2985             sqlite3_db_config(db, SQLITE_DBCONFIG_TRIGGER_EQP, 1, 0);
  2859   2986           }
  2860   2987           zEQP = sqlite3_mprintf("EXPLAIN QUERY PLAN %s", zStmtSql);
  2861   2988           rc = sqlite3_prepare_v2(db, zEQP, -1, &pExplain, 0);
  2862   2989           if( rc==SQLITE_OK ){
  2863   2990             while( sqlite3_step(pExplain)==SQLITE_ROW ){
  2864         -            raw_printf(pArg->out,"--EQP-- %d,",sqlite3_column_int(pExplain, 0));
  2865         -            raw_printf(pArg->out,"%d,", sqlite3_column_int(pExplain, 1));
  2866         -            raw_printf(pArg->out,"%d,", sqlite3_column_int(pExplain, 2));
  2867         -            utf8_printf(pArg->out,"%s\n", sqlite3_column_text(pExplain, 3));
         2991  +            const char *zEQPLine = (const char*)sqlite3_column_text(pExplain,3);
         2992  +            int iSelectId = sqlite3_column_int(pExplain, 0);
         2993  +            if( zEQPLine[0]=='-' ) eqp_render(pArg);
         2994  +            eqp_append(pArg, iSelectId, zEQPLine);
  2868   2995             }
         2996  +          eqp_render(pArg);
  2869   2997           }
  2870   2998           sqlite3_finalize(pExplain);
  2871   2999           sqlite3_free(zEQP);
  2872   3000           if( pArg->autoEQP>=AUTOEQP_full ){
  2873   3001             /* Also do an EXPLAIN for ".eqp full" mode */
  2874   3002             zEQP = sqlite3_mprintf("EXPLAIN %s", zStmtSql);
  2875   3003             rc = sqlite3_prepare_v2(db, zEQP, -1, &pExplain, 0);
................................................................................
  2889   3017             sqlite3_prepare_v2(db, zSql, -1, &pStmt, 0);
  2890   3018           }
  2891   3019           restore_debug_trace_modes();
  2892   3020         }
  2893   3021   
  2894   3022         if( pArg ){
  2895   3023           pArg->cMode = pArg->mode;
  2896         -        if( pArg->autoExplain
  2897         -         && sqlite3_column_count(pStmt)==8
         3024  +        if( pArg->autoExplain ){
         3025  +          if( sqlite3_column_count(pStmt)==8
  2898   3026            && sqlite3_strlike("EXPLAIN%", zStmtSql,0)==0
  2899   3027           ){
  2900   3028             pArg->cMode = MODE_Explain;
         3029  +          }
         3030  +          if( sqlite3_column_count(pStmt)==4
         3031  +           && sqlite3_strlike("EXPLAIN QUERY PLAN%", zStmtSql,0)==0 ){
         3032  +            pArg->cMode = MODE_EQP;
         3033  +          }
  2901   3034           }
  2902   3035   
  2903   3036           /* If the shell is currently in ".explain" mode, gather the extra
  2904   3037           ** data required to add indents to the output.*/
  2905   3038           if( pArg->cMode==MODE_Explain ){
  2906   3039             explain_data_prepare(pArg, pStmt);
  2907   3040           }
  2908   3041         }
  2909   3042   
  2910   3043         exec_prepared_stmt(pArg, pStmt);
  2911   3044         explain_data_delete(pArg);
         3045  +      eqp_render(pArg);
  2912   3046   
  2913   3047         /* print usage stats if stats on */
  2914   3048         if( pArg && pArg->statsOn ){
  2915   3049           display_stats(db, pArg, 0);
  2916   3050         }
  2917   3051   
  2918   3052         /* print loop-counters if required */
................................................................................
  2982   3116     rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
  2983   3117     sqlite3_free(zSql);
  2984   3118     if( rc ) return 0;
  2985   3119     while( sqlite3_step(pStmt)==SQLITE_ROW ){
  2986   3120       if( nCol>=nAlloc-2 ){
  2987   3121         nAlloc = nAlloc*2 + nCol + 10;
  2988   3122         azCol = sqlite3_realloc(azCol, nAlloc*sizeof(azCol[0]));
  2989         -      if( azCol==0 ){
  2990         -        raw_printf(stderr, "Error: out of memory\n");
  2991         -        exit(1);
  2992         -      }
         3123  +      if( azCol==0 ) shell_out_of_memory();
  2993   3124       }
  2994   3125       azCol[++nCol] = sqlite3_mprintf("%s", sqlite3_column_text(pStmt, 1));
  2995   3126       if( sqlite3_column_int(pStmt, 5) ){
  2996   3127         nPK++;
  2997   3128         if( nPK==1
  2998   3129          && sqlite3_stricmp((const char*)sqlite3_column_text(pStmt,2),
  2999   3130                             "INTEGER")==0
................................................................................
  3782   3913   };
  3783   3914   
  3784   3915   /* Append a single byte to z[] */
  3785   3916   static void import_append_char(ImportCtx *p, int c){
  3786   3917     if( p->n+1>=p->nAlloc ){
  3787   3918       p->nAlloc += p->nAlloc + 100;
  3788   3919       p->z = sqlite3_realloc64(p->z, p->nAlloc);
  3789         -    if( p->z==0 ){
  3790         -      raw_printf(stderr, "out of memory\n");
  3791         -      exit(1);
  3792         -    }
         3920  +    if( p->z==0 ) shell_out_of_memory();
  3793   3921     }
  3794   3922     p->z[p->n++] = (char)c;
  3795   3923   }
  3796   3924   
  3797   3925   /* Read a single field of CSV text.  Compatible with rfc4180 and extended
  3798   3926   ** with the option of having a separator other than ",".
  3799   3927   **
................................................................................
  3946   4074       utf8_printf(stderr, "Error %d: %s on [%s]\n",
  3947   4075               sqlite3_extended_errcode(p->db), sqlite3_errmsg(p->db),
  3948   4076               zQuery);
  3949   4077       goto end_data_xfer;
  3950   4078     }
  3951   4079     n = sqlite3_column_count(pQuery);
  3952   4080     zInsert = sqlite3_malloc64(200 + nTable + n*3);
  3953         -  if( zInsert==0 ){
  3954         -    raw_printf(stderr, "out of memory\n");
  3955         -    goto end_data_xfer;
  3956         -  }
         4081  +  if( zInsert==0 ) shell_out_of_memory();
  3957   4082     sqlite3_snprintf(200+nTable,zInsert,
  3958   4083                      "INSERT OR IGNORE INTO \"%s\" VALUES(?", zTable);
  3959   4084     i = strlen30(zInsert);
  3960   4085     for(j=1; j<n; j++){
  3961   4086       memcpy(zInsert+i, ",?", 2);
  3962   4087       i += 2;
  3963   4088     }
................................................................................
  4290   4415   */
  4291   4416   static int shellDatabaseError(sqlite3 *db){
  4292   4417     const char *zErr = sqlite3_errmsg(db);
  4293   4418     utf8_printf(stderr, "Error: %s\n", zErr);
  4294   4419     return 1;
  4295   4420   }
  4296   4421   
  4297         -/*
  4298         -** Print an out-of-memory message to stderr and return 1.
  4299         -*/
  4300         -static int shellNomemError(void){
  4301         -  raw_printf(stderr, "Error: out of memory\n");
  4302         -  return 1;
  4303         -}
  4304         -
  4305   4422   /*
  4306   4423   ** Compare the pattern in zGlob[] against the text in z[].  Return TRUE
  4307   4424   ** if they match and FALSE (0) if they do not match.
  4308   4425   **
  4309   4426   ** Globbing rules:
  4310   4427   **
  4311   4428   **      '*'       Matches any sequence of zero or more characters.
................................................................................
  5991   6108         utf8_printf(stderr, "Error: cannot open \"%s\"\n", zFile);
  5992   6109         return 1;
  5993   6110       }
  5994   6111       sCtx.cColSep = p->colSeparator[0];
  5995   6112       sCtx.cRowSep = p->rowSeparator[0];
  5996   6113       zSql = sqlite3_mprintf("SELECT * FROM %s", zTable);
  5997   6114       if( zSql==0 ){
  5998         -      raw_printf(stderr, "Error: out of memory\n");
  5999   6115         xCloser(sCtx.in);
  6000         -      return 1;
         6116  +      shell_out_of_memory();
  6001   6117       }
  6002   6118       nByte = strlen30(zSql);
  6003   6119       rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
  6004   6120       import_append_char(&sCtx, 0);    /* To ensure sCtx.z is allocated */
  6005   6121       if( rc && sqlite3_strglob("no such table: *", sqlite3_errmsg(p->db))==0 ){
  6006   6122         char *zCreate = sqlite3_mprintf("CREATE TABLE %s", zTable);
  6007   6123         char cSep = '(';
................................................................................
  6038   6154       }
  6039   6155       nCol = sqlite3_column_count(pStmt);
  6040   6156       sqlite3_finalize(pStmt);
  6041   6157       pStmt = 0;
  6042   6158       if( nCol==0 ) return 0; /* no columns, no error */
  6043   6159       zSql = sqlite3_malloc64( nByte*2 + 20 + nCol*2 );
  6044   6160       if( zSql==0 ){
  6045         -      raw_printf(stderr, "Error: out of memory\n");
  6046   6161         xCloser(sCtx.in);
  6047         -      return 1;
         6162  +      shell_out_of_memory();
  6048   6163       }
  6049   6164       sqlite3_snprintf(nByte+20, zSql, "INSERT INTO \"%w\" VALUES(?", zTable);
  6050   6165       j = strlen30(zSql);
  6051   6166       for(i=1; i<nCol; i++){
  6052   6167         zSql[j++] = ',';
  6053   6168         zSql[j++] = '?';
  6054   6169       }
................................................................................
  7311   7426         sqlite3_bind_text(pStmt, 1, "%", -1, SQLITE_STATIC);
  7312   7427       }
  7313   7428       while( sqlite3_step(pStmt)==SQLITE_ROW ){
  7314   7429         if( nRow>=nAlloc ){
  7315   7430           char **azNew;
  7316   7431           int n2 = nAlloc*2 + 10;
  7317   7432           azNew = sqlite3_realloc64(azResult, sizeof(azResult[0])*n2);
  7318         -        if( azNew==0 ){
  7319         -          rc = shellNomemError();
  7320         -          break;
  7321         -        }
         7433  +        if( azNew==0 ) shell_out_of_memory();
  7322   7434           nAlloc = n2;
  7323   7435           azResult = azNew;
  7324   7436         }
  7325   7437         azResult[nRow] = sqlite3_mprintf("%s", sqlite3_column_text(pStmt, 0));
  7326         -      if( 0==azResult[nRow] ){
  7327         -        rc = shellNomemError();
  7328         -        break;
  7329         -      }
         7438  +      if( 0==azResult[nRow] ) shell_out_of_memory();
  7330   7439         nRow++;
  7331   7440       }
  7332   7441       if( sqlite3_finalize(pStmt)!=SQLITE_OK ){
  7333   7442         rc = shellDatabaseError(p->db);
  7334   7443       }
  7335   7444   
  7336   7445       /* Pretty-print the contents of array azResult[] to the output */
................................................................................
  7893   8002       if( line_is_command_terminator(zLine) && line_is_complete(zSql, nSql) ){
  7894   8003         memcpy(zLine,";",2);
  7895   8004       }
  7896   8005       nLine = strlen30(zLine);
  7897   8006       if( nSql+nLine+2>=nAlloc ){
  7898   8007         nAlloc = nSql+nLine+100;
  7899   8008         zSql = realloc(zSql, nAlloc);
  7900         -      if( zSql==0 ){
  7901         -        raw_printf(stderr, "Error: out of memory\n");
  7902         -        exit(1);
  7903         -      }
         8009  +      if( zSql==0 ) shell_out_of_memory();
  7904   8010       }
  7905   8011       nSqlPrior = nSql;
  7906   8012       if( nSql==0 ){
  7907   8013         int i;
  7908   8014         for(i=0; zLine[i] && IsSpace(zLine[i]); i++){}
  7909   8015         assert( nAlloc>0 && zSql!=0 );
  7910   8016         memcpy(zSql, zLine+i, nLine+1-i);
................................................................................
  8212   8318     ** do this.  But we want to run an sqlite3_shutdown() afterwards so that
  8213   8319     ** subsequent sqlite3_config() calls will work.  So copy all results into
  8214   8320     ** memory that does not come from the SQLite memory allocator.
  8215   8321     */
  8216   8322   #if !SQLITE_SHELL_IS_UTF8
  8217   8323     sqlite3_initialize();
  8218   8324     argv = malloc(sizeof(argv[0])*argc);
  8219         -  if( argv==0 ){
  8220         -    raw_printf(stderr, "out of memory\n");
  8221         -    exit(1);
  8222         -  }
         8325  +  if( argv==0 ) shell_out_of_memory();
  8223   8326     for(i=0; i<argc; i++){
  8224   8327       char *z = sqlite3_win32_unicode_to_utf8(wargv[i]);
  8225   8328       int n;
  8226         -    if( z==0 ){
  8227         -      raw_printf(stderr, "out of memory\n");
  8228         -      exit(1);
  8229         -    }
         8329  +    if( z==0 ) shell_out_of_memory();
  8230   8330       n = (int)strlen(z);
  8231   8331       argv[i] = malloc( n+1 );
  8232         -    if( argv[i]==0 ){
  8233         -      raw_printf(stderr, "out of memory\n");
  8234         -      exit(1);
  8235         -    }
         8332  +    if( argv[i]==0 ) shell_out_of_memory();
  8236   8333       memcpy(argv[i], z, n+1);
  8237   8334       sqlite3_free(z);
  8238   8335     }
  8239   8336     sqlite3_shutdown();
  8240   8337   #endif
  8241   8338   
  8242   8339     assert( argc>=1 && argv && argv[0] );
................................................................................
  8277   8374           data.zDbFilename = z;
  8278   8375         }else{
  8279   8376           /* Excesss arguments are interpreted as SQL (or dot-commands) and
  8280   8377           ** mean that nothing is read from stdin */
  8281   8378           readStdin = 0;
  8282   8379           nCmd++;
  8283   8380           azCmd = realloc(azCmd, sizeof(azCmd[0])*nCmd);
  8284         -        if( azCmd==0 ){
  8285         -          raw_printf(stderr, "out of memory\n");
  8286         -          exit(1);
  8287         -        }
         8381  +        if( azCmd==0 ) shell_out_of_memory();
  8288   8382           azCmd[nCmd-1] = z;
  8289   8383         }
  8290   8384       }
  8291   8385       if( z[1]=='-' ) z++;
  8292   8386       if( strcmp(z,"-separator")==0
  8293   8387        || strcmp(z,"-nullvalue")==0
  8294   8388        || strcmp(z,"-newline")==0

Changes to src/vdbeaux.c.

  1641   1641   ** running the code, it invokes the callback once for each instruction.
  1642   1642   ** This feature is used to implement "EXPLAIN".
  1643   1643   **
  1644   1644   ** When p->explain==1, each instruction is listed.  When
  1645   1645   ** p->explain==2, only OP_Explain instructions are listed and these
  1646   1646   ** are shown in a different format.  p->explain==2 is used to implement
  1647   1647   ** EXPLAIN QUERY PLAN.
         1648  +** 2018-04-24:  In p->explain==2 mode, the OP_Init opcodes of triggers
         1649  +** are also shown, so that the boundaries between the main program and
         1650  +** each trigger are clear.
  1648   1651   **
  1649   1652   ** When p->explain==1, first the main program is listed, then each of
  1650   1653   ** the trigger subprograms are listed one by one.
  1651   1654   */
  1652   1655   int sqlite3VdbeList(
  1653   1656     Vdbe *p                   /* The VDBE */
  1654   1657   ){
................................................................................
  1703   1706         apSub = (SubProgram **)pSub->z;
  1704   1707       }
  1705   1708       for(i=0; i<nSub; i++){
  1706   1709         nRow += apSub[i]->nOp;
  1707   1710       }
  1708   1711     }
  1709   1712   
  1710         -  do{
         1713  +  while(1){  /* Loop exits via break */
  1711   1714       i = p->pc++;
  1712   1715       if( i>=nRow ){
  1713   1716         p->rc = SQLITE_OK;
  1714   1717         rc = SQLITE_DONE;
  1715   1718         break;
  1716   1719       }
  1717   1720       if( i<p->nOp ){
................................................................................
  1749   1752           apSub = (SubProgram **)pSub->z;
  1750   1753           apSub[nSub++] = pOp->p4.pProgram;
  1751   1754           pSub->flags |= MEM_Blob;
  1752   1755           pSub->n = nSub*sizeof(SubProgram*);
  1753   1756           nRow += pOp->p4.pProgram->nOp;
  1754   1757         }
  1755   1758       }
  1756         -  }while( p->explain==2 && pOp->opcode!=OP_Explain );
         1759  +    if( p->explain<2 ) break;
         1760  +    if( pOp->opcode==OP_Explain ) break;
         1761  +    if( pOp->opcode==OP_Init && p->pc>1 ) break;
         1762  +  }
  1757   1763   
  1758   1764     if( rc==SQLITE_OK ){
  1759   1765       if( db->u1.isInterrupted ){
  1760   1766         p->rc = SQLITE_INTERRUPT;
  1761   1767         rc = SQLITE_ERROR;
  1762   1768         sqlite3VdbeError(p, sqlite3ErrStr(p->rc));
  1763   1769       }else{