From aab002af3664640de200235ac42e11118a3dfb65 Mon Sep 17 00:00:00 2001
From: Melanie Plageman <melanieplageman@gmail.com>
Date: Fri, 25 Sep 2026 10:33:51 -0400
Subject: [PATCH v1 09/11] Return the prior visibility map bits from
 visibilitymap_clear()

Change visibilitymap_clear() to return the visibility map bits that were set
before the clear, instead of a bool indicating whether anything was cleared.
Callers can then tell which bits were set.
---
 src/backend/access/heap/heapam.c        |  9 ++++++---
 src/backend/access/heap/heapam_xlog.c   |  3 ++-
 src/backend/access/heap/visibilitymap.c | 15 ++++++++-------
 src/include/access/visibilitymap.h      |  4 ++--
 4 files changed, 18 insertions(+), 13 deletions(-)

diff --git a/src/backend/access/heap/heapam.c b/src/backend/access/heap/heapam.c
index d2797237f4c..bbee995b49b 100644
--- a/src/backend/access/heap/heapam.c
+++ b/src/backend/access/heap/heapam.c
@@ -3939,7 +3939,8 @@ heap_update(Relation relation, const ItemPointerData *otid, HeapTuple newtup,
 		{
 			/* It's possible all-frozen was already clear */
 			if (visibilitymap_clear(relation->rd_locator, block, vmbuffer,
-									VISIBILITYMAP_ALL_FROZEN))
+									VISIBILITYMAP_ALL_FROZEN) &
+				VISIBILITYMAP_ALL_FROZEN)
 				cleared_all_frozen = true;
 		}
 
@@ -5400,7 +5401,8 @@ heap_lock_tuple(Relation relation, HeapTuple tuple,
 	if (PageIsAllVisible(page))
 	{
 		if (visibilitymap_clear(relation->rd_locator, block, vmbuffer,
-								VISIBILITYMAP_ALL_FROZEN))
+								VISIBILITYMAP_ALL_FROZEN) &
+			VISIBILITYMAP_ALL_FROZEN)
 			cleared_all_frozen = true;
 	}
 
@@ -6193,7 +6195,8 @@ heap_lock_updated_tuple_rec(Relation rel, TransactionId priorXmax,
 		{
 			/* It's possible all-frozen was already clear */
 			if (visibilitymap_clear(rel->rd_locator, block, vmbuffer,
-									VISIBILITYMAP_ALL_FROZEN))
+									VISIBILITYMAP_ALL_FROZEN) &
+				VISIBILITYMAP_ALL_FROZEN)
 				cleared_all_frozen = true;
 		}
 
diff --git a/src/backend/access/heap/heapam_xlog.c b/src/backend/access/heap/heapam_xlog.c
index b0ca1acf2b8..a50463cbaf8 100644
--- a/src/backend/access/heap/heapam_xlog.c
+++ b/src/backend/access/heap/heapam_xlog.c
@@ -63,7 +63,8 @@ heap_xlog_vm_clear(XLogReaderState *record,
 		if (PageIsNew(vmpage))
 			PageInit(vmpage, BLCKSZ, 0);
 
-		if (visibilitymap_clear(target_locator, heap_blkno, vmbuffer, flags))
+		if (visibilitymap_clear(target_locator, heap_blkno, vmbuffer,
+								flags) & flags)
 			PageSetLSN(vmpage, lsn);
 	}
 	if (BufferIsValid(vmbuffer))
diff --git a/src/backend/access/heap/visibilitymap.c b/src/backend/access/heap/visibilitymap.c
index 73ca76462a9..39b356512be 100644
--- a/src/backend/access/heap/visibilitymap.c
+++ b/src/backend/access/heap/visibilitymap.c
@@ -145,10 +145,11 @@ static Buffer vm_extend(Relation rel, BlockNumber vm_nblocks);
  * You must pass a buffer containing the correct map page to this function,
  * which already needs to be pinned and locked exclusively.
  *
- * This function doesn't do any I/O. Returns true if any bits have been
- * cleared and false otherwise.
+ * This function doesn't do any I/O. Returns the visibility map bits that were
+ * set for the page before this call; the bits requested in 'flags' are now
+ * cleared.
  */
-bool
+uint8
 visibilitymap_clear(RelFileLocator rlocator, BlockNumber heapBlk,
 					Buffer vmbuf, uint8 flags)
 {
@@ -158,7 +159,7 @@ visibilitymap_clear(RelFileLocator rlocator, BlockNumber heapBlk,
 	uint8		mask = flags << mapOffset;
 	Page		page;
 	char	   *map;
-	bool		cleared = false;
+	uint8		status;
 
 	/* Must never clear all_visible bit while leaving all_frozen bit set */
 	Assert(flags & VISIBILITYMAP_VALID_BITS);
@@ -178,15 +179,15 @@ visibilitymap_clear(RelFileLocator rlocator, BlockNumber heapBlk,
 	page = BufferGetPage(vmbuf);
 	map = PageGetContents(page);
 
-	if (map[mapByte] & mask)
+	status = (map[mapByte] >> mapOffset) & VISIBILITYMAP_VALID_BITS;
+	if (status & flags)
 	{
 		map[mapByte] &= ~mask;
 
 		MarkBufferDirty(vmbuf);
-		cleared = true;
 	}
 
-	return cleared;
+	return status;
 }
 
 /*
diff --git a/src/include/access/visibilitymap.h b/src/include/access/visibilitymap.h
index 165efd1c00e..f7e5b174525 100644
--- a/src/include/access/visibilitymap.h
+++ b/src/include/access/visibilitymap.h
@@ -26,8 +26,8 @@
 #define VM_ALL_FROZEN(r, b, v) \
 	((visibilitymap_get_status((r), (b), (v)) & VISIBILITYMAP_ALL_FROZEN) != 0)
 
-extern bool visibilitymap_clear(RelFileLocator rlocator, BlockNumber heapBlk,
-								Buffer vmbuf, uint8 flags);
+extern uint8 visibilitymap_clear(RelFileLocator rlocator, BlockNumber heapBlk,
+								 Buffer vmbuf, uint8 flags);
 extern void visibilitymap_pin(Relation rel, BlockNumber heapBlk,
 							  Buffer *vmbuf);
 extern bool visibilitymap_pin_ok(BlockNumber heapBlk, Buffer vmbuf);
-- 
2.43.0

