From: drh Date: Tue, 2 Jan 2018 00:04:37 +0000 (+0000) Subject: The ".schema" command in the command-line shell now shows the structure of X-Git-Tag: version-3.22.0~119 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=667a2a25bad684983c4e647fdfa4acfcfab7f67d;p=thirdparty%2Fsqlite.git The ".schema" command in the command-line shell now shows the structure of table-valued functions and eponymous virtual tables if they are named on the ".schema" command line. Example: ".schema sql%" shows the structure of the "sqlite_dbstat" and "sqlite_stmt" virtual tables. FossilOrigin-Name: f80f6651df0b2843c6c9619a8f3e05c56cd50363402800a2e166e6eb664f7768 --- diff --git a/manifest b/manifest index 71d3959150..cf7032a36b 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Improved\sname\squoting\sand\sescaping\sin\sthe\sauxiliary\scolumn\sinfo\ssection\nof\sthe\s".schema"\soutput\sfor\sviews\sand\svirtual\stables. -D 2018-01-01T21:49:43.315 +C The\s".schema"\scommand\sin\sthe\scommand-line\sshell\snow\sshows\sthe\sstructure\sof\ntable-valued\sfunctions\sand\seponymous\svirtual\stables\sif\sthey\sare\snamed\son\sthe\n".schema"\scommand\sline.\s\sExample:\s\s".schema\ssql%"\sshows\sthe\sstructure\sof\nthe\s"sqlite_dbstat"\sand\s"sqlite_stmt"\svirtual\stables. +D 2018-01-02T00:04:37.286 F Makefile.in 1b11037c5ed3399a79433cc82c59b5e36a7b3a3e4e195bb27640d0d2145e03e1 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc f68b4f9b83cfeb057b6265e0288ad653f319e2ceacca731e0f22e19617829a89 @@ -479,7 +479,7 @@ F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 F src/resolve.c bbee7e31d369a18a2f4836644769882e9c5d40ef4a3af911db06410b65cb3730 F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac F src/select.c 8b22abe193e4d8243befa2038e4ae2405802fed1c446e5e502d11f652e09ba74 -F src/shell.c.in e0d3ef676265771a001446906765dd89617df2cece3249b08b1dcd24ba296f63 +F src/shell.c.in 6b1ec35f31058505650a79807c1facaec399a9a910fb317a40b9e267cb4bb312 F src/sqlite.h.in b4dc75265ed04b98e2184011a7dd0054ce2137ff84867a6be8b4f3bdfbc03d30 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h c02d628cca67f3889c689d82d25c3eb45e2c155db08e4c6089b5840d64687d34 @@ -1688,7 +1688,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 2234a87fa905312b23f46d52e06cff7cacbf23b187e16c4398a42e6bdae0ee9f -R ca3aef501320cce9e28be13c23be1622 +P d64b14e37d9624bf5d86059ddd091170d8e6d341a8043f84548b9b3dbb96a908 +R 58693511e34cddcc08538ba153bd6535 U drh -Z 2aaca99c49ba21a51639392b75414605 +Z 527d9b7c91bfab98cfe62f567d2e9f84 diff --git a/manifest.uuid b/manifest.uuid index 687c35b1d6..aed8d4df66 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -d64b14e37d9624bf5d86059ddd091170d8e6d341a8043f84548b9b3dbb96a908 \ No newline at end of file +f80f6651df0b2843c6c9619a8f3e05c56cd50363402800a2e166e6eb664f7768 \ No newline at end of file diff --git a/src/shell.c.in b/src/shell.c.in index 4861d4b506..e0e998632d 100644 --- a/src/shell.c.in +++ b/src/shell.c.in @@ -730,11 +730,10 @@ static char quoteChar(const char *zName){ } /* -** Construct a fake CREATE TABLE statement (or at least the part that comes -** after the "CREATE TABLE" keywords) that describes the columns of -** the view, virtual table, or table valued function zName in zSchema. +** Construct a fake object name and column list to describe the structure +** of the view, virtual table, or table valued function zSchema.zName. */ -static char *shellFakeCrTab( +static char *shellFakeSchema( sqlite3 *db, /* The database connection containing the vtab */ const char *zSchema, /* Schema of the database holding the vtab */ const char *zName /* The name of the virtual table */ @@ -744,6 +743,7 @@ static char *shellFakeCrTab( ShellText s; char cQuote; char *zDiv = "("; + int nRow = 0; zSql = sqlite3_mprintf("PRAGMA \"%w\".table_info=%Q;", zSchema ? zSchema : "main", zName); @@ -760,17 +760,40 @@ static char *shellFakeCrTab( appendText(&s, zName, cQuote); while( sqlite3_step(pStmt)==SQLITE_ROW ){ const char *zCol = (const char*)sqlite3_column_text(pStmt, 1); + nRow++; appendText(&s, zDiv, 0); zDiv = ","; cQuote = quoteChar(zCol); appendText(&s, zCol, cQuote); } appendText(&s, ")", 0); - sqlite3_finalize(pStmt); + if( nRow==0 ){ + freeText(&s); + s.z = 0; + } return s.z; } +/* +** SQL function: shell_module_schema(X) +** +** Return a fake schema for the table-valued function or eponymous virtual +** table X. +*/ +static void shellModuleSchema( + sqlite3_context *pCtx, + int nVal, + sqlite3_value **apVal +){ + const char *zName = (const char*)sqlite3_value_text(apVal[0]); + char *zFake = shellFakeSchema(sqlite3_context_db_handle(pCtx), 0, zName); + if( zFake ){ + sqlite3_result_text(pCtx, sqlite3_mprintf("/* %z */", zFake), + -1, sqlite3_free); + } +} + /* ** SQL function: shell_add_schema(S,X) ** @@ -806,12 +829,14 @@ static void shellAddSchemaName( int i = 0; const char *zIn = (const char*)sqlite3_value_text(apVal[0]); const char *zSchema = (const char*)sqlite3_value_text(apVal[1]); + const char *zName = (const char*)sqlite3_value_text(apVal[2]); sqlite3 *db = sqlite3_context_db_handle(pCtx); if( zIn!=0 && strncmp(zIn, "CREATE ", 7)==0 ){ for(i=0; i<(int)(sizeof(aPrefix)/sizeof(aPrefix[0])); i++){ int n = strlen30(aPrefix[i]); if( strncmp(zIn+7, aPrefix[i], n)==0 && zIn[n+7]==' ' ){ char *z = 0; + char *zFake = 0; if( zSchema ){ char cQuote = quoteChar(zSchema); if( cQuote && sqlite3_stricmp(zSchema,"temp")!=0 ){ @@ -820,11 +845,15 @@ static void shellAddSchemaName( z = sqlite3_mprintf("%.*s %s.%s", n+7, zIn, zSchema, zIn+n+8); } } - if( aPrefix[i][0]=='V' ){ - const char *zName = (const char*)sqlite3_value_text(apVal[2]); - if( z==0 ) z = sqlite3_mprintf("%s", zIn); - z = sqlite3_mprintf("%z\n/* %z */", z, - shellFakeCrTab(db, zSchema, zName)); + if( zName + && aPrefix[i][0]=='V' + && (zFake = shellFakeSchema(db, zSchema, zName))!=0 + ){ + if( z==0 ){ + z = sqlite3_mprintf("%s\n/* %z */", zIn, zFake); + }else{ + z = sqlite3_mprintf("%z\n/* %z */", z, zFake); + } } if( z ){ sqlite3_result_text(pCtx, z, -1, sqlite3_free); @@ -3052,6 +3081,8 @@ static void open_db(ShellState *p, int keepAlive){ sqlite3_completion_init(p->db, 0, 0); sqlite3_create_function(p->db, "shell_add_schema", 3, SQLITE_UTF8, 0, shellAddSchemaName, 0, 0); + sqlite3_create_function(p->db, "shell_module_schema", 1, SQLITE_UTF8, 0, + shellModuleSchema, 0, 0); } } @@ -5370,7 +5401,7 @@ static int do_meta_command(char *zLine, ShellState *p){ ShellText sSelect; ShellState data; char *zErrMsg = 0; - const char *zDiv = 0; + const char *zDiv = "("; const char *zName = 0; int iSchema = 0; int bDebug = 0; @@ -5395,9 +5426,8 @@ static int do_meta_command(char *zLine, ShellState *p){ } } if( zName!=0 ){ - if( sqlite3_stricmp(zName,"sqlite_master")==0 - || sqlite3_stricmp(zName,"sqlite_temp_master")==0 - ){ + int isMaster = sqlite3_strlike(zName, "sqlite_master", 0)==0; + if( isMaster || sqlite3_strlike(zName,"sqlite_temp_master",0)==0 ){ char *new_argv[2], *new_colv[2]; new_argv[0] = sqlite3_mprintf( "CREATE TABLE %s (\n" @@ -5406,18 +5436,13 @@ static int do_meta_command(char *zLine, ShellState *p){ " tbl_name text,\n" " rootpage integer,\n" " sql text\n" - ")", zName); + ")", isMaster ? "sqlite_master" : "sqlite_temp_master"); new_argv[1] = 0; new_colv[0] = "sql"; new_colv[1] = 0; callback(&data, 1, new_argv, new_colv); sqlite3_free(new_argv[0]); - rc = SQLITE_OK; - }else{ - zDiv = "("; } - }else if( zName==0 ){ - zDiv = "("; } if( zDiv ){ sqlite3_stmt *pStmt = 0; @@ -5452,6 +5477,11 @@ static int do_meta_command(char *zLine, ShellState *p){ appendText(&sSelect, ".sqlite_master", 0); } sqlite3_finalize(pStmt); + if( zName ){ + appendText(&sSelect, + " UNION ALL SELECT shell_module_schema(name)," + " 'table', name, name, name, 9e+99, 'main' FROM pragma_module_list", 0); + } appendText(&sSelect, ") WHERE ", 0); if( zName ){ char *zQarg = sqlite3_mprintf("%Q", zName);