From 464b9155bc4e5b45f65b1b5f90e180486ad364a2 Mon Sep 17 00:00:00 2001
From: Daniel Gustafsson <daniel@yesql.se>
Date: Fri, 25 Mar 2022 22:06:49 +0100
Subject: [PATCH] First WIP stab at --exclude-extension for pg_dump

---
 doc/src/sgml/ref/pg_dump.sgml | 23 +++++++++++++++++++++++
 src/bin/pg_dump/pg_dump.c     | 27 ++++++++++++++++++++++++---
 2 files changed, 47 insertions(+), 3 deletions(-)

diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml
index 2f0042fd96..69fe2d6ed2 100644
--- a/doc/src/sgml/ref/pg_dump.sgml
+++ b/doc/src/sgml/ref/pg_dump.sgml
@@ -253,6 +253,29 @@ PostgreSQL documentation
       </listitem>
      </varlistentry>
 
+     <varlistentry>
+      <term><option>--exclude-extension=<replaceable class="parameter">pattern</replaceable></option></term>
+      <listitem>
+       <para>
+        Do not dump extensions matching
+        <replaceable class="parameter">pattern</replaceable>. The pattern is
+        interpreted according to the same rules as <option>-e</option>.
+        <option>--exclude-extension</option> can be given more than once to
+        exclude extensions matching any of several patterns.
+       </para>
+
+       <para>
+        When both <option>-e</option> and <option>--exclude-extension</option>,
+        the behavior is to dump just the extensions that match at least one
+        <option>-e</option> switch but no <option>--exclude-extension</option>
+        switches. If <option>--exclude-extension</option> appears without
+        <option>-e</option> then extensions matching 
+        <option>--exclude-extension</option> are excluded from what is
+        otherwise a normal dump.
+       </para>
+      </listitem>
+     </varlistentry>
+
      <varlistentry>
       <term><option>-E <replaceable class="parameter">encoding</replaceable></option></term>
       <term><option>--encoding=<replaceable class="parameter">encoding</replaceable></option></term>
diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c
index 00629f0836..3f78c220d3 100644
--- a/src/bin/pg_dump/pg_dump.c
+++ b/src/bin/pg_dump/pg_dump.c
@@ -126,6 +126,8 @@ static SimpleOidList foreign_servers_include_oids = {NULL, NULL};
 
 static SimpleStringList extension_include_patterns = {NULL, NULL};
 static SimpleOidList extension_include_oids = {NULL, NULL};
+static SimpleStringList extension_exclude_patterns = {NULL, NULL};
+static SimpleOidList extension_exclude_oids = {NULL, NULL};
 
 static const CatalogId nilCatalogId = {0, 0};
 
@@ -409,6 +411,7 @@ main(int argc, char **argv)
 		{"on-conflict-do-nothing", no_argument, &dopt.do_nothing, 1},
 		{"rows-per-insert", required_argument, NULL, 10},
 		{"include-foreign-data", required_argument, NULL, 11},
+		{"exclude-extension", required_argument, NULL, 12},
 
 		{NULL, 0, NULL, 0}
 	};
@@ -619,6 +622,10 @@ main(int argc, char **argv)
 										  optarg);
 				break;
 
+			case 12:			/* exclude extensions */
+				simple_string_list_append(&extension_exclude_patterns, optarg);
+				break;
+
 			default:
 				fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname);
 				exit_nicely(1);
@@ -808,7 +815,9 @@ main(int argc, char **argv)
 		if (extension_include_oids.head == NULL)
 			fatal("no matching extensions were found");
 	}
-
+	expand_extension_name_patterns(fout, &extension_exclude_patterns,
+								   &extension_exclude_oids,
+								   strict_names);
 	/*
 	 * Dumping blobs is the default for dumps where an inclusion switch is not
 	 * used (an "include everything" dump).  -B can be used to exclude blobs
@@ -1012,6 +1021,7 @@ help(const char *progname)
 	printf(_("  -c, --clean                  clean (drop) database objects before recreating\n"));
 	printf(_("  -C, --create                 include commands to create database in dump\n"));
 	printf(_("  -e, --extension=PATTERN      dump the specified extension(s) only\n"));
+	printf(_("  --exclude-extension=PATTERN  do NOT dump the specified extension(s)\n"));
 	printf(_("  -E, --encoding=ENCODING      dump the data in encoding ENCODING\n"));
 	printf(_("  -n, --schema=PATTERN         dump the specified schema(s) only\n"));
 	printf(_("  -N, --exclude-schema=PATTERN do NOT dump the specified schema(s)\n"));
@@ -1854,6 +1864,11 @@ selectDumpableExtension(ExtensionInfo *extinfo, DumpOptions *dopt)
 				simple_oid_list_member(&extension_include_oids,
 									   extinfo->dobj.catId.oid) ?
 				DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE;
+		else if (extension_exclude_oids.head != NULL)
+			extinfo->dobj.dump = extinfo->dobj.dump_contains =
+				simple_oid_list_member(&extension_exclude_oids,
+									   extinfo->dobj.catId.oid) ?
+				DUMP_COMPONENT_NONE : DUMP_COMPONENT_ALL;
 		else
 			extinfo->dobj.dump = extinfo->dobj.dump_contains =
 				dopt->include_everything ?
@@ -17458,14 +17473,20 @@ processExtensionTables(Archive *fout, ExtensionInfo extinfo[],
 		int			nconditionitems = 0;
 
 		/*
-		 * Check if this extension is listed as to include in the dump.  If
-		 * not, any table data associated with it is discarded.
+		 * Check if this extension is listed to be included in, or excluded
+		 * from, the dump.  If the extension isn't included, any table data
+		 * associated with it is discarded.
 		 */
 		if (extension_include_oids.head != NULL &&
 			!simple_oid_list_member(&extension_include_oids,
 									curext->dobj.catId.oid))
 			continue;
 
+		if (extension_exclude_oids.head != NULL &&
+			simple_oid_list_member(&extension_exclude_oids,
+									curext->dobj.catId.oid))
+			continue;
+
 		if (strlen(extconfig) != 0 || strlen(extcondition) != 0)
 		{
 			int			j;
-- 
2.24.3 (Apple Git-128)

