From 3b1f38fe237418ef43d3435321652590da00cd9d Mon Sep 17 00:00:00 2001
From: reshke <reshke@qavm-273b4667.qemu>
Date: Mon, 20 Jul 2026 18:25:39 +0300
Subject: [PATCH v6 2/2] Add `primary_last_archived` column to
 pg_stat_wal_receiver view.

Comes in-handy for monitoring shared archive feature. TAP tests for
shared archive feature were extended to check for this column value.

Bumps catversion.
---
 src/backend/catalog/system_views.sql      |  1 +
 src/backend/replication/walreceiver.c     | 24 +++++++++++++++--------
 src/include/catalog/catversion.h          |  2 +-
 src/include/catalog/pg_proc.dat           |  6 +++---
 src/test/recovery/t/055_archive_shared.pl | 11 +++++++++++
 5 files changed, 32 insertions(+), 12 deletions(-)

diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql
index 090281a03dd..5bd037aa59b 100644
--- a/src/backend/catalog/system_views.sql
+++ b/src/backend/catalog/system_views.sql
@@ -1025,6 +1025,7 @@ CREATE VIEW pg_stat_wal_receiver AS
             s.last_msg_receipt_time,
             s.latest_end_lsn,
             s.latest_end_time,
+            s.primary_last_archived,
             s.slot_name,
             s.sender_host,
             s.sender_port,
diff --git a/src/backend/replication/walreceiver.c b/src/backend/replication/walreceiver.c
index f226ea422e1..b115703f0da 100644
--- a/src/backend/replication/walreceiver.c
+++ b/src/backend/replication/walreceiver.c
@@ -1712,6 +1712,7 @@ pg_stat_get_wal_receiver(PG_FUNCTION_ARGS)
 	int			sender_port = 0;
 	char		slotname[NAMEDATALEN];
 	char		conninfo[MAXCONNINFO];
+	char		primary_last_archived[MAX_XFN_CHARS + 1];
 
 	/* Take a lock to ensure value consistency */
 	SpinLockAcquire(&WalRcv->mutex);
@@ -1732,6 +1733,9 @@ pg_stat_get_wal_receiver(PG_FUNCTION_ARGS)
 	strlcpy(conninfo, WalRcv->conninfo, sizeof(conninfo));
 	SpinLockRelease(&WalRcv->mutex);
 
+	SpinLockAcquire(&PgArch->lock);
+	strlcpy(primary_last_archived, PgArch->primary_last_archived, sizeof(primary_last_archived));
+	SpinLockRelease(&PgArch->lock);
 	/*
 	 * No WAL receiver (or not ready yet), just return a tuple with NULL
 	 * values
@@ -1800,22 +1804,26 @@ pg_stat_get_wal_receiver(PG_FUNCTION_ARGS)
 			nulls[10] = true;
 		else
 			values[10] = TimestampTzGetDatum(latest_end_time);
-		if (*slotname == '\0')
+		if (*primary_last_archived == '\0')
 			nulls[11] = true;
 		else
-			values[11] = CStringGetTextDatum(slotname);
-		if (*sender_host == '\0')
+			values[11] = CStringGetTextDatum(primary_last_archived);
+		if (*slotname == '\0')
 			nulls[12] = true;
 		else
-			values[12] = CStringGetTextDatum(sender_host);
-		if (sender_port == 0)
+			values[12] = CStringGetTextDatum(slotname);
+		if (*sender_host == '\0')
 			nulls[13] = true;
 		else
-			values[13] = Int32GetDatum(sender_port);
-		if (*conninfo == '\0')
+			values[13] = CStringGetTextDatum(sender_host);
+		if (sender_port == 0)
 			nulls[14] = true;
 		else
-			values[14] = CStringGetTextDatum(conninfo);
+			values[14] = Int32GetDatum(sender_port);
+		if (*conninfo == '\0')
+			nulls[15] = true;
+		else
+			values[15] = CStringGetTextDatum(conninfo);
 	}
 
 	/* Returns the record as Datum */
diff --git a/src/include/catalog/catversion.h b/src/include/catalog/catversion.h
index f046605ccf9..d0399cc1cbe 100644
--- a/src/include/catalog/catversion.h
+++ b/src/include/catalog/catversion.h
@@ -57,6 +57,6 @@
  */
 
 /*							yyyymmddN */
-#define CATALOG_VERSION_NO	202607173
+#define CATALOG_VERSION_NO	202607201
 
 #endif
diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat
index 1c55a4dea34..bf7ed03c0ae 100644
--- a/src/include/catalog/pg_proc.dat
+++ b/src/include/catalog/pg_proc.dat
@@ -5718,9 +5718,9 @@
 { oid => '3317', descr => 'statistics: information about WAL receiver',
   proname => 'pg_stat_get_wal_receiver', proisstrict => 'f', provolatile => 's',
   proparallel => 'r', prorettype => 'record', proargtypes => '',
-  proallargtypes => '{int4,text,pg_lsn,int4,pg_lsn,pg_lsn,int4,timestamptz,timestamptz,pg_lsn,timestamptz,text,text,int4,text}',
-  proargmodes => '{o,o,o,o,o,o,o,o,o,o,o,o,o,o,o}',
-  proargnames => '{pid,status,receive_start_lsn,receive_start_tli,written_lsn,flushed_lsn,received_tli,last_msg_send_time,last_msg_receipt_time,latest_end_lsn,latest_end_time,slot_name,sender_host,sender_port,conninfo}',
+  proallargtypes => '{int4,text,pg_lsn,int4,pg_lsn,pg_lsn,int4,timestamptz,timestamptz,pg_lsn,timestamptz,text,text,text,int4,text}',
+  proargmodes => '{o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o}',
+  proargnames => '{pid,status,receive_start_lsn,receive_start_tli,written_lsn,flushed_lsn,received_tli,last_msg_send_time,last_msg_receipt_time,latest_end_lsn,latest_end_time,primary_last_archived,slot_name,sender_host,sender_port,conninfo}',
   prosrc => 'pg_stat_get_wal_receiver' },
 { oid => '6514', descr => 'statistics: information about WAL recovery',
   proname => 'pg_stat_get_recovery', proisstrict => 'f', provolatile => 's',
diff --git a/src/test/recovery/t/055_archive_shared.pl b/src/test/recovery/t/055_archive_shared.pl
index 2a94f98010f..f3f1e13c6de 100644
--- a/src/test/recovery/t/055_archive_shared.pl
+++ b/src/test/recovery/t/055_archive_shared.pl
@@ -85,6 +85,9 @@ cmp_ok($status_count, '>', 0, "standby creates archive status files for received
 
 # Generate more WAL and wait for archiving on primary
 my $initial_archived = $primary->safe_psql('postgres', 'SELECT archived_count FROM pg_stat_archiver');
+my $primary_last_archived = $primary->safe_psql('postgres',
+	q{SELECT pg_walfile_name(pg_current_wal_lsn())});
+
 $primary->safe_psql('postgres', "SELECT txid_current();SELECT pg_switch_wal();");
 
 # Wait for primary to archive the new segments
@@ -109,9 +112,17 @@ for (my $i = 0; $i < $PostgreSQL::Test::Utils::timeout_default; $i++)
 	last if $done_count > 0;
 	sleep(1);
 }
+	
 ok($done_count > 0, "standby marked segments as .done after primary's archival report");
 note("Standby has $done_count .done files");
 
+# The primary_last_archived  done status for WAL file itself must also be present.
+ok(-f "$standby_archive_status/$primary_last_archived.done",
+	"WAL segment $primary_last_archived done file exists in standby pg_wal/archive_status");
+
+is($primary_last_archived, $standby->safe_psql('postgres',
+	q{SELECT primary_last_archived from pg_stat_wal_receiver; }),  "standby wal receiver stat view updated with primary last archived wal");
+
 ###############################################################################
 # Test 2: Cascading replication
 ###############################################################################
-- 
2.43.0

