From 03b235487cadd402130848430feabbb3a1abec1f Mon Sep 17 00:00:00 2001
From: Justin Pryzby <pryzbyj@telsasoft.com>
Date: Tue, 22 Dec 2020 14:53:25 -0600
Subject: [PATCH 2/3] ExecReindex

---
 src/backend/commands/indexcmds.c | 59 ++++++++++++++++++++++++++++----
 src/backend/tcop/utility.c       | 39 ++-------------------
 src/include/commands/defrem.h    | 12 +------
 3 files changed, 55 insertions(+), 55 deletions(-)

diff --git a/src/backend/commands/indexcmds.c b/src/backend/commands/indexcmds.c
index 98a8ade20b..edd394ed4e 100644
--- a/src/backend/commands/indexcmds.c
+++ b/src/backend/commands/indexcmds.c
@@ -86,8 +86,14 @@ static char *ChooseIndexName(const char *tabname, Oid namespaceId,
 							 bool primary, bool isconstraint);
 static char *ChooseIndexNameAddition(List *colnames);
 static List *ChooseIndexColumnNames(List *indexElems);
+static void ReindexIndex(RangeVar *indexRelation, ReindexOptions *options,
+		bool isTopLevel);
 static void RangeVarCallbackForReindexIndex(const RangeVar *relation,
 											Oid relId, Oid oldRelId, void *arg);
+static Oid ReindexTable(RangeVar *relation, ReindexOptions *options,
+		bool isTopLevel);
+static void ReindexMultipleTables(const char *objectName,
+		ReindexObjectType objectKind, ReindexOptions *options);
 static void reindex_error_callback(void *args);
 static void ReindexPartitions(Oid relid, ReindexOptions *options,
 							  bool isTopLevel);
@@ -2455,12 +2461,17 @@ ChooseIndexColumnNames(List *indexElems)
 }
 
 /*
- * ReindexParseOptions
- *		Parse stmt into options.
+ * ExecReindex
+ * Reindex accordinging to stmt.
+ * This calls the intermediate routines: ReindexIndex, ReindexTable, ReindexMultipleTables,
+ * which ultimately call reindex_index, reindex_relation, ReindexRelationConcurrently.
+ * Note that partitioned relations are handled by ReindexPartitions, except that
+ * ReindexRelationConcurrently handles concurrently reindexing a table.
  */
 void
-ReindexParseOptions(ParseState *pstate, ReindexStmt *stmt, ReindexOptions *options)
+ExecReindex(ParseState *pstate, ReindexStmt *stmt, bool isTopLevel)
 {
+	ReindexOptions options = {0};
 	ListCell   *lc;
 	bool		concurrently = false;
 	bool		verbose = false;
@@ -2482,16 +2493,50 @@ ReindexParseOptions(ParseState *pstate, ReindexStmt *stmt, ReindexOptions *optio
 					 parser_errposition(pstate, opt->location)));
 	}
 
-	options->flags =
+	if (concurrently)
+		PreventInTransactionBlock(isTopLevel,
+								  "REINDEX CONCURRENTLY");
+
+	options.flags =
 		(verbose ? REINDEXOPT_VERBOSE : 0) |
 		(concurrently ? REINDEXOPT_CONCURRENTLY : 0);
+
+	switch (stmt->kind)
+	{
+		case REINDEX_OBJECT_INDEX:
+			ReindexIndex(stmt->relation, &options, isTopLevel);
+			break;
+		case REINDEX_OBJECT_TABLE:
+			ReindexTable(stmt->relation, &options, isTopLevel);
+			break;
+		case REINDEX_OBJECT_SCHEMA:
+		case REINDEX_OBJECT_SYSTEM:
+		case REINDEX_OBJECT_DATABASE:
+
+			/*
+			 * This cannot run inside a user transaction block; if
+			 * we were inside a transaction, then its commit- and
+			 * start-transaction-command calls would not have the
+			 * intended effect!
+			 */
+			PreventInTransactionBlock(isTopLevel,
+									  (stmt->kind == REINDEX_OBJECT_SCHEMA) ? "REINDEX SCHEMA" :
+									  (stmt->kind == REINDEX_OBJECT_SYSTEM) ? "REINDEX SYSTEM" :
+									  "REINDEX DATABASE");
+			ReindexMultipleTables(stmt->name, stmt->kind, &options);
+			break;
+		default:
+			elog(ERROR, "unrecognized object type: %d",
+				 (int) stmt->kind);
+			break;
+	}
 }
 
 /*
  * ReindexIndex
  *		Recreate a specific index.
  */
-void
+static void
 ReindexIndex(RangeVar *indexRelation, ReindexOptions *options, bool isTopLevel)
 {
 	struct ReindexIndexCallbackState state;
@@ -2613,7 +2658,7 @@ RangeVarCallbackForReindexIndex(const RangeVar *relation,
  * ReindexTable
  *		Recreate all indexes of a table (and of its toast table, if any)
  */
-Oid
+static Oid
 ReindexTable(RangeVar *relation, ReindexOptions *options, bool isTopLevel)
 {
 	Oid			heapOid;
@@ -2670,7 +2715,7 @@ ReindexTable(RangeVar *relation, ReindexOptions *options, bool isTopLevel)
  * separate transaction, so we can release the lock on it right away.
  * That means this must not be called within a user transaction block!
  */
-void
+static void
 ReindexMultipleTables(const char *objectName, ReindexObjectType objectKind,
 					  ReindexOptions *options)
 {
diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c
index 403b46cefb..4942e24a3a 100644
--- a/src/backend/tcop/utility.c
+++ b/src/backend/tcop/utility.c
@@ -919,44 +919,9 @@ standard_ProcessUtility(PlannedStmt *pstmt,
 		case T_ReindexStmt:
 			{
 				ReindexStmt *stmt = (ReindexStmt *) parsetree;
-				ReindexOptions options;
-
-				ReindexParseOptions(pstate, stmt, &options);
-				if ((options.flags & REINDEXOPT_CONCURRENTLY) != 0)
-					PreventInTransactionBlock(isTopLevel,
-											  "REINDEX CONCURRENTLY");
-
-				switch (stmt->kind)
-				{
-					case REINDEX_OBJECT_INDEX:
-						ReindexIndex(stmt->relation, &options, isTopLevel);
-						break;
-					case REINDEX_OBJECT_TABLE:
-						ReindexTable(stmt->relation, &options, isTopLevel);
-						break;
-					case REINDEX_OBJECT_SCHEMA:
-					case REINDEX_OBJECT_SYSTEM:
-					case REINDEX_OBJECT_DATABASE:
-
-						/*
-						 * This cannot run inside a user transaction block; if
-						 * we were inside a transaction, then its commit- and
-						 * start-transaction-command calls would not have the
-						 * intended effect!
-						 */
-						PreventInTransactionBlock(isTopLevel,
-												  (stmt->kind == REINDEX_OBJECT_SCHEMA) ? "REINDEX SCHEMA" :
-												  (stmt->kind == REINDEX_OBJECT_SYSTEM) ? "REINDEX SYSTEM" :
-												  "REINDEX DATABASE");
-						ReindexMultipleTables(stmt->name, stmt->kind, &options);
-						break;
-					default:
-						elog(ERROR, "unrecognized object type: %d",
-							 (int) stmt->kind);
-						break;
-				}
+				ExecReindex(pstate, stmt, isTopLevel);
+				break;
 			}
-			break;
 
 			/*
 			 * The following statements are supported by Event Triggers only
diff --git a/src/include/commands/defrem.h b/src/include/commands/defrem.h
index ca276e222d..d4ea57e757 100644
--- a/src/include/commands/defrem.h
+++ b/src/include/commands/defrem.h
@@ -35,17 +35,7 @@ extern ObjectAddress DefineIndex(Oid relationId,
 								 bool check_not_in_use,
 								 bool skip_build,
 								 bool quiet);
-extern void ReindexParseOptions(ParseState *pstate, ReindexStmt *stmt,
-								ReindexOptions *options);
-extern void ReindexIndex(RangeVar *indexRelation,
-						 ReindexOptions *options,
-						 bool isTopLevel);
-extern Oid	ReindexTable(RangeVar *relation,
-						 ReindexOptions *options,
-						 bool isTopLevel);
-extern void ReindexMultipleTables(const char *objectName,
-								  ReindexObjectType objectKind,
-								  ReindexOptions *options);
+extern void ExecReindex(ParseState *pstate, ReindexStmt *stmt, bool isTopLevel);
 extern char *makeObjectName(const char *name1, const char *name2,
 							const char *label);
 extern char *ChooseRelationName(const char *name1, const char *name2,
-- 
2.17.0

