From 17b31313014c8432a7e435d11d4f68e57ef7b623 Mon Sep 17 00:00:00 2001
From: Masahiko Sawada <sawada.mshk@gmail.com>
Date: Mon, 3 Jul 2023 16:07:48 +0900
Subject: [PATCH v2 1/2] PoC: Add --no-table-dependents option to pg_dump.

---
 doc/src/sgml/ref/pg_dump.sgml | 12 ++++++++++++
 src/bin/pg_dump/pg_backup.h   |  1 +
 src/bin/pg_dump/pg_dump.c     | 37 ++++++++++++++++++++++++++++++-----
 src/bin/pg_dump/pg_dump.h     |  3 +++
 4 files changed, 48 insertions(+), 5 deletions(-)

diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml
index a3cf0608f5..2e6221ffcb 100644
--- a/doc/src/sgml/ref/pg_dump.sgml
+++ b/doc/src/sgml/ref/pg_dump.sgml
@@ -994,6 +994,18 @@ PostgreSQL documentation
       </listitem>
      </varlistentry>
 
+     <varlistentry>
+      <term><option>--no-table-dependents</option></term>
+      <listitem>
+       <para>
+        Do not output commands to select table-dependent objects such as
+        indexes and triggers.  This option is not valid unless
+        <option>--table</option> or <option>--table-and-children</option>
+        is also specified.
+       </para>
+      </listitem>
+     </varlistentry>
+
      <varlistentry>
       <term><option>--no-tablespaces</option></term>
       <listitem>
diff --git a/src/bin/pg_dump/pg_backup.h b/src/bin/pg_dump/pg_backup.h
index aba780ef4b..eb7727ea93 100644
--- a/src/bin/pg_dump/pg_backup.h
+++ b/src/bin/pg_dump/pg_backup.h
@@ -178,6 +178,7 @@ typedef struct _dumpOptions
 	int			no_security_labels;
 	int			no_publications;
 	int			no_subscriptions;
+	int			no_table_dependents;
 	int			no_toast_compression;
 	int			no_unlogged_table_data;
 	int			serializable_deferrable;
diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c
index 5dab1ba9ea..27f1a2d274 100644
--- a/src/bin/pg_dump/pg_dump.c
+++ b/src/bin/pg_dump/pg_dump.c
@@ -422,6 +422,7 @@ main(int argc, char **argv)
 		{"no-publications", no_argument, &dopt.no_publications, 1},
 		{"no-security-labels", no_argument, &dopt.no_security_labels, 1},
 		{"no-subscriptions", no_argument, &dopt.no_subscriptions, 1},
+		{"no-table-dependents", no_argument, &dopt.no_table_dependents, 15},
 		{"no-toast-compression", no_argument, &dopt.no_toast_compression, 1},
 		{"no-unlogged-table-data", no_argument, &dopt.no_unlogged_table_data, 1},
 		{"no-sync", no_argument, NULL, 7},
@@ -707,6 +708,10 @@ main(int argc, char **argv)
 	if (dopt.if_exists && !dopt.outputClean)
 		pg_fatal("option --if-exists requires option -c/--clean");
 
+	if (dopt.no_table_dependents && table_include_patterns.head == NULL &&
+		table_include_patterns_and_children.head == NULL)
+		pg_fatal("option --no-table-dependents requires option -t/--table or --table-and-children");
+
 	/*
 	 * --inserts are already implied above if --column-inserts or
 	 * --rows-per-insert were specified.
@@ -1114,6 +1119,8 @@ help(const char *progname)
 	printf(_("  --no-security-labels         do not dump security label assignments\n"));
 	printf(_("  --no-subscriptions           do not dump subscriptions\n"));
 	printf(_("  --no-table-access-method     do not dump table access methods\n"));
+	printf(_("  --no-table-dependents        do not dump table-dependent objects such as indexes\n"
+			 "                               and triggers\n"));
 	printf(_("  --no-tablespaces             do not dump tablespace assignments\n"));
 	printf(_("  --no-toast-compression       do not dump TOAST compression methods\n"));
 	printf(_("  --no-unlogged-table-data     do not dump unlogged table data\n"));
@@ -1803,9 +1810,26 @@ selectDumpableTable(TableInfo *tbinfo, Archive *fout)
 	 * according to the parent namespace's dump flag.
 	 */
 	if (table_include_oids.head != NULL)
-		tbinfo->dobj.dump = simple_oid_list_member(&table_include_oids,
-												   tbinfo->dobj.catId.oid) ?
-			DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE;
+	{
+		if (simple_oid_list_member(&table_include_oids,
+								   tbinfo->dobj.catId.oid))
+		{
+			if (!fout->dopt->no_table_dependents)
+				tbinfo->dobj.dump = DUMP_COMPONENT_ALL;
+			else
+			{
+				/*
+				 * If --exclude-table-dependents option is specified, we
+				 * dump either/both the table schema or/and the table data.
+				 */
+				tbinfo->dobj.dump = fout->dopt->schemaOnly ?
+					DUMP_COMPONENT_DEFINITION :
+					(DUMP_COMPONENT_DEFINITION | DUMP_COMPONENT_DATA);
+			}
+		}
+		else
+			tbinfo->dobj.dump = DUMP_COMPONENT_NONE;
+	}
 	else
 		tbinfo->dobj.dump = tbinfo->dobj.namespace->dobj.dump_contains;
 
@@ -6982,6 +7006,9 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables)
 		if (!tbinfo->hasindex)
 			continue;
 
+		if (!(tbinfo->dobj.dump & DUMP_COMPONENT_INDEX))
+			continue;
+
 		/*
 		 * We can ignore indexes of uninteresting tables.
 		 */
@@ -7352,7 +7379,7 @@ getConstraints(Archive *fout, TableInfo tblinfo[], int numTables)
 		 */
 		if ((!tinfo->hastriggers &&
 			 tinfo->relkind != RELKIND_PARTITIONED_TABLE) ||
-			!(tinfo->dobj.dump & DUMP_COMPONENT_DEFINITION))
+			!(tinfo->dobj.dump & DUMP_COMPONENT_CONSTRAINT))
 			continue;
 
 		/* OK, we need info for this table */
@@ -7737,7 +7764,7 @@ getTriggers(Archive *fout, TableInfo tblinfo[], int numTables)
 		TableInfo  *tbinfo = &tblinfo[i];
 
 		if (!tbinfo->hastriggers ||
-			!(tbinfo->dobj.dump & DUMP_COMPONENT_DEFINITION))
+			!(tbinfo->dobj.dump & DUMP_COMPONENT_TRIGGER))
 			continue;
 
 		/* OK, we need info for this table */
diff --git a/src/bin/pg_dump/pg_dump.h b/src/bin/pg_dump/pg_dump.h
index bc8f2ec36d..64d2b685fa 100644
--- a/src/bin/pg_dump/pg_dump.h
+++ b/src/bin/pg_dump/pg_dump.h
@@ -100,6 +100,9 @@ typedef uint32 DumpComponents;
 #define DUMP_COMPONENT_ACL			(1 << 4)
 #define DUMP_COMPONENT_POLICY		(1 << 5)
 #define DUMP_COMPONENT_USERMAP		(1 << 6)
+#define DUMP_COMPONENT_INDEX		(1 << 7)
+#define DUMP_COMPONENT_TRIGGER		(1 << 8)
+#define DUMP_COMPONENT_CONSTRAINT	(1 << 9)
 #define DUMP_COMPONENT_ALL			(0xFFFF)
 
 /*
-- 
2.31.1

