From c1a2399f80bc4b9dc981df59b6157d7a136da517 Mon Sep 17 00:00:00 2001
From: Arseniy Mukhin <arseniy.mukhin.dev@gmail.com>
Date: Sat, 11 Apr 2026 16:21:37 +0300
Subject: [PATCH v12 2/3] amcheck: common_verify - snapshot indcheckxmin check

Adds indcheckxmin check to common_verify. Every index needs it for heapallindexed check.
---
 contrib/amcheck/verify_common.c | 25 +++++++++++++++++++++++++
 contrib/amcheck/verify_common.h |  3 +++
 2 files changed, 28 insertions(+)

diff --git a/contrib/amcheck/verify_common.c b/contrib/amcheck/verify_common.c
index 54ce901716b..6909d7aaaa5 100644
--- a/contrib/amcheck/verify_common.c
+++ b/contrib/amcheck/verify_common.c
@@ -189,3 +189,28 @@ index_checkable(Relation rel, Oid am_id)
 
 	return amcheck_index_mainfork_expected(rel);
 }
+
+/*
+ * GetTransactionSnapshot() always acquires a new MVCC snapshot in
+ * READ COMMITTED mode.  A new snapshot is guaranteed to have all
+ * the entries it requires in the index.
+ *
+ * We must defend against the possibility that an old xact
+ * snapshot was returned at higher isolation levels when that
+ * snapshot is not safe for index scans of the target index.  This
+ * is possible when the snapshot sees tuples that are before the
+ * index's indcheckxmin horizon.  Throwing an error here should be
+ * very rare.  It doesn't seem worth using a secondary snapshot to
+ * avoid this.
+ */
+void
+check_indcheckxmin(Relation idxrel, Snapshot snapshot)
+{
+	if (IsolationUsesXactSnapshot() && idxrel->rd_index->indcheckxmin &&
+		!TransactionIdPrecedes(HeapTupleHeaderGetXmin(idxrel->rd_indextuple->t_data),
+							   snapshot->xmin))
+		ereport(ERROR,
+				(errcode(ERRCODE_T_R_SERIALIZATION_FAILURE),
+				 errmsg("index \"%s\" cannot be verified using transaction snapshot",
+						RelationGetRelationName(idxrel))));
+}
diff --git a/contrib/amcheck/verify_common.h b/contrib/amcheck/verify_common.h
index 4c4ddc01aa7..4aaaefa6445 100644
--- a/contrib/amcheck/verify_common.h
+++ b/contrib/amcheck/verify_common.h
@@ -14,6 +14,7 @@
 #include "storage/lmgr.h"
 #include "storage/lockdefs.h"
 #include "utils/relcache.h"
+#include "utils/snapshot.h"
 #include "miscadmin.h"
 
 /* Typedef for callback function for amcheck_lock_relation_and_check */
@@ -26,3 +27,5 @@ extern void amcheck_lock_relation_and_check(Oid indrelid,
 											Oid am_id,
 											IndexDoCheckCallback check,
 											LOCKMODE lockmode, void *state);
+
+extern void check_indcheckxmin(Relation idxrel, Snapshot snapshot);
-- 
2.43.0

