From 7921185eb112e7c1839981e6d5309493c697a1c1 Mon Sep 17 00:00:00 2001
From: Antonin Houska <ah@cybertec.at>
Date: Wed, 26 Feb 2025 09:17:20 +0100
Subject: [PATCH 2/9] Move progress related fields from PgBackendStatus to
 PgBackendProgress.

REPACK CONCURRENTLY will need to save and restore these fields at some
point. This is because plan_cluster_use_sort() has to be called in a
subtransaction (so that it does not leave any additional locks on the table)
and rollback of that subtransaction clears the progress information.
---
 src/backend/access/heap/vacuumlazy.c          |  2 +-
 src/backend/commands/analyze.c                |  2 +-
 src/backend/utils/activity/backend_progress.c | 18 +++++++++---------
 src/backend/utils/activity/backend_status.c   |  4 ++--
 src/backend/utils/adt/pgstatfuncs.c           |  6 +++---
 src/include/utils/backend_progress.h          | 14 ++++++++++++++
 src/include/utils/backend_status.h            | 14 ++------------
 7 files changed, 32 insertions(+), 28 deletions(-)

diff --git a/src/backend/access/heap/vacuumlazy.c b/src/backend/access/heap/vacuumlazy.c
index 1af18a78a2..5a0eb1ca80 100644
--- a/src/backend/access/heap/vacuumlazy.c
+++ b/src/backend/access/heap/vacuumlazy.c
@@ -1100,7 +1100,7 @@ heap_vacuum_rel(Relation rel, VacuumParams *params,
 				 * the st_progress_param array.
 				 */
 				appendStringInfo(&buf, _("delay time: %.3f ms\n"),
-								 (double) MyBEEntry->st_progress_param[PROGRESS_VACUUM_DELAY_TIME] / 1000000.0);
+								 (double) MyBEEntry->st_progress.param[PROGRESS_VACUUM_DELAY_TIME] / 1000000.0);
 			}
 			if (track_io_timing)
 			{
diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c
index cd75954951..49fe8c43ce 100644
--- a/src/backend/commands/analyze.c
+++ b/src/backend/commands/analyze.c
@@ -815,7 +815,7 @@ do_analyze_rel(Relation onerel, VacuumParams *params,
 				 * only updated by the calling process.
 				 */
 				appendStringInfo(&buf, _("delay time: %.3f ms\n"),
-								 (double) MyBEEntry->st_progress_param[PROGRESS_ANALYZE_DELAY_TIME] / 1000000.0);
+								 (double) MyBEEntry->st_progress.param[PROGRESS_ANALYZE_DELAY_TIME] / 1000000.0);
 			}
 			if (track_io_timing)
 			{
diff --git a/src/backend/utils/activity/backend_progress.c b/src/backend/utils/activity/backend_progress.c
index 99a8c73bf0..eebc968193 100644
--- a/src/backend/utils/activity/backend_progress.c
+++ b/src/backend/utils/activity/backend_progress.c
@@ -32,9 +32,9 @@ pgstat_progress_start_command(ProgressCommandType cmdtype, Oid relid)
 		return;
 
 	PGSTAT_BEGIN_WRITE_ACTIVITY(beentry);
-	beentry->st_progress_command = cmdtype;
-	beentry->st_progress_command_target = relid;
-	MemSet(&beentry->st_progress_param, 0, sizeof(beentry->st_progress_param));
+	beentry->st_progress.command = cmdtype;
+	beentry->st_progress.command_target = relid;
+	MemSet(&beentry->st_progress.param, 0, sizeof(beentry->st_progress.param));
 	PGSTAT_END_WRITE_ACTIVITY(beentry);
 }
 
@@ -55,7 +55,7 @@ pgstat_progress_update_param(int index, int64 val)
 		return;
 
 	PGSTAT_BEGIN_WRITE_ACTIVITY(beentry);
-	beentry->st_progress_param[index] = val;
+	beentry->st_progress.param[index] = val;
 	PGSTAT_END_WRITE_ACTIVITY(beentry);
 }
 
@@ -76,7 +76,7 @@ pgstat_progress_incr_param(int index, int64 incr)
 		return;
 
 	PGSTAT_BEGIN_WRITE_ACTIVITY(beentry);
-	beentry->st_progress_param[index] += incr;
+	beentry->st_progress.param[index] += incr;
 	PGSTAT_END_WRITE_ACTIVITY(beentry);
 }
 
@@ -133,7 +133,7 @@ pgstat_progress_update_multi_param(int nparam, const int *index,
 	{
 		Assert(index[i] >= 0 && index[i] < PGSTAT_NUM_PROGRESS_PARAM);
 
-		beentry->st_progress_param[index[i]] = val[i];
+		beentry->st_progress.param[index[i]] = val[i];
 	}
 
 	PGSTAT_END_WRITE_ACTIVITY(beentry);
@@ -154,11 +154,11 @@ pgstat_progress_end_command(void)
 	if (!beentry || !pgstat_track_activities)
 		return;
 
-	if (beentry->st_progress_command == PROGRESS_COMMAND_INVALID)
+	if (beentry->st_progress.command == PROGRESS_COMMAND_INVALID)
 		return;
 
 	PGSTAT_BEGIN_WRITE_ACTIVITY(beentry);
-	beentry->st_progress_command = PROGRESS_COMMAND_INVALID;
-	beentry->st_progress_command_target = InvalidOid;
+	beentry->st_progress.command = PROGRESS_COMMAND_INVALID;
+	beentry->st_progress.command_target = InvalidOid;
 	PGSTAT_END_WRITE_ACTIVITY(beentry);
 }
diff --git a/src/backend/utils/activity/backend_status.c b/src/backend/utils/activity/backend_status.c
index 5f68ef26ad..647bf863f0 100644
--- a/src/backend/utils/activity/backend_status.c
+++ b/src/backend/utils/activity/backend_status.c
@@ -376,8 +376,8 @@ pgstat_bestart(void)
 #endif
 
 	lbeentry.st_state = STATE_UNDEFINED;
-	lbeentry.st_progress_command = PROGRESS_COMMAND_INVALID;
-	lbeentry.st_progress_command_target = InvalidOid;
+	lbeentry.st_progress.command = PROGRESS_COMMAND_INVALID;
+	lbeentry.st_progress.command_target = InvalidOid;
 	lbeentry.st_query_id = UINT64CONST(0);
 
 	/*
diff --git a/src/backend/utils/adt/pgstatfuncs.c b/src/backend/utils/adt/pgstatfuncs.c
index 02ac18fca6..6603b2a64b 100644
--- a/src/backend/utils/adt/pgstatfuncs.c
+++ b/src/backend/utils/adt/pgstatfuncs.c
@@ -299,7 +299,7 @@ pg_stat_get_progress_info(PG_FUNCTION_ARGS)
 		 * Report values for only those backends which are running the given
 		 * command.
 		 */
-		if (beentry->st_progress_command != cmdtype)
+		if (beentry->st_progress.command != cmdtype)
 			continue;
 
 		/* Value available to all callers */
@@ -309,9 +309,9 @@ pg_stat_get_progress_info(PG_FUNCTION_ARGS)
 		/* show rest of the values including relid only to role members */
 		if (HAS_PGSTAT_PERMISSIONS(beentry->st_userid))
 		{
-			values[2] = ObjectIdGetDatum(beentry->st_progress_command_target);
+			values[2] = ObjectIdGetDatum(beentry->st_progress.command_target);
 			for (i = 0; i < PGSTAT_NUM_PROGRESS_PARAM; i++)
-				values[i + 3] = Int64GetDatum(beentry->st_progress_param[i]);
+				values[i + 3] = Int64GetDatum(beentry->st_progress.param[i]);
 		}
 		else
 		{
diff --git a/src/include/utils/backend_progress.h b/src/include/utils/backend_progress.h
index da3d14bb97..2f1de46d05 100644
--- a/src/include/utils/backend_progress.h
+++ b/src/include/utils/backend_progress.h
@@ -31,8 +31,22 @@ typedef enum ProgressCommandType
 	PROGRESS_COMMAND_COPY,
 } ProgressCommandType;
 
+
 #define PGSTAT_NUM_PROGRESS_PARAM	20
 
+/*
+ * Any command which wishes can advertise that it is running by setting
+ * command, command_target, and param[].  command_target should be the OID of
+ * the relation which the command targets (we assume there's just one, as this
+ * is meant for utility commands), but the meaning of each element in the
+ * param array is command-specific.
+ */
+typedef struct PgBackendProgress
+{
+	ProgressCommandType command;
+	Oid			command_target;
+	int64		param[PGSTAT_NUM_PROGRESS_PARAM];
+} PgBackendProgress;
 
 extern void pgstat_progress_start_command(ProgressCommandType cmdtype,
 										  Oid relid);
diff --git a/src/include/utils/backend_status.h b/src/include/utils/backend_status.h
index d3d4ff6c5c..a73c76a442 100644
--- a/src/include/utils/backend_status.h
+++ b/src/include/utils/backend_status.h
@@ -155,18 +155,8 @@ typedef struct PgBackendStatus
 	 */
 	char	   *st_activity_raw;
 
-	/*
-	 * Command progress reporting.  Any command which wishes can advertise
-	 * that it is running by setting st_progress_command,
-	 * st_progress_command_target, and st_progress_param[].
-	 * st_progress_command_target should be the OID of the relation which the
-	 * command targets (we assume there's just one, as this is meant for
-	 * utility commands), but the meaning of each element in the
-	 * st_progress_param array is command-specific.
-	 */
-	ProgressCommandType st_progress_command;
-	Oid			st_progress_command_target;
-	int64		st_progress_param[PGSTAT_NUM_PROGRESS_PARAM];
+	/* Command progress reporting. */
+	PgBackendProgress	st_progress;
 
 	/* query identifier, optionally computed using post_parse_analyze_hook */
 	uint64		st_query_id;
-- 
2.43.5

