Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | In the output of ".schema", show the column names of virtual tables and views in a separate comment. |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA3-256: |
2234a87fa905312b23f46d52e06cff7c |
User & Date: | drh 2018-01-01 21:28:25.565 |
Context
2018-01-01
| ||
21:49 | Improved name quoting and escaping in the auxiliary column info section of the ".schema" output for views and virtual tables. (check-in: d64b14e37d user: drh tags: trunk) | |
21:28 | In the output of ".schema", show the column names of virtual tables and views in a separate comment. (check-in: 2234a87fa9 user: drh tags: trunk) | |
20:11 | Minor simplification to the ".schema" logic in the command-line shell. (check-in: add45c4728 user: drh tags: trunk) | |
Changes
Changes to src/shell.c.in.
︙ | ︙ | |||
724 725 726 727 728 729 730 731 732 733 734 735 736 737 | lwr = mid+1; }else{ upr = mid-1; } } return 0; } /* ** SQL function: shell_add_schema(S,X) ** ** Add the schema name X to the CREATE statement in S and return the result. ** Examples: ** | > > > > > > > > > > > > > > > > > > > > > > > > > > > | 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 | lwr = mid+1; }else{ upr = mid-1; } } return 0; } /* ** 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. */ static char *shellFakeCrTab( 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 */ ){ sqlite3_stmt *pStmt = 0; char *zSql; char *z = 0; zSql = sqlite3_mprintf("SELECT group_concat(name,',')" " FROM pragma_table_info(%Q,%Q);", zName, zSchema); sqlite3_prepare_v2(db, zSql, -1, &pStmt, 0); sqlite3_free(zSql); if( sqlite3_step(pStmt)==SQLITE_ROW ){ z = sqlite3_mprintf("/* %s.%s(%s) */", zSchema ? zSchema : "main", zName, sqlite3_column_text(pStmt, 0)); } sqlite3_finalize(pStmt); return z; } /* ** SQL function: shell_add_schema(S,X) ** ** Add the schema name X to the CREATE statement in S and return the result. ** Examples: ** |
︙ | ︙ | |||
760 761 762 763 764 765 766 | "VIEW", "TRIGGER", "VIRTUAL TABLE" }; int i = 0; const char *zIn = (const char*)sqlite3_value_text(apVal[0]); const char *zSchema = (const char*)sqlite3_value_text(apVal[1]); | | > > | < | | | | | > > > > > > > | | > | 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 | "VIEW", "TRIGGER", "VIRTUAL TABLE" }; int i = 0; const char *zIn = (const char*)sqlite3_value_text(apVal[0]); const char *zSchema = (const char*)sqlite3_value_text(apVal[1]); 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; if( zSchema ){ char cQuote = quoteChar(zSchema); if( cQuote && sqlite3_stricmp(zSchema,"temp")!=0 ){ z = sqlite3_mprintf("%.*s \"%w\".%s", n+7, zIn, zSchema, zIn+n+8); }else{ 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( z ){ sqlite3_result_text(pCtx, z, -1, sqlite3_free); return; } } } } sqlite3_result_value(pCtx, apVal[0]); } /* |
︙ | ︙ | |||
2994 2995 2996 2997 2998 2999 3000 | } #ifndef SQLITE_OMIT_LOAD_EXTENSION sqlite3_enable_load_extension(p->db, 1); #endif sqlite3_fileio_init(p->db, 0, 0); sqlite3_shathree_init(p->db, 0, 0); sqlite3_completion_init(p->db, 0, 0); | | | 3030 3031 3032 3033 3034 3035 3036 3037 3038 3039 3040 3041 3042 3043 3044 | } #ifndef SQLITE_OMIT_LOAD_EXTENSION sqlite3_enable_load_extension(p->db, 1); #endif sqlite3_fileio_init(p->db, 0, 0); sqlite3_shathree_init(p->db, 0, 0); sqlite3_completion_init(p->db, 0, 0); sqlite3_create_function(p->db, "shell_add_schema", 3, SQLITE_UTF8, 0, shellAddSchemaName, 0, 0); } } #if HAVE_READLINE || HAVE_EDITLINE /* ** Readline completion callbacks |
︙ | ︙ | |||
5315 5316 5317 5318 5319 5320 5321 5322 5323 5324 5325 5326 5327 5328 | }else if( c=='s' && strncmp(azArg[0], "schema", n)==0 ){ ShellText sSelect; ShellState data; char *zErrMsg = 0; const char *zDiv = 0; int iSchema = 0; open_db(p, 0); memcpy(&data, p, sizeof(data)); data.showHeader = 0; data.cMode = data.mode = MODE_Semi; initText(&sSelect); | > > > > | | | > > | > > > > | > | < < | | | | < < < < > | | > | > | | | | | | | < < < < | < | | | | > > > | > | 5351 5352 5353 5354 5355 5356 5357 5358 5359 5360 5361 5362 5363 5364 5365 5366 5367 5368 5369 5370 5371 5372 5373 5374 5375 5376 5377 5378 5379 5380 5381 5382 5383 5384 5385 5386 5387 5388 5389 5390 5391 5392 5393 5394 5395 5396 5397 5398 5399 5400 5401 5402 5403 5404 5405 5406 5407 5408 5409 5410 5411 5412 5413 5414 5415 5416 5417 5418 5419 5420 5421 5422 5423 5424 5425 5426 5427 5428 5429 5430 5431 5432 5433 5434 5435 5436 5437 5438 5439 5440 5441 5442 5443 5444 5445 5446 5447 5448 5449 5450 5451 5452 5453 5454 5455 5456 5457 5458 5459 5460 5461 5462 5463 5464 5465 | }else if( c=='s' && strncmp(azArg[0], "schema", n)==0 ){ ShellText sSelect; ShellState data; char *zErrMsg = 0; const char *zDiv = 0; const char *zName = 0; int iSchema = 0; int bDebug = 0; int ii; open_db(p, 0); memcpy(&data, p, sizeof(data)); data.showHeader = 0; data.cMode = data.mode = MODE_Semi; initText(&sSelect); for(ii=1; ii<nArg; ii++){ if( optionMatch(azArg[ii],"indent") ){ data.cMode = data.mode = MODE_Pretty; }else if( optionMatch(azArg[ii],"debug") ){ bDebug = 1; }else if( zName==0 ){ zName = azArg[ii]; }else{ raw_printf(stderr, "Usage: .schema ?--indent? ?LIKE-PATTERN?\n"); rc = 1; goto meta_command_exit; } } if( zName!=0 ){ if( sqlite3_stricmp(zName,"sqlite_master")==0 || sqlite3_stricmp(zName,"sqlite_temp_master")==0 ){ char *new_argv[2], *new_colv[2]; new_argv[0] = sqlite3_mprintf( "CREATE TABLE %s (\n" " type text,\n" " name text,\n" " tbl_name text,\n" " rootpage integer,\n" " sql text\n" ")", zName); 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; rc = sqlite3_prepare_v2(p->db, "SELECT name FROM pragma_database_list", -1, &pStmt, 0); if( rc ){ utf8_printf(stderr, "Error: %s\n", sqlite3_errmsg(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, '"'); appendText(&sSelect, ".sqlite_master", 0); } sqlite3_finalize(pStmt); appendText(&sSelect, ") WHERE ", 0); if( zName ){ char *zQarg = sqlite3_mprintf("%Q", zName); if( strchr(zName, '.') ){ appendText(&sSelect, "lower(printf('%s.%s',sname,tbl_name))", 0); }else{ appendText(&sSelect, "lower(tbl_name)", 0); } appendText(&sSelect, strchr(zName, '*') ? " GLOB " : " LIKE ", 0); appendText(&sSelect, zQarg, 0); appendText(&sSelect, " AND ", 0); sqlite3_free(zQarg); } appendText(&sSelect, "type!='meta' AND sql IS NOT NULL" " ORDER BY snum, rowid", 0); if( bDebug ){ utf8_printf(p->out, "SQL: %s;\n", sSelect.z); }else{ rc = sqlite3_exec(p->db, sSelect.z, callback, &data, &zErrMsg); } freeText(&sSelect); } if( zErrMsg ){ utf8_printf(stderr,"Error: %s\n", zErrMsg); sqlite3_free(zErrMsg); rc = 1; }else if( rc != SQLITE_OK ){ |
︙ | ︙ |
Changes to test/pragma5.test.
︙ | ︙ | |||
30 31 32 33 34 35 36 | do_execsql_test 1.0 { PRAGMA table_info(pragma_function_list) } { 0 name {} 0 {} 0 1 builtin {} 0 {} 0 } do_execsql_test 1.1 { | | | 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 | do_execsql_test 1.0 { PRAGMA table_info(pragma_function_list) } { 0 name {} 0 {} 0 1 builtin {} 0 {} 0 } do_execsql_test 1.1 { SELECT * FROM pragma_function_list WHERE name='upper' AND builtin } {upper 1} do_execsql_test 1.2 { SELECT * FROM pragma_function_list WHERE name LIKE 'exter%'; } {external 0} ifcapable fts5 { do_execsql_test 2.0 { |
︙ | ︙ |
Changes to test/shell1.test.
︙ | ︙ | |||
577 578 579 580 581 582 583 | catchcmd "test.db" { CREATE TABLE t1(x); CREATE VIEW v2 AS SELECT x+1 AS y FROM t1; CREATE VIEW v1 AS SELECT y+1 FROM v2; } catchcmd "test.db" ".schema" } {0 {CREATE TABLE t1(x); | | > | > | 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 | catchcmd "test.db" { CREATE TABLE t1(x); CREATE VIEW v2 AS SELECT x+1 AS y FROM t1; CREATE VIEW v1 AS SELECT y+1 FROM v2; } catchcmd "test.db" ".schema" } {0 {CREATE TABLE t1(x); CREATE VIEW v2 AS SELECT x+1 AS y FROM t1 /* main.v2(y) */; CREATE VIEW v1 AS SELECT y+1 FROM v2 /* main.v1(y+1) */;}} db eval {DROP VIEW v1; DROP VIEW v2; DROP TABLE t1;} } # .separator STRING Change column separator used by output and .import do_test shell1-3.22.1 { catchcmd "test.db" ".separator" } {1 {Usage: .separator COL ?ROW?}} |
︙ | ︙ |