From c3ae01de0ded48590995115065889f1613bf458f Mon Sep 17 00:00:00 2001
From: Melanie Plageman <melanieplageman@gmail.com>
Date: Fri, 21 Feb 2025 10:58:59 -0500
Subject: [PATCH v33 1/5] Add lossy indicator to TBMIterateResult

TBMIterateResult->ntuples is -1 when the page in the bitmap is lossy.
Add an explicit lossy indicator so that we can move ntuples out of the
TBMIterateResult in a future commit.
---
 src/backend/access/gin/ginget.c          |  6 ++++--
 src/backend/access/heap/heapam_handler.c | 10 +++++-----
 src/backend/nodes/tidbitmap.c            | 11 ++++++++---
 src/include/nodes/tidbitmap.h            |  5 +++--
 4 files changed, 20 insertions(+), 12 deletions(-)

diff --git a/src/backend/access/gin/ginget.c b/src/backend/access/gin/ginget.c
index 63dd1f3679f..54aecc1d1f1 100644
--- a/src/backend/access/gin/ginget.c
+++ b/src/backend/access/gin/ginget.c
@@ -827,7 +827,7 @@ entryGetItem(GinState *ginstate, GinScanEntry entry,
 			 * in the bitmap.
 			 */
 			while (entry->matchResult == NULL ||
-				   (entry->matchResult->ntuples >= 0 &&
+				   (!entry->matchResult->lossy &&
 					entry->offset >= entry->matchResult->ntuples) ||
 				   entry->matchResult->blockno < advancePastBlk ||
 				   (ItemPointerIsLossyPage(&advancePast) &&
@@ -860,7 +860,7 @@ entryGetItem(GinState *ginstate, GinScanEntry entry,
 			 * We're now on the first page after advancePast which has any
 			 * items on it. If it's a lossy result, return that.
 			 */
-			if (entry->matchResult->ntuples < 0)
+			if (entry->matchResult->lossy)
 			{
 				ItemPointerSetLossyPage(&entry->curItem,
 										entry->matchResult->blockno);
@@ -879,6 +879,8 @@ entryGetItem(GinState *ginstate, GinScanEntry entry,
 			 */
 			if (entry->matchResult->blockno == advancePastBlk)
 			{
+				Assert(entry->matchResult->ntuples > 0);
+
 				/*
 				 * First, do a quick check against the last offset on the
 				 * page. If that's > advancePast, so are all the other
diff --git a/src/backend/access/heap/heapam_handler.c b/src/backend/access/heap/heapam_handler.c
index c0bec014154..269d581c2ec 100644
--- a/src/backend/access/heap/heapam_handler.c
+++ b/src/backend/access/heap/heapam_handler.c
@@ -2170,7 +2170,7 @@ heapam_scan_bitmap_next_block(TableScanDesc scan,
 		VM_ALL_VISIBLE(scan->rs_rd, tbmres->blockno, &bscan->rs_vmbuffer))
 	{
 		/* can't be lossy in the skip_fetch case */
-		Assert(tbmres->ntuples >= 0);
+		Assert(!tbmres->lossy);
 		Assert(bscan->rs_empty_tuples_pending >= 0);
 
 		bscan->rs_empty_tuples_pending += tbmres->ntuples;
@@ -2207,7 +2207,7 @@ heapam_scan_bitmap_next_block(TableScanDesc scan,
 	/*
 	 * We need two separate strategies for lossy and non-lossy cases.
 	 */
-	if (tbmres->ntuples >= 0)
+	if (!tbmres->lossy)
 	{
 		/*
 		 * Bitmap is non-lossy, so we just look through the offsets listed in
@@ -2268,10 +2268,10 @@ heapam_scan_bitmap_next_block(TableScanDesc scan,
 	Assert(ntup <= MaxHeapTuplesPerPage);
 	hscan->rs_ntuples = ntup;
 
-	if (tbmres->ntuples >= 0)
-		(*exact_pages)++;
-	else
+	if (tbmres->lossy)
 		(*lossy_pages)++;
+	else
+		(*exact_pages)++;
 
 	/*
 	 * Return true to indicate that a valid block was found and the bitmap is
diff --git a/src/backend/nodes/tidbitmap.c b/src/backend/nodes/tidbitmap.c
index 66b3c387d53..3e0bca651f5 100644
--- a/src/backend/nodes/tidbitmap.c
+++ b/src/backend/nodes/tidbitmap.c
@@ -961,12 +961,13 @@ tbm_advance_schunkbit(PagetableEntry *chunk, int *schunkbitp)
  *
  * Returns a TBMIterateResult representing one page, or NULL if there are
  * no more pages to scan.  Pages are guaranteed to be delivered in numerical
- * order.  If result->ntuples < 0, then the bitmap is "lossy" and failed to
+ * order.  If lossy is true, then the bitmap is "lossy" and failed to
  * remember the exact tuples to look at on this page --- the caller must
  * examine all tuples on the page and check if they meet the intended
- * condition.  If result->recheck is true, only the indicated tuples need
+ * condition.  result->ntuples is set to -1 when the bitmap is lossy.
+ * If result->recheck is true, only the indicated tuples need
  * be examined, but the condition must be rechecked anyway.  (For ease of
- * testing, recheck is always set true when ntuples < 0.)
+ * testing, recheck is always set true when lossy is true.)
  */
 TBMIterateResult *
 tbm_private_iterate(TBMPrivateIterator *iterator)
@@ -1012,6 +1013,7 @@ tbm_private_iterate(TBMPrivateIterator *iterator)
 			/* Return a lossy page indicator from the chunk */
 			output->blockno = chunk_blockno;
 			output->ntuples = -1;
+			output->lossy = true;
 			output->recheck = true;
 			iterator->schunkbit++;
 			return output;
@@ -1033,6 +1035,7 @@ tbm_private_iterate(TBMPrivateIterator *iterator)
 		ntuples = tbm_extract_page_tuple(page, output);
 		output->blockno = page->blockno;
 		output->ntuples = ntuples;
+		output->lossy = false;
 		output->recheck = page->recheck;
 		iterator->spageptr++;
 		return output;
@@ -1105,6 +1108,7 @@ tbm_shared_iterate(TBMSharedIterator *iterator)
 			/* Return a lossy page indicator from the chunk */
 			output->blockno = chunk_blockno;
 			output->ntuples = -1;
+			output->lossy = true;
 			output->recheck = true;
 			istate->schunkbit++;
 
@@ -1122,6 +1126,7 @@ tbm_shared_iterate(TBMSharedIterator *iterator)
 		ntuples = tbm_extract_page_tuple(page, output);
 		output->blockno = page->blockno;
 		output->ntuples = ntuples;
+		output->lossy = false;
 		output->recheck = page->recheck;
 		istate->spageptr++;
 
diff --git a/src/include/nodes/tidbitmap.h b/src/include/nodes/tidbitmap.h
index a6ffeac90be..8cd93d90a86 100644
--- a/src/include/nodes/tidbitmap.h
+++ b/src/include/nodes/tidbitmap.h
@@ -54,9 +54,10 @@ typedef struct TBMIterator
 typedef struct TBMIterateResult
 {
 	BlockNumber blockno;		/* page number containing tuples */
-	int			ntuples;		/* -1 indicates lossy result */
+	int			ntuples;		/* -1 when lossy */
+	bool		lossy;
 	bool		recheck;		/* should the tuples be rechecked? */
-	/* Note: recheck is always true if ntuples < 0 */
+	/* Note: recheck is always true if lossy */
 	OffsetNumber offsets[FLEXIBLE_ARRAY_MEMBER];
 } TBMIterateResult;
 
-- 
2.34.1

