mirror of
https://github.com/postgres/postgres.git
synced 2025-07-09 22:41:56 +03:00
Display incoming as well as outgoing foreign-key constraints in psql's
\d output for a table. Kenneth D'Souza, some changes by myself.
This commit is contained in:
@ -3,7 +3,7 @@
|
|||||||
*
|
*
|
||||||
* Copyright (c) 2000-2008, PostgreSQL Global Development Group
|
* Copyright (c) 2000-2008, PostgreSQL Global Development Group
|
||||||
*
|
*
|
||||||
* $PostgreSQL: pgsql/src/bin/psql/describe.c,v 1.164 2008/01/01 19:45:56 momjian Exp $
|
* $PostgreSQL: pgsql/src/bin/psql/describe.c,v 1.165 2008/03/30 17:50:11 tgl Exp $
|
||||||
*/
|
*/
|
||||||
#include "postgres_fe.h"
|
#include "postgres_fe.h"
|
||||||
#include "describe.h"
|
#include "describe.h"
|
||||||
@ -1106,12 +1106,14 @@ describeOneTableDetails(const char *schemaname,
|
|||||||
*result3 = NULL,
|
*result3 = NULL,
|
||||||
*result4 = NULL,
|
*result4 = NULL,
|
||||||
*result5 = NULL,
|
*result5 = NULL,
|
||||||
*result6 = NULL;
|
*result6 = NULL,
|
||||||
|
*result7 = NULL;
|
||||||
int check_count = 0,
|
int check_count = 0,
|
||||||
index_count = 0,
|
index_count = 0,
|
||||||
foreignkey_count = 0,
|
foreignkey_count = 0,
|
||||||
rule_count = 0,
|
rule_count = 0,
|
||||||
trigger_count = 0,
|
trigger_count = 0,
|
||||||
|
referencedby_count = 0,
|
||||||
inherits_count = 0;
|
inherits_count = 0;
|
||||||
int count_footers = 0;
|
int count_footers = 0;
|
||||||
|
|
||||||
@ -1228,24 +1230,47 @@ describeOneTableDetails(const char *schemaname,
|
|||||||
foreignkey_count = PQntuples(result5);
|
foreignkey_count = PQntuples(result5);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* count inherited tables */
|
/* count incoming foreign-key references (none if no triggers) */
|
||||||
printfPQExpBuffer(&buf, "SELECT c.oid::regclass FROM pg_catalog.pg_class c, pg_catalog.pg_inherits i WHERE c.oid=i.inhparent AND i.inhrelid = '%s' ORDER BY inhseqno ASC", oid);
|
if (tableinfo.triggers)
|
||||||
|
|
||||||
result6 = PSQLexec(buf.data, false);
|
|
||||||
if (!result6)
|
|
||||||
{
|
{
|
||||||
|
printfPQExpBuffer(&buf,
|
||||||
|
"SELECT conname, conrelid::pg_catalog.regclass,\n"
|
||||||
|
" pg_catalog.pg_get_constraintdef(oid, true) as condef\n"
|
||||||
|
"FROM pg_catalog.pg_constraint c\n"
|
||||||
|
"WHERE c.confrelid = '%s' AND c.contype = 'f' ORDER BY 1",
|
||||||
|
oid);
|
||||||
|
result6 = PSQLexec(buf.data, false);
|
||||||
|
if (!result6)
|
||||||
|
{
|
||||||
|
PQclear(result1);
|
||||||
|
PQclear(result2);
|
||||||
|
PQclear(result3);
|
||||||
|
PQclear(result4);
|
||||||
|
PQclear(result5);
|
||||||
|
goto error_return;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
referencedby_count = PQntuples(result6);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* count inherited tables */
|
||||||
|
printfPQExpBuffer(&buf, "SELECT c.oid::pg_catalog.regclass FROM pg_catalog.pg_class c, pg_catalog.pg_inherits i WHERE c.oid=i.inhparent AND i.inhrelid = '%s' ORDER BY inhseqno", oid);
|
||||||
|
|
||||||
|
result7 = PSQLexec(buf.data, false);
|
||||||
|
if (!result7)
|
||||||
|
{
|
||||||
PQclear(result1);
|
PQclear(result1);
|
||||||
PQclear(result2);
|
PQclear(result2);
|
||||||
PQclear(result3);
|
PQclear(result3);
|
||||||
PQclear(result4);
|
PQclear(result4);
|
||||||
PQclear(result5);
|
PQclear(result5);
|
||||||
|
PQclear(result6);
|
||||||
goto error_return;
|
goto error_return;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
inherits_count = PQntuples(result6);
|
inherits_count = PQntuples(result7);
|
||||||
|
|
||||||
footers = pg_malloc_zero((index_count + check_count + rule_count + trigger_count + foreignkey_count + inherits_count + 7 + 1)
|
footers = pg_malloc_zero((index_count + check_count + rule_count + trigger_count + foreignkey_count + referencedby_count + inherits_count + 8 + 1) * sizeof(*footers));
|
||||||
* sizeof(*footers));
|
|
||||||
|
|
||||||
/* print indexes */
|
/* print indexes */
|
||||||
if (index_count > 0)
|
if (index_count > 0)
|
||||||
@ -1333,6 +1358,22 @@ describeOneTableDetails(const char *schemaname,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* print incoming foreign-key constraints */
|
||||||
|
if (referencedby_count > 0)
|
||||||
|
{
|
||||||
|
printfPQExpBuffer(&buf, _("Referenced by:"));
|
||||||
|
footers[count_footers++] = pg_strdup(buf.data);
|
||||||
|
for (i = 0; i < referencedby_count; i++)
|
||||||
|
{
|
||||||
|
printfPQExpBuffer(&buf, _(" \"%s\" IN %s %s"),
|
||||||
|
PQgetvalue(result6, i, 0),
|
||||||
|
PQgetvalue(result6, i, 1),
|
||||||
|
PQgetvalue(result6, i, 2));
|
||||||
|
|
||||||
|
footers[count_footers++] = pg_strdup(buf.data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* print rules */
|
/* print rules */
|
||||||
if (rule_count > 0)
|
if (rule_count > 0)
|
||||||
{
|
{
|
||||||
@ -1487,9 +1528,9 @@ describeOneTableDetails(const char *schemaname,
|
|||||||
const char *s = _("Inherits");
|
const char *s = _("Inherits");
|
||||||
|
|
||||||
if (i == 0)
|
if (i == 0)
|
||||||
printfPQExpBuffer(&buf, "%s: %s", s, PQgetvalue(result6, i, 0));
|
printfPQExpBuffer(&buf, "%s: %s", s, PQgetvalue(result7, i, 0));
|
||||||
else
|
else
|
||||||
printfPQExpBuffer(&buf, "%*s %s", (int) strlen(s), "", PQgetvalue(result6, i, 0));
|
printfPQExpBuffer(&buf, "%*s %s", (int) strlen(s), "", PQgetvalue(result7, i, 0));
|
||||||
if (i < inherits_count - 1)
|
if (i < inherits_count - 1)
|
||||||
appendPQExpBuffer(&buf, ",");
|
appendPQExpBuffer(&buf, ",");
|
||||||
|
|
||||||
@ -1516,6 +1557,7 @@ describeOneTableDetails(const char *schemaname,
|
|||||||
PQclear(result4);
|
PQclear(result4);
|
||||||
PQclear(result5);
|
PQclear(result5);
|
||||||
PQclear(result6);
|
PQclear(result6);
|
||||||
|
PQclear(result7);
|
||||||
}
|
}
|
||||||
|
|
||||||
printTable(title.data, headers,
|
printTable(title.data, headers,
|
||||||
|
Reference in New Issue
Block a user