From c7ae482c358bb7aef6cc450ae72f11f92a0bd148 Mon Sep 17 00:00:00 2001
From: Justin Pryzby <pryzbyj@telsasoft.com>
Date: Sun, 12 Jul 2020 14:10:37 -0500
Subject: [PATCH 2/3] vacuumdb support

---
 src/bin/scripts/vacuumdb.c | 47 ++++++++++++++++++++++++++++++++++++++
 1 file changed, 47 insertions(+)

diff --git a/src/bin/scripts/vacuumdb.c b/src/bin/scripts/vacuumdb.c
index 6a3c941158..2b838069da 100644
--- a/src/bin/scripts/vacuumdb.c
+++ b/src/bin/scripts/vacuumdb.c
@@ -39,6 +39,8 @@ typedef struct vacuumingOptions
 									 * parallel degree, otherwise -1 */
 	bool		do_index_cleanup;
 	bool		do_truncate;
+	bool		do_mainrel;
+	bool		do_toastrel;
 } vacuumingOptions;
 
 
@@ -100,6 +102,8 @@ main(int argc, char *argv[])
 		{"min-mxid-age", required_argument, NULL, 7},
 		{"no-index-cleanup", no_argument, NULL, 8},
 		{"no-truncate", no_argument, NULL, 9},
+		{"no-clean-main", no_argument, NULL, 10},
+		{"no-clean-toast", no_argument, NULL, 11},
 		{NULL, 0, NULL, 0}
 	};
 
@@ -126,6 +130,8 @@ main(int argc, char *argv[])
 	vacopts.parallel_workers = -1;
 	vacopts.do_index_cleanup = true;
 	vacopts.do_truncate = true;
+	vacopts.do_mainrel = true;
+	vacopts.do_toastrel = true;
 
 	pg_logging_init(argv[0]);
 	progname = get_progname(argv[0]);
@@ -235,6 +241,13 @@ main(int argc, char *argv[])
 			case 9:
 				vacopts.do_truncate = false;
 				break;
+			case 10:
+				vacopts.do_mainrel = false;
+				break;
+			case 11:
+				vacopts.do_toastrel = false;
+				break;
+
 			default:
 				fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname);
 				exit(1);
@@ -452,6 +465,22 @@ vacuum_one_database(const char *dbname, vacuumingOptions *vacopts,
 		exit(1);
 	}
 
+	if (!vacopts->do_mainrel && PQserverVersion(conn) < 140000)
+	{
+		PQfinish(conn);
+		pg_log_error("cannot use the \"%s\" option on server versions older than PostgreSQL %s",
+					 "no-mainrel", "14");
+		exit(1);
+	}
+
+	if (!vacopts->do_toastrel && PQserverVersion(conn) < 140000)
+	{
+		PQfinish(conn);
+		pg_log_error("cannot use the \"%s\" option on server versions older than PostgreSQL %s",
+					 "no-toastrel", "14");
+		exit(1);
+	}
+
 	if (vacopts->skip_locked && PQserverVersion(conn) < 120000)
 	{
 		PQfinish(conn);
@@ -886,6 +915,22 @@ prepare_vacuum_command(PQExpBuffer sql, int serverVersion,
 				appendPQExpBuffer(sql, "%sTRUNCATE FALSE", sep);
 				sep = comma;
 			}
+
+			if (!vacopts->do_mainrel)
+			{
+				/* supported since v14 */
+				Assert(serverVersion >= 140000);
+				appendPQExpBuffer(sql, "%sMAIN_RELATION_CLEANUP FALSE", sep);
+				sep = comma;
+			}
+			if (!vacopts->do_toastrel)
+			{
+				/* supported since v14 */
+				Assert(serverVersion >= 140000);
+				appendPQExpBuffer(sql, "%sTOAST_TABLE_CLEANUP FALSE", sep);
+				sep = comma;
+			}
+
 			if (vacopts->skip_locked)
 			{
 				/* SKIP_LOCKED is supported since v12 */
@@ -986,6 +1031,8 @@ help(const char *progname)
 	printf(_("      --min-xid-age=XID_AGE       minimum transaction ID age of tables to vacuum\n"));
 	printf(_("      --no-index-cleanup          don't remove index entries that point to dead tuples\n"));
 	printf(_("      --no-truncate               don't truncate empty pages at the end of the table\n"));
+	printf(_("      --no-clean-main             don't vacuum main relation\n"));
+	printf(_("      --no-clean-toast            don't vacuum TOAST relation\n"));
 	printf(_("  -P, --parallel=PARALLEL_DEGREE  use this many background workers for vacuum, if available\n"));
 	printf(_("  -q, --quiet                     don't write any messages\n"));
 	printf(_("      --skip-locked               skip relations that cannot be immediately locked\n"));
-- 
2.17.0

