From 5249eca2aa2cedc5e3e05e7e789cdceccfa7e552 Mon Sep 17 00:00:00 2001
From: Nathan Bossart <bossartn@amazon.com>
Date: Tue, 24 Jul 2018 17:14:47 +0000
Subject: [PATCH 1/1] Refactor logging logic for skipped relations in VACUUM
 and ANALYZE.

This change refactors the logging logic for skipped relations in
VACUUM and ANALYZE so that it can be reused in other places (such
as expand_vacuum_rel()) as part of the upcoming SKIP_LOCKED
parameter.
---
 src/backend/commands/analyze.c   |  35 ++----------
 src/backend/commands/vacuum.c    | 111 +++++++++++++++++++++++++++------------
 src/include/commands/vacuum.h    |  10 ++++
 src/tools/pgindent/typedefs.list |   1 +
 4 files changed, 92 insertions(+), 65 deletions(-)

diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c
index 3e148f03d0..8251205801 100644
--- a/src/backend/commands/analyze.c
+++ b/src/backend/commands/analyze.c
@@ -159,39 +159,14 @@ analyze_rel(Oid relid, RangeVar *relation, int options,
 	 */
 	if (!onerel)
 	{
-		/*
-		 * If the RangeVar is not defined, we do not have enough information
-		 * to provide a meaningful log statement.  Chances are that
-		 * analyze_rel's caller has intentionally not provided this
-		 * information so that this logging is skipped, anyway.
-		 */
-		if (relation == NULL)
-			return;
-
-		/*
-		 * Determine the log level.  For autovacuum logs, we emit a LOG if
-		 * log_autovacuum_min_duration is not disabled.  For manual ANALYZE,
-		 * we emit a WARNING to match the log statements in the permissions
-		 * checks.
-		 */
-		if (!IsAutoVacuumWorkerProcess())
-			elevel = WARNING;
-		else if (params->log_min_duration >= 0)
-			elevel = LOG;
-		else
-			return;
+		int			errcode;
 
-		if (!rel_lock)
-			ereport(elevel,
-					(errcode(ERRCODE_LOCK_NOT_AVAILABLE),
-					 errmsg("skipping analyze of \"%s\" --- lock not available",
-							relation->relname)));
+		if (rel_lock)
+			errcode = ERRCODE_UNDEFINED_TABLE;
 		else
-			ereport(elevel,
-					(errcode(ERRCODE_UNDEFINED_TABLE),
-					 errmsg("skipping analyze of \"%s\" --- relation no longer exists",
-							relation->relname)));
+			errcode = ERRCODE_LOCK_NOT_AVAILABLE;
 
+		report_skipped_relation(relation, params, errcode, SRS_ANALYZE);
 		return;
 	}
 
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 5736f12b8f..b53f9c709c 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -1393,43 +1393,14 @@ vacuum_rel(Oid relid, RangeVar *relation, int options, VacuumParams *params)
 	 */
 	if (!onerel)
 	{
-		int			elevel = 0;
+		int			errcode;
 
-		/*
-		 * Determine the log level.
-		 *
-		 * If the RangeVar is not defined, we do not have enough information
-		 * to provide a meaningful log statement.  Chances are that
-		 * vacuum_rel's caller has intentionally not provided this information
-		 * so that this logging is skipped, anyway.
-		 *
-		 * Otherwise, for autovacuum logs, we emit a LOG if
-		 * log_autovacuum_min_duration is not disabled.  For manual VACUUM, we
-		 * emit a WARNING to match the log statements in the permission
-		 * checks.
-		 */
-		if (relation != NULL)
-		{
-			if (!IsAutoVacuumWorkerProcess())
-				elevel = WARNING;
-			else if (params->log_min_duration >= 0)
-				elevel = LOG;
-		}
-
-		if (elevel != 0)
-		{
-			if (!rel_lock)
-				ereport(elevel,
-						(errcode(ERRCODE_LOCK_NOT_AVAILABLE),
-						 errmsg("skipping vacuum of \"%s\" --- lock not available",
-								relation->relname)));
-			else
-				ereport(elevel,
-						(errcode(ERRCODE_UNDEFINED_TABLE),
-						 errmsg("skipping vacuum of \"%s\" --- relation no longer exists",
-								relation->relname)));
-		}
+		if (rel_lock)
+			errcode = ERRCODE_UNDEFINED_TABLE;
+		else
+			errcode = ERRCODE_LOCK_NOT_AVAILABLE;
 
+		report_skipped_relation(relation, params, errcode, SRS_VACUUM);
 		PopActiveSnapshot();
 		CommitTransactionCommand();
 		return false;
@@ -1705,3 +1676,73 @@ vacuum_delay_point(void)
 		CHECK_FOR_INTERRUPTS();
 	}
 }
+
+/*
+ * report_skipped_relation
+ *
+ * This function reports that a relation has been skipped using the given error
+ * code.
+ *
+ * If the RangeVar is not defined, we do not have enough information to provide
+ * a meaningful log statement, and nothing is emitted.  Chances are that the
+ * caller has intentionally not provided this information so that logging is
+ * skipped anyway.
+ *
+ * Otherwise, for autovacuum logs, we emit a LOG if log_autovacuum_min_duration
+ * is not disabled.  For manual commands, we emit a WARNING to match the log
+ * statements in the permission checks for VACUUM and ANALYZE.
+ *
+ * Note that this function currently only accepts the following SQL error codes:
+ * 	ERRCODE_LOCK_NOT_AVAILABLE
+ * 	ERRCODE_UNDEFINED_TABLE
+ */
+void
+report_skipped_relation(RangeVar *relation, VacuumParams *params,
+						int sqlerrcode, SkippedRelStmtType stmttype)
+{
+	int			elevel;
+
+	Assert(params != NULL);
+
+	if (relation == NULL)
+		return;
+	else if (!IsAutoVacuumWorkerProcess())
+		elevel = WARNING;
+	else if (params->log_min_duration >= 0)
+		elevel = LOG;
+	else
+		return;
+
+	if (sqlerrcode == ERRCODE_LOCK_NOT_AVAILABLE)
+	{
+		if (stmttype == SRS_VACUUM)
+			ereport(elevel,
+					(errcode(sqlerrcode),
+					 errmsg("skipping vacuum of \"%s\" --- lock not available",
+							relation->relname)));
+		else if (stmttype == SRS_ANALYZE)
+			ereport(elevel,
+					(errcode(sqlerrcode),
+					 errmsg("skipping analyze of \"%s\" --- lock not available",
+							relation->relname)));
+		else
+			elog(ERROR, "unrecognized statement type: %d", stmttype);
+	}
+	else if (sqlerrcode == ERRCODE_UNDEFINED_TABLE)
+	{
+		if (stmttype == SRS_VACUUM)
+			ereport(elevel,
+					(errcode(sqlerrcode),
+					 errmsg("skipping vacuum of \"%s\" --- relation no longer exists",
+							relation->relname)));
+		else if (stmttype == SRS_ANALYZE)
+			ereport(elevel,
+					(errcode(sqlerrcode),
+					 errmsg("skipping analyze of \"%s\" --- relation no longer exists",
+							relation->relname)));
+		else
+			elog(ERROR, "unrecognized statement type: %d", stmttype);
+	}
+	else
+		elog(ERROR, "unrecognized error code: %d", sqlerrcode);
+}
diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h
index 85d472f0a5..d74835ec12 100644
--- a/src/include/commands/vacuum.h
+++ b/src/include/commands/vacuum.h
@@ -147,6 +147,12 @@ typedef struct VacuumParams
 									 * to use default */
 } VacuumParams;
 
+typedef enum SkippedRelStmtType
+{
+	SRS_VACUUM,
+	SRS_ANALYZE
+} SkippedRelStmtType;
+
 /* GUC parameters */
 extern PGDLLIMPORT int default_statistics_target;	/* PGDLLIMPORT for PostGIS */
 extern int	vacuum_freeze_min_age;
@@ -185,6 +191,10 @@ extern void vacuum_set_xid_limits(Relation rel,
 					  MultiXactId *mxactFullScanLimit);
 extern void vac_update_datfrozenxid(void);
 extern void vacuum_delay_point(void);
+extern void report_skipped_relation(RangeVar *relation,
+						VacuumParams *params,
+						int sqlerrcode,
+						SkippedRelStmtType stmttype);
 
 /* in commands/vacuumlazy.c */
 extern void lazy_vacuum_rel(Relation onerel, int options,
diff --git a/src/tools/pgindent/typedefs.list b/src/tools/pgindent/typedefs.list
index 9fe950b29d..7ec4049deb 100644
--- a/src/tools/pgindent/typedefs.list
+++ b/src/tools/pgindent/typedefs.list
@@ -2147,6 +2147,7 @@ SimpleStringList
 SimpleStringListCell
 SingleBoundSortItem
 Size
+SkippedRelStmtType
 SlabBlock
 SlabChunk
 SlabContext
-- 
2.16.2

