From 6b329308d81ffc7140d51c2709f59d1dd57f31e5 Mon Sep 17 00:00:00 2001
From: Osumi Takamichi <osumi.takamichi@fujitsu.com>
Date: Mon, 15 Nov 2021 08:45:55 +0000
Subject: [PATCH v10 1/2] Rename existing columns of
 pg_stat_subscription_workers and export PartitionTupleRouting

---
 doc/src/sgml/monitoring.sgml                | 24 +++++-----
 src/backend/catalog/system_views.sql        | 10 ++---
 src/backend/executor/execPartition.c        | 70 -----------------------------
 src/backend/utils/adt/pgstatfuncs.c         | 20 ++++-----
 src/include/catalog/pg_proc.dat             |  2 +-
 src/include/executor/execPartition.h        | 69 ++++++++++++++++++++++++++++
 src/test/regress/expected/rules.out         | 12 ++---
 src/test/subscription/t/026_error_report.pl |  8 ++--
 8 files changed, 107 insertions(+), 108 deletions(-)

diff --git a/doc/src/sgml/monitoring.sgml b/doc/src/sgml/monitoring.sgml
index 4ee97db..8b7920c 100644
--- a/doc/src/sgml/monitoring.sgml
+++ b/doc/src/sgml/monitoring.sgml
@@ -3103,31 +3103,31 @@ SELECT pid, wait_event_type, wait_event FROM pg_stat_activity WHERE wait_event i
 
      <row>
       <entry role="catalog_table_entry"><para role="column_definition">
-       <structfield>relid</structfield> <type>oid</type>
+       <structfield>last_error_relid</structfield> <type>oid</type>
       </para>
       <para>
        OID of the relation that the worker was processing when the
-       error occurred
+       last error occurred
       </para></entry>
      </row>
 
      <row>
       <entry role="catalog_table_entry"><para role="column_definition">
-       <structfield>command</structfield> <type>text</type>
+       <structfield>last_error_command</structfield> <type>text</type>
       </para>
       <para>
-       Name of command being applied when the error occurred.  This field
-       is always NULL if the error was reported during the initial data
-       copy.
+       Name of the last command being applied when the error occurred.
+       This field is always NULL if the error was reported during the
+       initial data copy.
       </para></entry>
      </row>
 
      <row>
       <entry role="catalog_table_entry"><para role="column_definition">
-       <structfield>xid</structfield> <type>xid</type>
+       <structfield>last_error_xid</structfield> <type>xid</type>
       </para>
       <para>
-       Transaction ID of the publisher node being applied when the error
+       Transaction ID of the publisher node being applied when the last error
        occurred.  This field is always NULL if the error was reported
        during the initial data copy.
       </para></entry>
@@ -3135,19 +3135,19 @@ SELECT pid, wait_event_type, wait_event FROM pg_stat_activity WHERE wait_event i
 
      <row>
       <entry role="catalog_table_entry"><para role="column_definition">
-       <structfield>error_count</structfield> <type>uint8</type>
+       <structfield>last_error_count</structfield> <type>uint8</type>
       </para>
       <para>
-       Number of consecutive times the error occurred
+       Number of consecutive times the last error occurred
       </para></entry>
      </row>
 
      <row>
       <entry role="catalog_table_entry"><para role="column_definition">
-       <structfield>error_message</structfield> <type>text</type>
+       <structfield>last_error_message</structfield> <type>text</type>
       </para>
       <para>
-       The error message
+       The last error message
       </para></entry>
      </row>
 
diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql
index cb2f77c..ecf1a0b 100644
--- a/src/backend/catalog/system_views.sql
+++ b/src/backend/catalog/system_views.sql
@@ -1267,11 +1267,11 @@ CREATE VIEW pg_stat_subscription_workers AS
         w.subid,
         s.subname,
         w.subrelid,
-        w.relid,
-        w.command,
-        w.xid,
-        w.error_count,
-        w.error_message,
+        w.last_error_relid,
+        w.last_error_command,
+        w.last_error_xid,
+        w.last_error_count,
+        w.last_error_message,
         w.first_error_time,
         w.last_error_time
     FROM (SELECT
diff --git a/src/backend/executor/execPartition.c b/src/backend/executor/execPartition.c
index 5c723bc..2467f4c 100644
--- a/src/backend/executor/execPartition.c
+++ b/src/backend/executor/execPartition.c
@@ -34,76 +34,6 @@
 #include "utils/rls.h"
 #include "utils/ruleutils.h"
 
-
-/*-----------------------
- * PartitionTupleRouting - Encapsulates all information required to
- * route a tuple inserted into a partitioned table to one of its leaf
- * partitions.
- *
- * partition_root
- *		The partitioned table that's the target of the command.
- *
- * partition_dispatch_info
- *		Array of 'max_dispatch' elements containing a pointer to a
- *		PartitionDispatch object for every partitioned table touched by tuple
- *		routing.  The entry for the target partitioned table is *always*
- *		present in the 0th element of this array.  See comment for
- *		PartitionDispatchData->indexes for details on how this array is
- *		indexed.
- *
- * nonleaf_partitions
- *		Array of 'max_dispatch' elements containing pointers to fake
- *		ResultRelInfo objects for nonleaf partitions, useful for checking
- *		the partition constraint.
- *
- * num_dispatch
- *		The current number of items stored in the 'partition_dispatch_info'
- *		array.  Also serves as the index of the next free array element for
- *		new PartitionDispatch objects that need to be stored.
- *
- * max_dispatch
- *		The current allocated size of the 'partition_dispatch_info' array.
- *
- * partitions
- *		Array of 'max_partitions' elements containing a pointer to a
- *		ResultRelInfo for every leaf partition touched by tuple routing.
- *		Some of these are pointers to ResultRelInfos which are borrowed out of
- *		the owning ModifyTableState node.  The remainder have been built
- *		especially for tuple routing.  See comment for
- *		PartitionDispatchData->indexes for details on how this array is
- *		indexed.
- *
- * is_borrowed_rel
- *		Array of 'max_partitions' booleans recording whether a given entry
- *		in 'partitions' is a ResultRelInfo pointer borrowed from the owning
- *		ModifyTableState node, rather than being built here.
- *
- * num_partitions
- *		The current number of items stored in the 'partitions' array.  Also
- *		serves as the index of the next free array element for new
- *		ResultRelInfo objects that need to be stored.
- *
- * max_partitions
- *		The current allocated size of the 'partitions' array.
- *
- * memcxt
- *		Memory context used to allocate subsidiary structs.
- *-----------------------
- */
-struct PartitionTupleRouting
-{
-	Relation	partition_root;
-	PartitionDispatch *partition_dispatch_info;
-	ResultRelInfo **nonleaf_partitions;
-	int			num_dispatch;
-	int			max_dispatch;
-	ResultRelInfo **partitions;
-	bool	   *is_borrowed_rel;
-	int			num_partitions;
-	int			max_partitions;
-	MemoryContext memcxt;
-};
-
 /*-----------------------
  * PartitionDispatch - information about one partitioned table in a partition
  * hierarchy required to route a tuple to any of its partitions.  A
diff --git a/src/backend/utils/adt/pgstatfuncs.c b/src/backend/utils/adt/pgstatfuncs.c
index 4e1bbcc..e7ff4ef 100644
--- a/src/backend/utils/adt/pgstatfuncs.c
+++ b/src/backend/utils/adt/pgstatfuncs.c
@@ -2441,15 +2441,15 @@ pg_stat_get_subscription_worker(PG_FUNCTION_ARGS)
 					   OIDOID, -1, 0);
 	TupleDescInitEntry(tupdesc, (AttrNumber) 2, "subrelid",
 					   OIDOID, -1, 0);
-	TupleDescInitEntry(tupdesc, (AttrNumber) 3, "relid",
+	TupleDescInitEntry(tupdesc, (AttrNumber) 3, "last_error_relid",
 					   OIDOID, -1, 0);
-	TupleDescInitEntry(tupdesc, (AttrNumber) 4, "command",
+	TupleDescInitEntry(tupdesc, (AttrNumber) 4, "last_error_command",
 					   TEXTOID, -1, 0);
-	TupleDescInitEntry(tupdesc, (AttrNumber) 5, "xid",
+	TupleDescInitEntry(tupdesc, (AttrNumber) 5, "last_error_xid",
 					   XIDOID, -1, 0);
-	TupleDescInitEntry(tupdesc, (AttrNumber) 6, "error_count",
+	TupleDescInitEntry(tupdesc, (AttrNumber) 6, "last_error_count",
 					   INT8OID, -1, 0);
-	TupleDescInitEntry(tupdesc, (AttrNumber) 7, "error_message",
+	TupleDescInitEntry(tupdesc, (AttrNumber) 7, "last_error_message",
 					   TEXTOID, -1, 0);
 	TupleDescInitEntry(tupdesc, (AttrNumber) 8, "first_error_time",
 					   TIMESTAMPTZOID, -1, 0);
@@ -2471,28 +2471,28 @@ pg_stat_get_subscription_worker(PG_FUNCTION_ARGS)
 	else
 		nulls[i++] = true;
 
-	/* relid */
+	/* last_error_relid */
 	if (OidIsValid(wentry->relid))
 		values[i++] = ObjectIdGetDatum(wentry->relid);
 	else
 		nulls[i++] = true;
 
-	/* command */
+	/* last_error_command */
 	if (wentry->command != 0)
 		values[i++] = CStringGetTextDatum(logicalrep_message_type(wentry->command));
 	else
 		nulls[i++] = true;
 
-	/* xid */
+	/* last_error_xid */
 	if (TransactionIdIsValid(wentry->xid))
 		values[i++] = TransactionIdGetDatum(wentry->xid);
 	else
 		nulls[i++] = true;
 
-	/* error_count */
+	/* last_error_count */
 	values[i++] = Int64GetDatum(wentry->error_count);
 
-	/* error_message */
+	/* last_error_message */
 	values[i++] = CStringGetTextDatum(wentry->error_message);
 
 	/* first_error_time */
diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat
index 50e1c7b..25f685f 100644
--- a/src/include/catalog/pg_proc.dat
+++ b/src/include/catalog/pg_proc.dat
@@ -5391,7 +5391,7 @@
   prorettype => 'record', proargtypes => 'oid oid',
   proallargtypes => '{oid,oid,oid,oid,oid,text,xid,int8,text,timestamptz,timestamptz}',
   proargmodes => '{i,i,o,o,o,o,o,o,o,o,o}',
-  proargnames => '{subid,subrelid,subid,subrelid,relid,command,xid,error_count,error_message,first_error_time,last_error_time}',
+  proargnames => '{subid,subrelid,subid,subrelid,last_error_relid,last_error_command,last_error_xid,last_error_count,last_error_message,first_error_time,last_error_time}',
   prosrc => 'pg_stat_get_subscription_worker' },
 { oid => '6118', descr => 'statistics: information about subscription',
   proname => 'pg_stat_get_subscription', prorows => '10', proisstrict => 'f',
diff --git a/src/include/executor/execPartition.h b/src/include/executor/execPartition.h
index 694e38b..4c796ab 100644
--- a/src/include/executor/execPartition.h
+++ b/src/include/executor/execPartition.h
@@ -110,6 +110,75 @@ typedef struct PartitionPruneState
 	PartitionPruningData *partprunedata[FLEXIBLE_ARRAY_MEMBER];
 } PartitionPruneState;
 
+/*-----------------------
+ * PartitionTupleRouting - Encapsulates all information required to
+ * route a tuple inserted into a partitioned table to one of its leaf
+ * partitions.
+ *
+ * partition_root
+ *		The partitioned table that's the target of the command.
+ *
+ * partition_dispatch_info
+ *		Array of 'max_dispatch' elements containing a pointer to a
+ *		PartitionDispatch object for every partitioned table touched by tuple
+ *		routing.  The entry for the target partitioned table is *always*
+ *		present in the 0th element of this array.  See comment for
+ *		PartitionDispatchData->indexes for details on how this array is
+ *		indexed.
+ *
+ * nonleaf_partitions
+ *		Array of 'max_dispatch' elements containing pointers to fake
+ *		ResultRelInfo objects for nonleaf partitions, useful for checking
+ *		the partition constraint.
+ *
+ * num_dispatch
+ *		The current number of items stored in the 'partition_dispatch_info'
+ *		array.  Also serves as the index of the next free array element for
+ *		new PartitionDispatch objects that need to be stored.
+ *
+ * max_dispatch
+ *		The current allocated size of the 'partition_dispatch_info' array.
+ *
+ * partitions
+ *		Array of 'max_partitions' elements containing a pointer to a
+ *		ResultRelInfo for every leaf partition touched by tuple routing.
+ *		Some of these are pointers to ResultRelInfos which are borrowed out of
+ *		the owning ModifyTableState node.  The remainder have been built
+ *		especially for tuple routing.  See comment for
+ *		PartitionDispatchData->indexes for details on how this array is
+ *		indexed.
+ *
+ * is_borrowed_rel
+ *		Array of 'max_partitions' booleans recording whether a given entry
+ *		in 'partitions' is a ResultRelInfo pointer borrowed from the owning
+ *		ModifyTableState node, rather than being built here.
+ *
+ * num_partitions
+ *		The current number of items stored in the 'partitions' array.  Also
+ *		serves as the index of the next free array element for new
+ *		ResultRelInfo objects that need to be stored.
+ *
+ * max_partitions
+ *		The current allocated size of the 'partitions' array.
+ *
+ * memcxt
+ *		Memory context used to allocate subsidiary structs.
+ *-----------------------
+ */
+struct PartitionTupleRouting
+{
+	Relation	partition_root;
+	PartitionDispatch *partition_dispatch_info;
+	ResultRelInfo **nonleaf_partitions;
+	int			num_dispatch;
+	int			max_dispatch;
+	ResultRelInfo **partitions;
+	bool	   *is_borrowed_rel;
+	int			num_partitions;
+	int			max_partitions;
+	MemoryContext memcxt;
+};
+
 extern PartitionTupleRouting *ExecSetupPartitionTupleRouting(EState *estate,
 															 Relation rel);
 extern ResultRelInfo *ExecFindPartition(ModifyTableState *mtstate,
diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out
index cb6da2c..d60c5a5 100644
--- a/src/test/regress/expected/rules.out
+++ b/src/test/regress/expected/rules.out
@@ -2097,11 +2097,11 @@ pg_stat_subscription| SELECT su.oid AS subid,
 pg_stat_subscription_workers| SELECT w.subid,
     s.subname,
     w.subrelid,
-    w.relid,
-    w.command,
-    w.xid,
-    w.error_count,
-    w.error_message,
+    w.last_error_relid,
+    w.last_error_command,
+    w.last_error_xid,
+    w.last_error_count,
+    w.last_error_message,
     w.first_error_time,
     w.last_error_time
    FROM ( SELECT pg_subscription.oid AS subid,
@@ -2112,7 +2112,7 @@ pg_stat_subscription_workers| SELECT w.subid,
             pg_subscription_rel.srrelid AS relid
            FROM pg_subscription_rel
           WHERE (pg_subscription_rel.srsubstate <> 'r'::"char")) sr,
-    (LATERAL pg_stat_get_subscription_worker(sr.subid, sr.relid) w(subid, subrelid, relid, command, xid, error_count, error_message, first_error_time, last_error_time)
+    (LATERAL pg_stat_get_subscription_worker(sr.subid, sr.relid) w(subid, subrelid, last_error_relid, last_error_command, last_error_xid, last_error_count, last_error_message, first_error_time, last_error_time)
      JOIN pg_subscription s ON ((w.subid = s.oid)));
 pg_stat_sys_indexes| SELECT pg_stat_all_indexes.relid,
     pg_stat_all_indexes.indexrelid,
diff --git a/src/test/subscription/t/026_error_report.pl b/src/test/subscription/t/026_error_report.pl
index 1227654..ca30ab2 100644
--- a/src/test/subscription/t/026_error_report.pl
+++ b/src/test/subscription/t/026_error_report.pl
@@ -15,8 +15,8 @@ sub test_subscription_error
 
     my $check_sql = qq[
 SELECT count(1) > 0 FROM pg_stat_subscription_workers
-WHERE relid = '$relname'::regclass];
-    $check_sql .= " AND xid = '$xid'::xid;" if $xid ne '';
+WHERE last_error_relid = '$relname'::regclass];
+    $check_sql .= " AND last_error_xid = '$xid'::xid;" if $xid ne '';
 
     # Wait for the error statistics to be updated.
     $node->poll_query_until(
@@ -26,9 +26,9 @@ WHERE relid = '$relname'::regclass];
     my $result = $node->safe_psql(
 	'postgres',
 	qq[
-SELECT subname, command, relid::regclass, error_count > 0
+SELECT subname, last_error_command, last_error_relid::regclass, last_error_count > 0
 FROM pg_stat_subscription_workers
-WHERE relid = '$relname'::regclass;
+WHERE last_error_relid = '$relname'::regclass;
 ]);
     is($result, $expected_error, $msg);
 }
-- 
2.2.0

