From 897789c88a963deef0181dfe32916ff777744814 Mon Sep 17 00:00:00 2001 From: Peter Geoghegan Date: Tue, 10 Mar 2026 14:22:25 -0400 Subject: [PATCH v15 01/17] 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 0716c5a9a..586bdc219 100644 --- a/src/include/nodes/execnodes.h +++ b/src/include/nodes/execnodes.h @@ -1732,7 +1732,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 */ @@ -1783,7 +1783,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; @@ -1824,7 +1824,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 296ea8a1e..e4b70166b 100644 --- a/src/backend/commands/explain.c +++ b/src/backend/commands/explain.c @@ -3880,7 +3880,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; } @@ -3888,7 +3888,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; } @@ -3896,7 +3896,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 e6f378c05..70c55ee6d 100644 --- a/src/backend/executor/nodeBitmapIndexscan.c +++ b/src/backend/executor/nodeBitmapIndexscan.c @@ -203,7 +203,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; } /* @@ -274,6 +274,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); @@ -325,7 +329,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 c8db357e6..9eab81fd1 100644 --- a/src/backend/executor/nodeIndexonlyscan.c +++ b/src/backend/executor/nodeIndexonlyscan.c @@ -93,7 +93,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); @@ -433,7 +433,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; } /* @@ -606,6 +606,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); @@ -787,7 +791,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); @@ -853,7 +857,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 bd83e4712..06143e94c 100644 --- a/src/backend/executor/nodeIndexscan.c +++ b/src/backend/executor/nodeIndexscan.c @@ -111,7 +111,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); @@ -207,7 +207,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); @@ -813,7 +813,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; } /* @@ -974,6 +974,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); @@ -1723,7 +1727,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); @@ -1787,7 +1791,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