From 2be368a5af44b1a1c509d16256036acc9ba6d78b Mon Sep 17 00:00:00 2001
From: Tom Lane <tgl@sss.pgh.pa.us>
Date: Sun, 30 Mar 2008 17:50:11 +0000
Subject: [PATCH] Display incoming as well as outgoing foreign-key constraints
 in psql's \d output for a table.

Kenneth D'Souza, some changes by myself.
---
 src/bin/psql/describe.c | 64 ++++++++++++++++++++++++++++++++++-------
 1 file changed, 53 insertions(+), 11 deletions(-)

diff --git a/src/bin/psql/describe.c b/src/bin/psql/describe.c
index 86b24b45494..96c578aa70e 100644
--- a/src/bin/psql/describe.c
+++ b/src/bin/psql/describe.c
@@ -3,7 +3,7 @@
  *
  * 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 "describe.h"
@@ -1106,12 +1106,14 @@ describeOneTableDetails(const char *schemaname,
 				   *result3 = NULL,
 				   *result4 = NULL,
 				   *result5 = NULL,
-				   *result6 = NULL;
+				   *result6 = NULL,
+				   *result7 = NULL;
 		int			check_count = 0,
 					index_count = 0,
 					foreignkey_count = 0,
 					rule_count = 0,
 					trigger_count = 0,
+					referencedby_count = 0,
 					inherits_count = 0;
 		int			count_footers = 0;
 
@@ -1228,24 +1230,47 @@ describeOneTableDetails(const char *schemaname,
 				foreignkey_count = PQntuples(result5);
 		}
 
+		/* count incoming foreign-key references (none if no triggers) */
+		if (tableinfo.triggers)
+		{
+			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::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);
+		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);
 
-		result6 = PSQLexec(buf.data, false);
-		if (!result6)
-		{
+		result7 = PSQLexec(buf.data, false);
+		if (!result7)
+		{        
 			PQclear(result1);
 			PQclear(result2);
 			PQclear(result3);
 			PQclear(result4);
 			PQclear(result5);
+			PQclear(result6);
 			goto error_return;
 		}
 		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)
-								 * sizeof(*footers));
+		footers = pg_malloc_zero((index_count + check_count + rule_count + trigger_count + foreignkey_count + referencedby_count + inherits_count + 8 + 1) * sizeof(*footers));
 
 		/* print indexes */
 		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 */
 		if (rule_count > 0)
 		{
@@ -1487,9 +1528,9 @@ describeOneTableDetails(const char *schemaname,
 			const char *s = _("Inherits");
 
 			if (i == 0)
-				printfPQExpBuffer(&buf, "%s: %s", s, PQgetvalue(result6, i, 0));
+				printfPQExpBuffer(&buf, "%s: %s", s, PQgetvalue(result7, i, 0));
 			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)
 				appendPQExpBuffer(&buf, ",");
 
@@ -1516,6 +1557,7 @@ describeOneTableDetails(const char *schemaname,
 		PQclear(result4);
 		PQclear(result5);
 		PQclear(result6);
+		PQclear(result7);
 	}
 
 	printTable(title.data, headers,
-- 
GitLab