From a3032b89ce8e8e325035e2858a2b58a92d6ede7c Mon Sep 17 00:00:00 2001
From: Andres Freund <andres@anarazel.de>
Date: Mon, 9 Jan 2023 11:24:37 -0800
Subject: [PATCH v3 3/6] wip: amcheck: Fix bugs relating to 64bit xids

Discussion: https://postgr.es/m/20230108002923.cyoser3ttmt63bfn@awork3.anarazel.de
---
 contrib/amcheck/verify_heapam.c | 16 +++++++++++++++-
 1 file changed, 15 insertions(+), 1 deletion(-)

diff --git a/contrib/amcheck/verify_heapam.c b/contrib/amcheck/verify_heapam.c
index 4fcfd6df72d..56a3b3e9974 100644
--- a/contrib/amcheck/verify_heapam.c
+++ b/contrib/amcheck/verify_heapam.c
@@ -1576,11 +1576,25 @@ FullTransactionIdFromXidAndCtx(TransactionId xid, const HeapCheckContext *ctx)
 {
 	uint32		epoch;
 
+	Assert(TransactionIdIsValid(ctx->next_xid));
+	Assert(FullTransactionIdIsValid(ctx->next_fxid));
+
 	if (!TransactionIdIsNormal(xid))
 		return FullTransactionIdFromEpochAndXid(0, xid);
 	epoch = EpochFromFullTransactionId(ctx->next_fxid);
 	if (xid > ctx->next_xid)
+	{
+		/*
+		 * FIXME, doubtful this is the best fix.
+		 *
+		 * Can't represent the 32bit xid as a 64bit xid, as it's before fxid
+		 * 0. Represent it as an xid from the future instead.
+		 */
+		if (epoch == 0)
+			return FullTransactionIdFromEpochAndXid(0, xid);
+
 		epoch--;
+	}
 	return FullTransactionIdFromEpochAndXid(epoch, xid);
 }
 
@@ -1597,8 +1611,8 @@ update_cached_xid_range(HeapCheckContext *ctx)
 	LWLockRelease(XidGenLock);
 
 	/* And compute alternate versions of the same */
-	ctx->oldest_fxid = FullTransactionIdFromXidAndCtx(ctx->oldest_xid, ctx);
 	ctx->next_xid = XidFromFullTransactionId(ctx->next_fxid);
+	ctx->oldest_fxid = FullTransactionIdFromXidAndCtx(ctx->oldest_xid, ctx);
 }
 
 /*
-- 
2.38.0

