Subject: Re: pgstat include expansion

From: Alvaro Herrera <[email-masked]>
Date: Mon, 16 Feb 2026 19:34:12 +0100

Hello,

On 2026-Feb-16, Andres Freund wrote:

> On 2026-02-16 17:18:36 +0100, Alvaro Herrera wrote:

> > I don't think the removal of pg_list.h works terribly well though, as
> > that is something that I would expect to be pretty much everywhere, so
> > it seems somewhat pointless to try to avoid it in this file.
> 
> Yea, I was on the fence about that one.
> 
> It does seem pretty crappy that pg_list.h is so widely included and in turn
> includes nodes/nodes.h, which then depends on the generated nodetags.h.  For
> one it forces an unnecessary rebuild of too much if you add a new node type,
> but it also just aesthetically feels wrong.

Yeah, I was unhappy about pg_list.h too on my recent header hacking, and
perhaps we can improve this somehow, but I think it's a bigger effort.

> > I think we should in addition remove some includes that were kept during
> > recent IWYU hacking "for backwards compatibility", and instead include
> > them explicitly wherever they are needed.  The attached does that.
> 
> FWIW, the "for backwards compatibility" includes are from prep work towards
> shared memory stats. Before that all the stuff in backend_status.h,
> backend_progress.h and wait_event.h was in pgstat.h, which was quite
> unwieldy.

Ah, okay.

> The creation of those headers would have broken a lot of extensions if
> we had not provided those backward compat includes from pgstat.h.

Right ... TBH the real issue for me is that wait_event.h includes the
generated file wait_event_types.h (same complaint you had above), but I
decided that if I was wielding a weapon against pgstat.h, it could as
well be a shotgun.  I guess I would be satisfied if we remove
wait_events.h from pgstat.h, and that probably won't break as many
extensions and won't have as much of a fallout.  Although TB further H,
I don't really see it as terribly bad if we break extensions with this
kind of work, since the fix on their side is fairly easy, noninvasive,
and doesn't have to be done with any urgency.

> FWIW, your patch that you sent subsequently doesn't seem to apply cleanly for
> me? I think it's perhaps based on an older tree, it doesn't know about the
> conflict.h include yet...  And it fails to build e.g. due to miscadmin.h
> defines around BackendType not being indirectly included in pgstat.h anymore,
> but there are many other failures...

Yeah, I just wrote it on (almost) clean master, but feel free to push
your changes whenever, and I'll rebase on top of that.  I suspect the
failures just mean that the implicit header inclusions are worse than
they appear at first.

-- 
Álvaro Herrera         PostgreSQL Developer  —  https://www.EnterpriseDB.com/

---

From: Alvaro Herrera <[email-masked]>
Date: Wed, 18 Feb 2026 16:10:38 +0100

On 2026-Feb-16, Alvaro Herrera wrote:

> > FWIW, your patch that you sent subsequently doesn't seem to apply
> > cleanly for me? I think it's perhaps based on an older tree, it
> > doesn't know about the conflict.h include yet...  And it fails to
> > build e.g. due to miscadmin.h defines around BackendType not being
> > indirectly included in pgstat.h anymore, but there are many other
> > failures...
> 
> your changes whenever, and I'll rebase on top of that.

Actually, being more surgical and removing only wait_event.h, the
attached patch applies and compiles cleanly -- after yours this time,
rather than on master.  I think this is the most significant change
because of it including the generated file.  Given that pgstat.h is not
_so_ widely used, I think leaving the other includes there doesn't hurt
all that much anyway.

-- 
Álvaro Herrera         PostgreSQL Developer  —  https://www.EnterpriseDB.com/
<Schwern> It does it in a really, really complicated way
<crab> why does it need to be complicated?
<Schwern> Because it's MakeMaker.
diff --git a/contrib/pg_prewarm/autoprewarm.c b/contrib/pg_prewarm/autoprewarm.c
index 89e187425cc..ba0bc8e6d4a 100644
--- a/contrib/pg_prewarm/autoprewarm.c
+++ b/contrib/pg_prewarm/autoprewarm.c
@@ -48,6 +48,7 @@
 #include "utils/rel.h"
 #include "utils/relfilenumbermap.h"
 #include "utils/timestamp.h"
+#include "utils/wait_event.h"
 
 #define AUTOPREWARM_FILE "autoprewarm.blocks"
 
diff --git a/src/backend/access/brin/brin.c b/src/backend/access/brin/brin.c
index 6887e421442..126ae349452 100644
--- a/src/backend/access/brin/brin.c
+++ b/src/backend/access/brin/brin.c
@@ -42,6 +42,7 @@
 #include "utils/memutils.h"
 #include "utils/rel.h"
 #include "utils/tuplesort.h"
+#include "utils/wait_event.h"
 
 /* Magic numbers for parallel state sharing */
 #define PARALLEL_KEY_BRIN_SHARED		UINT64CONST(0xB000000000000001)
diff --git a/src/backend/access/gin/gininsert.c b/src/backend/access/gin/gininsert.c
index 0d63fb4ba27..e38da2e5b98 100644
--- a/src/backend/access/gin/gininsert.c
+++ b/src/backend/access/gin/gininsert.c
@@ -34,7 +34,7 @@
 #include "utils/builtins.h"
 #include "utils/rel.h"
 #include "utils/typcache.h"
-
+#include "utils/wait_event.h"
 
 /* Magic numbers for parallel state sharing */
 #define PARALLEL_KEY_GIN_SHARED			UINT64CONST(0xB000000000000001)
diff --git a/src/backend/access/heap/rewriteheap.c b/src/backend/access/heap/rewriteheap.c
index 77fd48eb59e..6b19ac3030d 100644
--- a/src/backend/access/heap/rewriteheap.c
+++ b/src/backend/access/heap/rewriteheap.c
@@ -122,6 +122,7 @@
 #include "storage/procarray.h"
 #include "utils/memutils.h"
 #include "utils/rel.h"
+#include "utils/wait_event.h"
 
 /*
  * State associated with a rewrite operation. This is opaque to the user
diff --git a/src/backend/access/heap/vacuumlazy.c b/src/backend/access/heap/vacuumlazy.c
index 4be267ff657..259f0822564 100644
--- a/src/backend/access/heap/vacuumlazy.c
+++ b/src/backend/access/heap/vacuumlazy.c
@@ -154,6 +154,7 @@
 #include "utils/lsyscache.h"
 #include "utils/pg_rusage.h"
 #include "utils/timestamp.h"
+#include "utils/wait_event.h"

 /*
diff --git a/src/backend/access/nbtree/nbtree.c b/src/backend/access/nbtree/nbtree.c
index 3dec1ee657d..6d0a6f27f3f 100644
--- a/src/backend/access/nbtree/nbtree.c
+++ b/src/backend/access/nbtree/nbtree.c
@@ -35,6 +35,7 @@
 #include "utils/fmgrprotos.h"
 #include "utils/index_selfuncs.h"
 #include "utils/memutils.h"
+#include "utils/wait_event.h"

 /*
diff --git a/src/backend/access/nbtree/nbtsort.c b/src/backend/access/nbtree/nbtsort.c
index 3a45508f62e..a9b0618f464 100644
--- a/src/backend/access/nbtree/nbtsort.c
+++ b/src/backend/access/nbtree/nbtsort.c
@@ -56,6 +56,7 @@
 #include "utils/rel.h"
 #include "utils/sortsupport.h"
 #include "utils/tuplesort.h"
+#include "utils/wait_event.h"

 /* Magic numbers for parallel state sharing */
diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c
index b5c38bbb162..3ee1cfdbc24 100644
--- a/src/backend/access/transam/clog.c
+++ b/src/backend/access/transam/clog.c
@@ -45,6 +45,7 @@
 #include "storage/proc.h"
 #include "storage/sync.h"
 #include "utils/guc_hooks.h"
+#include "utils/wait_event.h"
 
 /*
  * Defines for CLOG page sizes.  A page is the same BLCKSZ as is used
diff --git a/src/backend/access/transam/parallel.c b/src/backend/access/transam/parallel.c
index fe00488487d..96cf8ee9bcc 100644
--- a/src/backend/access/transam/parallel.c
+++ b/src/backend/access/transam/parallel.c
@@ -44,6 +44,7 @@
 #include "utils/memutils.h"
 #include "utils/relmapper.h"
 #include "utils/snapmgr.h"
+#include "utils/wait_event.h"
 
 /*
  * We don't want to waste a lot of memory on an error queue which, most of
diff --git a/src/backend/access/transam/slru.c b/src/backend/access/transam/slru.c
index 549c7e3e64b..556edcbf7cb 100644
--- a/src/backend/access/transam/slru.c
+++ b/src/backend/access/transam/slru.c
@@ -71,6 +71,7 @@
 #include "storage/fd.h"
 #include "storage/shmem.h"
 #include "utils/guc.h"
+#include "utils/wait_event.h"
 
 /*
  * Converts segment number to the filename of the segment.
diff --git a/src/backend/access/transam/timeline.c b/src/backend/access/transam/timeline.c
index 60ee28665b1..68e5f692d26 100644
--- a/src/backend/access/transam/timeline.c
+++ b/src/backend/access/transam/timeline.c
@@ -41,6 +41,7 @@
 #include "access/xlogdefs.h"
 #include "pgstat.h"
 #include "storage/fd.h"
+#include "utils/wait_event.h"
 
 /*
  * Copies all timeline history files with id's between 'begin' and 'end'
diff --git a/src/backend/access/transam/twophase.c b/src/backend/access/transam/twophase.c
index eabc4d48208..47c0ede807e 100644
--- a/src/backend/access/transam/twophase.c
+++ b/src/backend/access/transam/twophase.c
@@ -106,6 +106,7 @@
 #include "utils/injection_point.h"
 #include "utils/memutils.h"
 #include "utils/timestamp.h"
+#include "utils/wait_event.h"
 
 /*
  * Directory where Two-phase commit files reside within PGDATA
diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c
index 13ec6225b85..2eb7d376427 100644
--- a/src/backend/access/transam/xlog.c
+++ b/src/backend/access/transam/xlog.c
@@ -105,6 +105,7 @@
 #include "utils/timeout.h"
 #include "utils/timestamp.h"
 #include "utils/varlena.h"
+#include "utils/wait_event.h"
 
 #ifdef WAL_DEBUG
 #include "utils/memutils.h"
diff --git a/src/backend/access/transam/xlogarchive.c b/src/backend/access/transam/xlogarchive.c
index aa0c2fe3afd..9a0c8097cb1 100644
--- a/src/backend/access/transam/xlogarchive.c
+++ b/src/backend/access/transam/xlogarchive.c
@@ -31,6 +31,7 @@
 #include "replication/walsender.h"
 #include "storage/fd.h"
 #include "storage/ipc.h"
+#include "utils/wait_event.h"
 
 /*
  * Attempt to retrieve the specified file from off-line archival storage.
diff --git a/src/backend/access/transam/xlogfuncs.c b/src/backend/access/transam/xlogfuncs.c
index 2efe4105efb..8965be29703 100644
--- a/src/backend/access/transam/xlogfuncs.c
+++ b/src/backend/access/transam/xlogfuncs.c
@@ -34,6 +34,7 @@
 #include "utils/memutils.h"
 #include "utils/pg_lsn.h"
 #include "utils/timestamp.h"
+#include "utils/wait_event.h"
 
 /*
  * Backup-related variables.
diff --git a/src/backend/access/transam/xlogreader.c b/src/backend/access/transam/xlogreader.c
index 03ada8aa0c5..d26a71e3a89 100644
--- a/src/backend/access/transam/xlogreader.c
+++ b/src/backend/access/transam/xlogreader.c
@@ -32,6 +32,7 @@
 #include "catalog/pg_control.h"
 #include "common/pg_lzcompress.h"
 #include "replication/origin.h"
+#include "utils/wait_event.h"
 
 #ifndef FRONTEND
 #include "pgstat.h"
diff --git a/src/backend/access/transam/xlogrecovery.c b/src/backend/access/transam/xlogrecovery.c
index c0c2744d45b..bc1dd23a822 100644
--- a/src/backend/access/transam/xlogrecovery.c
+++ b/src/backend/access/transam/xlogrecovery.c
@@ -65,6 +65,7 @@
 #include "utils/pg_lsn.h"
 #include "utils/ps_status.h"
 #include "utils/pg_rusage.h"
+#include "utils/wait_event.h"
 
 /* Unsupported old recovery command file names (relative to $PGDATA) */
 #define RECOVERY_COMMAND_FILE	"recovery.conf"
diff --git a/src/backend/access/transam/xlogwait.c b/src/backend/access/transam/xlogwait.c
index d286ff63123..bf4630677b4 100644
--- a/src/backend/access/transam/xlogwait.c
+++ b/src/backend/access/transam/xlogwait.c
@@ -60,6 +60,7 @@
 #include "utils/fmgrprotos.h"
 #include "utils/pg_lsn.h"
 #include "utils/snapmgr.h"
+#include "utils/wait_event.h"

 static int	waitlsn_cmp(const pairingheap_node *a, const pairingheap_node *b,
diff --git a/src/backend/archive/shell_archive.c b/src/backend/archive/shell_archive.c
index 5b565968818..0b427a68809 100644
--- a/src/backend/archive/shell_archive.c
+++ b/src/backend/archive/shell_archive.c
@@ -22,6 +22,7 @@
 #include "archive/shell_archive.h"
 #include "common/percentrepl.h"
 #include "pgstat.h"
+#include "utils/wait_event.h"
 
 static bool shell_archive_configured(ArchiveModuleState *state);
 static bool shell_archive_file(ArchiveModuleState *state,
diff --git a/src/backend/backup/basebackup.c b/src/backend/backup/basebackup.c
index 2d74c648335..ab1fbae8001 100644
--- a/src/backend/backup/basebackup.c
+++ b/src/backend/backup/basebackup.c
@@ -48,6 +48,7 @@
 #include "utils/ps_status.h"
 #include "utils/relcache.h"
 #include "utils/resowner.h"
+#include "utils/wait_event.h"
 
 /*
  * How much data do we want to send in one CopyData message? Note that
diff --git a/src/backend/backup/basebackup_throttle.c b/src/backend/backup/basebackup_throttle.c
index e112eed7485..4d8d90f356b 100644
--- a/src/backend/backup/basebackup_throttle.c
+++ b/src/backend/backup/basebackup_throttle.c
@@ -19,6 +19,7 @@
 #include "pgstat.h"
 #include "storage/latch.h"
 #include "utils/timestamp.h"
+#include "utils/wait_event.h"
 
 typedef struct bbsink_throttle
 {
diff --git a/src/backend/commands/copyfromparse.c b/src/backend/commands/copyfromparse.c
index 94d6f415a06..ef6bb36e9df 100644
--- a/src/backend/commands/copyfromparse.c
+++ b/src/backend/commands/copyfromparse.c
@@ -74,6 +74,7 @@
 #include "port/pg_bswap.h"
 #include "utils/builtins.h"
 #include "utils/rel.h"
+#include "utils/wait_event.h"
 
 #define ISOCTAL(c) (((c) >= '0') && ((c) <= '7'))
 #define OCTVALUE(c) ((c) - '0')
diff --git a/src/backend/commands/copyto.c b/src/backend/commands/copyto.c
index 9ceeff6d99e..d6ef7275a64 100644
--- a/src/backend/commands/copyto.c
+++ b/src/backend/commands/copyto.c
@@ -37,6 +37,7 @@
 #include "utils/memutils.h"
 #include "utils/rel.h"
 #include "utils/snapmgr.h"
+#include "utils/wait_event.h"
 
 /*
  * Represents the different dest cases we need to worry about at
diff --git a/src/backend/commands/dbcommands.c b/src/backend/commands/dbcommands.c
index 33311760df7..ea56cf0056b 100644
--- a/src/backend/commands/dbcommands.c
+++ b/src/backend/commands/dbcommands.c
@@ -70,6 +70,7 @@
 #include "utils/relmapper.h"
 #include "utils/snapmgr.h"
 #include "utils/syscache.h"
+#include "utils/wait_event.h"
 
 /*
  * Create database strategy.
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 03932f45c8a..c61c9eb0a01 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -61,6 +61,7 @@
 #include "utils/memutils.h"
 #include "utils/snapmgr.h"
 #include "utils/syscache.h"
+#include "utils/wait_event.h"
 
 /*
  * Minimum interval for cost-based vacuum delay reports from a parallel worker.
diff --git a/src/backend/executor/nodeAppend.c b/src/backend/executor/nodeAppend.c
index 7138dc692c6..677b9e367c0 100644
--- a/src/backend/executor/nodeAppend.c
+++ b/src/backend/executor/nodeAppend.c
@@ -64,6 +64,7 @@
 #include "miscadmin.h"
 #include "pgstat.h"
 #include "storage/latch.h"
+#include "utils/wait_event.h"
 
 /* Shared state for parallel-aware Append. */
 struct ParallelAppendState
diff --git a/src/backend/executor/nodeBitmapHeapscan.c b/src/backend/executor/nodeBitmapHeapscan.c
index c68c26cbf38..e0b6df64767 100644
--- a/src/backend/executor/nodeBitmapHeapscan.c
+++ b/src/backend/executor/nodeBitmapHeapscan.c
@@ -45,6 +45,7 @@
 #include "storage/bufmgr.h"
 #include "utils/rel.h"
 #include "utils/spccache.h"
+#include "utils/wait_event.h"
 
 static void BitmapTableScanSetup(BitmapHeapScanState *node);
 static TupleTableSlot *BitmapHeapNext(BitmapHeapScanState *node);
diff --git a/src/backend/libpq/be-secure-gssapi.c b/src/backend/libpq/be-secure-gssapi.c
index df7dc79b827..ff355201afa 100644
--- a/src/backend/libpq/be-secure-gssapi.c
+++ b/src/backend/libpq/be-secure-gssapi.c
@@ -23,6 +23,7 @@
 #include "port/pg_bswap.h"
 #include "utils/injection_point.h"
 #include "utils/memutils.h"
+#include "utils/wait_event.h"

 /*
diff --git a/src/backend/libpq/be-secure-openssl.c b/src/backend/libpq/be-secure-openssl.c
index 4da6ac22ff9..14c6532bb16 100644
--- a/src/backend/libpq/be-secure-openssl.c
+++ b/src/backend/libpq/be-secure-openssl.c
@@ -35,6 +35,7 @@
 #include "storage/latch.h"
 #include "utils/guc.h"
 #include "utils/memutils.h"
+#include "utils/wait_event.h"
 
 /*
  * These SSL-related #includes must come after all system-provided headers.
diff --git a/src/backend/libpq/pqmq.c b/src/backend/libpq/pqmq.c
index 6e4bbfb5aa1..8270bcc8007 100644
--- a/src/backend/libpq/pqmq.c
+++ b/src/backend/libpq/pqmq.c
@@ -22,6 +22,7 @@
 #include "replication/logicalworker.h"
 #include "tcop/tcopprot.h"
 #include "utils/builtins.h"
+#include "utils/wait_event.h"
 
 static shm_mq_handle *pq_mq_handle = NULL;
 static bool pq_mq_busy = false;
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index 6fde740465f..695e187ba11 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -109,6 +109,7 @@
 #include "utils/syscache.h"
 #include "utils/timeout.h"
 #include "utils/timestamp.h"
+#include "utils/wait_event.h"

 /*
diff --git a/src/backend/postmaster/bgworker.c b/src/backend/postmaster/bgworker.c
index 261ccd3f59c..9a4ee4f6746 100644
--- a/src/backend/postmaster/bgworker.c
+++ b/src/backend/postmaster/bgworker.c
@@ -34,6 +34,7 @@
 #include "utils/memutils.h"
 #include "utils/ps_status.h"
 #include "utils/timeout.h"
+#include "utils/wait_event.h"
 
 /*
  * The postmaster's list of registered background workers, in private memory.
diff --git a/src/backend/postmaster/bgwriter.c b/src/backend/postmaster/bgwriter.c
index 0956bd39a85..1d8947774a9 100644
--- a/src/backend/postmaster/bgwriter.c
+++ b/src/backend/postmaster/bgwriter.c
@@ -51,6 +51,7 @@
 #include "utils/memutils.h"
 #include "utils/resowner.h"
 #include "utils/timestamp.h"
+#include "utils/wait_event.h"
 
 /*
  * GUC parameters
diff --git a/src/backend/postmaster/checkpointer.c b/src/backend/postmaster/checkpointer.c
index e03c19123bc..3c982c6ffac 100644
--- a/src/backend/postmaster/checkpointer.c
+++ b/src/backend/postmaster/checkpointer.c
@@ -67,6 +67,7 @@
 #include "utils/guc.h"
 #include "utils/memutils.h"
 #include "utils/resowner.h"
+#include "utils/wait_event.h"

 /*----------
diff --git a/src/backend/postmaster/pgarch.c b/src/backend/postmaster/pgarch.c
index 82731e452fc..fa4bdfe9ab9 100644
--- a/src/backend/postmaster/pgarch.c
+++ b/src/backend/postmaster/pgarch.c
@@ -53,6 +53,7 @@
 #include "utils/ps_status.h"
 #include "utils/resowner.h"
 #include "utils/timeout.h"
+#include "utils/wait_event.h"

 /* ----------
diff --git a/src/backend/postmaster/syslogger.c b/src/backend/postmaster/syslogger.c
index 86c5e376b40..9792f638718 100644
--- a/src/backend/postmaster/syslogger.c
+++ b/src/backend/postmaster/syslogger.c
@@ -51,6 +51,7 @@
 #include "utils/guc.h"
 #include "utils/memutils.h"
 #include "utils/ps_status.h"
+#include "utils/wait_event.h"
 
 /*
  * We read() into a temp buffer twice as big as a chunk, so that any fragment
diff --git a/src/backend/postmaster/walwriter.c b/src/backend/postmaster/walwriter.c
index 7c0e2809c17..9cd86ad7022 100644
--- a/src/backend/postmaster/walwriter.c
+++ b/src/backend/postmaster/walwriter.c
@@ -62,6 +62,7 @@
 #include "utils/hsearch.h"
 #include "utils/memutils.h"
 #include "utils/resowner.h"
+#include "utils/wait_event.h"

 /*
diff --git a/src/backend/replication/logical/applyparallelworker.c b/src/backend/replication/logical/applyparallelworker.c
index 8a01f16a2ca..05d83c606a5 100644
--- a/src/backend/replication/logical/applyparallelworker.c
+++ b/src/backend/replication/logical/applyparallelworker.c
@@ -171,6 +171,7 @@
 #include "utils/inval.h"
 #include "utils/memutils.h"
 #include "utils/syscache.h"
+#include "utils/wait_event.h"
 
 #define PG_LOGICAL_APPLY_SHM_MAGIC 0x787ca067
 
diff --git a/src/backend/replication/logical/launcher.c b/src/backend/replication/logical/launcher.c
index 3ed86480be2..fe1cc792fc2 100644
--- a/src/backend/replication/logical/launcher.c
+++ b/src/backend/replication/logical/launcher.c
@@ -44,6 +44,7 @@
 #include "utils/pg_lsn.h"
 #include "utils/snapmgr.h"
 #include "utils/syscache.h"
+#include "utils/wait_event.h"
 
 /* max sleep time between cycles (3min) */
 #define DEFAULT_NAPTIME_PER_CYCLE 180000L
diff --git a/src/backend/replication/logical/origin.c b/src/backend/replication/logical/origin.c
index c3271a6fd0e..26afd8f0af9 100644
--- a/src/backend/replication/logical/origin.c
+++ b/src/backend/replication/logical/origin.c
@@ -95,6 +95,7 @@
 #include "utils/rel.h"
 #include "utils/snapmgr.h"
 #include "utils/syscache.h"
+#include "utils/wait_event.h"
 
 /* paths for replication origin checkpoint files */
 #define PG_REPLORIGIN_CHECKPOINT_FILENAME PG_LOGICAL_DIR "/replorigin_checkpoint"
diff --git a/src/backend/replication/logical/reorderbuffer.c b/src/backend/replication/logical/reorderbuffer.c
index 94b2b29945c..758e0ae5677 100644
--- a/src/backend/replication/logical/reorderbuffer.c
+++ b/src/backend/replication/logical/reorderbuffer.c
@@ -113,6 +113,7 @@
 #include "utils/memutils.h"
 #include "utils/rel.h"
 #include "utils/relfilenumbermap.h"
+#include "utils/wait_event.h"
 
 /*
  * Each transaction has an 8MB limit for invalidation messages distributed from
diff --git a/src/backend/replication/logical/slotsync.c b/src/backend/replication/logical/slotsync.c
index 062a08ccb88..19976efe4f2 100644
--- a/src/backend/replication/logical/slotsync.c
+++ b/src/backend/replication/logical/slotsync.c
@@ -75,6 +75,7 @@
 #include "utils/pg_lsn.h"
 #include "utils/ps_status.h"
 #include "utils/timeout.h"
+#include "utils/wait_event.h"
 
 /*
  * Struct for sharing information to control slot synchronization.
diff --git a/src/backend/replication/logical/snapbuild.c b/src/backend/replication/logical/snapbuild.c
index 7f79621b57e..eddb3d9105c 100644
--- a/src/backend/replication/logical/snapbuild.c
+++ b/src/backend/replication/logical/snapbuild.c
@@ -144,6 +144,9 @@
 #include "utils/memutils.h"
 #include "utils/snapmgr.h"
 #include "utils/snapshot.h"
+#include "utils/wait_event.h"
+
+
 /*
  * Starting a transaction -- which we need to do while exporting a snapshot --
  * removes knowledge about the previously used resowner, so we save it here.
diff --git a/src/backend/replication/logical/tablesync.c b/src/backend/replication/logical/tablesync.c
index 19a3c21a863..4306e682728 100644
--- a/src/backend/replication/logical/tablesync.c
+++ b/src/backend/replication/logical/tablesync.c
@@ -121,6 +121,7 @@
 #include "utils/snapmgr.h"
 #include "utils/syscache.h"
 #include "utils/usercontext.h"
+#include "utils/wait_event.h"
 
 List	   *table_states_not_ready = NIL;
 
diff --git a/src/backend/replication/logical/worker.c b/src/backend/replication/logical/worker.c
index 32725c48623..688182c3e3d 100644
--- a/src/backend/replication/logical/worker.c
+++ b/src/backend/replication/logical/worker.c
@@ -295,6 +295,7 @@
 #include "utils/snapmgr.h"
 #include "utils/syscache.h"
 #include "utils/usercontext.h"
+#include "utils/wait_event.h"
 
 #define NAPTIME_PER_CYCLE 1000	/* max sleep time between cycles (1s) */
 
diff --git a/src/backend/replication/slot.c b/src/backend/replication/slot.c
index 28c7019402b..a9092fc2382 100644
--- a/src/backend/replication/slot.c
+++ b/src/backend/replication/slot.c
@@ -59,6 +59,7 @@
 #include "utils/guc_hooks.h"
 #include "utils/injection_point.h"
 #include "utils/varlena.h"
+#include "utils/wait_event.h"
 
 /*
  * Replication slot on-disk data structure.
diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c
index 7ea6001e9ad..87202e491ed 100644
--- a/src/backend/replication/syncrep.c
+++ b/src/backend/replication/syncrep.c
@@ -85,6 +85,7 @@
 #include "tcop/tcopprot.h"
 #include "utils/guc_hooks.h"
 #include "utils/ps_status.h"
+#include "utils/wait_event.h"
 
 /* User-settable parameters for sync rep */
 char	   *SyncRepStandbyNames;
diff --git a/src/backend/replication/walreceiver.c b/src/backend/replication/walreceiver.c
index 10e64a7d1f4..34a38678ec1 100644
--- a/src/backend/replication/walreceiver.c
+++ b/src/backend/replication/walreceiver.c
@@ -79,6 +79,7 @@
 #include "utils/pg_lsn.h"
 #include "utils/ps_status.h"
 #include "utils/timestamp.h"
+#include "utils/wait_event.h"

 /*
diff --git a/src/backend/replication/walreceiverfuncs.c b/src/backend/replication/walreceiverfuncs.c
index 42e3e170bc0..f0413dedf71 100644
--- a/src/backend/replication/walreceiverfuncs.c
+++ b/src/backend/replication/walreceiverfuncs.c
@@ -30,6 +30,7 @@
 #include "storage/proc.h"
 #include "storage/shmem.h"
 #include "utils/timestamp.h"
+#include "utils/wait_event.h"
 
 WalRcvData *WalRcv = NULL;
 
diff --git a/src/backend/replication/walsender.c b/src/backend/replication/walsender.c
index 2cde8ebc729..829ec538ea5 100644
--- a/src/backend/replication/walsender.c
+++ b/src/backend/replication/walsender.c
@@ -98,6 +98,7 @@
 #include "utils/ps_status.h"
 #include "utils/timeout.h"
 #include "utils/timestamp.h"
+#include "utils/wait_event.h"
 
 /* Minimum interval used by walsender for stats flushes, in ms */
 #define WALSENDER_STATS_FLUSH_INTERVAL         1000
diff --git a/src/backend/storage/buffer/bufmgr.c b/src/backend/storage/buffer/bufmgr.c
index d1babaff023..5f3d083e938 100644
--- a/src/backend/storage/buffer/bufmgr.c
+++ b/src/backend/storage/buffer/bufmgr.c
@@ -68,6 +68,7 @@
 #include "utils/rel.h"
 #include "utils/resowner.h"
 #include "utils/timestamp.h"
+#include "utils/wait_event.h"

 /* Note: these two macros only work on shared buffers, not local ones! */
diff --git a/src/backend/storage/file/buffile.c b/src/backend/storage/file/buffile.c
index ddf3a410d6f..c4afe4d368a 100644
--- a/src/backend/storage/file/buffile.c
+++ b/src/backend/storage/file/buffile.c
@@ -53,6 +53,7 @@
 #include "storage/bufmgr.h"
 #include "storage/fd.h"
 #include "utils/resowner.h"
+#include "utils/wait_event.h"
 
 /*
  * We break BufFiles into gigabyte-sized segments, regardless of RELSEG_SIZE.
diff --git a/src/backend/storage/file/copydir.c b/src/backend/storage/file/copydir.c
index 596d9070fd8..5ee141f13a5 100644
--- a/src/backend/storage/file/copydir.c
+++ b/src/backend/storage/file/copydir.c
@@ -29,6 +29,7 @@
 #include "pgstat.h"
 #include "storage/copydir.h"
 #include "storage/fd.h"
+#include "utils/wait_event.h"
 
 /* GUCs */
 int			file_copy_method = FILE_COPY_METHOD_COPY;
diff --git a/src/backend/storage/ipc/dsm_impl.c b/src/backend/storage/ipc/dsm_impl.c
index e208457df27..e8c07805f59 100644
--- a/src/backend/storage/ipc/dsm_impl.c
+++ b/src/backend/storage/ipc/dsm_impl.c
@@ -68,6 +68,7 @@
 #include "storage/fd.h"
 #include "utils/guc.h"
 #include "utils/memutils.h"
+#include "utils/wait_event.h"
 
 #ifdef USE_DSM_POSIX
 static bool dsm_impl_posix(dsm_op op, dsm_handle handle, Size request_size,
diff --git a/src/backend/storage/ipc/procarray.c b/src/backend/storage/ipc/procarray.c
index 40312df2cac..406b8253f8b 100644
--- a/src/backend/storage/ipc/procarray.c
+++ b/src/backend/storage/ipc/procarray.c
@@ -67,6 +67,7 @@
 #include "utils/lsyscache.h"
 #include "utils/rel.h"
 #include "utils/snapmgr.h"
+#include "utils/wait_event.h"
 
 #define UINT32_ACCESS_ONCE(var)		 ((uint32)(*((volatile uint32 *)&(var))))
 
diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c
index 4e32a29766c..82fc9a6b1d0 100644
--- a/src/backend/storage/ipc/procsignal.c
+++ b/src/backend/storage/ipc/procsignal.c
@@ -33,6 +33,7 @@
 #include "storage/smgr.h"
 #include "tcop/tcopprot.h"
 #include "utils/memutils.h"
+#include "utils/wait_event.h"
 
 /*
  * The SIGUSR1 signal is multiplexed to support signaling multiple event
diff --git a/src/backend/storage/ipc/shm_mq.c b/src/backend/storage/ipc/shm_mq.c
index 3ce6068ac54..ab0d4cdf063 100644
--- a/src/backend/storage/ipc/shm_mq.c
+++ b/src/backend/storage/ipc/shm_mq.c
@@ -25,6 +25,7 @@
 #include "storage/shm_mq.h"
 #include "storage/spin.h"
 #include "utils/memutils.h"
+#include "utils/wait_event.h"
 
 /*
  * This structure represents the actual queue, stored in shared memory.
diff --git a/src/backend/storage/ipc/signalfuncs.c b/src/backend/storage/ipc/signalfuncs.c
index d48b4fe3799..800b699de21 100644
--- a/src/backend/storage/ipc/signalfuncs.c
+++ b/src/backend/storage/ipc/signalfuncs.c
@@ -25,6 +25,7 @@
 #include "storage/procarray.h"
 #include "utils/acl.h"
 #include "utils/fmgrprotos.h"
+#include "utils/wait_event.h"

 /*
diff --git a/src/backend/storage/ipc/standby.c b/src/backend/storage/ipc/standby.c
index d83afbfb9d6..f3ad90c7c7a 100644
--- a/src/backend/storage/ipc/standby.c
+++ b/src/backend/storage/ipc/standby.c
@@ -35,6 +35,7 @@
 #include "utils/ps_status.h"
 #include "utils/timeout.h"
 #include "utils/timestamp.h"
+#include "utils/wait_event.h"
 
 /* User-settable GUC parameters */
 int			max_standby_archive_delay = 30 * 1000;
diff --git a/src/backend/storage/lmgr/lwlock.c b/src/backend/storage/lmgr/lwlock.c
index 517c55375b4..49382de88fc 100644
--- a/src/backend/storage/lmgr/lwlock.c
+++ b/src/backend/storage/lmgr/lwlock.c
@@ -85,6 +85,7 @@
 #include "storage/procnumber.h"
 #include "storage/spin.h"
 #include "utils/memutils.h"
+#include "utils/wait_event.h"
 
 #ifdef LWLOCK_STATS
 #include "utils/hsearch.h"
diff --git a/src/backend/storage/lmgr/predicate.c b/src/backend/storage/lmgr/predicate.c
index fe75ead3501..548b4f66470 100644
--- a/src/backend/storage/lmgr/predicate.c
+++ b/src/backend/storage/lmgr/predicate.c
@@ -214,6 +214,7 @@
 #include "utils/guc_hooks.h"
 #include "utils/rel.h"
 #include "utils/snapmgr.h"
+#include "utils/wait_event.h"
 
 /* Uncomment the next line to test the graceful degradation code. */
 /* #define TEST_SUMMARIZE_SERIAL */
diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c
index fd8318bdf3d..d8fbf50db93 100644
--- a/src/backend/storage/lmgr/proc.c
+++ b/src/backend/storage/lmgr/proc.c
@@ -53,6 +53,7 @@
 #include "storage/standby.h"
 #include "utils/timeout.h"
 #include "utils/timestamp.h"
+#include "utils/wait_event.h"
 
 /* GUC variables */
 int			DeadlockTimeout = 1000;
diff --git a/src/backend/storage/smgr/md.c b/src/backend/storage/smgr/md.c
index 443434e4ea8..dee29037b16 100644
--- a/src/backend/storage/smgr/md.c
+++ b/src/backend/storage/smgr/md.c
@@ -40,6 +40,7 @@
 #include "storage/smgr.h"
 #include "storage/sync.h"
 #include "utils/memutils.h"
+#include "utils/wait_event.h"
 
 /*
  * The magnetic disk storage manager keeps track of open file
diff --git a/src/backend/storage/sync/sync.c b/src/backend/storage/sync/sync.c
index b1accc68b95..2c964b6f3d9 100644
--- a/src/backend/storage/sync/sync.c
+++ b/src/backend/storage/sync/sync.c
@@ -31,6 +31,7 @@
 #include "storage/md.h"
 #include "utils/hsearch.h"
 #include "utils/memutils.h"
+#include "utils/wait_event.h"
 
 /*
  * In some contexts (currently, standalone backends and the checkpointer)
diff --git a/src/backend/utils/adt/misc.c b/src/backend/utils/adt/misc.c
index 32a787d7df7..864032c32bf 100644
--- a/src/backend/utils/adt/misc.c
+++ b/src/backend/utils/adt/misc.c
@@ -46,6 +46,7 @@
 #include "utils/ruleutils.h"
 #include "utils/syscache.h"
 #include "utils/timestamp.h"
+#include "utils/wait_event.h"

 /*
diff --git a/src/backend/utils/cache/relmapper.c b/src/backend/utils/cache/relmapper.c
index 778b14a2318..3aaf466868d 100644
--- a/src/backend/utils/cache/relmapper.c
+++ b/src/backend/utils/cache/relmapper.c
@@ -54,6 +54,7 @@
 #include "storage/lwlock.h"
 #include "utils/inval.h"
 #include "utils/relmapper.h"
+#include "utils/wait_event.h"

 /*
diff --git a/src/backend/utils/init/miscinit.c b/src/backend/utils/init/miscinit.c
index 03f6c8479f2..ba191977697 100644
--- a/src/backend/utils/init/miscinit.c
+++ b/src/backend/utils/init/miscinit.c
@@ -55,6 +55,7 @@
 #include "utils/pidfile.h"
 #include "utils/syscache.h"
 #include "utils/varlena.h"
+#include "utils/wait_event.h"

 #define DIRECTORY_LOCK_FILE		"postmaster.pid"
diff --git a/src/common/controldata_utils.c b/src/common/controldata_utils.c
index 14530c6489a..4ab116afcde 100644
--- a/src/common/controldata_utils.c
+++ b/src/common/controldata_utils.c
@@ -37,6 +37,7 @@
 #ifndef FRONTEND
 #include "pgstat.h"
 #include "storage/fd.h"
+#include "utils/wait_event.h"
 #endif
 
 /*
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index a2021a0e66f..d0fefb133e4 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -18,7 +18,6 @@
 #include "utils/backend_progress.h" /* for backward compatibility */	/* IWYU pragma: export */
 #include "utils/backend_status.h"	/* for backward compatibility */	/* IWYU pragma: export */
 #include "utils/pgstat_kind.h"
-#include "utils/wait_event.h"	/* for backward compatibility */	/* IWYU pragma: export */
 
 /* to avoid including access/transam.h, for FullTransactionId */
 typedef struct FullTransactionId FullTransactionId;

---

From: Amit Kapila <[email-masked]>
Date: Fri, 20 Feb 2026 10:05:04 +0530

> _so_ widely used, I think leaving the other includes there doesn't hurt

After pushing the patch for removing worker_internal.h from pgstat.h,
I tried this patch, but it failed to apply for pgstat.h. I fixed that
manually and tried to build on mac and windows. I see the following
problems.

On Windows (using meson build):
==========================
[951/2089] Compiling C object
src/backend/postgres_lib.a.p/utils_adt_pgstatfuncs.c.obj
../src/backend/utils/adt/pgstatfuncs.c(473): warning C4047: '=':
'const char *' differs in levels of indirection from 'int'
../src/backend/utils/adt/pgstatfuncs.c(474): warning C4047: '=':
'const char *' differs in levels of indirection from 'int'
../src/backend/utils/adt/pgstatfuncs.c(833): warning C4047: '=':
'const char *' differs in levels of indirection from 'int'
../src/backend/utils/adt/pgstatfuncs.c(860): warning C4047: '=':
'const char *' differs in levels of indirection from 'int'
...
...
[1472/2089] Linking target src/backend/postgres.exe
FAILED: [code=1120] src/backend/postgres.exe src/backend/postgres.pdb
"link" @src/backend/postgres.exe.rsp
   Creating library src\backend\postgres.lib
access_transam_xact.c.obj : error LNK2019: unresolved external symbol
pgstat_report_wait_end referenced in function AbortTransaction
postmaster_auxprocess.c.obj : error LNK2001: unresolved external
symbol pgstat_report_wait_end
storage_file_fd.c.obj : error LNK2001: unresolved external symbol
pgstat_report_wait_end
storage_ipc_waiteventset.c.obj : error LNK2001: unresolved external
symbol pgstat_report_wait_end
storage_file_fd.c.obj : error LNK2019: unresolved external symbol
pgstat_report_wait_start referenced in function FileReadV
storage_ipc_waiteventset.c.obj : error LNK2001: unresolved external
symbol pgstat_report_wait_start
src\backend\postgres.exe : fatal error LNK1120: 2 unresolved externals

On Mac:
=======
xact.c:2855:2: error: call to undeclared function
'pgstat_report_wait_end'; ISO C99 and later do not support implicit
function declarations [-Wimplicit-function-declaration]
 2855 |         pgstat_report_wait_end();
      |         ^
xact.c:5263:2: error: call to undeclared function
'pgstat_report_wait_end'; ISO C99 and later do not support implicit
function declarations [-Wimplicit-function-declaration]
 5263 |         pgstat_report_wait_end();
      |         ^
2 errors generated.

Do let me know if everything is good at your end, I can retry to see
if there are any dev-environment issues at my end.

-- 
With Regards,
Amit Kapila.