Hi,

On 8/17/23 9:37 AM, Masahiro Ikeda wrote:
Hi,

On 2023-08-17 14:53, Drouvot, Bertrand wrote:

The followings are additional comments for v7.

1)

I am not sure that "pg_wait_event" is a good idea for the name if the
new view.  How about "pg_wait_events" instead, in plural form?  There
is more than one wait event listed.
I'd prefer the singular form. There is a lot of places where it's already used
(pg_database, pg_user, pg_namespace...to name a few) and it looks like that 
using
the plural form are exceptions.

Since I got the same feeling as Michael-san that "pg_wait_events" would be 
better,
I check the names of all system views. I think the singular form seems to be
exceptions for views though the singular form is used usually for system 
catalogs.

https://www.postgresql.org/docs/devel/views.html
https://www.postgresql.org/docs/devel/catalogs.html

Okay, using the plural form in v8 attached.


2)

$ctmp must be $wctmp?

+    rename($wctmp, "$output_path/wait_event_funcs_data.c")
+      || die "rename: $ctmp to $output_path/wait_event_funcs_data.c: $!";


Nice catch, thanks, fixed in v8.


3)

"List all the wait events type, name and descriptions" is enough?

+ * List all the wait events (type, name) and their descriptions.


Agree, used "List all the wait events type, name and description" in v8
(using description in singular as compared to your proposal)

4)

Why don't you add the usage of the view in the monitoring.sgml?

```
    <para>
      Here is an example of how wait events can be viewed:

<programlisting>
SELECT pid, wait_event_type, wait_event FROM pg_stat_activity WHERE wait_event 
is NOT NULL;
  pid  | wait_event_type | wait_event
------+-----------------+------------
  2540 | Lock            | relation
  6644 | LWLock          | ProcArray
(2 rows)
</programlisting>
    </para>
```

ex.
postgres(3789417)=# SELECT a.pid, a.wait_event_type, a.wait_event, 
w.description FROM pg_stat_activity a JOIN pg_wait_event w ON 
(a.wait_event_type = w.type AND a.wait_event = w.name) WHERE wait_event is NOT 
NULL;

Agree, I think that's a good idea.

I'd prefer to add also a filtering on "state='active'" for this example (I 
think that would provide
a "real" use case as the sessions are not waiting if they are not active).

Done in v8.

5)

Though I'm not familiar the value, do we need procost?


I think it makes sense to add a "small" one as it's done.
BTW, while looking at it, I changed prorows to a more "accurate"
value.


Regards,

--
Bertrand Drouvot
PostgreSQL Contributors Team
RDS Open Source Databases
Amazon Web Services: https://aws.amazon.com
From 027a83d37d52eee52e3c82bcf814c6d5949f7ccf Mon Sep 17 00:00:00 2001
From: bdrouvotAWS <bdrou...@amazon.com>
Date: Sat, 5 Aug 2023 12:39:42 +0000
Subject: [PATCH v8] Add catalog pg_wait_events

Adding a new system view, namely pg_wait_events, that describes the wait
events.
---
 doc/src/sgml/monitoring.sgml                  | 13 ++-
 doc/src/sgml/system-views.sgml                | 64 +++++++++++++
 src/backend/Makefile                          |  3 +-
 src/backend/catalog/system_views.sql          |  3 +
 src/backend/utils/activity/.gitignore         |  1 +
 src/backend/utils/activity/Makefile           |  8 +-
 .../activity/generate-wait_event_types.pl     | 54 ++++++++++-
 src/backend/utils/activity/meson.build        |  1 +
 src/backend/utils/activity/wait_event.c       | 44 +++++++++
 src/backend/utils/activity/wait_event_funcs.c | 93 +++++++++++++++++++
 src/include/catalog/pg_proc.dat               |  6 ++
 src/include/utils/meson.build                 |  4 +-
 src/include/utils/wait_event.h                |  1 +
 .../modules/worker_spi/t/001_worker_spi.pl    |  6 ++
 src/test/regress/expected/rules.out           |  4 +
 src/test/regress/expected/sysviews.out        | 16 ++++
 src/test/regress/sql/sysviews.sql             |  4 +
 src/tools/msvc/Solution.pm                    |  3 +-
 src/tools/msvc/clean.bat                      |  1 +
 19 files changed, 318 insertions(+), 11 deletions(-)
 create mode 100644 src/backend/utils/activity/wait_event_funcs.c

diff --git a/doc/src/sgml/monitoring.sgml b/doc/src/sgml/monitoring.sgml
index 70511a2388..bfa658f7a8 100644
--- a/doc/src/sgml/monitoring.sgml
+++ b/doc/src/sgml/monitoring.sgml
@@ -1103,7 +1103,7 @@ postgres   27093  0.0  0.0  30096  2752 ?        Ss   
11:34   0:00 postgres: ser
   &wait_event_types;
 
    <para>
-     Here is an example of how wait events can be viewed:
+     Here is are examples of how wait events can be viewed:
 
 <programlisting>
 SELECT pid, wait_event_type, wait_event FROM pg_stat_activity WHERE wait_event 
is NOT NULL;
@@ -1112,6 +1112,17 @@ SELECT pid, wait_event_type, wait_event FROM 
pg_stat_activity WHERE wait_event i
  2540 | Lock            | relation
  6644 | LWLock          | ProcArray
 (2 rows)
+</programlisting>
+
+<programlisting>
+SELECT a.pid, a.wait_event, w.description
+FROM pg_stat_activity a JOIN pg_wait_events w
+ON (a.wait_event_type = w.type AND a.wait_event = w.name)
+WHERE wait_event is NOT NULL and a.state = 'active';
+-[ RECORD 1 ]------------------------------------------------------------------
+pid         | 686674
+wait_event  | WALInitSync
+description | Waiting for a newly initialized WAL file to reach durable storage
 </programlisting>
    </para>
 
diff --git a/doc/src/sgml/system-views.sgml b/doc/src/sgml/system-views.sgml
index 57b228076e..2b35c2f91b 100644
--- a/doc/src/sgml/system-views.sgml
+++ b/doc/src/sgml/system-views.sgml
@@ -221,6 +221,11 @@
       <entry>views</entry>
      </row>
 
+     <row>
+      <entry><link 
linkend="view-pg-wait-events"><structname>pg_wait_events</structname></link></entry>
+      <entry>wait events</entry>
+     </row>
+
     </tbody>
    </tgroup>
   </table>
@@ -4825,4 +4830,63 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx
   </table>
  </sect1>
 
+
+ <sect1 id="view-pg-wait-events">
+  <title><structname>pg_wait_events</structname></title>
+
+  <indexterm zone="view-pg-wait-events">
+   <primary>pg_wait_events</primary>
+  </indexterm>
+
+  <para>
+   The view <structname>pg_wait_events</structname> provides description about 
the
+   wait events.
+  </para>
+
+  <table>
+   <title><structname>pg_wait_events</structname> Columns</title>
+   <tgroup cols="1">
+    <thead>
+     <row>
+      <entry role="catalog_table_entry"><para role="column_definition">
+       Column Type
+      </para>
+      <para>
+       Description
+      </para></entry>
+     </row>
+    </thead>
+
+    <tbody>
+     <row>
+      <entry role="catalog_table_entry"><para role="column_definition">
+       <structfield>type</structfield> <type>text</type>
+      </para>
+      <para>
+       Wait event type
+      </para></entry>
+     </row>
+
+     <row>
+      <entry role="catalog_table_entry"><para role="column_definition">
+       <structfield>name</structfield> <type>text</type>
+      </para>
+      <para>
+       Wait event name
+      </para></entry>
+     </row>
+
+     <row>
+      <entry role="catalog_table_entry"><para role="column_definition">
+       <structfield>description</structfield> <type>text</type>
+      </para>
+      <para>
+       Wait event description
+      </para></entry>
+     </row>
+    </tbody>
+   </tgroup>
+  </table>
+ </sect1>
+
 </chapter>
diff --git a/src/backend/Makefile b/src/backend/Makefile
index 1c929383c4..3e275ac759 100644
--- a/src/backend/Makefile
+++ b/src/backend/Makefile
@@ -134,7 +134,7 @@ storage/lmgr/lwlocknames.h: 
storage/lmgr/generate-lwlocknames.pl storage/lmgr/lw
        $(MAKE) -C storage/lmgr lwlocknames.h lwlocknames.c
 
 utils/activity/wait_event_types.h: utils/activity/generate-wait_event_types.pl 
utils/activity/wait_event_names.txt
-       $(MAKE) -C utils/activity wait_event_types.h pgstat_wait_event.c
+       $(MAKE) -C utils/activity wait_event_types.h pgstat_wait_event.c 
wait_event_funcs_data.c
 
 # run this unconditionally to avoid needing to know its dependencies here:
 submake-catalog-headers:
@@ -311,6 +311,7 @@ maintainer-clean: distclean
              storage/lmgr/lwlocknames.c \
              storage/lmgr/lwlocknames.h \
              utils/activity/pgstat_wait_event.c \
+             utils/activity/wait_event_funcs_data.c \
              utils/activity/wait_event_types.h \
              utils/adt/jsonpath_gram.c \
              utils/adt/jsonpath_gram.h \
diff --git a/src/backend/catalog/system_views.sql 
b/src/backend/catalog/system_views.sql
index af65af6bdd..362b1ea8d5 100644
--- a/src/backend/catalog/system_views.sql
+++ b/src/backend/catalog/system_views.sql
@@ -1342,3 +1342,6 @@ CREATE VIEW pg_stat_subscription_stats AS
         ss.stats_reset
     FROM pg_subscription as s,
          pg_stat_get_subscription_stats(s.oid) as ss;
+
+CREATE VIEW pg_wait_events AS
+    SELECT * FROM pg_get_wait_events() AS we;
diff --git a/src/backend/utils/activity/.gitignore 
b/src/backend/utils/activity/.gitignore
index d77079285b..bd0c0c7772 100644
--- a/src/backend/utils/activity/.gitignore
+++ b/src/backend/utils/activity/.gitignore
@@ -1,2 +1,3 @@
 /pgstat_wait_event.c
 /wait_event_types.h
+/wait_event_funcs_data.c
diff --git a/src/backend/utils/activity/Makefile 
b/src/backend/utils/activity/Makefile
index f1117745d4..f57cf3958c 100644
--- a/src/backend/utils/activity/Makefile
+++ b/src/backend/utils/activity/Makefile
@@ -32,10 +32,14 @@ OBJS = \
        pgstat_subscription.o \
        pgstat_wal.o \
        pgstat_xact.o \
-       wait_event.o
+       wait_event.o \
+       wait_event_funcs.o
 
 include $(top_srcdir)/src/backend/common.mk
 
+wait_event_funcs.o: wait_event_funcs_data.c
+wait_event_funcs_data.c: wait_event_types.h
+
 wait_event.o: pgstat_wait_event.c
 pgstat_wait_event.c: wait_event_types.h
        touch $@
@@ -44,4 +48,4 @@ wait_event_types.h: 
$(top_srcdir)/src/backend/utils/activity/wait_event_names.tx
        $(PERL) $(srcdir)/generate-wait_event_types.pl --code $<
 
 maintainer-clean: clean
-       rm -f wait_event_types.h pgstat_wait_event.c
+       rm -f wait_event_types.h pgstat_wait_event.c wait_event_funcs_data.c
diff --git a/src/backend/utils/activity/generate-wait_event_types.pl 
b/src/backend/utils/activity/generate-wait_event_types.pl
index 56335e8730..9c4557d903 100644
--- a/src/backend/utils/activity/generate-wait_event_types.pl
+++ b/src/backend/utils/activity/generate-wait_event_types.pl
@@ -4,6 +4,7 @@
 # Generate wait events support files from wait_event_names.txt:
 # - wait_event_types.h (if --code is passed)
 # - pgstat_wait_event.c (if --code is passed)
+# - wait_event_funcs_data.c (if --code is passed)
 # - wait_event_types.sgml (if --docs is passed)
 #
 # Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group
@@ -98,8 +99,10 @@ if ($gen_code)
        # multiple times.
        my $htmp = "$output_path/wait_event_types.h.tmp$$";
        my $ctmp = "$output_path/pgstat_wait_event.c.tmp$$";
+       my $wctmp = "$output_path/wait_event_funcs_data.c.tmp$$";
        open my $h, '>', $htmp or die "Could not open $htmp: $!";
        open my $c, '>', $ctmp or die "Could not open $ctmp: $!";
+       open my $wc, '>', $wctmp or die "Could not open $wctmp: $!";
 
        my $header_comment =
          
'/*-------------------------------------------------------------------------
@@ -129,12 +132,14 @@ if ($gen_code)
 
        printf $c $header_comment, 'pgstat_wait_event.c';
 
+       printf $wc $header_comment, 'wait_event_funcs_data.c';
+
+       # Generate the pgstat_wait_event.c and wait_event_types.h files
        # uc() is being used to force the comparison to be case-insensitive.
        foreach my $waitclass (sort { uc($a) cmp uc($b) } keys %hashwe)
        {
-
-               # Don't generate .c and .h files for Extension, LWLock and
-               # Lock, these are handled independently.
+               # Don't generate the pgstat_wait_event.c and wait_event_types.h 
files
+               # for Extension, LWLock and Lock, these are handled 
independently.
                next
                  if ( $waitclass eq 'WaitEventExtension'
                        || $waitclass eq 'WaitEventLWLock'
@@ -183,14 +188,55 @@ if ($gen_code)
                printf $c "}\n\n";
        }
 
+       # Generate wait_event_funcs_data.c, for the contents of static C
+       # structure holding all the information about the wait events.
+       # uc() is being used to force the comparison to be case-insensitive,
+       # even though it is not strictly mandatory here.
+       foreach my $waitclass (sort { uc($a) cmp uc($b) } keys %hashwe)
+       {
+               my $last = $waitclass;
+               $last =~ s/^WaitEvent//;
+
+               foreach my $wev (@{ $hashwe{$waitclass} })
+               {
+                       my $new_desc = substr $wev->[2], 1, -2;
+                       # Escape single quotes.
+                       $new_desc =~ s/'/\\'/g;
+
+                       # Replace the "quote" markups by real ones.
+                       $new_desc =~ s/<quote>(.*?)<\/quote>/\\"$1\\"/g;
+
+                       # Remove SGML markups.
+                       $new_desc =~ s/<.*?>(.*?)<.*?>/$1/g;
+
+                       # Tweak contents about links <xref linkend="text"/> on 
GUCs,
+                       while (my ($capture) =
+                               $new_desc =~ m/<xref linkend="guc-(.*?)"\/>/g)
+                       {
+                               $capture =~ s/-/_/g;
+                               $new_desc =~ s/<xref 
linkend="guc-.*?"\/>/$capture/g;
+                       }
+                       # Then remove any reference to "see <xref 
linkend="text"/>".
+                       $new_desc =~ s/; see.*$//;
+
+                       # One element to the C structure holding the wait event
+                       # info, as of (type, name, description).
+                       printf $wc "\t{\"%s\", \"%s\", \"%s\"},\n", $last, 
$wev->[1],
+                         $new_desc;
+               }
+       }
+
        printf $h "#endif                          /* WAIT_EVENT_TYPES_H */\n";
        close $h;
        close $c;
+       close $wc;
 
        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 to $output_path/pgstat_wait_event.c: $!";
+       rename($wctmp, "$output_path/wait_event_funcs_data.c")
+         || die "rename: $wctmp to $output_path/wait_event_funcs_data.c: $!";
 }
 # Generate the .sgml file.
 elsif ($gen_docs)
@@ -249,7 +295,7 @@ Usage: perl  [--output <path>] [--code ] [ --sgml ] 
input_file
 
 Options:
     --outdir         Output directory (default '.')
-    --code           Generate wait_event_types.h and pgstat_wait_event.c.
+    --code           Generate C and header files.
     --sgml           Generate wait_event_types.sgml.
 
 generate-wait_event_types.pl generates the SGML documentation and code
diff --git a/src/backend/utils/activity/meson.build 
b/src/backend/utils/activity/meson.build
index 9633f3623c..46a27e7548 100644
--- a/src/backend/utils/activity/meson.build
+++ b/src/backend/utils/activity/meson.build
@@ -23,6 +23,7 @@ backend_sources += files(
 # seems nicer to not add that as an include path for the whole backend.
 waitevent_sources = files(
   'wait_event.c',
+  'wait_event_funcs.c',
 )
 
 wait_event = static_library('wait_event_names',
diff --git a/src/backend/utils/activity/wait_event.c 
b/src/backend/utils/activity/wait_event.c
index 4b9b5c01cb..d31767df80 100644
--- a/src/backend/utils/activity/wait_event.c
+++ b/src/backend/utils/activity/wait_event.c
@@ -264,6 +264,50 @@ GetWaitEventExtensionIdentifier(uint16 eventId)
 }
 
 
+/*
+ * Returns a list of currently defined custom wait event names for extensions.
+ * The result is a palloc'd array, with the number of elements returned into
+ * *nwaitevents.
+ */
+char **
+GetWaitEventExtensionNames(int *nwaitevents)
+{
+       char      **waiteventnames;
+       WaitEventExtensionEntryByName *hentry;
+       HASH_SEQ_STATUS hash_seq;
+       int                     index;
+       int                     els;
+
+       LWLockAcquire(WaitEventExtensionLock, LW_SHARED);
+
+       /* Now we can safely count the number of entries */
+       els = hash_get_num_entries(WaitEventExtensionHashByName);
+
+       /* Allocate enough space for all entries */
+       waiteventnames = palloc(els * sizeof(char[NAMEDATALEN]));
+
+       /* Now scan the hash table to copy the data */
+       hash_seq_init(&hash_seq, WaitEventExtensionHashByName);
+
+       index = 0;
+       while ((hentry = (WaitEventExtensionEntryByName *) 
hash_seq_search(&hash_seq)) != NULL)
+       {
+
+               waiteventnames[index] = palloc(sizeof(char[NAMEDATALEN]));
+               strlcpy(waiteventnames[index], hentry->wait_event_name,
+                               sizeof(char[NAMEDATALEN]));
+
+               index++;
+       }
+
+       LWLockRelease(WaitEventExtensionLock);
+
+       Assert(index == els);
+
+       *nwaitevents = index;
+       return waiteventnames;
+}
+
 /*
  * Configure wait event reporting to report wait events to *wait_event_info.
  * *wait_event_info needs to be valid until pgstat_reset_wait_event_storage()
diff --git a/src/backend/utils/activity/wait_event_funcs.c 
b/src/backend/utils/activity/wait_event_funcs.c
new file mode 100644
index 0000000000..06992f04a9
--- /dev/null
+++ b/src/backend/utils/activity/wait_event_funcs.c
@@ -0,0 +1,93 @@
+/*------------------------------------------------------------------------
+ *
+ * wait_event_funcs.c
+ *       Functions for accessing wait event data.
+ *
+ * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1994, Regents of the University of California
+ *
+ *
+ * IDENTIFICATION
+ *       src/backend/utils/activity/wait_event_funcs.c
+ *
+ *------------------------------------------------------------------------
+ */
+#include "postgres.h"
+
+#include "funcapi.h"
+#include "utils/builtins.h"
+#include "utils/wait_event.h"
+
+/*
+ * Each wait event has one corresponding entry in this structure, fed to
+ * the SQL function of this file.
+ */
+static const struct
+{
+       const char *type;
+       const char *name;
+       const char *description;
+}
+
+waitEventData[] =
+{
+#include "wait_event_funcs_data.c"
+       /* end of list */
+       {NULL, NULL, NULL}
+};
+
+
+/*
+ * pg_get_wait_events
+ *
+ * List all the wait events type, name and description.
+ */
+Datum
+pg_get_wait_events(PG_FUNCTION_ARGS)
+{
+#define PG_GET_WAIT_EVENTS_COLS 3
+       ReturnSetInfo *rsinfo = (ReturnSetInfo *) fcinfo->resultinfo;
+       char      **waiteventnames;
+       int                     nbextwaitevents;
+
+       /* Build tuplestore to hold the result rows */
+       InitMaterializedSRF(fcinfo, 0);
+
+       /* Iterate over the list of wait events */
+       for (int idx = 0; waitEventData[idx].type != NULL; idx++)
+       {
+               Datum           values[PG_GET_WAIT_EVENTS_COLS] = {0};
+               bool            nulls[PG_GET_WAIT_EVENTS_COLS] = {0};
+
+               values[0] = CStringGetTextDatum(waitEventData[idx].type);
+               values[1] = CStringGetTextDatum(waitEventData[idx].name);
+               values[2] = CStringGetTextDatum(waitEventData[idx].description);
+
+               tuplestore_putvalues(rsinfo->setResult, rsinfo->setDesc, 
values, nulls);
+       }
+
+       /* Handling extension custom wait events */
+       waiteventnames = GetWaitEventExtensionNames(&nbextwaitevents);
+
+       for (int idx = 0; idx < nbextwaitevents; idx++)
+       {
+               StringInfoData buf;
+               Datum           values[PG_GET_WAIT_EVENTS_COLS] = {0};
+               bool            nulls[PG_GET_WAIT_EVENTS_COLS] = {0};
+
+
+               values[0] = CStringGetTextDatum("Extension");
+               values[1] = CStringGetTextDatum(waiteventnames[idx]);
+
+               initStringInfo(&buf);
+               appendStringInfoString(&buf, "Waiting for custom wait event 
\"");
+               appendStringInfoString(&buf, waiteventnames[idx]);
+               appendStringInfoString(&buf, "\" defined by an extension 
module");
+
+               values[2] = CStringGetTextDatum(buf.data);
+
+               tuplestore_putvalues(rsinfo->setResult, rsinfo->setDesc, 
values, nulls);
+       }
+
+       return (Datum) 0;
+}
diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat
index 6996073989..b2dab98a8d 100644
--- a/src/include/catalog/pg_proc.dat
+++ b/src/include/catalog/pg_proc.dat
@@ -5417,6 +5417,12 @@
   proargmodes => 
'{i,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o}',
   proargnames => 
'{pid,datid,pid,usesysid,application_name,state,query,wait_event_type,wait_event,xact_start,query_start,backend_start,state_change,client_addr,client_hostname,client_port,backend_xid,backend_xmin,backend_type,ssl,sslversion,sslcipher,sslbits,ssl_client_dn,ssl_client_serial,ssl_issuer_dn,gss_auth,gss_princ,gss_enc,gss_delegation,leader_pid,query_id}',
   prosrc => 'pg_stat_get_activity' },
+{ oid => '8403', descr => 'describe wait events',
+  proname => 'pg_get_wait_events', procost => '10', prorows => '250',
+  proretset => 't', provolatile => 's', prorettype => 'record',
+  proargtypes => '', proallargtypes => '{text,text,text}',
+  proargmodes => '{o,o,o}', proargnames => '{type,name,description}',
+  prosrc => 'pg_get_wait_events' },
 { oid => '3318',
   descr => 'statistics: information about progress of backends running 
maintenance command',
   proname => 'pg_stat_get_progress_info', prorows => '100', proretset => 't',
diff --git a/src/include/utils/meson.build b/src/include/utils/meson.build
index 6de5d93799..c179478611 100644
--- a/src/include/utils/meson.build
+++ b/src/include/utils/meson.build
@@ -1,6 +1,6 @@
 # Copyright (c) 2022-2023, PostgreSQL Global Development Group
 
-wait_event_output = ['wait_event_types.h', 'pgstat_wait_event.c']
+wait_event_output = ['wait_event_types.h', 'pgstat_wait_event.c', 
'wait_event_funcs_data.c']
 wait_event_target = custom_target('wait_event_names',
   input: files('../../backend/utils/activity/wait_event_names.txt'),
   output: wait_event_output,
@@ -11,7 +11,7 @@ wait_event_target = custom_target('wait_event_names',
   ],
   build_by_default: true,
   install: true,
-  install_dir: [dir_include_server / 'utils', false],
+  install_dir: [dir_include_server / 'utils', false, false],
 )
 
 wait_event_types_h = wait_event_target[0]
diff --git a/src/include/utils/wait_event.h b/src/include/utils/wait_event.h
index 3eebdfad38..009b03a520 100644
--- a/src/include/utils/wait_event.h
+++ b/src/include/utils/wait_event.h
@@ -63,6 +63,7 @@ extern void WaitEventExtensionShmemInit(void);
 extern Size WaitEventExtensionShmemSize(void);
 
 extern uint32 WaitEventExtensionNew(const char *wait_event_name);
+extern char **GetWaitEventExtensionNames(int *nwaitevents);
 
 /* ----------
  * pgstat_report_wait_start() -
diff --git a/src/test/modules/worker_spi/t/001_worker_spi.pl 
b/src/test/modules/worker_spi/t/001_worker_spi.pl
index 26b8a49bec..2965acd789 100644
--- a/src/test/modules/worker_spi/t/001_worker_spi.pl
+++ b/src/test/modules/worker_spi/t/001_worker_spi.pl
@@ -47,6 +47,12 @@ $result = $node->poll_query_until(
 is($result, 1,
        'dynamic bgworker has reported "worker_spi_main" as wait event');
 
+# Check the wait event used by the dynamic bgworker appears in pg_wait_events
+$result = $node->safe_psql('postgres',
+       q[SELECT count(*) > 0 from pg_wait_events where type = 'Extension' and 
name = 'worker_spi_main';]
+);
+is($result, 't', '"worker_spi_main" is reported in pg_wait_events');
+
 note "testing bgworkers loaded with shared_preload_libraries";
 
 # Create the database first so as the workers can connect to it when
diff --git a/src/test/regress/expected/rules.out 
b/src/test/regress/expected/rules.out
index e07afcd4aa..55447d8090 100644
--- a/src/test/regress/expected/rules.out
+++ b/src/test/regress/expected/rules.out
@@ -2631,6 +2631,10 @@ pg_views| SELECT n.nspname AS schemaname,
    FROM (pg_class c
      LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace)))
   WHERE (c.relkind = 'v'::"char");
+pg_wait_events| SELECT type,
+    name,
+    description
+   FROM pg_get_wait_events() we(type, name, description);
 SELECT tablename, rulename, definition FROM pg_rules
 WHERE schemaname = 'pg_catalog'
 ORDER BY tablename, rulename;
diff --git a/src/test/regress/expected/sysviews.out 
b/src/test/regress/expected/sysviews.out
index 001c6e7eb9..aae5d51e1c 100644
--- a/src/test/regress/expected/sysviews.out
+++ b/src/test/regress/expected/sysviews.out
@@ -134,6 +134,22 @@ select name, setting from pg_settings where name like 
'enable%';
  enable_tidscan                 | on
 (21 rows)
 
+-- There are always wait event descriptions for various types.
+select type, count(*) > 0 as ok FROM pg_wait_events
+  group by type order by type COLLATE "C";
+   type    | ok 
+-----------+----
+ Activity  | t
+ BufferPin | t
+ Client    | t
+ Extension | t
+ IO        | t
+ IPC       | t
+ LWLock    | t
+ Lock      | t
+ Timeout   | t
+(9 rows)
+
 -- Test that the pg_timezone_names and pg_timezone_abbrevs views are
 -- more-or-less working.  We can't test their contents in any great detail
 -- without the outputs changing anytime IANA updates the underlying data,
diff --git a/src/test/regress/sql/sysviews.sql 
b/src/test/regress/sql/sysviews.sql
index 351e469c77..6b4e24601d 100644
--- a/src/test/regress/sql/sysviews.sql
+++ b/src/test/regress/sql/sysviews.sql
@@ -55,6 +55,10 @@ select count(*) = 0 as ok from pg_stat_wal_receiver;
 -- a regression test run.
 select name, setting from pg_settings where name like 'enable%';
 
+-- There are always wait event descriptions for various types.
+select type, count(*) > 0 as ok FROM pg_wait_events
+  group by type order by type COLLATE "C";
+
 -- Test that the pg_timezone_names and pg_timezone_abbrevs views are
 -- more-or-less working.  We can't test their contents in any great detail
 -- without the outputs changing anytime IANA updates the underlying data,
diff --git a/src/tools/msvc/Solution.pm b/src/tools/msvc/Solution.pm
index c98a1e9f9a..a50f730260 100644
--- a/src/tools/msvc/Solution.pm
+++ b/src/tools/msvc/Solution.pm
@@ -588,7 +588,8 @@ sub GenerateFiles
                        'src/include/utils/wait_event_types.h',
                        'src/backend/utils/activity/wait_event_names.txt'))
        {
-               print "Generating pgstat_wait_event.c and 
wait_event_types.h...\n";
+               print
+                 "Generating pgstat_wait_event.c, wait_event_types.h and 
wait_event_funcs_data.c...\n";
                my $activ = 'src/backend/utils/activity';
                system(
                        "perl $activ/generate-wait_event_types.pl --outdir 
$activ --code $activ/wait_event_names.txt"
diff --git a/src/tools/msvc/clean.bat b/src/tools/msvc/clean.bat
index 7cb23ea894..ac8da581e4 100755
--- a/src/tools/msvc/clean.bat
+++ b/src/tools/msvc/clean.bat
@@ -55,6 +55,7 @@ if exist src\include\catalog\header-stamp del /q 
src\include\catalog\header-stam
 if exist doc\src\sgml\version.sgml del /q doc\src\sgml\version.sgml
 
 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\utils\activity\wait_event_funcs_data.c del 
/q src\backend\utils\activity\wait_event_funcs_data.c
 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\backend\utils\fmgroids.h del /q 
src\backend\utils\fmgroids.h
 if %DIST%==1 if exist src\backend\utils\fmgrprotos.h del /q 
src\backend\utils\fmgrprotos.h
-- 
2.34.1

Reply via email to