On Mon, Mar 4, 2019 at 1:45 PM Corey Huinker <corey.huin...@gmail.com>
wrote:

>
>>> - Tab completion for \descibe-verbose.
>>> I know that \d+ tab completion is also not there, but I think we must
>>> have tab completion for \descibe-verbose.
>>>
>>> postgres=# \describe-
>>> \describe-extension
>>>  \describe-replication-publication         \describe-user-mapping
>>> \describe-foreign-data-wrapper
>>> \describe-replication-subscription        \describe-view
>>> \describe-foreign-server                  \describe-role
>>>             \describe-window-function
>>> \describe-foreign-table                   \describe-rule
>>>  ...
>>>
>>
> I just confirmed that there isn't tab completion for the existing S/+
> options, so it's hard to justify them for the equivalent verbose suffixes.
>

We can add completions for describe[-thing-]-verbose, but the
auto-completions start to run into combinatoric complexity, and the
original short-codes don't do that completion, probably for the same reason.

+                                                               success =
>>> listTables("tvmsE", NULL, show_verbose, show_system);
>>> +                                               }
>>> +                                               status =
>>> PSQL_CMD_UNKNOWN;
>>>
>>>
> I'll look into this, thanks!
>

This was fixed, good find.



> - Confusion about \desc and \desC
>>> There is confusion while running the \desc command. I know the problem,
>>> but the user may confuse by this.
>>> postgres=# \desC
>>>        List of foreign servers
>>>  Name | Owner | Foreign-data wrapper
>>> ------+-------+----------------------
>>> (0 rows)
>>>
>>> postgres=# \desc
>>> Invalid command \desc. Try \? for help.
>>>
>>
I've changed the code to first strip out 0-1 instances of "-verbose" and
"-system" and the remaining string must be an exact match of a describe
command or it's an error. This same system could be applied to the short
commands to strip out 'S' and '+' and it might clean up the original code a
bit.

This command shows a list of relation "\d"
>>> postgres=# \describe-aggregatE-function
>>>         List of relations
>>>  Schema | Name | Type  |  Owner
>>> --------+------+-------+---------
>>>  public | foo  | table | vagrant
>>> (1 row)
>>>
>>
Same issue, same fix.


>>> I have done a brief code review except for the documentation code. I
>>> don't like this code
>>>
>>> if (cmd_match(cmd,"describe-aggregate-function"))
>>>
>>>  success = describeAggregates(pattern, show_verbose, show_system);
>>>                              else if (cmd_match(cmd,
>>> "describe-access-method"))
>>>                                  success =
>>> describeAccessMethods(pattern, show_verbose);
>>>                              else if (cmd_match(cmd,
>>> "describe-tablespace"))
>>>                                  success = describeTablespaces(pattern,
>>> show_verbose);
>>>                              else if (cmd_match(cmd,
>>> "describe-conversion"))
>>>                                  success = listConversions(pattern,
>>> show_verbose, show_system);
>>>                              else if (cmd_match(cmd, "describe-cast"))
>>>                                  success = listCasts(pattern,
>>> show_verbose
>>>
>>>
>>> This can be achieved with the list/array/hash table, so I have changed
>>> that code in the attached patch just for a sample if you want I can do that
>>> for whole code.
>>>
>>
> There's some problems with a hash table. The function signatures vary
> quite a lot, and some require additional psql_scan_slash_options to be
> called. The hash option, if implemented, probably should be expanded to all
> slash commands, at which point maybe it belongs in psqlscanslash.l...
>

As I suspected, there's a lot of variance in the function signatures of the
various listSomething()/describeSomething() commands,
and listDbRoleSettings requires a second pattern to be scanned, and as far
as I know PsqlScanState isn't known inside describe.h, so building and
using a hash table would be a lot of work for uncertain gain. The original
code just plows through strings in alphabetical order, breaking things up
by comparing leading characters, so I largely did the same at the
des/decribe levels.

Instead of a hash table, It might be fun to write something that takes a
list of alphabetized strings, and builds a binary search tree at compile
time, but that would only work for the long form commands, the short forms
that allow filters like df[anptw]+ and d[tvmisE]+ effectively defeat any
attempt at hashing or btree-ing that I can presently imagine.

Having said that, here's v3 of the patch.

Since this is now waiting for v13, there's a bit more time to entertain the
question of whether we'd rather have these in psql or in a new server
command DESCRIBE [verbose] [system], and if so, whether the output of that
would itself be query-able or not.
From 6ff5ebd39a5bda3c2b398ac0b0062bd629f3c877 Mon Sep 17 00:00:00 2001
From: Corey Huinker <corey.huin...@gmail.com>
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=&gt;
     same line.
     </para>
 
+    <para>
+    The family of meta-commands starting with <literal>\d</literal> often
+    have an equivalent <literal>\describe-</literal> "long form" command.
+    The long-form commands often have the suffixes <literal>-system</literal>
+    and <literal>-verbose</literal> which are the equivalent of the
+    short form suffixes <literal>S</literal> and <literal>+</literal>
+    respectively. The long form suffixes cannot be used on the short form
+    variants. Every <literal>\describe</literal> variant has an equivalent
+    short form variant.
+    </para>
+
     <para>
     The following meta-commands are defined:
 
@@ -1147,6 +1158,7 @@ testdb=&gt;
 
       <varlistentry>
         <term><literal>\d[S+] [ <link linkend="app-psql-patterns"><replaceable class="parameter">pattern</replaceable></link> ]</literal></term>
+        <term><literal>\describe[-system][-verbose] [ <link linkend="app-psql-patterns"><replaceable class="parameter">pattern</replaceable></link> ]</literal></term>
 
         <listitem>
         <para>
@@ -1165,13 +1177,13 @@ testdb=&gt;
         </para>
 
         <para>
-        For some types of relation, <literal>\d</literal> shows additional information
+        For some types of relation, <literal>\d</literal> (and <literal>\describe</literal> shows additional information
         for each column: column values for sequences, indexed expressions for
         indexes, and foreign data wrapper options for foreign tables.
         </para>
 
         <para>
-        The command form <literal>\d+</literal> is identical, except that
+        The command forms <literal>\d+</literal> and <literal>\describe-verbose</literal> are identical to <literal>\d</literal>, 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=&gt;
 
         <para>
         By default, only user-created objects are shown;  supply a
-        pattern or the <literal>S</literal> modifier to include system
+        pattern or the <literal>S</literal> modifier for <literal>\d</literal> or <literal>-verbose</literal> modifier for <literal>\describe</literal> modifier to include system
         objects.
         </para>
 
         <note>
         <para>
-        If <command>\d</command> is used without a
+        If <command>\d</command> / <command>\describe</command> is used without a
         <replaceable class="parameter">pattern</replaceable> argument, it is
         equivalent to <command>\dtvmsE</command> which will show a list of
         all visible tables, views, materialized views, sequences and
@@ -1200,6 +1212,7 @@ testdb=&gt;
 
       <varlistentry>
         <term><literal>\da[S] [ <link linkend="app-psql-patterns"><replaceable class="parameter">pattern</replaceable></link> ]</literal></term>
+        <term><literal>\describe-aggregate[-system] [ <link linkend="app-psql-patterns"><replaceable class="parameter">pattern</replaceable></link> ]</literal></term>
 
         <listitem>
         <para>
@@ -1208,7 +1221,7 @@ testdb=&gt;
         class="parameter">pattern</replaceable>
         is specified, only aggregates whose names match the pattern are shown.
         By default, only user-created objects are shown;  supply a
-        pattern or the <literal>S</literal> modifier to include system
+        pattern or the <literal>S</literal>/<literal>-system</literal> modifier to include system
         objects.
         </para>
         </listitem>
@@ -1216,13 +1229,14 @@ testdb=&gt;
 
       <varlistentry>
         <term><literal>\dA[+] [ <link linkend="app-psql-patterns"><replaceable class="parameter">pattern</replaceable></link> ]</literal></term>
+        <term><literal>\describe-access-method[-verbose] [ <link linkend="app-psql-patterns"><replaceable class="parameter">pattern</replaceable></link> ]</literal></term>
 
         <listitem>
         <para>
         Lists access methods. If <replaceable
         class="parameter">pattern</replaceable> is specified, only access
         methods whose names match the pattern are shown. If
-        <literal>+</literal> is appended to the command name, each access
+        <literal>+</literal>/<literal>-verbose</literal> is appended to the command name, each access
         method is listed with its associated handler function and description.
         </para>
         </listitem>
@@ -1230,13 +1244,14 @@ testdb=&gt;
 
       <varlistentry>
         <term><literal>\db[+] [ <link linkend="app-psql-patterns"><replaceable class="parameter">pattern</replaceable></link> ]</literal></term>
+        <term><literal>\describe-tablespace[-verbose] [ <link linkend="app-psql-patterns"><replaceable class="parameter">pattern</replaceable></link> ]</literal></term>
 
         <listitem>
         <para>
         Lists tablespaces. If <replaceable
         class="parameter">pattern</replaceable>
         is specified, only tablespaces whose names match the pattern are shown.
-        If <literal>+</literal> is appended to the command name, each tablespace
+        If <literal>+</literal>/<literal>-verbose</literal> is appended to the command name, each tablespace
         is listed with its associated options, on-disk size, permissions and
         description.
         </para>
@@ -1246,6 +1261,7 @@ testdb=&gt;
 
       <varlistentry>
         <term><literal>\dc[S+] [ <link linkend="app-psql-patterns"><replaceable class="parameter">pattern</replaceable></link> ]</literal></term>
+        <term><literal>\describe-conversion[-system][-verbose] [ <link linkend="app-psql-patterns"><replaceable class="parameter">pattern</replaceable></link> ]</literal></term>
         <listitem>
         <para>
         Lists conversions between character-set encodings.
@@ -1253,9 +1269,9 @@ testdb=&gt;
         is specified, only conversions whose names match the pattern are
         listed.
         By default, only user-created objects are shown;  supply a
-        pattern or the <literal>S</literal> modifier to include system
+        pattern or the <literal>S</literal>/<literal>-system</literal> modifier to include system
         objects.
-        If <literal>+</literal> is appended to the command name, each object
+        If <literal>+</literal>/<literal>-verbose</literal> is appended to the command name, each object
         is listed with its associated description.
         </para>
         </listitem>
@@ -1264,13 +1280,14 @@ testdb=&gt;
 
       <varlistentry>
         <term><literal>\dC[+] [ <link linkend="app-psql-patterns"><replaceable class="parameter">pattern</replaceable></link> ]</literal></term>
+        <term><literal>\describe-cast[-verbose] [ <link linkend="app-psql-patterns"><replaceable class="parameter">pattern</replaceable></link> ]</literal></term>
         <listitem>
         <para>
         Lists type casts.
         If <replaceable class="parameter">pattern</replaceable>
         is specified, only casts whose source or target types match the
         pattern are listed.
-        If <literal>+</literal> is appended to the command name, each object
+        If <literal>+</literal>/<literal>-verbose</literal> is appended to the command name, each object
         is listed with its associated description.
         </para>
         </listitem>
@@ -1279,6 +1296,11 @@ testdb=&gt;
 
       <varlistentry>
         <term><literal>\dd[S] [ <link linkend="app-psql-patterns"><replaceable class="parameter">pattern</replaceable></link> ]</literal></term>
+        <term><literal>\describe-constraint[-system] [ <link linkend="app-psql-patterns"><replaceable class="parameter">pattern</replaceable></link> ]</literal></term>
+        <term><literal>\describe-operator-class[-system] [ <link linkend="app-psql-patterns"><replaceable class="parameter">pattern</replaceable></link> ]</literal></term>
+        <term><literal>\describe-operator-family[-system] [ <link linkend="app-psql-patterns"><replaceable class="parameter">pattern</replaceable></link> ]</literal></term>
+        <term><literal>\describe-rule[-system] [ <link linkend="app-psql-patterns"><replaceable class="parameter">pattern</replaceable></link> ]</literal></term>
+        <term><literal>\describe-trigger[-system] [ <link linkend="app-psql-patterns"><replaceable class="parameter">pattern</replaceable></link> ]</literal></term>
         <listitem>
         <para>
         Shows the descriptions of objects of type <literal>constraint</literal>,
@@ -1293,7 +1315,7 @@ testdb=&gt;
         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 <literal>S</literal> modifier to include system
+        pattern or the <literal>S</literal>/<literal>-system</literal> modifier to include system
         objects.
         </para>
 
@@ -1308,15 +1330,16 @@ testdb=&gt;
 
       <varlistentry>
         <term><literal>\dD[S+] [ <link linkend="app-psql-patterns"><replaceable class="parameter">pattern</replaceable></link> ]</literal></term>
+        <term><literal>\describe-domain[-system][-verbose] [ <link linkend="app-psql-patterns"><replaceable class="parameter">pattern</replaceable></link> ]</literal></term>
         <listitem>
         <para>
         Lists domains. If <replaceable
         class="parameter">pattern</replaceable>
         is specified, only domains whose names match the pattern are shown.
         By default, only user-created objects are shown;  supply a
-        pattern or the <literal>S</literal> modifier to include system
+        pattern or the <literal>S</literal>/<literal>-system</literal> modifier to include system
         objects.
-        If <literal>+</literal> is appended to the command name, each object
+        If <literal>+</literal>/<literal>-verbose</literal> is appended to the command name, each object
         is listed with its associated permissions and description.
         </para>
         </listitem>
@@ -1325,6 +1348,7 @@ testdb=&gt;
 
       <varlistentry>
         <term><literal>\ddp [ <link linkend="app-psql-patterns"><replaceable class="parameter">pattern</replaceable></link> ]</literal></term>
+        <term><literal>\describe-default-access-privelege [ <link linkend="app-psql-patterns"><replaceable class="parameter">pattern</replaceable></link> ]</literal></term>
         <listitem>
         <para>
         Lists default access privilege settings.  An entry is shown for
@@ -1352,6 +1376,11 @@ testdb=&gt;
         <term><literal>\ds[S+] [ <link linkend="app-psql-patterns"><replaceable class="parameter">pattern</replaceable></link> ]</literal></term>
         <term><literal>\dt[S+] [ <link linkend="app-psql-patterns"><replaceable class="parameter">pattern</replaceable></link> ]</literal></term>
         <term><literal>\dv[S+] [ <link linkend="app-psql-patterns"><replaceable class="parameter">pattern</replaceable></link> ]</literal></term>
+        <term><literal>\describe-index[-system][-verbose] [ <link linkend="app-psql-patterns"><replaceable class="parameter">pattern</replaceable></link> ]</literal></term>
+        <term><literal>\describe-materialized-view[-system][-verbose] [ <link linkend="app-psql-patterns"><replaceable class="parameter">pattern</replaceable></link> ]</literal></term>
+        <term><literal>\describe-sequence[-system][-verbose] [ <link linkend="app-psql-patterns"><replaceable class="parameter">pattern</replaceable></link> ]</literal></term>
+        <term><literal>\describe-table[-system][-verbose] [ <link linkend="app-psql-patterns"><replaceable class="parameter">pattern</replaceable></link> ]</literal></term>
+        <term><literal>\describe-view[-system][-verbose] [ <link linkend="app-psql-patterns"><replaceable class="parameter">pattern</replaceable></link> ]</literal></term>
 
         <listitem>
         <para>
@@ -1360,16 +1389,22 @@ testdb=&gt;
         <literal>t</literal>, and <literal>v</literal>
         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, <literal>\dit</literal> lists indexes
-        and tables.  If <literal>+</literal> is
+        and tables.  If <literal>+</literal>/<literal>-verbose</literal> is
         appended to the command name, each object is listed with its
         physical size on disk and its associated description, if any.
+        <literal>\describe-foreign-table</literal> is equivalent to <literal>\dE</literal>.
+        <literal>\describe-index</literal> is equivalent to <literal>\di</literal>.
+        <literal>\describe-materialized-view</literal> is equivalent to <literal>\dm</literal>.
+        <literal>\describe-sequence</literal> is equivalent to <literal>\ds</literal>.
+        <literal>\describe-table</literal> is equivalent to <literal>\dt</literal>.
+        <literal>\describe-view</literal> is equivalent to <literal>\dv</literal>.
         If <replaceable class="parameter">pattern</replaceable> is
         specified, only objects whose names match the pattern are listed.
         By default, only user-created objects are shown; supply a
-        pattern or the <literal>S</literal> modifier to include system
+        pattern or the <literal>S</literal>/<literal>-system</literal> modifier to include system
         objects.
         </para>
         </listitem>
@@ -1378,13 +1413,14 @@ testdb=&gt;
 
       <varlistentry>
         <term><literal>\des[+] [ <link linkend="app-psql-patterns"><replaceable class="parameter">pattern</replaceable></link> ]</literal></term>
+        <term><literal>\describe-foreign-servers[-verbose] [ <link linkend="app-psql-patterns"><replaceable class="parameter">pattern</replaceable></link> ]</literal></term>
         <listitem>
         <para>
         Lists foreign servers (mnemonic: <quote>external
         servers</quote>).
         If <replaceable class="parameter">pattern</replaceable> is
         specified, only those servers whose name matches the pattern
-        are listed.  If the form <literal>\des+</literal> is used, a
+        are listed.  If the forms <literal>\des+</literal> or <literal>\describe-foreign-server-verbose</literal> are used, a
         full description of each server is shown, including the
         server's access privileges, type, version, options, and description.
         </para>
@@ -1394,13 +1430,14 @@ testdb=&gt;
 
       <varlistentry>
         <term><literal>\det[+] [ <link linkend="app-psql-patterns"><replaceable class="parameter">pattern</replaceable></link> ]</literal></term>
+        <term><literal>\describe-foreign-table[-verbose] [ <link linkend="app-psql-patterns"><replaceable class="parameter">pattern</replaceable></link> ]</literal></term>
         <listitem>
         <para>
         Lists foreign tables (mnemonic: <quote>external tables</quote>).
         If <replaceable class="parameter">pattern</replaceable> is
         specified, only entries whose table name or schema name matches
-        the pattern are listed.  If the form <literal>\det+</literal>
-        is used, generic options and the foreign table description
+        the pattern are listed.  If the forms <literal>\det+</literal> or <literal>\describe-foreign-table-verbose</literal>
+        are used, generic options and the foreign table description
         are also displayed.
         </para>
         </listitem>
@@ -1409,19 +1446,20 @@ testdb=&gt;
 
       <varlistentry>
         <term><literal>\deu[+] [ <link linkend="app-psql-patterns"><replaceable class="parameter">pattern</replaceable></link> ]</literal></term>
+        <term><literal>\describe-user-mapping[-verbose] [ <link linkend="app-psql-patterns"><replaceable class="parameter">pattern</replaceable></link> ]</literal></term>
         <listitem>
         <para>
         Lists user mappings (mnemonic: <quote>external
         users</quote>).
         If <replaceable class="parameter">pattern</replaceable> is
         specified, only those mappings whose user names match the
-        pattern are listed.  If the form <literal>\deu+</literal> is
+        pattern are listed.  If the forms <literal>\deu+</literal> or <literal>\describe-user-mapping-verboze</literal> are
         used, additional information about each mapping is shown.
         </para>
 
         <caution>
         <para>
-        <literal>\deu+</literal> might also display the user name and
+        <literal>\deu+</literal> and <literal>\describe-user-mapping-verboze</literal> might also display the user name and
         password of the remote user, so care should be taken not to
         disclose them.
         </para>
@@ -1432,14 +1470,15 @@ testdb=&gt;
 
       <varlistentry>
         <term><literal>\dew[+] [ <link linkend="app-psql-patterns"><replaceable class="parameter">pattern</replaceable></link> ]</literal></term>
+        <term><literal>\describe-foreign-data-wrapper[-verbose] [ <link linkend="app-psql-patterns"><replaceable class="parameter">pattern</replaceable></link> ]</literal></term>
         <listitem>
         <para>
         Lists foreign-data wrappers (mnemonic: <quote>external
         wrappers</quote>).
         If <replaceable class="parameter">pattern</replaceable> is
         specified, only those foreign-data wrappers whose name matches
-        the pattern are listed.  If the form <literal>\dew+</literal>
-        is used, the access privileges, options, and description of the
+        the pattern are listed.  If the forms <literal>\dew+</literal> or <literal>\describe-foreign-data-wrapper-verbose</literal>
+        are used, the access privileges, options, and description of the
         foreign-data wrapper are also shown.
         </para>
         </listitem>
@@ -1448,25 +1487,37 @@ testdb=&gt;
 
       <varlistentry>
         <term><literal>\df[anptwS+] [ <link linkend="app-psql-patterns"><replaceable class="parameter">pattern</replaceable></link> ]</literal></term>
+        <term><literal>\describe-function[-system][-verbose] [ <link linkend="app-psql-patterns"><replaceable class="parameter">pattern</replaceable></link> ]</literal></term>
+        <term><literal>\describe-normal-function[-system][-verbose] [ <link linkend="app-psql-patterns"><replaceable class="parameter">pattern</replaceable></link> ]</literal></term>
+        <term><literal>\describe-procedure[-system][-verbose] [ <link linkend="app-psql-patterns"><replaceable class="parameter">pattern</replaceable></link> ]</literal></term>
+        <term><literal>\describe-aggregate-function[-system][-verbose] [ <link linkend="app-psql-patterns"><replaceable class="parameter">pattern</replaceable></link> ]</literal></term>
+        <term><literal>\describe-trigger-function[-system][-verbose] [ <link linkend="app-psql-patterns"><replaceable class="parameter">pattern</replaceable></link> ]</literal></term>
+        <term><literal>\describe-window-function[-system][-verbose] [ <link linkend="app-psql-patterns"><replaceable class="parameter">pattern</replaceable></link> ]</literal></term>
 
         <listitem>
         <para>
         Lists functions, together with their result data types, argument data
         types, and function types, which are classified as <quote>agg</quote>
         (aggregate), <quote>normal</quote>, <quote>procedure</quote>, <quote>trigger</quote>, or <quote>window</quote>.
-        To display only functions
+        In the short form, to display only functions
         of specific type(s), add the corresponding letters <literal>a</literal>,
         <literal>n</literal>, <literal>p</literal>, <literal>t</literal>, or <literal>w</literal> to the command.
         If <replaceable
         class="parameter">pattern</replaceable> is specified, only
         functions whose names match the pattern are shown.
         By default, only user-created
-        objects are shown; supply a pattern or the <literal>S</literal>
+        objects are shown; supply a pattern or the <literal>S</literal>/<literal>-system</literal>
         modifier to include system objects.
-        If the form <literal>\df+</literal> is used, additional information
+        If the form <literal>\df+</literal> or the <literal>-verbose</literal> suffix is used, additional information
         about each function is shown, including volatility,
         parallel safety, owner, security classification, access privileges,
         language, source code and description.
+        <literal>\describe-function</literal> is the equivalent of <literal>\df</literal>.
+        <literal>\describe-normal-function</literal> is the equivalent of <literal>\dff</literal>.
+        <literal>\describe-procedure</literal> is the equivalent of <literal>\dfp</literal>.
+        <literal>\describe-aggregate-function</literal> is the equivalent of <literal>\dfa</literal>.
+        <literal>\describe-trigger-function</literal> is the equivalent of <literal>\dft</literal>.
+        <literal>\describe-window-function</literal> is the equivalent of <literal>\dfw</literal>.
         </para>
 
         <tip>
@@ -1482,12 +1533,13 @@ testdb=&gt;
 
       <varlistentry>
         <term><literal>\dF[+] [ <link linkend="app-psql-patterns"><replaceable class="parameter">pattern</replaceable></link> ]</literal></term>
+        <term><literal>\describe-text-search-configuration[-verbose] [ <link linkend="app-psql-patterns"><replaceable class="parameter">pattern</replaceable></link> ]</literal></term>
         <listitem>
         <para>
          Lists text search configurations.
          If <replaceable class="parameter">pattern</replaceable> is specified,
          only configurations whose names match the pattern are shown.
-         If the form <literal>\dF+</literal> is used, a full description of
+         If the form <literal>\dF+</literal> or <literal>\describe-text-search-configuration-verbose</literal> 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.
         </para>
@@ -1496,12 +1548,13 @@ testdb=&gt;
 
       <varlistentry>
         <term><literal>\dFd[+] [ <link linkend="app-psql-patterns"><replaceable class="parameter">pattern</replaceable></link> ]</literal></term>
+        <term><literal>\describe-text-search-dictionary[-verbose] [ <link linkend="app-psql-patterns"><replaceable class="parameter">pattern</replaceable></link> ]</literal></term>
         <listitem>
         <para>
          Lists text search dictionaries.
          If <replaceable class="parameter">pattern</replaceable> is specified,
          only dictionaries whose names match the pattern are shown.
-         If the form <literal>\dFd+</literal> is used, additional information
+         If the form <literal>\dFd+</literal> or <literal>\describe-text-search-dictionary-verbose</literal> is used, additional information
          is shown about each selected dictionary, including the underlying
          text search template and the option values.
         </para>
@@ -1510,12 +1563,13 @@ testdb=&gt;
 
       <varlistentry>
         <term><literal>\dFp[+] [ <link linkend="app-psql-patterns"><replaceable class="parameter">pattern</replaceable></link> ]</literal></term>
+        <term><literal>\describe-text-search-parser[-verbose] [ <link linkend="app-psql-patterns"><replaceable class="parameter">pattern</replaceable></link> ]</literal></term>
         <listitem>
         <para>
          Lists text search parsers.
          If <replaceable class="parameter">pattern</replaceable> is specified,
          only parsers whose names match the pattern are shown.
-         If the form <literal>\dFp+</literal> is used, a full description of
+         If the form <literal>\dFp+</literal> or <literal>\describe-text-search-parser-verbose</literal> is used, a full description of
          each parser is shown, including the underlying functions and the
          list of recognized token types.
         </para>
@@ -1524,12 +1578,13 @@ testdb=&gt;
 
       <varlistentry>
         <term><literal>\dFt[+] [ <link linkend="app-psql-patterns"><replaceable class="parameter">pattern</replaceable></link> ]</literal></term>
+        <term><literal>\describe-text-search-template[-verbose] [ <link linkend="app-psql-patterns"><replaceable class="parameter">pattern</replaceable></link> ]</literal></term>
         <listitem>
         <para>
          Lists text search templates.
          If <replaceable class="parameter">pattern</replaceable> is specified,
          only templates whose names match the pattern are shown.
-         If the form <literal>\dFt+</literal> is used, additional information
+         If the form <literal>\dFt+</literal> or <literal>\describe-text-search-template-verbose</literal> is used, additional information
          is shown about each template, including the underlying function names.
         </para>
         </listitem>
@@ -1538,6 +1593,7 @@ testdb=&gt;
 
       <varlistentry>
         <term><literal>\dg[S+] [ <link linkend="app-psql-patterns"><replaceable class="parameter">pattern</replaceable></link> ]</literal></term>
+        <term><literal>\describe-role[-system][-verbose] [ <link linkend="app-psql-patterns"><replaceable class="parameter">pattern</replaceable></link> ]</literal></term>
         <listitem>
         <para>
         Lists database roles.
@@ -1545,10 +1601,10 @@ testdb=&gt;
         unified into <quote>roles</quote>, this command is now equivalent to
         <literal>\du</literal>.)
         By default, only user-created roles are shown; supply the
-        <literal>S</literal> modifier to include system roles.
+        <literal>S</literal> or <literal>-system</literal> modifier to include system roles.
         If <replaceable class="parameter">pattern</replaceable> is specified,
         only those roles whose names match the pattern are listed.
-        If the form <literal>\dg+</literal> is used, additional information
+        If the suffix <literal>+</literal> or <literal>-verbose></literal> is specified, additional information
         is shown about each role; currently this adds the comment for each
         role.
         </para>
@@ -1568,14 +1624,15 @@ testdb=&gt;
 
       <varlistentry>
         <term><literal>\dL[S+] [ <link linkend="app-psql-patterns"><replaceable class="parameter">pattern</replaceable></link> ]</literal></term>
+        <term><literal>\describe-procedural-language[-system][-verbose] [ <link linkend="app-psql-patterns"><replaceable class="parameter">pattern</replaceable></link> ]</literal></term>
         <listitem>
         <para>
         Lists procedural languages. If <replaceable
         class="parameter">pattern</replaceable>
         is specified, only languages whose names match the pattern are listed.
         By default, only user-created languages
-        are shown; supply the <literal>S</literal> modifier to include system
-        objects. If <literal>+</literal> is appended to the command name, each
+        are shown; supply the <literal>S</literal> or <literal>-system</literal> modifier to include system
+        objects. If <literal>+</literal> or <literal>-verbose</literal> is appended to the command name, each
         language is listed with its call handler, validator, access privileges,
         and whether it is a system object.
         </para>
@@ -1585,6 +1642,8 @@ testdb=&gt;
 
       <varlistentry>
         <term><literal>\dn[S+] [ <link linkend="app-psql-patterns"><replaceable class="parameter">pattern</replaceable></link> ]</literal></term>
+        <term><literal>\describe-schema[-system][-verbose] [ <link linkend="app-psql-patterns"><replaceable class="parameter">pattern</replaceable></link> ]</literal></term>
+        <term><literal>\describe-namespace[-system][-verbose] [ <link linkend="app-psql-patterns"><replaceable class="parameter">pattern</replaceable></link> ]</literal></term>
 
         <listitem>
         <para>
@@ -1592,8 +1651,8 @@ testdb=&gt;
         class="parameter">pattern</replaceable>
         is specified, only schemas whose names match the pattern are listed.
         By default, only user-created objects are shown; supply a
-        pattern or the <literal>S</literal> modifier to include system objects.
-        If <literal>+</literal> is appended to the command name, each object
+        pattern or the <literal>S</literal> or <literal>-system</literal> modifier to include system objects.
+        If <literal>+</literal> (or <literal>-verbose</literal> is appended to the command name, each object
         is listed with its associated permissions and description, if any.
         </para>
         </listitem>
@@ -1602,15 +1661,16 @@ testdb=&gt;
 
       <varlistentry>
         <term><literal>\do[S+] [ <link linkend="app-psql-patterns"><replaceable class="parameter">pattern</replaceable></link> ]</literal></term>
+        <term><literal>\describe-operator[-system][-verbose] [ <link linkend="app-psql-patterns"><replaceable class="parameter">pattern</replaceable></link> ]</literal></term>
         <listitem>
         <para>
         Lists operators with their operand and result types.
         If <replaceable class="parameter">pattern</replaceable> is
         specified, only operators whose names match the pattern are listed.
         By default, only user-created objects are shown; supply a
-        pattern or the <literal>S</literal> modifier to include system
+        pattern or the <literal>S</literal> or <literal>-system</literal> modifier to include system
         objects.
-        If <literal>+</literal> is appended to the command name,
+        If <literal>+</literal> or <literal>-verbose</literal> is appended to the command name,
         additional information about each operator is shown, currently just
         the name of the underlying function.
         </para>
@@ -1620,14 +1680,15 @@ testdb=&gt;
 
       <varlistentry>
         <term><literal>\dO[S+] [ <link linkend="app-psql-patterns"><replaceable class="parameter">pattern</replaceable></link> ]</literal></term>
+        <term><literal>\describe-collation[-system][-verbose] [ <link linkend="app-psql-patterns"><replaceable class="parameter">pattern</replaceable></link> ]</literal></term>
         <listitem>
         <para>
         Lists collations.
         If <replaceable class="parameter">pattern</replaceable> is
         specified, only collations whose names match the pattern are
         listed.  By default, only user-created objects are shown;
-        supply a pattern or the <literal>S</literal> modifier to
-        include system objects.  If <literal>+</literal> is appended
+        supply a pattern or the <literal>S</literal> or <literal>-system</literal> modifier to
+        include system objects.  If <literal>+</literal> or <literal>-verbose</literal> 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=&gt;
 
       <varlistentry>
         <term><literal>\dp [ <link linkend="app-psql-patterns"><replaceable class="parameter">pattern</replaceable></link> ]</literal></term>
+        <term><literal>\describe-privilege [ <link linkend="app-psql-patterns"><replaceable class="parameter">pattern</replaceable></link> ]</literal></term>
         <listitem>
         <para>
         Lists tables, views and sequences with their
@@ -1661,6 +1723,7 @@ testdb=&gt;
 
       <varlistentry>
         <term><literal>\drds [ <link linkend="app-psql-patterns"><replaceable class="parameter">role-pattern</replaceable></link> [ <link linkend="app-psql-patterns"><replaceable class="parameter">database-pattern</replaceable></link> ] ]</literal></term>
+        <term><literal>\describe-defined-configuration-setting [ <link linkend="app-psql-patterns"><replaceable class="parameter">role-pattern</replaceable></link> [ <link linkend="app-psql-patterns"><replaceable class="parameter">database-pattern</replaceable></link> ] ]</literal></term>
         <listitem>
         <para>
         Lists defined configuration settings.  These settings can be
@@ -1683,13 +1746,14 @@ testdb=&gt;
 
       <varlistentry>
         <term><literal>\dRp[+] [ <link linkend="app-psql-patterns"><replaceable class="parameter">pattern</replaceable></link> ]</literal></term>
+        <term><literal>\describe-replication-publication[-verbose] [ <link linkend="app-psql-patterns"><replaceable class="parameter">pattern</replaceable></link> ]</literal></term>
         <listitem>
         <para>
         Lists replication publications.
         If <replaceable class="parameter">pattern</replaceable> is
         specified, only those publications whose names match the pattern are
         listed.
-        If <literal>+</literal> is appended to the command name, the tables
+        If <literal>+</literal> or <literal>-verbose</literal> is appended to the command name, the tables
         associated with each publication are shown as well.
         </para>
         </listitem>
@@ -1697,13 +1761,14 @@ testdb=&gt;
 
       <varlistentry>
         <term><literal>\dRs[+] [ <link linkend="app-psql-patterns"><replaceable class="parameter">pattern</replaceable></link> ]</literal></term>
+        <term><literal>\describe-replication-subscription[-verbose] [ <link linkend="app-psql-patterns"><replaceable class="parameter">pattern</replaceable></link> ]</literal></term>
         <listitem>
         <para>
         Lists replication subscriptions.
         If <replaceable class="parameter">pattern</replaceable> is
         specified, only those subscriptions whose names match the pattern are
         listed.
-        If <literal>+</literal> is appended to the command name, additional
+        If <literal>+</literal> or <literal>-verbose</literal> is appended to the command name, additional
         properties of the subscriptions are shown.
         </para>
         </listitem>
@@ -1711,16 +1776,17 @@ testdb=&gt;
 
       <varlistentry>
         <term><literal>\dT[S+] [ <link linkend="app-psql-patterns"><replaceable class="parameter">pattern</replaceable></link> ]</literal></term>
+        <term><literal>\describe-type[-system][-verbose] [ <link linkend="app-psql-patterns"><replaceable class="parameter">pattern</replaceable></link> ]</literal></term>
         <listitem>
         <para>
         Lists data types.
         If <replaceable class="parameter">pattern</replaceable> is
         specified, only types whose names match the pattern are listed.
-        If <literal>+</literal> is appended to the command name, each type is
+        If <literal>+</literal> or <literal>-verbose</literal> is appended to the command name, each type is
         listed with its internal name and size, its allowed values
         if it is an <type>enum</type> type, and its associated permissions.
         By default, only user-created objects are shown;  supply a
-        pattern or the <literal>S</literal> modifier to include system
+        pattern or the <literal>S</literal> or <literal>-system</literal> modifier to include system
         objects.
         </para>
         </listitem>
@@ -1728,6 +1794,7 @@ testdb=&gt;
 
       <varlistentry>
         <term><literal>\du[S+] [ <link linkend="app-psql-patterns"><replaceable class="parameter">pattern</replaceable></link> ]</literal></term>
+        <term><literal>\describe-role[S+] [ <link linkend="app-psql-patterns"><replaceable class="parameter">pattern</replaceable></link> ]</literal></term>
         <listitem>
         <para>
         Lists database roles.
@@ -1735,10 +1802,10 @@ testdb=&gt;
         unified into <quote>roles</quote>, this command is now equivalent to
         <literal>\dg</literal>.)
         By default, only user-created roles are shown; supply the
-        <literal>S</literal> modifier to include system roles.
+        <literal>S</literal> or <literal>-system</literal> modifier to include system roles.
         If <replaceable class="parameter">pattern</replaceable> is specified,
         only those roles whose names match the pattern are listed.
-        If the form <literal>\du+</literal> is used, additional information
+        If the suffix <literal>+</literal> or <literal>-verbose</literal> is used, additional information
         is shown about each role; currently this adds the comment for each
         role.
         </para>
@@ -1747,13 +1814,14 @@ testdb=&gt;
 
       <varlistentry>
         <term><literal>\dx[+] [ <link linkend="app-psql-patterns"><replaceable class="parameter">pattern</replaceable></link> ]</literal></term>
+        <term><literal>\describe-extension[-verbose] [ <link linkend="app-psql-patterns"><replaceable class="parameter">pattern</replaceable></link> ]</literal></term>
         <listitem>
         <para>
         Lists installed extensions.
         If <replaceable class="parameter">pattern</replaceable>
         is specified, only those extensions whose names match the pattern
         are listed.
-        If the form <literal>\dx+</literal> is used, all the objects belonging
+        If the suffix <literal>+</literal> or <literal>-verbose</literal> is used, all the objects belonging
         to each matching extension are listed.
         </para>
         </listitem>
@@ -1761,15 +1829,24 @@ testdb=&gt;
 
       <varlistentry>
         <term><literal>\dy[+] [ <link linkend="app-psql-patterns"><replaceable class="parameter">pattern</replaceable></link> ]</literal></term>
+        <term><literal>\describe-event-trigger[-verbose] [ <link linkend="app-psql-patterns"><replaceable class="parameter">pattern</replaceable></link> ]</literal></term>
         <listitem>
         <para>
         Lists event triggers.
         If <replaceable class="parameter">pattern</replaceable>
         is specified, only those event triggers whose names match the pattern
         are listed.
-        If <literal>+</literal> is appended to the command name, each object
+        If <literal>+</literal> or <literal>-verbose</literal> is appended to the command name, each object
         is listed with its associated description.
         </para>
+
+        <tip>
+        <para>
+        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
+        <literal>\describe</literal> commands.
+        </para>
+        </tip>
         </listitem>
       </varlistentry>
 
@@ -2305,7 +2382,7 @@ SELECT
         character set encodings, and access privileges.
         If <replaceable class="parameter">pattern</replaceable> is specified,
         only databases whose names match the pattern are listed.
-        If <literal>+</literal> is appended to the command name, database
+        If <literal>+</literal> (or <literal>-verbose</literal> 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

Reply via email to