From 707ccce1f082fad2c7313801c0fd01df4ba56dff Mon Sep 17 00:00:00 2001
From: Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
Date: Wed, 28 Oct 2026 06:49:21 +0000
Subject: [PATCH v2 6/8] Add table scan instrumentation for sample and TID
 scans

Sample and TID scans may run entirely in a worker, but they do not have
the per worker table scan instrumentation used by sequential, bitmap heap,
and TID range scans.

Add the same DSM estimate, initialization, worker attachment, and retrieval
handling for these nodes. Allow their scan descriptors to request table scan
instrumentation and record it during scan setup.

This lets callers retrieve leader and worker scan instrumentation consistently.

Author: Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
Reviewed-by: Sami Imseih <samimseih.pg@gmail.com>
Discussion: https://postgr.es/m/auCYYbDyrQEwIsQq@bdtpg
---
 src/backend/executor/execParallel.c    |  36 ++++++++
 src/backend/executor/nodeSamplescan.c  | 112 +++++++++++++++++++++++-
 src/backend/executor/nodeTidscan.c     | 114 ++++++++++++++++++++++++-
 src/backend/utils/adt/tid.c            |   2 +-
 src/include/access/tableam.h           |   8 +-
 src/include/executor/instrument_node.h |  37 ++++++++
 src/include/executor/nodeSamplescan.h  |  10 +++
 src/include/executor/nodeTidscan.h     |  10 +++
 src/include/nodes/execnodes.h          |   2 +
 src/tools/pgindent/typedefs.list       |   4 +
 10 files changed, 324 insertions(+), 11 deletions(-)
  76.1% src/backend/executor/
   3.3% src/include/access/
  17.3% src/include/executor/
   3.1% src/

diff --git a/src/backend/executor/execParallel.c b/src/backend/executor/execParallel.c
index 316dd3f67c6..c429570e9a7 100644
--- a/src/backend/executor/execParallel.c
+++ b/src/backend/executor/execParallel.c
@@ -38,9 +38,11 @@
 #include "executor/nodeIndexscan.h"
 #include "executor/nodeMaterial.h"
 #include "executor/nodeMemoize.h"
+#include "executor/nodeSamplescan.h"
 #include "executor/nodeSeqscan.h"
 #include "executor/nodeSort.h"
 #include "executor/nodeSubplan.h"
+#include "executor/nodeTidscan.h"
 #include "executor/nodeTidrangescan.h"
 #include "executor/tqueue.h"
 #include "jit/jit.h"
@@ -262,6 +264,11 @@ ExecParallelEstimate(PlanState *planstate, ExecParallelEstimateContext *e)
 			ExecSeqScanInstrumentEstimate((SeqScanState *) planstate,
 										  e->pcxt);
 			break;
+		case T_SampleScanState:
+			/* even when not parallel-aware, for EXPLAIN ANALYZE */
+			ExecSampleScanInstrumentEstimate((SampleScanState *) planstate,
+											 e->pcxt);
+			break;
 		case T_IndexScanState:
 			if (planstate->plan->parallel_aware)
 				ExecIndexScanEstimate((IndexScanState *) planstate,
@@ -288,6 +295,10 @@ ExecParallelEstimate(PlanState *planstate, ExecParallelEstimateContext *e)
 				ExecForeignScanEstimate((ForeignScanState *) planstate,
 										e->pcxt);
 			break;
+		case T_TidScanState:
+			/* even when not parallel-aware, for EXPLAIN ANALYZE */
+			ExecTidScanInstrumentEstimate((TidScanState *) planstate, e->pcxt);
+			break;
 		case T_TidRangeScanState:
 			if (planstate->plan->parallel_aware)
 				ExecTidRangeScanEstimate((TidRangeScanState *) planstate,
@@ -515,6 +526,11 @@ ExecParallelInitializeDSM(PlanState *planstate,
 			ExecSeqScanInstrumentInitDSM((SeqScanState *) planstate,
 										 d->pcxt);
 			break;
+		case T_SampleScanState:
+			/* even when not parallel-aware, for EXPLAIN ANALYZE */
+			ExecSampleScanInstrumentInitDSM((SampleScanState *) planstate,
+											d->pcxt);
+			break;
 		case T_IndexScanState:
 			if (planstate->plan->parallel_aware)
 				ExecIndexScanInitializeDSM((IndexScanState *) planstate,
@@ -540,6 +556,10 @@ ExecParallelInitializeDSM(PlanState *planstate,
 				ExecForeignScanInitializeDSM((ForeignScanState *) planstate,
 											 d->pcxt);
 			break;
+		case T_TidScanState:
+			/* even when not parallel-aware, for EXPLAIN ANALYZE */
+			ExecTidScanInstrumentInitDSM((TidScanState *) planstate, d->pcxt);
+			break;
 		case T_TidRangeScanState:
 			if (planstate->plan->parallel_aware)
 				ExecTidRangeScanInitializeDSM((TidRangeScanState *) planstate,
@@ -1174,6 +1194,12 @@ ExecParallelRetrieveInstrumentation(PlanState *planstate,
 		case T_SeqScanState:
 			ExecSeqScanRetrieveInstrumentation((SeqScanState *) planstate);
 			break;
+		case T_SampleScanState:
+			ExecSampleScanRetrieveInstrumentation((SampleScanState *) planstate);
+			break;
+		case T_TidScanState:
+			ExecTidScanRetrieveInstrumentation((TidScanState *) planstate);
+			break;
 		case T_TidRangeScanState:
 			ExecTidRangeScanRetrieveInstrumentation((TidRangeScanState *) planstate);
 			break;
@@ -1420,6 +1446,11 @@ ExecParallelInitializeWorker(PlanState *planstate, ParallelWorkerContext *pwcxt)
 			/* even when not parallel-aware, for EXPLAIN ANALYZE */
 			ExecSeqScanInstrumentInitWorker((SeqScanState *) planstate, pwcxt);
 			break;
+		case T_SampleScanState:
+			/* even when not parallel-aware, for EXPLAIN ANALYZE */
+			ExecSampleScanInstrumentInitWorker((SampleScanState *) planstate,
+											   pwcxt);
+			break;
 		case T_IndexScanState:
 			if (planstate->plan->parallel_aware)
 				ExecIndexScanInitializeWorker((IndexScanState *) planstate,
@@ -1446,6 +1477,11 @@ ExecParallelInitializeWorker(PlanState *planstate, ParallelWorkerContext *pwcxt)
 				ExecForeignScanInitializeWorker((ForeignScanState *) planstate,
 												pwcxt);
 			break;
+		case T_TidScanState:
+			/* even when not parallel-aware, for EXPLAIN ANALYZE */
+			ExecTidScanInstrumentInitWorker((TidScanState *) planstate,
+											pwcxt);
+			break;
 		case T_TidRangeScanState:
 			if (planstate->plan->parallel_aware)
 				ExecTidRangeScanInitializeWorker((TidRangeScanState *) planstate,
diff --git a/src/backend/executor/nodeSamplescan.c b/src/backend/executor/nodeSamplescan.c
index f3d273e1c5e..2bdebb81293 100644
--- a/src/backend/executor/nodeSamplescan.c
+++ b/src/backend/executor/nodeSamplescan.c
@@ -18,7 +18,9 @@
 #include "access/tableam.h"
 #include "access/tsmapi.h"
 #include "common/pg_prng.h"
+#include "executor/execParallel.h"
 #include "executor/executor.h"
+#include "executor/instrument.h"
 #include "executor/nodeSamplescan.h"
 #include "utils/fmgrprotos.h"
 #include "utils/rel.h"
@@ -179,17 +181,31 @@ ExecInitSampleScan(SampleScan *node, EState *estate, int eflags)
 void
 ExecEndSampleScan(SampleScanState *node)
 {
+	TableScanDesc scan = node->ss.ss_currentScanDesc;
+
 	/*
 	 * Tell sampling function that we finished the scan.
 	 */
 	if (node->tsmroutine->EndSampleScan)
 		node->tsmroutine->EndSampleScan(node);
 
+	/* Collect scan statistics for this process into shared instrumentation */
+	if (node->sinstrument != NULL && IsParallelWorker())
+	{
+		SampleScanInstrumentation *si;
+
+		Assert(ParallelWorkerNumber < node->sinstrument->num_workers);
+		si = &node->sinstrument->sinstrument[ParallelWorkerNumber];
+
+		if (scan && scan->rs_instrument)
+			CombineTableScanInstrumentation(&si->stats, scan->rs_instrument);
+	}
+
 	/*
 	 * close heap scan
 	 */
-	if (node->ss.ss_currentScanDesc)
-		table_endscan(node->ss.ss_currentScanDesc);
+	if (scan)
+		table_endscan(scan);
 }
 
 /* ----------------------------------------------------------------
@@ -211,6 +227,89 @@ ExecReScanSampleScan(SampleScanState *node)
 	ExecScanReScan(&node->ss);
 }
 
+/*
+ * Compute the amount of space needed for shared sample scan instrumentation.
+ */
+void
+ExecSampleScanInstrumentEstimate(SampleScanState *node, ParallelContext *pcxt)
+{
+	EState	   *estate = node->ss.ps.state;
+	Size		size;
+
+	if ((estate->es_instrument & INSTRUMENT_BUFFERS) == 0 || pcxt->nworkers == 0)
+		return;
+
+	size = add_size(offsetof(SharedSampleScanInstrumentation, sinstrument),
+					mul_size(pcxt->nworkers, sizeof(SampleScanInstrumentation)));
+
+	shm_toc_estimate_chunk(&pcxt->estimator, size);
+	shm_toc_estimate_keys(&pcxt->estimator, 1);
+}
+
+/*
+ * Set up shared sample scan instrumentation.
+ */
+void
+ExecSampleScanInstrumentInitDSM(SampleScanState *node, ParallelContext *pcxt)
+{
+	EState	   *estate = node->ss.ps.state;
+	SharedSampleScanInstrumentation *sinstrument;
+	Size		size;
+
+	if ((estate->es_instrument & INSTRUMENT_BUFFERS) == 0 ||
+		pcxt->nworkers == 0)
+		return;
+
+	size = add_size(offsetof(SharedSampleScanInstrumentation, sinstrument),
+					mul_size(pcxt->nworkers, sizeof(SampleScanInstrumentation)));
+
+	sinstrument = shm_toc_allocate(pcxt->toc, size);
+	memset(sinstrument, 0, size);
+	sinstrument->num_workers = pcxt->nworkers;
+
+	shm_toc_insert(pcxt->toc, node->ss.ps.plan->plan_node_id +
+				   PARALLEL_KEY_SCAN_INSTRUMENT_OFFSET,
+				   sinstrument);
+
+	node->sinstrument = sinstrument;
+}
+
+/*
+ * Look up the shared sample scan instrumentation in a parallel worker.
+ */
+void
+ExecSampleScanInstrumentInitWorker(SampleScanState *node, ParallelWorkerContext *pwcxt)
+{
+	EState	   *estate = node->ss.ps.state;
+
+	if ((estate->es_instrument & INSTRUMENT_BUFFERS) == 0)
+		return;
+
+	node->sinstrument = shm_toc_lookup(pwcxt->toc,
+									   node->ss.ps.plan->plan_node_id +
+									   PARALLEL_KEY_SCAN_INSTRUMENT_OFFSET,
+									   false);
+}
+
+/*
+ * Transfer sample scan instrumentation from DSM to private memory.
+ */
+void
+ExecSampleScanRetrieveInstrumentation(SampleScanState *node)
+{
+	SharedSampleScanInstrumentation *sinstrument = node->sinstrument;
+	Size		size;
+
+	if (sinstrument == NULL)
+		return;
+
+	size = offsetof(SharedSampleScanInstrumentation, sinstrument)
+		+ sinstrument->num_workers * sizeof(SampleScanInstrumentation);
+
+	node->sinstrument = palloc(size);
+	memcpy(node->sinstrument, sinstrument, size);
+}
+
 
 /*
  * Initialize the TABLESAMPLE method: evaluate params and call BeginSampleScan.
@@ -292,6 +391,12 @@ tablesample_init(SampleScanState *scanstate)
 	/* Now we can create or reset the HeapScanDesc */
 	if (scanstate->ss.ss_currentScanDesc == NULL)
 	{
+		uint32		flags = ScanRelIsReadOnly(&scanstate->ss) ?
+			SO_HINT_REL_READ_ONLY : SO_NONE;
+
+		if (scanstate->ss.ps.state->es_instrument & INSTRUMENT_BUFFERS)
+			flags |= SO_SCAN_INSTRUMENT_STRATEGY;
+
 		scanstate->ss.ss_currentScanDesc =
 			table_beginscan_sampling(scanstate->ss.ss_currentRelation,
 									 scanstate->ss.ps.state->es_snapshot,
@@ -299,8 +404,7 @@ tablesample_init(SampleScanState *scanstate)
 									 scanstate->use_bulkread,
 									 allow_sync,
 									 scanstate->use_pagemode,
-									 ScanRelIsReadOnly(&scanstate->ss) ?
-									 SO_HINT_REL_READ_ONLY : SO_NONE);
+									 flags);
 	}
 	else
 	{
diff --git a/src/backend/executor/nodeTidscan.c b/src/backend/executor/nodeTidscan.c
index b63329de330..ff516f9c4e8 100644
--- a/src/backend/executor/nodeTidscan.c
+++ b/src/backend/executor/nodeTidscan.c
@@ -25,7 +25,9 @@
 #include "access/sysattr.h"
 #include "access/tableam.h"
 #include "catalog/pg_type.h"
+#include "executor/execParallel.h"
 #include "executor/executor.h"
+#include "executor/instrument.h"
 #include "executor/nodeTidscan.h"
 #include "lib/qunique.h"
 #include "miscadmin.h"
@@ -146,9 +148,17 @@ TidListEval(TidScanState *tidstate)
 	 * the node might never get executed.
 	 */
 	if (tidstate->ss.ss_currentScanDesc == NULL)
+	{
+		uint32		flags = SO_NONE;
+
+		if (tidstate->ss.ps.state->es_instrument & INSTRUMENT_BUFFERS)
+			flags |= SO_SCAN_INSTRUMENT_STRATEGY;
+
 		tidstate->ss.ss_currentScanDesc =
 			table_beginscan_tid(tidstate->ss.ss_currentRelation,
-								tidstate->ss.ps.state->es_snapshot);
+								tidstate->ss.ps.state->es_snapshot,
+								flags);
+	}
 	scan = tidstate->ss.ss_currentScanDesc;
 
 	/*
@@ -473,8 +483,106 @@ ExecReScanTidScan(TidScanState *node)
 void
 ExecEndTidScan(TidScanState *node)
 {
-	if (node->ss.ss_currentScanDesc)
-		table_endscan(node->ss.ss_currentScanDesc);
+	TableScanDesc scan = node->ss.ss_currentScanDesc;
+
+	/* Collect scan statistics for this process into shared instrumentation */
+	if (node->tss_sinstrument != NULL && IsParallelWorker())
+	{
+		TidScanInstrumentation *si;
+
+		Assert(ParallelWorkerNumber < node->tss_sinstrument->num_workers);
+		si = &node->tss_sinstrument->sinstrument[ParallelWorkerNumber];
+
+		if (scan && scan->rs_instrument)
+			CombineTableScanInstrumentation(&si->stats, scan->rs_instrument);
+	}
+
+	if (scan)
+		table_endscan(scan);
+}
+
+/*
+ * Compute the amount of space needed for shared TID scan instrumentation.
+ */
+void
+ExecTidScanInstrumentEstimate(TidScanState *node, ParallelContext *pcxt)
+{
+	EState	   *estate = node->ss.ps.state;
+	Size		size;
+
+	if ((estate->es_instrument & INSTRUMENT_BUFFERS) == 0 ||
+		pcxt->nworkers == 0)
+		return;
+
+	size = add_size(offsetof(SharedTidScanInstrumentation, sinstrument),
+					mul_size(pcxt->nworkers, sizeof(TidScanInstrumentation)));
+
+	shm_toc_estimate_chunk(&pcxt->estimator, size);
+	shm_toc_estimate_keys(&pcxt->estimator, 1);
+}
+
+/*
+ * Set up shared TID scan instrumentation.
+ */
+void
+ExecTidScanInstrumentInitDSM(TidScanState *node, ParallelContext *pcxt)
+{
+	EState	   *estate = node->ss.ps.state;
+	SharedTidScanInstrumentation *sinstrument;
+	Size		size;
+
+	if ((estate->es_instrument & INSTRUMENT_BUFFERS) == 0 ||
+		pcxt->nworkers == 0)
+		return;
+
+	size = add_size(offsetof(SharedTidScanInstrumentation, sinstrument),
+					mul_size(pcxt->nworkers, sizeof(TidScanInstrumentation)));
+
+	sinstrument = shm_toc_allocate(pcxt->toc, size);
+	memset(sinstrument, 0, size);
+	sinstrument->num_workers = pcxt->nworkers;
+
+	shm_toc_insert(pcxt->toc, node->ss.ps.plan->plan_node_id +
+				   PARALLEL_KEY_SCAN_INSTRUMENT_OFFSET,
+				   sinstrument);
+
+	node->tss_sinstrument = sinstrument;
+}
+
+/*
+ * Look up the shared TID scan instrumentation in a parallel worker.
+ */
+void
+ExecTidScanInstrumentInitWorker(TidScanState *node, ParallelWorkerContext *pwcxt)
+{
+	EState	   *estate = node->ss.ps.state;
+
+	if ((estate->es_instrument & INSTRUMENT_BUFFERS) == 0)
+		return;
+
+	node->tss_sinstrument = shm_toc_lookup(pwcxt->toc,
+										   node->ss.ps.plan->plan_node_id +
+										   PARALLEL_KEY_SCAN_INSTRUMENT_OFFSET,
+										   false);
+}
+
+/*
+ * Transfer TID scan instrumentation from DSM to private memory.
+ */
+void
+ExecTidScanRetrieveInstrumentation(TidScanState *node)
+{
+	SharedTidScanInstrumentation *sinstrument = node->tss_sinstrument;
+	Size		size;
+
+	if (sinstrument == NULL)
+		return;
+
+	size = offsetof(SharedTidScanInstrumentation, sinstrument)
+		+ sinstrument->num_workers * sizeof(TidScanInstrumentation);
+
+	node->tss_sinstrument = palloc(size);
+	memcpy(node->tss_sinstrument, sinstrument, size);
 }
 
 /* ----------------------------------------------------------------
diff --git a/src/backend/utils/adt/tid.c b/src/backend/utils/adt/tid.c
index f730b2f07c2..223a75866f6 100644
--- a/src/backend/utils/adt/tid.c
+++ b/src/backend/utils/adt/tid.c
@@ -355,7 +355,7 @@ currtid_internal(Relation rel, const ItemPointerData *tid)
 	ItemPointerCopy(tid, result);
 
 	snapshot = RegisterSnapshot(GetLatestSnapshot());
-	scan = table_beginscan_tid(rel, snapshot);
+	scan = table_beginscan_tid(rel, snapshot, SO_NONE);
 	table_tuple_get_latest_tid(scan, result);
 	table_endscan(scan);
 	UnregisterSnapshot(snapshot);
diff --git a/src/include/access/tableam.h b/src/include/access/tableam.h
index 9ad8dde300f..2a649431e13 100644
--- a/src/include/access/tableam.h
+++ b/src/include/access/tableam.h
@@ -1032,14 +1032,16 @@ table_beginscan_sampling(Relation rel, Snapshot snapshot,
  * table_beginscan_tid is an alternative entry point for setting up a
  * TableScanDesc for a Tid scan. As with bitmap scans, it's worth using
  * the same data structure although the behavior is rather different.
+ *
+ * flags is a bitmask of ScanOptions. No SO_INTERNAL_FLAGS are permitted.
  */
 static inline TableScanDesc
-table_beginscan_tid(Relation rel, Snapshot snapshot)
+table_beginscan_tid(Relation rel, Snapshot snapshot, uint32 flags)
 {
-	uint32		flags = SO_TYPE_TIDSCAN;
+	uint32		internal_flags = SO_TYPE_TIDSCAN;
 
 	return table_beginscan_common(rel, snapshot, 0, NULL, NULL,
-								  flags, SO_NONE);
+								  internal_flags, flags);
 }
 
 /*
diff --git a/src/include/executor/instrument_node.h b/src/include/executor/instrument_node.h
index 845c18e7aa1..005fdc6f57b 100644
--- a/src/include/executor/instrument_node.h
+++ b/src/include/executor/instrument_node.h
@@ -335,6 +335,43 @@ typedef struct SharedSeqScanInstrumentation
 } SharedSeqScanInstrumentation;
 
 
+/* ---------------------
+ *	Instrumentation information for sample scans
+ * ---------------------
+ */
+typedef struct SampleScanInstrumentation
+{
+	TableScanInstrumentation stats;
+} SampleScanInstrumentation;
+
+/*
+ * Shared memory container for per-worker information
+ */
+typedef struct SharedSampleScanInstrumentation
+{
+	int			num_workers;
+	SampleScanInstrumentation sinstrument[FLEXIBLE_ARRAY_MEMBER];
+} SharedSampleScanInstrumentation;
+
+/* ---------------------
+ *	Instrumentation information for TID scans
+ * ---------------------
+ */
+typedef struct TidScanInstrumentation
+{
+	TableScanInstrumentation stats;
+} TidScanInstrumentation;
+
+/*
+ * Shared memory container for per-worker information
+ */
+typedef struct SharedTidScanInstrumentation
+{
+	int			num_workers;
+	TidScanInstrumentation sinstrument[FLEXIBLE_ARRAY_MEMBER];
+} SharedTidScanInstrumentation;
+
+
 /*
  *	Instrumentation information for TID range scans
  */
diff --git a/src/include/executor/nodeSamplescan.h b/src/include/executor/nodeSamplescan.h
index d08d2be44e2..d2db06b6c2c 100644
--- a/src/include/executor/nodeSamplescan.h
+++ b/src/include/executor/nodeSamplescan.h
@@ -14,10 +14,20 @@
 #ifndef NODESAMPLESCAN_H
 #define NODESAMPLESCAN_H
 
+#include "access/parallel.h"
 #include "nodes/execnodes.h"
 
 extern SampleScanState *ExecInitSampleScan(SampleScan *node, EState *estate, int eflags);
 extern void ExecEndSampleScan(SampleScanState *node);
 extern void ExecReScanSampleScan(SampleScanState *node);
 
+/* instrument support */
+extern void ExecSampleScanInstrumentEstimate(SampleScanState *node,
+											 ParallelContext *pcxt);
+extern void ExecSampleScanInstrumentInitDSM(SampleScanState *node,
+											ParallelContext *pcxt);
+extern void ExecSampleScanInstrumentInitWorker(SampleScanState *node,
+											   ParallelWorkerContext *pwcxt);
+extern void ExecSampleScanRetrieveInstrumentation(SampleScanState *node);
+
 #endif							/* NODESAMPLESCAN_H */
diff --git a/src/include/executor/nodeTidscan.h b/src/include/executor/nodeTidscan.h
index 65f8587986f..8729fdbd12e 100644
--- a/src/include/executor/nodeTidscan.h
+++ b/src/include/executor/nodeTidscan.h
@@ -14,10 +14,20 @@
 #ifndef NODETIDSCAN_H
 #define NODETIDSCAN_H
 
+#include "access/parallel.h"
 #include "nodes/execnodes.h"
 
 extern TidScanState *ExecInitTidScan(TidScan *node, EState *estate, int eflags);
 extern void ExecEndTidScan(TidScanState *node);
 extern void ExecReScanTidScan(TidScanState *node);
 
+/* instrument support */
+extern void ExecTidScanInstrumentEstimate(TidScanState *node,
+										  ParallelContext *pcxt);
+extern void ExecTidScanInstrumentInitDSM(TidScanState *node,
+										 ParallelContext *pcxt);
+extern void ExecTidScanInstrumentInitWorker(TidScanState *node,
+											ParallelWorkerContext *pwcxt);
+extern void ExecTidScanRetrieveInstrumentation(TidScanState *node);
+
 #endif							/* NODETIDSCAN_H */
diff --git a/src/include/nodes/execnodes.h b/src/include/nodes/execnodes.h
index fe8681ba642..2e1d584096b 100644
--- a/src/include/nodes/execnodes.h
+++ b/src/include/nodes/execnodes.h
@@ -1672,6 +1672,7 @@ typedef struct SampleScanState
 	int64		donetuples;		/* number of tuples already returned */
 	bool		haveblock;		/* has a block for sampling been determined */
 	bool		done;			/* exhausted all tuples? */
+	struct SharedSampleScanInstrumentation *sinstrument;
 } SampleScanState;
 
 /*
@@ -1874,6 +1875,7 @@ typedef struct TidScanState
 	int			tss_NumTids;
 	int			tss_TidPtr;
 	ItemPointerData *tss_TidList;
+	struct SharedTidScanInstrumentation *tss_sinstrument;
 } TidScanState;
 
 /* ----------------
diff --git a/src/tools/pgindent/typedefs.list b/src/tools/pgindent/typedefs.list
index cfef572df80..a7b1035f068 100644
--- a/src/tools/pgindent/typedefs.list
+++ b/src/tools/pgindent/typedefs.list
@@ -2767,6 +2767,7 @@ SYNCHRONIZATION_BARRIER
 SYSTEM_INFO
 SampleScan
 SampleScanGetSampleSize_function
+SampleScanInstrumentation
 SampleScanState
 SavedTransactionCharacteristics
 ScalarArrayOpExpr
@@ -2867,8 +2868,10 @@ SharedMemoizeInfo
 SharedRecordTableEntry
 SharedRecordTableKey
 SharedRecordTypmodRegistry
+SharedSampleScanInstrumentation
 SharedSeqScanInstrumentation
 SharedSortInfo
+SharedTidScanInstrumentation
 SharedTidRangeScanInstrumentation
 SharedTuplestore
 SharedTuplestoreAccessor
@@ -3182,6 +3185,7 @@ TidRangeScan
 TidRangeScanInstrumentation
 TidRangeScanState
 TidScan
+TidScanInstrumentation
 TidScanState
 TidStore
 TidStoreIter
-- 
2.34.1

