From 65a894a6516bf870e157f0e86fc58517bbf03e81 Mon Sep 17 00:00:00 2001
From: Jim Jones <jim.jones@uni-muenster.de>
Date: Mon, 2 Nov 2026 10:03:26 +0100
Subject: [PATCH v3 4/5] pg_visibility: Reject unlogged tables during recovery

Unlogged tables have no data on a standby, so reading one there must
fail.  The pg_visibility functions read the table or its visibility map
directly instead of going through the planner.  On a standby, some of
them failed with a confusing low-level message instead of the error
that SELECT reports:

  ERROR:  could not open file "base/5/16384": No such file or directory

while pg_visibility_map(regclass, bigint) and pg_visibility_map_summary()
reported every page as neither all-visible nor all-frozen, because the
visibility map fork does not exist there.

Check for this case in check_relation_relkind(), which every function
calls, and report the same error as SELECT:

  ERROR:  cannot access temporary or unlogged relations during recovery

Author: Jim Jones <jim.jones@uni-muenster.de>
Reported-by: Zsolt Parragi <zsolt.parragi@percona.com>
Reviewed-by: Kirill Reshke <reshkekirill@gmail.com>
Reviewed-by: Michael Paquier <michael@paquier.xyz>
---
 contrib/pg_visibility/pg_visibility.c | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/contrib/pg_visibility/pg_visibility.c b/contrib/pg_visibility/pg_visibility.c
index 717c851583f..4195aeacc2a 100644
--- a/contrib/pg_visibility/pg_visibility.c
+++ b/contrib/pg_visibility/pg_visibility.c
@@ -13,6 +13,7 @@
 #include "access/heapam.h"
 #include "access/htup_details.h"
 #include "access/visibilitymap.h"
+#include "access/xlog.h"
 #include "access/xloginsert.h"
 #include "catalog/pg_type.h"
 #include "catalog/storage_xlog.h"
@@ -918,7 +919,7 @@ tuple_all_visible(HeapTuple tup, TransactionId OldestXmin, Buffer buffer)
 
 /*
  * check_relation_relkind - convenience routine to check that relation
- * is of the relkind supported by the callers
+ * is of the relkind supported by the callers and can be accessed
  */
 static void
 check_relation_relkind(Relation rel)
@@ -929,4 +930,10 @@ check_relation_relkind(Relation rel)
 				 errmsg("relation \"%s\" is of wrong relation kind",
 						RelationGetRelationName(rel)),
 				 errdetail_relkind_not_supported(rel->rd_rel->relkind)));
+
+	/* Temporary and unlogged relations are inaccessible during recovery. */
+	if (!RelationIsPermanent(rel) && RecoveryInProgress())
+		ereport(ERROR,
+				(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+				 errmsg("cannot access temporary or unlogged relations during recovery")));
 }
-- 
2.56.0

