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
This commit is contained in:
+50
-20
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user