On Wed, Jul 14, 2021 at 07:42:33AM +0200, Laurenz Albe wrote: > Besides, schemas are not physical, but logical containers. So I see a point > in > measuring the storage used in a certain tablespace, but not so much by all > objects > in a certain schema. It might be useful for accounting purposes, though.
We use only a few schemas, 1) to hide child tables; 2) to exclude some extended stats from backups, and 1-2 other things. But it's useful to be able to see how storage is used by schema, and better to do it conveniently. I think it'd be even more useful for people who use schemas more widely than we do: "Who's using all our space?" \dn++ "Oh, it's that one - let me clean that up..." Or, "what's the pg_toast stuff, and do I need to do something about it?" > But I don't expect it to be in frequent enough demand to add a psql command. > > What about inventing a function pg_schema_size(regnamespace)? But for "physical" storage it's also possible to get the size from the OS, much more efficiently, using /bin/df or zfs list (assuming nothing else is using those filesystems). The pg_*_size functions are inefficient, but psql \db+ and \l+ already call them anyway. For schemas, there's no way to get the size from the OS, so it's nice to make the size available from psql, conveniently. v3 patch: - fixes an off by one in forkNum loop; - removes an unnecessary subquery in describe.c; - returns 0 rather than NULL if the schema is empty; - adds pg_am_size; regression=# \dA++ List of access methods Name | Type | Handler | Description | Size --------+-------+----------------------+----------------------------------------+--------- brin | Index | brinhandler | block range index (BRIN) access method | 744 kB btree | Index | bthandler | b-tree index access method | 21 MB gin | Index | ginhandler | GIN index access method | 2672 kB gist | Index | gisthandler | GiST index access method | 2800 kB hash | Index | hashhandler | hash index access method | 2112 kB heap | Table | heap_tableam_handler | heap table access method | 60 MB heap2 | Table | heap_tableam_handler | | 120 kB spgist | Index | spghandler | SP-GiST index access method | 5840 kB (8 rows) regression=# \dn++ List of schemas Name | Owner | Access privileges | Description | Size --------------------+---------+--------------------+------------------------+--------- fkpart3 | pryzbyj | | | 168 kB fkpart4 | pryzbyj | | | 104 kB fkpart5 | pryzbyj | | | 40 kB fkpart6 | pryzbyj | | | 48 kB mvtest_mvschema | pryzbyj | | | 16 kB public | pryzbyj | pryzbyj=UC/pryzbyj+| standard public schema | 69 MB | | =UC/pryzbyj | | regress_indexing | pryzbyj | | | 48 kB regress_rls_schema | pryzbyj | | | 0 bytes regress_schema_2 | pryzbyj | | | 0 bytes testxmlschema | pryzbyj | | | 24 kB (10 rows) -- Justin
>From d7f5446c0aa1a12a512482d2ed121eb44f6e2f59 Mon Sep 17 00:00:00 2001 From: Justin Pryzby <pryz...@telsasoft.com> Date: Tue, 13 Jul 2021 21:25:48 -0500 Subject: [PATCH v3 1/4] psql: show size of schemas and AMs in \dn+ and \dA+.. See also: 358a897fa, 528ac10c7 Add pg_am_size() and psql \dA++ --- src/backend/utils/adt/dbsize.c | 138 ++++++++++++++++++++++++++++++++ src/bin/psql/describe.c | 12 ++- src/include/catalog/pg_proc.dat | 19 +++++ 3 files changed, 168 insertions(+), 1 deletion(-) diff --git a/src/backend/utils/adt/dbsize.c b/src/backend/utils/adt/dbsize.c index d5a7fb13f3..62273d4f15 100644 --- a/src/backend/utils/adt/dbsize.c +++ b/src/backend/utils/adt/dbsize.c @@ -13,18 +13,23 @@ #include <sys/stat.h> +#include "access/genam.h" #include "access/htup_details.h" #include "access/relation.h" +#include "access/table.h" #include "catalog/catalog.h" #include "catalog/namespace.h" #include "catalog/pg_authid.h" #include "catalog/pg_tablespace.h" #include "commands/dbcommands.h" +#include "commands/defrem.h" #include "commands/tablespace.h" #include "miscadmin.h" #include "storage/fd.h" #include "utils/acl.h" #include "utils/builtins.h" +#include "utils/fmgroids.h" +#include "utils/lsyscache.h" #include "utils/numeric.h" #include "utils/rel.h" #include "utils/relfilenodemap.h" @@ -832,6 +837,139 @@ pg_size_bytes(PG_FUNCTION_ARGS) PG_RETURN_INT64(result); } +/* Return the sum of size of relations for which the given attribute has the specified OID */ +static int64 +calculate_size_attvalue(int attnum, Oid attval) +{ + int64 totalsize = 0; + ScanKeyData skey; + Relation pg_class; + SysScanDesc scan; + HeapTuple tuple; + + ScanKeyInit(&skey, attnum, + BTEqualStrategyNumber, F_OIDEQ, attval); + + pg_class = table_open(RelationRelationId, AccessShareLock); + scan = systable_beginscan(pg_class, InvalidOid, false, NULL, 1, &skey); + while (HeapTupleIsValid(tuple = systable_getnext(scan))) + { + Relation rel; + Form_pg_class classtuple = (Form_pg_class) GETSTRUCT(tuple); + + rel = try_relation_open(classtuple->oid, AccessShareLock); + if (!rel) + continue; + + for (int forkNum = 0; forkNum <= MAX_FORKNUM; forkNum++) + totalsize += calculate_relation_size(&rel->rd_node, rel->rd_backend, forkNum); + + relation_close(rel, AccessShareLock); + } + + systable_endscan(scan); + table_close(pg_class, AccessShareLock); + return totalsize; +} + +/* Compute the size of relations in a schema (namespace) */ +static int64 +calculate_namespace_size(Oid nspOid) +{ + /* + * User must be a member of pg_read_all_stats or have CREATE privilege for + * target namespace. + */ + if (!is_member_of_role(GetUserId(), ROLE_PG_READ_ALL_STATS)) + { + AclResult aclresult; + aclresult = pg_namespace_aclcheck(nspOid, GetUserId(), ACL_CREATE); + if (aclresult != ACLCHECK_OK) + aclcheck_error(aclresult, OBJECT_SCHEMA, + get_namespace_name(nspOid)); + } + + return calculate_size_attvalue(Anum_pg_class_relnamespace, nspOid); +} + +Datum +pg_namespace_size_oid(PG_FUNCTION_ARGS) +{ + int64 size; + Oid nspOid = PG_GETARG_OID(0); + + size = calculate_namespace_size(nspOid); + + if (size < 0) + PG_RETURN_NULL(); + + PG_RETURN_INT64(size); +} + +Datum +pg_namespace_size_name(PG_FUNCTION_ARGS) +{ + int64 size; + Name nspName = PG_GETARG_NAME(0); + Oid nspOid = get_namespace_oid(NameStr(*nspName), false); + + size = calculate_namespace_size(nspOid); + + if (size < 0) + PG_RETURN_NULL(); + + PG_RETURN_INT64(size); +} + +/* Compute the size of relations using an access method */ +static int64 +calculate_am_size(Oid amOid) +{ + /* + * User must be a member of pg_read_all_stats or have CREATE privilege for + * target namespace. + */ + if (!is_member_of_role(GetUserId(), ROLE_PG_READ_ALL_STATS)) + { + AclResult aclresult; + aclresult = pg_namespace_aclcheck(amOid, GetUserId(), ACL_CREATE); + if (aclresult != ACLCHECK_OK) + aclcheck_error(aclresult, OBJECT_SCHEMA, + get_am_name(amOid)); + } + + return calculate_size_attvalue(Anum_pg_class_relam, amOid); +} + +Datum +pg_am_size_oid(PG_FUNCTION_ARGS) +{ + int64 size; + Oid amOid = PG_GETARG_OID(0); + + size = calculate_am_size(amOid); + + if (size < 0) + PG_RETURN_NULL(); + + PG_RETURN_INT64(size); +} + +Datum +pg_am_size_name(PG_FUNCTION_ARGS) +{ + int64 size; + Name amName = PG_GETARG_NAME(0); + Oid amOid = get_am_oid(NameStr(*amName), false); + + size = calculate_am_size(amOid); + + if (size < 0) + PG_RETURN_NULL(); + + PG_RETURN_INT64(size); +} + /* * Get the filenode of a relation * diff --git a/src/bin/psql/describe.c b/src/bin/psql/describe.c index ba658f731b..fe5d88a2b7 100644 --- a/src/bin/psql/describe.c +++ b/src/bin/psql/describe.c @@ -152,7 +152,7 @@ describeAccessMethods(const char *pattern, bool verbose) PQExpBufferData buf; PGresult *res; printQueryOpt myopt = pset.popt; - static const bool translate_columns[] = {false, true, false, false}; + static const bool translate_columns[] = {false, true, false, false, false}; if (pset.sversion < 90600) { @@ -184,6 +184,11 @@ describeAccessMethods(const char *pattern, bool verbose) " pg_catalog.obj_description(oid, 'pg_am') AS \"%s\"", gettext_noop("Handler"), gettext_noop("Description")); + + if (pset.sversion >= 150000) + appendPQExpBuffer(&buf, + ",\n pg_catalog.pg_size_pretty(pg_catalog.pg_am_size(oid)) AS \"%s\"", + gettext_noop("Size")); } appendPQExpBufferStr(&buf, @@ -5036,6 +5041,11 @@ listSchemas(const char *pattern, bool verbose, bool showSystem) appendPQExpBuffer(&buf, ",\n pg_catalog.obj_description(n.oid, 'pg_namespace') AS \"%s\"", gettext_noop("Description")); + + if (verbose && pset.sversion >= 150000) + appendPQExpBuffer(&buf, + ",\n pg_catalog.pg_size_pretty(pg_namespace_size(n.oid)) AS \"%s\"", + gettext_noop("Size")); } appendPQExpBufferStr(&buf, diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index fde251fa4f..4518aad200 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -7158,6 +7158,25 @@ descr => 'total disk space usage for the specified tablespace', proname => 'pg_tablespace_size', provolatile => 'v', prorettype => 'int8', proargtypes => 'name', prosrc => 'pg_tablespace_size_name' }, + +{ oid => '9410', + descr => 'total disk space usage for the specified namespace', + proname => 'pg_namespace_size', provolatile => 'v', prorettype => 'int8', + proargtypes => 'oid', prosrc => 'pg_namespace_size_oid' }, +{ oid => '9411', + descr => 'total disk space usage for the specified namespace', + proname => 'pg_namespace_size', provolatile => 'v', prorettype => 'int8', + proargtypes => 'name', prosrc => 'pg_namespace_size_name' }, + +{ oid => '9412', + descr => 'total disk space usage for the specified access method', + proname => 'pg_am_size', provolatile => 'v', prorettype => 'int8', + proargtypes => 'oid', prosrc => 'pg_am_size_oid' }, +{ oid => '9413', + descr => 'total disk space usage for the specified access method', + proname => 'pg_am_size', provolatile => 'v', prorettype => 'int8', + proargtypes => 'name', prosrc => 'pg_am_size_name' }, + { oid => '2324', descr => 'total disk space usage for the specified database', proname => 'pg_database_size', provolatile => 'v', prorettype => 'int8', proargtypes => 'oid', prosrc => 'pg_database_size_oid' }, -- 2.17.0
>From 351de9f97334467b5513b2245e62ea3edad3d1f5 Mon Sep 17 00:00:00 2001 From: Justin Pryzby <pryz...@telsasoft.com> Date: Thu, 15 Jul 2021 03:14:20 -0500 Subject: [PATCH v3 2/4] psql \dn, \dA, \db and \l to show the size only with ++.. \dt+ and \dP+ are not changed, since showing the table sizes is their primary purpose. --- src/bin/psql/command.c | 22 ++++++++++++++-------- src/bin/psql/describe.c | 16 ++++++++-------- src/bin/psql/describe.h | 8 ++++---- 3 files changed, 26 insertions(+), 20 deletions(-) diff --git a/src/bin/psql/command.c b/src/bin/psql/command.c index 49d4c0e3ce..bfb10d91e4 100644 --- a/src/bin/psql/command.c +++ b/src/bin/psql/command.c @@ -362,7 +362,8 @@ exec_command(const char *cmd, else if (strcmp(cmd, "if") == 0) status = exec_command_if(scan_state, cstack, query_buf); else if (strcmp(cmd, "l") == 0 || strcmp(cmd, "list") == 0 || - strcmp(cmd, "l+") == 0 || strcmp(cmd, "list+") == 0) + strcmp(cmd, "l+") == 0 || strcmp(cmd, "l++") == 0 || + strcmp(cmd, "list+") == 0 || strcmp(cmd, "list++") == 0) status = exec_command_list(scan_state, active_branch, cmd); else if (strncmp(cmd, "lo_", 3) == 0) status = exec_command_lo(scan_state, active_branch, cmd); @@ -707,6 +708,7 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd) if (active_branch) { char *pattern; + int verbose = 0; bool show_verbose, show_system; @@ -714,7 +716,10 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd) pattern = psql_scan_slash_option(scan_state, OT_NORMAL, NULL, true); - show_verbose = strchr(cmd, '+') ? true : false; + for (const char *t = cmd; *t != '\0'; ++t) + verbose += *t == '+' ? 1 : 0; + + show_verbose = (bool) (verbose != 0); show_system = strchr(cmd, 'S') ? true : false; switch (cmd[1]) @@ -739,7 +744,7 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd) { case '\0': case '+': - success = describeAccessMethods(pattern, show_verbose); + success = describeAccessMethods(pattern, verbose); break; case 'c': success = listOperatorClasses(pattern, pattern2, show_verbose); @@ -766,7 +771,7 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd) success = describeAggregates(pattern, show_verbose, show_system); break; case 'b': - success = describeTablespaces(pattern, show_verbose); + success = describeTablespaces(pattern, verbose); break; case 'c': success = listConversions(pattern, show_verbose, show_system); @@ -813,7 +818,7 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd) success = listLanguages(pattern, show_verbose, show_system); break; case 'n': - success = listSchemas(pattern, show_verbose, show_system); + success = listSchemas(pattern, verbose, show_system); break; case 'o': success = exec_command_dfo(scan_state, cmd, pattern, @@ -1870,14 +1875,15 @@ exec_command_list(PsqlScanState scan_state, bool active_branch, const char *cmd) if (active_branch) { char *pattern; - bool show_verbose; + int verbose = 0; pattern = psql_scan_slash_option(scan_state, OT_NORMAL, NULL, true); - show_verbose = strchr(cmd, '+') ? true : false; + for (const char *t = cmd; *t != '\0'; ++t) + verbose += *t == '+' ? 1 : 0; - success = listAllDbs(pattern, show_verbose); + success = listAllDbs(pattern, verbose); if (pattern) free(pattern); diff --git a/src/bin/psql/describe.c b/src/bin/psql/describe.c index fe5d88a2b7..ce04dbb9ce 100644 --- a/src/bin/psql/describe.c +++ b/src/bin/psql/describe.c @@ -147,7 +147,7 @@ describeAggregates(const char *pattern, bool verbose, bool showSystem) * Takes an optional regexp to select particular access methods */ bool -describeAccessMethods(const char *pattern, bool verbose) +describeAccessMethods(const char *pattern, int verbose) { PQExpBufferData buf; PGresult *res; @@ -185,7 +185,7 @@ describeAccessMethods(const char *pattern, bool verbose) gettext_noop("Handler"), gettext_noop("Description")); - if (pset.sversion >= 150000) + if (verbose > 1 && pset.sversion >= 150000) appendPQExpBuffer(&buf, ",\n pg_catalog.pg_size_pretty(pg_catalog.pg_am_size(oid)) AS \"%s\"", gettext_noop("Size")); @@ -222,7 +222,7 @@ describeAccessMethods(const char *pattern, bool verbose) * Takes an optional regexp to select particular tablespaces */ bool -describeTablespaces(const char *pattern, bool verbose) +describeTablespaces(const char *pattern, int verbose) { PQExpBufferData buf; PGresult *res; @@ -268,7 +268,7 @@ describeTablespaces(const char *pattern, bool verbose) ",\n spcoptions AS \"%s\"", gettext_noop("Options")); - if (verbose && pset.sversion >= 90200) + if (verbose > 1 && pset.sversion >= 90200) appendPQExpBuffer(&buf, ",\n pg_catalog.pg_size_pretty(pg_catalog.pg_tablespace_size(oid)) AS \"%s\"", gettext_noop("Size")); @@ -1028,7 +1028,7 @@ describeOperators(const char *oper_pattern, * for \l, \list, and -l switch */ bool -listAllDbs(const char *pattern, bool verbose) +listAllDbs(const char *pattern, int verbose) { PGresult *res; PQExpBufferData buf; @@ -1051,7 +1051,7 @@ listAllDbs(const char *pattern, bool verbose) gettext_noop("Ctype")); appendPQExpBufferStr(&buf, " "); printACLColumn(&buf, "d.datacl"); - if (verbose && pset.sversion >= 80200) + if (verbose > 1 && pset.sversion >= 80200) appendPQExpBuffer(&buf, ",\n CASE WHEN pg_catalog.has_database_privilege(d.datname, 'CONNECT')\n" " THEN pg_catalog.pg_size_pretty(pg_catalog.pg_database_size(d.datname))\n" @@ -5021,7 +5021,7 @@ listCollations(const char *pattern, bool verbose, bool showSystem) * Describes schemas (namespaces) */ bool -listSchemas(const char *pattern, bool verbose, bool showSystem) +listSchemas(const char *pattern, int verbose, bool showSystem) { PQExpBufferData buf; PGresult *res; @@ -5042,7 +5042,7 @@ listSchemas(const char *pattern, bool verbose, bool showSystem) ",\n pg_catalog.obj_description(n.oid, 'pg_namespace') AS \"%s\"", gettext_noop("Description")); - if (verbose && pset.sversion >= 150000) + if (verbose > 1 && pset.sversion >= 150000) appendPQExpBuffer(&buf, ",\n pg_catalog.pg_size_pretty(pg_namespace_size(n.oid)) AS \"%s\"", gettext_noop("Size")); diff --git a/src/bin/psql/describe.h b/src/bin/psql/describe.h index 71b320f1fc..edeea38580 100644 --- a/src/bin/psql/describe.h +++ b/src/bin/psql/describe.h @@ -13,10 +13,10 @@ extern bool describeAggregates(const char *pattern, bool verbose, bool showSystem); /* \dA */ -extern bool describeAccessMethods(const char *pattern, bool verbose); +extern bool describeAccessMethods(const char *pattern, int verbose); /* \db */ -extern bool describeTablespaces(const char *pattern, bool verbose); +extern bool describeTablespaces(const char *pattern, int verbose); /* \df, \dfa, \dfn, \dft, \dfw, etc. */ extern bool describeFunctions(const char *functypes, const char *func_pattern, @@ -62,7 +62,7 @@ extern bool listTSDictionaries(const char *pattern, bool verbose); extern bool listTSTemplates(const char *pattern, bool verbose); /* \l */ -extern bool listAllDbs(const char *pattern, bool verbose); +extern bool listAllDbs(const char *pattern, int verbose); /* \dt, \di, \ds, \dS, etc. */ extern bool listTables(const char *tabtypes, const char *pattern, bool verbose, bool showSystem); @@ -83,7 +83,7 @@ extern bool listCasts(const char *pattern, bool verbose); extern bool listCollations(const char *pattern, bool verbose, bool showSystem); /* \dn */ -extern bool listSchemas(const char *pattern, bool verbose, bool showSystem); +extern bool listSchemas(const char *pattern, int verbose, bool showSystem); /* \dew */ extern bool listForeignDataWrappers(const char *pattern, bool verbose); -- 2.17.0
>From 79b02af25ba0253b6025cef6b3e94abb2ddfe2eb Mon Sep 17 00:00:00 2001 From: Justin Pryzby <pryz...@telsasoft.com> Date: Thu, 15 Jul 2021 03:19:58 -0500 Subject: [PATCH v3 3/4] f!convert the other verbose to int, too --- src/bin/psql/command.c | 74 +++++++++-------- src/bin/psql/describe.c | 172 ++++++++++++++++++++-------------------- src/bin/psql/describe.h | 54 ++++++------- 3 files changed, 149 insertions(+), 151 deletions(-) diff --git a/src/bin/psql/command.c b/src/bin/psql/command.c index bfb10d91e4..c3738a106f 100644 --- a/src/bin/psql/command.c +++ b/src/bin/psql/command.c @@ -75,7 +75,7 @@ static backslashResult exec_command_d(PsqlScanState scan_state, bool active_bran const char *cmd); static bool exec_command_dfo(PsqlScanState scan_state, const char *cmd, const char *pattern, - bool show_verbose, bool show_system); + int verbose, bool show_system); static backslashResult exec_command_edit(PsqlScanState scan_state, bool active_branch, PQExpBuffer query_buf, PQExpBuffer previous_buf); static backslashResult exec_command_ef_ev(PsqlScanState scan_state, bool active_branch, @@ -709,8 +709,7 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd) { char *pattern; int verbose = 0; - bool show_verbose, - show_system; + bool show_system; /* We don't do SQLID reduction on the pattern yet */ pattern = psql_scan_slash_option(scan_state, @@ -719,7 +718,6 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd) for (const char *t = cmd; *t != '\0'; ++t) verbose += *t == '+' ? 1 : 0; - show_verbose = (bool) (verbose != 0); show_system = strchr(cmd, 'S') ? true : false; switch (cmd[1]) @@ -728,10 +726,10 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd) case '+': case 'S': if (pattern) - success = describeTableDetails(pattern, show_verbose, show_system); + success = describeTableDetails(pattern, verbose, show_system); else /* standard listing of interesting things */ - success = listTables("tvmsE", NULL, show_verbose, show_system); + success = listTables("tvmsE", NULL, verbose, show_system); break; case 'A': { @@ -747,16 +745,16 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd) success = describeAccessMethods(pattern, verbose); break; case 'c': - success = listOperatorClasses(pattern, pattern2, show_verbose); + success = listOperatorClasses(pattern, pattern2, verbose); break; case 'f': - success = listOperatorFamilies(pattern, pattern2, show_verbose); + success = listOperatorFamilies(pattern, pattern2, verbose); break; case 'o': - success = listOpFamilyOperators(pattern, pattern2, show_verbose); + success = listOpFamilyOperators(pattern, pattern2, verbose); break; case 'p': - success = listOpFamilyFunctions(pattern, pattern2, show_verbose); + success = listOpFamilyFunctions(pattern, pattern2, verbose); break; default: status = PSQL_CMD_UNKNOWN; @@ -768,16 +766,16 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd) } break; case 'a': - success = describeAggregates(pattern, show_verbose, show_system); + success = describeAggregates(pattern, verbose, show_system); break; case 'b': success = describeTablespaces(pattern, verbose); break; case 'c': - success = listConversions(pattern, show_verbose, show_system); + success = listConversions(pattern, verbose, show_system); break; case 'C': - success = listCasts(pattern, show_verbose); + success = listCasts(pattern, verbose); break; case 'd': if (strncmp(cmd, "ddp", 3) == 0) @@ -786,7 +784,7 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd) success = objectDescription(pattern, show_system); break; case 'D': - success = listDomains(pattern, show_verbose, show_system); + success = listDomains(pattern, verbose, show_system); break; case 'f': /* function subsystem */ switch (cmd[2]) @@ -800,7 +798,7 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd) case 't': case 'w': success = exec_command_dfo(scan_state, cmd, pattern, - show_verbose, show_system); + verbose, show_system); break; default: status = PSQL_CMD_UNKNOWN; @@ -809,23 +807,23 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd) break; case 'g': /* no longer distinct from \du */ - success = describeRoles(pattern, show_verbose, show_system); + success = describeRoles(pattern, verbose, show_system); break; case 'l': success = do_lo_list(); break; case 'L': - success = listLanguages(pattern, show_verbose, show_system); + success = listLanguages(pattern, verbose, show_system); break; case 'n': success = listSchemas(pattern, verbose, show_system); break; case 'o': success = exec_command_dfo(scan_state, cmd, pattern, - show_verbose, show_system); + verbose, show_system); break; case 'O': - success = listCollations(pattern, show_verbose, show_system); + success = listCollations(pattern, verbose, show_system); break; case 'p': success = permissionsList(pattern); @@ -839,7 +837,7 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd) case 't': case 'i': case 'n': - success = listPartitionedTables(&cmd[2], pattern, show_verbose); + success = listPartitionedTables(&cmd[2], pattern, verbose); break; default: status = PSQL_CMD_UNKNOWN; @@ -848,7 +846,7 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd) } break; case 'T': - success = describeTypes(pattern, show_verbose, show_system); + success = describeTypes(pattern, verbose, show_system); break; case 't': case 'v': @@ -856,7 +854,7 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd) case 'i': case 's': case 'E': - success = listTables(&cmd[1], pattern, show_verbose, show_system); + success = listTables(&cmd[1], pattern, verbose, show_system); break; case 'r': if (cmd[2] == 'd' && cmd[3] == 's') @@ -878,36 +876,36 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd) switch (cmd[2]) { case 'p': - if (show_verbose) + if (verbose > 0) success = describePublications(pattern); else success = listPublications(pattern); break; case 's': - success = describeSubscriptions(pattern, show_verbose); + success = describeSubscriptions(pattern, verbose); break; default: status = PSQL_CMD_UNKNOWN; } break; case 'u': - success = describeRoles(pattern, show_verbose, show_system); + success = describeRoles(pattern, verbose, show_system); break; case 'F': /* text search subsystem */ switch (cmd[2]) { case '\0': case '+': - success = listTSConfigs(pattern, show_verbose); + success = listTSConfigs(pattern, verbose); break; case 'p': - success = listTSParsers(pattern, show_verbose); + success = listTSParsers(pattern, verbose); break; case 'd': - success = listTSDictionaries(pattern, show_verbose); + success = listTSDictionaries(pattern, verbose); break; case 't': - success = listTSTemplates(pattern, show_verbose); + success = listTSTemplates(pattern, verbose); break; default: status = PSQL_CMD_UNKNOWN; @@ -918,16 +916,16 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd) switch (cmd[2]) { case 's': - success = listForeignServers(pattern, show_verbose); + success = listForeignServers(pattern, verbose); break; case 'u': - success = listUserMappings(pattern, show_verbose); + success = listUserMappings(pattern, verbose); break; case 'w': - success = listForeignDataWrappers(pattern, show_verbose); + success = listForeignDataWrappers(pattern, verbose); break; case 't': - success = listForeignTables(pattern, show_verbose); + success = listForeignTables(pattern, verbose); break; default: status = PSQL_CMD_UNKNOWN; @@ -935,7 +933,7 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd) } break; case 'x': /* Extensions */ - if (show_verbose) + if (verbose > 0) success = listExtensionContents(pattern); else success = listExtensions(pattern); @@ -944,7 +942,7 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd) success = listExtendedStats(pattern); break; case 'y': /* Event Triggers */ - success = listEventTriggers(pattern, show_verbose); + success = listEventTriggers(pattern, verbose); break; default: status = PSQL_CMD_UNKNOWN; @@ -966,7 +964,7 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd) static bool exec_command_dfo(PsqlScanState scan_state, const char *cmd, const char *pattern, - bool show_verbose, bool show_system) + int verbose, bool show_system) { bool success; char *arg_patterns[FUNC_MAX_ARGS]; @@ -989,11 +987,11 @@ exec_command_dfo(PsqlScanState scan_state, const char *cmd, if (cmd[1] == 'f') success = describeFunctions(&cmd[2], pattern, arg_patterns, num_arg_patterns, - show_verbose, show_system); + verbose, show_system); else success = describeOperators(pattern, arg_patterns, num_arg_patterns, - show_verbose, show_system); + verbose, show_system); while (--num_arg_patterns >= 0) free(arg_patterns[num_arg_patterns]); diff --git a/src/bin/psql/describe.c b/src/bin/psql/describe.c index ce04dbb9ce..d6e3fee154 100644 --- a/src/bin/psql/describe.c +++ b/src/bin/psql/describe.c @@ -32,7 +32,7 @@ static const char *map_typename_pattern(const char *pattern); static bool describeOneTableDetails(const char *schemaname, const char *relationname, const char *oid, - bool verbose); + int verbose); static void add_tablespace_footer(printTableContent *const cont, char relkind, Oid tablespace, const bool newline); static void add_role_attribute(PQExpBuffer buf, const char *const str); @@ -61,7 +61,7 @@ static bool listOneExtensionContents(const char *extname, const char *oid); * Takes an optional regexp to select particular aggregates */ bool -describeAggregates(const char *pattern, bool verbose, bool showSystem) +describeAggregates(const char *pattern, int verbose, bool showSystem) { PQExpBufferData buf; PGresult *res; @@ -177,7 +177,7 @@ describeAccessMethods(const char *pattern, int verbose) gettext_noop("Table"), gettext_noop("Type")); - if (verbose) + if (verbose > 0) { appendPQExpBuffer(&buf, ",\n amhandler AS \"%s\",\n" @@ -257,13 +257,13 @@ describeTablespaces(const char *pattern, int verbose) gettext_noop("Owner"), gettext_noop("Location")); - if (verbose) + if (verbose > 0) { appendPQExpBufferStr(&buf, ",\n "); printACLColumn(&buf, "spcacl"); } - if (verbose && pset.sversion >= 90000) + if (verbose > 0 && pset.sversion >= 90000) appendPQExpBuffer(&buf, ",\n spcoptions AS \"%s\"", gettext_noop("Options")); @@ -273,7 +273,7 @@ describeTablespaces(const char *pattern, int verbose) ",\n pg_catalog.pg_size_pretty(pg_catalog.pg_tablespace_size(oid)) AS \"%s\"", gettext_noop("Size")); - if (verbose && pset.sversion >= 80200) + if (verbose > 0 && pset.sversion >= 80200) appendPQExpBuffer(&buf, ",\n pg_catalog.shobj_description(oid, 'pg_tablespace') AS \"%s\"", gettext_noop("Description")); @@ -320,7 +320,7 @@ describeTablespaces(const char *pattern, int verbose) bool describeFunctions(const char *functypes, const char *func_pattern, char **arg_patterns, int num_arg_patterns, - bool verbose, bool showSystem) + int verbose, bool showSystem) { bool showAggregate = strchr(functypes, 'a') != NULL; bool showNormal = strchr(functypes, 'n') != NULL; @@ -480,7 +480,7 @@ describeFunctions(const char *functypes, const char *func_pattern, gettext_noop("func"), gettext_noop("Type")); - if (verbose) + if (verbose > 0) { appendPQExpBuffer(&buf, ",\n CASE\n" @@ -540,7 +540,7 @@ describeFunctions(const char *functypes, const char *func_pattern, i, i, i, i, i, i); } - if (verbose) + if (verbose > 0) appendPQExpBufferStr(&buf, " LEFT JOIN pg_catalog.pg_language l ON l.oid = p.prolang\n"); @@ -719,7 +719,7 @@ describeFunctions(const char *functypes, const char *func_pattern, * describe types */ bool -describeTypes(const char *pattern, bool verbose, bool showSystem) +describeTypes(const char *pattern, int verbose, bool showSystem) { PQExpBufferData buf; PGresult *res; @@ -732,7 +732,7 @@ describeTypes(const char *pattern, bool verbose, bool showSystem) " pg_catalog.format_type(t.oid, NULL) AS \"%s\",\n", gettext_noop("Schema"), gettext_noop("Name")); - if (verbose) + if (verbose > 0) appendPQExpBuffer(&buf, " t.typname AS \"%s\",\n" " CASE WHEN t.typrelid != 0\n" @@ -743,7 +743,7 @@ describeTypes(const char *pattern, bool verbose, bool showSystem) " END AS \"%s\",\n", gettext_noop("Internal name"), gettext_noop("Size")); - if (verbose && pset.sversion >= 80300) + if (verbose > 0 && pset.sversion >= 80300) { appendPQExpBufferStr(&buf, " pg_catalog.array_to_string(\n" @@ -765,13 +765,13 @@ describeTypes(const char *pattern, bool verbose, bool showSystem) " ) AS \"%s\",\n", gettext_noop("Elements")); } - if (verbose) + if (verbose > 0) { appendPQExpBuffer(&buf, " pg_catalog.pg_get_userbyid(t.typowner) AS \"%s\",\n", gettext_noop("Owner")); } - if (verbose && pset.sversion >= 90200) + if (verbose > 0 && pset.sversion >= 90200) { printACLColumn(&buf, "t.typacl"); appendPQExpBufferStr(&buf, ",\n "); @@ -895,7 +895,7 @@ map_typename_pattern(const char *pattern) bool describeOperators(const char *oper_pattern, char **arg_patterns, int num_arg_patterns, - bool verbose, bool showSystem) + int verbose, bool showSystem) { PQExpBufferData buf; PGresult *res; @@ -932,7 +932,7 @@ describeOperators(const char *oper_pattern, gettext_noop("Right arg type"), gettext_noop("Result type")); - if (verbose) + if (verbose > 0) appendPQExpBuffer(&buf, " o.oprcode AS \"%s\",\n", gettext_noop("Function")); @@ -1058,17 +1058,17 @@ listAllDbs(const char *pattern, int verbose) " ELSE 'No Access'\n" " END as \"%s\"", gettext_noop("Size")); - if (verbose && pset.sversion >= 80000) + if (verbose > 0 && pset.sversion >= 80000) appendPQExpBuffer(&buf, ",\n t.spcname as \"%s\"", gettext_noop("Tablespace")); - if (verbose && pset.sversion >= 80200) + if (verbose > 0 && pset.sversion >= 80200) appendPQExpBuffer(&buf, ",\n pg_catalog.shobj_description(d.oid, 'pg_database') as \"%s\"", gettext_noop("Description")); appendPQExpBufferStr(&buf, "\nFROM pg_catalog.pg_database d\n"); - if (verbose && pset.sversion >= 80000) + if (verbose > 0 && pset.sversion >= 80000) appendPQExpBufferStr(&buf, " JOIN pg_catalog.pg_tablespace t on d.dattablespace = t.oid\n"); @@ -1532,10 +1532,10 @@ objectDescription(const char *pattern, bool showSystem) * This routine finds the tables to be displayed, and calls * describeOneTableDetails for each one. * - * verbose: if true, this is \d+ + * verbose: this is \d+ (or \d++) */ bool -describeTableDetails(const char *pattern, bool verbose, bool showSystem) +describeTableDetails(const char *pattern, int verbose, bool showSystem) { PQExpBufferData buf; PGresult *res; @@ -1616,7 +1616,7 @@ static bool describeOneTableDetails(const char *schemaname, const char *relationname, const char *oid, - bool verbose) + int verbose) { bool retval = false; PQExpBufferData buf; @@ -2055,7 +2055,7 @@ describeOneTableDetails(const char *schemaname, " pg_catalog.pg_options_to_table(attfdwoptions)), ', ') || ')' END AS attfdwoptions"); fdwopts_col = cols++; } - if (verbose) + if (verbose > 0) { appendPQExpBufferStr(&buf, ",\n a.attstorage"); attstorage_col = cols++; @@ -2318,7 +2318,7 @@ describeOneTableDetails(const char *schemaname, "false as inhdetachpending"); /* If verbose, also request the partition constraint definition */ - if (verbose) + if (verbose > 0) appendPQExpBufferStr(&buf, ",\n pg_catalog.pg_get_partition_constraintdef(c.oid)"); appendPQExpBuffer(&buf, @@ -2341,7 +2341,7 @@ describeOneTableDetails(const char *schemaname, strcmp(detached, "t") == 0 ? " DETACH PENDING" : ""); printTableAddFooter(&cont, tmpbuf.data); - if (verbose) + if (verbose > 0) { char *partconstraintdef = NULL; @@ -3548,7 +3548,7 @@ describeOneTableDetails(const char *schemaname, printfPQExpBuffer(&buf, _("Number of partitions: %d"), tuples); printTableAddFooter(&cont, buf.data); } - else if (!verbose) + else if (verbose == 0) { /* print the number of child tables, if any */ if (tuples > 0) @@ -3598,7 +3598,7 @@ describeOneTableDetails(const char *schemaname, printTableAddFooter(&cont, buf.data); } - if (verbose && + if (verbose > 0 && (tableinfo.relkind == RELKIND_RELATION || tableinfo.relkind == RELKIND_MATVIEW) && @@ -3622,7 +3622,7 @@ describeOneTableDetails(const char *schemaname, } /* OIDs, if verbose and not a materialized view */ - if (verbose && tableinfo.relkind != RELKIND_MATVIEW && tableinfo.hasoids) + if (verbose > 0 && tableinfo.relkind != RELKIND_MATVIEW && tableinfo.hasoids) printTableAddFooter(&cont, _("Has OIDs: yes")); /* Tablespace info */ @@ -3630,7 +3630,7 @@ describeOneTableDetails(const char *schemaname, true); /* Access method info */ - if (verbose && tableinfo.relam != NULL && !pset.hide_tableam) + if (verbose > 0 && tableinfo.relam != NULL && !pset.hide_tableam) { printfPQExpBuffer(&buf, _("Access method: %s"), tableinfo.relam); printTableAddFooter(&cont, buf.data); @@ -3638,7 +3638,7 @@ describeOneTableDetails(const char *schemaname, } /* reloptions, if verbose */ - if (verbose && + if (verbose > 0 && tableinfo.reloptions && tableinfo.reloptions[0] != '\0') { const char *t = _("Options"); @@ -3741,7 +3741,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, bool showSystem) +describeRoles(const char *pattern, int verbose, bool showSystem) { PQExpBufferData buf; PGresult *res; @@ -3769,7 +3769,7 @@ describeRoles(const char *pattern, bool verbose, bool showSystem) " JOIN pg_catalog.pg_roles b ON (m.roleid = b.oid)\n" " WHERE m.member = r.oid) as memberof"); - if (verbose && pset.sversion >= 80200) + if (verbose > 0 && pset.sversion >= 80200) { appendPQExpBufferStr(&buf, "\n, pg_catalog.shobj_description(r.oid, 'pg_authid') AS description"); ncols++; @@ -3824,7 +3824,7 @@ describeRoles(const char *pattern, bool verbose, bool showSystem) /* ignores implicit memberships from superuser & pg_database_owner */ printTableAddHeader(&cont, gettext_noop("Member of"), true, align); - if (verbose && pset.sversion >= 80200) + if (verbose > 0 && pset.sversion >= 80200) printTableAddHeader(&cont, gettext_noop("Description"), true, align); for (i = 0; i < nrows; i++) @@ -3884,7 +3884,7 @@ describeRoles(const char *pattern, bool verbose, bool showSystem) printTableAddCell(&cont, PQgetvalue(res, i, 8), false, false); - if (verbose && pset.sversion >= 80200) + if (verbose > 0 && pset.sversion >= 80200) printTableAddCell(&cont, PQgetvalue(res, i, 9), false, false); } termPQExpBuffer(&buf); @@ -3997,7 +3997,7 @@ listDbRoleSettings(const char *pattern, const char *pattern2) * (any order of the above is fine) */ bool -listTables(const char *tabtypes, const char *pattern, bool verbose, bool showSystem) +listTables(const char *tabtypes, const char *pattern, int verbose, bool showSystem) { bool showTables = strchr(tabtypes, 't') != NULL; bool showIndexes = strchr(tabtypes, 'i') != NULL; @@ -4062,7 +4062,7 @@ listTables(const char *tabtypes, const char *pattern, bool verbose, bool showSys cols_so_far++; } - if (verbose) + if (verbose > 0) { /* * Show whether a relation is permanent, temporary, or unlogged. Like @@ -4213,7 +4213,7 @@ listTables(const char *tabtypes, const char *pattern, bool verbose, bool showSys * and you can mix and match these in any order. */ bool -listPartitionedTables(const char *reltypes, const char *pattern, bool verbose) +listPartitionedTables(const char *reltypes, const char *pattern, int verbose) { bool showTables = strchr(reltypes, 't') != NULL; bool showIndexes = strchr(reltypes, 'i') != NULL; @@ -4288,7 +4288,7 @@ listPartitionedTables(const char *reltypes, const char *pattern, bool verbose) ",\n c2.oid::regclass as \"%s\"", gettext_noop("Table")); - if (verbose) + if (verbose > 0) { if (showNested) { @@ -4323,7 +4323,7 @@ listPartitionedTables(const char *reltypes, const char *pattern, bool verbose) appendPQExpBufferStr(&buf, "\n LEFT JOIN pg_catalog.pg_inherits inh ON c.oid = inh.inhrelid"); - if (verbose) + if (verbose > 0) { if (pset.sversion < 120000) { @@ -4409,7 +4409,7 @@ listPartitionedTables(const char *reltypes, const char *pattern, bool verbose) * Describes languages. */ bool -listLanguages(const char *pattern, bool verbose, bool showSystem) +listLanguages(const char *pattern, int verbose, bool showSystem) { PQExpBufferData buf; PGresult *res; @@ -4429,7 +4429,7 @@ listLanguages(const char *pattern, bool verbose, bool showSystem) " l.lanpltrusted AS \"%s\"", gettext_noop("Trusted")); - if (verbose) + if (verbose > 0) { appendPQExpBuffer(&buf, ",\n NOT l.lanispl AS \"%s\",\n" @@ -4484,7 +4484,7 @@ listLanguages(const char *pattern, bool verbose, bool showSystem) * Describes domains. */ bool -listDomains(const char *pattern, bool verbose, bool showSystem) +listDomains(const char *pattern, int verbose, bool showSystem) { PQExpBufferData buf; PGresult *res; @@ -4515,7 +4515,7 @@ listDomains(const char *pattern, bool verbose, bool showSystem) gettext_noop("Default"), gettext_noop("Check")); - if (verbose) + if (verbose > 0) { if (pset.sversion >= 90200) { @@ -4531,7 +4531,7 @@ listDomains(const char *pattern, bool verbose, bool showSystem) "\nFROM pg_catalog.pg_type t\n" " LEFT JOIN pg_catalog.pg_namespace n ON n.oid = t.typnamespace\n"); - if (verbose) + if (verbose > 0) appendPQExpBufferStr(&buf, " LEFT JOIN pg_catalog.pg_description d " "ON d.classoid = t.tableoid AND d.objoid = t.oid " @@ -4570,7 +4570,7 @@ listDomains(const char *pattern, bool verbose, bool showSystem) * Describes conversions. */ bool -listConversions(const char *pattern, bool verbose, bool showSystem) +listConversions(const char *pattern, int verbose, bool showSystem) { PQExpBufferData buf; PGresult *res; @@ -4594,7 +4594,7 @@ listConversions(const char *pattern, bool verbose, bool showSystem) gettext_noop("yes"), gettext_noop("no"), gettext_noop("Default?")); - if (verbose) + if (verbose > 0) appendPQExpBuffer(&buf, ",\n d.description AS \"%s\"", gettext_noop("Description")); @@ -4604,7 +4604,7 @@ listConversions(const char *pattern, bool verbose, bool showSystem) " JOIN pg_catalog.pg_namespace n " "ON n.oid = c.connamespace\n"); - if (verbose) + if (verbose > 0) appendPQExpBufferStr(&buf, "LEFT JOIN pg_catalog.pg_description d " "ON d.classoid = c.tableoid\n" @@ -4646,7 +4646,7 @@ listConversions(const char *pattern, bool verbose, bool showSystem) * Describes Event Triggers. */ bool -listEventTriggers(const char *pattern, bool verbose) +listEventTriggers(const char *pattern, int verbose) { PQExpBufferData buf; PGresult *res; @@ -4677,7 +4677,7 @@ listEventTriggers(const char *pattern, bool verbose) gettext_noop("Enabled"), gettext_noop("Function"), gettext_noop("Tags")); - if (verbose) + if (verbose > 0) appendPQExpBuffer(&buf, ",\npg_catalog.obj_description(e.oid, 'pg_event_trigger') as \"%s\"", gettext_noop("Description")); @@ -4804,7 +4804,7 @@ listExtendedStats(const char *pattern) * Describes casts. */ bool -listCasts(const char *pattern, bool verbose) +listCasts(const char *pattern, int verbose) { PQExpBufferData buf; PGresult *res; @@ -4852,7 +4852,7 @@ listCasts(const char *pattern, bool verbose) gettext_noop("yes"), gettext_noop("Implicit?")); - if (verbose) + if (verbose > 0) appendPQExpBuffer(&buf, ",\n d.description AS \"%s\"", gettext_noop("Description")); @@ -4873,7 +4873,7 @@ listCasts(const char *pattern, bool verbose) " LEFT JOIN pg_catalog.pg_namespace nt\n" " ON nt.oid = tt.typnamespace\n"); - if (verbose) + if (verbose > 0) appendPQExpBufferStr(&buf, " LEFT JOIN pg_catalog.pg_description d\n" " ON d.classoid = c.tableoid AND d.objoid = " @@ -4922,7 +4922,7 @@ listCasts(const char *pattern, bool verbose) * Describes collations. */ bool -listCollations(const char *pattern, bool verbose, bool showSystem) +listCollations(const char *pattern, int verbose, bool showSystem) { PQExpBufferData buf; PGresult *res; @@ -4971,7 +4971,7 @@ listCollations(const char *pattern, bool verbose, bool showSystem) gettext_noop("yes"), gettext_noop("Deterministic?")); - if (verbose) + if (verbose > 0) appendPQExpBuffer(&buf, ",\n pg_catalog.obj_description(c.oid, 'pg_collation') AS \"%s\"", gettext_noop("Description")); @@ -5034,7 +5034,7 @@ listSchemas(const char *pattern, int verbose, bool showSystem) gettext_noop("Name"), gettext_noop("Owner")); - if (verbose) + if (verbose > 0) { appendPQExpBufferStr(&buf, ",\n "); printACLColumn(&buf, "n.nspacl"); @@ -5083,7 +5083,7 @@ listSchemas(const char *pattern, int verbose, bool showSystem) * list text search parsers */ bool -listTSParsers(const char *pattern, bool verbose) +listTSParsers(const char *pattern, int verbose) { PQExpBufferData buf; PGresult *res; @@ -5099,7 +5099,7 @@ listTSParsers(const char *pattern, bool verbose) return true; } - if (verbose) + if (verbose > 0) return listTSParsersVerbose(pattern); initPQExpBuffer(&buf); @@ -5330,7 +5330,7 @@ describeOneTSParser(const char *oid, const char *nspname, const char *prsname) * list text search dictionaries */ bool -listTSDictionaries(const char *pattern, bool verbose) +listTSDictionaries(const char *pattern, int verbose) { PQExpBufferData buf; PGresult *res; @@ -5355,7 +5355,7 @@ listTSDictionaries(const char *pattern, bool verbose) gettext_noop("Schema"), gettext_noop("Name")); - if (verbose) + if (verbose > 0) { appendPQExpBuffer(&buf, " ( SELECT COALESCE(nt.nspname, '(null)')::pg_catalog.text || '.' || t.tmplname FROM\n" @@ -5401,7 +5401,7 @@ listTSDictionaries(const char *pattern, bool verbose) * list text search templates */ bool -listTSTemplates(const char *pattern, bool verbose) +listTSTemplates(const char *pattern, int verbose) { PQExpBufferData buf; PGresult *res; @@ -5419,7 +5419,7 @@ listTSTemplates(const char *pattern, bool verbose) initPQExpBuffer(&buf); - if (verbose) + if (verbose > 0) printfPQExpBuffer(&buf, "SELECT\n" " n.nspname AS \"%s\",\n" @@ -5472,7 +5472,7 @@ listTSTemplates(const char *pattern, bool verbose) * list text search configurations */ bool -listTSConfigs(const char *pattern, bool verbose) +listTSConfigs(const char *pattern, int verbose) { PQExpBufferData buf; PGresult *res; @@ -5488,7 +5488,7 @@ listTSConfigs(const char *pattern, bool verbose) return true; } - if (verbose) + if (verbose > 0) return listTSConfigsVerbose(pattern); initPQExpBuffer(&buf); @@ -5678,7 +5678,7 @@ describeOneTSConfig(const char *oid, const char *nspname, const char *cfgname, * Describes foreign-data wrappers */ bool -listForeignDataWrappers(const char *pattern, bool verbose) +listForeignDataWrappers(const char *pattern, int verbose) { PQExpBufferData buf; PGresult *res; @@ -5708,7 +5708,7 @@ listForeignDataWrappers(const char *pattern, bool verbose) " fdw.fdwvalidator::pg_catalog.regproc AS \"%s\"", gettext_noop("Validator")); - if (verbose) + if (verbose > 0) { appendPQExpBufferStr(&buf, ",\n "); printACLColumn(&buf, "fdwacl"); @@ -5729,7 +5729,7 @@ listForeignDataWrappers(const char *pattern, bool verbose) appendPQExpBufferStr(&buf, "\nFROM pg_catalog.pg_foreign_data_wrapper fdw\n"); - if (verbose && pset.sversion >= 90100) + if (verbose > 0 && pset.sversion >= 90100) appendPQExpBufferStr(&buf, "LEFT JOIN pg_catalog.pg_description d\n" " ON d.classoid = fdw.tableoid " @@ -5761,7 +5761,7 @@ listForeignDataWrappers(const char *pattern, bool verbose) * Describes foreign servers. */ bool -listForeignServers(const char *pattern, bool verbose) +listForeignServers(const char *pattern, int verbose) { PQExpBufferData buf; PGresult *res; @@ -5786,7 +5786,7 @@ listForeignServers(const char *pattern, bool verbose) gettext_noop("Owner"), gettext_noop("Foreign-data wrapper")); - if (verbose) + if (verbose > 0) { appendPQExpBufferStr(&buf, ",\n "); printACLColumn(&buf, "s.srvacl"); @@ -5811,7 +5811,7 @@ listForeignServers(const char *pattern, bool verbose) "\nFROM pg_catalog.pg_foreign_server s\n" " JOIN pg_catalog.pg_foreign_data_wrapper f ON f.oid=s.srvfdw\n"); - if (verbose) + if (verbose > 0) appendPQExpBufferStr(&buf, "LEFT JOIN pg_catalog.pg_description d\n " "ON d.classoid = s.tableoid AND d.objoid = s.oid " @@ -5843,7 +5843,7 @@ listForeignServers(const char *pattern, bool verbose) * Describes user mappings. */ bool -listUserMappings(const char *pattern, bool verbose) +listUserMappings(const char *pattern, int verbose) { PQExpBufferData buf; PGresult *res; @@ -5866,7 +5866,7 @@ listUserMappings(const char *pattern, bool verbose) gettext_noop("Server"), gettext_noop("User name")); - if (verbose) + if (verbose > 0) appendPQExpBuffer(&buf, ",\n CASE WHEN umoptions IS NULL THEN '' ELSE " " '(' || pg_catalog.array_to_string(ARRAY(SELECT " @@ -5904,7 +5904,7 @@ listUserMappings(const char *pattern, bool verbose) * Describes foreign tables. */ bool -listForeignTables(const char *pattern, bool verbose) +listForeignTables(const char *pattern, int verbose) { PQExpBufferData buf; PGresult *res; @@ -5929,7 +5929,7 @@ listForeignTables(const char *pattern, bool verbose) gettext_noop("Table"), gettext_noop("Server")); - if (verbose) + if (verbose > 0) appendPQExpBuffer(&buf, ",\n CASE WHEN ftoptions IS NULL THEN '' ELSE " " '(' || pg_catalog.array_to_string(ARRAY(SELECT " @@ -5949,7 +5949,7 @@ listForeignTables(const char *pattern, bool verbose) " ON n.oid = c.relnamespace\n" " INNER JOIN pg_catalog.pg_foreign_server s" " ON s.oid = ft.ftserver\n"); - if (verbose) + if (verbose > 0) appendPQExpBufferStr(&buf, " LEFT JOIN pg_catalog.pg_description d\n" " ON d.classoid = c.tableoid AND " @@ -6393,7 +6393,7 @@ describePublications(const char *pattern) * Takes an optional regexp to select particular subscriptions */ bool -describeSubscriptions(const char *pattern, bool verbose) +describeSubscriptions(const char *pattern, int verbose) { PQExpBufferData buf; PGresult *res; @@ -6423,7 +6423,7 @@ describeSubscriptions(const char *pattern, bool verbose) gettext_noop("Enabled"), gettext_noop("Publication")); - if (verbose) + if (verbose > 0) { /* Binary mode and streaming are only supported in v14 and higher */ if (pset.sversion >= 140000) @@ -6504,7 +6504,7 @@ printACLColumn(PQExpBuffer buf, const char *colname) */ bool listOperatorClasses(const char *access_method_pattern, - const char *type_pattern, bool verbose) + const char *type_pattern, int verbose) { PQExpBufferData buf; PGresult *res; @@ -6539,7 +6539,7 @@ listOperatorClasses(const char *access_method_pattern, gettext_noop("yes"), gettext_noop("no"), gettext_noop("Default?")); - if (verbose) + if (verbose > 0) appendPQExpBuffer(&buf, ",\n CASE\n" " WHEN pg_catalog.pg_opfamily_is_visible(of.oid)\n" @@ -6555,7 +6555,7 @@ listOperatorClasses(const char *access_method_pattern, " LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.opcnamespace\n" " LEFT JOIN pg_catalog.pg_type t ON t.oid = c.opcintype\n" " LEFT JOIN pg_catalog.pg_namespace tn ON tn.oid = t.typnamespace\n"); - if (verbose) + if (verbose > 0) appendPQExpBufferStr(&buf, " LEFT JOIN pg_catalog.pg_opfamily of ON of.oid = c.opcfamily\n" " LEFT JOIN pg_catalog.pg_namespace ofn ON ofn.oid = of.opfnamespace\n"); @@ -6598,7 +6598,7 @@ listOperatorClasses(const char *access_method_pattern, */ bool listOperatorFamilies(const char *access_method_pattern, - const char *type_pattern, bool verbose) + const char *type_pattern, int verbose) { PQExpBufferData buf; PGresult *res; @@ -6623,7 +6623,7 @@ listOperatorFamilies(const char *access_method_pattern, gettext_noop("AM"), gettext_noop("Operator family"), gettext_noop("Applicable types")); - if (verbose) + if (verbose > 0) appendPQExpBuffer(&buf, ",\n pg_catalog.pg_get_userbyid(f.opfowner) AS \"%s\"\n", gettext_noop("Owner")); @@ -6680,7 +6680,7 @@ listOperatorFamilies(const char *access_method_pattern, */ bool listOpFamilyOperators(const char *access_method_pattern, - const char *family_pattern, bool verbose) + const char *family_pattern, int verbose) { PQExpBufferData buf; PGresult *res; @@ -6713,7 +6713,7 @@ listOpFamilyOperators(const char *access_method_pattern, gettext_noop("search"), gettext_noop("Purpose")); - if (verbose) + if (verbose > 0) appendPQExpBuffer(&buf, ", ofs.opfname AS \"%s\"\n", gettext_noop("Sort opfamily")); @@ -6722,7 +6722,7 @@ listOpFamilyOperators(const char *access_method_pattern, " LEFT JOIN pg_catalog.pg_opfamily of ON of.oid = o.amopfamily\n" " LEFT JOIN pg_catalog.pg_am am ON am.oid = of.opfmethod AND am.oid = o.amopmethod\n" " LEFT JOIN pg_catalog.pg_namespace nsf ON of.opfnamespace = nsf.oid\n"); - if (verbose) + if (verbose > 0) appendPQExpBufferStr(&buf, " LEFT JOIN pg_catalog.pg_opfamily ofs ON ofs.oid = o.amopsortfamily\n"); @@ -6767,7 +6767,7 @@ listOpFamilyOperators(const char *access_method_pattern, */ bool listOpFamilyFunctions(const char *access_method_pattern, - const char *family_pattern, bool verbose) + const char *family_pattern, int verbose) { PQExpBufferData buf; PGresult *res; @@ -6794,7 +6794,7 @@ listOpFamilyFunctions(const char *access_method_pattern, gettext_noop("Registered right type"), gettext_noop("Number")); - if (!verbose) + if (verbose == 0) appendPQExpBuffer(&buf, ", p.proname AS \"%s\"\n", gettext_noop("Function")); diff --git a/src/bin/psql/describe.h b/src/bin/psql/describe.h index edeea38580..cdf286242b 100644 --- a/src/bin/psql/describe.h +++ b/src/bin/psql/describe.h @@ -10,7 +10,7 @@ /* \da */ -extern bool describeAggregates(const char *pattern, bool verbose, bool showSystem); +extern bool describeAggregates(const char *pattern, int verbose, bool showSystem); /* \dA */ extern bool describeAccessMethods(const char *pattern, int verbose); @@ -21,18 +21,18 @@ extern bool describeTablespaces(const char *pattern, int verbose); /* \df, \dfa, \dfn, \dft, \dfw, etc. */ extern bool describeFunctions(const char *functypes, const char *func_pattern, char **arg_patterns, int num_arg_patterns, - bool verbose, bool showSystem); + int verbose, bool showSystem); /* \dT */ -extern bool describeTypes(const char *pattern, bool verbose, bool showSystem); +extern bool describeTypes(const char *pattern, int verbose, bool showSystem); /* \do */ extern bool describeOperators(const char *oper_pattern, char **arg_patterns, int num_arg_patterns, - bool verbose, bool showSystem); + int verbose, bool showSystem); /* \du, \dg */ -extern bool describeRoles(const char *pattern, bool verbose, bool showSystem); +extern bool describeRoles(const char *pattern, int verbose, bool showSystem); /* \drds */ extern bool listDbRoleSettings(const char *pattern, const char *pattern2); @@ -47,58 +47,58 @@ extern bool listDefaultACLs(const char *pattern); extern bool objectDescription(const char *pattern, bool showSystem); /* \d foo */ -extern bool describeTableDetails(const char *pattern, bool verbose, bool showSystem); +extern bool describeTableDetails(const char *pattern, int verbose, bool showSystem); /* \dF */ -extern bool listTSConfigs(const char *pattern, bool verbose); +extern bool listTSConfigs(const char *pattern, int verbose); /* \dFp */ -extern bool listTSParsers(const char *pattern, bool verbose); +extern bool listTSParsers(const char *pattern, int verbose); /* \dFd */ -extern bool listTSDictionaries(const char *pattern, bool verbose); +extern bool listTSDictionaries(const char *pattern, int verbose); /* \dFt */ -extern bool listTSTemplates(const char *pattern, bool verbose); +extern bool listTSTemplates(const char *pattern, int verbose); /* \l */ extern bool listAllDbs(const char *pattern, int verbose); /* \dt, \di, \ds, \dS, etc. */ -extern bool listTables(const char *tabtypes, const char *pattern, bool verbose, bool showSystem); +extern bool listTables(const char *tabtypes, const char *pattern, int verbose, bool showSystem); /* \dP */ -extern bool listPartitionedTables(const char *reltypes, const char *pattern, bool verbose); +extern bool listPartitionedTables(const char *reltypes, const char *pattern, int verbose); /* \dD */ -extern bool listDomains(const char *pattern, bool verbose, bool showSystem); +extern bool listDomains(const char *pattern, int verbose, bool showSystem); /* \dc */ -extern bool listConversions(const char *pattern, bool verbose, bool showSystem); +extern bool listConversions(const char *pattern, int verbose, bool showSystem); /* \dC */ -extern bool listCasts(const char *pattern, bool verbose); +extern bool listCasts(const char *pattern, int verbose); /* \dO */ -extern bool listCollations(const char *pattern, bool verbose, bool showSystem); +extern bool listCollations(const char *pattern, int verbose, bool showSystem); /* \dn */ extern bool listSchemas(const char *pattern, int verbose, bool showSystem); /* \dew */ -extern bool listForeignDataWrappers(const char *pattern, bool verbose); +extern bool listForeignDataWrappers(const char *pattern, int verbose); /* \des */ -extern bool listForeignServers(const char *pattern, bool verbose); +extern bool listForeignServers(const char *pattern, int verbose); /* \deu */ -extern bool listUserMappings(const char *pattern, bool verbose); +extern bool listUserMappings(const char *pattern, int verbose); /* \det */ -extern bool listForeignTables(const char *pattern, bool verbose); +extern bool listForeignTables(const char *pattern, int verbose); /* \dL */ -extern bool listLanguages(const char *pattern, bool verbose, bool showSystem); +extern bool listLanguages(const char *pattern, int verbose, bool showSystem); /* \dx */ extern bool listExtensions(const char *pattern); @@ -110,7 +110,7 @@ extern bool listExtensionContents(const char *pattern); extern bool listExtendedStats(const char *pattern); /* \dy */ -extern bool listEventTriggers(const char *pattern, bool verbose); +extern bool listEventTriggers(const char *pattern, int verbose); /* \dRp */ bool listPublications(const char *pattern); @@ -119,25 +119,25 @@ bool listPublications(const char *pattern); bool describePublications(const char *pattern); /* \dRs */ -bool describeSubscriptions(const char *pattern, bool verbose); +bool describeSubscriptions(const char *pattern, int verbose); /* \dAc */ extern bool listOperatorClasses(const char *access_method_pattern, const char *opclass_pattern, - bool verbose); + int verbose); /* \dAf */ extern bool listOperatorFamilies(const char *access_method_pattern, const char *opclass_pattern, - bool verbose); + int verbose); /* \dAo */ extern bool listOpFamilyOperators(const char *accessMethod_pattern, - const char *family_pattern, bool verbose); + const char *family_pattern, int verbose); /* \dAp */ extern bool listOpFamilyFunctions(const char *access_method_pattern, - const char *family_pattern, bool verbose); + const char *family_pattern, int verbose); #endif /* DESCRIBE_H */ -- 2.17.0
>From 4dd48f8ce389d176bf153dcfce601558b9e823fb Mon Sep 17 00:00:00 2001 From: Justin Pryzby <pryz...@telsasoft.com> Date: Thu, 15 Jul 2021 13:35:26 -0500 Subject: [PATCH v3 4/4] Move the double-plus verbose options to the right-most column --- src/bin/psql/describe.c | 27 +++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/src/bin/psql/describe.c b/src/bin/psql/describe.c index d6e3fee154..2829d3c0f1 100644 --- a/src/bin/psql/describe.c +++ b/src/bin/psql/describe.c @@ -268,16 +268,16 @@ describeTablespaces(const char *pattern, int verbose) ",\n spcoptions AS \"%s\"", gettext_noop("Options")); - if (verbose > 1 && pset.sversion >= 90200) - appendPQExpBuffer(&buf, - ",\n pg_catalog.pg_size_pretty(pg_catalog.pg_tablespace_size(oid)) AS \"%s\"", - gettext_noop("Size")); - if (verbose > 0 && pset.sversion >= 80200) appendPQExpBuffer(&buf, ",\n pg_catalog.shobj_description(oid, 'pg_tablespace') AS \"%s\"", gettext_noop("Description")); + if (verbose > 1 && pset.sversion >= 90200) + appendPQExpBuffer(&buf, + ",\n pg_catalog.pg_size_pretty(pg_catalog.pg_tablespace_size(oid)) AS \"%s\"", + gettext_noop("Size")); + appendPQExpBufferStr(&buf, "\nFROM pg_catalog.pg_tablespace\n"); @@ -1051,13 +1051,7 @@ listAllDbs(const char *pattern, int verbose) gettext_noop("Ctype")); appendPQExpBufferStr(&buf, " "); printACLColumn(&buf, "d.datacl"); - if (verbose > 1 && pset.sversion >= 80200) - appendPQExpBuffer(&buf, - ",\n CASE WHEN pg_catalog.has_database_privilege(d.datname, 'CONNECT')\n" - " THEN pg_catalog.pg_size_pretty(pg_catalog.pg_database_size(d.datname))\n" - " ELSE 'No Access'\n" - " END as \"%s\"", - gettext_noop("Size")); + if (verbose > 0 && pset.sversion >= 80000) appendPQExpBuffer(&buf, ",\n t.spcname as \"%s\"", @@ -1066,6 +1060,15 @@ listAllDbs(const char *pattern, int verbose) appendPQExpBuffer(&buf, ",\n pg_catalog.shobj_description(d.oid, 'pg_database') as \"%s\"", gettext_noop("Description")); + + if (verbose > 1 && pset.sversion >= 80200) + appendPQExpBuffer(&buf, + ",\n CASE WHEN pg_catalog.has_database_privilege(d.datname, 'CONNECT')\n" + " THEN pg_catalog.pg_size_pretty(pg_catalog.pg_database_size(d.datname))\n" + " ELSE 'No Access'\n" + " END as \"%s\"", + gettext_noop("Size")); + appendPQExpBufferStr(&buf, "\nFROM pg_catalog.pg_database d\n"); if (verbose > 0 && pset.sversion >= 80000) -- 2.17.0