diff --git a/src/backend/commands/explain.c b/src/backend/commands/explain.c index 989b6aad67..fe0419311b 100644 *** a/src/backend/commands/explain.c --- b/src/backend/commands/explain.c *************** *** 1459,1470 **** ExplainNode(PlanState *planstate, List *ancestors, show_instrumentation_count("Rows Removed by Filter", 1, planstate, es); if (es->analyze) ! { ! long heapFetches = ! ((IndexOnlyScanState *) planstate)->ioss_HeapFetches; ! ! ExplainPropertyInteger("Heap Fetches", NULL, heapFetches, es); ! } break; case T_BitmapIndexScan: show_scan_qual(((BitmapIndexScan *) plan)->indexqualorig, --- 1459,1466 ---- show_instrumentation_count("Rows Removed by Filter", 1, planstate, es); if (es->analyze) ! ExplainPropertyInteger("Heap Fetches", NULL, ! planstate->instrument->ntuples2, es); break; case T_BitmapIndexScan: show_scan_qual(((BitmapIndexScan *) plan)->indexqualorig, diff --git a/src/backend/executor/insindex 86252cee1f..fe5d55904d 100644 *** a/src/backend/executor/instrument.c --- b/src/backend/executor/instrument.c *************** *** 156,161 **** InstrAggNode(Instrumentation *dst, Instrumentation *add) --- 156,162 ---- dst->startup += add->startup; dst->total += add->total; dst->ntuples += add->ntuples; + dst->ntuples2 += add->ntuples2; dst->nloops += add->nloops; dst->nfiltered1 += add->nfiltered1; dst->nfiltered2 += add->nfiltered2; diff --git a/src/backend/executor/nodeInindex ddc0ae9061..3a02a99621 100644 *** a/src/backend/executor/nodeIndexonlyscan.c --- b/src/backend/executor/nodeIndexonlyscan.c *************** *** 162,168 **** IndexOnlyNext(IndexOnlyScanState *node) /* * Rats, we have to visit the heap to check visibility. */ ! node->ioss_HeapFetches++; tuple = index_fetch_heap(scandesc); if (tuple == NULL) continue; /* no visible tuple, try next index entry */ --- 162,168 ---- /* * Rats, we have to visit the heap to check visibility. */ ! InstrCountTuples2(node, 1); tuple = index_fetch_heap(scandesc); if (tuple == NULL) continue; /* no visible tuple, try next index entry */ *************** *** 509,515 **** ExecInitIndexOnlyScan(IndexOnlyScan *node, EState *estate, int eflags) indexstate->ss.ps.plan = (Plan *) node; indexstate->ss.ps.state = estate; indexstate->ss.ps.ExecProcNode = ExecIndexOnlyScan; - indexstate->ioss_HeapFetches = 0; /* * Miscellaneous initialization --- 509,514 ---- diff --git a/src/include/executor/instrument.h index 28eb0093d4..0ba407f83a 100644 *** a/src/include/executor/instrument.h --- b/src/include/executor/instrument.h *************** *** 57,62 **** typedef struct Instrumentation --- 57,63 ---- double startup; /* Total startup time (in seconds) */ double total; /* Total total time (in seconds) */ double ntuples; /* Total tuples produced */ + double ntuples2; /* Secondary generic tuple counter */ double nloops; /* # of run cycles for this node */ double nfiltered1; /* # tuples removed by scanqual or joinqual OR * # tuples inserted by MERGE */ diff --git a/src/include/nodes/execnodesindex 06456f07cc..deab875466 100644 *** a/src/include/nodes/execnodes.h --- b/src/include/nodes/execnodes.h *************** *** 1004,1009 **** typedef struct PlanState --- 1004,1014 ---- #define outerPlanState(node) (((PlanState *)(node))->lefttree) /* Macros for inline access to certain instrumentation counters */ + #define InstrCountTuples2(node, delta) \ + do { \ + if (((PlanState *)(node))->instrument) \ + ((PlanState *)(node))->instrument->ntuples2 += (delta); \ + } while (0) #define InstrCountFiltered1(node, delta) \ do { \ if (((PlanState *)(node))->instrument) \ *************** *** 1368,1374 **** typedef struct IndexScanState * RelationDesc index relation descriptor * ScanDesc index scan descriptor * VMBuffer buffer in use for visibility map testing, if any - * HeapFetches number of tuples we were forced to fetch from heap * ioss_PscanLen Size of parallel index-only scan descriptor * ---------------- */ --- 1373,1378 ----