/*
** These are the allowed modes.
*/
-#define MODE_Line 0 /* One column per line. Blank line between records */
-#define MODE_Column 1 /* One record per line in neat columns */
-#define MODE_List 2 /* One record per line with a separator */
-#define MODE_Semi 3 /* Same as MODE_List but append ";" to each line */
-#define MODE_Html 4 /* Generate an XHTML table */
-#define MODE_Insert 5 /* Generate SQL "insert" statements */
-#define MODE_Quote 6 /* Quote values as for SQL */
-#define MODE_Tcl 7 /* Generate ANSI-C or TCL quoted elements */
-#define MODE_Csv 8 /* Quote strings, numbers are plain */
-#define MODE_Ascii 9 /* Use ASCII unit and record separators (0x1F/0x1E) */
-#define MODE_Pretty 10 /* Pretty-print schemas */
-#define MODE_Json 11 /* Output JSON */
-#define MODE_Markdown 12 /* Markdown formatting */
-#define MODE_Table 13 /* MySQL-style table formatting */
-#define MODE_Box 14 /* Unicode box-drawing characters */
-#define MODE_Count 15 /* Output only a count of the rows of output */
-#define MODE_Off 16 /* No query output shown */
-#define MODE_Www 17 /* Full web-page output */
+#define MODE_Line 0 /* One column per line. Blank line between records */
+#define MODE_Column 1 /* One record per line in neat columns */
+#define MODE_List 2 /* One record per line with a separator */
+#define MODE_Html 3 /* Generate an XHTML table */
+#define MODE_Insert 4 /* Generate SQL "insert" statements */
+#define MODE_Quote 5 /* Quote values as for SQL */
+#define MODE_Tcl 6 /* Generate ANSI-C or TCL quoted elements */
+#define MODE_Csv 7 /* Quote strings, numbers are plain */
+#define MODE_Ascii 8 /* Use ASCII unit and record separators (0x1F/0x1E) */
+#define MODE_Json 9 /* Output JSON */
+#define MODE_Markdown 10 /* Markdown formatting */
+#define MODE_Table 11 /* MySQL-style table formatting */
+#define MODE_Box 12 /* Unicode box-drawing characters */
+#define MODE_Count 13 /* Output only a count of the rows of output */
+#define MODE_Off 14 /* No query output shown */
+#define MODE_Www 15 /* Full web-page output */
static const char *modeDescr[] = {
"line",
"column",
"list",
- "semi",
"html",
"insert",
"quote",
"tcl",
"csv",
"ascii",
- "prettyprint",
"json",
"markdown",
"table",
/* line */ QRF_STYLE_Line,
/* column */ QRF_STYLE_Column,
/* list */ QRF_STYLE_List,
- /* semi */ 101,
/* html */ QRF_STYLE_Html,
/* insert */ QRF_STYLE_Insert,
/* quote */ QRF_STYLE_Quote,
/* tcl */ QRF_STYLE_List,
/* csv */ QRF_STYLE_Csv,
/* ascii */ QRF_STYLE_List,
- /* prettyprint */ 105,
/* json */ QRF_STYLE_Json,
/* markdown */ QRF_STYLE_Markdown,
/* table */ QRF_STYLE_Table,
#endif
/*
-** Print a schema statement. Part of MODE_Semi and MODE_Pretty output.
+** Print a schema statement. This is helper routine to dump_callbac().
**
** This routine converts some CREATE TABLE statements for shadow tables
** in FTS3/4/5 into CREATE TABLE IF NOT EXISTS statements.
}
sqlite3_free(zToFree);
}
-static void printSchemaLineN(FILE *out, char *z, int n, const char *zTail){
- char c = z[n];
- z[n] = 0;
- printSchemaLine(out, z, zTail);
- z[n] = c;
-}
/*
** Return true if string z[] has nothing but whitespace and comments to the
return 1;
}
+/*
+** SQL Function: shell_format_schema(SQL,FLAGS)
+**
+** This function is internally by the CLI to assist with the
+** ".schema", ".fullschema", and ".dump" commands. The first
+** argument is the value from sqlite_schema.sql. The value returned
+** is a modification of the input that can actually be run as SQL
+** to recreate the schema object.
+**
+** When FLAGS is zero, the only changes is to append ";". If the
+** 0x01 bit of FLAGS is set, then transformations are made to implement
+** ".schema --indent".
+*/
+static void shellFormatSchema(
+ sqlite3_context *pCtx,
+ int nVal,
+ sqlite3_value **apVal
+){
+ int flags; /* Value of 2nd parameter */
+ const char *zSql; /* Value of 1st parameter */
+ int nSql; /* Bytes of text in zSql[] */
+ sqlite3_str *pOut; /* Output buffer */
+ char *z; /* Writable copy of zSql */
+ int i, j; /* Loop counters */
+ int nParen = 0;
+ char cEnd = 0;
+ char c;
+ int nLine = 0;
+ int isIndex;
+ int isWhere = 0;
+
+ assert( nVal==2 );
+ pOut = sqlite3_str_new(sqlite3_context_db_handle(pCtx));
+ nSql = sqlite3_value_bytes(apVal[0]);
+ zSql = (const char*)sqlite3_value_text(apVal[0]);
+ if( zSql==0 || zSql[0]==0 ) goto shellFormatSchema_finish;
+ flags = sqlite3_value_int(apVal[1]);
+ if( (flags & 0x01)==0 ){
+ sqlite3_str_append(pOut, zSql, nSql);
+ sqlite3_str_append(pOut, ";", 1);
+ goto shellFormatSchema_finish;
+ }
+ if( sqlite3_strlike("CREATE VIEW%", zSql, 0)==0
+ || sqlite3_strlike("CREATE TRIG%", zSql, 0)==0
+ ){
+ sqlite3_str_append(pOut, zSql, nSql);
+ sqlite3_str_append(pOut, ";", 1);
+ goto shellFormatSchema_finish;
+ }
+ isIndex = sqlite3_strlike("CREATE INDEX%", zSql, 0)==0
+ || sqlite3_strlike("CREATE UNIQUE INDEX%", zSql, 0)==0;
+ z = sqlite3_mprintf("%s", zSql);
+ if( z==0 ){
+ sqlite3_free(sqlite3_str_finish(pOut));
+ sqlite3_result_error_nomem(pCtx);
+ return;
+ }
+ j = 0;
+ for(i=0; IsSpace(z[i]); i++){}
+ for(; (c = z[i])!=0; i++){
+ if( IsSpace(c) ){
+ if( z[j-1]=='\r' ) z[j-1] = '\n';
+ if( IsSpace(z[j-1]) || z[j-1]=='(' ) continue;
+ }else if( (c=='(' || c==')') && j>0 && IsSpace(z[j-1]) ){
+ j--;
+ }
+ z[j++] = c;
+ }
+ while( j>0 && IsSpace(z[j-1]) ){ j--; }
+ z[j] = 0;
+ if( strlen30(z)>=79 ){
+ for(i=j=0; (c = z[i])!=0; i++){ /* Copy from z[i] back to z[j] */
+ if( c==cEnd ){
+ cEnd = 0;
+ }else if( c=='"' || c=='\'' || c=='`' ){
+ cEnd = c;
+ }else if( c=='[' ){
+ cEnd = ']';
+ }else if( c=='-' && z[i+1]=='-' ){
+ cEnd = '\n';
+ }else if( c=='(' ){
+ nParen++;
+ }else if( c==')' ){
+ nParen--;
+ if( nLine>0 && nParen==0 && j>0 && !isWhere ){
+ sqlite3_str_append(pOut, z, j);
+ sqlite3_str_append(pOut, "\n", 1);
+ j = 0;
+ }
+ }else if( (c=='w' || c=='W')
+ && nParen==0 && isIndex
+ && sqlite3_strnicmp("WHERE",&z[i],5)==0
+ && !IsAlnum(z[i+5]) && z[i+5]!='_' ){
+ isWhere = 1;
+ }else if( isWhere && (c=='A' || c=='a')
+ && nParen==0
+ && sqlite3_strnicmp("AND",&z[i],3)==0
+ && !IsAlnum(z[i+3]) && z[i+3]!='_' ){
+ sqlite3_str_append(pOut, z, j);
+ sqlite3_str_append(pOut, "\n ", 5);
+ j = 0;
+ }
+ z[j++] = c;
+ if( nParen==1 && cEnd==0
+ && (c=='(' || c=='\n' || (c==',' && !wsToEol(z+i+1)))
+ && !isWhere
+ ){
+ if( c=='\n' ) j--;
+ sqlite3_str_append(pOut, z, j);
+ sqlite3_str_append(pOut, "\n ", 3);
+ j = 0;
+ nLine++;
+ while( IsSpace(z[i+1]) ){ i++; }
+ }
+ }
+ z[j] = 0;
+ }
+ sqlite3_str_appendall(pOut, z);
+ sqlite3_str_append(pOut, ";", 1);
+ sqlite3_free(z);
+
+shellFormatSchema_finish:
+ sqlite3_result_text(pCtx, sqlite3_str_finish(pOut), -1, sqlite3_free);
+}
+
#ifndef SQLITE_OMIT_PROGRESS_CALLBACK
/*
** Progress handler callback.
case MODE_Count: assert(0); break;
case MODE_Off: assert(0); break;
case MODE_Line: assert(0); break;
- case MODE_Semi: { /* .schema and .fullschema output */
- printSchemaLine(p->out, azArg[0], ";\n");
- break;
- }
- case MODE_Pretty: { /* .schema and .fullschema with --indent */
- char *z;
- int j;
- int nParen = 0;
- char cEnd = 0;
- char c;
- int nLine = 0;
- int isIndex;
- int isWhere = 0;
- assert( nArg==1 );
- if( azArg[0]==0 ) break;
- if( sqlite3_strlike("CREATE VIEW%", azArg[0], 0)==0
- || sqlite3_strlike("CREATE TRIG%", azArg[0], 0)==0
- ){
- sqlite3_fprintf(p->out, "%s;\n", azArg[0]);
- break;
- }
- isIndex = sqlite3_strlike("CREATE INDEX%", azArg[0], 0)==0
- || sqlite3_strlike("CREATE UNIQUE INDEX%", azArg[0], 0)==0;
- z = sqlite3_mprintf("%s", azArg[0]);
- shell_check_oom(z);
- j = 0;
- for(i=0; IsSpace(z[i]); i++){}
- for(; (c = z[i])!=0; i++){
- if( IsSpace(c) ){
- if( z[j-1]=='\r' ) z[j-1] = '\n';
- if( IsSpace(z[j-1]) || z[j-1]=='(' ) continue;
- }else if( (c=='(' || c==')') && j>0 && IsSpace(z[j-1]) ){
- j--;
- }
- z[j++] = c;
- }
- while( j>0 && IsSpace(z[j-1]) ){ j--; }
- z[j] = 0;
- if( strlen30(z)>=79 ){
- for(i=j=0; (c = z[i])!=0; i++){ /* Copy from z[i] back to z[j] */
- if( c==cEnd ){
- cEnd = 0;
- }else if( c=='"' || c=='\'' || c=='`' ){
- cEnd = c;
- }else if( c=='[' ){
- cEnd = ']';
- }else if( c=='-' && z[i+1]=='-' ){
- cEnd = '\n';
- }else if( c=='(' ){
- nParen++;
- }else if( c==')' ){
- nParen--;
- if( nLine>0 && nParen==0 && j>0 && !isWhere ){
- printSchemaLineN(p->out, z, j, "\n");
- j = 0;
- }
- }else if( (c=='w' || c=='W')
- && nParen==0 && isIndex
- && sqlite3_strnicmp("WHERE",&z[i],5)==0
- && !IsAlnum(z[i+5]) && z[i+5]!='_' ){
- isWhere = 1;
- }else if( isWhere && (c=='A' || c=='a')
- && nParen==0
- && sqlite3_strnicmp("AND",&z[i],3)==0
- && !IsAlnum(z[i+3]) && z[i+3]!='_' ){
- printSchemaLineN(p->out, z, j, "\n ");
- j = 0;
- }
- z[j++] = c;
- if( nParen==1 && cEnd==0
- && (c=='(' || c=='\n' || (c==',' && !wsToEol(z+i+1)))
- && !isWhere
- ){
- if( c=='\n' ) j--;
- printSchemaLineN(p->out, z, j, "\n ");
- j = 0;
- nLine++;
- while( IsSpace(z[i+1]) ){ i++; }
- }
- }
- z[j] = 0;
- }
- printSchemaLine(p->out, z, ";\n");
- sqlite3_free(z);
- break;
- }
case MODE_List: assert(0); break;
case MODE_Html: assert(0); break;
case MODE_Www: {
return 0;
}
-/*
-** This is the callback routine that the SQLite library
-** invokes for each row of a query result.
-*/
-static int callback(void *pArg, int nArg, char **azArg, char **azCol){
- /* since we don't have type info, call the shell_callback with a NULL value */
- return shell_callback(pArg, nArg, azArg, azCol, NULL);
-}
-
/*
** This is the callback routine from sqlite3_exec() that appends all
** output onto the end of a ShellText object.
shellModuleSchema, 0, 0);
sqlite3_create_function(p->db, "shell_putsnl", 1, SQLITE_UTF8, p,
shellPutsFunc, 0, 0);
+ sqlite3_create_function(p->db, "shell_format_schema", 2, SQLITE_UTF8, p,
+ shellFormatSchema, 0, 0);
sqlite3_create_function(p->db, "usleep",1,SQLITE_UTF8,0,
shellUSleepFunc, 0, 0);
#ifndef SQLITE_NOHAVE_SYSTEM
if( c=='f' && cli_strncmp(azArg[0], "fullschema", n)==0 ){
ShellState data;
int doStats = 0;
+ int hasStat[5];
+ int flgs = 0;
+ char *zSql;
memcpy(&data, p, sizeof(data));
data.showHeader = 0;
- data.cMode = data.mode = MODE_Semi;
+ data.cMode = data.mode = MODE_List;
+ data.rowSeparator[0] = '\n';
+ data.rowSeparator[1] = 0;
if( nArg==2 && optionMatch(azArg[1], "indent") ){
- data.cMode = data.mode = MODE_Pretty;
nArg = 1;
}
if( nArg!=1 ){
goto meta_command_exit;
}
open_db(p, 0);
- rc = sqlite3_exec(p->db,
- "SELECT sql FROM"
+ zSql = sqlite3_mprintf(
+ "SELECT shell_format_schema(sql,%d) FROM"
" (SELECT sql sql, type type, tbl_name tbl_name, name name, rowid x"
" FROM sqlite_schema UNION ALL"
" SELECT sql, type, tbl_name, name, rowid FROM sqlite_temp_schema) "
"WHERE type!='meta' AND sql NOTNULL"
- " AND name NOT LIKE 'sqlite__%' ESCAPE '_' "
- "ORDER BY x",
- callback, &data, 0
- );
+ " AND name NOT LIKE 'sqlite__%%' ESCAPE '_' "
+ "ORDER BY x", flgs);
+ rc = shell_exec(&data,zSql,0);
+ sqlite3_free(zSql);
if( rc==SQLITE_OK ){
+ memset(hasStat, 0, sizeof(hasStat));
sqlite3_stmt *pStmt;
rc = sqlite3_prepare_v2(p->db,
- "SELECT rowid FROM sqlite_schema"
+ "SELECT substr(name,12,1) FROM sqlite_schema"
" WHERE name GLOB 'sqlite_stat[134]'",
-1, &pStmt, 0);
if( rc==SQLITE_OK ){
- doStats = sqlite3_step(pStmt)==SQLITE_ROW;
- sqlite3_finalize(pStmt);
+ while( sqlite3_step(pStmt)==SQLITE_ROW ){
+ int k = sqlite3_column_int(pStmt,0);
+ assert( k==1 || k==3 || k==4 );
+ hasStat[k] = 1;
+ doStats = 1;
+ }
}
+ sqlite3_finalize(pStmt);
}
if( doStats==0 ){
sqlite3_fputs("/* No STAT tables available */\n", p->out);
}else{
sqlite3_fputs("ANALYZE sqlite_schema;\n", p->out);
data.cMode = data.mode = MODE_Insert;
- data.zDestTable = "sqlite_stat1";
- shell_exec(&data, "SELECT * FROM sqlite_stat1", 0);
- data.zDestTable = "sqlite_stat4";
- shell_exec(&data, "SELECT * FROM sqlite_stat4", 0);
+ if( hasStat[1] ){
+ data.zDestTable = "sqlite_stat1";
+ shell_exec(&data, "SELECT * FROM sqlite_stat1", 0);
+ }
+ if( hasStat[4] ){
+ data.zDestTable = "sqlite_stat4";
+ shell_exec(&data, "SELECT * FROM sqlite_stat4", 0);
+ }
sqlite3_fputs("ANALYZE sqlite_schema;\n", p->out);
}
}else
}else
if( c=='s' && cli_strncmp(azArg[0], "schema", n)==0 ){
- ShellText sSelect;
ShellState data;
char *zErrMsg = 0;
const char *zDiv = "(";
int iSchema = 0;
int bDebug = 0;
int bNoSystemTabs = 0;
+ int bIndent = 0;
int ii;
-
+ sqlite3_str *pSql;
+ sqlite3_stmt *pStmt = 0;
+
open_db(p, 0);
memcpy(&data, p, sizeof(data));
data.showHeader = 0;
- data.cMode = data.mode = MODE_Semi;
- initText(&sSelect);
+ data.cMode = data.mode = MODE_List;
+ memcpy(data.rowSeparator,"\n",2);
for(ii=1; ii<nArg; ii++){
if( optionMatch(azArg[ii],"indent") ){
- data.cMode = data.mode = MODE_Pretty;
+ bIndent = 1;
}else if( optionMatch(azArg[ii],"debug") ){
bDebug = 1;
}else if( optionMatch(azArg[ii],"nosys") ){
|| sqlite3_strlike(zName,"sqlite_temp_master", '\\')==0
|| sqlite3_strlike(zName,"sqlite_temp_schema", '\\')==0;
if( isSchema ){
- char *new_argv[2], *new_colv[2];
- new_argv[0] = sqlite3_mprintf(
+ sqlite3_fprintf(p->out,
"CREATE TABLE %s (\n"
" type text,\n"
" name text,\n"
" tbl_name text,\n"
" rootpage integer,\n"
" sql text\n"
- ")", zName);
- shell_check_oom(new_argv[0]);
- new_argv[1] = 0;
- new_colv[0] = "sql";
- new_colv[1] = 0;
- callback(&data, 1, new_argv, new_colv);
- sqlite3_free(new_argv[0]);
+ ");\n", zName);
}
}
- if( zDiv ){
- sqlite3_stmt *pStmt = 0;
- rc = sqlite3_prepare_v2(p->db, "SELECT name FROM pragma_database_list",
- -1, &pStmt, 0);
- if( rc ){
- shellDatabaseError(p->db);
- sqlite3_finalize(pStmt);
- rc = 1;
- goto meta_command_exit;
- }
- appendText(&sSelect, "SELECT sql FROM", 0);
- iSchema = 0;
- while( sqlite3_step(pStmt)==SQLITE_ROW ){
- const char *zDb = (const char*)sqlite3_column_text(pStmt, 0);
- char zScNum[30];
- sqlite3_snprintf(sizeof(zScNum), zScNum, "%d", ++iSchema);
- appendText(&sSelect, zDiv, 0);
- zDiv = " UNION ALL ";
- appendText(&sSelect, "SELECT shell_add_schema(sql,", 0);
- if( sqlite3_stricmp(zDb, "main")!=0 ){
- appendText(&sSelect, zDb, '\'');
- }else{
- appendText(&sSelect, "NULL", 0);
- }
- appendText(&sSelect, ",name) AS sql, type, tbl_name, name, rowid,", 0);
- appendText(&sSelect, zScNum, 0);
- appendText(&sSelect, " AS snum, ", 0);
- appendText(&sSelect, zDb, '\'');
- appendText(&sSelect, " AS sname FROM ", 0);
- appendText(&sSelect, zDb, quoteChar(zDb));
- appendText(&sSelect, ".sqlite_schema", 0);
- }
+ rc = sqlite3_prepare_v2(p->db, "SELECT name FROM pragma_database_list",
+ -1, &pStmt, 0);
+ if( rc ){
+ shellDatabaseError(p->db);
sqlite3_finalize(pStmt);
-#ifndef SQLITE_OMIT_INTROSPECTION_PRAGMAS
- if( zName ){
- appendText(&sSelect,
- " UNION ALL SELECT shell_module_schema(name),"
- " 'table', name, name, name, 9e+99, 'main' FROM pragma_module_list",
- 0);
- }
-#endif
- appendText(&sSelect, ") WHERE ", 0);
- if( zName ){
- char *zQarg = sqlite3_mprintf("%Q", zName);
- int bGlob;
- shell_check_oom(zQarg);
- bGlob = strchr(zName, '*') != 0 || strchr(zName, '?') != 0 ||
- strchr(zName, '[') != 0;
- if( strchr(zName, '.') ){
- appendText(&sSelect, "lower(printf('%s.%s',sname,tbl_name))", 0);
- }else{
- appendText(&sSelect, "lower(tbl_name)", 0);
- }
- appendText(&sSelect, bGlob ? " GLOB " : " LIKE ", 0);
- appendText(&sSelect, zQarg, 0);
- if( !bGlob ){
- appendText(&sSelect, " ESCAPE '\\' ", 0);
- }
- appendText(&sSelect, " AND ", 0);
- sqlite3_free(zQarg);
+
+ rc = 1;
+ goto meta_command_exit;
+ }
+ pSql = sqlite3_str_new(p->db);
+ sqlite3_str_appendf(pSql, "SELECT sql FROM", 0);
+ iSchema = 0;
+ while( sqlite3_step(pStmt)==SQLITE_ROW ){
+ const char *zDb = (const char*)sqlite3_column_text(pStmt, 0);
+ char zScNum[30];
+ sqlite3_snprintf(sizeof(zScNum), zScNum, "%d", ++iSchema);
+ sqlite3_str_appendall(pSql, zDiv);
+ zDiv = " UNION ALL ";
+ if( sqlite3_stricmp(zDb, "main")==0 ){
+ sqlite3_str_appendf(pSql,
+ "SELECT shell_format_schema(shell_add_schema(sql,NULL,name),%d)",
+ bIndent);
+ }else{
+ sqlite3_str_appendf(pSql,
+ "SELECT shell_format_schema(shell_add_schema(sql,%Q,name),%d))",
+ zDb, bIndent);
}
- if( bNoSystemTabs ){
- appendText(&sSelect, "name NOT LIKE 'sqlite__%%' ESCAPE '_' AND ", 0);
+ sqlite3_str_appendf(pSql,
+ " AS sql, type, tbl_name, name, rowid, %d AS snum, %Q as sname",
+ ++iSchema, zDb);
+ sqlite3_str_appendf(pSql," FROM \"%w\".sqlite_schema", zDb);
+ }
+ sqlite3_finalize(pStmt);
+#ifndef SQLITE_OMIT_INTROSPECTION_PRAGMAS
+ if( zName ){
+ sqlite3_str_appendf(pSql,
+ " UNION ALL SELECT shell_module_schema(name),"
+ " 'table', name, name, name, 9e+99, 'main' FROM pragma_module_list",
+ 0);
+ }
+#endif
+ sqlite3_str_appendf(pSql, ") WHERE ", 0);
+ if( zName ){
+ int bGlob;
+ bGlob = strchr(zName, '*') != 0 || strchr(zName, '?') != 0 ||
+ strchr(zName, '[') != 0;
+ if( strchr(zName, '.') ){
+ sqlite3_str_appendf(pSql, "lower(format('%s.%s',sname,tbl_name))", 0);
+ }else{
+ sqlite3_str_appendf(pSql, "lower(tbl_name)", 0);
}
- appendText(&sSelect, "sql IS NOT NULL"
- " ORDER BY snum, rowid", 0);
- if( bDebug ){
- sqlite3_fprintf(p->out, "SQL: %s;\n", sSelect.zTxt);
+ if( bGlob ){
+ sqlite3_str_appendf(pSql, " GLOB %Q AND ", zName);
}else{
- rc = sqlite3_exec(p->db, sSelect.zTxt, callback, &data, &zErrMsg);
+ sqlite3_str_appendf(pSql, " LIKE %Q ESCAPE '\\' AND ", zName);
}
- freeText(&sSelect);
}
+ if( bNoSystemTabs ){
+ sqlite3_str_appendf(pSql, " name NOT LIKE 'sqlite__%%' ESCALE '_' AND ");
+ }
+ sqlite3_str_appendf(pSql, "sql IS NOT NULL ORDER BY snum, rowid");
+ if( bDebug ){
+ sqlite3_fprintf(p->out, "SQL: %s;\n", sqlite3_str_value(pSql));
+ }else{
+ rc = shell_exec(&data, sqlite3_str_value(pSql), &zErrMsg);
+ }
+ sqlite3_free(sqlite3_str_finish(pSql));
+
if( zErrMsg ){
shellEmitError(zErrMsg);
sqlite3_free(zErrMsg);