From 2fb3f61e7b5eeef7c6ac35bb643c730230ef180c Mon Sep 17 00:00:00 2001
From: Michael Paquier <michael@otacoo.com>
Date: Fri, 6 Mar 2015 15:34:23 +0900
Subject: [PATCH 3/3] Add wraparound control parameters in VacuumStmt

This is easy to manipulate across the stack of vacuum routines as it
does not need special handling, contrary to relid and do_toast when
vacuum_rel is called for toast relations.
---
 src/backend/commands/vacuum.c       | 20 +++++++++-----------
 src/backend/postmaster/autovacuum.c |  4 ++--
 src/backend/tcop/utility.c          |  2 +-
 src/include/commands/vacuum.h       |  4 +++-
 4 files changed, 15 insertions(+), 15 deletions(-)

diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index d6091c0..385e478 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -72,8 +72,7 @@ static void vac_truncate_clog(TransactionId frozenXID,
 				  TransactionId lastSaneFrozenXid,
 				  MultiXactId lastSaneMinMulti);
 static bool vacuum_rel(Oid relid, RangeVar *relation, int options,
-					   VacuumParams *params, bool do_toast,
-					   bool for_wraparound);
+					   VacuumParams *params, bool do_toast);
 
 
 /*
@@ -89,9 +88,6 @@ static bool vacuum_rel(Oid relid, RangeVar *relation, int options,
  * do_toast is passed as FALSE by autovacuum, because it processes TOAST
  * tables separately.
  *
- * for_wraparound is used by autovacuum to let us know when it's forcing
- * a vacuum for wraparound, which should not be auto-canceled.
- *
  * bstrategy is normally given as NULL, but in autovacuum it can be passed
  * in to use the same buffer strategy object across multiple vacuum() calls.
  *
@@ -103,7 +99,7 @@ static bool vacuum_rel(Oid relid, RangeVar *relation, int options,
  */
 void
 vacuum(VacuumStmt *vacstmt, VacuumParams *params, Oid relid, bool do_toast,
-	   BufferAccessStrategy bstrategy, bool for_wraparound, bool isTopLevel)
+	   BufferAccessStrategy bstrategy, bool isTopLevel)
 {
 	const char *stmttype;
 	volatile bool in_outer_xact,
@@ -252,8 +248,7 @@ vacuum(VacuumStmt *vacstmt, VacuumParams *params, Oid relid, bool do_toast,
 			if (vacstmt->options & VACOPT_VACUUM)
 			{
 				if (!vacuum_rel(relid, vacstmt->relation,
-								vacstmt->options, params, do_toast,
-								for_wraparound))
+								vacstmt->options, params, do_toast))
 					continue;
 			}
 
@@ -1121,7 +1116,7 @@ vac_truncate_clog(TransactionId frozenXID,
  */
 static bool
 vacuum_rel(Oid relid, RangeVar *relation, int options, VacuumParams *params,
-		   bool do_toast, bool for_wraparound)
+		   bool do_toast)
 {
 	LOCKMODE	lmode;
 	Relation	onerel;
@@ -1130,6 +1125,10 @@ vacuum_rel(Oid relid, RangeVar *relation, int options, VacuumParams *params,
 	Oid			save_userid;
 	int			save_sec_context;
 	int			save_nestlevel;
+	bool		for_wraparound;
+
+	/* Set parameters if present */
+	for_wraparound = params ? params->is_wraparound : false;
 
 	/* Begin a transaction for vacuuming this relation */
 	StartTransactionCommand();
@@ -1350,8 +1349,7 @@ vacuum_rel(Oid relid, RangeVar *relation, int options, VacuumParams *params,
 	 * totally unimportant for toast relations.
 	 */
 	if (toast_relid != InvalidOid)
-		vacuum_rel(toast_relid, relation, options, params, false,
-				   for_wraparound);
+		vacuum_rel(toast_relid, relation, options, params, false);
 
 	/*
 	 * Now release the session-level lock on the master table.
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index 67c8cdc..8bcfee9 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2767,12 +2767,12 @@ autovacuum_do_vac_analyze(autovac_table *tab,
 	params.freeze_table_age = tab->at_freeze_table_age;
 	params.multixact_freeze_min_age = tab->at_multixact_freeze_min_age;
 	params.multixact_freeze_table_age = tab->at_multixact_freeze_table_age;
+	params.is_wraparound = tab->at_wraparound;
 
 	/* Let pgstat know what we're doing */
 	autovac_report_activity(tab);
 
-	vacuum(&vacstmt, &params, tab->at_relid, false, bstrategy,
-		   tab->at_wraparound, true);
+	vacuum(&vacstmt, &params, tab->at_relid, false, bstrategy, true);
 }
 
 /*
diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c
index 774b99f..4e4b11f 100644
--- a/src/backend/tcop/utility.c
+++ b/src/backend/tcop/utility.c
@@ -627,7 +627,7 @@ standard_ProcessUtility(Node *parsetree,
 				/* we choose to allow this during "read only" transactions */
 				PreventCommandDuringRecovery((stmt->options & VACOPT_VACUUM) ?
 											 "VACUUM" : "ANALYZE");
-				vacuum(stmt, NULL, InvalidOid, true, NULL, false, isTopLevel);
+				vacuum(stmt, NULL, InvalidOid, true, NULL, isTopLevel);
 			}
 			break;
 
diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h
index 58dd2ee..f636618 100644
--- a/src/include/commands/vacuum.h
+++ b/src/include/commands/vacuum.h
@@ -141,6 +141,8 @@ typedef struct VacuumParams
 										 * or -1 to use default */
 	int		multixact_freeze_table_age;	/* multixact age at which to
 										 * scan whole table */
+	bool	is_wraparound;		/* enforce a wraparound for vacuum, which
+								 * should not be auto-canceled */
 } VacuumParams;
 
 /* GUC parameters */
@@ -155,7 +157,7 @@ extern int	vacuum_multixact_freeze_table_age;
 /* in commands/vacuum.c */
 extern void vacuum(VacuumStmt *vacstmt, VacuumParams *params, Oid relid,
 				   bool do_toast, BufferAccessStrategy bstrategy,
-				   bool for_wraparound, bool isTopLevel);
+				   bool isTopLevel);
 extern void vac_open_indexes(Relation relation, LOCKMODE lockmode,
 				 int *nindexes, Relation **Irel);
 extern void vac_close_indexes(int nindexes, Relation *Irel, LOCKMODE lockmode);
-- 
2.3.1

