>From de650c53515ca822abb78ff0e7720638a55564ee Mon Sep 17 00:00:00 2001
From: Cary Huang <cary.huang@highgo.ca>
Date: Wed, 13 Aug 2025 14:26:56 -0700
Subject: [PATCH v9 3/3] fix the incorrect call to scan_set_tidrange()

---
 src/backend/access/heap/heapam.c        |  5 ----
 src/backend/access/table/tableam.c      |  7 ++++-
 src/backend/executor/nodeTidrangescan.c | 37 +++++++++++++++++++++----
 src/include/access/tableam.h            |  4 ++-
 4 files changed, 40 insertions(+), 13 deletions(-)

diff --git a/src/backend/access/heap/heapam.c b/src/backend/access/heap/heapam.c
index d0e650de57..46f5df2ec4 100644
--- a/src/backend/access/heap/heapam.c
+++ b/src/backend/access/heap/heapam.c
@@ -492,11 +492,6 @@ heap_setscanlimits(TableScanDesc sscan, BlockNumber startBlk, BlockNumber numBlk
 	scan->rs_numblocks = numBlks;
 
 	/* set the limits in the ParallelBlockTableScanDesc, when present */
-
-	/*
-	 * XXX no lock is being taken here.  What guarantees are there that there
-	 * isn't some worker using the old limits when the new limits are imposed?
-	 */
 	if (scan->rs_base.rs_parallel != NULL)
 	{
 		ParallelBlockTableScanDesc bpscan;
diff --git a/src/backend/access/table/tableam.c b/src/backend/access/table/tableam.c
index 8036654c77..01ca264ba4 100644
--- a/src/backend/access/table/tableam.c
+++ b/src/backend/access/table/tableam.c
@@ -189,7 +189,8 @@ table_beginscan_parallel(Relation relation, ParallelTableScanDesc pscan)
 }
 
 TableScanDesc
-table_beginscan_parallel_tidrange(Relation relation, ParallelTableScanDesc pscan)
+table_beginscan_parallel_tidrange(Relation relation, ParallelTableScanDesc pscan,
+		ItemPointerData * mintid, ItemPointerData * maxtid)
 {
 	Snapshot	snapshot;
 	uint32		flags = SO_TYPE_TIDRANGESCAN | SO_ALLOW_PAGEMODE;
@@ -216,6 +217,10 @@ table_beginscan_parallel_tidrange(Relation relation, ParallelTableScanDesc pscan
 	sscan = relation->rd_tableam->scan_begin(relation, snapshot, 0, NULL,
 											 pscan, flags);
 
+	/* Set the TID range if needed */
+	if (mintid && maxtid)
+		relation->rd_tableam->scan_set_tidrange(sscan, mintid, maxtid);
+
 	return sscan;
 }
 
diff --git a/src/backend/executor/nodeTidrangescan.c b/src/backend/executor/nodeTidrangescan.c
index afa47b01de..eef44e9d78 100644
--- a/src/backend/executor/nodeTidrangescan.c
+++ b/src/backend/executor/nodeTidrangescan.c
@@ -250,9 +250,13 @@ TidRangeNext(TidRangeScanState *node)
 		}
 		else
 		{
-			/* rescan with the updated TID range */
-			table_rescan_tidrange(scandesc, &node->trss_mintid,
-								  &node->trss_maxtid);
+			/* rescan with the updated TID range only in non-parallel mode */
+			if (scandesc->rs_parallel == NULL)
+			{
+				/* rescan with the updated TID range */
+				table_rescan_tidrange(scandesc, &node->trss_mintid,
+									  &node->trss_maxtid);
+			}
 		}
 
 		node->trss_inScan = true;
@@ -446,8 +450,19 @@ ExecTidRangeScanInitializeDSM(TidRangeScanState *node, ParallelContext *pcxt)
 								  pscan,
 								  estate->es_snapshot);
 	shm_toc_insert(pcxt->toc, node->ss.ps.plan->plan_node_id, pscan);
-	node->ss.ss_currentScanDesc =
-		table_beginscan_parallel_tidrange(node->ss.ss_currentRelation, pscan);
+
+	/*
+	 * Initialize parallel scan descriptor with given TID range if it can be
+	 * evaluated successfully.
+	 */
+	if (TidRangeEval(node))
+		node->ss.ss_currentScanDesc =
+			table_beginscan_parallel_tidrange(node->ss.ss_currentRelation, pscan,
+					&node->trss_mintid, &node->trss_maxtid);
+	else
+		node->ss.ss_currentScanDesc =
+			table_beginscan_parallel_tidrange(node->ss.ss_currentRelation, pscan,
+					NULL, NULL);
 }
 
 /* ----------------------------------------------------------------
@@ -465,6 +480,11 @@ ExecTidRangeScanReInitializeDSM(TidRangeScanState *node,
 	pscan = node->ss.ss_currentScanDesc->rs_parallel;
 	table_parallelscan_reinitialize(node->ss.ss_currentRelation, pscan);
 
+	/* Set the new TID range if it can be evaluated successfully */
+	if (TidRangeEval(node))
+		node->ss.ss_currentRelation->rd_tableam->scan_set_tidrange(
+				node->ss.ss_currentScanDesc, &node->trss_mintid,
+				&node->trss_maxtid);
 }
 
 /* ----------------------------------------------------------------
@@ -480,6 +500,11 @@ ExecTidRangeScanInitializeWorker(TidRangeScanState *node,
 	ParallelTableScanDesc pscan;
 
 	pscan = shm_toc_lookup(pwcxt->toc, node->ss.ps.plan->plan_node_id, false);
+
+	/*
+	 * As a worker, there is no need to set TID range as it has already been set
+	 * by the leader and available in shared memory.
+	 */
 	node->ss.ss_currentScanDesc =
-		table_beginscan_parallel_tidrange(node->ss.ss_currentRelation, pscan);
+		table_beginscan_parallel_tidrange(node->ss.ss_currentRelation, pscan, NULL, NULL);
 }
diff --git a/src/include/access/tableam.h b/src/include/access/tableam.h
index 0f46a47c2e..99596d6258 100644
--- a/src/include/access/tableam.h
+++ b/src/include/access/tableam.h
@@ -1133,7 +1133,9 @@ extern TableScanDesc table_beginscan_parallel(Relation relation,
  * Caller must hold a suitable lock on the relation.
  */
 extern TableScanDesc table_beginscan_parallel_tidrange(Relation relation,
-													   ParallelTableScanDesc pscan);
+													   ParallelTableScanDesc pscan,
+													   ItemPointerData * mintid,
+													   ItemPointerData * maxtid);
 
 /*
  * Restart a parallel scan.  Call this in the leader process.  Caller is
-- 
2.17.1

