Hi,

On 4/20/23 3:09 AM, Michael Paquier wrote:
On Wed, Mar 29, 2023 at 02:51:27PM +0200, Drouvot, Bertrand wrote:
Just realized that more polishing was needed.

Done in V2 attached.

That would be pretty cool to get that done in an automated way, I've
wanted that for a few years now.  And I guess that a few others have
the same feeling after missing to update these docs when adding a new
wait event, or just to enforce this alphabetically, so let's do
something about it in v17.

Thanks for the feedback!

About the alphabetical order, could we have the script enforce a sort
of the elements parsed from waiteventnames.txt, based on the second
column?  This now relies on the order of the items in the file, but
my history with this stuff has proved that forcing an ordering rule
would be a very good thing long-term.

Not having the lines in order would not have been a problem for the perl script
(as it populated the hash table based on the category column while reading the
text file).

That said I do agree that enforcing an order is a good idea, as it's "easier" 
to read
the generated output files (their content is now somehow "ordered").

This is done in V3 attached.

Seeing waiteventnames.txt, I think that we should have something
closer to errcodes.txt.  Well, seeing the patch, I assume that this is
inspired by errcodes.txt, but this new file should be able to do more
IMO:
- Supporting the parsing of comments, by ignoring them in
generate-waiteventnames.pl.
- Ignore empty likes.
- Add a proper header, copyright, the output generated from it, etc.
- Document the format lines of the file.


Fully agree, it's done in V3 attached.

It is clear that the format of the file is:
- category
- C symbol in enums.
- Format in the system views.
- Description in the docs.
Or perhaps it would be better to divide this file by sections (like
errcodes.txt) for each category so as we eliminate entirely the first
column?


Yeah, that could be an option. V3 is still using the category as the first 
column
but I'm ok to change it by a section if you prefer (though I don't really see 
the need).

Perhaps waiteventnames.c should be named pgstat_wait_event.c?

Agree, done.

Similarly,
wait_event_types.h would be a better name for the set of enums?


Also agree, done.


           utils/adt/jsonpath_scan.c \
+         utils/activity/waiteventnames.c \
+         utils/activity/waiteventnames.h \
+         utils/adt/jsonpath_scan.c \

Looks like a copy-pasto.

Why do you think so? both files have to be removed.

Regards,

--
Bertrand Drouvot
PostgreSQL Contributors Team
RDS Open Source Databases
Amazon Web Services: https://aws.amazon.com
From aa359811161198d7a811113e2853e22aec10a40f Mon Sep 17 00:00:00 2001
From: Bertrand Drouvot <bertranddrouvot...@gmail.com>
Date: Sat, 22 Apr 2023 10:37:56 +0000
Subject: [PATCH v3] Generating wait_event_types.h, pgstat_wait_event.c and
 waiteventnames.sgml

Purpose is to auto-generate those files based on the newly created 
waiteventnames.txt file.

Having auto generated files would help to avoid:

- wait event without description like observed in 
https://www.postgresql.org/message-id/CA%2BhUKGJixAHc860Ej9Qzd_z96Z6aoajAgJ18bYfV3Lfn6t9%3D%2BQ%40mail.gmail.com
- orphaned wait event like observed in 
https://www.postgresql.org/message-id/CA%2BhUKGK6tqm59KuF1z%2Bh5Y8fsWcu5v8%2B84kduSHwRzwjB2aa_A%40mail.gmail.com
---
 doc/src/sgml/.gitignore                       |   1 +
 doc/src/sgml/Makefile                         |   5 +-
 doc/src/sgml/filelist.sgml                    |   1 +
 doc/src/sgml/meson.build                      |  10 +
 doc/src/sgml/monitoring.sgml                  | 792 +-----------------
 src/backend/Makefile                          |  14 +-
 src/backend/utils/activity/Makefile           |  10 +
 .../utils/activity/generate-waiteventnames.pl | 171 ++++
 src/backend/utils/activity/meson.build        |  24 +
 src/backend/utils/activity/wait_event.c       | 567 +------------
 src/backend/utils/activity/waiteventnames.txt | 188 +++++
 src/include/Makefile                          |   2 +-
 src/include/utils/.gitignore                  |   1 +
 src/include/utils/meson.build                 |  18 +
 src/include/utils/wait_event.h                | 214 +----
 src/tools/msvc/Solution.pm                    |  19 +
 src/tools/msvc/clean.bat                      |   3 +
 17 files changed, 468 insertions(+), 1572 deletions(-)
  35.9% doc/src/sgml/
  53.1% src/backend/utils/activity/
   8.6% src/include/utils/

diff --git a/doc/src/sgml/.gitignore b/doc/src/sgml/.gitignore
index d8e3dab338..e8cbd687d5 100644
--- a/doc/src/sgml/.gitignore
+++ b/doc/src/sgml/.gitignore
@@ -17,6 +17,7 @@
 /errcodes-table.sgml
 /keywords-table.sgml
 /version.sgml
+/waiteventnames.sgml
 # Assorted byproducts from building the above
 /postgres-full.xml
 /INSTALL.html
diff --git a/doc/src/sgml/Makefile b/doc/src/sgml/Makefile
index 71cbef230f..01a6aa8187 100644
--- a/doc/src/sgml/Makefile
+++ b/doc/src/sgml/Makefile
@@ -58,7 +58,7 @@ override XSLTPROCFLAGS += --stringparam pg.version 
'$(VERSION)'
 
 GENERATED_SGML = version.sgml \
        features-supported.sgml features-unsupported.sgml errcodes-table.sgml \
-       keywords-table.sgml
+       keywords-table.sgml waiteventnames.sgml
 
 ALLSGML := $(wildcard $(srcdir)/*.sgml $(srcdir)/ref/*.sgml) $(GENERATED_SGML)
 
@@ -111,6 +111,9 @@ errcodes-table.sgml: 
$(top_srcdir)/src/backend/utils/errcodes.txt generate-errco
 keywords-table.sgml: $(top_srcdir)/src/include/parser/kwlist.h $(wildcard 
$(srcdir)/keywords/sql*.txt) generate-keywords-table.pl
        $(PERL) $(srcdir)/generate-keywords-table.pl $(srcdir) > $@
 
+waiteventnames.sgml: 
$(top_srcdir)/src/backend/utils/activity/waiteventnames.txt 
$(top_srcdir)/src/backend/utils/activity/generate-waiteventnames.pl
+       $(PERL) 
$(top_srcdir)/src/backend/utils/activity/generate-waiteventnames.pl $< > $@
+       rm pgstat_wait_event.c; rm wait_event_types.h
 
 ##
 ## Generation of some text files.
diff --git a/doc/src/sgml/filelist.sgml b/doc/src/sgml/filelist.sgml
index 0d6be9a2fa..9ab235d36a 100644
--- a/doc/src/sgml/filelist.sgml
+++ b/doc/src/sgml/filelist.sgml
@@ -42,6 +42,7 @@
 <!ENTITY maintenance   SYSTEM "maintenance.sgml">
 <!ENTITY manage-ag     SYSTEM "manage-ag.sgml">
 <!ENTITY monitoring    SYSTEM "monitoring.sgml">
+<!ENTITY waiteventnames    SYSTEM "waiteventnames.sgml">
 <!ENTITY regress       SYSTEM "regress.sgml">
 <!ENTITY runtime       SYSTEM "runtime.sgml">
 <!ENTITY config        SYSTEM "config.sgml">
diff --git a/doc/src/sgml/meson.build b/doc/src/sgml/meson.build
index c6d77b5a15..53e4505b97 100644
--- a/doc/src/sgml/meson.build
+++ b/doc/src/sgml/meson.build
@@ -46,6 +46,16 @@ doc_generated += custom_target('errcodes-table.sgml',
   capture: true,
 )
 
+doc_generated += custom_target('waiteventnames.sgml',
+  input: files(
+    '../../../src/backend/utils/activity/waiteventnames.txt'),
+  output: 'waiteventnames.sgml',
+  command: [perl, 
files('../../../src/backend/utils/activity/generate-waiteventnames.pl'), 
'@INPUT@'],
+  build_by_default: false,
+  install: false,
+  capture: true,
+)
+
 # FIXME: this actually has further inputs, adding depfile support to
 # generate-keywords-table.pl is probably the best way to address that
 # robustly.
diff --git a/doc/src/sgml/monitoring.sgml b/doc/src/sgml/monitoring.sgml
index 99f7f95c39..c8648fca18 100644
--- a/doc/src/sgml/monitoring.sgml
+++ b/doc/src/sgml/monitoring.sgml
@@ -1100,74 +1100,7 @@ postgres   27093  0.0  0.0  30096  2752 ?        Ss   
11:34   0:00 postgres: ser
    </tgroup>
   </table>
 
-  <table id="wait-event-activity-table">
-   <title>Wait Events of Type <literal>Activity</literal></title>
-   <tgroup cols="2">
-    <thead>
-     <row>
-      <entry><literal>Activity</literal> Wait Event</entry>
-      <entry>Description</entry>
-     </row>
-    </thead>
-
-    <tbody>
-     <row>
-      <entry><literal>ArchiverMain</literal></entry>
-      <entry>Waiting in main loop of archiver process.</entry>
-     </row>
-     <row>
-      <entry><literal>AutoVacuumMain</literal></entry>
-      <entry>Waiting in main loop of autovacuum launcher process.</entry>
-     </row>
-     <row>
-      <entry><literal>BgWriterHibernate</literal></entry>
-      <entry>Waiting in background writer process, hibernating.</entry>
-     </row>
-     <row>
-      <entry><literal>BgWriterMain</literal></entry>
-      <entry>Waiting in main loop of background writer process.</entry>
-     </row>
-     <row>
-      <entry><literal>CheckpointerMain</literal></entry>
-      <entry>Waiting in main loop of checkpointer process.</entry>
-     </row>
-     <row>
-      <entry><literal>LogicalApplyMain</literal></entry>
-      <entry>Waiting in main loop of logical replication apply process.</entry>
-     </row>
-     <row>
-      <entry><literal>LogicalLauncherMain</literal></entry>
-      <entry>Waiting in main loop of logical replication launcher 
process.</entry>
-     </row>
-     <row>
-      <entry><literal>LogicalParallelApplyMain</literal></entry>
-      <entry>Waiting in main loop of logical replication parallel apply
-       process.</entry>
-     </row>
-     <row>
-      <entry><literal>RecoveryWalStream</literal></entry>
-      <entry>Waiting in main loop of startup process for WAL to arrive, during
-       streaming recovery.</entry>
-     </row>
-     <row>
-      <entry><literal>SysLoggerMain</literal></entry>
-      <entry>Waiting in main loop of syslogger process.</entry>
-     </row>
-     <row>
-      <entry><literal>WalReceiverMain</literal></entry>
-      <entry>Waiting in main loop of WAL receiver process.</entry>
-     </row>
-     <row>
-      <entry><literal>WalSenderMain</literal></entry>
-      <entry>Waiting in main loop of WAL sender process.</entry>
-     </row>
-     <row>
-      <entry><literal>WalWriterMain</literal></entry>
-      <entry>Waiting in main loop of WAL writer process.</entry>
-     </row>
-    </tbody>
-   </tgroup>
-  </table>
+  &waiteventnames;
 
   <table id="wait-event-bufferpin-table">
    <title>Wait Events of Type <literal>BufferPin</literal></title>
@@ -1188,56 +1121,6 @@ postgres   27093  0.0  0.0  30096  2752 ?        Ss   
11:34   0:00 postgres: ser
    </tgroup>
   </table>
 
-  <table id="wait-event-client-table">
-   <title>Wait Events of Type <literal>Client</literal></title>
-   <tgroup cols="2">
-    <thead>
-     <row>
-      <entry><literal>Client</literal> Wait Event</entry>
-      <entry>Description</entry>
-     </row>
-    </thead>
-
-    <tbody>
-     <row>
-      <entry><literal>ClientRead</literal></entry>
-      <entry>Waiting to read data from the client.</entry>
-     </row>
-     <row>
-      <entry><literal>ClientWrite</literal></entry>
-      <entry>Waiting to write data to the client.</entry>
-     </row>
-     <row>
-      <entry><literal>GSSOpenServer</literal></entry>
-      <entry>Waiting to read data from the client while establishing a GSSAPI
-       session.</entry>
-     </row>
-     <row>
-      <entry><literal>LibPQWalReceiverConnect</literal></entry>
-      <entry>Waiting in WAL receiver to establish connection to remote
-       server.</entry>
-     </row>
-     <row>
-      <entry><literal>LibPQWalReceiverReceive</literal></entry>
-      <entry>Waiting in WAL receiver to receive data from remote 
server.</entry>
-     </row>
-     <row>
-      <entry><literal>SSLOpenServer</literal></entry>
-      <entry>Waiting for SSL while attempting connection.</entry>
-     </row>
-     <row>
-      <entry><literal>WalSenderWaitForWAL</literal></entry>
-      <entry>Waiting for WAL to be flushed in WAL sender process.</entry>
-     </row>
-     <row>
-      <entry><literal>WalSenderWriteData</literal></entry>
-      <entry>Waiting for any activity when processing replies from WAL
-       receiver in WAL sender process.</entry>
-     </row>
-    </tbody>
-   </tgroup>
-  </table>
-
   <table id="wait-event-extension-table">
    <title>Wait Events of Type <literal>Extension</literal></title>
    <tgroup cols="2">
@@ -1257,623 +1140,6 @@ postgres   27093  0.0  0.0  30096  2752 ?        Ss   
11:34   0:00 postgres: ser
    </tgroup>
   </table>
 
-  <table id="wait-event-io-table">
-   <title>Wait Events of Type <literal>IO</literal></title>
-   <tgroup cols="2">
-    <thead>
-     <row>
-      <entry><literal>IO</literal> Wait Event</entry>
-      <entry>Description</entry>
-     </row>
-    </thead>
-
-    <tbody>
-     <row>
-      <entry><literal>BaseBackupRead</literal></entry>
-      <entry>Waiting for base backup to read from a file.</entry>
-     </row>
-     <row>
-      <entry><literal>BaseBackupSync</literal></entry>
-      <entry>Waiting for data written by a base backup to reach durable 
storage.</entry>
-     </row>
-     <row>
-      <entry><literal>BaseBackupWrite</literal></entry>
-      <entry>Waiting for base backup to write to a file.</entry>
-     </row>
-     <row>
-      <entry><literal>BufFileRead</literal></entry>
-      <entry>Waiting for a read from a buffered file.</entry>
-     </row>
-     <row>
-      <entry><literal>BufFileWrite</literal></entry>
-      <entry>Waiting for a write to a buffered file.</entry>
-     </row>
-     <row>
-      <entry><literal>BufFileTruncate</literal></entry>
-      <entry>Waiting for a buffered file to be truncated.</entry>
-     </row>
-     <row>
-      <entry><literal>ControlFileRead</literal></entry>
-      <entry>Waiting for a read from the <filename>pg_control</filename>
-       file.</entry>
-     </row>
-     <row>
-      <entry><literal>ControlFileSync</literal></entry>
-      <entry>Waiting for the <filename>pg_control</filename> file to reach
-       durable storage.</entry>
-     </row>
-     <row>
-      <entry><literal>ControlFileSyncUpdate</literal></entry>
-      <entry>Waiting for an update to the <filename>pg_control</filename> file
-       to reach durable storage.</entry>
-     </row>
-     <row>
-      <entry><literal>ControlFileWrite</literal></entry>
-      <entry>Waiting for a write to the <filename>pg_control</filename>
-       file.</entry>
-     </row>
-     <row>
-      <entry><literal>ControlFileWriteUpdate</literal></entry>
-      <entry>Waiting for a write to update the <filename>pg_control</filename>
-       file.</entry>
-     </row>
-     <row>
-      <entry><literal>CopyFileRead</literal></entry>
-      <entry>Waiting for a read during a file copy operation.</entry>
-     </row>
-     <row>
-      <entry><literal>CopyFileWrite</literal></entry>
-      <entry>Waiting for a write during a file copy operation.</entry>
-     </row>
-     <row>
-      <entry><literal>DSMAllocate</literal></entry>
-      <entry>Waiting for a dynamic shared memory segment to be
-       allocated.</entry>
-     </row>
-     <row>
-      <entry><literal>DSMFillZeroWrite</literal></entry>
-      <entry>Waiting to fill a dynamic shared memory backing file with
-       zeroes.</entry>
-     </row>
-     <row>
-      <entry><literal>DataFileExtend</literal></entry>
-      <entry>Waiting for a relation data file to be extended.</entry>
-     </row>
-     <row>
-      <entry><literal>DataFileFlush</literal></entry>
-      <entry>Waiting for a relation data file to reach durable storage.</entry>
-     </row>
-     <row>
-      <entry><literal>DataFileImmediateSync</literal></entry>
-      <entry>Waiting for an immediate synchronization of a relation data file 
to
-       durable storage.</entry>
-     </row>
-     <row>
-      <entry><literal>DataFilePrefetch</literal></entry>
-      <entry>Waiting for an asynchronous prefetch from a relation data
-       file.</entry>
-     </row>
-     <row>
-      <entry><literal>DataFileRead</literal></entry>
-      <entry>Waiting for a read from a relation data file.</entry>
-     </row>
-     <row>
-      <entry><literal>DataFileSync</literal></entry>
-      <entry>Waiting for changes to a relation data file to reach durable 
storage.</entry>
-     </row>
-     <row>
-      <entry><literal>DataFileTruncate</literal></entry>
-      <entry>Waiting for a relation data file to be truncated.</entry>
-     </row>
-     <row>
-      <entry><literal>DataFileWrite</literal></entry>
-      <entry>Waiting for a write to a relation data file.</entry>
-     </row>
-     <row>
-      <entry><literal>LockFileAddToDataDirRead</literal></entry>
-      <entry>Waiting for a read while adding a line to the data directory lock
-       file.</entry>
-     </row>
-     <row>
-      <entry><literal>LockFileAddToDataDirSync</literal></entry>
-      <entry>Waiting for data to reach durable storage while adding a line to 
the
-       data directory lock file.</entry>
-     </row>
-     <row>
-      <entry><literal>LockFileAddToDataDirWrite</literal></entry>
-      <entry>Waiting for a write while adding a line to the data directory
-       lock file.</entry>
-     </row>
-     <row>
-      <entry><literal>LockFileCreateRead</literal></entry>
-      <entry>Waiting to read while creating the data directory lock
-       file.</entry>
-     </row>
-     <row>
-      <entry><literal>LockFileCreateSync</literal></entry>
-      <entry>Waiting for data to reach durable storage while creating the data
-       directory lock file.</entry>
-     </row>
-     <row>
-      <entry><literal>LockFileCreateWrite</literal></entry>
-      <entry>Waiting for a write while creating the data directory lock
-       file.</entry>
-     </row>
-     <row>
-      <entry><literal>LockFileReCheckDataDirRead</literal></entry>
-      <entry>Waiting for a read during recheck of the data directory lock
-       file.</entry>
-     </row>
-     <row>
-      <entry><literal>LogicalRewriteCheckpointSync</literal></entry>
-      <entry>Waiting for logical rewrite mappings to reach durable storage
-       during a checkpoint.</entry>
-     </row>
-     <row>
-      <entry><literal>LogicalRewriteMappingSync</literal></entry>
-      <entry>Waiting for mapping data to reach durable storage during a logical
-       rewrite.</entry>
-     </row>
-     <row>
-      <entry><literal>LogicalRewriteMappingWrite</literal></entry>
-      <entry>Waiting for a write of mapping data during a logical
-       rewrite.</entry>
-     </row>
-     <row>
-      <entry><literal>LogicalRewriteSync</literal></entry>
-      <entry>Waiting for logical rewrite mappings to reach durable
-       storage.</entry>
-     </row>
-     <row>
-      <entry><literal>LogicalRewriteTruncate</literal></entry>
-      <entry>Waiting for truncate of mapping data during a logical
-       rewrite.</entry>
-     </row>
-     <row>
-      <entry><literal>LogicalRewriteWrite</literal></entry>
-      <entry>Waiting for a write of logical rewrite mappings.</entry>
-     </row>
-     <row>
-      <entry><literal>RelationMapRead</literal></entry>
-      <entry>Waiting for a read of the relation map file.</entry>
-     </row>
-     <row>
-      <entry><literal>RelationMapReplace</literal></entry>
-      <entry>Waiting for durable replacement of a relation map file.</entry>
-     </row>
-     <row>
-      <entry><literal>RelationMapWrite</literal></entry>
-      <entry>Waiting for a write to the relation map file.</entry>
-     </row>
-     <row>
-      <entry><literal>ReorderBufferRead</literal></entry>
-      <entry>Waiting for a read during reorder buffer management.</entry>
-     </row>
-     <row>
-      <entry><literal>ReorderBufferWrite</literal></entry>
-      <entry>Waiting for a write during reorder buffer management.</entry>
-     </row>
-     <row>
-      <entry><literal>ReorderLogicalMappingRead</literal></entry>
-      <entry>Waiting for a read of a logical mapping during reorder buffer
-       management.</entry>
-     </row>
-     <row>
-      <entry><literal>ReplicationSlotRead</literal></entry>
-      <entry>Waiting for a read from a replication slot control file.</entry>
-     </row>
-     <row>
-      <entry><literal>ReplicationSlotRestoreSync</literal></entry>
-      <entry>Waiting for a replication slot control file to reach durable 
storage
-       while restoring it to memory.</entry>
-     </row>
-     <row>
-      <entry><literal>ReplicationSlotSync</literal></entry>
-      <entry>Waiting for a replication slot control file to reach durable
-       storage.</entry>
-     </row>
-     <row>
-      <entry><literal>ReplicationSlotWrite</literal></entry>
-      <entry>Waiting for a write to a replication slot control file.</entry>
-     </row>
-     <row>
-      <entry><literal>SLRUFlushSync</literal></entry>
-      <entry>Waiting for SLRU data to reach durable storage during a checkpoint
-       or database shutdown.</entry>
-     </row>
-     <row>
-      <entry><literal>SLRURead</literal></entry>
-      <entry>Waiting for a read of an SLRU page.</entry>
-     </row>
-     <row>
-      <entry><literal>SLRUSync</literal></entry>
-      <entry>Waiting for SLRU data to reach durable storage following a page
-       write.</entry>
-     </row>
-     <row>
-      <entry><literal>SLRUWrite</literal></entry>
-      <entry>Waiting for a write of an SLRU page.</entry>
-     </row>
-     <row>
-      <entry><literal>SnapbuildRead</literal></entry>
-      <entry>Waiting for a read of a serialized historical catalog
-       snapshot.</entry>
-     </row>
-     <row>
-      <entry><literal>SnapbuildSync</literal></entry>
-      <entry>Waiting for a serialized historical catalog snapshot to reach
-       durable storage.</entry>
-     </row>
-     <row>
-      <entry><literal>SnapbuildWrite</literal></entry>
-      <entry>Waiting for a write of a serialized historical catalog
-       snapshot.</entry>
-     </row>
-     <row>
-      <entry><literal>TimelineHistoryFileSync</literal></entry>
-      <entry>Waiting for a timeline history file received via streaming
-       replication to reach durable storage.</entry>
-     </row>
-     <row>
-      <entry><literal>TimelineHistoryFileWrite</literal></entry>
-      <entry>Waiting for a write of a timeline history file received via
-       streaming replication.</entry>
-     </row>
-     <row>
-      <entry><literal>TimelineHistoryRead</literal></entry>
-      <entry>Waiting for a read of a timeline history file.</entry>
-     </row>
-     <row>
-      <entry><literal>TimelineHistorySync</literal></entry>
-      <entry>Waiting for a newly created timeline history file to reach durable
-       storage.</entry>
-     </row>
-     <row>
-      <entry><literal>TimelineHistoryWrite</literal></entry>
-      <entry>Waiting for a write of a newly created timeline history
-       file.</entry>
-     </row>
-     <row>
-      <entry><literal>TwophaseFileRead</literal></entry>
-      <entry>Waiting for a read of a two phase state file.</entry>
-     </row>
-     <row>
-      <entry><literal>TwophaseFileSync</literal></entry>
-      <entry>Waiting for a two phase state file to reach durable 
storage.</entry>
-     </row>
-     <row>
-      <entry><literal>TwophaseFileWrite</literal></entry>
-      <entry>Waiting for a write of a two phase state file.</entry>
-     </row>
-     <row>
-      <entry><literal>VersionFileWrite</literal></entry>
-      <entry>Waiting for the version file to be written while creating a 
database.</entry>
-     </row>
-     <row>
-      <entry><literal>WALBootstrapSync</literal></entry>
-      <entry>Waiting for WAL to reach durable storage during
-       bootstrapping.</entry>
-     </row>
-     <row>
-      <entry><literal>WALBootstrapWrite</literal></entry>
-      <entry>Waiting for a write of a WAL page during bootstrapping.</entry>
-     </row>
-     <row>
-      <entry><literal>WALCopyRead</literal></entry>
-      <entry>Waiting for a read when creating a new WAL segment by copying an
-       existing one.</entry>
-     </row>
-     <row>
-      <entry><literal>WALCopySync</literal></entry>
-      <entry>Waiting for a new WAL segment created by copying an existing one 
to
-       reach durable storage.</entry>
-     </row>
-     <row>
-      <entry><literal>WALCopyWrite</literal></entry>
-      <entry>Waiting for a write when creating a new WAL segment by copying an
-       existing one.</entry>
-     </row>
-     <row>
-      <entry><literal>WALInitSync</literal></entry>
-      <entry>Waiting for a newly initialized WAL file to reach durable
-       storage.</entry>
-     </row>
-     <row>
-      <entry><literal>WALInitWrite</literal></entry>
-      <entry>Waiting for a write while initializing a new WAL file.</entry>
-     </row>
-     <row>
-      <entry><literal>WALRead</literal></entry>
-      <entry>Waiting for a read from a WAL file.</entry>
-     </row>
-     <row>
-      <entry><literal>WALSenderTimelineHistoryRead</literal></entry>
-      <entry>Waiting for a read from a timeline history file during a walsender
-       timeline command.</entry>
-     </row>
-     <row>
-      <entry><literal>WALSync</literal></entry>
-      <entry>Waiting for a WAL file to reach durable storage.</entry>
-     </row>
-     <row>
-      <entry><literal>WALSyncMethodAssign</literal></entry>
-      <entry>Waiting for data to reach durable storage while assigning a new
-       WAL sync method.</entry>
-     </row>
-     <row>
-      <entry><literal>WALWrite</literal></entry>
-      <entry>Waiting for a write to a WAL file.</entry>
-     </row>
-    </tbody>
-   </tgroup>
-  </table>
-
-  <table id="wait-event-ipc-table">
-   <title>Wait Events of Type <literal>IPC</literal></title>
-   <tgroup cols="2">
-    <thead>
-     <row>
-      <entry><literal>IPC</literal> Wait Event</entry>
-      <entry>Description</entry>
-     </row>
-    </thead>
-
-    <tbody>
-     <row>
-      <entry><literal>AppendReady</literal></entry>
-      <entry>Waiting for subplan nodes of an <literal>Append</literal> plan
-       node to be ready.</entry>
-     </row>
-     <row>
-      <entry><literal>ArchiveCleanupCommand</literal></entry>
-      <entry>Waiting for <xref linkend="guc-archive-cleanup-command"/> to
-       complete.</entry>
-     </row>
-     <row>
-      <entry><literal>ArchiveCommand</literal></entry>
-      <entry>Waiting for <xref linkend="guc-archive-command"/> to
-       complete.</entry>
-     </row>
-     <row>
-      <entry><literal>BackendTermination</literal></entry>
-      <entry>Waiting for the termination of another backend.</entry>
-     </row>
-     <row>
-      <entry><literal>BackupWaitWalArchive</literal></entry>
-      <entry>Waiting for WAL files required for a backup to be successfully
-       archived.</entry>
-     </row>
-     <row>
-      <entry><literal>BgWorkerShutdown</literal></entry>
-      <entry>Waiting for background worker to shut down.</entry>
-     </row>
-     <row>
-      <entry><literal>BgWorkerStartup</literal></entry>
-      <entry>Waiting for background worker to start up.</entry>
-     </row>
-     <row>
-      <entry><literal>BtreePage</literal></entry>
-      <entry>Waiting for the page number needed to continue a parallel B-tree
-       scan to become available.</entry>
-     </row>
-     <row>
-      <entry><literal>BufferIO</literal></entry>
-      <entry>Waiting for buffer I/O to complete.</entry>
-     </row>
-     <row>
-      <entry><literal>CheckpointDone</literal></entry>
-      <entry>Waiting for a checkpoint to complete.</entry>
-     </row>
-     <row>
-      <entry><literal>CheckpointStart</literal></entry>
-      <entry>Waiting for a checkpoint to start.</entry>
-     </row>
-     <row>
-      <entry><literal>ExecuteGather</literal></entry>
-      <entry>Waiting for activity from a child process while
-       executing a <literal>Gather</literal> plan node.</entry>
-     </row>
-     <row>
-      <entry><literal>HashBatchAllocate</literal></entry>
-      <entry>Waiting for an elected Parallel Hash participant to allocate a 
hash
-       table.</entry>
-     </row>
-     <row>
-      <entry><literal>HashBatchElect</literal></entry>
-      <entry>Waiting to elect a Parallel Hash participant to allocate a hash
-       table.</entry>
-     </row>
-     <row>
-      <entry><literal>HashBatchLoad</literal></entry>
-      <entry>Waiting for other Parallel Hash participants to finish loading a
-       hash table.</entry>
-     </row>
-     <row>
-      <entry><literal>HashBuildAllocate</literal></entry>
-      <entry>Waiting for an elected Parallel Hash participant to allocate the
-       initial hash table.</entry>
-     </row>
-     <row>
-      <entry><literal>HashBuildElect</literal></entry>
-      <entry>Waiting to elect a Parallel Hash participant to allocate the
-       initial hash table.</entry>
-     </row>
-     <row>
-      <entry><literal>HashBuildHashInner</literal></entry>
-      <entry>Waiting for other Parallel Hash participants to finish hashing the
-       inner relation.</entry>
-     </row>
-     <row>
-      <entry><literal>HashBuildHashOuter</literal></entry>
-      <entry>Waiting for other Parallel Hash participants to finish 
partitioning
-       the outer relation.</entry>
-     </row>
-     <row>
-      <entry><literal>HashGrowBatchesDecide</literal></entry>
-      <entry>Waiting to elect a Parallel Hash participant to decide on future
-       batch growth.</entry>
-     </row>
-     <row>
-      <entry><literal>HashGrowBatchesElect</literal></entry>
-      <entry>Waiting to elect a Parallel Hash participant to allocate more
-       batches.</entry>
-     </row>
-     <row>
-      <entry><literal>HashGrowBatchesFinish</literal></entry>
-      <entry>Waiting for an elected Parallel Hash participant to decide on
-       future batch growth.</entry>
-     </row>
-     <row>
-      <entry><literal>HashGrowBatchesReallocate</literal></entry>
-      <entry>Waiting for an elected Parallel Hash participant to allocate more
-       batches.</entry>
-     </row>
-     <row>
-      <entry><literal>HashGrowBatchesRepartition</literal></entry>
-      <entry>Waiting for other Parallel Hash participants to finish
-       repartitioning.</entry>
-     </row>
-     <row>
-      <entry><literal>HashGrowBucketsElect</literal></entry>
-      <entry>Waiting to elect a Parallel Hash participant to allocate more
-       buckets.</entry>
-     </row>
-     <row>
-      <entry><literal>HashGrowBucketsReallocate</literal></entry>
-      <entry>Waiting for an elected Parallel Hash participant to finish
-       allocating more buckets.</entry>
-     </row>
-     <row>
-      <entry><literal>HashGrowBucketsReinsert</literal></entry>
-      <entry>Waiting for other Parallel Hash participants to finish inserting
-       tuples into new buckets.</entry>
-     </row>
-     <row>
-      <entry><literal>LogicalApplySendData</literal></entry>
-      <entry>Waiting for a logical replication leader apply process to send
-       data to a parallel apply process.</entry>
-     </row>
-     <row>
-      <entry><literal>LogicalParallelApplyStateChange</literal></entry>
-      <entry>Waiting for a logical replication parallel apply process to change
-       state.</entry>
-     </row>
-     <row>
-      <entry><literal>LogicalSyncData</literal></entry>
-      <entry>Waiting for a logical replication remote server to send data for
-       initial table synchronization.</entry>
-     </row>
-     <row>
-      <entry><literal>LogicalSyncStateChange</literal></entry>
-      <entry>Waiting for a logical replication remote server to change
-       state.</entry>
-     </row>
-     <row>
-      <entry><literal>MessageQueueInternal</literal></entry>
-      <entry>Waiting for another process to be attached to a shared message
-       queue.</entry>
-     </row>
-     <row>
-      <entry><literal>MessageQueuePutMessage</literal></entry>
-      <entry>Waiting to write a protocol message to a shared message 
queue.</entry>
-     </row>
-     <row>
-      <entry><literal>MessageQueueReceive</literal></entry>
-      <entry>Waiting to receive bytes from a shared message queue.</entry>
-     </row>
-     <row>
-      <entry><literal>MessageQueueSend</literal></entry>
-      <entry>Waiting to send bytes to a shared message queue.</entry>
-     </row>
-     <row>
-      <entry><literal>ParallelBitmapScan</literal></entry>
-      <entry>Waiting for parallel bitmap scan to become initialized.</entry>
-     </row>
-     <row>
-      <entry><literal>ParallelCreateIndexScan</literal></entry>
-      <entry>Waiting for parallel <command>CREATE INDEX</command> workers to
-       finish heap scan.</entry>
-     </row>
-     <row>
-      <entry><literal>ParallelFinish</literal></entry>
-      <entry>Waiting for parallel workers to finish computing.</entry>
-     </row>
-     <row>
-      <entry><literal>ProcArrayGroupUpdate</literal></entry>
-      <entry>Waiting for the group leader to clear the transaction ID at
-       end of a parallel operation.</entry>
-     </row>
-     <row>
-      <entry><literal>ProcSignalBarrier</literal></entry>
-      <entry>Waiting for a barrier event to be processed by all
-       backends.</entry>
-     </row>
-     <row>
-      <entry><literal>Promote</literal></entry>
-      <entry>Waiting for standby promotion.</entry>
-     </row>
-     <row>
-      <entry><literal>RecoveryConflictSnapshot</literal></entry>
-      <entry>Waiting for recovery conflict resolution for a vacuum
-       cleanup.</entry>
-     </row>
-     <row>
-      <entry><literal>RecoveryConflictTablespace</literal></entry>
-      <entry>Waiting for recovery conflict resolution for dropping a
-       tablespace.</entry>
-     </row>
-     <row>
-      <entry><literal>RecoveryEndCommand</literal></entry>
-      <entry>Waiting for <xref linkend="guc-recovery-end-command"/> to
-       complete.</entry>
-     </row>
-     <row>
-      <entry><literal>RecoveryPause</literal></entry>
-      <entry>Waiting for recovery to be resumed.</entry>
-     </row>
-     <row>
-      <entry><literal>ReplicationOriginDrop</literal></entry>
-      <entry>Waiting for a replication origin to become inactive so it can be
-       dropped.</entry>
-     </row>
-     <row>
-      <entry><literal>ReplicationSlotDrop</literal></entry>
-      <entry>Waiting for a replication slot to become inactive so it can be
-       dropped.</entry>
-     </row>
-     <row>
-      <entry><literal>RestoreCommand</literal></entry>
-      <entry>Waiting for <xref linkend="guc-restore-command"/> to
-       complete.</entry>
-     </row>
-     <row>
-      <entry><literal>SafeSnapshot</literal></entry>
-      <entry>Waiting to obtain a valid snapshot for a <literal>READ ONLY
-       DEFERRABLE</literal> transaction.</entry>
-     </row>
-     <row>
-      <entry><literal>SyncRep</literal></entry>
-      <entry>Waiting for confirmation from a remote server during synchronous
-       replication.</entry>
-     </row>
-     <row>
-      <entry><literal>WalReceiverExit</literal></entry>
-      <entry>Waiting for the WAL receiver to exit.</entry>
-     </row>
-     <row>
-      <entry><literal>WalReceiverWaitStart</literal></entry>
-      <entry>Waiting for startup process to send initial data for streaming
-       replication.</entry>
-     </row>
-     <row>
-      <entry><literal>XactGroupUpdate</literal></entry>
-      <entry>Waiting for the group leader to update transaction status at
-       end of a parallel operation.</entry>
-     </row>
-    </tbody>
-   </tgroup>
-  </table>
-
   <table id="wait-event-lock-table">
    <title>Wait Events of Type <literal>Lock</literal></title>
    <tgroup cols="2">
@@ -2305,62 +1571,6 @@ postgres   27093  0.0  0.0  30096  2752 ?        Ss   
11:34   0:00 postgres: ser
     </para>
    </note>
 
-  <table id="wait-event-timeout-table">
-   <title>Wait Events of Type <literal>Timeout</literal></title>
-   <tgroup cols="2">
-    <thead>
-     <row>
-      <entry><literal>Timeout</literal> Wait Event</entry>
-      <entry>Description</entry>
-     </row>
-    </thead>
-
-    <tbody>
-     <row>
-      <entry><literal>BaseBackupThrottle</literal></entry>
-      <entry>Waiting during base backup when throttling activity.</entry>
-     </row>
-     <row>
-      <entry><literal>CheckpointWriteDelay</literal></entry>
-      <entry>Waiting between writes while performing a checkpoint.</entry>
-     </row>
-     <row>
-      <entry><literal>PgSleep</literal></entry>
-      <entry>Waiting due to a call to <function>pg_sleep</function> or
-       a sibling function.</entry>
-     </row>
-     <row>
-      <entry><literal>RecoveryApplyDelay</literal></entry>
-      <entry>Waiting to apply WAL during recovery because of a delay
-       setting.</entry>
-     </row>
-     <row>
-      <entry><literal>RecoveryRetrieveRetryInterval</literal></entry>
-      <entry>Waiting during recovery when WAL data is not available from any
-       source (<filename>pg_wal</filename>, archive or stream).</entry>
-     </row>
-     <row>
-      <entry><literal>RegisterSyncRequest</literal></entry>
-      <entry>Waiting while sending synchronization requests to the
-       checkpointer, because the request queue is full.</entry>
-     </row>
-     <row>
-      <entry><literal>SpinDelay</literal></entry>
-      <entry>Waiting while acquiring a contended spinlock.</entry>
-     </row>
-     <row>
-      <entry><literal>VacuumDelay</literal></entry>
-      <entry>Waiting in a cost-based vacuum delay point.</entry>
-     </row>
-     <row>
-      <entry><literal>VacuumTruncate</literal></entry>
-      <entry>Waiting to acquire an exclusive lock to truncate off any
-       empty pages at the end of a table vacuumed.</entry>
-     </row>
-    </tbody>
-   </tgroup>
-  </table>
-
    <para>
      Here is an example of how wait events can be viewed:
 
diff --git a/src/backend/Makefile b/src/backend/Makefile
index e4bf0fe9c0..fb67f13822 100644
--- a/src/backend/Makefile
+++ b/src/backend/Makefile
@@ -134,6 +134,9 @@ parser/gram.h: parser/gram.y
 storage/lmgr/lwlocknames.h: storage/lmgr/generate-lwlocknames.pl 
storage/lmgr/lwlocknames.txt
        $(MAKE) -C storage/lmgr lwlocknames.h lwlocknames.c
 
+utils/activity/wait_event_types.h: utils/activity/generate-waiteventnames.pl 
utils/activity/waiteventnames.txt
+       $(MAKE) -C utils/activity wait_event_types.h pgstat_wait_event.c
+
 # run this unconditionally to avoid needing to know its dependencies here:
 submake-catalog-headers:
        $(MAKE) -C catalog distprep generated-header-symlinks
@@ -161,13 +164,18 @@ submake-utils-headers:
 
 .PHONY: generated-headers
 
-generated-headers: $(top_builddir)/src/include/storage/lwlocknames.h 
submake-catalog-headers submake-nodes-headers submake-utils-headers
+generated-headers: $(top_builddir)/src/include/storage/lwlocknames.h 
$(top_builddir)/src/include/utils/wait_event_types.h submake-catalog-headers 
submake-nodes-headers submake-utils-headers
 
 $(top_builddir)/src/include/storage/lwlocknames.h: storage/lmgr/lwlocknames.h
        prereqdir=`cd '$(dir $<)' >/dev/null && pwd` && \
          cd '$(dir $@)' && rm -f $(notdir $@) && \
          $(LN_S) "$$prereqdir/$(notdir $<)" .
 
+$(top_builddir)/src/include/utils/wait_event_types.h: 
utils/activity/wait_event_types.h
+       prereqdir=`cd '$(dir $<)' >/dev/null && pwd` && \
+         cd '$(dir $@)' && rm -f $(notdir $@) && \
+         $(LN_S) "$$prereqdir/$(notdir $<)" .
+
 utils/probes.o: utils/probes.d $(SUBDIROBJS)
        $(DTRACE) $(DTRACEFLAGS) -C -G -s $(call expand_subsys,$^) -o $@
 
@@ -185,6 +193,7 @@ distprep:
        $(MAKE) -C utils        distprep
        $(MAKE) -C utils/adt    jsonpath_gram.c jsonpath_gram.h jsonpath_scan.c
        $(MAKE) -C utils/misc   guc-file.c
+       $(MAKE) -C utils/actvity        wait_event_types.h pgstat_wait_event.c
 
 
 ##########################################################################
@@ -305,6 +314,9 @@ maintainer-clean: distclean
              utils/adt/jsonpath_gram.c \
              utils/adt/jsonpath_gram.h \
              utils/adt/jsonpath_scan.c \
+             utils/activity/pgstat_wait_event.c \
+             utils/activity/wait_event_types.h \
+             utils/adt/jsonpath_scan.c \
              utils/misc/guc-file.c
 
 
diff --git a/src/backend/utils/activity/Makefile 
b/src/backend/utils/activity/Makefile
index 7d7482dde0..65487da7aa 100644
--- a/src/backend/utils/activity/Makefile
+++ b/src/backend/utils/activity/Makefile
@@ -33,3 +33,13 @@ OBJS = \
        wait_event.o
 
 include $(top_srcdir)/src/backend/common.mk
+
+wait_event.o: pgstat_wait_event.c
+pgstat_wait_event.c: wait_event_types.h
+       touch $@
+
+wait_event_types.h: 
$(top_srcdir)/src/backend/utils/activity/waiteventnames.txt 
generate-waiteventnames.pl
+       $(PERL) $(srcdir)/generate-waiteventnames.pl $<
+
+maintainer-clean: clean
+       rm -f wait_event_types.h pgstat_wait_event.c
diff --git a/src/backend/utils/activity/generate-waiteventnames.pl 
b/src/backend/utils/activity/generate-waiteventnames.pl
new file mode 100644
index 0000000000..219807fe56
--- /dev/null
+++ b/src/backend/utils/activity/generate-waiteventnames.pl
@@ -0,0 +1,171 @@
+#!/usr/bin/perl
+#----------------------------------------------------------------------
+#
+# Generate wait events support files from waiteventnames.txt:
+# - wait_event_types.h
+# - pgstat_wait_event.c
+# - waiteventnames.sgml
+#
+# Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group
+# Portions Copyright (c) 1994, Regents of the University of California
+#
+# src/backend/utils/activity/generate-waiteventnames.pl
+#
+#----------------------------------------------------------------------
+
+use strict;
+use warnings;
+use Getopt::Long;
+
+my $output_path = '.';
+
+my $continue    = "\n";
+my %hashwe;
+my $waitclass;
+my @wait_classes = ("PG_WAIT_ACTIVITY", "PG_WAIT_CLIENT", "PG_WAIT_IPC", 
"PG_WAIT_TIMEOUT", "PG_WAIT_IO");
+
+GetOptions(
+       'outdir:s'       => \$output_path);
+
+open my $waiteventnames, '<', $ARGV[0] or die;
+
+# Include PID in suffix in case parallel make runs this multiple times.
+my $htmp = "$output_path/wait_event_types.h.tmp$$";
+my $ctmp = "$output_path/pgstat_wait_event.c.tmp$$";
+my $stmp = "$output_path/waiteventnames.s.tmp$$";
+open my $h, '>', $htmp or die "Could not open $htmp: $!";
+open my $c, '>', $ctmp or die "Could not open $ctmp: $!";
+open my $s, '>', $stmp or die "Could not open $stmp: $!";
+
+my $header_comment =
+  '/*-------------------------------------------------------------------------
+ *
+ * %s
+ *    Generated wait events infrastructure code
+ *
+ * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1994, Regents of the University of California
+ *
+ * NOTES
+ *  ******************************
+ *  *** DO NOT EDIT THIS FILE! ***
+ *  ******************************
+ *
+ *  It has been GENERATED by 
src/backend/utils/activity/generate-waiteventnames.pl
+ *
+ *-------------------------------------------------------------------------
+ */
+';
+
+printf $h $header_comment, 'wait_event_types.h';
+printf $h "#ifndef WAITEVENTNAMES_H\n";
+printf $h "#define WAITEVENTNAMES_H\n\n";
+printf $h "#include \"utils/wait_event.h\"\n\n";
+
+printf $c $header_comment, 'pgstat_wait_event.c';
+
+my @lines;
+my $line;
+
+# Remove comments and empty lines
+while (<$waiteventnames>)
+{
+       chomp;
+
+       # Skip comments
+       next if /^#/;
+
+       # Skip empty lines
+       next if /^\s*$/;
+
+       push(@lines, $_);
+}
+
+# Sort the lines based on the second column
+my @lines_sorted = sort { (split(/\t/, $a))[1] cmp (split(/\t/, $b))[1] } 
@lines;
+
+# Read the sorted lines and populate the hash table
+foreach $line (@lines_sorted)
+{
+       die "unable to parse waiteventnames.txt"
+         unless $line =~ /^(\w+)\t+(\w+)\t+("\w+")\t+("\w.*\.")$/;
+
+       (my $waitclassname, my $waiteventenumname, my $waiteventdescription, my 
$waitevendocsentence) = split (/\t/, $line);
+
+       my @waiteventlist = [$waiteventenumname, $waiteventdescription, 
$waitevendocsentence];
+       my $trimmedwaiteventname = $waiteventenumname;
+       $trimmedwaiteventname =~ s/^WAIT_EVENT_//;
+       die "wait event names must start with 'WAIT_EVENT_'" if 
$trimmedwaiteventname eq $waiteventenumname;
+       $continue    = ",\n";
+       push(@{ $hashwe{$waitclassname} }, @waiteventlist);
+}
+
+# Generate the output files
+foreach $waitclass (keys %hashwe) {
+       my $last = $waitclass;
+       $last =~ s/^WaitEvent//;
+       my $lastuc = uc $last;
+       my $lastlc = lc $last;
+       my $firstpass = 1;
+       my $pg_wait_class;
+
+       printf $h "typedef enum\n{\n";
+
+       printf $c "static const char *\npgstat_get_wait_$lastlc($waitclass 
w)\n{\n";
+       printf $c "\tconst char *event_name = \"unknown wait event\";\n\n";
+       printf $c "\tswitch (w)\n\t{\n";
+
+       printf $s "  <table id=\"wait-event-%s-table\">\n", $lastlc;
+       printf $s "   <title>Wait Events of Type 
<literal>%s</literal></title>\n", ucfirst($lastlc);
+       printf $s "   <tgroup cols=\"2\">\n";
+       printf $s "    <thead>\n";
+       printf $s "     <row>\n";
+       printf $s "      <entry><literal>Activity</literal> Wait 
Event</entry>\n";
+       printf $s "      <entry>Description</entry>\n";
+    printf $s "     </row>\n";
+       printf $s "    </thead>\n\n";
+       printf $s "    <tbody>\n";
+
+       foreach my $wev (@{$hashwe{$waitclass}}) {
+               if ($firstpass) {
+                       $pg_wait_class = "PG_WAIT_".$lastuc;
+                       die "waitclass $pg_wait_class does not exist" unless 
grep( /^$pg_wait_class$/, @wait_classes );
+                       printf $h "\t%s = %s", $wev->[0], $pg_wait_class;
+                       $continue = ",\n";
+               } else {
+                       printf $h "%s\t%s", $continue, $wev->[0];
+                       $continue = ",\n";
+               }
+               $firstpass = 0;
+
+               printf $c "\t\t case %s:\n", $wev->[0];
+               printf $c "\t\t\t event_name = %s;\n\t\t\t break;\n", $wev->[1];
+
+               printf $s "     <row>\n";
+               printf $s "      <entry><literal>%s</literal></entry>\n", 
substr $wev->[1], 1, -1;
+               printf $s "      <entry>%s</entry>\n", substr $wev->[2], 1, -1;
+               printf $s "     </row>\n";
+       }
+
+       printf $h "\n} $waitclass;\n\n";
+
+       printf $c "\t\t\t /* no default case, so that compiler will warn */\n";
+       printf $c "\t}\n\n";
+       printf $c "\treturn event_name;\n";
+       printf $c "\n}\n";
+
+       printf $s "    </tbody>\n";
+       printf $s "   </tgroup>\n";
+       printf $s "  </table>\n";
+}
+
+printf $h "#endif                          /* WAITEVENTNAMES_H */";
+close $h;
+close $c;
+close $s;
+
+rename($htmp, "$output_path/wait_event_types.h") || die "rename: $htmp to 
$output_path/wait_event_types.h: $!";
+rename($ctmp, "$output_path/pgstat_wait_event.c") || die "rename: $ctmp: $!";
+rename($stmp, "$output_path/waiteventnames.sgml") || die "rename: $ctmp: $!";
+
+close $waiteventnames;
diff --git a/src/backend/utils/activity/meson.build 
b/src/backend/utils/activity/meson.build
index 518ee3f798..83004c986a 100644
--- a/src/backend/utils/activity/meson.build
+++ b/src/backend/utils/activity/meson.build
@@ -1,5 +1,17 @@
 # Copyright (c) 2022-2023, PostgreSQL Global Development Group
 
+waiteventnames = custom_target('waiteventnames',
+  input: files('./waiteventnames.txt'),
+  output: ['pgstat_wait_event.c'],
+  command: [
+    perl, files('./generate-waiteventnames.pl'),
+    '-o', '@OUTDIR@',
+    '@INPUT@'
+  ],
+  install: true,
+  install_dir: [false],
+)
+
 backend_sources += files(
   'backend_progress.c',
   'backend_status.c',
@@ -17,5 +29,17 @@ backend_sources += files(
   'pgstat_subscription.c',
   'pgstat_wal.c',
   'pgstat_xact.c',
+)
+
+# these include .c files generated in ../../../include/activity, seems nicer 
to not
+# add that as an include path for the whole backend
+waitevent_sources = files(
   'wait_event.c',
 )
+
+backend_link_with += static_library('waiteventnames',
+  waitevent_sources,
+  dependencies: [backend_code],
+  include_directories: include_directories('../../../include/utils'),
+  kwargs: internal_lib_args,
+)
diff --git a/src/backend/utils/activity/wait_event.c 
b/src/backend/utils/activity/wait_event.c
index 7940d64639..4831f8a25e 100644
--- a/src/backend/utils/activity/wait_event.c
+++ b/src/backend/utils/activity/wait_event.c
@@ -196,569 +196,4 @@ pgstat_get_wait_event(uint32 wait_event_info)
        return event_name;
 }
 
-/* ----------
- * pgstat_get_wait_activity() -
- *
- * Convert WaitEventActivity to string.
- * ----------
- */
-static const char *
-pgstat_get_wait_activity(WaitEventActivity w)
-{
-       const char *event_name = "unknown wait event";
-
-       switch (w)
-       {
-               case WAIT_EVENT_ARCHIVER_MAIN:
-                       event_name = "ArchiverMain";
-                       break;
-               case WAIT_EVENT_AUTOVACUUM_MAIN:
-                       event_name = "AutoVacuumMain";
-                       break;
-               case WAIT_EVENT_BGWRITER_HIBERNATE:
-                       event_name = "BgWriterHibernate";
-                       break;
-               case WAIT_EVENT_BGWRITER_MAIN:
-                       event_name = "BgWriterMain";
-                       break;
-               case WAIT_EVENT_CHECKPOINTER_MAIN:
-                       event_name = "CheckpointerMain";
-                       break;
-               case WAIT_EVENT_LOGICAL_APPLY_MAIN:
-                       event_name = "LogicalApplyMain";
-                       break;
-               case WAIT_EVENT_LOGICAL_LAUNCHER_MAIN:
-                       event_name = "LogicalLauncherMain";
-                       break;
-               case WAIT_EVENT_LOGICAL_PARALLEL_APPLY_MAIN:
-                       event_name = "LogicalParallelApplyMain";
-                       break;
-               case WAIT_EVENT_RECOVERY_WAL_STREAM:
-                       event_name = "RecoveryWalStream";
-                       break;
-               case WAIT_EVENT_SYSLOGGER_MAIN:
-                       event_name = "SysLoggerMain";
-                       break;
-               case WAIT_EVENT_WAL_RECEIVER_MAIN:
-                       event_name = "WalReceiverMain";
-                       break;
-               case WAIT_EVENT_WAL_SENDER_MAIN:
-                       event_name = "WalSenderMain";
-                       break;
-               case WAIT_EVENT_WAL_WRITER_MAIN:
-                       event_name = "WalWriterMain";
-                       break;
-                       /* no default case, so that compiler will warn */
-       }
-
-       return event_name;
-}
-
-/* ----------
- * pgstat_get_wait_client() -
- *
- * Convert WaitEventClient to string.
- * ----------
- */
-static const char *
-pgstat_get_wait_client(WaitEventClient w)
-{
-       const char *event_name = "unknown wait event";
-
-       switch (w)
-       {
-               case WAIT_EVENT_CLIENT_READ:
-                       event_name = "ClientRead";
-                       break;
-               case WAIT_EVENT_CLIENT_WRITE:
-                       event_name = "ClientWrite";
-                       break;
-               case WAIT_EVENT_GSS_OPEN_SERVER:
-                       event_name = "GSSOpenServer";
-                       break;
-               case WAIT_EVENT_LIBPQWALRECEIVER_CONNECT:
-                       event_name = "LibPQWalReceiverConnect";
-                       break;
-               case WAIT_EVENT_LIBPQWALRECEIVER_RECEIVE:
-                       event_name = "LibPQWalReceiverReceive";
-                       break;
-               case WAIT_EVENT_SSL_OPEN_SERVER:
-                       event_name = "SSLOpenServer";
-                       break;
-               case WAIT_EVENT_WAL_SENDER_WAIT_WAL:
-                       event_name = "WalSenderWaitForWAL";
-                       break;
-               case WAIT_EVENT_WAL_SENDER_WRITE_DATA:
-                       event_name = "WalSenderWriteData";
-                       break;
-                       /* no default case, so that compiler will warn */
-       }
-
-       return event_name;
-}
-
-/* ----------
- * pgstat_get_wait_ipc() -
- *
- * Convert WaitEventIPC to string.
- * ----------
- */
-static const char *
-pgstat_get_wait_ipc(WaitEventIPC w)
-{
-       const char *event_name = "unknown wait event";
-
-       switch (w)
-       {
-               case WAIT_EVENT_APPEND_READY:
-                       event_name = "AppendReady";
-                       break;
-               case WAIT_EVENT_ARCHIVE_CLEANUP_COMMAND:
-                       event_name = "ArchiveCleanupCommand";
-                       break;
-               case WAIT_EVENT_ARCHIVE_COMMAND:
-                       event_name = "ArchiveCommand";
-                       break;
-               case WAIT_EVENT_BACKEND_TERMINATION:
-                       event_name = "BackendTermination";
-                       break;
-               case WAIT_EVENT_BACKUP_WAIT_WAL_ARCHIVE:
-                       event_name = "BackupWaitWalArchive";
-                       break;
-               case WAIT_EVENT_BGWORKER_SHUTDOWN:
-                       event_name = "BgWorkerShutdown";
-                       break;
-               case WAIT_EVENT_BGWORKER_STARTUP:
-                       event_name = "BgWorkerStartup";
-                       break;
-               case WAIT_EVENT_BTREE_PAGE:
-                       event_name = "BtreePage";
-                       break;
-               case WAIT_EVENT_BUFFER_IO:
-                       event_name = "BufferIO";
-                       break;
-               case WAIT_EVENT_CHECKPOINT_DONE:
-                       event_name = "CheckpointDone";
-                       break;
-               case WAIT_EVENT_CHECKPOINT_START:
-                       event_name = "CheckpointStart";
-                       break;
-               case WAIT_EVENT_EXECUTE_GATHER:
-                       event_name = "ExecuteGather";
-                       break;
-               case WAIT_EVENT_HASH_BATCH_ALLOCATE:
-                       event_name = "HashBatchAllocate";
-                       break;
-               case WAIT_EVENT_HASH_BATCH_ELECT:
-                       event_name = "HashBatchElect";
-                       break;
-               case WAIT_EVENT_HASH_BATCH_LOAD:
-                       event_name = "HashBatchLoad";
-                       break;
-               case WAIT_EVENT_HASH_BUILD_ALLOCATE:
-                       event_name = "HashBuildAllocate";
-                       break;
-               case WAIT_EVENT_HASH_BUILD_ELECT:
-                       event_name = "HashBuildElect";
-                       break;
-               case WAIT_EVENT_HASH_BUILD_HASH_INNER:
-                       event_name = "HashBuildHashInner";
-                       break;
-               case WAIT_EVENT_HASH_BUILD_HASH_OUTER:
-                       event_name = "HashBuildHashOuter";
-                       break;
-               case WAIT_EVENT_HASH_GROW_BATCHES_DECIDE:
-                       event_name = "HashGrowBatchesDecide";
-                       break;
-               case WAIT_EVENT_HASH_GROW_BATCHES_ELECT:
-                       event_name = "HashGrowBatchesElect";
-                       break;
-               case WAIT_EVENT_HASH_GROW_BATCHES_FINISH:
-                       event_name = "HashGrowBatchesFinish";
-                       break;
-               case WAIT_EVENT_HASH_GROW_BATCHES_REALLOCATE:
-                       event_name = "HashGrowBatchesReallocate";
-                       break;
-               case WAIT_EVENT_HASH_GROW_BATCHES_REPARTITION:
-                       event_name = "HashGrowBatchesRepartition";
-                       break;
-               case WAIT_EVENT_HASH_GROW_BUCKETS_ELECT:
-                       event_name = "HashGrowBucketsElect";
-                       break;
-               case WAIT_EVENT_HASH_GROW_BUCKETS_REALLOCATE:
-                       event_name = "HashGrowBucketsReallocate";
-                       break;
-               case WAIT_EVENT_HASH_GROW_BUCKETS_REINSERT:
-                       event_name = "HashGrowBucketsReinsert";
-                       break;
-               case WAIT_EVENT_LOGICAL_APPLY_SEND_DATA:
-                       event_name = "LogicalApplySendData";
-                       break;
-               case WAIT_EVENT_LOGICAL_PARALLEL_APPLY_STATE_CHANGE:
-                       event_name = "LogicalParallelApplyStateChange";
-                       break;
-               case WAIT_EVENT_LOGICAL_SYNC_DATA:
-                       event_name = "LogicalSyncData";
-                       break;
-               case WAIT_EVENT_LOGICAL_SYNC_STATE_CHANGE:
-                       event_name = "LogicalSyncStateChange";
-                       break;
-               case WAIT_EVENT_MQ_INTERNAL:
-                       event_name = "MessageQueueInternal";
-                       break;
-               case WAIT_EVENT_MQ_PUT_MESSAGE:
-                       event_name = "MessageQueuePutMessage";
-                       break;
-               case WAIT_EVENT_MQ_RECEIVE:
-                       event_name = "MessageQueueReceive";
-                       break;
-               case WAIT_EVENT_MQ_SEND:
-                       event_name = "MessageQueueSend";
-                       break;
-               case WAIT_EVENT_PARALLEL_BITMAP_SCAN:
-                       event_name = "ParallelBitmapScan";
-                       break;
-               case WAIT_EVENT_PARALLEL_CREATE_INDEX_SCAN:
-                       event_name = "ParallelCreateIndexScan";
-                       break;
-               case WAIT_EVENT_PARALLEL_FINISH:
-                       event_name = "ParallelFinish";
-                       break;
-               case WAIT_EVENT_PROCARRAY_GROUP_UPDATE:
-                       event_name = "ProcArrayGroupUpdate";
-                       break;
-               case WAIT_EVENT_PROC_SIGNAL_BARRIER:
-                       event_name = "ProcSignalBarrier";
-                       break;
-               case WAIT_EVENT_PROMOTE:
-                       event_name = "Promote";
-                       break;
-               case WAIT_EVENT_RECOVERY_CONFLICT_SNAPSHOT:
-                       event_name = "RecoveryConflictSnapshot";
-                       break;
-               case WAIT_EVENT_RECOVERY_CONFLICT_TABLESPACE:
-                       event_name = "RecoveryConflictTablespace";
-                       break;
-               case WAIT_EVENT_RECOVERY_END_COMMAND:
-                       event_name = "RecoveryEndCommand";
-                       break;
-               case WAIT_EVENT_RECOVERY_PAUSE:
-                       event_name = "RecoveryPause";
-                       break;
-               case WAIT_EVENT_REPLICATION_ORIGIN_DROP:
-                       event_name = "ReplicationOriginDrop";
-                       break;
-               case WAIT_EVENT_REPLICATION_SLOT_DROP:
-                       event_name = "ReplicationSlotDrop";
-                       break;
-               case WAIT_EVENT_RESTORE_COMMAND:
-                       event_name = "RestoreCommand";
-                       break;
-               case WAIT_EVENT_SAFE_SNAPSHOT:
-                       event_name = "SafeSnapshot";
-                       break;
-               case WAIT_EVENT_SYNC_REP:
-                       event_name = "SyncRep";
-                       break;
-               case WAIT_EVENT_WAL_RECEIVER_EXIT:
-                       event_name = "WalReceiverExit";
-                       break;
-               case WAIT_EVENT_WAL_RECEIVER_WAIT_START:
-                       event_name = "WalReceiverWaitStart";
-                       break;
-               case WAIT_EVENT_XACT_GROUP_UPDATE:
-                       event_name = "XactGroupUpdate";
-                       break;
-                       /* no default case, so that compiler will warn */
-       }
-
-       return event_name;
-}
-
-/* ----------
- * pgstat_get_wait_timeout() -
- *
- * Convert WaitEventTimeout to string.
- * ----------
- */
-static const char *
-pgstat_get_wait_timeout(WaitEventTimeout w)
-{
-       const char *event_name = "unknown wait event";
-
-       switch (w)
-       {
-               case WAIT_EVENT_BASE_BACKUP_THROTTLE:
-                       event_name = "BaseBackupThrottle";
-                       break;
-               case WAIT_EVENT_CHECKPOINT_WRITE_DELAY:
-                       event_name = "CheckpointWriteDelay";
-                       break;
-               case WAIT_EVENT_PG_SLEEP:
-                       event_name = "PgSleep";
-                       break;
-               case WAIT_EVENT_RECOVERY_APPLY_DELAY:
-                       event_name = "RecoveryApplyDelay";
-                       break;
-               case WAIT_EVENT_RECOVERY_RETRIEVE_RETRY_INTERVAL:
-                       event_name = "RecoveryRetrieveRetryInterval";
-                       break;
-               case WAIT_EVENT_REGISTER_SYNC_REQUEST:
-                       event_name = "RegisterSyncRequest";
-                       break;
-               case WAIT_EVENT_SPIN_DELAY:
-                       event_name = "SpinDelay";
-                       break;
-               case WAIT_EVENT_VACUUM_DELAY:
-                       event_name = "VacuumDelay";
-                       break;
-               case WAIT_EVENT_VACUUM_TRUNCATE:
-                       event_name = "VacuumTruncate";
-                       break;
-                       /* no default case, so that compiler will warn */
-       }
-
-       return event_name;
-}
-
-/* ----------
- * pgstat_get_wait_io() -
- *
- * Convert WaitEventIO to string.
- * ----------
- */
-static const char *
-pgstat_get_wait_io(WaitEventIO w)
-{
-       const char *event_name = "unknown wait event";
-
-       switch (w)
-       {
-               case WAIT_EVENT_BASEBACKUP_READ:
-                       event_name = "BaseBackupRead";
-                       break;
-               case WAIT_EVENT_BASEBACKUP_SYNC:
-                       event_name = "BaseBackupSync";
-                       break;
-               case WAIT_EVENT_BASEBACKUP_WRITE:
-                       event_name = "BaseBackupWrite";
-                       break;
-               case WAIT_EVENT_BUFFILE_READ:
-                       event_name = "BufFileRead";
-                       break;
-               case WAIT_EVENT_BUFFILE_WRITE:
-                       event_name = "BufFileWrite";
-                       break;
-               case WAIT_EVENT_BUFFILE_TRUNCATE:
-                       event_name = "BufFileTruncate";
-                       break;
-               case WAIT_EVENT_CONTROL_FILE_READ:
-                       event_name = "ControlFileRead";
-                       break;
-               case WAIT_EVENT_CONTROL_FILE_SYNC:
-                       event_name = "ControlFileSync";
-                       break;
-               case WAIT_EVENT_CONTROL_FILE_SYNC_UPDATE:
-                       event_name = "ControlFileSyncUpdate";
-                       break;
-               case WAIT_EVENT_CONTROL_FILE_WRITE:
-                       event_name = "ControlFileWrite";
-                       break;
-               case WAIT_EVENT_CONTROL_FILE_WRITE_UPDATE:
-                       event_name = "ControlFileWriteUpdate";
-                       break;
-               case WAIT_EVENT_COPY_FILE_READ:
-                       event_name = "CopyFileRead";
-                       break;
-               case WAIT_EVENT_COPY_FILE_WRITE:
-                       event_name = "CopyFileWrite";
-                       break;
-               case WAIT_EVENT_DATA_FILE_EXTEND:
-                       event_name = "DataFileExtend";
-                       break;
-               case WAIT_EVENT_DATA_FILE_FLUSH:
-                       event_name = "DataFileFlush";
-                       break;
-               case WAIT_EVENT_DATA_FILE_IMMEDIATE_SYNC:
-                       event_name = "DataFileImmediateSync";
-                       break;
-               case WAIT_EVENT_DATA_FILE_PREFETCH:
-                       event_name = "DataFilePrefetch";
-                       break;
-               case WAIT_EVENT_DATA_FILE_READ:
-                       event_name = "DataFileRead";
-                       break;
-               case WAIT_EVENT_DATA_FILE_SYNC:
-                       event_name = "DataFileSync";
-                       break;
-               case WAIT_EVENT_DATA_FILE_TRUNCATE:
-                       event_name = "DataFileTruncate";
-                       break;
-               case WAIT_EVENT_DATA_FILE_WRITE:
-                       event_name = "DataFileWrite";
-                       break;
-               case WAIT_EVENT_DSM_ALLOCATE:
-                       event_name = "DSMAllocate";
-                       break;
-               case WAIT_EVENT_DSM_FILL_ZERO_WRITE:
-                       event_name = "DSMFillZeroWrite";
-                       break;
-               case WAIT_EVENT_LOCK_FILE_ADDTODATADIR_READ:
-                       event_name = "LockFileAddToDataDirRead";
-                       break;
-               case WAIT_EVENT_LOCK_FILE_ADDTODATADIR_SYNC:
-                       event_name = "LockFileAddToDataDirSync";
-                       break;
-               case WAIT_EVENT_LOCK_FILE_ADDTODATADIR_WRITE:
-                       event_name = "LockFileAddToDataDirWrite";
-                       break;
-               case WAIT_EVENT_LOCK_FILE_CREATE_READ:
-                       event_name = "LockFileCreateRead";
-                       break;
-               case WAIT_EVENT_LOCK_FILE_CREATE_SYNC:
-                       event_name = "LockFileCreateSync";
-                       break;
-               case WAIT_EVENT_LOCK_FILE_CREATE_WRITE:
-                       event_name = "LockFileCreateWrite";
-                       break;
-               case WAIT_EVENT_LOCK_FILE_RECHECKDATADIR_READ:
-                       event_name = "LockFileReCheckDataDirRead";
-                       break;
-               case WAIT_EVENT_LOGICAL_REWRITE_CHECKPOINT_SYNC:
-                       event_name = "LogicalRewriteCheckpointSync";
-                       break;
-               case WAIT_EVENT_LOGICAL_REWRITE_MAPPING_SYNC:
-                       event_name = "LogicalRewriteMappingSync";
-                       break;
-               case WAIT_EVENT_LOGICAL_REWRITE_MAPPING_WRITE:
-                       event_name = "LogicalRewriteMappingWrite";
-                       break;
-               case WAIT_EVENT_LOGICAL_REWRITE_SYNC:
-                       event_name = "LogicalRewriteSync";
-                       break;
-               case WAIT_EVENT_LOGICAL_REWRITE_TRUNCATE:
-                       event_name = "LogicalRewriteTruncate";
-                       break;
-               case WAIT_EVENT_LOGICAL_REWRITE_WRITE:
-                       event_name = "LogicalRewriteWrite";
-                       break;
-               case WAIT_EVENT_RELATION_MAP_READ:
-                       event_name = "RelationMapRead";
-                       break;
-               case WAIT_EVENT_RELATION_MAP_REPLACE:
-                       event_name = "RelationMapReplace";
-                       break;
-               case WAIT_EVENT_RELATION_MAP_WRITE:
-                       event_name = "RelationMapWrite";
-                       break;
-               case WAIT_EVENT_REORDER_BUFFER_READ:
-                       event_name = "ReorderBufferRead";
-                       break;
-               case WAIT_EVENT_REORDER_BUFFER_WRITE:
-                       event_name = "ReorderBufferWrite";
-                       break;
-               case WAIT_EVENT_REORDER_LOGICAL_MAPPING_READ:
-                       event_name = "ReorderLogicalMappingRead";
-                       break;
-               case WAIT_EVENT_REPLICATION_SLOT_READ:
-                       event_name = "ReplicationSlotRead";
-                       break;
-               case WAIT_EVENT_REPLICATION_SLOT_RESTORE_SYNC:
-                       event_name = "ReplicationSlotRestoreSync";
-                       break;
-               case WAIT_EVENT_REPLICATION_SLOT_SYNC:
-                       event_name = "ReplicationSlotSync";
-                       break;
-               case WAIT_EVENT_REPLICATION_SLOT_WRITE:
-                       event_name = "ReplicationSlotWrite";
-                       break;
-               case WAIT_EVENT_SLRU_FLUSH_SYNC:
-                       event_name = "SLRUFlushSync";
-                       break;
-               case WAIT_EVENT_SLRU_READ:
-                       event_name = "SLRURead";
-                       break;
-               case WAIT_EVENT_SLRU_SYNC:
-                       event_name = "SLRUSync";
-                       break;
-               case WAIT_EVENT_SLRU_WRITE:
-                       event_name = "SLRUWrite";
-                       break;
-               case WAIT_EVENT_SNAPBUILD_READ:
-                       event_name = "SnapbuildRead";
-                       break;
-               case WAIT_EVENT_SNAPBUILD_SYNC:
-                       event_name = "SnapbuildSync";
-                       break;
-               case WAIT_EVENT_SNAPBUILD_WRITE:
-                       event_name = "SnapbuildWrite";
-                       break;
-               case WAIT_EVENT_TIMELINE_HISTORY_FILE_SYNC:
-                       event_name = "TimelineHistoryFileSync";
-                       break;
-               case WAIT_EVENT_TIMELINE_HISTORY_FILE_WRITE:
-                       event_name = "TimelineHistoryFileWrite";
-                       break;
-               case WAIT_EVENT_TIMELINE_HISTORY_READ:
-                       event_name = "TimelineHistoryRead";
-                       break;
-               case WAIT_EVENT_TIMELINE_HISTORY_SYNC:
-                       event_name = "TimelineHistorySync";
-                       break;
-               case WAIT_EVENT_TIMELINE_HISTORY_WRITE:
-                       event_name = "TimelineHistoryWrite";
-                       break;
-               case WAIT_EVENT_TWOPHASE_FILE_READ:
-                       event_name = "TwophaseFileRead";
-                       break;
-               case WAIT_EVENT_TWOPHASE_FILE_SYNC:
-                       event_name = "TwophaseFileSync";
-                       break;
-               case WAIT_EVENT_TWOPHASE_FILE_WRITE:
-                       event_name = "TwophaseFileWrite";
-                       break;
-               case WAIT_EVENT_VERSION_FILE_WRITE:
-                       event_name = "VersionFileWrite";
-                       break;
-               case WAIT_EVENT_WALSENDER_TIMELINE_HISTORY_READ:
-                       event_name = "WALSenderTimelineHistoryRead";
-                       break;
-               case WAIT_EVENT_WAL_BOOTSTRAP_SYNC:
-                       event_name = "WALBootstrapSync";
-                       break;
-               case WAIT_EVENT_WAL_BOOTSTRAP_WRITE:
-                       event_name = "WALBootstrapWrite";
-                       break;
-               case WAIT_EVENT_WAL_COPY_READ:
-                       event_name = "WALCopyRead";
-                       break;
-               case WAIT_EVENT_WAL_COPY_SYNC:
-                       event_name = "WALCopySync";
-                       break;
-               case WAIT_EVENT_WAL_COPY_WRITE:
-                       event_name = "WALCopyWrite";
-                       break;
-               case WAIT_EVENT_WAL_INIT_SYNC:
-                       event_name = "WALInitSync";
-                       break;
-               case WAIT_EVENT_WAL_INIT_WRITE:
-                       event_name = "WALInitWrite";
-                       break;
-               case WAIT_EVENT_WAL_READ:
-                       event_name = "WALRead";
-                       break;
-               case WAIT_EVENT_WAL_SYNC:
-                       event_name = "WALSync";
-                       break;
-               case WAIT_EVENT_WAL_SYNC_METHOD_ASSIGN:
-                       event_name = "WALSyncMethodAssign";
-                       break;
-               case WAIT_EVENT_WAL_WRITE:
-                       event_name = "WALWrite";
-                       break;
-
-                       /* no default case, so that compiler will warn */
-       }
-
-       return event_name;
-}
+#include "pgstat_wait_event.c"
diff --git a/src/backend/utils/activity/waiteventnames.txt 
b/src/backend/utils/activity/waiteventnames.txt
new file mode 100644
index 0000000000..0e56afaea7
--- /dev/null
+++ b/src/backend/utils/activity/waiteventnames.txt
@@ -0,0 +1,188 @@
+#
+# waiteventnames.txt
+#      PostgreSQL wait events
+#
+# Copyright (c) 2023, PostgreSQL Global Development Group
+#
+# This list serves as the basis for generating source files related to wait
+# events.
+#
+# The files generated from this one are:
+#
+#   src/backend/utils/activity/wait_event_types.h
+#      typedef enum definitions for wait events
+#
+#   src/backend/utils/activity/pgstat_wait_event.c
+#      c functions to get the wait event name based on the enum
+#
+#   src/backend/utils/activity/waiteventnames.sgml
+#      SGML tables of wait events for inclusion in the documentation
+#
+# The format of this file is one wait event per line, with the following
+# tab-separated fields:
+#
+#      category "C symbol in enums" "format in the system views" "description 
in the docs"
+#
+# When adding a new wait event, make sure it is placed in the appropriate
+# category.
+#
+# This file is used as input by 
src/backend/utils/activity/generate-waiteventnames.pl
+#
+
+WaitEventActivity      WAIT_EVENT_ARCHIVER_MAIN        "ArchiverMain"  
"Waiting in main loop of archiver process."
+WaitEventActivity      WAIT_EVENT_AUTOVACUUM_MAIN      "AutoVacuumMain"        
"Waiting in main loop of autovacuum launcher process."
+WaitEventActivity      WAIT_EVENT_BGWRITER_HIBERNATE   "BgWriterHibernate"     
"Waiting in background writer process, hibernating."
+WaitEventActivity      WAIT_EVENT_BGWRITER_MAIN        "BgWriterMain"  
"Waiting in main loop of background writer process."
+WaitEventActivity      WAIT_EVENT_CHECKPOINTER_MAIN    "CheckpointerMain"      
"Waiting in main loop of checkpointer process."
+WaitEventActivity      WAIT_EVENT_LOGICAL_APPLY_MAIN   "LogicalApplyMain"      
"Waiting in main loop of logical replication apply process."
+WaitEventActivity      WAIT_EVENT_LOGICAL_LAUNCHER_MAIN        
"LogicalLauncherMain"   "Waiting in main loop of logical replication launcher 
process."
+WaitEventActivity      WAIT_EVENT_LOGICAL_PARALLEL_APPLY_MAIN  
"LogicalParallelApplyMain"      "Waiting in main loop of logical replication 
parallel apply process."
+WaitEventActivity      WAIT_EVENT_RECOVERY_WAL_STREAM  "RecoveryWalStream"     
"Waiting in main loop of startup process for WAL to arrive, during streaming 
recovery."
+WaitEventActivity      WAIT_EVENT_SYSLOGGER_MAIN       "SysLoggerMain" 
"Waiting in main loop of syslogger process."
+WaitEventActivity      WAIT_EVENT_WAL_RECEIVER_MAIN    "WalReceiverMain"       
"Waiting in main loop of WAL receiver process."
+WaitEventActivity      WAIT_EVENT_WAL_SENDER_MAIN      "WalSenderMain" 
"Waiting in main loop of WAL sender process."
+WaitEventActivity      WAIT_EVENT_WAL_WRITER_MAIN      "WalWriterMain" 
"Waiting in main loop of WAL writer process."
+WaitEventClient        WAIT_EVENT_CLIENT_READ  "ClientRead"    "Waiting to 
read data from the client."
+WaitEventClient        WAIT_EVENT_CLIENT_WRITE "ClientWrite"   "Waiting to 
write data to the client."
+WaitEventClient        WAIT_EVENT_GSS_OPEN_SERVER      "GSSOpenServer" 
"Waiting to read data from the client while establishing a GSSAPI session."
+WaitEventClient        WAIT_EVENT_LIBPQWALRECEIVER_CONNECT     
"LibPQWalReceiverConnect"       "Waiting in WAL receiver to establish 
connection to remote server."
+WaitEventClient        WAIT_EVENT_LIBPQWALRECEIVER_RECEIVE     
"LibPQWalReceiverReceive"       "Waiting in WAL receiver to receive data from 
remote server."
+WaitEventClient        WAIT_EVENT_SSL_OPEN_SERVER      "SSLOpenServer" 
"Waiting for SSL while attempting connection."
+WaitEventClient        WAIT_EVENT_WAL_SENDER_WAIT_WAL  "WalSenderWaitForWAL"   
"Waiting for WAL to be flushed in WAL sender process."
+WaitEventClient        WAIT_EVENT_WAL_SENDER_WRITE_DATA        
"WalSenderWriteData"    "Waiting for any activity when processing replies from 
WAL receiver in WAL sender process."
+WaitEventIPC   WAIT_EVENT_APPEND_READY "AppendReady"   "Waiting for subplan 
nodes of an <literal>Append</literal> plan node to be ready."
+WaitEventIPC   WAIT_EVENT_ARCHIVE_CLEANUP_COMMAND      "ArchiveCleanupCommand" 
"Waiting for <xref linkend="guc-archive-cleanup-command"/> to complete."
+WaitEventIPC   WAIT_EVENT_ARCHIVE_COMMAND      "ArchiveCommand"        
"Waiting for <xref linkend="guc-archive-command"/> to complete."
+WaitEventIPC   WAIT_EVENT_BACKEND_TERMINATION  "BackendTermination"    
"Waiting for the termination of another backend."
+WaitEventIPC   WAIT_EVENT_BACKUP_WAIT_WAL_ARCHIVE      "BackupWaitWalArchive"  
"Waiting for WAL files required for a backup to be successfully archived."
+WaitEventIPC   WAIT_EVENT_BGWORKER_SHUTDOWN    "BgWorkerShutdown"      
"Waiting for background worker to shut down."
+WaitEventIPC   WAIT_EVENT_BGWORKER_STARTUP     "BgWorkerStartup"       
"Waiting for background worker to start up."
+WaitEventIPC   WAIT_EVENT_BTREE_PAGE   "BtreePage"     "Waiting for the page 
number needed to continue a parallel B-tree scan to become available."
+WaitEventIPC   WAIT_EVENT_BUFFER_IO    "BufferIO"      "Waiting for buffer I/O 
to complete."
+WaitEventIPC   WAIT_EVENT_CHECKPOINT_DONE      "CheckpointDone"        
"Waiting for a checkpoint to complete."
+WaitEventIPC   WAIT_EVENT_CHECKPOINT_START     "CheckpointStart"       
"Waiting for a checkpoint to start."
+WaitEventIPC   WAIT_EVENT_EXECUTE_GATHER       "ExecuteGather" "Waiting for 
activity from a child process while executing a <literal>Gather</literal> plan 
node."
+WaitEventIPC   WAIT_EVENT_HASH_BATCH_ALLOCATE  "HashBatchAllocate"     
"Waiting for an elected Parallel Hash participant to allocate a hash table."
+WaitEventIPC   WAIT_EVENT_HASH_BATCH_ELECT     "HashBatchElect"        
"Waiting to elect a Parallel Hash participant to allocate a hash table."
+WaitEventIPC   WAIT_EVENT_HASH_BATCH_LOAD      "HashBatchLoad" "Waiting for 
other Parallel Hash participants to finish loading a hash table."
+WaitEventIPC   WAIT_EVENT_HASH_BUILD_ALLOCATE  "HashBuildAllocate"     
"Waiting for an elected Parallel Hash participant to allocate the initial hash 
table."
+WaitEventIPC   WAIT_EVENT_HASH_BUILD_ELECT     "HashBuildElect"        
"Waiting to elect a Parallel Hash participant to allocate the initial hash 
table."
+WaitEventIPC   WAIT_EVENT_HASH_BUILD_HASH_INNER        "HashBuildHashInner"    
"Waiting for other Parallel Hash participants to finish hashing the inner 
relation."
+WaitEventIPC   WAIT_EVENT_HASH_BUILD_HASH_OUTER        "HashBuildHashOuter"    
"Waiting for other Parallel Hash participants to finish partitioning the outer 
relation."
+WaitEventIPC   WAIT_EVENT_HASH_GROW_BATCHES_DECIDE     "HashGrowBatchesDecide" 
"Waiting to elect a Parallel Hash participant to decide on future batch growth."
+WaitEventIPC   WAIT_EVENT_HASH_GROW_BATCHES_ELECT      "HashGrowBatchesElect"  
"Waiting to elect a Parallel Hash participant to allocate more batches."
+WaitEventIPC   WAIT_EVENT_HASH_GROW_BATCHES_FINISH     "HashGrowBatchesFinish" 
"Waiting for an elected Parallel Hash participant to decide on future batch 
growth."
+WaitEventIPC   WAIT_EVENT_HASH_GROW_BATCHES_REALLOCATE 
"HashGrowBatchesReallocate"     "Waiting for an elected Parallel Hash 
participant to allocate more batches."
+WaitEventIPC   WAIT_EVENT_HASH_GROW_BATCHES_REPARTITION        
"HashGrowBatchesRepartition"    "Waiting for other Parallel Hash participants 
to finish repartitioning."
+WaitEventIPC   WAIT_EVENT_HASH_GROW_BUCKETS_ELECT      "HashGrowBucketsElect"  
"Waiting to elect a Parallel Hash participant to allocate more buckets."
+WaitEventIPC   WAIT_EVENT_HASH_GROW_BUCKETS_REALLOCATE 
"HashGrowBucketsReallocate"     "Waiting for an elected Parallel Hash 
participant to finish allocating more buckets."
+WaitEventIPC   WAIT_EVENT_HASH_GROW_BUCKETS_REINSERT   
"HashGrowBucketsReinsert"       "Waiting for other Parallel Hash participants 
to finish inserting tuples into new buckets."
+WaitEventIPC   WAIT_EVENT_LOGICAL_APPLY_SEND_DATA      "LogicalApplySendData"  
"Waiting for a logical replication leader apply process to send data to a 
parallel apply process."
+WaitEventIPC   WAIT_EVENT_LOGICAL_PARALLEL_APPLY_STATE_CHANGE  
"LogicalParallelApplyStateChange"       "Waiting for a logical replication 
parallel apply process to change state."
+WaitEventIPC   WAIT_EVENT_LOGICAL_SYNC_DATA    "LogicalSyncData"       
"Waiting for a logical replication remote server to send data for initial table 
synchronization."
+WaitEventIPC   WAIT_EVENT_LOGICAL_SYNC_STATE_CHANGE    
"LogicalSyncStateChange"        "Waiting for a logical replication remote 
server to change state."
+WaitEventIPC   WAIT_EVENT_MQ_INTERNAL  "MessageQueueInternal"  "Waiting for 
another process to be attached to a shared message queue."
+WaitEventIPC   WAIT_EVENT_MQ_PUT_MESSAGE       "MessageQueuePutMessage"        
"Waiting to write a protocol message to a shared message queue."
+WaitEventIPC   WAIT_EVENT_MQ_RECEIVE   "MessageQueueReceive"   "Waiting to 
receive bytes from a shared message queue."
+WaitEventIPC   WAIT_EVENT_MQ_SEND      "MessageQueueSend"      "Waiting to 
send bytes to a shared message queue."
+WaitEventIPC   WAIT_EVENT_PARALLEL_BITMAP_SCAN "ParallelBitmapScan"    
"Waiting for parallel bitmap scan to become initialized."
+WaitEventIPC   WAIT_EVENT_PARALLEL_CREATE_INDEX_SCAN   
"ParallelCreateIndexScan"       "Waiting for parallel <command>CREATE 
INDEX</command> workers to finish heap scan."
+WaitEventIPC   WAIT_EVENT_PARALLEL_FINISH      "ParallelFinish"        
"Waiting for parallel workers to finish computing."
+WaitEventIPC   WAIT_EVENT_PROCARRAY_GROUP_UPDATE       "ProcArrayGroupUpdate"  
"Waiting for the group leader to clear the transaction ID at end of a parallel 
operation."
+WaitEventIPC   WAIT_EVENT_PROC_SIGNAL_BARRIER  "ProcSignalBarrier"     
"Waiting for a barrier event to be processed by all backends."
+WaitEventIPC   WAIT_EVENT_PROMOTE      "Promote"       "Waiting for standby 
promotion."
+WaitEventIPC   WAIT_EVENT_RECOVERY_CONFLICT_SNAPSHOT   
"RecoveryConflictSnapshot"      "Waiting for recovery conflict resolution for a 
vacuum cleanup."
+WaitEventIPC   WAIT_EVENT_RECOVERY_CONFLICT_TABLESPACE 
"RecoveryConflictTablespace"    "Waiting for recovery conflict resolution for 
dropping a tablespace."
+WaitEventIPC   WAIT_EVENT_RECOVERY_END_COMMAND "RecoveryEndCommand"    
"Waiting for <xref linkend="guc-recovery-end-command"/> to complete."
+WaitEventIPC   WAIT_EVENT_RECOVERY_PAUSE       "RecoveryPause" "Waiting for 
recovery to be resumed."
+WaitEventIPC   WAIT_EVENT_REPLICATION_ORIGIN_DROP      "ReplicationOriginDrop" 
"Waiting for a replication origin to become inactive so it can be dropped."
+WaitEventIPC   WAIT_EVENT_REPLICATION_SLOT_DROP        "ReplicationSlotDrop"   
"Waiting for a replication slot to become inactive so it can be dropped."
+WaitEventIPC   WAIT_EVENT_RESTORE_COMMAND      "RestoreCommand"        
"Waiting for <xref linkend="guc-restore-command"/> to complete."
+WaitEventIPC   WAIT_EVENT_SAFE_SNAPSHOT        "SafeSnapshot"  "Waiting to 
obtain a valid snapshot for a <literal>READ ONLY DEFERRABLE</literal> 
transaction."
+WaitEventIPC   WAIT_EVENT_SYNC_REP     "SyncRep"       "Waiting for 
confirmation from a remote server during synchronous replication. Waiting to 
read or update information about the state of synchronous replication."
+WaitEventIPC   WAIT_EVENT_WAL_RECEIVER_EXIT    "WalReceiverExit"       
"Waiting for the WAL receiver to exit."
+WaitEventIPC   WAIT_EVENT_WAL_RECEIVER_WAIT_START      "WalReceiverWaitStart"  
"Waiting for startup process to send initial data for streaming replication."
+WaitEventIPC   WAIT_EVENT_XACT_GROUP_UPDATE    "XactGroupUpdate"       
"Waiting for the group leader to update transaction status at end of a parallel 
operation."
+WaitEventTimeout       WAIT_EVENT_BASE_BACKUP_THROTTLE "BaseBackupThrottle"    
"Waiting during base backup when throttling activity."
+WaitEventTimeout       WAIT_EVENT_CHECKPOINT_WRITE_DELAY       
"CheckpointWriteDelay"  "Waiting between writes while performing a checkpoint."
+WaitEventTimeout       WAIT_EVENT_PG_SLEEP     "PgSleep"       "Waiting due to 
a call to <function>pg_sleep</function> or a sibling function."
+WaitEventTimeout       WAIT_EVENT_RECOVERY_APPLY_DELAY "RecoveryApplyDelay"    
"Waiting to apply WAL during recovery because of a delay setting."
+WaitEventTimeout       WAIT_EVENT_RECOVERY_RETRIEVE_RETRY_INTERVAL     
"RecoveryRetrieveRetryInterval" "Waiting during recovery when WAL data is not 
available from any source (<filename>pg_wal</filename>, archive or stream)."
+WaitEventTimeout       WAIT_EVENT_REGISTER_SYNC_REQUEST        
"RegisterSyncRequest"   "Waiting while sending synchronization requests to the 
checkpointer, because the request queue is full."
+WaitEventTimeout       WAIT_EVENT_SPIN_DELAY   "SpinDelay"     "Waiting while 
acquiring a contended spinlock."
+WaitEventTimeout       WAIT_EVENT_VACUUM_DELAY "VacuumDelay"   "Waiting in a 
cost-based vacuum delay point."
+WaitEventTimeout       WAIT_EVENT_VACUUM_TRUNCATE      "VacuumTruncate"        
"Waiting to acquire an exclusive lock to truncate off any empty pages at the 
end of a table vacuumed."
+WaitEventIO    WAIT_EVENT_BASEBACKUP_READ      "BaseBackupRead"        
"Waiting for base backup to read from a file."
+WaitEventIO    WAIT_EVENT_BASEBACKUP_SYNC      "BaseBackupSync"        
"Waiting for data written by a base backup to reach durable storage."
+WaitEventIO    WAIT_EVENT_BASEBACKUP_WRITE     "BaseBackupWrite"       
"Waiting for base backup to write to a file."
+WaitEventIO    WAIT_EVENT_BUFFILE_READ "BufFileRead"   "Waiting for a read 
from a buffered file."
+WaitEventIO    WAIT_EVENT_BUFFILE_WRITE        "BufFileWrite"  "Waiting for a 
write to a buffered file."
+WaitEventIO    WAIT_EVENT_BUFFILE_TRUNCATE     "BufFileTruncate"       
"Waiting for a buffered file to be truncated."
+WaitEventIO    WAIT_EVENT_CONTROL_FILE_READ    "ControlFileRead"       
"Waiting for a read from the <filename>pg_control</filename> file."
+WaitEventIO    WAIT_EVENT_CONTROL_FILE_SYNC    "ControlFileSync"       
"Waiting for the <filename>pg_control</filename> file to reach durable storage. 
Waiting for an update to the <filename>pg_control</filename> file to reach 
durable storage."
+WaitEventIO    WAIT_EVENT_CONTROL_FILE_SYNC_UPDATE     "ControlFileSyncUpdate" 
"Waiting for an update to the <filename>pg_control</filename> file to reach 
durable storage."
+WaitEventIO    WAIT_EVENT_CONTROL_FILE_WRITE   "ControlFileWrite"      
"Waiting for a write to the <filename>pg_control</filename> file. Waiting for a 
write to update the <filename>pg_control</filename> file."
+WaitEventIO    WAIT_EVENT_CONTROL_FILE_WRITE_UPDATE    
"ControlFileWriteUpdate"        "Waiting for a write to update the 
<filename>pg_control</filename> file."
+WaitEventIO    WAIT_EVENT_COPY_FILE_READ       "CopyFileRead"  "Waiting for a 
read during a file copy operation."
+WaitEventIO    WAIT_EVENT_COPY_FILE_WRITE      "CopyFileWrite" "Waiting for a 
write during a file copy operation."
+WaitEventIO    WAIT_EVENT_DATA_FILE_EXTEND     "DataFileExtend"        
"Waiting for a relation data file to be extended."
+WaitEventIO    WAIT_EVENT_DATA_FILE_FLUSH      "DataFileFlush" "Waiting for a 
relation data file to reach durable storage."
+WaitEventIO    WAIT_EVENT_DATA_FILE_IMMEDIATE_SYNC     "DataFileImmediateSync" 
"Waiting for an immediate synchronization of a relation data file to durable 
storage."
+WaitEventIO    WAIT_EVENT_DATA_FILE_PREFETCH   "DataFilePrefetch"      
"Waiting for an asynchronous prefetch from a relation data file."
+WaitEventIO    WAIT_EVENT_DATA_FILE_READ       "DataFileRead"  "Waiting for a 
read from a relation data file."
+WaitEventIO    WAIT_EVENT_DATA_FILE_SYNC       "DataFileSync"  "Waiting for 
changes to a relation data file to reach durable storage."
+WaitEventIO    WAIT_EVENT_DATA_FILE_TRUNCATE   "DataFileTruncate"      
"Waiting for a relation data file to be truncated."
+WaitEventIO    WAIT_EVENT_DATA_FILE_WRITE      "DataFileWrite" "Waiting for a 
write to a relation data file."
+WaitEventIO    WAIT_EVENT_DSM_ALLOCATE "DSMAllocate"   "Waiting for a dynamic 
shared memory segment to be allocated."
+WaitEventIO    WAIT_EVENT_DSM_FILL_ZERO_WRITE  "DSMFillZeroWrite"      
"Waiting to fill a dynamic shared memory backing file with zeroes."
+WaitEventIO    WAIT_EVENT_LOCK_FILE_ADDTODATADIR_READ  
"LockFileAddToDataDirRead"      "Waiting for a read while adding a line to the 
data directory lock file."
+WaitEventIO    WAIT_EVENT_LOCK_FILE_ADDTODATADIR_SYNC  
"LockFileAddToDataDirSync"      "Waiting for data to reach durable storage 
while adding a line to the data directory lock file."
+WaitEventIO    WAIT_EVENT_LOCK_FILE_ADDTODATADIR_WRITE 
"LockFileAddToDataDirWrite"     "Waiting for a write while adding a line to the 
data directory lock file."
+WaitEventIO    WAIT_EVENT_LOCK_FILE_CREATE_READ        "LockFileCreateRead"    
"Waiting to read while creating the data directory lock file."
+WaitEventIO    WAIT_EVENT_LOCK_FILE_CREATE_SYNC        "LockFileCreateSync"    
"Waiting for data to reach durable storage while creating the data directory 
lock file."
+WaitEventIO    WAIT_EVENT_LOCK_FILE_CREATE_WRITE       "LockFileCreateWrite"   
"Waiting for a write while creating the data directory lock file."
+WaitEventIO    WAIT_EVENT_LOCK_FILE_RECHECKDATADIR_READ        
"LockFileReCheckDataDirRead"    "Waiting for a read during recheck of the data 
directory lock file."
+WaitEventIO    WAIT_EVENT_LOGICAL_REWRITE_CHECKPOINT_SYNC      
"LogicalRewriteCheckpointSync"  "Waiting for logical rewrite mappings to reach 
durable storage during a checkpoint."
+WaitEventIO    WAIT_EVENT_LOGICAL_REWRITE_MAPPING_SYNC 
"LogicalRewriteMappingSync"     "Waiting for mapping data to reach durable 
storage during a logical rewrite."
+WaitEventIO    WAIT_EVENT_LOGICAL_REWRITE_MAPPING_WRITE        
"LogicalRewriteMappingWrite"    "Waiting for a write of mapping data during a 
logical rewrite."
+WaitEventIO    WAIT_EVENT_LOGICAL_REWRITE_SYNC "LogicalRewriteSync"    
"Waiting for logical rewrite mappings to reach durable storage."
+WaitEventIO    WAIT_EVENT_LOGICAL_REWRITE_TRUNCATE     
"LogicalRewriteTruncate"        "Waiting for truncate of mapping data during a 
logical rewrite."
+WaitEventIO    WAIT_EVENT_LOGICAL_REWRITE_WRITE        "LogicalRewriteWrite"   
"Waiting for a write of logical rewrite mappings."
+WaitEventIO    WAIT_EVENT_RELATION_MAP_READ    "RelationMapRead"       
"Waiting for a read of the relation map file."
+WaitEventIO    WAIT_EVENT_RELATION_MAP_REPLACE "RelationMapReplace"    
"Waiting for durable replacement of a relation map file."
+WaitEventIO    WAIT_EVENT_RELATION_MAP_WRITE   "RelationMapWrite"      
"Waiting for a write to the relation map file."
+WaitEventIO    WAIT_EVENT_REORDER_BUFFER_READ  "ReorderBufferRead"     
"Waiting for a read during reorder buffer management."
+WaitEventIO    WAIT_EVENT_REORDER_BUFFER_WRITE "ReorderBufferWrite"    
"Waiting for a write during reorder buffer management."
+WaitEventIO    WAIT_EVENT_REORDER_LOGICAL_MAPPING_READ 
"ReorderLogicalMappingRead"     "Waiting for a read of a logical mapping during 
reorder buffer management."
+WaitEventIO    WAIT_EVENT_REPLICATION_SLOT_READ        "ReplicationSlotRead"   
"Waiting for a read from a replication slot control file."
+WaitEventIO    WAIT_EVENT_REPLICATION_SLOT_RESTORE_SYNC        
"ReplicationSlotRestoreSync"    "Waiting for a replication slot control file to 
reach durable storage while restoring it to memory."
+WaitEventIO    WAIT_EVENT_REPLICATION_SLOT_SYNC        "ReplicationSlotSync"   
"Waiting for a replication slot control file to reach durable storage."
+WaitEventIO    WAIT_EVENT_REPLICATION_SLOT_WRITE       "ReplicationSlotWrite"  
"Waiting for a write to a replication slot control file."
+WaitEventIO    WAIT_EVENT_SLRU_FLUSH_SYNC      "SLRUFlushSync" "Waiting for 
SLRU data to reach durable storage during a checkpoint or database shutdown."
+WaitEventIO    WAIT_EVENT_SLRU_READ    "SLRURead"      "Waiting for a read of 
an SLRU page."
+WaitEventIO    WAIT_EVENT_SLRU_SYNC    "SLRUSync"      "Waiting for SLRU data 
to reach durable storage following a page write."
+WaitEventIO    WAIT_EVENT_SLRU_WRITE   "SLRUWrite"     "Waiting for a write of 
an SLRU page."
+WaitEventIO    WAIT_EVENT_SNAPBUILD_READ       "SnapbuildRead" "Waiting for a 
read of a serialized historical catalog snapshot."
+WaitEventIO    WAIT_EVENT_SNAPBUILD_SYNC       "SnapbuildSync" "Waiting for a 
serialized historical catalog snapshot to reach durable storage."
+WaitEventIO    WAIT_EVENT_SNAPBUILD_WRITE      "SnapbuildWrite"        
"Waiting for a write of a serialized historical catalog snapshot."
+WaitEventIO    WAIT_EVENT_TIMELINE_HISTORY_FILE_SYNC   
"TimelineHistoryFileSync"       "Waiting for a timeline history file received 
via streaming replication to reach durable storage."
+WaitEventIO    WAIT_EVENT_TIMELINE_HISTORY_FILE_WRITE  
"TimelineHistoryFileWrite"      "Waiting for a write of a timeline history file 
received via streaming replication."
+WaitEventIO    WAIT_EVENT_TIMELINE_HISTORY_READ        "TimelineHistoryRead"   
"Waiting for a read of a timeline history file."
+WaitEventIO    WAIT_EVENT_TIMELINE_HISTORY_SYNC        "TimelineHistorySync"   
"Waiting for a newly created timeline history file to reach durable storage."
+WaitEventIO    WAIT_EVENT_TIMELINE_HISTORY_WRITE       "TimelineHistoryWrite"  
"Waiting for a write of a newly created timeline history file."
+WaitEventIO    WAIT_EVENT_TWOPHASE_FILE_READ   "TwophaseFileRead"      
"Waiting for a read of a two phase state file."
+WaitEventIO    WAIT_EVENT_TWOPHASE_FILE_SYNC   "TwophaseFileSync"      
"Waiting for a two phase state file to reach durable storage."
+WaitEventIO    WAIT_EVENT_TWOPHASE_FILE_WRITE  "TwophaseFileWrite"     
"Waiting for a write of a two phase state file."
+WaitEventIO    WAIT_EVENT_VERSION_FILE_WRITE   "VersionFileWrite"      
"Waiting for the version file to be written while creating a database."
+WaitEventIO    WAIT_EVENT_WALSENDER_TIMELINE_HISTORY_READ      
"WALSenderTimelineHistoryRead"  "Waiting for a read from a timeline history 
file during a walsender timeline command."
+WaitEventIO    WAIT_EVENT_WAL_BOOTSTRAP_SYNC   "WALBootstrapSync"      
"Waiting for WAL to reach durable storage during bootstrapping."
+WaitEventIO    WAIT_EVENT_WAL_BOOTSTRAP_WRITE  "WALBootstrapWrite"     
"Waiting for a write of a WAL page during bootstrapping."
+WaitEventIO    WAIT_EVENT_WAL_COPY_READ        "WALCopyRead"   "Waiting for a 
read when creating a new WAL segment by copying an existing one."
+WaitEventIO    WAIT_EVENT_WAL_COPY_SYNC        "WALCopySync"   "Waiting for a 
new WAL segment created by copying an existing one to reach durable storage."
+WaitEventIO    WAIT_EVENT_WAL_COPY_WRITE       "WALCopyWrite"  "Waiting for a 
write when creating a new WAL segment by copying an existing one."
+WaitEventIO    WAIT_EVENT_WAL_INIT_SYNC        "WALInitSync"   "Waiting for a 
newly initialized WAL file to reach durable storage."
+WaitEventIO    WAIT_EVENT_WAL_INIT_WRITE       "WALInitWrite"  "Waiting for a 
write while initializing a new WAL file."
+WaitEventIO    WAIT_EVENT_WAL_READ     "WALRead"       "Waiting for a read 
from a WAL file."
+WaitEventIO    WAIT_EVENT_WAL_SYNC     "WALSync"       "Waiting for a WAL file 
to reach durable storage. Waiting for data to reach durable storage while 
assigning a new WAL sync method."
+WaitEventIO    WAIT_EVENT_WAL_SYNC_METHOD_ASSIGN       "WALSyncMethodAssign"   
"Waiting for data to reach durable storage while assigning a new WAL sync 
method."
+WaitEventIO    WAIT_EVENT_WAL_WRITE    "WALWrite"      "Waiting for a write to 
a WAL file. Waiting for WAL buffers to be written to disk."
diff --git a/src/include/Makefile b/src/include/Makefile
index 56576dcf5c..5d213187e2 100644
--- a/src/include/Makefile
+++ b/src/include/Makefile
@@ -72,7 +72,7 @@ uninstall:
 
 clean:
        rm -f utils/fmgroids.h utils/fmgrprotos.h utils/errcodes.h 
utils/header-stamp
-       rm -f storage/lwlocknames.h utils/probes.h
+       rm -f storage/lwlocknames.h utils/probes.h utils/wait_event_types.h
        rm -f catalog/schemapg.h catalog/system_fk_info.h
        rm -f catalog/pg_*_d.h catalog/header-stamp
        rm -f nodes/nodetags.h nodes/header-stamp
diff --git a/src/include/utils/.gitignore b/src/include/utils/.gitignore
index 05cfa7a8d6..c1b4c66213 100644
--- a/src/include/utils/.gitignore
+++ b/src/include/utils/.gitignore
@@ -3,3 +3,4 @@
 /probes.h
 /errcodes.h
 /header-stamp
+/wait_event_types.h
diff --git a/src/include/utils/meson.build b/src/include/utils/meson.build
index 2fed1e3f8e..a1d2d81404 100644
--- a/src/include/utils/meson.build
+++ b/src/include/utils/meson.build
@@ -1,5 +1,21 @@
 # Copyright (c) 2022-2023, PostgreSQL Global Development Group
 
+waiteventnames = custom_target('waiteventnames',
+  input: files('../../backend/utils/activity/waiteventnames.txt'),
+  output: ['wait_event_types.h'],
+  command: [
+    perl, files('../../backend/utils/activity/generate-waiteventnames.pl'),
+    '-o', '@OUTDIR@',
+    '@INPUT@'
+  ],
+  build_by_default: true,
+  install: true,
+  install_dir: [dir_include_server / 'utils'],
+)
+
+wait_event_types_h = waiteventnames[0]
+generated_backend_headers += wait_event_types_h
+
 errcodes = custom_target('errcodes',
   input: files('../../backend/utils/errcodes.txt'),
   output: ['errcodes.h'],
@@ -57,3 +73,5 @@ generated_sources_ac += {
   'src/backend/utils': fmgrtab_output + ['errcodes.h', 'probes.h', 
'fmgr-stamp'],
   'src/include/utils': ['header-stamp'],
 }
+
+generated_sources_ac += {'src/backend/utils/activity': ['wait_event_types.h']}
diff --git a/src/include/utils/wait_event.h b/src/include/utils/wait_event.h
index 518d3b0a1f..160227972e 100644
--- a/src/include/utils/wait_event.h
+++ b/src/include/utils/wait_event.h
@@ -25,218 +25,8 @@
 #define PG_WAIT_TIMEOUT                                0x09000000U
 #define PG_WAIT_IO                                     0x0A000000U
 
-/* ----------
- * Wait Events - Activity
- *
- * Use this category when a process is waiting because it has no work to do,
- * unless the "Client" or "Timeout" category describes the situation better.
- * Typically, this should only be used for background processes.
- * ----------
- */
-typedef enum
-{
-       WAIT_EVENT_ARCHIVER_MAIN = PG_WAIT_ACTIVITY,
-       WAIT_EVENT_AUTOVACUUM_MAIN,
-       WAIT_EVENT_BGWRITER_HIBERNATE,
-       WAIT_EVENT_BGWRITER_MAIN,
-       WAIT_EVENT_CHECKPOINTER_MAIN,
-       WAIT_EVENT_LOGICAL_APPLY_MAIN,
-       WAIT_EVENT_LOGICAL_LAUNCHER_MAIN,
-       WAIT_EVENT_LOGICAL_PARALLEL_APPLY_MAIN,
-       WAIT_EVENT_RECOVERY_WAL_STREAM,
-       WAIT_EVENT_SYSLOGGER_MAIN,
-       WAIT_EVENT_WAL_RECEIVER_MAIN,
-       WAIT_EVENT_WAL_SENDER_MAIN,
-       WAIT_EVENT_WAL_WRITER_MAIN
-} WaitEventActivity;
-
-/* ----------
- * Wait Events - Client
- *
- * Use this category when a process is waiting to send data to or receive data
- * from the frontend process to which it is connected.  This is never used for
- * a background process, which has no client connection.
- * ----------
- */
-typedef enum
-{
-       WAIT_EVENT_CLIENT_READ = PG_WAIT_CLIENT,
-       WAIT_EVENT_CLIENT_WRITE,
-       WAIT_EVENT_GSS_OPEN_SERVER,
-       WAIT_EVENT_LIBPQWALRECEIVER_CONNECT,
-       WAIT_EVENT_LIBPQWALRECEIVER_RECEIVE,
-       WAIT_EVENT_SSL_OPEN_SERVER,
-       WAIT_EVENT_WAL_SENDER_WAIT_WAL,
-       WAIT_EVENT_WAL_SENDER_WRITE_DATA,
-} WaitEventClient;
-
-/* ----------
- * Wait Events - IPC
- *
- * Use this category when a process cannot complete the work it is doing 
because
- * it is waiting for a notification from another process.
- * ----------
- */
-typedef enum
-{
-       WAIT_EVENT_APPEND_READY = PG_WAIT_IPC,
-       WAIT_EVENT_ARCHIVE_CLEANUP_COMMAND,
-       WAIT_EVENT_ARCHIVE_COMMAND,
-       WAIT_EVENT_BACKEND_TERMINATION,
-       WAIT_EVENT_BACKUP_WAIT_WAL_ARCHIVE,
-       WAIT_EVENT_BGWORKER_SHUTDOWN,
-       WAIT_EVENT_BGWORKER_STARTUP,
-       WAIT_EVENT_BTREE_PAGE,
-       WAIT_EVENT_BUFFER_IO,
-       WAIT_EVENT_CHECKPOINT_DONE,
-       WAIT_EVENT_CHECKPOINT_START,
-       WAIT_EVENT_EXECUTE_GATHER,
-       WAIT_EVENT_HASH_BATCH_ALLOCATE,
-       WAIT_EVENT_HASH_BATCH_ELECT,
-       WAIT_EVENT_HASH_BATCH_LOAD,
-       WAIT_EVENT_HASH_BUILD_ALLOCATE,
-       WAIT_EVENT_HASH_BUILD_ELECT,
-       WAIT_EVENT_HASH_BUILD_HASH_INNER,
-       WAIT_EVENT_HASH_BUILD_HASH_OUTER,
-       WAIT_EVENT_HASH_GROW_BATCHES_DECIDE,
-       WAIT_EVENT_HASH_GROW_BATCHES_ELECT,
-       WAIT_EVENT_HASH_GROW_BATCHES_FINISH,
-       WAIT_EVENT_HASH_GROW_BATCHES_REALLOCATE,
-       WAIT_EVENT_HASH_GROW_BATCHES_REPARTITION,
-       WAIT_EVENT_HASH_GROW_BUCKETS_ELECT,
-       WAIT_EVENT_HASH_GROW_BUCKETS_REALLOCATE,
-       WAIT_EVENT_HASH_GROW_BUCKETS_REINSERT,
-       WAIT_EVENT_LOGICAL_APPLY_SEND_DATA,
-       WAIT_EVENT_LOGICAL_PARALLEL_APPLY_STATE_CHANGE,
-       WAIT_EVENT_LOGICAL_SYNC_DATA,
-       WAIT_EVENT_LOGICAL_SYNC_STATE_CHANGE,
-       WAIT_EVENT_MQ_INTERNAL,
-       WAIT_EVENT_MQ_PUT_MESSAGE,
-       WAIT_EVENT_MQ_RECEIVE,
-       WAIT_EVENT_MQ_SEND,
-       WAIT_EVENT_PARALLEL_BITMAP_SCAN,
-       WAIT_EVENT_PARALLEL_CREATE_INDEX_SCAN,
-       WAIT_EVENT_PARALLEL_FINISH,
-       WAIT_EVENT_PROCARRAY_GROUP_UPDATE,
-       WAIT_EVENT_PROC_SIGNAL_BARRIER,
-       WAIT_EVENT_PROMOTE,
-       WAIT_EVENT_RECOVERY_CONFLICT_SNAPSHOT,
-       WAIT_EVENT_RECOVERY_CONFLICT_TABLESPACE,
-       WAIT_EVENT_RECOVERY_END_COMMAND,
-       WAIT_EVENT_RECOVERY_PAUSE,
-       WAIT_EVENT_REPLICATION_ORIGIN_DROP,
-       WAIT_EVENT_REPLICATION_SLOT_DROP,
-       WAIT_EVENT_RESTORE_COMMAND,
-       WAIT_EVENT_SAFE_SNAPSHOT,
-       WAIT_EVENT_SYNC_REP,
-       WAIT_EVENT_WAL_RECEIVER_EXIT,
-       WAIT_EVENT_WAL_RECEIVER_WAIT_START,
-       WAIT_EVENT_XACT_GROUP_UPDATE
-} WaitEventIPC;
-
-/* ----------
- * Wait Events - Timeout
- *
- * Use this category when a process is waiting for a timeout to expire.
- * ----------
- */
-typedef enum
-{
-       WAIT_EVENT_BASE_BACKUP_THROTTLE = PG_WAIT_TIMEOUT,
-       WAIT_EVENT_CHECKPOINT_WRITE_DELAY,
-       WAIT_EVENT_PG_SLEEP,
-       WAIT_EVENT_RECOVERY_APPLY_DELAY,
-       WAIT_EVENT_RECOVERY_RETRIEVE_RETRY_INTERVAL,
-       WAIT_EVENT_REGISTER_SYNC_REQUEST,
-       WAIT_EVENT_SPIN_DELAY,
-       WAIT_EVENT_VACUUM_DELAY,
-       WAIT_EVENT_VACUUM_TRUNCATE
-} WaitEventTimeout;
-
-/* ----------
- * Wait Events - IO
- *
- * Use this category when a process is waiting for a IO.
- * ----------
- */
-typedef enum
-{
-       WAIT_EVENT_BASEBACKUP_READ = PG_WAIT_IO,
-       WAIT_EVENT_BASEBACKUP_SYNC,
-       WAIT_EVENT_BASEBACKUP_WRITE,
-       WAIT_EVENT_BUFFILE_READ,
-       WAIT_EVENT_BUFFILE_WRITE,
-       WAIT_EVENT_BUFFILE_TRUNCATE,
-       WAIT_EVENT_CONTROL_FILE_READ,
-       WAIT_EVENT_CONTROL_FILE_SYNC,
-       WAIT_EVENT_CONTROL_FILE_SYNC_UPDATE,
-       WAIT_EVENT_CONTROL_FILE_WRITE,
-       WAIT_EVENT_CONTROL_FILE_WRITE_UPDATE,
-       WAIT_EVENT_COPY_FILE_READ,
-       WAIT_EVENT_COPY_FILE_WRITE,
-       WAIT_EVENT_DATA_FILE_EXTEND,
-       WAIT_EVENT_DATA_FILE_FLUSH,
-       WAIT_EVENT_DATA_FILE_IMMEDIATE_SYNC,
-       WAIT_EVENT_DATA_FILE_PREFETCH,
-       WAIT_EVENT_DATA_FILE_READ,
-       WAIT_EVENT_DATA_FILE_SYNC,
-       WAIT_EVENT_DATA_FILE_TRUNCATE,
-       WAIT_EVENT_DATA_FILE_WRITE,
-       WAIT_EVENT_DSM_ALLOCATE,
-       WAIT_EVENT_DSM_FILL_ZERO_WRITE,
-       WAIT_EVENT_LOCK_FILE_ADDTODATADIR_READ,
-       WAIT_EVENT_LOCK_FILE_ADDTODATADIR_SYNC,
-       WAIT_EVENT_LOCK_FILE_ADDTODATADIR_WRITE,
-       WAIT_EVENT_LOCK_FILE_CREATE_READ,
-       WAIT_EVENT_LOCK_FILE_CREATE_SYNC,
-       WAIT_EVENT_LOCK_FILE_CREATE_WRITE,
-       WAIT_EVENT_LOCK_FILE_RECHECKDATADIR_READ,
-       WAIT_EVENT_LOGICAL_REWRITE_CHECKPOINT_SYNC,
-       WAIT_EVENT_LOGICAL_REWRITE_MAPPING_SYNC,
-       WAIT_EVENT_LOGICAL_REWRITE_MAPPING_WRITE,
-       WAIT_EVENT_LOGICAL_REWRITE_SYNC,
-       WAIT_EVENT_LOGICAL_REWRITE_TRUNCATE,
-       WAIT_EVENT_LOGICAL_REWRITE_WRITE,
-       WAIT_EVENT_RELATION_MAP_READ,
-       WAIT_EVENT_RELATION_MAP_REPLACE,
-       WAIT_EVENT_RELATION_MAP_WRITE,
-       WAIT_EVENT_REORDER_BUFFER_READ,
-       WAIT_EVENT_REORDER_BUFFER_WRITE,
-       WAIT_EVENT_REORDER_LOGICAL_MAPPING_READ,
-       WAIT_EVENT_REPLICATION_SLOT_READ,
-       WAIT_EVENT_REPLICATION_SLOT_RESTORE_SYNC,
-       WAIT_EVENT_REPLICATION_SLOT_SYNC,
-       WAIT_EVENT_REPLICATION_SLOT_WRITE,
-       WAIT_EVENT_SLRU_FLUSH_SYNC,
-       WAIT_EVENT_SLRU_READ,
-       WAIT_EVENT_SLRU_SYNC,
-       WAIT_EVENT_SLRU_WRITE,
-       WAIT_EVENT_SNAPBUILD_READ,
-       WAIT_EVENT_SNAPBUILD_SYNC,
-       WAIT_EVENT_SNAPBUILD_WRITE,
-       WAIT_EVENT_TIMELINE_HISTORY_FILE_SYNC,
-       WAIT_EVENT_TIMELINE_HISTORY_FILE_WRITE,
-       WAIT_EVENT_TIMELINE_HISTORY_READ,
-       WAIT_EVENT_TIMELINE_HISTORY_SYNC,
-       WAIT_EVENT_TIMELINE_HISTORY_WRITE,
-       WAIT_EVENT_TWOPHASE_FILE_READ,
-       WAIT_EVENT_TWOPHASE_FILE_SYNC,
-       WAIT_EVENT_TWOPHASE_FILE_WRITE,
-       WAIT_EVENT_VERSION_FILE_WRITE,
-       WAIT_EVENT_WALSENDER_TIMELINE_HISTORY_READ,
-       WAIT_EVENT_WAL_BOOTSTRAP_SYNC,
-       WAIT_EVENT_WAL_BOOTSTRAP_WRITE,
-       WAIT_EVENT_WAL_COPY_READ,
-       WAIT_EVENT_WAL_COPY_SYNC,
-       WAIT_EVENT_WAL_COPY_WRITE,
-       WAIT_EVENT_WAL_INIT_SYNC,
-       WAIT_EVENT_WAL_INIT_WRITE,
-       WAIT_EVENT_WAL_READ,
-       WAIT_EVENT_WAL_SYNC,
-       WAIT_EVENT_WAL_SYNC_METHOD_ASSIGN,
-       WAIT_EVENT_WAL_WRITE
-} WaitEventIO;
-
+/* enums for wait events */
+#include "utils/wait_event_types.h"
 
 extern const char *pgstat_get_wait_event(uint32 wait_event_info);
 extern const char *pgstat_get_wait_event_type(uint32 wait_event_info);
diff --git a/src/tools/msvc/Solution.pm b/src/tools/msvc/Solution.pm
index ef10cda576..784d2f518d 100644
--- a/src/tools/msvc/Solution.pm
+++ b/src/tools/msvc/Solution.pm
@@ -582,6 +582,7 @@ sub GenerateFiles
                my $lmgr = 'src/backend/storage/lmgr';
                system("perl $lmgr/generate-lwlocknames.pl --outdir $lmgr 
$lmgr/lwlocknames.txt");
        }
+
        if (IsNewer(
                        'src/include/storage/lwlocknames.h',
                        'src/backend/storage/lmgr/lwlocknames.h'))
@@ -591,6 +592,24 @@ sub GenerateFiles
                        'src/include/storage/lwlocknames.h');
        }
 
+       if (IsNewer(
+                       'src/include/utils/wait_event_types.h',
+                       'src/backend/utils/activity/waiteventnames.txt'))
+       {
+               print "Generating pgstat_wait_event.c and 
wait_event_types.h...\n";
+               my $activ = 'src/backend/utils/activity';
+               system("perl $activ/generate-waiteventnames.pl --outdir $activ 
$activ/waiteventnames.txt");
+       }
+
+       if (IsNewer(
+                       'src/include/utils/wait_event_types.h',
+                       'src/backend/utils/activity/wait_event_types.h'))
+       {
+               copyFile(
+                       'src/backend/utils/activity/wait_event_types.h',
+                       'src/include/utils/wait_event_types.h');
+       }
+
        if (IsNewer('src/include/utils/probes.h', 'src/backend/utils/probes.d'))
        {
                print "Generating probes.h...\n";
diff --git a/src/tools/msvc/clean.bat b/src/tools/msvc/clean.bat
index d0e8bfbf86..22d6f52e72 100755
--- a/src/tools/msvc/clean.bat
+++ b/src/tools/msvc/clean.bat
@@ -47,6 +47,7 @@ if exist src\include\utils\errcodes.h del /q 
src\include\utils\errcodes.h
 if exist src\include\utils\fmgroids.h del /q src\include\utils\fmgroids.h
 if exist src\include\utils\fmgrprotos.h del /q src\include\utils\fmgrprotos.h
 if exist src\include\storage\lwlocknames.h del /q 
src\include\storage\lwlocknames.h
+if exist src\include\utils\wait_event_types.h del /q 
src\include\utils\wait_event_types.h
 if exist src\include\utils\probes.h del /q src\include\utils\probes.h
 if exist src\include\catalog\schemapg.h del /q src\include\catalog\schemapg.h
 if exist src\include\catalog\system_fk_info.h del /q 
src\include\catalog\system_fk_info.h
@@ -61,7 +62,9 @@ if %DIST%==1 if exist src\backend\utils\fmgr-stamp del /q 
src\backend\utils\fmgr
 if %DIST%==1 if exist src\backend\utils\errcodes.h del /q 
src\backend\utils\errcodes.h
 if %DIST%==1 if exist src\backend\nodes\nodetags.h del /q 
src\backend\nodes\nodetags.h
 if %DIST%==1 if exist src\backend\storage\lmgr\lwlocknames.c del /q 
src\backend\storage\lmgr\lwlocknames.c
+if %DIST%==1 if exist src\backend\utils\activity\pgstat_wait_event.c del /q 
src\backend\utils\activity\pgstat_wait_event.c
 if %DIST%==1 if exist src\backend\storage\lmgr\lwlocknames.h del /q 
src\backend\storage\lmgr\lwlocknames.h
+if %DIST%==1 if exist src\backend\utils\activity\wait_event_types.h del /q 
src\backend\utils\activity\wait_event_types.h
 if %DIST%==1 if exist src\pl\plpython\spiexceptions.h del /q 
src\pl\plpython\spiexceptions.h
 if %DIST%==1 if exist src\pl\plpgsql\src\plerrcodes.h del /q 
src\pl\plpgsql\src\plerrcodes.h
 if %DIST%==1 if exist src\pl\tcl\pltclerrcodes.h del /q 
src\pl\tcl\pltclerrcodes.h
-- 
2.34.1

Reply via email to