From dd5f2dae5f10e0c709db86db77aad41fff5532e2 Mon Sep 17 00:00:00 2001 From: Peter Geoghegan Date: Tue, 10 Mar 2026 14:22:25 -0400 Subject: [PATCH v13 04/19] Make IndexScanInstrumentation a pointer in executor scan nodes. Change the IndexScanInstrumentation fields in IndexScanState, IndexOnlyScanState, and BitmapIndexScanState from inline structs to pointers. This avoids adding additional overhead as new fields are added to IndexScanInstrumentation, at least in the common case where the instrumentation isn't used (i.e. when the executor node isn't being run through an EXPLAIN ANALYZE). --- src/include/nodes/execnodes.h | 6 +++--- src/backend/commands/explain.c | 6 +++--- src/backend/executor/nodeBitmapIndexscan.c | 8 ++++++-- src/backend/executor/nodeIndexonlyscan.c | 12 ++++++++---- src/backend/executor/nodeIndexscan.c | 14 +++++++++----- 5 files changed, 29 insertions(+), 17 deletions(-) diff --git a/src/include/nodes/execnodes.h b/src/include/nodes/execnodes.h index 63c067d5a..51782d1fc 100644 --- a/src/include/nodes/execnodes.h +++ b/src/include/nodes/execnodes.h @@ -1723,7 +1723,7 @@ typedef struct IndexScanState ExprContext *iss_RuntimeContext; Relation iss_RelationDesc; struct IndexScanDescData *iss_ScanDesc; - IndexScanInstrumentation iss_Instrument; + IndexScanInstrumentation *iss_Instrument; SharedIndexScanInstrumentation *iss_SharedInfo; /* These are needed for re-checking ORDER BY expr ordering */ @@ -1774,7 +1774,7 @@ typedef struct IndexOnlyScanState ExprContext *ioss_RuntimeContext; Relation ioss_RelationDesc; struct IndexScanDescData *ioss_ScanDesc; - IndexScanInstrumentation ioss_Instrument; + IndexScanInstrumentation *ioss_Instrument; SharedIndexScanInstrumentation *ioss_SharedInfo; TupleTableSlot *ioss_TableSlot; Buffer ioss_VMBuffer; @@ -1815,7 +1815,7 @@ typedef struct BitmapIndexScanState ExprContext *biss_RuntimeContext; Relation biss_RelationDesc; struct IndexScanDescData *biss_ScanDesc; - IndexScanInstrumentation biss_Instrument; + IndexScanInstrumentation *biss_Instrument; SharedIndexScanInstrumentation *biss_SharedInfo; } BitmapIndexScanState; diff --git a/src/backend/commands/explain.c b/src/backend/commands/explain.c index 93918a223..bed6587c8 100644 --- a/src/backend/commands/explain.c +++ b/src/backend/commands/explain.c @@ -3878,7 +3878,7 @@ show_indexsearches_info(PlanState *planstate, ExplainState *es) { IndexScanState *indexstate = ((IndexScanState *) planstate); - nsearches = indexstate->iss_Instrument.nsearches; + nsearches = indexstate->iss_Instrument->nsearches; SharedInfo = indexstate->iss_SharedInfo; break; } @@ -3886,7 +3886,7 @@ show_indexsearches_info(PlanState *planstate, ExplainState *es) { IndexOnlyScanState *indexstate = ((IndexOnlyScanState *) planstate); - nsearches = indexstate->ioss_Instrument.nsearches; + nsearches = indexstate->ioss_Instrument->nsearches; SharedInfo = indexstate->ioss_SharedInfo; break; } @@ -3894,7 +3894,7 @@ show_indexsearches_info(PlanState *planstate, ExplainState *es) { BitmapIndexScanState *indexstate = ((BitmapIndexScanState *) planstate); - nsearches = indexstate->biss_Instrument.nsearches; + nsearches = indexstate->biss_Instrument->nsearches; SharedInfo = indexstate->biss_SharedInfo; break; } diff --git a/src/backend/executor/nodeBitmapIndexscan.c b/src/backend/executor/nodeBitmapIndexscan.c index 058a59ef5..2ca822cf8 100644 --- a/src/backend/executor/nodeBitmapIndexscan.c +++ b/src/backend/executor/nodeBitmapIndexscan.c @@ -201,7 +201,7 @@ ExecEndBitmapIndexScan(BitmapIndexScanState *node) * shutdown on the workers. On rescan it will spin up new workers * which will have a new BitmapIndexScanState and zeroed stats. */ - winstrument->nsearches += node->biss_Instrument.nsearches; + winstrument->nsearches += node->biss_Instrument->nsearches; } /* @@ -272,6 +272,10 @@ ExecInitBitmapIndexScan(BitmapIndexScan *node, EState *estate, int eflags) if (eflags & EXEC_FLAG_EXPLAIN_ONLY) return indexstate; + /* Set up instrumentation of bitmap index scans if requested */ + if (estate->es_instrument) + indexstate->biss_Instrument = palloc0_object(IndexScanInstrumentation); + /* Open the index relation. */ lockmode = exec_rt_fetch(node->scan.scanrelid, estate)->rellockmode; indexstate->biss_RelationDesc = index_open(node->indexid, lockmode); @@ -323,7 +327,7 @@ ExecInitBitmapIndexScan(BitmapIndexScan *node, EState *estate, int eflags) indexstate->biss_ScanDesc = index_beginscan_bitmap(indexstate->biss_RelationDesc, estate->es_snapshot, - &indexstate->biss_Instrument, + indexstate->biss_Instrument, indexstate->biss_NumScanKeys); /* diff --git a/src/backend/executor/nodeIndexonlyscan.c b/src/backend/executor/nodeIndexonlyscan.c index c2d093745..f84db0476 100644 --- a/src/backend/executor/nodeIndexonlyscan.c +++ b/src/backend/executor/nodeIndexonlyscan.c @@ -92,7 +92,7 @@ IndexOnlyNext(IndexOnlyScanState *node) scandesc = index_beginscan(node->ss.ss_currentRelation, node->ioss_RelationDesc, estate->es_snapshot, - &node->ioss_Instrument, + node->ioss_Instrument, node->ioss_NumScanKeys, node->ioss_NumOrderByKeys); @@ -432,7 +432,7 @@ ExecEndIndexOnlyScan(IndexOnlyScanState *node) * shutdown on the workers. On rescan it will spin up new workers * which will have a new IndexOnlyScanState and zeroed stats. */ - winstrument->nsearches += node->ioss_Instrument.nsearches; + winstrument->nsearches += node->ioss_Instrument->nsearches; } /* @@ -604,6 +604,10 @@ ExecInitIndexOnlyScan(IndexOnlyScan *node, EState *estate, int eflags) if (eflags & EXEC_FLAG_EXPLAIN_ONLY) return indexstate; + /* Set up instrumentation of index-only scans if requested */ + if (estate->es_instrument) + indexstate->ioss_Instrument = palloc0_object(IndexScanInstrumentation); + /* Open the index relation. */ lockmode = exec_rt_fetch(node->scan.scanrelid, estate)->rellockmode; indexRelation = index_open(node->indexid, lockmode); @@ -785,7 +789,7 @@ ExecIndexOnlyScanInitializeDSM(IndexOnlyScanState *node, node->ioss_ScanDesc = index_beginscan_parallel(node->ss.ss_currentRelation, node->ioss_RelationDesc, - &node->ioss_Instrument, + node->ioss_Instrument, node->ioss_NumScanKeys, node->ioss_NumOrderByKeys, piscan); @@ -851,7 +855,7 @@ ExecIndexOnlyScanInitializeWorker(IndexOnlyScanState *node, node->ioss_ScanDesc = index_beginscan_parallel(node->ss.ss_currentRelation, node->ioss_RelationDesc, - &node->ioss_Instrument, + node->ioss_Instrument, node->ioss_NumScanKeys, node->ioss_NumOrderByKeys, piscan); diff --git a/src/backend/executor/nodeIndexscan.c b/src/backend/executor/nodeIndexscan.c index a616abff0..36320d7d2 100644 --- a/src/backend/executor/nodeIndexscan.c +++ b/src/backend/executor/nodeIndexscan.c @@ -109,7 +109,7 @@ IndexNext(IndexScanState *node) scandesc = index_beginscan(node->ss.ss_currentRelation, node->iss_RelationDesc, estate->es_snapshot, - &node->iss_Instrument, + node->iss_Instrument, node->iss_NumScanKeys, node->iss_NumOrderByKeys); @@ -205,7 +205,7 @@ IndexNextWithReorder(IndexScanState *node) scandesc = index_beginscan(node->ss.ss_currentRelation, node->iss_RelationDesc, estate->es_snapshot, - &node->iss_Instrument, + node->iss_Instrument, node->iss_NumScanKeys, node->iss_NumOrderByKeys); @@ -811,7 +811,7 @@ ExecEndIndexScan(IndexScanState *node) * shutdown on the workers. On rescan it will spin up new workers * which will have a new IndexOnlyScanState and zeroed stats. */ - winstrument->nsearches += node->iss_Instrument.nsearches; + winstrument->nsearches += node->iss_Instrument->nsearches; } /* @@ -971,6 +971,10 @@ ExecInitIndexScan(IndexScan *node, EState *estate, int eflags) if (eflags & EXEC_FLAG_EXPLAIN_ONLY) return indexstate; + /* Set up instrumentation of index scans if requested */ + if (estate->es_instrument) + indexstate->iss_Instrument = palloc0_object(IndexScanInstrumentation); + /* Open the index relation. */ lockmode = exec_rt_fetch(node->scan.scanrelid, estate)->rellockmode; indexstate->iss_RelationDesc = index_open(node->indexid, lockmode); @@ -1720,7 +1724,7 @@ ExecIndexScanInitializeDSM(IndexScanState *node, node->iss_ScanDesc = index_beginscan_parallel(node->ss.ss_currentRelation, node->iss_RelationDesc, - &node->iss_Instrument, + node->iss_Instrument, node->iss_NumScanKeys, node->iss_NumOrderByKeys, piscan); @@ -1784,7 +1788,7 @@ ExecIndexScanInitializeWorker(IndexScanState *node, node->iss_ScanDesc = index_beginscan_parallel(node->ss.ss_currentRelation, node->iss_RelationDesc, - &node->iss_Instrument, + node->iss_Instrument, node->iss_NumScanKeys, node->iss_NumOrderByKeys, piscan); -- 2.53.0