v22-0008-Push-current-scan-descriptor-into-specialized-sc.patch

text/x-patch

Filename: v22-0008-Push-current-scan-descriptor-into-specialized-sc.patch
Type: text/x-patch
Part: 7
Message: Re: BitmapHeapScan streaming read user and prelim refactoring

Patch

Format: format-patch
Series: patch v22-0008
Subject: Push current scan descriptor into specialized scan states
File+
src/backend/executor/nodeBitmapHeapscan.c 5 5
src/backend/executor/nodeBitmapIndexscan.c 0 1
src/backend/executor/nodeIndexonlyscan.c 0 1
src/backend/executor/nodeIndexscan.c 0 1
src/backend/executor/nodeSamplescan.c 7 7
src/backend/executor/nodeSeqscan.c 7 7
src/backend/executor/nodeTidrangescan.c 4 4
src/backend/executor/nodeTidscan.c 9 9
src/include/nodes/execnodes.h 8 2
From 6c6703e9a1fda3d57f813918b63bd992caa34f21 Mon Sep 17 00:00:00 2001
From: Melanie Plageman <melanieplageman@gmail.com>
Date: Tue, 11 Jun 2024 08:41:49 -0400
Subject: [PATCH v22 08/19] Push current scan descriptor into specialized scan
 states

To allow Bitmap Table Scans to use a forthcoming bitmap table-specific
scan descriptor in table AM-agnostic code, move the current scan
descriptor out of the generic ScanState node.

This adds a bit of duplication, but a few of the scan types don't use
the current scan descriptor anyway. Additionally, for many scan types,
the scan descriptor is initialized later in execution than the other
members of the generic ScanState.
---
 src/backend/executor/nodeBitmapHeapscan.c  | 10 +++++-----
 src/backend/executor/nodeBitmapIndexscan.c |  1 -
 src/backend/executor/nodeIndexonlyscan.c   |  1 -
 src/backend/executor/nodeIndexscan.c       |  1 -
 src/backend/executor/nodeSamplescan.c      | 14 +++++++-------
 src/backend/executor/nodeSeqscan.c         | 14 +++++++-------
 src/backend/executor/nodeTidrangescan.c    |  8 ++++----
 src/backend/executor/nodeTidscan.c         | 18 +++++++++---------
 src/include/nodes/execnodes.h              | 10 ++++++++--
 9 files changed, 40 insertions(+), 37 deletions(-)

diff --git a/src/backend/executor/nodeBitmapHeapscan.c b/src/backend/executor/nodeBitmapHeapscan.c
index 33e4ef13bd6..b841eee58b4 100644
--- a/src/backend/executor/nodeBitmapHeapscan.c
+++ b/src/backend/executor/nodeBitmapHeapscan.c
@@ -78,7 +78,7 @@ BitmapHeapNext(BitmapHeapScanState *node)
 	 */
 	econtext = node->ss.ps.ps_ExprContext;
 	slot = node->ss.ss_ScanTupleSlot;
-	scan = node->ss.ss_currentScanDesc;
+	scan = node->ss_currentScanDesc;
 
 	/*
 	 * If we haven't yet performed the underlying index scan, do it, and begin
@@ -162,7 +162,7 @@ BitmapHeapNext(BitmapHeapScanState *node)
 									  NULL,
 									  need_tuples);
 
-			node->ss.ss_currentScanDesc = scan;
+			node->ss_currentScanDesc = scan;
 		}
 
 		tbm_begin_iterate(&scan->tbmiterator, node->tbm, dsa,
@@ -539,8 +539,8 @@ ExecReScanBitmapHeapScan(BitmapHeapScanState *node)
 	PlanState  *outerPlan = outerPlanState(node);
 
 	/* rescan to release any page pin */
-	if (node->ss.ss_currentScanDesc)
-		table_rescan(node->ss.ss_currentScanDesc, NULL);
+	if (node->ss_currentScanDesc)
+		table_rescan(node->ss_currentScanDesc, NULL);
 
 	/* release bitmaps and buffers if any */
 	tbm_end_iterate(&node->prefetch_iterator);
@@ -580,7 +580,7 @@ ExecEndBitmapHeapScan(BitmapHeapScanState *node)
 	/*
 	 * extract information from the node
 	 */
-	scanDesc = node->ss.ss_currentScanDesc;
+	scanDesc = node->ss_currentScanDesc;
 
 	/*
 	 * close down subplans
diff --git a/src/backend/executor/nodeBitmapIndexscan.c b/src/backend/executor/nodeBitmapIndexscan.c
index 6df8e17ec84..b4af2f17ed4 100644
--- a/src/backend/executor/nodeBitmapIndexscan.c
+++ b/src/backend/executor/nodeBitmapIndexscan.c
@@ -225,7 +225,6 @@ ExecInitBitmapIndexScan(BitmapIndexScan *node, EState *estate, int eflags)
 	 */
 
 	indexstate->ss.ss_currentRelation = NULL;
-	indexstate->ss.ss_currentScanDesc = NULL;
 
 	/*
 	 * Miscellaneous initialization
diff --git a/src/backend/executor/nodeIndexonlyscan.c b/src/backend/executor/nodeIndexonlyscan.c
index b49194c0167..194c544c167 100644
--- a/src/backend/executor/nodeIndexonlyscan.c
+++ b/src/backend/executor/nodeIndexonlyscan.c
@@ -534,7 +534,6 @@ ExecInitIndexOnlyScan(IndexOnlyScan *node, EState *estate, int eflags)
 	currentRelation = ExecOpenScanRelation(estate, node->scan.scanrelid, eflags);
 
 	indexstate->ss.ss_currentRelation = currentRelation;
-	indexstate->ss.ss_currentScanDesc = NULL;	/* no heap scan here */
 
 	/*
 	 * Build the scan tuple type using the indextlist generated by the
diff --git a/src/backend/executor/nodeIndexscan.c b/src/backend/executor/nodeIndexscan.c
index 8000feff4c9..8260cb0954d 100644
--- a/src/backend/executor/nodeIndexscan.c
+++ b/src/backend/executor/nodeIndexscan.c
@@ -910,7 +910,6 @@ ExecInitIndexScan(IndexScan *node, EState *estate, int eflags)
 	currentRelation = ExecOpenScanRelation(estate, node->scan.scanrelid, eflags);
 
 	indexstate->ss.ss_currentRelation = currentRelation;
-	indexstate->ss.ss_currentScanDesc = NULL;	/* no heap scan here */
 
 	/*
 	 * get the scan type from the relation descriptor.
diff --git a/src/backend/executor/nodeSamplescan.c b/src/backend/executor/nodeSamplescan.c
index 714b076e646..d15bf249d31 100644
--- a/src/backend/executor/nodeSamplescan.c
+++ b/src/backend/executor/nodeSamplescan.c
@@ -123,7 +123,7 @@ ExecInitSampleScan(SampleScan *node, EState *estate, int eflags)
 							 eflags);
 
 	/* we won't set up the HeapScanDesc till later */
-	scanstate->ss.ss_currentScanDesc = NULL;
+	scanstate->ss_currentScanDesc = NULL;
 
 	/* and create slot with appropriate rowtype */
 	ExecInitScanTupleSlot(estate, &scanstate->ss,
@@ -187,8 +187,8 @@ ExecEndSampleScan(SampleScanState *node)
 	/*
 	 * close heap scan
 	 */
-	if (node->ss.ss_currentScanDesc)
-		table_endscan(node->ss.ss_currentScanDesc);
+	if (node->ss_currentScanDesc)
+		table_endscan(node->ss_currentScanDesc);
 }
 
 /* ----------------------------------------------------------------
@@ -289,9 +289,9 @@ tablesample_init(SampleScanState *scanstate)
 	allow_sync = (tsm->NextSampleBlock == NULL);
 
 	/* Now we can create or reset the HeapScanDesc */
-	if (scanstate->ss.ss_currentScanDesc == NULL)
+	if (scanstate->ss_currentScanDesc == NULL)
 	{
-		scanstate->ss.ss_currentScanDesc =
+		scanstate->ss_currentScanDesc =
 			table_beginscan_sampling(scanstate->ss.ss_currentRelation,
 									 scanstate->ss.ps.state->es_snapshot,
 									 0, NULL,
@@ -301,7 +301,7 @@ tablesample_init(SampleScanState *scanstate)
 	}
 	else
 	{
-		table_rescan_set_params(scanstate->ss.ss_currentScanDesc, NULL,
+		table_rescan_set_params(scanstate->ss_currentScanDesc, NULL,
 								scanstate->use_bulkread,
 								allow_sync,
 								scanstate->use_pagemode);
@@ -319,7 +319,7 @@ tablesample_init(SampleScanState *scanstate)
 static TupleTableSlot *
 tablesample_getnext(SampleScanState *scanstate)
 {
-	TableScanDesc scan = scanstate->ss.ss_currentScanDesc;
+	TableScanDesc scan = scanstate->ss_currentScanDesc;
 	TupleTableSlot *slot = scanstate->ss.ss_ScanTupleSlot;
 
 	ExecClearTuple(slot);
diff --git a/src/backend/executor/nodeSeqscan.c b/src/backend/executor/nodeSeqscan.c
index 7cb12a11c2d..89f5e8c80da 100644
--- a/src/backend/executor/nodeSeqscan.c
+++ b/src/backend/executor/nodeSeqscan.c
@@ -57,7 +57,7 @@ SeqNext(SeqScanState *node)
 	/*
 	 * get information from the estate and scan state
 	 */
-	scandesc = node->ss.ss_currentScanDesc;
+	scandesc = node->ss_currentScanDesc;
 	estate = node->ss.ps.state;
 	direction = estate->es_direction;
 	slot = node->ss.ss_ScanTupleSlot;
@@ -71,7 +71,7 @@ SeqNext(SeqScanState *node)
 		scandesc = table_beginscan(node->ss.ss_currentRelation,
 								   estate->es_snapshot,
 								   0, NULL);
-		node->ss.ss_currentScanDesc = scandesc;
+		node->ss_currentScanDesc = scandesc;
 	}
 
 	/*
@@ -188,7 +188,7 @@ ExecEndSeqScan(SeqScanState *node)
 	/*
 	 * get information from node
 	 */
-	scanDesc = node->ss.ss_currentScanDesc;
+	scanDesc = node->ss_currentScanDesc;
 
 	/*
 	 * close heap scan
@@ -213,7 +213,7 @@ ExecReScanSeqScan(SeqScanState *node)
 {
 	TableScanDesc scan;
 
-	scan = node->ss.ss_currentScanDesc;
+	scan = node->ss_currentScanDesc;
 
 	if (scan != NULL)
 		table_rescan(scan,		/* scan desc */
@@ -264,7 +264,7 @@ ExecSeqScanInitializeDSM(SeqScanState *node,
 								  pscan,
 								  estate->es_snapshot);
 	shm_toc_insert(pcxt->toc, node->ss.ps.plan->plan_node_id, pscan);
-	node->ss.ss_currentScanDesc =
+	node->ss_currentScanDesc =
 		table_beginscan_parallel(node->ss.ss_currentRelation, pscan);
 }
 
@@ -280,7 +280,7 @@ ExecSeqScanReInitializeDSM(SeqScanState *node,
 {
 	ParallelTableScanDesc pscan;
 
-	pscan = node->ss.ss_currentScanDesc->rs_parallel;
+	pscan = node->ss_currentScanDesc->rs_parallel;
 	table_parallelscan_reinitialize(node->ss.ss_currentRelation, pscan);
 }
 
@@ -297,6 +297,6 @@ ExecSeqScanInitializeWorker(SeqScanState *node,
 	ParallelTableScanDesc pscan;
 
 	pscan = shm_toc_lookup(pwcxt->toc, node->ss.ps.plan->plan_node_id, false);
-	node->ss.ss_currentScanDesc =
+	node->ss_currentScanDesc =
 		table_beginscan_parallel(node->ss.ss_currentRelation, pscan);
 }
diff --git a/src/backend/executor/nodeTidrangescan.c b/src/backend/executor/nodeTidrangescan.c
index 9aa7683d7e3..bc523a5d773 100644
--- a/src/backend/executor/nodeTidrangescan.c
+++ b/src/backend/executor/nodeTidrangescan.c
@@ -227,7 +227,7 @@ TidRangeNext(TidRangeScanState *node)
 	/*
 	 * extract necessary information from TID scan node
 	 */
-	scandesc = node->ss.ss_currentScanDesc;
+	scandesc = node->ss_currentScanDesc;
 	estate = node->ss.ps.state;
 	slot = node->ss.ss_ScanTupleSlot;
 	direction = estate->es_direction;
@@ -244,7 +244,7 @@ TidRangeNext(TidRangeScanState *node)
 												estate->es_snapshot,
 												&node->trss_mintid,
 												&node->trss_maxtid);
-			node->ss.ss_currentScanDesc = scandesc;
+			node->ss_currentScanDesc = scandesc;
 		}
 		else
 		{
@@ -326,7 +326,7 @@ ExecReScanTidRangeScan(TidRangeScanState *node)
 void
 ExecEndTidRangeScan(TidRangeScanState *node)
 {
-	TableScanDesc scan = node->ss.ss_currentScanDesc;
+	TableScanDesc scan = node->ss_currentScanDesc;
 
 	if (scan != NULL)
 		table_endscan(scan);
@@ -375,7 +375,7 @@ ExecInitTidRangeScan(TidRangeScan *node, EState *estate, int eflags)
 	currentRelation = ExecOpenScanRelation(estate, node->scan.scanrelid, eflags);
 
 	tidrangestate->ss.ss_currentRelation = currentRelation;
-	tidrangestate->ss.ss_currentScanDesc = NULL;	/* no table scan here */
+	tidrangestate->ss_currentScanDesc = NULL;	/* no table scan here */
 
 	/*
 	 * get the scan type from the relation descriptor.
diff --git a/src/backend/executor/nodeTidscan.c b/src/backend/executor/nodeTidscan.c
index 864a9013b62..f08bc7daa89 100644
--- a/src/backend/executor/nodeTidscan.c
+++ b/src/backend/executor/nodeTidscan.c
@@ -145,11 +145,11 @@ TidListEval(TidScanState *tidstate)
 	 * the size of the table), so it makes sense to delay that until needed -
 	 * the node might never get executed.
 	 */
-	if (tidstate->ss.ss_currentScanDesc == NULL)
-		tidstate->ss.ss_currentScanDesc =
+	if (tidstate->ss_currentScanDesc == NULL)
+		tidstate->ss_currentScanDesc =
 			table_beginscan_tid(tidstate->ss.ss_currentRelation,
 								tidstate->ss.ps.state->es_snapshot);
-	scan = tidstate->ss.ss_currentScanDesc;
+	scan = tidstate->ss_currentScanDesc;
 
 	/*
 	 * We initialize the array with enough slots for the case that all quals
@@ -336,7 +336,7 @@ TidNext(TidScanState *node)
 	if (node->tss_TidList == NULL)
 		TidListEval(node);
 
-	scan = node->ss.ss_currentScanDesc;
+	scan = node->ss_currentScanDesc;
 	tidList = node->tss_TidList;
 	numTids = node->tss_NumTids;
 
@@ -453,8 +453,8 @@ ExecReScanTidScan(TidScanState *node)
 	node->tss_TidPtr = -1;
 
 	/* not really necessary, but seems good form */
-	if (node->ss.ss_currentScanDesc)
-		table_rescan(node->ss.ss_currentScanDesc, NULL);
+	if (node->ss_currentScanDesc)
+		table_rescan(node->ss_currentScanDesc, NULL);
 
 	ExecScanReScan(&node->ss);
 }
@@ -469,8 +469,8 @@ ExecReScanTidScan(TidScanState *node)
 void
 ExecEndTidScan(TidScanState *node)
 {
-	if (node->ss.ss_currentScanDesc)
-		table_endscan(node->ss.ss_currentScanDesc);
+	if (node->ss_currentScanDesc)
+		table_endscan(node->ss_currentScanDesc);
 }
 
 /* ----------------------------------------------------------------
@@ -518,7 +518,7 @@ ExecInitTidScan(TidScan *node, EState *estate, int eflags)
 	currentRelation = ExecOpenScanRelation(estate, node->scan.scanrelid, eflags);
 
 	tidstate->ss.ss_currentRelation = currentRelation;
-	tidstate->ss.ss_currentScanDesc = NULL; /* no heap scan here */
+	tidstate->ss_currentScanDesc = NULL;	/* no heap scan here */
 
 	/*
 	 * get the scan type from the relation descriptor.
diff --git a/src/include/nodes/execnodes.h b/src/include/nodes/execnodes.h
index 1f262db776c..62bc883bc28 100644
--- a/src/include/nodes/execnodes.h
+++ b/src/include/nodes/execnodes.h
@@ -1555,7 +1555,6 @@ typedef struct BitmapOrState
  *		retrieved from the subplan.
  *
  *		currentRelation    relation being scanned (NULL if none)
- *		currentScanDesc    current scan descriptor for scan (NULL if none)
  *		ScanTupleSlot	   pointer to slot in tuple table holding scan tuple
  * ----------------
  */
@@ -1563,7 +1562,6 @@ typedef struct ScanState
 {
 	PlanState	ps;				/* its first field is NodeTag */
 	Relation	ss_currentRelation;
-	struct TableScanDescData *ss_currentScanDesc;
 	TupleTableSlot *ss_ScanTupleSlot;
 } ScanState;
 
@@ -1574,6 +1572,7 @@ typedef struct ScanState
 typedef struct SeqScanState
 {
 	ScanState	ss;				/* its first field is NodeTag */
+	struct TableScanDescData *ss_currentScanDesc;	/* current scan descriptor */
 	Size		pscan_len;		/* size of parallel heap scan descriptor */
 } SeqScanState;
 
@@ -1584,6 +1583,7 @@ typedef struct SeqScanState
 typedef struct SampleScanState
 {
 	ScanState	ss;
+	struct TableScanDescData *ss_currentScanDesc;	/* current scan descriptor */
 	List	   *args;			/* expr states for TABLESAMPLE params */
 	ExprState  *repeatable;		/* expr state for REPEATABLE expr */
 	/* use struct pointer to avoid including tsmapi.h here */
@@ -1793,6 +1793,7 @@ typedef struct ParallelBitmapHeapState
 /* ----------------
  *	 BitmapHeapScanState information
  *
+ *      currentScanDesc    current scan descriptor for scan (NULL if none)
  *		bitmapqualorig	   execution state for bitmapqualorig expressions
  *		tbm				   bitmap obtained from child index scan(s)
  *		pvmbuffer		   buffer for visibility-map lookups of prefetched pages
@@ -1812,6 +1813,7 @@ typedef struct ParallelBitmapHeapState
 typedef struct BitmapHeapScanState
 {
 	ScanState	ss;				/* its first field is NodeTag */
+	struct TableScanDescData *ss_currentScanDesc;
 	ExprState  *bitmapqualorig;
 	TIDBitmap  *tbm;
 	Buffer		pvmbuffer;
@@ -1831,6 +1833,7 @@ typedef struct BitmapHeapScanState
 /* ----------------
  *	 TidScanState information
  *
+ *      currentScanDesc    current scan descriptor for scan (NULL if none)
  *		tidexprs	   list of TidExpr structs (see nodeTidscan.c)
  *		isCurrentOf    scan has a CurrentOfExpr qual
  *		NumTids		   number of tids in this scan
@@ -1841,6 +1844,7 @@ typedef struct BitmapHeapScanState
 typedef struct TidScanState
 {
 	ScanState	ss;				/* its first field is NodeTag */
+	struct TableScanDescData *ss_currentScanDesc;
 	List	   *tss_tidexprs;
 	bool		tss_isCurrentOf;
 	int			tss_NumTids;
@@ -1851,6 +1855,7 @@ typedef struct TidScanState
 /* ----------------
  *	 TidRangeScanState information
  *
+ *      currentScanDesc    current scan descriptor for scan (NULL if none)
  *		trss_tidexprs		list of TidOpExpr structs (see nodeTidrangescan.c)
  *		trss_mintid			the lowest TID in the scan range
  *		trss_maxtid			the highest TID in the scan range
@@ -1860,6 +1865,7 @@ typedef struct TidScanState
 typedef struct TidRangeScanState
 {
 	ScanState	ss;				/* its first field is NodeTag */
+	struct TableScanDescData *ss_currentScanDesc;
 	List	   *trss_tidexprs;
 	ItemPointerData trss_mintid;
 	ItemPointerData trss_maxtid;
-- 
2.34.1