From 501b0d7d24d019c55f4b676f89020be48ceb72f3 Mon Sep 17 00:00:00 2001
From: Justin Pryzby <pryzbyj@telsasoft.com>
Date: Fri, 28 Feb 2020 19:20:48 -0600
Subject: [PATCH v9 3/3] fixes

---
 src/backend/catalog/index.c         |  5 +++--
 src/backend/commands/cluster.c      |  2 +-
 src/backend/commands/indexcmds.c    | 10 ++++------
 src/backend/commands/vacuum.c       |  3 ++-
 src/backend/nodes/copyfuncs.c       |  1 +
 src/backend/nodes/equalfuncs.c      |  1 +
 src/backend/parser/gram.y           |  3 +++
 src/backend/postmaster/autovacuum.c |  1 +
 8 files changed, 16 insertions(+), 10 deletions(-)

diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index fd07379118..ad6d325a46 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -3469,7 +3469,8 @@ reindex_index(Oid indexId, Oid tablespaceOid, bool skip_constraint_checks,
 	 * We cannot support moving mapped relations into different tablespaces.
 	 * (In particular this eliminates all shared catalogs.)
 	 */
-	if (OidIsValid(tablespaceOid) && RelationIsMapped(iRel))
+	if (OidIsValid(tablespaceOid) &&
+			(IsSystemRelation(iRel) || IsToastRelation(iRel)))
 		ereport(ERROR,
 				(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
 				 errmsg("cannot move system relation \"%s\"",
@@ -3811,7 +3812,7 @@ reindex_relation(Oid relid, Oid tablespaceOid, int flags, int options)
 	 * still hold the lock on the master table.
 	 */
 	if ((flags & REINDEX_REL_PROCESS_TOAST) && OidIsValid(toast_relid))
-		result |= reindex_relation(toast_relid, tablespaceOid, flags, options);
+		result |= reindex_relation(toast_relid, InvalidOid, flags, options);
 
 	return result;
 }
diff --git a/src/backend/commands/cluster.c b/src/backend/commands/cluster.c
index 0e13c5192e..edd56df4cb 100644
--- a/src/backend/commands/cluster.c
+++ b/src/backend/commands/cluster.c
@@ -603,7 +603,7 @@ rebuild_relation(Relation OldHeap, Oid indexOid, Oid NewTableSpaceOid, bool verb
 	TransactionId frozenXid;
 	MultiXactId cutoffMulti;
 
-	/* Use new TeableSpace if passed. */
+	/* Use new TableSpace if passed. */
 	if (OidIsValid(NewTableSpaceOid))
 		tableSpace = NewTableSpaceOid;
 
diff --git a/src/backend/commands/indexcmds.c b/src/backend/commands/indexcmds.c
index d508f55207..5d934d648b 100644
--- a/src/backend/commands/indexcmds.c
+++ b/src/backend/commands/indexcmds.c
@@ -2692,12 +2692,10 @@ ReindexMultipleTables(const char *objectName, ReindexObjectType objectKind, char
 		}
 
 		/*
-		 * Skip all mapped relations if TABLESPACE is specified.
-		 * relfilenode == 0 checks after that, similarly to
-		 * RelationIsMapped().
+		 * Skip all system relations if TABLESPACE is specified.
 		 */
 		if (OidIsValid(tablespaceOid) &&
-			!OidIsValid(classtuple->relfilenode))
+				IsCatalogRelationOid(relid))
 		{
 			if (!mapped_warning)
 				ereport(WARNING,
@@ -2871,7 +2869,7 @@ ReindexRelationConcurrently(Oid relationOid, Oid tablespaceOid, int options)
 				/* Open relation to get its indexes */
 				heapRelation = table_open(relationOid, ShareUpdateExclusiveLock);
 
-				if (OidIsValid(tablespaceOid) && RelationIsMapped(heapRelation))
+				if (OidIsValid(tablespaceOid) && IsCatalogRelationOid(relationOid))
 					ereport(ERROR,
 							(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
 							 errmsg("cannot change tablespace of indexes for mapped relation \"%s\"",
@@ -3049,7 +3047,7 @@ ReindexRelationConcurrently(Oid relationOid, Oid tablespaceOid, int options)
 		if (indexRel->rd_rel->relpersistence == RELPERSISTENCE_TEMP)
 			elog(ERROR, "cannot reindex a temporary table concurrently");
 
-		if (OidIsValid(tablespaceOid) && RelationIsMapped(heapRel))
+		if (OidIsValid(tablespaceOid) && IsSystemRelation(heapRel))
 			ereport(ERROR,
 					(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
 					 errmsg("cannot change tablespace of mapped relation \"%s\"",
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index c8b3451f5c..005c4ce2cb 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -1827,7 +1827,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params)
 	/*
 	 * We cannot support moving system relations into different tablespaces.
 	 */
-	if (!(params->options & VACOPT_FULL) && OidIsValid(params->tablespace_oid) && IsSystemRelation(onerel))
+	if (!(params->options & VACOPT_FULL) && OidIsValid(params->tablespace_oid)
+			&& IsSystemRelation(onerel))
 	{
 		ereport(WARNING,
 			(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
diff --git a/src/backend/nodes/copyfuncs.c b/src/backend/nodes/copyfuncs.c
index 83ab90c612..12c7f92bc6 100644
--- a/src/backend/nodes/copyfuncs.c
+++ b/src/backend/nodes/copyfuncs.c
@@ -3890,6 +3890,7 @@ _copyVacuumStmt(const VacuumStmt *from)
 	COPY_NODE_FIELD(options);
 	COPY_NODE_FIELD(rels);
 	COPY_SCALAR_FIELD(is_vacuumcmd);
+	COPY_STRING_FIELD(tablespacename);
 
 	return newnode;
 }
diff --git a/src/backend/nodes/equalfuncs.c b/src/backend/nodes/equalfuncs.c
index e63ed0729b..6a169ec773 100644
--- a/src/backend/nodes/equalfuncs.c
+++ b/src/backend/nodes/equalfuncs.c
@@ -1693,6 +1693,7 @@ _equalVacuumStmt(const VacuumStmt *a, const VacuumStmt *b)
 	COMPARE_NODE_FIELD(options);
 	COMPARE_NODE_FIELD(rels);
 	COMPARE_SCALAR_FIELD(is_vacuumcmd);
+	COMPARE_SCALAR_FIELD(tablespacename);
 
 	return true;
 }
diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y
index b982a45cb3..3cab0caa83 100644
--- a/src/backend/parser/gram.y
+++ b/src/backend/parser/gram.y
@@ -10596,6 +10596,7 @@ ClusterStmt:
 					n->options = 0;
 					if ($2)
 						n->options |= CLUOPT_VERBOSE;
+					n->tablespacename = NULL;
 					$$ = (Node*)n;
 				}
 			/* kept for pre-8.3 compatibility */
@@ -10699,6 +10700,7 @@ AnalyzeStmt: analyze_keyword opt_verbose opt_vacuum_relation_list
 											 makeDefElem("verbose", NULL, @2));
 					n->rels = $3;
 					n->is_vacuumcmd = false;
+					n->tablespacename = NULL;
 					$$ = (Node *)n;
 				}
 			| analyze_keyword '(' vac_analyze_option_list ')' opt_vacuum_relation_list
@@ -10707,6 +10709,7 @@ AnalyzeStmt: analyze_keyword opt_verbose opt_vacuum_relation_list
 					n->options = $3;
 					n->rels = $5;
 					n->is_vacuumcmd = false;
+					n->tablespacename = NULL;
 					$$ = (Node *) n;
 				}
 		;
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index 6d1f28c327..e7dbe56a6e 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2894,6 +2894,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
 		tab->at_params.multixact_freeze_table_age = multixact_freeze_table_age;
 		tab->at_params.is_wraparound = wraparound;
 		tab->at_params.log_min_duration = log_min_duration;
+		tab->at_params.tablespace_oid = InvalidOid;
 		tab->at_vacuum_cost_limit = vac_cost_limit;
 		tab->at_vacuum_cost_delay = vac_cost_delay;
 		tab->at_relname = NULL;
-- 
2.17.0

