]> granicus.if.org Git - postgresql/blobdiff - src/bin/psql/describe.c
Add missing translate_columns array entry
[postgresql] / src / bin / psql / describe.c
index 5a9ceca0df5e6ba1da3597d9a73b5f98582289d0..2cdc5acf30264355c2d5784eca1c8bd9529e3141 100644 (file)
@@ -6,7 +6,7 @@
  * with servers of versions 7.4 and up.  It's okay to omit irrelevant
  * information for an old server, but not to fail outright.
  *
- * Copyright (c) 2000-2014, PostgreSQL Global Development Group
+ * Copyright (c) 2000-2016, PostgreSQL Global Development Group
  *
  * src/bin/psql/describe.c
  */
 #include <ctype.h>
 
 #include "catalog/pg_default_acl.h"
+#include "fe_utils/string_utils.h"
 
 #include "common.h"
 #include "describe.h"
-#include "dumputils.h"
-#include "mbprint.h"
-#include "print.h"
+#include "fe_utils/mbprint.h"
+#include "fe_utils/print.h"
 #include "settings.h"
 #include "variables.h"
 
@@ -123,7 +123,71 @@ describeAggregates(const char *pattern, bool verbose, bool showSystem)
        myopt.title = _("List of aggregate functions");
        myopt.translate_header = true;
 
-       printQuery(res, &myopt, pset.queryFout, pset.logfile);
+       printQuery(res, &myopt, pset.queryFout, false, pset.logfile);
+
+       PQclear(res);
+       return true;
+}
+
+/* \dA
+ * Takes an optional regexp to select particular access methods
+ */
+bool
+describeAccessMethods(const char *pattern, bool verbose)
+{
+       PQExpBufferData buf;
+       PGresult   *res;
+       printQueryOpt myopt = pset.popt;
+       static const bool translate_columns[] = {false, true, false, false};
+
+       if (pset.sversion < 90600)
+       {
+               psql_error("The server (version %d.%d) does not support access methods.\n",
+                                  pset.sversion / 10000, (pset.sversion / 100) % 100);
+               return true;
+       }
+
+       initPQExpBuffer(&buf);
+
+       printfPQExpBuffer(&buf,
+                                         "SELECT amname AS \"%s\",\n"
+                                         "  CASE amtype"
+                                         " WHEN 'i' THEN '%s'"
+                                         " END AS \"%s\"",
+                                         gettext_noop("Name"),
+                                         gettext_noop("Index"),
+                                         gettext_noop("Type"));
+
+       if (verbose)
+       {
+               appendPQExpBuffer(&buf,
+                                                 ",\n  amhandler AS \"%s\",\n"
+                                         "  pg_catalog.obj_description(oid, 'pg_am') AS \"%s\"",
+                                                 gettext_noop("Handler"),
+                                                 gettext_noop("Description"));
+       }
+
+       appendPQExpBufferStr(&buf,
+                                                "\nFROM pg_catalog.pg_am\n");
+
+       processSQLNamePattern(pset.db, &buf, pattern, false, false,
+                                                 NULL, "amname", NULL,
+                                                 NULL);
+
+       appendPQExpBufferStr(&buf, "ORDER BY 1;");
+
+       res = PSQLexec(buf.data);
+       termPQExpBuffer(&buf);
+       if (!res)
+               return false;
+
+       myopt.nullPrint = NULL;
+       myopt.title = _("List of access methods");
+       myopt.translate_header = true;
+       myopt.translate_columns = translate_columns;
+       myopt.n_translate_columns = lengthof(translate_columns);
+
+       printQuery(res, &myopt, pset.queryFout, false, pset.logfile);
 
        PQclear(res);
        return true;
@@ -204,7 +268,7 @@ describeTablespaces(const char *pattern, bool verbose)
        myopt.title = _("List of tablespaces");
        myopt.translate_header = true;
 
-       printQuery(res, &myopt, pset.queryFout, pset.logfile);
+       printQuery(res, &myopt, pset.queryFout, false, pset.logfile);
 
        PQclear(res);
        return true;
@@ -469,7 +533,7 @@ describeFunctions(const char *functypes, const char *pattern, bool verbose, bool
        myopt.translate_columns = translate_columns;
        myopt.n_translate_columns = lengthof(translate_columns);
 
-       printQuery(res, &myopt, pset.queryFout, pset.logfile);
+       printQuery(res, &myopt, pset.queryFout, false, pset.logfile);
 
        PQclear(res);
        return true;
@@ -528,6 +592,12 @@ describeTypes(const char *pattern, bool verbose, bool showSystem)
                                                  "  ) AS \"%s\",\n",
                                                  gettext_noop("Elements"));
        }
+       if (verbose)
+       {
+               appendPQExpBuffer(&buf,
+                                        "  pg_catalog.pg_get_userbyid(t.typowner) AS \"%s\",\n",
+                                                 gettext_noop("Owner"));
+       }
        if (verbose && pset.sversion >= 90200)
        {
                printACLColumn(&buf, "t.typacl");
@@ -579,7 +649,7 @@ describeTypes(const char *pattern, bool verbose, bool showSystem)
        myopt.title = _("List of data types");
        myopt.translate_header = true;
 
-       printQuery(res, &myopt, pset.queryFout, pset.logfile);
+       printQuery(res, &myopt, pset.queryFout, false, pset.logfile);
 
        PQclear(res);
        return true;
@@ -654,7 +724,7 @@ describeOperators(const char *pattern, bool verbose, bool showSystem)
        myopt.title = _("List of operators");
        myopt.translate_header = true;
 
-       printQuery(res, &myopt, pset.queryFout, pset.logfile);
+       printQuery(res, &myopt, pset.queryFout, false, pset.logfile);
 
        PQclear(res);
        return true;
@@ -725,7 +795,7 @@ listAllDbs(const char *pattern, bool verbose)
        myopt.title = _("List of databases");
        myopt.translate_header = true;
 
-       printQuery(res, &myopt, pset.queryFout, pset.logfile);
+       printQuery(res, &myopt, pset.queryFout, false, pset.logfile);
 
        PQclear(res);
        return true;
@@ -784,8 +854,8 @@ permissionsList(const char *pattern)
                appendPQExpBuffer(&buf,
                                                  ",\n  pg_catalog.array_to_string(ARRAY(\n"
                                                  "    SELECT polname\n"
-                                                 "    || CASE WHEN polcmd IS NOT NULL THEN\n"
-                                                 "           E' (' || polcmd || E')'\n"
+                                                 "    || CASE WHEN polcmd != '*' THEN\n"
+                                                 "           E' (' || polcmd || E'):'\n"
                                                  "       ELSE E':' \n"
                                                  "       END\n"
                                                  "    || CASE WHEN polqual IS NOT NULL THEN\n"
@@ -797,7 +867,7 @@ permissionsList(const char *pattern)
                                                  "       ELSE E''\n"
                                                  "       END"
                                                  "    || CASE WHEN polroles <> '{0}' THEN\n"
-                                                 "           E'\\n  to: ' || pg_catalog.array_to_string(\n"
+                                  "           E'\\n  to: ' || pg_catalog.array_to_string(\n"
                                                  "               ARRAY(\n"
                                                  "                   SELECT rolname\n"
                                                  "                   FROM pg_catalog.pg_roles\n"
@@ -841,7 +911,7 @@ permissionsList(const char *pattern)
        myopt.translate_columns = translate_columns;
        myopt.n_translate_columns = lengthof(translate_columns);
 
-       printQuery(res, &myopt, pset.queryFout, pset.logfile);
+       printQuery(res, &myopt, pset.queryFout, false, pset.logfile);
 
        termPQExpBuffer(&buf);
        PQclear(res);
@@ -915,7 +985,7 @@ listDefaultACLs(const char *pattern)
        myopt.translate_columns = translate_columns;
        myopt.n_translate_columns = lengthof(translate_columns);
 
-       printQuery(res, &myopt, pset.queryFout, pset.logfile);
+       printQuery(res, &myopt, pset.queryFout, false, pset.logfile);
 
        termPQExpBuffer(&buf);
        PQclear(res);
@@ -952,7 +1022,7 @@ objectDescription(const char *pattern, bool showSystem)
                                          gettext_noop("Object"),
                                          gettext_noop("Description"));
 
-       /* Constraint descriptions */
+       /* Table constraint descriptions */
        appendPQExpBuffer(&buf,
                                          "  SELECT pgc.oid as oid, pgc.tableoid AS tableoid,\n"
                                          "  n.nspname as nspname,\n"
@@ -963,7 +1033,7 @@ objectDescription(const char *pattern, bool showSystem)
                                          "ON c.oid = pgc.conrelid\n"
                                          "    LEFT JOIN pg_catalog.pg_namespace n "
                                          "    ON n.oid = c.relnamespace\n",
-                                         gettext_noop("constraint"));
+                                         gettext_noop("table constraint"));
 
        if (!showSystem && !pattern)
                appendPQExpBufferStr(&buf, "WHERE n.nspname <> 'pg_catalog'\n"
@@ -973,6 +1043,29 @@ objectDescription(const char *pattern, bool showSystem)
                                                  false, "n.nspname", "pgc.conname", NULL,
                                                  "pg_catalog.pg_table_is_visible(c.oid)");
 
+       /* Domain constraint descriptions */
+       appendPQExpBuffer(&buf,
+                                         "UNION ALL\n"
+                                         "  SELECT pgc.oid as oid, pgc.tableoid AS tableoid,\n"
+                                         "  n.nspname as nspname,\n"
+                                         "  CAST(pgc.conname AS pg_catalog.text) as name,"
+                                         "  CAST('%s' AS pg_catalog.text) as object\n"
+                                         "  FROM pg_catalog.pg_constraint pgc\n"
+                                         "    JOIN pg_catalog.pg_type t "
+                                         "ON t.oid = pgc.contypid\n"
+                                         "    LEFT JOIN pg_catalog.pg_namespace n "
+                                         "    ON n.oid = t.typnamespace\n",
+                                         gettext_noop("domain constraint"));
+
+       if (!showSystem && !pattern)
+               appendPQExpBufferStr(&buf, "WHERE n.nspname <> 'pg_catalog'\n"
+                                                        "      AND n.nspname <> 'information_schema'\n");
+
+       processSQLNamePattern(pset.db, &buf, pattern, !showSystem && !pattern,
+                                                 false, "n.nspname", "pgc.conname", NULL,
+                                                 "pg_catalog.pg_type_is_visible(t.oid)");
+
+
        /*
         * pg_opclass.opcmethod only available in 8.3+
         */
@@ -1088,7 +1181,7 @@ objectDescription(const char *pattern, bool showSystem)
        myopt.translate_columns = translate_columns;
        myopt.n_translate_columns = lengthof(translate_columns);
 
-       printQuery(res, &myopt, pset.queryFout, pset.logfile);
+       printQuery(res, &myopt, pset.queryFout, false, pset.logfile);
 
        PQclear(res);
        return true;
@@ -1205,6 +1298,7 @@ describeOneTableDetails(const char *schemaname,
                bool            hasrules;
                bool            hastriggers;
                bool            rowsecurity;
+               bool            forcerowsecurity;
                bool            hasoids;
                Oid                     tablespace;
                char       *reloptions;
@@ -1230,8 +1324,8 @@ describeOneTableDetails(const char *schemaname,
        {
                printfPQExpBuffer(&buf,
                          "SELECT c.relchecks, c.relkind, c.relhasindex, c.relhasrules, "
-                                                 "c.relhastriggers, c.relrowsecurity, c.relhasoids, "
-                                                 "%s, c.reltablespace, "
+                               "c.relhastriggers, c.relrowsecurity, c.relforcerowsecurity, "
+                                                 "c.relhasoids, %s, c.reltablespace, "
                                                  "CASE WHEN c.reloftype = 0 THEN '' ELSE c.reloftype::pg_catalog.regtype::pg_catalog.text END, "
                                                  "c.relpersistence, c.relreplident\n"
                                                  "FROM pg_catalog.pg_class c\n "
@@ -1247,7 +1341,7 @@ describeOneTableDetails(const char *schemaname,
        {
                printfPQExpBuffer(&buf,
                          "SELECT c.relchecks, c.relkind, c.relhasindex, c.relhasrules, "
-                                                 "c.relhastriggers, false, c.relhasoids, "
+                                                 "c.relhastriggers, false, false, c.relhasoids, "
                                                  "%s, c.reltablespace, "
                                                  "CASE WHEN c.reloftype = 0 THEN '' ELSE c.reloftype::pg_catalog.regtype::pg_catalog.text END, "
                                                  "c.relpersistence, c.relreplident\n"
@@ -1264,7 +1358,7 @@ describeOneTableDetails(const char *schemaname,
        {
                printfPQExpBuffer(&buf,
                          "SELECT c.relchecks, c.relkind, c.relhasindex, c.relhasrules, "
-                                                 "c.relhastriggers, false, c.relhasoids, "
+                                                 "c.relhastriggers, false, false, c.relhasoids, "
                                                  "%s, c.reltablespace, "
                                                  "CASE WHEN c.reloftype = 0 THEN '' ELSE c.reloftype::pg_catalog.regtype::pg_catalog.text END, "
                                                  "c.relpersistence\n"
@@ -1281,7 +1375,7 @@ describeOneTableDetails(const char *schemaname,
        {
                printfPQExpBuffer(&buf,
                          "SELECT c.relchecks, c.relkind, c.relhasindex, c.relhasrules, "
-                                                 "c.relhastriggers, false, c.relhasoids, "
+                                                 "c.relhastriggers, false, false, c.relhasoids, "
                                                  "%s, c.reltablespace, "
                                                  "CASE WHEN c.reloftype = 0 THEN '' ELSE c.reloftype::pg_catalog.regtype::pg_catalog.text END\n"
                                                  "FROM pg_catalog.pg_class c\n "
@@ -1297,7 +1391,7 @@ describeOneTableDetails(const char *schemaname,
        {
                printfPQExpBuffer(&buf,
                          "SELECT c.relchecks, c.relkind, c.relhasindex, c.relhasrules, "
-                                                 "c.relhastriggers, false, c.relhasoids, "
+                                                 "c.relhastriggers, false, false, c.relhasoids, "
                                                  "%s, c.reltablespace\n"
                                                  "FROM pg_catalog.pg_class c\n "
                   "LEFT JOIN pg_catalog.pg_class tc ON (c.reltoastrelid = tc.oid)\n"
@@ -1312,7 +1406,7 @@ describeOneTableDetails(const char *schemaname,
        {
                printfPQExpBuffer(&buf,
                                          "SELECT relchecks, relkind, relhasindex, relhasrules, "
-                                                 "reltriggers <> 0, false, relhasoids, "
+                                                 "reltriggers <> 0, false, false, relhasoids, "
                                                  "%s, reltablespace\n"
                                                  "FROM pg_catalog.pg_class WHERE oid = '%s';",
                                                  (verbose ?
@@ -1323,7 +1417,7 @@ describeOneTableDetails(const char *schemaname,
        {
                printfPQExpBuffer(&buf,
                                          "SELECT relchecks, relkind, relhasindex, relhasrules, "
-                                                 "reltriggers <> 0, false, relhasoids, "
+                                                 "reltriggers <> 0, false, false, relhasoids, "
                                                  "'', reltablespace\n"
                                                  "FROM pg_catalog.pg_class WHERE oid = '%s';",
                                                  oid);
@@ -1332,7 +1426,7 @@ describeOneTableDetails(const char *schemaname,
        {
                printfPQExpBuffer(&buf,
                                          "SELECT relchecks, relkind, relhasindex, relhasrules, "
-                                                 "reltriggers <> 0, false, relhasoids, "
+                                                 "reltriggers <> 0, false, false, relhasoids, "
                                                  "'', ''\n"
                                                  "FROM pg_catalog.pg_class WHERE oid = '%s';",
                                                  oid);
@@ -1356,18 +1450,19 @@ describeOneTableDetails(const char *schemaname,
        tableinfo.hasrules = strcmp(PQgetvalue(res, 0, 3), "t") == 0;
        tableinfo.hastriggers = strcmp(PQgetvalue(res, 0, 4), "t") == 0;
        tableinfo.rowsecurity = strcmp(PQgetvalue(res, 0, 5), "t") == 0;
-       tableinfo.hasoids = strcmp(PQgetvalue(res, 0, 6), "t") == 0;
+       tableinfo.forcerowsecurity = strcmp(PQgetvalue(res, 0, 6), "t") == 0;
+       tableinfo.hasoids = strcmp(PQgetvalue(res, 0, 7), "t") == 0;
        tableinfo.reloptions = (pset.sversion >= 80200) ?
-               pg_strdup(PQgetvalue(res, 0, 7)) : NULL;
+               pg_strdup(PQgetvalue(res, 0, 8)) : NULL;
        tableinfo.tablespace = (pset.sversion >= 80000) ?
-               atooid(PQgetvalue(res, 0, 8)) : 0;
+               atooid(PQgetvalue(res, 0, 9)) : 0;
        tableinfo.reloftype = (pset.sversion >= 90000 &&
-                                                  strcmp(PQgetvalue(res, 0, 9), "") != 0) ?
-               pg_strdup(PQgetvalue(res, 0, 9)) : NULL;
+                                                  strcmp(PQgetvalue(res, 0, 10), "") != 0) ?
+               pg_strdup(PQgetvalue(res, 0, 10)) : NULL;
        tableinfo.relpersistence = (pset.sversion >= 90100) ?
-               *(PQgetvalue(res, 0, 10)) : 0;
+               *(PQgetvalue(res, 0, 11)) : 0;
        tableinfo.relreplident = (pset.sversion >= 90400) ?
-               *(PQgetvalue(res, 0, 11)) : 'd';
+               *(PQgetvalue(res, 0, 12)) : 'd';
        PQclear(res);
        res = NULL;
 
@@ -1582,7 +1677,7 @@ describeOneTableDetails(const char *schemaname,
                        if (!PQgetisnull(res, i, 5))
                        {
                                if (tmpbuf.len > 0)
-                                       appendPQExpBufferStr(&tmpbuf, " ");
+                                       appendPQExpBufferChar(&tmpbuf, ' ');
                                appendPQExpBuffer(&tmpbuf, _("collate %s"),
                                                                  PQgetvalue(res, i, 5));
                        }
@@ -1590,7 +1685,7 @@ describeOneTableDetails(const char *schemaname,
                        if (strcmp(PQgetvalue(res, i, 3), "t") == 0)
                        {
                                if (tmpbuf.len > 0)
-                                       appendPQExpBufferStr(&tmpbuf, " ");
+                                       appendPQExpBufferChar(&tmpbuf, ' ');
                                appendPQExpBufferStr(&tmpbuf, _("not null"));
                        }
 
@@ -1599,7 +1694,7 @@ describeOneTableDetails(const char *schemaname,
                        if (strlen(PQgetvalue(res, i, 2)) != 0)
                        {
                                if (tmpbuf.len > 0)
-                                       appendPQExpBufferStr(&tmpbuf, " ");
+                                       appendPQExpBufferChar(&tmpbuf, ' ');
                                /* translator: default values of column definitions */
                                appendPQExpBuffer(&tmpbuf, _("default %s"),
                                                                  PQgetvalue(res, i, 2));
@@ -2002,18 +2097,19 @@ describeOneTableDetails(const char *schemaname,
                if (pset.sversion >= 90500)
                {
                        printfPQExpBuffer(&buf,
-                                                  "SELECT pol.polname,\n"
-                                                  "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE array_to_string(array(select rolname from pg_roles where oid = any (pol.polroles) order by 1),',') END,\n"
-                                                  "pg_catalog.pg_get_expr(pol.polqual, pol.polrelid),\n"
-                                                  "pg_catalog.pg_get_expr(pol.polwithcheck, pol.polrelid),\n"
-                                                  "CASE pol.polcmd \n"
-                                                  "WHEN 'r' THEN 'SELECT'\n"
-                                                  "WHEN 'u' THEN 'UPDATE'\n"
-                                                  "WHEN 'a' THEN 'INSERT'\n"
-                                                  "WHEN 'd' THEN 'DELETE'\n"
-                                                  "END AS cmd\n"
+                                                         "SELECT pol.polname,\n"
+                                                         "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE array_to_string(array(select rolname from pg_roles where oid = any (pol.polroles) order by 1),',') END,\n"
+                                          "pg_catalog.pg_get_expr(pol.polqual, pol.polrelid),\n"
+                                 "pg_catalog.pg_get_expr(pol.polwithcheck, pol.polrelid),\n"
+                                                         "CASE pol.polcmd \n"
+                                                         "WHEN 'r' THEN 'SELECT'\n"
+                                                         "WHEN 'a' THEN 'INSERT'\n"
+                                                         "WHEN 'w' THEN 'UPDATE'\n"
+                                                         "WHEN 'd' THEN 'DELETE'\n"
+                                                         "WHEN '*' THEN 'ALL'\n"
+                                                         "END AS cmd\n"
                                                          "FROM pg_catalog.pg_policy pol\n"
-                                 "WHERE pol.polrelid = '%s' ORDER BY 1;",
+                                                         "WHERE pol.polrelid = '%s' ORDER BY 1;",
                                                          oid);
 
                        result = PSQLexec(buf.data);
@@ -2023,24 +2119,30 @@ describeOneTableDetails(const char *schemaname,
                                tuples = PQntuples(result);
 
                        /*
-                        * Handle cases where RLS is enabled and there are policies,
-                        * or there aren't policies, or RLS isn't enabled but there
-                        * are policies
+                        * Handle cases where RLS is enabled and there are policies, or
+                        * there aren't policies, or RLS isn't enabled but there are
+                        * policies
                         */
-                       if (tableinfo.rowsecurity && tuples > 0)
+                       if (tableinfo.rowsecurity && !tableinfo.forcerowsecurity && tuples > 0)
                                printTableAddFooter(&cont, _("Policies:"));
 
-                       if (tableinfo.rowsecurity && tuples == 0)
-                               printTableAddFooter(&cont, _("Policies (Row Security Enabled): (None)"));
+                       if (tableinfo.rowsecurity && tableinfo.forcerowsecurity && tuples > 0)
+                               printTableAddFooter(&cont, _("Policies (forced row security enabled):"));
+
+                       if (tableinfo.rowsecurity && !tableinfo.forcerowsecurity && tuples == 0)
+                               printTableAddFooter(&cont, _("Policies (row security enabled): (none)"));
+
+                       if (tableinfo.rowsecurity && tableinfo.forcerowsecurity && tuples == 0)
+                               printTableAddFooter(&cont, _("Policies (forced row security enabled): (none)"));
 
                        if (!tableinfo.rowsecurity && tuples > 0)
-                               printTableAddFooter(&cont, _("Policies (Row Security Disabled):"));
+                               printTableAddFooter(&cont, _("Policies (row security disabled):"));
 
                        /* Might be an empty set - that's ok */
                        for (i = 0; i < tuples; i++)
                        {
                                printfPQExpBuffer(&buf, "    POLICY \"%s\"",
-                                                                         PQgetvalue(result, i, 0));
+                                                                 PQgetvalue(result, i, 0));
 
                                if (!PQgetisnull(result, i, 4))
                                        appendPQExpBuffer(&buf, " FOR %s",
@@ -2053,11 +2155,11 @@ describeOneTableDetails(const char *schemaname,
                                }
 
                                if (!PQgetisnull(result, i, 2))
-                                       appendPQExpBuffer(&buf, "\n      USING %s",
+                                       appendPQExpBuffer(&buf, "\n      USING (%s)",
                                                                          PQgetvalue(result, i, 2));
 
                                if (!PQgetisnull(result, i, 3))
-                                       appendPQExpBuffer(&buf, "\n      WITH CHECK %s",
+                                       appendPQExpBuffer(&buf, "\n      WITH CHECK (%s)",
                                                                          PQgetvalue(result, i, 3));
 
                                printTableAddFooter(&cont, buf.data);
@@ -2410,7 +2512,7 @@ describeOneTableDetails(const char *schemaname,
                                        printfPQExpBuffer(&buf, "%*s  %s",
                                                                          sw, "", PQgetvalue(result, i, 0));
                                if (i < tuples - 1)
-                                       appendPQExpBufferStr(&buf, ",");
+                                       appendPQExpBufferChar(&buf, ',');
 
                                printTableAddFooter(&cont, buf.data);
                        }
@@ -2508,8 +2610,7 @@ describeOneTableDetails(const char *schemaname,
                printTableAddFooter(&cont, buf.data);
        }
 
-       printTable(&cont, pset.queryFout, pset.logfile);
-       printTableCleanup(&cont);
+       printTable(&cont, pset.queryFout, false, pset.logfile);
 
        retval = true;
 
@@ -2609,7 +2710,7 @@ add_tablespace_footer(printTableContent *const cont, char relkind,
  * Describes roles.  Any schema portion of the pattern is ignored.
  */
 bool
-describeRoles(const char *pattern, bool verbose)
+describeRoles(const char *pattern, bool verbose, bool showSystem)
 {
        PQExpBufferData buf;
        PGresult   *res;
@@ -2654,6 +2755,9 @@ describeRoles(const char *pattern, bool verbose)
 
                appendPQExpBufferStr(&buf, "\nFROM pg_catalog.pg_roles r\n");
 
+               if (!showSystem && !pattern)
+                       appendPQExpBufferStr(&buf, "WHERE r.rolname !~ '^pg_'\n");
+
                processSQLNamePattern(pset.db, &buf, pattern, false, false,
                                                          NULL, "r.rolname", NULL, NULL);
        }
@@ -2753,7 +2857,7 @@ describeRoles(const char *pattern, bool verbose)
        }
        termPQExpBuffer(&buf);
 
-       printTable(&cont, pset.queryFout, pset.logfile);
+       printTable(&cont, pset.queryFout, false, pset.logfile);
        printTableCleanup(&cont);
 
        for (i = 0; i < nrows; i++)
@@ -2827,7 +2931,7 @@ listDbRoleSettings(const char *pattern, const char *pattern2)
                myopt.title = _("List of settings");
                myopt.translate_header = true;
 
-               printQuery(res, &myopt, pset.queryFout, pset.logfile);
+               printQuery(res, &myopt, pset.queryFout, false, pset.logfile);
        }
 
        PQclear(res);
@@ -2991,7 +3095,7 @@ listTables(const char *tabtypes, const char *pattern, bool verbose, bool showSys
                myopt.translate_columns = translate_columns;
                myopt.n_translate_columns = lengthof(translate_columns);
 
-               printQuery(res, &myopt, pset.queryFout, pset.logfile);
+               printQuery(res, &myopt, pset.queryFout, false, pset.logfile);
        }
 
        PQclear(res);
@@ -3067,7 +3171,7 @@ listLanguages(const char *pattern, bool verbose, bool showSystem)
        myopt.title = _("List of languages");
        myopt.translate_header = true;
 
-       printQuery(res, &myopt, pset.queryFout, pset.logfile);
+       printQuery(res, &myopt, pset.queryFout, false, pset.logfile);
 
        PQclear(res);
        return true;
@@ -3154,7 +3258,7 @@ listDomains(const char *pattern, bool verbose, bool showSystem)
        myopt.title = _("List of domains");
        myopt.translate_header = true;
 
-       printQuery(res, &myopt, pset.queryFout, pset.logfile);
+       printQuery(res, &myopt, pset.queryFout, false, pset.logfile);
 
        PQclear(res);
        return true;
@@ -3230,7 +3334,7 @@ listConversions(const char *pattern, bool verbose, bool showSystem)
        myopt.translate_columns = translate_columns;
        myopt.n_translate_columns = lengthof(translate_columns);
 
-       printQuery(res, &myopt, pset.queryFout, pset.logfile);
+       printQuery(res, &myopt, pset.queryFout, false, pset.logfile);
 
        PQclear(res);
        return true;
@@ -3296,7 +3400,7 @@ listEventTriggers(const char *pattern, bool verbose)
        myopt.translate_columns = translate_columns;
        myopt.n_translate_columns = lengthof(translate_columns);
 
-       printQuery(res, &myopt, pset.queryFout, pset.logfile);
+       printQuery(res, &myopt, pset.queryFout, false, pset.logfile);
 
        PQclear(res);
        return true;
@@ -3395,7 +3499,7 @@ listCasts(const char *pattern, bool verbose)
        myopt.translate_columns = translate_columns;
        myopt.n_translate_columns = lengthof(translate_columns);
 
-       printQuery(res, &myopt, pset.queryFout, pset.logfile);
+       printQuery(res, &myopt, pset.queryFout, false, pset.logfile);
 
        PQclear(res);
        return true;
@@ -3471,7 +3575,7 @@ listCollations(const char *pattern, bool verbose, bool showSystem)
        myopt.translate_columns = translate_columns;
        myopt.n_translate_columns = lengthof(translate_columns);
 
-       printQuery(res, &myopt, pset.queryFout, pset.logfile);
+       printQuery(res, &myopt, pset.queryFout, false, pset.logfile);
 
        PQclear(res);
        return true;
@@ -3528,7 +3632,7 @@ listSchemas(const char *pattern, bool verbose, bool showSystem)
        myopt.title = _("List of schemas");
        myopt.translate_header = true;
 
-       printQuery(res, &myopt, pset.queryFout, pset.logfile);
+       printQuery(res, &myopt, pset.queryFout, false, pset.logfile);
 
        PQclear(res);
        return true;
@@ -3585,7 +3689,7 @@ listTSParsers(const char *pattern, bool verbose)
        myopt.title = _("List of text search parsers");
        myopt.translate_header = true;
 
-       printQuery(res, &myopt, pset.queryFout, pset.logfile);
+       printQuery(res, &myopt, pset.queryFout, false, pset.logfile);
 
        PQclear(res);
        return true;
@@ -3731,7 +3835,7 @@ describeOneTSParser(const char *oid, const char *nspname, const char *prsname)
        myopt.translate_columns = translate_columns;
        myopt.n_translate_columns = lengthof(translate_columns);
 
-       printQuery(res, &myopt, pset.queryFout, pset.logfile);
+       printQuery(res, &myopt, pset.queryFout, false, pset.logfile);
 
        PQclear(res);
 
@@ -3763,7 +3867,7 @@ describeOneTSParser(const char *oid, const char *nspname, const char *prsname)
        myopt.translate_columns = NULL;
        myopt.n_translate_columns = 0;
 
-       printQuery(res, &myopt, pset.queryFout, pset.logfile);
+       printQuery(res, &myopt, pset.queryFout, false, pset.logfile);
 
        PQclear(res);
        return true;
@@ -3831,7 +3935,7 @@ listTSDictionaries(const char *pattern, bool verbose)
        myopt.title = _("List of text search dictionaries");
        myopt.translate_header = true;
 
-       printQuery(res, &myopt, pset.queryFout, pset.logfile);
+       printQuery(res, &myopt, pset.queryFout, false, pset.logfile);
 
        PQclear(res);
        return true;
@@ -3899,7 +4003,7 @@ listTSTemplates(const char *pattern, bool verbose)
        myopt.title = _("List of text search templates");
        myopt.translate_header = true;
 
-       printQuery(res, &myopt, pset.queryFout, pset.logfile);
+       printQuery(res, &myopt, pset.queryFout, false, pset.logfile);
 
        PQclear(res);
        return true;
@@ -3956,7 +4060,7 @@ listTSConfigs(const char *pattern, bool verbose)
        myopt.title = _("List of text search configurations");
        myopt.translate_header = true;
 
-       printQuery(res, &myopt, pset.queryFout, pset.logfile);
+       printQuery(res, &myopt, pset.queryFout, false, pset.logfile);
 
        PQclear(res);
        return true;
@@ -4094,7 +4198,7 @@ describeOneTSConfig(const char *oid, const char *nspname, const char *cfgname,
        myopt.topt.default_footer = false;
        myopt.translate_header = true;
 
-       printQuery(res, &myopt, pset.queryFout, pset.logfile);
+       printQuery(res, &myopt, pset.queryFout, false, pset.logfile);
 
        termPQExpBuffer(&title);
 
@@ -4177,7 +4281,7 @@ listForeignDataWrappers(const char *pattern, bool verbose)
        myopt.title = _("List of foreign-data wrappers");
        myopt.translate_header = true;
 
-       printQuery(res, &myopt, pset.queryFout, pset.logfile);
+       printQuery(res, &myopt, pset.queryFout, false, pset.logfile);
 
        PQclear(res);
        return true;
@@ -4256,7 +4360,7 @@ listForeignServers(const char *pattern, bool verbose)
        myopt.title = _("List of foreign servers");
        myopt.translate_header = true;
 
-       printQuery(res, &myopt, pset.queryFout, pset.logfile);
+       printQuery(res, &myopt, pset.queryFout, false, pset.logfile);
 
        PQclear(res);
        return true;
@@ -4314,7 +4418,7 @@ listUserMappings(const char *pattern, bool verbose)
        myopt.title = _("List of user mappings");
        myopt.translate_header = true;
 
-       printQuery(res, &myopt, pset.queryFout, pset.logfile);
+       printQuery(res, &myopt, pset.queryFout, false, pset.logfile);
 
        PQclear(res);
        return true;
@@ -4375,7 +4479,8 @@ listForeignTables(const char *pattern, bool verbose)
                                                         "d.objoid = c.oid AND d.objsubid = 0\n");
 
        processSQLNamePattern(pset.db, &buf, pattern, false, false,
-                                                 NULL, "n.nspname", "c.relname", NULL);
+                                                 "n.nspname", "c.relname", NULL,
+                                                 "pg_catalog.pg_table_is_visible(c.oid)");
 
        appendPQExpBufferStr(&buf, "ORDER BY 1, 2;");
 
@@ -4388,7 +4493,7 @@ listForeignTables(const char *pattern, bool verbose)
        myopt.title = _("List of foreign tables");
        myopt.translate_header = true;
 
-       printQuery(res, &myopt, pset.queryFout, pset.logfile);
+       printQuery(res, &myopt, pset.queryFout, false, pset.logfile);
 
        PQclear(res);
        return true;
@@ -4442,7 +4547,7 @@ listExtensions(const char *pattern)
        myopt.title = _("List of installed extensions");
        myopt.translate_header = true;
 
-       printQuery(res, &myopt, pset.queryFout, pset.logfile);
+       printQuery(res, &myopt, pset.queryFout, false, pset.logfile);
 
        PQclear(res);
        return true;
@@ -4549,7 +4654,7 @@ listOneExtensionContents(const char *extname, const char *oid)
        myopt.title = title;
        myopt.translate_header = true;
 
-       printQuery(res, &myopt, pset.queryFout, pset.logfile);
+       printQuery(res, &myopt, pset.queryFout, false, pset.logfile);
 
        PQclear(res);
        return true;