mirror of
https://git.postgresql.org/git/postgresql.git
synced 2024-12-21 08:29:39 +08:00
New \d format:
Example: test=# \d test Table "public.test" Column | Type | Modifiers --------+---------+----------- a | integer | not null Indexes: "test_pkey" PRIMARY KEY btree (a) Check Constraints: "$2" CHECK (a > 1) Foreign Key Constraints: "$1" FOREIGN KEY (a) REFERENCES parent(b) Rules: myrule AS ON INSERT TO test DO INSTEAD NOTHING Triggers: "asdf asdf" AFTER INSERT OR DELETE ON test FOR EACH STATEMENT EXECUTE PROCEDURE update_pg_pwd_and_pg_group(), mytrigger AFTER INSERT OR DELETE ON test FOR EACH ROW EXECUTE PROCEDURE update_pg_pwd_and_pg_group() I have minimised the double quoting of identifiers as much as I could easily, and I will submit another patch when I have time to work on it that will use a 'fmtId' function to determine it exactly. I think it's a significant improvement in legibility... Obviously the table example above is slightly degenerate in that not many tables in production have heaps of (non-constraint) triggers and rules. Christopher Kings-Lynne
This commit is contained in:
parent
5e8499d995
commit
c75d65485d
@ -3,7 +3,7 @@
|
||||
*
|
||||
* Copyright 2000-2002 by PostgreSQL Global Development Group
|
||||
*
|
||||
* $Header: /cvsroot/pgsql/src/bin/psql/describe.c,v 1.75 2003/02/24 03:54:06 tgl Exp $
|
||||
* $Header: /cvsroot/pgsql/src/bin/psql/describe.c,v 1.76 2003/03/27 16:57:39 momjian Exp $
|
||||
*/
|
||||
#include "postgres_fe.h"
|
||||
#include "describe.h"
|
||||
@ -975,7 +975,7 @@ describeOneTableDetails(const char *schemaname,
|
||||
if (tableinfo.hasrules)
|
||||
{
|
||||
printfPQExpBuffer(&buf,
|
||||
"SELECT r.rulename\n"
|
||||
"SELECT r.rulename, trim(trailing ';' from pg_catalog.pg_get_ruledef(r.oid))\n"
|
||||
"FROM pg_catalog.pg_rewrite r\n"
|
||||
"WHERE r.ev_class = '%s'",
|
||||
oid);
|
||||
@ -990,7 +990,7 @@ describeOneTableDetails(const char *schemaname,
|
||||
if (tableinfo.triggers)
|
||||
{
|
||||
printfPQExpBuffer(&buf,
|
||||
"SELECT t.tgname\n"
|
||||
"SELECT t.tgname, pg_catalog.pg_get_triggerdef(t.oid)\n"
|
||||
"FROM pg_catalog.pg_trigger t\n"
|
||||
"WHERE t.tgrelid = '%s' "
|
||||
"and (not tgisconstraint "
|
||||
@ -1022,29 +1022,28 @@ describeOneTableDetails(const char *schemaname,
|
||||
foreignkey_count = PQntuples(result5);
|
||||
}
|
||||
|
||||
footers = xmalloczero((index_count + check_count + rule_count + trigger_count + foreignkey_count + 1)
|
||||
footers = xmalloczero((index_count + check_count + rule_count + trigger_count + foreignkey_count + 6)
|
||||
* sizeof(*footers));
|
||||
|
||||
/* print indexes */
|
||||
if (index_count > 0) {
|
||||
printfPQExpBuffer(&buf, _("Indexes:"));
|
||||
footers[count_footers++] = xstrdup(buf.data);
|
||||
for (i = 0; i < index_count; i++)
|
||||
{
|
||||
char *s = _("Indexes");
|
||||
const char *indexdef;
|
||||
const char *usingpos;
|
||||
|
||||
if (i == 0)
|
||||
printfPQExpBuffer(&buf, "%s: %s", s,
|
||||
PQgetvalue(result1, i, 0));
|
||||
else
|
||||
printfPQExpBuffer(&buf, "%*s %s", (int) strlen(s), "",
|
||||
/* Output index/constraint name */
|
||||
printfPQExpBuffer(&buf, " \"%s\"",
|
||||
PQgetvalue(result1, i, 0));
|
||||
|
||||
/* Label as primary key or unique (but not both) */
|
||||
appendPQExpBuffer(&buf,
|
||||
strcmp(PQgetvalue(result1, i, 1), "t") == 0
|
||||
? _(" primary key") :
|
||||
? _(" PRIMARY KEY") :
|
||||
(strcmp(PQgetvalue(result1, i, 2), "t") == 0
|
||||
? _(" unique")
|
||||
? _(" UNIQUE")
|
||||
: ""));
|
||||
|
||||
/* Everything after "USING" is echoed verbatim */
|
||||
@ -1060,39 +1059,31 @@ describeOneTableDetails(const char *schemaname,
|
||||
|
||||
footers[count_footers++] = xstrdup(buf.data);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* print check constraints */
|
||||
if (check_count > 0) {
|
||||
printfPQExpBuffer(&buf, _("Check Constraints:"));
|
||||
footers[count_footers++] = xstrdup(buf.data);
|
||||
for (i = 0; i < check_count; i++)
|
||||
{
|
||||
char *s = _("Check constraints");
|
||||
printfPQExpBuffer(&buf, _(" \"%s\" CHECK %s"),
|
||||
PQgetvalue(result2, i, 1),
|
||||
PQgetvalue(result2, i, 0));
|
||||
if (i < check_count - 1)
|
||||
appendPQExpBuffer(&buf, ",");
|
||||
|
||||
if (i == 0)
|
||||
printfPQExpBuffer(&buf, _("%s: \"%s\" %s"),
|
||||
s,
|
||||
PQgetvalue(result2, i, 1),
|
||||
PQgetvalue(result2, i, 0));
|
||||
else
|
||||
printfPQExpBuffer(&buf, _("%*s \"%s\" %s"),
|
||||
(int) strlen(s), "",
|
||||
PQgetvalue(result2, i, 1),
|
||||
PQgetvalue(result2, i, 0));
|
||||
footers[count_footers++] = xstrdup(buf.data);
|
||||
}
|
||||
}
|
||||
|
||||
/* print foreign key constraints */
|
||||
if (foreignkey_count > 0) {
|
||||
printfPQExpBuffer(&buf, _("Foreign Key Constraints:"));
|
||||
footers[count_footers++] = xstrdup(buf.data);
|
||||
for (i = 0; i < foreignkey_count; i++)
|
||||
{
|
||||
char *s = _("Foreign Key constraints");
|
||||
|
||||
if (i == 0)
|
||||
printfPQExpBuffer(&buf, _("%s: %s %s"),
|
||||
s,
|
||||
PQgetvalue(result5, i, 0),
|
||||
PQgetvalue(result5, i, 1));
|
||||
else
|
||||
printfPQExpBuffer(&buf, _("%*s %s %s"),
|
||||
(int) strlen(s), "",
|
||||
printfPQExpBuffer(&buf, _(" \"%s\" %s"),
|
||||
PQgetvalue(result5, i, 0),
|
||||
PQgetvalue(result5, i, 1));
|
||||
if (i < foreignkey_count - 1)
|
||||
@ -1100,36 +1091,52 @@ describeOneTableDetails(const char *schemaname,
|
||||
|
||||
footers[count_footers++] = xstrdup(buf.data);
|
||||
}
|
||||
}
|
||||
|
||||
/* print rules */
|
||||
if (rule_count > 0) {
|
||||
printfPQExpBuffer(&buf, _("Rules:"));
|
||||
footers[count_footers++] = xstrdup(buf.data);
|
||||
for (i = 0; i < rule_count; i++)
|
||||
{
|
||||
char *s = _("Rules");
|
||||
const char *ruledef;
|
||||
|
||||
/* Everything after "CREATE RULE" is echoed verbatim */
|
||||
ruledef = PQgetvalue(result3, i, 1);
|
||||
ruledef += 12;
|
||||
|
||||
printfPQExpBuffer(&buf, " %s", ruledef);
|
||||
|
||||
if (i == 0)
|
||||
printfPQExpBuffer(&buf, "%s: %s", s, PQgetvalue(result3, i, 0));
|
||||
else
|
||||
printfPQExpBuffer(&buf, "%*s %s", (int) strlen(s), "", PQgetvalue(result3, i, 0));
|
||||
if (i < rule_count - 1)
|
||||
appendPQExpBuffer(&buf, ",");
|
||||
|
||||
footers[count_footers++] = xstrdup(buf.data);
|
||||
}
|
||||
}
|
||||
|
||||
/* print triggers */
|
||||
if (trigger_count > 0) {
|
||||
printfPQExpBuffer(&buf, _("Triggers:"));
|
||||
footers[count_footers++] = xstrdup(buf.data);
|
||||
for (i = 0; i < trigger_count; i++)
|
||||
{
|
||||
char *s = _("Triggers");
|
||||
const char *tgdef;
|
||||
const char *usingpos;
|
||||
|
||||
/* Everything after "TRIGGER" is echoed verbatim */
|
||||
tgdef = PQgetvalue(result4, i, 1);
|
||||
usingpos = strstr(tgdef, " TRIGGER ");
|
||||
if (usingpos)
|
||||
tgdef = usingpos + 9;
|
||||
|
||||
printfPQExpBuffer(&buf, " %s", tgdef);
|
||||
|
||||
if (i == 0)
|
||||
printfPQExpBuffer(&buf, "%s: %s", s, PQgetvalue(result4, i, 0));
|
||||
else
|
||||
printfPQExpBuffer(&buf, "%*s %s", (int) strlen(s), "", PQgetvalue(result4, i, 0));
|
||||
if (i < trigger_count - 1)
|
||||
appendPQExpBuffer(&buf, ",");
|
||||
|
||||
footers[count_footers++] = xstrdup(buf.data);
|
||||
}
|
||||
}
|
||||
|
||||
/* end of list marker */
|
||||
footers[count_footers] = NULL;
|
||||
|
Loading…
Reference in New Issue
Block a user