Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.89) (envelope-from ) id 1iTumE-0006Qk-4A for pgsql-hackers@arkaria.postgresql.org; Sun, 10 Nov 2019 21:29:42 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.89) (envelope-from ) id 1iTumC-0001Y3-OI for pgsql-hackers@arkaria.postgresql.org; Sun, 10 Nov 2019 21:29:40 +0000 Received: from makus.postgresql.org ([2001:4800:3e1:1::229]) by malur.postgresql.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.89) (envelope-from ) id 1iTumC-0001Xw-7R for pgsql-hackers@lists.postgresql.org; Sun, 10 Nov 2019 21:29:40 +0000 Received: from mail-yw1-xc42.google.com ([2607:f8b0:4864:20::c42]) by makus.postgresql.org with esmtps (TLS1.3:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.92) (envelope-from ) id 1iTum4-0001DF-KP for pgsql-hackers@postgresql.org; Sun, 10 Nov 2019 21:29:38 +0000 Received: by mail-yw1-xc42.google.com with SMTP id j190so4543942ywf.8 for ; Sun, 10 Nov 2019 13:29:32 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=telsasoft-com.20150623.gappssmtp.com; s=20150623; h=date:from:to:subject:message-id:mime-version:content-disposition :user-agent; bh=KHgFQ4na0r8VA0LWr1kDL92UGz0WLCtWuC21OpXX8fY=; b=QguKZexEd6uvzWMzGOw0JwGONrPh6P4fIgPjwX4muDbveAco66CyQR5cZgc2BRciHk C0whDTkjV+BihdHWhUZQ95iS7TdJhzkZoUDHC3iYF4sz3/OmSohRXHJc8u+OxzaSdvil Ey6eZglIdR4MJO7j5gIQOBmDiNq3S8wkPxN6NrJDatXeOi1bP4x0GPgyLThZzWVDdUbz Thzsad/ROiIT0ZQLypZbVlcCt363OnwNM+3fO43Wrvv/zvXw+/dRAL4arPWSpooPam3F Q4D+sPkXTY4UAM0/Stfdp/qoZgIfwGeZUWBQNgdjDftnLntaO0CgQnZA+qJvQjNx89Z4 umkQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:from:to:subject:message-id:mime-version :content-disposition:user-agent; bh=KHgFQ4na0r8VA0LWr1kDL92UGz0WLCtWuC21OpXX8fY=; b=lytQHS1RAWh9k9wKIJFk5ijjA4cbKg4fTVufVlqrbFSPqTAuQNYuWlFKtUZiybBjLX 5jnzlxQWjC/Uk9qsDxnrtreXGrNgRZJxGoccNzIf+eUOGieddWmnmi1NLf3BARnTInG5 /zT5CM+govF7M/DIGCgdJ55fTn4nK+I1zVflUIZtyLPKjPokCFcJIumAi3+zikwhCQG6 DN1waZsXA1g4p5jovvVbxi4BicQnPpbOhRsPykBZJJbukhQcOq0DsTR7e6F5rvjrMert SdfChqpi57NrITYr+PJIDCnzpThHBvEfSHQS+mANxn0/GzOF1Y+2Sp7hZ+LHZ+GObDIy goYQ== X-Gm-Message-State: APjAAAWSvCxH66R4INinh/Cx/JqDtR/cXKC2uDI+rN3XUlrgIDAIQfJi BIPIIo2nHQtn8seLXuY/hSiBQNe0msk= X-Google-Smtp-Source: APXvYqwcriHtJvjVEn7c7sEa60W9tQdlbla2+5Z1rSopUN2S4g3QQRn9a7/fW6JzmbgolvMVbY0Rmg== X-Received: by 2002:a81:1189:: with SMTP id 131mr15452935ywr.308.1573421370903; Sun, 10 Nov 2019 13:29:30 -0800 (PST) Received: from pryzbyj (charmander.telsasoft.com. [50.244.222.1]) by smtp.gmail.com with ESMTPSA id s24sm4236335ywa.92.2019.11.10.13.29.29 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sun, 10 Nov 2019 13:29:30 -0800 (PST) Received: by pryzbyj (Postfix, from userid 1000) id 8D6CC800A81; Sun, 10 Nov 2019 15:29:28 -0600 (CST) Date: Sun, 10 Nov 2019 15:29:28 -0600 From: Justin Pryzby To: pgsql-hackers@postgresql.org Subject: psql \d for wide tables / pattern for individual columns Message-ID: <20191110212928.GQ4999@telsasoft.com> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="47eKBCiAZYFK5l32" Content-Disposition: inline User-Agent: Mutt/1.5.24 (2015-08-30) List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Precedence: bulk --47eKBCiAZYFK5l32 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline We have some very wide tables (historically, up to 1600 columns ; this is improved now, but sometimes still several hundred, with numerous pages output to psql pager). Is is reasonable to suggest adding a psql command to show a table's definition, without all the columns listed? Or limit display to matching columns ? That's more general than the above functionality, if "empty string" is taken to mean "show no columns", like \d table "" or \d table *id or \d table ???? Attached minimal patch for the latter. postgres=# \d pg_attribute "" Table "pg_catalog.pg_attribute" Column | Type | Collation | Nullable | Default --------+------+-----------+----------+--------- Indexes: "pg_attribute_relid_attnam_index" UNIQUE, btree (attrelid, attname) "pg_attribute_relid_attnum_index" UNIQUE, btree (attrelid, attnum) postgres=# \d pg_attribute "attn*|attrel*" Table "pg_catalog.pg_attribute" Column | Type | Collation | Nullable | Default ------------+----------+-----------+----------+--------- attrelid | oid | | not null | attname | name | | not null | attnum | smallint | | not null | attndims | integer | | not null | attnotnull | boolean | | not null | Indexes: "pg_attribute_relid_attnam_index" UNIQUE, btree (attrelid, attname) "pg_attribute_relid_attnum_index" UNIQUE, btree (attrelid, attnum) postgres=# \d pg_attribute ?????? Table "pg_catalog.pg_attribute" Column | Type | Collation | Nullable | Default --------+-----------+-----------+----------+--------- attlen | smallint | | not null | attnum | smallint | | not null | attacl | aclitem[] | | | Indexes: "pg_attribute_relid_attnam_index" UNIQUE, btree (attrelid, attname) "pg_attribute_relid_attnum_index" UNIQUE, btree (attrelid, attnum) postgres=# \d pg_attribute *id Table "pg_catalog.pg_attribute" Column | Type | Collation | Nullable | Default ----------+------+-----------+----------+--------- attrelid | oid | | not null | atttypid | oid | | not null | Indexes: "pg_attribute_relid_attnam_index" UNIQUE, btree (attrelid, attname) "pg_attribute_relid_attnum_index" UNIQUE, btree (attrelid, attnum) --47eKBCiAZYFK5l32 Content-Type: text/x-diff; charset=us-ascii Content-Disposition: attachment; filename="v1-0001-psql-Allow-filtering-columns-shown-by-d.patch" From fdcde33f93af544eb1be0f327ffa49a133397da3 Mon Sep 17 00:00:00 2001 From: Justin Pryzby Date: Sun, 10 Nov 2019 15:02:00 -0600 Subject: [PATCH v1] psql: Allow filtering columns shown by \d --- src/bin/psql/command.c | 7 +++++-- src/bin/psql/describe.c | 26 ++++++++++++++++---------- src/bin/psql/describe.h | 2 +- 3 files changed, 22 insertions(+), 13 deletions(-) diff --git a/src/bin/psql/command.c b/src/bin/psql/command.c index ecfa1bc..7746f63 100644 --- a/src/bin/psql/command.c +++ b/src/bin/psql/command.c @@ -699,13 +699,16 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd) if (active_branch) { - char *pattern; + char *pattern, *pattern2, quote; bool show_verbose, show_system; /* We don't do SQLID reduction on the pattern yet */ pattern = psql_scan_slash_option(scan_state, OT_NORMAL, NULL, true); + if (pattern) + pattern2 = psql_scan_slash_option(scan_state, + OT_SQLID, "e, true); show_verbose = strchr(cmd, '+') ? true : false; show_system = strchr(cmd, 'S') ? true : false; @@ -716,7 +719,7 @@ 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, show_verbose, show_system, pattern2); else /* standard listing of interesting things */ success = listTables("tvmsE", NULL, show_verbose, show_system); diff --git a/src/bin/psql/describe.c b/src/bin/psql/describe.c index 02740dd..dce4a4e 100644 --- a/src/bin/psql/describe.c +++ b/src/bin/psql/describe.c @@ -30,7 +30,8 @@ static bool describeOneTableDetails(const char *schemaname, const char *relationname, const char *oid, - bool verbose); + bool verbose, + const char *pattern2); 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); @@ -1363,7 +1364,7 @@ objectDescription(const char *pattern, bool showSystem) * verbose: if true, this is \d+ */ bool -describeTableDetails(const char *pattern, bool verbose, bool showSystem) +describeTableDetails(const char *pattern, bool verbose, bool showSystem, const char *pattern2) { PQExpBufferData buf; PGresult *res; @@ -1417,7 +1418,7 @@ describeTableDetails(const char *pattern, bool verbose, bool showSystem) nspname = PQgetvalue(res, i, 1); relname = PQgetvalue(res, i, 2); - if (!describeOneTableDetails(nspname, relname, oid, verbose)) + if (!describeOneTableDetails(nspname, relname, oid, verbose, pattern2)) { PQclear(res); return false; @@ -1444,7 +1445,8 @@ static bool describeOneTableDetails(const char *schemaname, const char *relationname, const char *oid, - bool verbose) + bool verbose, + const char *pattern2) { bool retval = false; PQExpBufferData buf; @@ -1917,12 +1919,16 @@ describeOneTableDetails(const char *schemaname, appendPQExpBufferStr(&buf, "\nFROM pg_catalog.pg_attribute a"); appendPQExpBuffer(&buf, "\nWHERE a.attrelid = '%s' AND a.attnum > 0 AND NOT a.attisdropped", oid); - appendPQExpBufferStr(&buf, "\nORDER BY a.attnum;"); - - res = PSQLexec(buf.data); - if (!res) - goto error_return; - numrows = PQntuples(res); + if (pattern2 && !*pattern2) { + numrows = 0; + } else { + processSQLNamePattern(pset.db, &buf, pattern2, true, false, NULL, "attname", NULL, NULL); + appendPQExpBufferStr(&buf, "\nORDER BY a.attnum;"); + res = PSQLexec(buf.data); + if (!res) + goto error_return; + numrows = PQntuples(res); + } /* Make title */ switch (tableinfo.relkind) diff --git a/src/bin/psql/describe.h b/src/bin/psql/describe.h index b50c7d2..a585645 100644 --- a/src/bin/psql/describe.h +++ b/src/bin/psql/describe.h @@ -43,7 +43,7 @@ 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, bool verbose, bool showSystem, const char *pattern2); /* \dF */ extern bool listTSConfigs(const char *pattern, bool verbose); -- 2.7.4 --47eKBCiAZYFK5l32--