From 6ff5ebd39a5bda3c2b398ac0b0062bd629f3c877 Mon Sep 17 00:00:00 2001 From: Corey Huinker Date: Fri, 8 Mar 2019 23:38:10 +0000 Subject: [PATCH] Add describe commands to compliment d commands --- doc/src/sgml/ref/psql-ref.sgml | 175 ++++++++++++++++++-------- src/bin/psql/command.c | 190 +++++++++++++++++++++++----- src/bin/psql/command.h | 1 - src/bin/psql/describe.c | 39 ++++++ src/bin/psql/describe.h | 15 ++- src/bin/psql/tab-complete.c | 222 ++++++++++++++++++++++++--------- 6 files changed, 505 insertions(+), 137 deletions(-) diff --git a/doc/src/sgml/ref/psql-ref.sgml b/doc/src/sgml/ref/psql-ref.sgml index d7539ae743..afdc212cd5 100644 --- a/doc/src/sgml/ref/psql-ref.sgml +++ b/doc/src/sgml/ref/psql-ref.sgml @@ -871,6 +871,17 @@ testdb=> same line. + + The family of meta-commands starting with \d often + have an equivalent \describe- "long form" command. + The long-form commands often have the suffixes -system + and -verbose which are the equivalent of the + short form suffixes S and + + respectively. The long form suffixes cannot be used on the short form + variants. Every \describe variant has an equivalent + short form variant. + + The following meta-commands are defined: @@ -1147,6 +1158,7 @@ testdb=> \d[S+] [ pattern ] + \describe[-system][-verbose] [ pattern ] @@ -1165,13 +1177,13 @@ testdb=> - For some types of relation, \d shows additional information + For some types of relation, \d (and \describe shows additional information for each column: column values for sequences, indexed expressions for indexes, and foreign data wrapper options for foreign tables. - The command form \d+ is identical, except that + The command forms \d+ and \describe-verbose are identical to \d, except that more information is displayed: any comments associated with the columns of the table are shown, as is the presence of OIDs in the table, the view definition if the relation is a view, a non-default @@ -1181,13 +1193,13 @@ testdb=> By default, only user-created objects are shown; supply a - pattern or the S modifier to include system + pattern or the S modifier for \d or -verbose modifier for \describe modifier to include system objects. - If \d is used without a + If \d / \describe is used without a pattern argument, it is equivalent to \dtvmsE which will show a list of all visible tables, views, materialized views, sequences and @@ -1200,6 +1212,7 @@ testdb=> \da[S] [ pattern ] + \describe-aggregate[-system] [ pattern ] @@ -1208,7 +1221,7 @@ testdb=> class="parameter">pattern is specified, only aggregates whose names match the pattern are shown. By default, only user-created objects are shown; supply a - pattern or the S modifier to include system + pattern or the S/-system modifier to include system objects. @@ -1216,13 +1229,14 @@ testdb=> \dA[+] [ pattern ] + \describe-access-method[-verbose] [ pattern ] Lists access methods. If pattern is specified, only access methods whose names match the pattern are shown. If - + is appended to the command name, each access + +/-verbose is appended to the command name, each access method is listed with its associated handler function and description. @@ -1230,13 +1244,14 @@ testdb=> \db[+] [ pattern ] + \describe-tablespace[-verbose] [ pattern ] Lists tablespaces. If pattern is specified, only tablespaces whose names match the pattern are shown. - If + is appended to the command name, each tablespace + If +/-verbose is appended to the command name, each tablespace is listed with its associated options, on-disk size, permissions and description. @@ -1246,6 +1261,7 @@ testdb=> \dc[S+] [ pattern ] + \describe-conversion[-system][-verbose] [ pattern ] Lists conversions between character-set encodings. @@ -1253,9 +1269,9 @@ testdb=> is specified, only conversions whose names match the pattern are listed. By default, only user-created objects are shown; supply a - pattern or the S modifier to include system + pattern or the S/-system modifier to include system objects. - If + is appended to the command name, each object + If +/-verbose is appended to the command name, each object is listed with its associated description. @@ -1264,13 +1280,14 @@ testdb=> \dC[+] [ pattern ] + \describe-cast[-verbose] [ pattern ] Lists type casts. If pattern is specified, only casts whose source or target types match the pattern are listed. - If + is appended to the command name, each object + If +/-verbose is appended to the command name, each object is listed with its associated description. @@ -1279,6 +1296,11 @@ testdb=> \dd[S] [ pattern ] + \describe-constraint[-system] [ pattern ] + \describe-operator-class[-system] [ pattern ] + \describe-operator-family[-system] [ pattern ] + \describe-rule[-system] [ pattern ] + \describe-trigger[-system] [ pattern ] Shows the descriptions of objects of type constraint, @@ -1293,7 +1315,7 @@ testdb=> objects of the appropriate type if no argument is given. But in either case, only objects that have a description are listed. By default, only user-created objects are shown; supply a - pattern or the S modifier to include system + pattern or the S/-system modifier to include system objects. @@ -1308,15 +1330,16 @@ testdb=> \dD[S+] [ pattern ] + \describe-domain[-system][-verbose] [ pattern ] Lists domains. If pattern is specified, only domains whose names match the pattern are shown. By default, only user-created objects are shown; supply a - pattern or the S modifier to include system + pattern or the S/-system modifier to include system objects. - If + is appended to the command name, each object + If +/-verbose is appended to the command name, each object is listed with its associated permissions and description. @@ -1325,6 +1348,7 @@ testdb=> \ddp [ pattern ] + \describe-default-access-privelege [ pattern ] Lists default access privilege settings. An entry is shown for @@ -1352,6 +1376,11 @@ testdb=> \ds[S+] [ pattern ] \dt[S+] [ pattern ] \dv[S+] [ pattern ] + \describe-index[-system][-verbose] [ pattern ] + \describe-materialized-view[-system][-verbose] [ pattern ] + \describe-sequence[-system][-verbose] [ pattern ] + \describe-table[-system][-verbose] [ pattern ] + \describe-view[-system][-verbose] [ pattern ] @@ -1360,16 +1389,22 @@ testdb=> t, and v stand for foreign table, index, materialized view, sequence, table, and view, respectively. - You can specify any or all of + In the short forms, you can specify any or all of these letters, in any order, to obtain a listing of objects of these types. For example, \dit lists indexes - and tables. If + is + and tables. If +/-verbose is appended to the command name, each object is listed with its physical size on disk and its associated description, if any. + \describe-foreign-table is equivalent to \dE. + \describe-index is equivalent to \di. + \describe-materialized-view is equivalent to \dm. + \describe-sequence is equivalent to \ds. + \describe-table is equivalent to \dt. + \describe-view is equivalent to \dv. If pattern is specified, only objects whose names match the pattern are listed. By default, only user-created objects are shown; supply a - pattern or the S modifier to include system + pattern or the S/-system modifier to include system objects. @@ -1378,13 +1413,14 @@ testdb=> \des[+] [ pattern ] + \describe-foreign-servers[-verbose] [ pattern ] Lists foreign servers (mnemonic: external servers). If pattern is specified, only those servers whose name matches the pattern - are listed. If the form \des+ is used, a + are listed. If the forms \des+ or \describe-foreign-server-verbose are used, a full description of each server is shown, including the server's access privileges, type, version, options, and description. @@ -1394,13 +1430,14 @@ testdb=> \det[+] [ pattern ] + \describe-foreign-table[-verbose] [ pattern ] Lists foreign tables (mnemonic: external tables). If pattern is specified, only entries whose table name or schema name matches - the pattern are listed. If the form \det+ - is used, generic options and the foreign table description + the pattern are listed. If the forms \det+ or \describe-foreign-table-verbose + are used, generic options and the foreign table description are also displayed. @@ -1409,19 +1446,20 @@ testdb=> \deu[+] [ pattern ] + \describe-user-mapping[-verbose] [ pattern ] Lists user mappings (mnemonic: external users). If pattern is specified, only those mappings whose user names match the - pattern are listed. If the form \deu+ is + pattern are listed. If the forms \deu+ or \describe-user-mapping-verboze are used, additional information about each mapping is shown. - \deu+ might also display the user name and + \deu+ and \describe-user-mapping-verboze might also display the user name and password of the remote user, so care should be taken not to disclose them. @@ -1432,14 +1470,15 @@ testdb=> \dew[+] [ pattern ] + \describe-foreign-data-wrapper[-verbose] [ pattern ] Lists foreign-data wrappers (mnemonic: external wrappers). If pattern is specified, only those foreign-data wrappers whose name matches - the pattern are listed. If the form \dew+ - is used, the access privileges, options, and description of the + the pattern are listed. If the forms \dew+ or \describe-foreign-data-wrapper-verbose + are used, the access privileges, options, and description of the foreign-data wrapper are also shown. @@ -1448,25 +1487,37 @@ testdb=> \df[anptwS+] [ pattern ] + \describe-function[-system][-verbose] [ pattern ] + \describe-normal-function[-system][-verbose] [ pattern ] + \describe-procedure[-system][-verbose] [ pattern ] + \describe-aggregate-function[-system][-verbose] [ pattern ] + \describe-trigger-function[-system][-verbose] [ pattern ] + \describe-window-function[-system][-verbose] [ pattern ] Lists functions, together with their result data types, argument data types, and function types, which are classified as agg (aggregate), normal, procedure, trigger, or window. - To display only functions + In the short form, to display only functions of specific type(s), add the corresponding letters a, n, p, t, or w to the command. If pattern is specified, only functions whose names match the pattern are shown. By default, only user-created - objects are shown; supply a pattern or the S + objects are shown; supply a pattern or the S/-system modifier to include system objects. - If the form \df+ is used, additional information + If the form \df+ or the -verbose suffix is used, additional information about each function is shown, including volatility, parallel safety, owner, security classification, access privileges, language, source code and description. + \describe-function is the equivalent of \df. + \describe-normal-function is the equivalent of \dff. + \describe-procedure is the equivalent of \dfp. + \describe-aggregate-function is the equivalent of \dfa. + \describe-trigger-function is the equivalent of \dft. + \describe-window-function is the equivalent of \dfw. @@ -1482,12 +1533,13 @@ testdb=> \dF[+] [ pattern ] + \describe-text-search-configuration[-verbose] [ pattern ] Lists text search configurations. If pattern is specified, only configurations whose names match the pattern are shown. - If the form \dF+ is used, a full description of + If the form \dF+ or \describe-text-search-configuration-verbose is used, a full description of each configuration is shown, including the underlying text search parser and the dictionary list for each parser token type. @@ -1496,12 +1548,13 @@ testdb=> \dFd[+] [ pattern ] + \describe-text-search-dictionary[-verbose] [ pattern ] Lists text search dictionaries. If pattern is specified, only dictionaries whose names match the pattern are shown. - If the form \dFd+ is used, additional information + If the form \dFd+ or \describe-text-search-dictionary-verbose is used, additional information is shown about each selected dictionary, including the underlying text search template and the option values. @@ -1510,12 +1563,13 @@ testdb=> \dFp[+] [ pattern ] + \describe-text-search-parser[-verbose] [ pattern ] Lists text search parsers. If pattern is specified, only parsers whose names match the pattern are shown. - If the form \dFp+ is used, a full description of + If the form \dFp+ or \describe-text-search-parser-verbose is used, a full description of each parser is shown, including the underlying functions and the list of recognized token types. @@ -1524,12 +1578,13 @@ testdb=> \dFt[+] [ pattern ] + \describe-text-search-template[-verbose] [ pattern ] Lists text search templates. If pattern is specified, only templates whose names match the pattern are shown. - If the form \dFt+ is used, additional information + If the form \dFt+ or \describe-text-search-template-verbose is used, additional information is shown about each template, including the underlying function names. @@ -1538,6 +1593,7 @@ testdb=> \dg[S+] [ pattern ] + \describe-role[-system][-verbose] [ pattern ] Lists database roles. @@ -1545,10 +1601,10 @@ testdb=> unified into roles, this command is now equivalent to \du.) By default, only user-created roles are shown; supply the - S modifier to include system roles. + S or -system modifier to include system roles. If pattern is specified, only those roles whose names match the pattern are listed. - If the form \dg+ is used, additional information + If the suffix + or -verbose> is specified, additional information is shown about each role; currently this adds the comment for each role. @@ -1568,14 +1624,15 @@ testdb=> \dL[S+] [ pattern ] + \describe-procedural-language[-system][-verbose] [ pattern ] Lists procedural languages. If pattern is specified, only languages whose names match the pattern are listed. By default, only user-created languages - are shown; supply the S modifier to include system - objects. If + is appended to the command name, each + are shown; supply the S or -system modifier to include system + objects. If + or -verbose is appended to the command name, each language is listed with its call handler, validator, access privileges, and whether it is a system object. @@ -1585,6 +1642,8 @@ testdb=> \dn[S+] [ pattern ] + \describe-schema[-system][-verbose] [ pattern ] + \describe-namespace[-system][-verbose] [ pattern ] @@ -1592,8 +1651,8 @@ testdb=> class="parameter">pattern is specified, only schemas whose names match the pattern are listed. By default, only user-created objects are shown; supply a - pattern or the S modifier to include system objects. - If + is appended to the command name, each object + pattern or the S or -system modifier to include system objects. + If + (or -verbose is appended to the command name, each object is listed with its associated permissions and description, if any. @@ -1602,15 +1661,16 @@ testdb=> \do[S+] [ pattern ] + \describe-operator[-system][-verbose] [ pattern ] Lists operators with their operand and result types. If pattern is specified, only operators whose names match the pattern are listed. By default, only user-created objects are shown; supply a - pattern or the S modifier to include system + pattern or the S or -system modifier to include system objects. - If + is appended to the command name, + If + or -verbose is appended to the command name, additional information about each operator is shown, currently just the name of the underlying function. @@ -1620,14 +1680,15 @@ testdb=> \dO[S+] [ pattern ] + \describe-collation[-system][-verbose] [ pattern ] Lists collations. If pattern is specified, only collations whose names match the pattern are listed. By default, only user-created objects are shown; - supply a pattern or the S modifier to - include system objects. If + is appended + supply a pattern or the S or -system modifier to + include system objects. If + or -verbose is appended to the command name, each collation is listed with its associated description, if any. Note that only collations usable with the current database's encoding @@ -1640,6 +1701,7 @@ testdb=> \dp [ pattern ] + \describe-privilege [ pattern ] Lists tables, views and sequences with their @@ -1661,6 +1723,7 @@ testdb=> \drds [ role-pattern [ database-pattern ] ] + \describe-defined-configuration-setting [ role-pattern [ database-pattern ] ] Lists defined configuration settings. These settings can be @@ -1683,13 +1746,14 @@ testdb=> \dRp[+] [ pattern ] + \describe-replication-publication[-verbose] [ pattern ] Lists replication publications. If pattern is specified, only those publications whose names match the pattern are listed. - If + is appended to the command name, the tables + If + or -verbose is appended to the command name, the tables associated with each publication are shown as well. @@ -1697,13 +1761,14 @@ testdb=> \dRs[+] [ pattern ] + \describe-replication-subscription[-verbose] [ pattern ] Lists replication subscriptions. If pattern is specified, only those subscriptions whose names match the pattern are listed. - If + is appended to the command name, additional + If + or -verbose is appended to the command name, additional properties of the subscriptions are shown. @@ -1711,16 +1776,17 @@ testdb=> \dT[S+] [ pattern ] + \describe-type[-system][-verbose] [ pattern ] Lists data types. If pattern is specified, only types whose names match the pattern are listed. - If + is appended to the command name, each type is + If + or -verbose is appended to the command name, each type is listed with its internal name and size, its allowed values if it is an enum type, and its associated permissions. By default, only user-created objects are shown; supply a - pattern or the S modifier to include system + pattern or the S or -system modifier to include system objects. @@ -1728,6 +1794,7 @@ testdb=> \du[S+] [ pattern ] + \describe-role[S+] [ pattern ] Lists database roles. @@ -1735,10 +1802,10 @@ testdb=> unified into roles, this command is now equivalent to \dg.) By default, only user-created roles are shown; supply the - S modifier to include system roles. + S or -system modifier to include system roles. If pattern is specified, only those roles whose names match the pattern are listed. - If the form \du+ is used, additional information + If the suffix + or -verbose is used, additional information is shown about each role; currently this adds the comment for each role. @@ -1747,13 +1814,14 @@ testdb=> \dx[+] [ pattern ] + \describe-extension[-verbose] [ pattern ] Lists installed extensions. If pattern is specified, only those extensions whose names match the pattern are listed. - If the form \dx+ is used, all the objects belonging + If the suffix + or -verbose is used, all the objects belonging to each matching extension are listed. @@ -1761,15 +1829,24 @@ testdb=> \dy[+] [ pattern ] + \describe-event-trigger[-verbose] [ pattern ] Lists event triggers. If pattern is specified, only those event triggers whose names match the pattern are listed. - If + is appended to the command name, each object + If + or -verbose is appended to the command name, each object is listed with its associated description. + + + + Long form commands can aid in clarity when sharing code with others. + Using tab completion can reduce typing and aid in the discovery of new + \describe commands. + + @@ -2305,7 +2382,7 @@ SELECT character set encodings, and access privileges. If pattern is specified, only databases whose names match the pattern are listed. - If + is appended to the command name, database + If + (or -verbose in the long form) is appended to the command name, database sizes, default tablespaces, and descriptions are also displayed. (Size information is only available for databases that the current user can connect to.) diff --git a/src/bin/psql/command.c b/src/bin/psql/command.c index ab259c473a..5ec4fb7a34 100644 --- a/src/bin/psql/command.c +++ b/src/bin/psql/command.c @@ -685,6 +685,27 @@ exec_command_crosstabview(PsqlScanState scan_state, bool active_branch) return status; } +/* + * \ddp pattern1 [pattern2] + * \describe-defined-configuration-setting pattern1 [pattern2] + */ +static bool +describe_defined_configuration_setting(PsqlScanState scan_state, const char *pattern) +{ + char *pattern2 = NULL; + bool success; + + if (pattern) + pattern2 = psql_scan_slash_option(scan_state, + OT_NORMAL, NULL, true); + success = listDbRoleSettings(pattern, pattern2); + + if (pattern2) + free(pattern2); + + return success; +} + /* * \d* commands */ @@ -712,11 +733,7 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd) case '\0': case '+': case 'S': - if (pattern) - success = describeTableDetails(pattern, show_verbose, show_system); - else - /* standard listing of interesting things */ - success = listTables("tvmsE", NULL, show_verbose, show_system); + success = describeAnything(pattern, show_verbose, show_system); break; case 'A': success = describeAccessMethods(pattern, show_verbose); @@ -795,17 +812,7 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd) break; case 'r': if (cmd[2] == 'd' && cmd[3] == 's') - { - char *pattern2 = NULL; - - if (pattern) - pattern2 = psql_scan_slash_option(scan_state, - OT_NORMAL, NULL, true); - success = listDbRoleSettings(pattern, pattern2); - - if (pattern2) - free(pattern2); - } + success = describe_defined_configuration_setting(scan_state, pattern); else status = PSQL_CMD_UNKNOWN; break; @@ -813,10 +820,7 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd) switch (cmd[2]) { case 'p': - if (show_verbose) - success = describePublications(pattern); - else - success = listPublications(pattern); + success = describeReplicationPublication(pattern, show_verbose); break; case 's': success = describeSubscriptions(pattern, show_verbose); @@ -849,12 +853,10 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd) break; } break; - case 'e': /* SQL/MED subsystem */ + case 'e': + /* SQL/MED subsystem and longform describe */ switch (cmd[2]) { - case 's': - success = listForeignServers(pattern, show_verbose); - break; case 'u': success = listUserMappings(pattern, show_verbose); break; @@ -864,16 +866,148 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd) case 't': success = listForeignTables(pattern, show_verbose); break; + case 's': + if (cmd[3] != 'c') + { + /* no \describe, just \des */ + success = listForeignServers(pattern, show_verbose); + break; + } + else if (strncmp(cmd, "describe", strlen("describe")) == 0) + { + char *command_detail = pg_malloc(1 + strlen(cmd) - strlen("describe")); + char *suffix_pos; + + /* copy everyting after "describe[-]" to the detail string */ + strcpy(command_detail, + (cmd[strlen("describe")] == '-') ? + &cmd[strlen("describe-")] : + &cmd[strlen("describe")]); + + /* search for and remove first -verbose found */ + show_verbose = false; + suffix_pos = strstr(command_detail, "-verbose"); + if (suffix_pos != NULL) + { + show_verbose = true; + strcpy(suffix_pos, &suffix_pos[strlen("-verbose")]); + } + + /* search for and remove first -system found */ + show_system = false; + suffix_pos = strstr(command_detail, "-system"); + if (suffix_pos != NULL) + { + show_system = true; + strcpy(suffix_pos, &suffix_pos[strlen("-system")]); + } + + /* most common case is \describe + suffixes */ + if (command_detail[0] == '\0') + success = describeAnything(pattern, show_verbose, show_system); + else if (strcmp(command_detail, "access-method") == 0) + success = describeAccessMethods(pattern, show_verbose); + else if (strcmp(command_detail, "aggregate-function") == 0) + success = describeAggregates(pattern, show_verbose, show_system); + else if (strcmp(command_detail, "cast") == 0) + success = listCasts(pattern, show_verbose); + else if (strcmp(command_detail, "constraint") == 0) + success = objectDescription(pattern, show_system); + else if (strcmp(command_detail, "conversion") == 0) + success = listConversions(pattern, show_verbose, show_system); + else if (strcmp(command_detail, "constraint") == 0) + success = listConversions(pattern, show_verbose, show_system); + else if (strcmp(command_detail, "collation") == 0) + success = listCollations(pattern, show_verbose, show_system); + else if (strcmp(command_detail, "defined-configuration-setting") == 0) + success = describe_defined_configuration_setting(scan_state, pattern); + else if (strcmp(command_detail, "default-access-privelege") == 0) + success = listDefaultACLs(pattern); + else if (strcmp(command_detail, "domain") == 0) + success = listDomains(pattern, show_verbose, show_system); + else if (strcmp(command_detail, "extension") == 0) + success = describeExtension(pattern, show_verbose); + else if (strcmp(command_detail, "event-trigger") == 0) + success = listEventTriggers(pattern, show_verbose); + else if (strcmp(command_detail, "foreign-data-wrapper") == 0) + success = listForeignDataWrappers(pattern, show_verbose); + else if (strcmp(command_detail, "foreign-server") == 0) + success = listForeignServers(pattern, show_verbose); + else if (strcmp(command_detail, "foreign-table") == 0) + success = listForeignTables(pattern, show_verbose); + else if (strcmp(command_detail, "function") == 0) + success = describeFunctions("\0", pattern, show_verbose, show_system); + else if (strcmp(command_detail, "index") == 0) + success = listTables("i", pattern, show_verbose, show_system); + else if (strcmp(command_detail, "materialized-view") == 0) + success = listTables("m", pattern, show_verbose, show_system); + else if (strcmp(command_detail, "namespace") == 0) + success = listSchemas(pattern, show_verbose, show_system); + else if (strcmp(command_detail, "normal-function") == 0) + success = describeFunctions("n", pattern, show_verbose, show_system); + else if (strcmp(command_detail, "operator") == 0) + success = describeOperators(pattern, show_verbose, show_system); + else if (strcmp(command_detail, "operator-class") == 0) + success = objectDescription(pattern, show_system); + else if (strcmp(command_detail, "operator-family") == 0) + success = objectDescription(pattern, show_system); + else if (strcmp(command_detail, "privilege") == 0) + success = permissionsList(pattern); + else if (strcmp(command_detail, "procedural-language") == 0) + success = listLanguages(pattern, show_verbose, show_system); + else if (strcmp(command_detail, "procedure") == 0) + success = describeFunctions("p", pattern, show_verbose, show_system); + else if (strcmp(command_detail, "replication-publication") == 0) + success = describeReplicationPublication(pattern, show_verbose); + else if (strcmp(command_detail, "replication-subscription") == 0) + success = describeSubscriptions(pattern, show_verbose); + else if (strcmp(command_detail, "role") == 0) + success = describeRoles(pattern, show_verbose, show_system); + else if (strcmp(command_detail, "rule") == 0) + success = objectDescription(pattern, show_system); + else if (strcmp(command_detail, "schema") == 0) + success = listSchemas(pattern, show_verbose, show_system); + else if (strcmp(command_detail, "sequence") == 0) + success = listTables("s", pattern, show_verbose, show_system); + else if (strcmp(command_detail, "table") == 0) + success = listTables("t", pattern, show_verbose, show_system); + else if (strcmp(command_detail, "tablespace") == 0) + success = describeTablespaces(pattern, show_verbose); + else if (strcmp(command_detail, "text-search-configuration") == 0) + success = listTSConfigs(pattern, show_verbose); + else if (strcmp(command_detail, "text-search-dictionary") == 0) + success = listTSDictionaries(pattern, show_verbose); + else if (strcmp(command_detail, "text-search-parser") == 0) + success = listTSParsers(pattern, show_verbose); + else if (strcmp(command_detail, "text-search-templates") == 0) + success = listTSTemplates(pattern, show_verbose); + else if (strcmp(command_detail, "trigger") == 0) + success = objectDescription(pattern, show_system); + else if (strcmp(command_detail, "trigger-function") == 0) + success = describeFunctions("t", pattern, show_verbose, show_system); + else if (strcmp(command_detail, "type") == 0) + success = describeTypes(pattern, show_verbose, show_system); + else if (strcmp(command_detail, "user-mapping") == 0) + success = listUserMappings(pattern, show_verbose); + else if (strcmp(command_detail, "view") == 0) + success = listTables("v", pattern, show_verbose, show_system); + else if (strcmp(command_detail, "window-function") == 0) + success = describeFunctions("w", pattern, show_verbose, show_system); + else + status = PSQL_CMD_UNKNOWN; + free(command_detail); + break; + } + else + status = PSQL_CMD_UNKNOWN; + break; default: status = PSQL_CMD_UNKNOWN; break; } break; case 'x': /* Extensions */ - if (show_verbose) - success = listExtensionContents(pattern); - else - success = listExtensions(pattern); + success = describeExtension(pattern, show_verbose); break; case 'y': /* Event Triggers */ success = listEventTriggers(pattern, show_verbose); diff --git a/src/bin/psql/command.h b/src/bin/psql/command.h index de748d320e..ed05d0de93 100644 --- a/src/bin/psql/command.h +++ b/src/bin/psql/command.h @@ -24,7 +24,6 @@ typedef enum _backslashResult * resulted in an error */ } backslashResult; - extern backslashResult HandleSlashCmds(PsqlScanState scan_state, ConditionalStack cstack, PQExpBuffer query_buf, diff --git a/src/bin/psql/describe.c b/src/bin/psql/describe.c index 4da6719ce7..ce02472987 100644 --- a/src/bin/psql/describe.c +++ b/src/bin/psql/describe.c @@ -5611,3 +5611,42 @@ printACLColumn(PQExpBuffer buf, const char *colname) "pg_catalog.array_to_string(%s, '\\n') AS \"%s\"", colname, gettext_noop("Access privileges")); } + +/* + * \d [pattern] + * \describe [pattern] + */ +bool +describeAnything(const char *pattern, bool show_verbose, bool show_system) +{ + if (pattern) + return describeTableDetails(pattern, show_verbose, show_system); + /* standard listing of interesting things */ + return listTables("tvmsE", NULL, show_verbose, show_system); +} + +/* + * \dRp + * \describe-replication-publication pattern + */ +bool +describeReplicationPublication(const char *pattern, bool show_verbose) +{ + if (show_verbose) + return describePublications(pattern); + + return listPublications(pattern); +} + +/* + * \dx + * \describe-extension + */ +bool +describeExtension(const char *pattern, bool show_verbose) +{ + if (show_verbose) + return listExtensionContents(pattern); + + return listExtensions(pattern); +} diff --git a/src/bin/psql/describe.h b/src/bin/psql/describe.h index 4ff1f91f38..34a497461e 100644 --- a/src/bin/psql/describe.h +++ b/src/bin/psql/describe.h @@ -103,12 +103,21 @@ extern bool listExtensionContents(const char *pattern); extern bool listEventTriggers(const char *pattern, bool verbose); /* \dRp */ -bool listPublications(const char *pattern); +extern bool listPublications(const char *pattern); /* \dRp+ */ -bool describePublications(const char *pattern); +extern bool describePublications(const char *pattern); /* \dRs */ -bool describeSubscriptions(const char *pattern, bool verbose); +extern bool describeSubscriptions(const char *pattern, bool verbose); + +/* \d \describe */ +extern bool describeAnything(const char *pattern, bool show_verbose, bool show_system); + +/* \dRp \describe-replication-publication pattern */ +extern bool describeReplicationPublication(const char *pattern, bool show_verbose); + +/* \dx \describe-extension */ +extern bool describeExtension(const char *pattern, bool show_verbose); #endif /* DESCRIBE_H */ diff --git a/src/bin/psql/tab-complete.c b/src/bin/psql/tab-complete.c index 7b7a88fda3..a83ab73192 100644 --- a/src/bin/psql/tab-complete.c +++ b/src/bin/psql/tab-complete.c @@ -1402,6 +1402,51 @@ psql_completion(const char *text, int start, int end) "\\w", "\\watch", "\\z", "\\!", "\\?", + "\\describe-access-method", + "\\describe-aggregate-function", + "\\describe-aggregate", + "\\describe-cast", + "\\describe-collation", + "\\describe-constraint", + "\\describe-conversion", + "\\describe-default-access-privelege", + "\\describe-defined-configuration-setting", + "\\describe-domain", + "\\describe-event-trigger", + "\\describe-extension", + "\\describe-foreign-data-wrapper", + "\\describe-foreign-server", + "\\describe-foreign-table", + "\\describe-function", + "\\describe-index", + "\\describe-materialized-view", + "\\describe-namespace", + "\\describe-normal-function", + "\\describe-operator-class", + "\\describe-operator-family", + "\\describe-operator", + "\\describe-privilege", + "\\describe-procedural-language", + "\\describe-procedure", + "\\describe-replication-publication", + "\\describe-replication-subscription", + "\\describe-role", + "\\describe-rule", + "\\describe-schema", + "\\describe-sequence", + "\\describe-tablespace", + "\\describe-table", + "\\describe-text-search-configuration", + "\\describe-text-search-dictionary", + "\\describe-text-search-parser", + "\\describe-text-search-templates", + "\\describe-trigger-function", + "\\describe-trigger", + "\\describe-type", + "\\describe-user-mapping", + "\\describe-view", + "\\describe-window-function", + "\\describe", NULL }; @@ -3468,63 +3513,128 @@ psql_completion(const char *text, int start, int end) if (!recognized_connection_string(prev_wd)) COMPLETE_WITH_QUERY(Query_for_list_of_roles); } - else if (TailMatchesCS("\\da*")) - COMPLETE_WITH_VERSIONED_SCHEMA_QUERY(Query_for_list_of_aggregates, NULL); - else if (TailMatchesCS("\\dA*")) - COMPLETE_WITH_QUERY(Query_for_list_of_access_methods); - else if (TailMatchesCS("\\db*")) - COMPLETE_WITH_QUERY(Query_for_list_of_tablespaces); - else if (TailMatchesCS("\\dD*")) - COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_domains, NULL); - else if (TailMatchesCS("\\des*")) - COMPLETE_WITH_QUERY(Query_for_list_of_servers); - else if (TailMatchesCS("\\deu*")) - COMPLETE_WITH_QUERY(Query_for_list_of_user_mappings); - else if (TailMatchesCS("\\dew*")) - COMPLETE_WITH_QUERY(Query_for_list_of_fdws); - else if (TailMatchesCS("\\df*")) - COMPLETE_WITH_VERSIONED_SCHEMA_QUERY(Query_for_list_of_functions, NULL); - - else if (TailMatchesCS("\\dFd*")) - COMPLETE_WITH_QUERY(Query_for_list_of_ts_dictionaries); - else if (TailMatchesCS("\\dFp*")) - COMPLETE_WITH_QUERY(Query_for_list_of_ts_parsers); - else if (TailMatchesCS("\\dFt*")) - COMPLETE_WITH_QUERY(Query_for_list_of_ts_templates); - /* must be at end of \dF alternatives: */ - else if (TailMatchesCS("\\dF*")) - COMPLETE_WITH_QUERY(Query_for_list_of_ts_configurations); - - else if (TailMatchesCS("\\di*")) - COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_indexes, NULL); - else if (TailMatchesCS("\\dL*")) - COMPLETE_WITH_QUERY(Query_for_list_of_languages); - else if (TailMatchesCS("\\dn*")) - COMPLETE_WITH_QUERY(Query_for_list_of_schemas); - else if (TailMatchesCS("\\dp") || TailMatchesCS("\\z")) - COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_grantables, NULL); - else if (TailMatchesCS("\\ds*")) - COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_sequences, NULL); - else if (TailMatchesCS("\\dt*")) - COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables, NULL); - else if (TailMatchesCS("\\dT*")) - COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_datatypes, NULL); - else if (TailMatchesCS("\\du*") || TailMatchesCS("\\dg*")) - COMPLETE_WITH_QUERY(Query_for_list_of_roles); - else if (TailMatchesCS("\\dv*")) - COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_views, NULL); - else if (TailMatchesCS("\\dx*")) - COMPLETE_WITH_QUERY(Query_for_list_of_extensions); - else if (TailMatchesCS("\\dm*")) - COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_matviews, NULL); - else if (TailMatchesCS("\\dE*")) - COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_foreign_tables, NULL); - else if (TailMatchesCS("\\dy*")) - COMPLETE_WITH_QUERY(Query_for_list_of_event_triggers); - - /* must be at end of \d alternatives: */ else if (TailMatchesCS("\\d*")) - COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_relations, NULL); + { + if (TailMatchesCS("\\df*")) + COMPLETE_WITH_VERSIONED_SCHEMA_QUERY(Query_for_list_of_functions, NULL); + else if (TailMatchesCS("\\da*")) + COMPLETE_WITH_VERSIONED_SCHEMA_QUERY(Query_for_list_of_aggregates, NULL); + else if (TailMatchesCS("\\dA*")) + COMPLETE_WITH_QUERY(Query_for_list_of_access_methods); + else if (TailMatchesCS("\\db*")) + COMPLETE_WITH_QUERY(Query_for_list_of_tablespaces); + else if (TailMatchesCS("\\dD*")) + COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_domains, NULL); + else if (TailMatchesCS("\\deu*")) + COMPLETE_WITH_QUERY(Query_for_list_of_user_mappings); + else if (TailMatchesCS("\\dew*")) + COMPLETE_WITH_QUERY(Query_for_list_of_fdws); + else if (TailMatchesCS("\\dFd*")) + COMPLETE_WITH_QUERY(Query_for_list_of_ts_dictionaries); + else if (TailMatchesCS("\\dFp*")) + COMPLETE_WITH_QUERY(Query_for_list_of_ts_parsers); + else if (TailMatchesCS("\\dFt*")) + COMPLETE_WITH_QUERY(Query_for_list_of_ts_templates); + /* must be at end of \dF alternatives: */ + else if (TailMatchesCS("\\dF*")) + COMPLETE_WITH_QUERY(Query_for_list_of_ts_configurations); + else if (TailMatchesCS("\\di*")) + COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_indexes, NULL); + else if (TailMatchesCS("\\dL*")) + COMPLETE_WITH_QUERY(Query_for_list_of_languages); + else if (TailMatchesCS("\\dn*")) + COMPLETE_WITH_QUERY(Query_for_list_of_schemas); + else if (TailMatchesCS("\\dp") || TailMatchesCS("\\z")) + COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_grantables, NULL); + else if (TailMatchesCS("\\ds*")) + COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_sequences, NULL); + else if (TailMatchesCS("\\dt*")) + COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables, NULL); + else if (TailMatchesCS("\\dT*")) + COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_datatypes, NULL); + else if (TailMatchesCS("\\du*") || TailMatchesCS("\\dg*")) + COMPLETE_WITH_QUERY(Query_for_list_of_roles); + else if (TailMatchesCS("\\dv*")) + COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_views, NULL); + else if (TailMatchesCS("\\dx*")) + COMPLETE_WITH_QUERY(Query_for_list_of_extensions); + else if (TailMatchesCS("\\dm*")) + COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_matviews, NULL); + else if (TailMatchesCS("\\dE*")) + COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_foreign_tables, NULL); + else if (TailMatchesCS("\\dy*")) + COMPLETE_WITH_QUERY(Query_for_list_of_event_triggers); + else if (TailMatchesCS("\\des*")) + { + if (TailMatchesCS("\\describe*")) + { + if (TailMatchesCS("\\describe-access-method*")) + COMPLETE_WITH_QUERY(Query_for_list_of_access_methods); + else if (TailMatchesCS("\\describe-aggregate-function*")) + COMPLETE_WITH_VERSIONED_SCHEMA_QUERY(Query_for_list_of_functions, NULL); + else if (TailMatchesCS("\\describe-aggregate*")) + COMPLETE_WITH_VERSIONED_SCHEMA_QUERY(Query_for_list_of_aggregates, NULL); + else if (TailMatchesCS("\\describe-domain*")) + COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_domains, NULL); + else if (TailMatchesCS("\\describe-event-trigger*")) + COMPLETE_WITH_QUERY(Query_for_list_of_event_triggers); + else if (TailMatchesCS("\\describe-extension*")) + COMPLETE_WITH_QUERY(Query_for_list_of_extensions); + else if (TailMatchesCS("\\describe-foreign-data-wrapper*")) + COMPLETE_WITH_QUERY(Query_for_list_of_fdws); + else if (TailMatchesCS("\\describe-foreign-server*")) + COMPLETE_WITH_QUERY(Query_for_list_of_servers); + else if (TailMatchesCS("\\describe-foreign-table*")) + COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_foreign_tables, NULL); + else if (TailMatchesCS("\\describe-function*")) + COMPLETE_WITH_VERSIONED_SCHEMA_QUERY(Query_for_list_of_functions, NULL); + else if (TailMatchesCS("\\describe-index*")) + COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_indexes, NULL); + else if (TailMatchesCS("\\describe-materialized-view*")) + COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_matviews, NULL); + else if (TailMatchesCS("\\describe-namespace*")) + COMPLETE_WITH_QUERY(Query_for_list_of_schemas); + else if (TailMatchesCS("\\describe-normal-function*")) + COMPLETE_WITH_VERSIONED_SCHEMA_QUERY(Query_for_list_of_functions, NULL); + else if (TailMatchesCS("\\describe-privelege*")) + COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_grantables, NULL); + else if (TailMatchesCS("\\describe-procedural-language*")) + COMPLETE_WITH_QUERY(Query_for_list_of_languages); + else if (TailMatchesCS("\\describe-procedure*")) + COMPLETE_WITH_VERSIONED_SCHEMA_QUERY(Query_for_list_of_functions, NULL); + else if (TailMatchesCS("\\describe-role*")) + COMPLETE_WITH_QUERY(Query_for_list_of_roles); + else if (TailMatchesCS("\\describe-tablespace*")) + COMPLETE_WITH_QUERY(Query_for_list_of_tablespaces); + else if (TailMatchesCS("\\describe-schema*")) + COMPLETE_WITH_QUERY(Query_for_list_of_schemas); + else if (TailMatchesCS("\\describe-sequence*")) + COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_sequences, NULL); + else if (TailMatchesCS("\\describe-table*")) + COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables, NULL); + else if (TailMatchesCS("\\describe-text-search-dictionary*")) + COMPLETE_WITH_QUERY(Query_for_list_of_ts_dictionaries); + else if (TailMatchesCS("\\describe-text-search-parser*")) + COMPLETE_WITH_QUERY(Query_for_list_of_ts_parsers); + else if (TailMatchesCS("\\describe-text-search-template*")) + COMPLETE_WITH_QUERY(Query_for_list_of_ts_templates); + else if (TailMatchesCS("\\describe-type*")) + COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_datatypes, NULL); + else if (TailMatchesCS("\\describe-user-mapping*")) + COMPLETE_WITH_QUERY(Query_for_list_of_user_mappings); + else if (TailMatchesCS("\\describe-view*")) + COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_views, NULL); + else if (TailMatchesCS("\\describe-window-function*")) + COMPLETE_WITH_VERSIONED_SCHEMA_QUERY(Query_for_list_of_functions, NULL); + else + COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_relations, NULL); + } + else /* \\des* must go after \\describe */ + COMPLETE_WITH_QUERY(Query_for_list_of_servers); + } + else /* must be at end of \d alternatives: */ + COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_relations, NULL); + } else if (TailMatchesCS("\\ef")) COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_routines, NULL); -- 2.17.1