From c5ce0fa996cb268cfaac4dbc6a19425c510c790c Mon Sep 17 00:00:00 2001 From: Melanie Plageman Date: Tue, 11 Jun 2024 08:41:49 -0400 Subject: [PATCH v23 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 b7bf877594..9a4a050a7d 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, @@ -542,7 +542,7 @@ ExecReScanBitmapHeapScan(BitmapHeapScanState *node) { PlanState *outerPlan = outerPlanState(node); - TableScanDesc scan = node->ss.ss_currentScanDesc; + TableScanDesc scan = node->ss_currentScanDesc; if (scan) { @@ -552,7 +552,7 @@ ExecReScanBitmapHeapScan(BitmapHeapScanState *node) tbm_end_iterate(&scan->tbmiterator); /* rescan to release any page pin */ - table_rescan(node->ss.ss_currentScanDesc, NULL); + table_rescan(node->ss_currentScanDesc, NULL); } /* End iteration on iterators saved in the node . */ @@ -595,7 +595,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 6df8e17ec8..b4af2f17ed 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 b49194c016..194c544c16 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 8000feff4c..8260cb0954 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 714b076e64..d15bf249d3 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 7cb12a11c2..89f5e8c80d 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 9aa7683d7e..bc523a5d77 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 864a9013b6..f08bc7daa8 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 fd11f7db03..c4907d624d 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