]> granicus.if.org Git - postgresql/blobdiff - src/bin/psql/describe.c
Teach psql to display the comments on conversions and domains.
[postgresql] / src / bin / psql / describe.c
index bab67174a255c38e1978cfd0d66442058d5a4e96..5587721ea8f0c4b040e5dfe833849f012a4896fb 100644 (file)
@@ -1159,7 +1159,7 @@ describeOneTableDetails(const char *schemaname,
                                                  "c.relpersistence\n"
                                                  "FROM pg_catalog.pg_class c\n "
                   "LEFT JOIN pg_catalog.pg_class tc ON (c.reltoastrelid = tc.oid)\n"
-                                                 "WHERE c.oid = '%s'\n",
+                                                 "WHERE c.oid = '%s';",
                                                  (verbose ?
                                                   "pg_catalog.array_to_string(c.reloptions || "
                                                   "array(select 'toast.' || x from pg_catalog.unnest(tc.reloptions) x), ', ')\n"
@@ -1175,7 +1175,7 @@ describeOneTableDetails(const char *schemaname,
                                                  "CASE WHEN c.reloftype = 0 THEN '' ELSE c.reloftype::pg_catalog.regtype::pg_catalog.text END\n"
                                                  "FROM pg_catalog.pg_class c\n "
                   "LEFT JOIN pg_catalog.pg_class tc ON (c.reltoastrelid = tc.oid)\n"
-                                                 "WHERE c.oid = '%s'\n",
+                                                 "WHERE c.oid = '%s';",
                                                  (verbose ?
                                                   "pg_catalog.array_to_string(c.reloptions || "
                                                   "array(select 'toast.' || x from pg_catalog.unnest(tc.reloptions) x), ', ')\n"
@@ -1190,7 +1190,7 @@ describeOneTableDetails(const char *schemaname,
                                                  "%s, c.reltablespace\n"
                                                  "FROM pg_catalog.pg_class c\n "
                   "LEFT JOIN pg_catalog.pg_class tc ON (c.reltoastrelid = tc.oid)\n"
-                                                 "WHERE c.oid = '%s'\n",
+                                                 "WHERE c.oid = '%s';",
                                                  (verbose ?
                                                   "pg_catalog.array_to_string(c.reloptions || "
                                                   "array(select 'toast.' || x from pg_catalog.unnest(tc.reloptions) x), ', ')\n"
@@ -1203,7 +1203,7 @@ describeOneTableDetails(const char *schemaname,
                                          "SELECT relchecks, relkind, relhasindex, relhasrules, "
                                                  "reltriggers <> 0, relhasoids, "
                                                  "%s, reltablespace\n"
-                                                 "FROM pg_catalog.pg_class WHERE oid = '%s'",
+                                                 "FROM pg_catalog.pg_class WHERE oid = '%s';",
                                                  (verbose ?
                                         "pg_catalog.array_to_string(reloptions, E', ')" : "''"),
                                                  oid);
@@ -1214,7 +1214,7 @@ describeOneTableDetails(const char *schemaname,
                                          "SELECT relchecks, relkind, relhasindex, relhasrules, "
                                                  "reltriggers <> 0, relhasoids, "
                                                  "'', reltablespace\n"
-                                                 "FROM pg_catalog.pg_class WHERE oid = '%s'",
+                                                 "FROM pg_catalog.pg_class WHERE oid = '%s';",
                                                  oid);
        }
        else
@@ -1223,7 +1223,7 @@ describeOneTableDetails(const char *schemaname,
                                          "SELECT relchecks, relkind, relhasindex, relhasrules, "
                                                  "reltriggers <> 0, relhasoids, "
                                                  "'', ''\n"
-                                                 "FROM pg_catalog.pg_class WHERE oid = '%s'",
+                                                 "FROM pg_catalog.pg_class WHERE oid = '%s';",
                                                  oid);
        }
 
@@ -1265,7 +1265,7 @@ describeOneTableDetails(const char *schemaname,
        {
                printfPQExpBuffer(&buf, "SELECT * FROM %s", fmtId(schemaname));
                /* must be separate because fmtId isn't reentrant */
-               appendPQExpBuffer(&buf, ".%s", fmtId(relationname));
+               appendPQExpBuffer(&buf, ".%s;", fmtId(relationname));
 
                res = PSQLexec(buf.data, false);
                if (!res)
@@ -1281,24 +1281,46 @@ describeOneTableDetails(const char *schemaname,
                res = NULL;
        }
 
-       /* Get column info */
+       /*
+        * Get column info
+        *
+        * You need to modify value of "firstvcol" which willbe defined below if
+        * you are adding column(s) preceding to verbose-only columns.
+        */
        printfPQExpBuffer(&buf, "SELECT a.attname,");
        appendPQExpBuffer(&buf, "\n  pg_catalog.format_type(a.atttypid, a.atttypmod),"
                                          "\n  (SELECT substring(pg_catalog.pg_get_expr(d.adbin, d.adrelid) for 128)"
                                          "\n   FROM pg_catalog.pg_attrdef d"
                                          "\n   WHERE d.adrelid = a.attrelid AND d.adnum = a.attnum AND a.atthasdef),"
-                                         "\n  a.attnotnull, a.attnum");
+                                         "\n  a.attnotnull, a.attnum,");
        if (pset.sversion >= 90100)
-               appendPQExpBuffer(&buf, ",\n  (SELECT collname FROM pg_collation WHERE oid = a.attcollation AND collname <> 'default') AS attcollation");
+               appendPQExpBuffer(&buf, "\n  (SELECT c.collname FROM pg_catalog.pg_collation c, pg_catalog.pg_type t\n"
+                                                 "   WHERE c.oid = a.attcollation AND t.oid = a.atttypid AND a.attcollation <> t.typcollation) AS attcollation");
        else
-               appendPQExpBuffer(&buf, ",\n  NULL AS attcollation");
+               appendPQExpBuffer(&buf, "\n  NULL AS attcollation");
        if (tableinfo.relkind == 'i')
                appendPQExpBuffer(&buf, ",\n  pg_catalog.pg_get_indexdef(a.attrelid, a.attnum, TRUE) AS indexdef");
+       else
+               appendPQExpBuffer(&buf, ",\n  NULL AS indexdef");
+       if (tableinfo.relkind == 'f' && pset.sversion >= 90200)
+               appendPQExpBuffer(&buf, ",\n  a.attfdwoptions");
+       else
+               appendPQExpBuffer(&buf, ",\n  NULL AS attfdwoptions");
        if (verbose)
-               appendPQExpBuffer(&buf, ",\n  a.attstorage, pg_catalog.col_description(a.attrelid, a.attnum)");
+       {
+               appendPQExpBuffer(&buf, ",\n  a.attstorage");
+               /*
+                * In 9.0+, we have column comments for: relations, views, composite
+                * types, and foreign tables (c.f. CommentObject() in comment.c).
+                */
+               if (tableinfo.relkind == 'r' || tableinfo.relkind == 'v' ||
+                       tableinfo.relkind == 'f' || tableinfo.relkind == 'c')
+                       appendPQExpBuffer(&buf, ", pg_catalog.col_description(a.attrelid, a.attnum)");
+       }
+
        appendPQExpBuffer(&buf, "\nFROM pg_catalog.pg_attribute a");
        appendPQExpBuffer(&buf, "\nWHERE a.attrelid = '%s' AND a.attnum > 0 AND NOT a.attisdropped", oid);
-       appendPQExpBuffer(&buf, "\nORDER BY a.attnum");
+       appendPQExpBuffer(&buf, "\nORDER BY a.attnum;");
 
        res = PSQLexec(buf.data, false);
        if (!res)
@@ -1362,7 +1384,7 @@ describeOneTableDetails(const char *schemaname,
        cols = 2;
 
        if (tableinfo.relkind == 'r' || tableinfo.relkind == 'v' ||
-               tableinfo.relkind == 'f')
+               tableinfo.relkind == 'f' || tableinfo.relkind == 'c')
        {
                show_modifiers = true;
                headers[cols++] = gettext_noop("Modifiers");
@@ -1375,10 +1397,16 @@ describeOneTableDetails(const char *schemaname,
        if (tableinfo.relkind == 'i')
                headers[cols++] = gettext_noop("Definition");
 
+       if (tableinfo.relkind == 'f' && pset.sversion >= 90200)
+               headers[cols++] = gettext_noop("Options");
+
        if (verbose)
        {
                headers[cols++] = gettext_noop("Storage");
-               headers[cols++] = gettext_noop("Description");
+               /* Column comments, if the relkind supports this feature. */
+               if (tableinfo.relkind == 'r' || tableinfo.relkind == 'v' ||
+                       tableinfo.relkind == 'c' || tableinfo.relkind == 'f')
+                       headers[cols++] = gettext_noop("Description");
        }
 
        printTableInit(&cont, &myopt, title.data, cols, numrows);
@@ -1393,7 +1421,7 @@ describeOneTableDetails(const char *schemaname,
                PGresult   *result;
 
                printfPQExpBuffer(&buf,
-                         "SELECT pg_catalog.pg_get_viewdef('%s'::pg_catalog.oid, true)",
+                         "SELECT pg_catalog.pg_get_viewdef('%s'::pg_catalog.oid, true);",
                                                  oid);
                result = PSQLexec(buf.data, false);
                if (!result)
@@ -1457,10 +1485,14 @@ describeOneTableDetails(const char *schemaname,
                if (tableinfo.relkind == 'i')
                        printTableAddCell(&cont, PQgetvalue(res, i, 6), false, false);
 
+               /* FDW options for foreign table column, only for 9.2 or later */
+               if (tableinfo.relkind == 'f' && pset.sversion >= 90200)
+                       printTableAddCell(&cont, PQgetvalue(res, i, 7), false, false);
+
                /* Storage and Description */
                if (verbose)
                {
-                       int                     firstvcol = (tableinfo.relkind == 'i' ? 7 : 6);
+                       int                     firstvcol = 8;
                        char       *storage = PQgetvalue(res, i, firstvcol);
 
                        /* these strings are literal in our syntax, so not translated. */
@@ -1470,8 +1502,11 @@ describeOneTableDetails(const char *schemaname,
                                                                                (storage[0] == 'e' ? "external" :
                                                                                 "???")))),
                                                          false, false);
-                       printTableAddCell(&cont, PQgetvalue(res, i, firstvcol + 1),
-                                                         false, false);
+                       /* Column comments, if the relkind supports this feature. */
+                       if (tableinfo.relkind == 'r' || tableinfo.relkind == 'v' ||
+                               tableinfo.relkind == 'c' || tableinfo.relkind == 'f')
+                               printTableAddCell(&cont, PQgetvalue(res, i, firstvcol + 1),
+                                                                 false, false);
                }
        }
 
@@ -1508,7 +1543,7 @@ describeOneTableDetails(const char *schemaname,
                                          "pg_catalog.pg_get_expr(i.indpred, i.indrelid, true)\n"
                                                  "FROM pg_catalog.pg_index i, pg_catalog.pg_class c, pg_catalog.pg_class c2, pg_catalog.pg_am a\n"
                  "WHERE i.indexrelid = c.oid AND c.oid = '%s' AND c.relam = a.oid\n"
-                                                 "AND i.indrelid = c2.oid",
+                                                 "AND i.indrelid = c2.oid;",
                                                  oid);
 
                result = PSQLexec(buf.data, false);
@@ -1579,7 +1614,7 @@ describeOneTableDetails(const char *schemaname,
                        printfPQExpBuffer(&buf,
                                                          "SELECT r.rulename, trim(trailing ';' from pg_catalog.pg_get_ruledef(r.oid, true))\n"
                                                          "FROM pg_catalog.pg_rewrite r\n"
-                       "WHERE r.ev_class = '%s' AND r.rulename != '_RETURN' ORDER BY 1",
+                       "WHERE r.ev_class = '%s' AND r.rulename != '_RETURN' ORDER BY 1;",
                                                          oid);
                        result = PSQLexec(buf.data, false);
                        if (!result)
@@ -1636,7 +1671,7 @@ describeOneTableDetails(const char *schemaname,
                                                                  "  LEFT JOIN pg_catalog.pg_constraint con ON (conrelid = i.indrelid AND conindid = i.indexrelid AND contype IN ('p','u','x'))\n");
                        appendPQExpBuffer(&buf,
                                                          "WHERE c.oid = '%s' AND c.oid = i.indrelid AND i.indexrelid = c2.oid\n"
-                         "ORDER BY i.indisprimary DESC, i.indisunique DESC, c2.relname",
+                         "ORDER BY i.indisprimary DESC, i.indisunique DESC, c2.relname;",
                                                          oid);
                        result = PSQLexec(buf.data, false);
                        if (!result)
@@ -1716,7 +1751,7 @@ describeOneTableDetails(const char *schemaname,
                                                          "SELECT r.conname, "
                                                          "pg_catalog.pg_get_constraintdef(r.oid, true)\n"
                                                          "FROM pg_catalog.pg_constraint r\n"
-                                  "WHERE r.conrelid = '%s' AND r.contype = 'c'\nORDER BY 1",
+                                  "WHERE r.conrelid = '%s' AND r.contype = 'c'\nORDER BY 1;",
                                                          oid);
                        result = PSQLexec(buf.data, false);
                        if (!result)
@@ -1745,11 +1780,9 @@ describeOneTableDetails(const char *schemaname,
                {
                        printfPQExpBuffer(&buf,
                                                          "SELECT conname,\n"
-                          "  pg_catalog.pg_get_constraintdef(r.oid, true) as condef\n");
-                       if (pset.sversion >= 90100)
-                               appendPQExpBuffer(&buf, "  ,convalidated\n");
-                       appendPQExpBuffer(&buf, "FROM pg_catalog.pg_constraint r\n"
-                                       "WHERE r.conrelid = '%s' AND r.contype = 'f' ORDER BY 1",
+                                "  pg_catalog.pg_get_constraintdef(r.oid, true) as condef\n"
+                                                         "FROM pg_catalog.pg_constraint r\n"
+                                       "WHERE r.conrelid = '%s' AND r.contype = 'f' ORDER BY 1;",
                                                          oid);
                        result = PSQLexec(buf.data, false);
                        if (!result)
@@ -1767,9 +1800,6 @@ describeOneTableDetails(const char *schemaname,
                                                                          PQgetvalue(result, i, 0),
                                                                          PQgetvalue(result, i, 1));
 
-                                       if (pset.sversion >= 90100 && strcmp(PQgetvalue(result, i, 2), "f") == 0)
-                                               appendPQExpBuffer(&buf, " NOT VALID");
-
                                        printTableAddFooter(&cont, buf.data);
                                }
                        }
@@ -1783,7 +1813,7 @@ describeOneTableDetails(const char *schemaname,
                                                   "SELECT conname, conrelid::pg_catalog.regclass,\n"
                                 "  pg_catalog.pg_get_constraintdef(c.oid, true) as condef\n"
                                                          "FROM pg_catalog.pg_constraint c\n"
-                                  "WHERE c.confrelid = '%s' AND c.contype = 'f' ORDER BY 1",
+                                  "WHERE c.confrelid = '%s' AND c.contype = 'f' ORDER BY 1;",
                                                          oid);
                        result = PSQLexec(buf.data, false);
                        if (!result)
@@ -1816,7 +1846,7 @@ describeOneTableDetails(const char *schemaname,
                                                                  "SELECT r.rulename, trim(trailing ';' from pg_catalog.pg_get_ruledef(r.oid, true)), "
                                                                  "ev_enabled\n"
                                                                  "FROM pg_catalog.pg_rewrite r\n"
-                                                                 "WHERE r.ev_class = '%s' ORDER BY 1",
+                                                                 "WHERE r.ev_class = '%s' ORDER BY 1;",
                                                                  oid);
                        }
                        else
@@ -1825,7 +1855,7 @@ describeOneTableDetails(const char *schemaname,
                                                                  "SELECT r.rulename, trim(trailing ';' from pg_catalog.pg_get_ruledef(r.oid, true)), "
                                                                  "'O'::char AS ev_enabled\n"
                                                                  "FROM pg_catalog.pg_rewrite r\n"
-                                                                 "WHERE r.ev_class = '%s' ORDER BY 1",
+                                                                 "WHERE r.ev_class = '%s' ORDER BY 1;",
                                                                  oid);
                        }
                        result = PSQLexec(buf.data, false);
@@ -1931,7 +1961,7 @@ describeOneTableDetails(const char *schemaname,
                                                          "  (SELECT 1 FROM pg_catalog.pg_depend d "
                                                          "   JOIN pg_catalog.pg_constraint c ON (d.refclassid = c.tableoid AND d.refobjid = c.oid) "
                                                          "   WHERE d.classid = t.tableoid AND d.objid = t.oid AND d.deptype = 'i' AND c.contype = 'f'))");
-               appendPQExpBuffer(&buf, "\nORDER BY 1");
+               appendPQExpBuffer(&buf, "\nORDER BY 1;");
 
                result = PSQLexec(buf.data, false);
                if (!result)
@@ -2039,7 +2069,7 @@ describeOneTableDetails(const char *schemaname,
                                                          "SELECT s.srvname\n"
                                                          "FROM pg_catalog.pg_foreign_table f,\n"
                                                          "     pg_catalog.pg_foreign_server s\n"
-                                                         "WHERE f.ftrelid = %s AND s.oid = f.ftserver",
+                                                         "WHERE f.ftrelid = %s AND s.oid = f.ftserver;",
                                                          oid);
                        result = PSQLexec(buf.data, false);
                        if (!result)
@@ -2057,7 +2087,7 @@ describeOneTableDetails(const char *schemaname,
                }
 
                /* print inherited tables */
-               printfPQExpBuffer(&buf, "SELECT c.oid::pg_catalog.regclass FROM pg_catalog.pg_class c, pg_catalog.pg_inherits i WHERE c.oid=i.inhparent AND i.inhrelid = '%s' ORDER BY inhseqno", oid);
+               printfPQExpBuffer(&buf, "SELECT c.oid::pg_catalog.regclass FROM pg_catalog.pg_class c, pg_catalog.pg_inherits i WHERE c.oid=i.inhparent AND i.inhrelid = '%s' ORDER BY inhseqno;", oid);
 
                result = PSQLexec(buf.data, false);
                if (!result)
@@ -2219,7 +2249,7 @@ add_tablespace_footer(printTableContent *const cont, char relkind,
                        initPQExpBuffer(&buf);
                        printfPQExpBuffer(&buf,
                                                          "SELECT spcname FROM pg_catalog.pg_tablespace\n"
-                                                         "WHERE oid = '%u'", tablespace);
+                                                         "WHERE oid = '%u';", tablespace);
                        result = PSQLexec(buf.data, false);
                        if (!result)
                                return;
@@ -2428,7 +2458,7 @@ listDbRoleSettings(const char *pattern, const char *pattern2)
                                                                           NULL, "pg_roles.rolname", NULL, NULL);
                processSQLNamePattern(pset.db, &buf, pattern2, havewhere, false,
                                                          NULL, "pg_database.datname", NULL, NULL);
-               appendPQExpBufferStr(&buf, "ORDER BY role, database");
+               appendPQExpBufferStr(&buf, "ORDER BY role, database;");
        }
        else
        {
@@ -2654,13 +2684,20 @@ listLanguages(const char *pattern, bool verbose, bool showSystem)
        }
 
        appendPQExpBuffer(&buf,
-                                         "\nFROM pg_catalog.pg_language l\n");
+                                         ",\n       d.description AS \"%s\""
+                                         "\nFROM pg_catalog.pg_language l\n"
+                                         "LEFT JOIN pg_catalog.pg_description d\n"
+                                         "  ON d.classoid = l.tableoid AND d.objoid = l.oid\n"
+                                         "  AND d.objsubid = 0\n",
+                                         gettext_noop("Description"));
 
-       processSQLNamePattern(pset.db, &buf, pattern, false, false,
-                                                 NULL, "l.lanname", NULL, NULL);
+       if (pattern)
+               processSQLNamePattern(pset.db, &buf, pattern, false, false,
+                                                         NULL, "l.lanname", NULL, NULL);
 
        if (!showSystem && !pattern)
-               appendPQExpBuffer(&buf, "WHERE lanplcallfoid != 0\n");
+               appendPQExpBuffer(&buf, "WHERE l.lanplcallfoid != 0\n");
+
 
        appendPQExpBuffer(&buf, "ORDER BY 1;");
 
@@ -2686,7 +2723,7 @@ listLanguages(const char *pattern, bool verbose, bool showSystem)
  * Describes domains.
  */
 bool
-listDomains(const char *pattern, bool showSystem)
+listDomains(const char *pattern, bool verbose, bool showSystem)
 {
        PQExpBufferData buf;
        PGresult   *res;
@@ -2698,23 +2735,41 @@ listDomains(const char *pattern, bool showSystem)
                                          "SELECT n.nspname as \"%s\",\n"
                                          "       t.typname as \"%s\",\n"
         "       pg_catalog.format_type(t.typbasetype, t.typtypmod) as \"%s\",\n"
-                                         "       CASE WHEN t.typnotnull AND t.typdefault IS NOT NULL THEN 'not null default '||t.typdefault\n"
-       "            WHEN t.typnotnull AND t.typdefault IS NULL THEN 'not null'\n"
-                                         "            WHEN NOT t.typnotnull AND t.typdefault IS NOT NULL THEN 'default '||t.typdefault\n"
-                                         "            ELSE ''\n"
-                                         "       END as \"%s\",\n"
-                                         "       pg_catalog.array_to_string(ARRAY(\n"
-                                         "         SELECT pg_catalog.pg_get_constraintdef(r.oid, true) FROM pg_catalog.pg_constraint r WHERE t.oid = r.contypid\n"
-                                         "       ), ' ') as \"%s\"\n"
-                                         "FROM pg_catalog.pg_type t\n"
-          "     LEFT JOIN pg_catalog.pg_namespace n ON n.oid = t.typnamespace\n"
-                                         "WHERE t.typtype = 'd'\n",
+                                         "       TRIM(LEADING\n",
                                          gettext_noop("Schema"),
                                          gettext_noop("Name"),
-                                         gettext_noop("Type"),
+                                         gettext_noop("Type"));
+       if (pset.sversion >= 90100)
+               appendPQExpBuffer(&buf,
+                                                 "            COALESCE((SELECT ' collate ' || c.collname FROM pg_catalog.pg_collation c, pg_catalog.pg_type bt\n"
+                                                 "                      WHERE c.oid = t.typcollation AND bt.oid = t.typbasetype AND t.typcollation <> bt.typcollation), '') ||\n");
+       appendPQExpBuffer(&buf,
+          "            CASE WHEN t.typnotnull THEN ' not null' ELSE '' END ||\n"
+                                         "            CASE WHEN t.typdefault IS NOT NULL THEN ' default ' || t.typdefault ELSE '' END\n"
+                                         "       ) as \"%s\",\n"
+                                         "       pg_catalog.array_to_string(ARRAY(\n"
+                                         "         SELECT pg_catalog.pg_get_constraintdef(r.oid, true) FROM pg_catalog.pg_constraint r WHERE t.oid = r.contypid\n"
+                                         "       ), ' ') as \"%s\"",
                                          gettext_noop("Modifier"),
                                          gettext_noop("Check"));
 
+       if (verbose)
+               appendPQExpBuffer(&buf,
+                                                 ",\n       d.description as \"%s\"",
+                                                 gettext_noop("Description"));
+
+       appendPQExpBuffer(&buf,
+                                         "\nFROM pg_catalog.pg_type t\n"
+          "     LEFT JOIN pg_catalog.pg_namespace n ON n.oid = t.typnamespace\n");
+
+       if (verbose)
+               appendPQExpBuffer(&buf,
+                                                 "     LEFT JOIN pg_catalog.pg_description d "
+                                                 "ON d.classoid = t.tableoid AND d.objoid = t.oid "
+                                                 "AND d.objsubid = 0\n");
+
+       appendPQExpBuffer(&buf, "WHERE t.typtype = 'd'\n");
+
        if (!showSystem && !pattern)
                appendPQExpBuffer(&buf, "      AND n.nspname <> 'pg_catalog'\n"
                                                  "      AND n.nspname <> 'information_schema'\n");
@@ -2746,7 +2801,7 @@ listDomains(const char *pattern, bool showSystem)
  * Describes conversions.
  */
 bool
-listConversions(const char *pattern, bool showSystem)
+listConversions(const char *pattern, bool verbose, bool showSystem)
 {
        PQExpBufferData buf;
        PGresult   *res;
@@ -2761,9 +2816,7 @@ listConversions(const char *pattern, bool showSystem)
           "       pg_catalog.pg_encoding_to_char(c.conforencoding) AS \"%s\",\n"
                "       pg_catalog.pg_encoding_to_char(c.contoencoding) AS \"%s\",\n"
                                          "       CASE WHEN c.condefault THEN '%s'\n"
-                                         "       ELSE '%s' END AS \"%s\"\n"
-                          "FROM pg_catalog.pg_conversion c, pg_catalog.pg_namespace n\n"
-                                         "WHERE n.oid = c.connamespace\n",
+                                         "       ELSE '%s' END AS \"%s\"",
                                          gettext_noop("Schema"),
                                          gettext_noop("Name"),
                                          gettext_noop("Source"),
@@ -2771,9 +2824,28 @@ listConversions(const char *pattern, bool showSystem)
                                          gettext_noop("yes"), gettext_noop("no"),
                                          gettext_noop("Default?"));
 
+       if (verbose)
+               appendPQExpBuffer(&buf,
+                                                 ",\n       d.description AS \"%s\"",
+                                                 gettext_noop("Description"));
+
+       appendPQExpBuffer(&buf,
+                                         "\nFROM pg_catalog.pg_conversion c\n"
+                                         "     JOIN pg_catalog.pg_namespace n "
+                                         "ON n.oid = c.connamespace\n");
+
+       if (verbose)
+               appendPQExpBuffer(&buf,
+                                                 "LEFT JOIN pg_catalog.pg_description d "
+                                                 "ON d.classoid = c.tableoid\n"
+                                                 "          AND d.objoid = c.oid "
+                                                 "AND d.objsubid = 0\n");
+
+       appendPQExpBuffer(&buf, "WHERE true\n");
+
        if (!showSystem && !pattern)
-               appendPQExpBuffer(&buf, "      AND n.nspname <> 'pg_catalog'\n"
-                                                 "      AND n.nspname <> 'information_schema'\n");
+               appendPQExpBuffer(&buf, "  AND n.nspname <> 'pg_catalog'\n"
+                                                 "  AND n.nspname <> 'information_schema'\n");
 
        processSQLNamePattern(pset.db, &buf, pattern, true, false,
                                                  "n.nspname", "c.conname", NULL,
@@ -2803,7 +2875,7 @@ listConversions(const char *pattern, bool showSystem)
  * Describes casts.
  */
 bool
-listCasts(const char *pattern)
+listCasts(const char *pattern, bool verbose)
 {
        PQExpBufferData buf;
        PGresult   *res;
@@ -2827,7 +2899,21 @@ listCasts(const char *pattern)
                                          "       CASE WHEN c.castcontext = 'e' THEN '%s'\n"
                                          "            WHEN c.castcontext = 'a' THEN '%s'\n"
                                          "            ELSE '%s'\n"
-                                         "       END as \"%s\"\n"
+                                         "       END as \"%s\"",
+                                         gettext_noop("Source type"),
+                                         gettext_noop("Target type"),
+                                         gettext_noop("Function"),
+                                         gettext_noop("no"),
+                                         gettext_noop("in assignment"),
+                                         gettext_noop("yes"),
+                                         gettext_noop("Implicit?"));
+
+       if (verbose)
+               appendPQExpBuffer(&buf,
+                                                 ",\n       d.description AS \"%s\"\n",
+                                                 gettext_noop("Description"));
+
+       appendPQExpBuffer(&buf,
                                 "FROM pg_catalog.pg_cast c LEFT JOIN pg_catalog.pg_proc p\n"
                                          "     ON c.castfunc = p.oid\n"
                                          "     LEFT JOIN pg_catalog.pg_type ts\n"
@@ -2837,13 +2923,15 @@ listCasts(const char *pattern)
                                          "     LEFT JOIN pg_catalog.pg_type tt\n"
                                          "     ON c.casttarget = tt.oid\n"
                                          "     LEFT JOIN pg_catalog.pg_namespace nt\n"
-                                         "     ON nt.oid = tt.typnamespace\n"
-                                         "WHERE (true",
-                                         gettext_noop("Source type"),
-                                         gettext_noop("Target type"),
-                                         gettext_noop("Function"),
-         gettext_noop("no"), gettext_noop("in assignment"), gettext_noop("yes"),
-                                         gettext_noop("Implicit?"));
+                                         "     ON nt.oid = tt.typnamespace\n");
+
+       if (verbose)
+               appendPQExpBuffer(&buf,
+                                                 "     LEFT JOIN pg_catalog.pg_description d\n"
+                                                 "     ON d.classoid = c.tableoid AND d.objoid = "
+                                                 "c.oid AND d.objsubid = 0\n");
+
+       appendPQExpBuffer(&buf, "WHERE ( (true");
 
        /*
         * Match name pattern against either internal or external name of either
@@ -2861,7 +2949,7 @@ listCasts(const char *pattern)
                                                  "pg_catalog.format_type(tt.oid, NULL)",
                                                  "pg_catalog.pg_type_is_visible(tt.oid)");
 
-       appendPQExpBuffer(&buf, ")\nORDER BY 1, 2;");
+       appendPQExpBuffer(&buf, ") )\nORDER BY 1, 2;");
 
        res = PSQLexec(buf.data, false);
        termPQExpBuffer(&buf);
@@ -3169,7 +3257,7 @@ describeOneTSParser(const char *oid, const char *nspname, const char *prsname)
                                          "   p.prslextype::pg_catalog.regproc, \n"
                                  "   pg_catalog.obj_description(p.prslextype, 'pg_proc') \n"
                                          " FROM pg_catalog.pg_ts_parser p \n"
-                                         " WHERE p.oid = '%s' \n",
+                                         " WHERE p.oid = '%s';",
                                          gettext_noop("Start parse"),
                                          gettext_noop("Method"),
                                          gettext_noop("Function"),
@@ -3530,7 +3618,7 @@ describeOneTSConfig(const char *oid, const char *nspname, const char *cfgname,
         "FROM pg_catalog.pg_ts_config AS c, pg_catalog.pg_ts_config_map AS m \n"
                                          "WHERE c.oid = '%s' AND m.mapcfg = c.oid \n"
                                          "GROUP BY m.mapcfg, m.maptokentype, c.cfgparser \n"
-                                         "ORDER BY 1",
+                                         "ORDER BY 1;",
                                          gettext_noop("Token"),
                                          gettext_noop("Dictionaries"),
                                          oid);