IWYU annotations

Started by Peter Eisentrautabout 1 year ago9 messages
#1Peter Eisentraut
peter@eisentraut.org
2 attachment(s)

I have done a pass over much of the source code with
include-what-you-use (IWYU) to remove superfluous includes (commits
dbbca2cf299, 9be4e5d293b, ecb5af77987). Along the way I have collected
some pragma annotations to deal with exceptions and special cases and
peculiarities of the PostgreSQL source code header structures (see [0]https://github.com/include-what-you-use/include-what-you-use/blob/master/docs/IWYUPragmas.md
for description). Here I'm proposing a set of patches to add such
annotations in commonly useful cases that should deal with most of the
noise.

[0]: https://github.com/include-what-you-use/include-what-you-use/blob/master/docs/IWYUPragmas.md
https://github.com/include-what-you-use/include-what-you-use/blob/master/docs/IWYUPragmas.md

Attachments:

0001-IWYU-widely-useful-pragmas.patchtext/plain; charset=UTF-8; name=0001-IWYU-widely-useful-pragmas.patchDownload
From 0ee1c6c9f620ca8e1e3f9c601e5aa335a95c91d3 Mon Sep 17 00:00:00 2001
From: Peter Eisentraut <peter@eisentraut.org>
Date: Mon, 9 Dec 2024 12:25:10 +0100
Subject: [PATCH 1/2] IWYU widely useful pragmas

Add various widely useful "IWYU pragma" annotations, such as

- Common header files such as c.h, postgres.h should be "always_keep".

- System headers included in c.h, postgres.h etc. should be considered
  "export".

- Some portability headers such as getopt_long.h should be
  "always_keep", so they are not considered superfluous on some
  platforms.

- Certain system headers included from portability headers should be
  considered "export" because the purpose of the portability header is
  to wrap them.

- Superfluous includes marked as "for backward compatibility" get a
  formal IWYU annotation.

- Special handling of access/rmgrlist.h in
  src/bin/pg_waldump/rmgrdesc.c, similar to what was already done in
  src/backend/access/transam/rmgr.c.

- Generated header included in utils/syscache.h is marked exported.
  This is a very commonly used include and this avoids lots of
  complaints.
---
 src/bin/pg_waldump/rmgrdesc.c    | 10 +++++++---
 src/include/c.h                  |  5 +++++
 src/include/getopt_long.h        |  3 ++-
 src/include/pg_getopt.h          |  5 +++--
 src/include/pg_trace.h           |  2 +-
 src/include/pgstat.h             |  6 +++---
 src/include/port/pg_iovec.h      |  2 +-
 src/include/port/pg_pthread.h    |  2 +-
 src/include/postgres.h           |  5 +++++
 src/include/postgres_ext.h       |  1 +
 src/include/postgres_fe.h        |  5 +++++
 src/include/utils/syscache.h     |  2 +-
 src/interfaces/libpq/libpq-int.h |  2 ++
 13 files changed, 37 insertions(+), 13 deletions(-)

diff --git a/src/bin/pg_waldump/rmgrdesc.c b/src/bin/pg_waldump/rmgrdesc.c
index 6b8c17bb4c4..f5f53ceda32 100644
--- a/src/bin/pg_waldump/rmgrdesc.c
+++ b/src/bin/pg_waldump/rmgrdesc.c
@@ -8,6 +8,12 @@
 #define FRONTEND 1
 #include "postgres.h"
 
+#include "access/rmgr.h"
+#include "access/xlog_internal.h"
+#include "rmgrdesc.h"
+
+/* includes needed for "access/rmgrlist.h" */
+/* IWYU pragma: begin_keep */
 #include "access/brin_xlog.h"
 #include "access/clog.h"
 #include "access/commit_ts.h"
@@ -18,19 +24,17 @@
 #include "access/heapam_xlog.h"
 #include "access/multixact.h"
 #include "access/nbtxlog.h"
-#include "access/rmgr.h"
 #include "access/spgxlog.h"
 #include "access/xact.h"
-#include "access/xlog_internal.h"
 #include "catalog/storage_xlog.h"
 #include "commands/dbcommands_xlog.h"
 #include "commands/sequence.h"
 #include "commands/tablespace.h"
 #include "replication/message.h"
 #include "replication/origin.h"
-#include "rmgrdesc.h"
 #include "storage/standbydefs.h"
 #include "utils/relmapper.h"
+/* IWYU pragma: end_keep */
 
 #define PG_RMGR(symname,name,redo,desc,identify,startup,cleanup,mask,decode) \
 	{ name, desc, identify},
diff --git a/src/include/c.h b/src/include/c.h
index 13bb39fdef3..884128e781d 100644
--- a/src/include/c.h
+++ b/src/include/c.h
@@ -16,6 +16,7 @@
  *
  *-------------------------------------------------------------------------
  */
+/* IWYU pragma: always_keep */
 /*
  *----------------------------------------------------------------
  *	 TABLE OF CONTENTS
@@ -46,6 +47,8 @@
 #ifndef C_H
 #define C_H
 
+/* IWYU pragma: begin_exports */
+
 /*
  * These headers must be included before any system headers, because on some
  * platforms they affect the behavior of the system headers (for example, by
@@ -1327,4 +1330,6 @@ typedef intptr_t sigjmp_buf[5];
 /* /port compatibility functions */
 #include "port.h"
 
+/* IWYU pragma: end_exports */
+
 #endif							/* C_H */
diff --git a/src/include/getopt_long.h b/src/include/getopt_long.h
index 0fdbefae7fb..a15ebbc0037 100644
--- a/src/include/getopt_long.h
+++ b/src/include/getopt_long.h
@@ -6,10 +6,11 @@
  *
  * src/include/getopt_long.h
  */
+/* IWYU pragma: always_keep */
 #ifndef GETOPT_LONG_H
 #define GETOPT_LONG_H
 
-#include "pg_getopt.h"
+#include "pg_getopt.h"			/* IWYU pragma: export */
 
 #ifndef HAVE_STRUCT_OPTION
 
diff --git a/src/include/pg_getopt.h b/src/include/pg_getopt.h
index c87ea20b14f..698cc61ce83 100644
--- a/src/include/pg_getopt.h
+++ b/src/include/pg_getopt.h
@@ -15,15 +15,16 @@
  *
  * src/include/pg_getopt.h
  */
+/* IWYU pragma: always_keep */
 #ifndef PG_GETOPT_H
 #define PG_GETOPT_H
 
 /* POSIX says getopt() is provided by unistd.h */
-#include <unistd.h>
+#include <unistd.h>				/* IWYU pragma: export */
 
 /* rely on the system's getopt.h if present */
 #ifdef HAVE_GETOPT_H
-#include <getopt.h>
+#include <getopt.h>				/* IWYU pragma: export */
 #endif
 
 /*
diff --git a/src/include/pg_trace.h b/src/include/pg_trace.h
index bae819ab466..00c172d7435 100644
--- a/src/include/pg_trace.h
+++ b/src/include/pg_trace.h
@@ -12,6 +12,6 @@
 #ifndef PG_TRACE_H
 #define PG_TRACE_H
 
-#include "utils/probes.h"		/* pgrminclude ignore */
+#include "utils/probes.h"		/* pgrminclude ignore */	/* IWYU pragma: export */
 
 #endif							/* PG_TRACE_H */
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index 59c28b4aca8..5fe9158559f 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -16,10 +16,10 @@
 #include "portability/instr_time.h"
 #include "postmaster/pgarch.h"	/* for MAX_XFN_CHARS */
 #include "replication/conflict.h"
-#include "utils/backend_progress.h" /* for backward compatibility */
-#include "utils/backend_status.h"	/* for backward compatibility */
+#include "utils/backend_progress.h" /* for backward compatibility */	/* IWYU pragma: export */
+#include "utils/backend_status.h"	/* for backward compatibility */	/* IWYU pragma: export */
 #include "utils/relcache.h"
-#include "utils/wait_event.h"	/* for backward compatibility */
+#include "utils/wait_event.h"	/* for backward compatibility */	/* IWYU pragma: export */
 
 
 /* ----------
diff --git a/src/include/port/pg_iovec.h b/src/include/port/pg_iovec.h
index e5fe677b371..7df67b081fa 100644
--- a/src/include/port/pg_iovec.h
+++ b/src/include/port/pg_iovec.h
@@ -16,7 +16,7 @@
 #ifndef WIN32
 
 #include <limits.h>
-#include <sys/uio.h>
+#include <sys/uio.h>			/* IWYU pragma: export */
 #include <unistd.h>
 
 #else
diff --git a/src/include/port/pg_pthread.h b/src/include/port/pg_pthread.h
index d102ce9d6f3..4dbb3c8a52f 100644
--- a/src/include/port/pg_pthread.h
+++ b/src/include/port/pg_pthread.h
@@ -13,7 +13,7 @@
 #ifndef PG_PTHREAD_H
 #define PG_PTHREAD_H
 
-#include <pthread.h>
+#include <pthread.h>			/* IWYU pragma: export */
 
 #ifndef HAVE_PTHREAD_BARRIER_WAIT
 
diff --git a/src/include/postgres.h b/src/include/postgres.h
index 5d5fd7813e8..65e574c8570 100644
--- a/src/include/postgres.h
+++ b/src/include/postgres.h
@@ -14,6 +14,7 @@
  *
  *-------------------------------------------------------------------------
  */
+/* IWYU pragma: always_keep */
 /*
  *----------------------------------------------------------------
  *	 TABLE OF CONTENTS
@@ -42,10 +43,14 @@
 #ifndef POSTGRES_H
 #define POSTGRES_H
 
+/* IWYU pragma: begin_exports */
+
 #include "c.h"
 #include "utils/elog.h"
 #include "utils/palloc.h"
 
+/* IWYU pragma: end_exports */
+
 /* ----------------------------------------------------------------
  *				Section 1:	Datum type + support functions
  * ----------------------------------------------------------------
diff --git a/src/include/postgres_ext.h b/src/include/postgres_ext.h
index 202eb049622..9f2e3c52972 100644
--- a/src/include/postgres_ext.h
+++ b/src/include/postgres_ext.h
@@ -19,6 +19,7 @@
  *
  *-------------------------------------------------------------------------
  */
+/* IWYU pragma: always_keep */
 
 #ifndef POSTGRES_EXT_H
 #define POSTGRES_EXT_H
diff --git a/src/include/postgres_fe.h b/src/include/postgres_fe.h
index 9c605daa365..33eb594380c 100644
--- a/src/include/postgres_fe.h
+++ b/src/include/postgres_fe.h
@@ -15,6 +15,7 @@
  *
  *-------------------------------------------------------------------------
  */
+/* IWYU pragma: always_keep */
 #ifndef POSTGRES_FE_H
 #define POSTGRES_FE_H
 
@@ -22,8 +23,12 @@
 #define FRONTEND 1
 #endif
 
+/* IWYU pragma: begin_exports */
+
 #include "c.h"
 
 #include "common/fe_memutils.h"
 
+/* IWYU pragma: end_exports */
+
 #endif							/* POSTGRES_FE_H */
diff --git a/src/include/utils/syscache.h b/src/include/utils/syscache.h
index b541911c8fc..c71934f1e86 100644
--- a/src/include/utils/syscache.h
+++ b/src/include/utils/syscache.h
@@ -20,7 +20,7 @@
 #include "access/htup.h"
 /* we intentionally do not include utils/catcache.h here */
 
-#include "catalog/syscache_ids.h"
+#include "catalog/syscache_ids.h"	/* IWYU pragma: export */
 
 extern void InitCatalogCache(void);
 extern void InitCatalogCachePhase2(void);
diff --git a/src/interfaces/libpq/libpq-int.h b/src/interfaces/libpq/libpq-int.h
index 4606eb2ad34..3fff069598e 100644
--- a/src/interfaces/libpq/libpq-int.h
+++ b/src/interfaces/libpq/libpq-int.h
@@ -41,6 +41,7 @@
 #include "fe-auth-sasl.h"
 #include "pqexpbuffer.h"
 
+/* IWYU pragma: begin_exports */
 #ifdef ENABLE_GSS
 #if defined(HAVE_GSSAPI_H)
 #include <gssapi.h>
@@ -48,6 +49,7 @@
 #include <gssapi/gssapi.h>
 #endif
 #endif
+/* IWYU pragma: end_exports */
 
 #ifdef ENABLE_SSPI
 #define SECURITY_WIN32
-- 
2.47.1

0002-IWYU-pragmas-for-catalog-headers.patchtext/plain; charset=UTF-8; name=0002-IWYU-pragmas-for-catalog-headers.patchDownload
From 06e03c04b65abb16ad606e5e1415868eecf51c37 Mon Sep 17 00:00:00 2001
From: Peter Eisentraut <peter@eisentraut.org>
Date: Mon, 9 Dec 2024 12:25:25 +0100
Subject: [PATCH 2/2] IWYU pragmas for catalog headers

Add "IWYU pragma: export" annotations in each catalog header file so
that, for instance, including "catalog/pg_aggregate.h" is considered
acceptable in place of "catalog/pg_aggregate_d.h".  This is very
common and it seems better to silence IWYU about it than trying to fix
this up.
---
 src/include/catalog/pg_aggregate.h             | 2 +-
 src/include/catalog/pg_am.h                    | 2 +-
 src/include/catalog/pg_amop.h                  | 2 +-
 src/include/catalog/pg_amproc.h                | 2 +-
 src/include/catalog/pg_attrdef.h               | 2 +-
 src/include/catalog/pg_attribute.h             | 2 +-
 src/include/catalog/pg_auth_members.h          | 2 +-
 src/include/catalog/pg_authid.h                | 2 +-
 src/include/catalog/pg_cast.h                  | 2 +-
 src/include/catalog/pg_class.h                 | 2 +-
 src/include/catalog/pg_collation.h             | 2 +-
 src/include/catalog/pg_constraint.h            | 2 +-
 src/include/catalog/pg_conversion.h            | 2 +-
 src/include/catalog/pg_database.h              | 2 +-
 src/include/catalog/pg_db_role_setting.h       | 2 +-
 src/include/catalog/pg_default_acl.h           | 2 +-
 src/include/catalog/pg_depend.h                | 2 +-
 src/include/catalog/pg_description.h           | 2 +-
 src/include/catalog/pg_enum.h                  | 2 +-
 src/include/catalog/pg_event_trigger.h         | 2 +-
 src/include/catalog/pg_extension.h             | 2 +-
 src/include/catalog/pg_foreign_data_wrapper.h  | 2 +-
 src/include/catalog/pg_foreign_server.h        | 2 +-
 src/include/catalog/pg_foreign_table.h         | 2 +-
 src/include/catalog/pg_index.h                 | 2 +-
 src/include/catalog/pg_inherits.h              | 2 +-
 src/include/catalog/pg_init_privs.h            | 2 +-
 src/include/catalog/pg_language.h              | 2 +-
 src/include/catalog/pg_largeobject.h           | 2 +-
 src/include/catalog/pg_largeobject_metadata.h  | 2 +-
 src/include/catalog/pg_namespace.h             | 2 +-
 src/include/catalog/pg_opclass.h               | 2 +-
 src/include/catalog/pg_operator.h              | 2 +-
 src/include/catalog/pg_opfamily.h              | 2 +-
 src/include/catalog/pg_parameter_acl.h         | 2 +-
 src/include/catalog/pg_partitioned_table.h     | 2 +-
 src/include/catalog/pg_policy.h                | 2 +-
 src/include/catalog/pg_proc.h                  | 2 +-
 src/include/catalog/pg_publication.h           | 2 +-
 src/include/catalog/pg_publication_namespace.h | 2 +-
 src/include/catalog/pg_publication_rel.h       | 2 +-
 src/include/catalog/pg_range.h                 | 2 +-
 src/include/catalog/pg_replication_origin.h    | 2 +-
 src/include/catalog/pg_rewrite.h               | 2 +-
 src/include/catalog/pg_seclabel.h              | 2 +-
 src/include/catalog/pg_sequence.h              | 2 +-
 src/include/catalog/pg_shdepend.h              | 2 +-
 src/include/catalog/pg_shdescription.h         | 2 +-
 src/include/catalog/pg_shseclabel.h            | 2 +-
 src/include/catalog/pg_statistic.h             | 2 +-
 src/include/catalog/pg_statistic_ext.h         | 2 +-
 src/include/catalog/pg_statistic_ext_data.h    | 2 +-
 src/include/catalog/pg_subscription.h          | 2 +-
 src/include/catalog/pg_subscription_rel.h      | 2 +-
 src/include/catalog/pg_tablespace.h            | 2 +-
 src/include/catalog/pg_transform.h             | 2 +-
 src/include/catalog/pg_trigger.h               | 2 +-
 src/include/catalog/pg_ts_config.h             | 2 +-
 src/include/catalog/pg_ts_dict.h               | 2 +-
 src/include/catalog/pg_ts_parser.h             | 2 +-
 src/include/catalog/pg_ts_template.h           | 2 +-
 src/include/catalog/pg_type.h                  | 2 +-
 src/include/catalog/pg_user_mapping.h          | 2 +-
 63 files changed, 63 insertions(+), 63 deletions(-)

diff --git a/src/include/catalog/pg_aggregate.h b/src/include/catalog/pg_aggregate.h
index 490f6454695..ba490e45a12 100644
--- a/src/include/catalog/pg_aggregate.h
+++ b/src/include/catalog/pg_aggregate.h
@@ -19,7 +19,7 @@
 #define PG_AGGREGATE_H
 
 #include "catalog/genbki.h"
-#include "catalog/pg_aggregate_d.h"
+#include "catalog/pg_aggregate_d.h" /* IWYU pragma: export */
 
 #include "catalog/objectaddress.h"
 #include "nodes/pg_list.h"
diff --git a/src/include/catalog/pg_am.h b/src/include/catalog/pg_am.h
index 475593fad4c..5be4accff72 100644
--- a/src/include/catalog/pg_am.h
+++ b/src/include/catalog/pg_am.h
@@ -19,7 +19,7 @@
 #define PG_AM_H
 
 #include "catalog/genbki.h"
-#include "catalog/pg_am_d.h"
+#include "catalog/pg_am_d.h"	/* IWYU pragma: export */
 
 /* ----------------
  *		pg_am definition.  cpp turns this into
diff --git a/src/include/catalog/pg_amop.h b/src/include/catalog/pg_amop.h
index 570100fad41..17a67d54896 100644
--- a/src/include/catalog/pg_amop.h
+++ b/src/include/catalog/pg_amop.h
@@ -44,7 +44,7 @@
 #define PG_AMOP_H
 
 #include "catalog/genbki.h"
-#include "catalog/pg_amop_d.h"
+#include "catalog/pg_amop_d.h"	/* IWYU pragma: export */
 
 /* ----------------
  *		pg_amop definition.  cpp turns this into
diff --git a/src/include/catalog/pg_amproc.h b/src/include/catalog/pg_amproc.h
index 1dbebeca175..04f05efc8e1 100644
--- a/src/include/catalog/pg_amproc.h
+++ b/src/include/catalog/pg_amproc.h
@@ -33,7 +33,7 @@
 #define PG_AMPROC_H
 
 #include "catalog/genbki.h"
-#include "catalog/pg_amproc_d.h"
+#include "catalog/pg_amproc_d.h"	/* IWYU pragma: export */
 
 /* ----------------
  *		pg_amproc definition.  cpp turns this into
diff --git a/src/include/catalog/pg_attrdef.h b/src/include/catalog/pg_attrdef.h
index 14f034a3b52..dd8544ae0bd 100644
--- a/src/include/catalog/pg_attrdef.h
+++ b/src/include/catalog/pg_attrdef.h
@@ -20,7 +20,7 @@
 
 #include "catalog/genbki.h"
 #include "catalog/objectaddress.h"
-#include "catalog/pg_attrdef_d.h"
+#include "catalog/pg_attrdef_d.h"	/* IWYU pragma: export */
 
 /* ----------------
  *		pg_attrdef definition.  cpp turns this into
diff --git a/src/include/catalog/pg_attribute.h b/src/include/catalog/pg_attribute.h
index 1c62b8bfcb5..20e54ae551b 100644
--- a/src/include/catalog/pg_attribute.h
+++ b/src/include/catalog/pg_attribute.h
@@ -23,7 +23,7 @@
 #define PG_ATTRIBUTE_H
 
 #include "catalog/genbki.h"
-#include "catalog/pg_attribute_d.h"
+#include "catalog/pg_attribute_d.h" /* IWYU pragma: export */
 
 /* ----------------
  *		pg_attribute definition.  cpp turns this into
diff --git a/src/include/catalog/pg_auth_members.h b/src/include/catalog/pg_auth_members.h
index 5f4b30756ca..d0c345780d1 100644
--- a/src/include/catalog/pg_auth_members.h
+++ b/src/include/catalog/pg_auth_members.h
@@ -20,7 +20,7 @@
 #define PG_AUTH_MEMBERS_H
 
 #include "catalog/genbki.h"
-#include "catalog/pg_auth_members_d.h"
+#include "catalog/pg_auth_members_d.h"	/* IWYU pragma: export */
 
 /* ----------------
  *		pg_auth_members definition.  cpp turns this into
diff --git a/src/include/catalog/pg_authid.h b/src/include/catalog/pg_authid.h
index b0dbdf2dd2e..8e77ae6daa8 100644
--- a/src/include/catalog/pg_authid.h
+++ b/src/include/catalog/pg_authid.h
@@ -21,7 +21,7 @@
 #define PG_AUTHID_H
 
 #include "catalog/genbki.h"
-#include "catalog/pg_authid_d.h"
+#include "catalog/pg_authid_d.h"	/* IWYU pragma: export */
 
 /* ----------------
  *		pg_authid definition.  cpp turns this into
diff --git a/src/include/catalog/pg_cast.h b/src/include/catalog/pg_cast.h
index 6c995509bc3..d7d72e04fb0 100644
--- a/src/include/catalog/pg_cast.h
+++ b/src/include/catalog/pg_cast.h
@@ -22,7 +22,7 @@
 
 #include "catalog/dependency.h"
 #include "catalog/genbki.h"
-#include "catalog/pg_cast_d.h"
+#include "catalog/pg_cast_d.h"	/* IWYU pragma: export */
 
 /* ----------------
  *		pg_cast definition.  cpp turns this into
diff --git a/src/include/catalog/pg_class.h b/src/include/catalog/pg_class.h
index 0fc2c093b0d..bcb4b3e50a4 100644
--- a/src/include/catalog/pg_class.h
+++ b/src/include/catalog/pg_class.h
@@ -19,7 +19,7 @@
 #define PG_CLASS_H
 
 #include "catalog/genbki.h"
-#include "catalog/pg_class_d.h"
+#include "catalog/pg_class_d.h" /* IWYU pragma: export */
 
 /* ----------------
  *		pg_class definition.  cpp turns this into
diff --git a/src/include/catalog/pg_collation.h b/src/include/catalog/pg_collation.h
index 5ce289d74bd..50cdeebfe83 100644
--- a/src/include/catalog/pg_collation.h
+++ b/src/include/catalog/pg_collation.h
@@ -19,7 +19,7 @@
 #define PG_COLLATION_H
 
 #include "catalog/genbki.h"
-#include "catalog/pg_collation_d.h"
+#include "catalog/pg_collation_d.h" /* IWYU pragma: export */
 
 /* ----------------
  *		pg_collation definition.  cpp turns this into
diff --git a/src/include/catalog/pg_constraint.h b/src/include/catalog/pg_constraint.h
index 4b4476738a2..c5c60f644e4 100644
--- a/src/include/catalog/pg_constraint.h
+++ b/src/include/catalog/pg_constraint.h
@@ -20,7 +20,7 @@
 
 #include "catalog/dependency.h"
 #include "catalog/genbki.h"
-#include "catalog/pg_constraint_d.h"
+#include "catalog/pg_constraint_d.h"	/* IWYU pragma: export */
 #include "nodes/pg_list.h"
 
 /* ----------------
diff --git a/src/include/catalog/pg_conversion.h b/src/include/catalog/pg_conversion.h
index d94f0229672..db3c6b9f536 100644
--- a/src/include/catalog/pg_conversion.h
+++ b/src/include/catalog/pg_conversion.h
@@ -19,7 +19,7 @@
 
 #include "catalog/genbki.h"
 #include "catalog/objectaddress.h"
-#include "catalog/pg_conversion_d.h"
+#include "catalog/pg_conversion_d.h"	/* IWYU pragma: export */
 
 /* ----------------
  *		pg_conversion definition.  cpp turns this into
diff --git a/src/include/catalog/pg_database.h b/src/include/catalog/pg_database.h
index dbd4379ffa5..4454f92eea0 100644
--- a/src/include/catalog/pg_database.h
+++ b/src/include/catalog/pg_database.h
@@ -19,7 +19,7 @@
 #define PG_DATABASE_H
 
 #include "catalog/genbki.h"
-#include "catalog/pg_database_d.h"
+#include "catalog/pg_database_d.h"	/* IWYU pragma: export */
 
 /* ----------------
  *		pg_database definition.  cpp turns this into
diff --git a/src/include/catalog/pg_db_role_setting.h b/src/include/catalog/pg_db_role_setting.h
index 7e1a652381f..45ebb009151 100644
--- a/src/include/catalog/pg_db_role_setting.h
+++ b/src/include/catalog/pg_db_role_setting.h
@@ -20,7 +20,7 @@
 #define PG_DB_ROLE_SETTING_H
 
 #include "catalog/genbki.h"
-#include "catalog/pg_db_role_setting_d.h"
+#include "catalog/pg_db_role_setting_d.h"	/* IWYU pragma: export */
 
 #include "utils/guc.h"
 #include "utils/relcache.h"
diff --git a/src/include/catalog/pg_default_acl.h b/src/include/catalog/pg_default_acl.h
index d272cdf08b4..f9aee902c34 100644
--- a/src/include/catalog/pg_default_acl.h
+++ b/src/include/catalog/pg_default_acl.h
@@ -20,7 +20,7 @@
 #define PG_DEFAULT_ACL_H
 
 #include "catalog/genbki.h"
-#include "catalog/pg_default_acl_d.h"
+#include "catalog/pg_default_acl_d.h"	/* IWYU pragma: export */
 
 /* ----------------
  *		pg_default_acl definition.  cpp turns this into
diff --git a/src/include/catalog/pg_depend.h b/src/include/catalog/pg_depend.h
index eb1ee43b012..8b5064831e0 100644
--- a/src/include/catalog/pg_depend.h
+++ b/src/include/catalog/pg_depend.h
@@ -32,7 +32,7 @@
 #define PG_DEPEND_H
 
 #include "catalog/genbki.h"
-#include "catalog/pg_depend_d.h"
+#include "catalog/pg_depend_d.h"	/* IWYU pragma: export */
 
 /* ----------------
  *		pg_depend definition.  cpp turns this into
diff --git a/src/include/catalog/pg_description.h b/src/include/catalog/pg_description.h
index e30a6976beb..c523a6d3b53 100644
--- a/src/include/catalog/pg_description.h
+++ b/src/include/catalog/pg_description.h
@@ -38,7 +38,7 @@
 #define PG_DESCRIPTION_H
 
 #include "catalog/genbki.h"
-#include "catalog/pg_description_d.h"
+#include "catalog/pg_description_d.h"	/* IWYU pragma: export */
 
 /* ----------------
  *		pg_description definition.  cpp turns this into
diff --git a/src/include/catalog/pg_enum.h b/src/include/catalog/pg_enum.h
index 4d9a241d348..d88cb2e4f98 100644
--- a/src/include/catalog/pg_enum.h
+++ b/src/include/catalog/pg_enum.h
@@ -19,7 +19,7 @@
 #define PG_ENUM_H
 
 #include "catalog/genbki.h"
-#include "catalog/pg_enum_d.h"
+#include "catalog/pg_enum_d.h"	/* IWYU pragma: export */
 
 #include "nodes/pg_list.h"
 
diff --git a/src/include/catalog/pg_event_trigger.h b/src/include/catalog/pg_event_trigger.h
index 9170a4ddfe8..2909f9519a6 100644
--- a/src/include/catalog/pg_event_trigger.h
+++ b/src/include/catalog/pg_event_trigger.h
@@ -19,7 +19,7 @@
 #define PG_EVENT_TRIGGER_H
 
 #include "catalog/genbki.h"
-#include "catalog/pg_event_trigger_d.h"
+#include "catalog/pg_event_trigger_d.h" /* IWYU pragma: export */
 
 /* ----------------
  *		pg_event_trigger definition.    cpp turns this into
diff --git a/src/include/catalog/pg_extension.h b/src/include/catalog/pg_extension.h
index 673181b39ae..f14452df59b 100644
--- a/src/include/catalog/pg_extension.h
+++ b/src/include/catalog/pg_extension.h
@@ -19,7 +19,7 @@
 #define PG_EXTENSION_H
 
 #include "catalog/genbki.h"
-#include "catalog/pg_extension_d.h"
+#include "catalog/pg_extension_d.h" /* IWYU pragma: export */
 
 /* ----------------
  *		pg_extension definition.  cpp turns this into
diff --git a/src/include/catalog/pg_foreign_data_wrapper.h b/src/include/catalog/pg_foreign_data_wrapper.h
index 0d8759d3fd3..91fe201a4b2 100644
--- a/src/include/catalog/pg_foreign_data_wrapper.h
+++ b/src/include/catalog/pg_foreign_data_wrapper.h
@@ -19,7 +19,7 @@
 #define PG_FOREIGN_DATA_WRAPPER_H
 
 #include "catalog/genbki.h"
-#include "catalog/pg_foreign_data_wrapper_d.h"
+#include "catalog/pg_foreign_data_wrapper_d.h"	/* IWYU pragma: export */
 
 /* ----------------
  *		pg_foreign_data_wrapper definition.  cpp turns this into
diff --git a/src/include/catalog/pg_foreign_server.h b/src/include/catalog/pg_foreign_server.h
index a4b81936b09..fcffd8cfb98 100644
--- a/src/include/catalog/pg_foreign_server.h
+++ b/src/include/catalog/pg_foreign_server.h
@@ -18,7 +18,7 @@
 #define PG_FOREIGN_SERVER_H
 
 #include "catalog/genbki.h"
-#include "catalog/pg_foreign_server_d.h"
+#include "catalog/pg_foreign_server_d.h"	/* IWYU pragma: export */
 
 /* ----------------
  *		pg_foreign_server definition.  cpp turns this into
diff --git a/src/include/catalog/pg_foreign_table.h b/src/include/catalog/pg_foreign_table.h
index d17ff0e76e1..3b8f0fe2db2 100644
--- a/src/include/catalog/pg_foreign_table.h
+++ b/src/include/catalog/pg_foreign_table.h
@@ -18,7 +18,7 @@
 #define PG_FOREIGN_TABLE_H
 
 #include "catalog/genbki.h"
-#include "catalog/pg_foreign_table_d.h"
+#include "catalog/pg_foreign_table_d.h" /* IWYU pragma: export */
 
 /* ----------------
  *		pg_foreign_table definition.  cpp turns this into
diff --git a/src/include/catalog/pg_index.h b/src/include/catalog/pg_index.h
index 6c89639a9e4..73fb53b9f3e 100644
--- a/src/include/catalog/pg_index.h
+++ b/src/include/catalog/pg_index.h
@@ -19,7 +19,7 @@
 #define PG_INDEX_H
 
 #include "catalog/genbki.h"
-#include "catalog/pg_index_d.h"
+#include "catalog/pg_index_d.h" /* IWYU pragma: export */
 
 /* ----------------
  *		pg_index definition.  cpp turns this into
diff --git a/src/include/catalog/pg_inherits.h b/src/include/catalog/pg_inherits.h
index b3da78c24bd..479ce03ea42 100644
--- a/src/include/catalog/pg_inherits.h
+++ b/src/include/catalog/pg_inherits.h
@@ -19,7 +19,7 @@
 #define PG_INHERITS_H
 
 #include "catalog/genbki.h"
-#include "catalog/pg_inherits_d.h"
+#include "catalog/pg_inherits_d.h"	/* IWYU pragma: export */
 
 #include "nodes/pg_list.h"
 #include "storage/lock.h"
diff --git a/src/include/catalog/pg_init_privs.h b/src/include/catalog/pg_init_privs.h
index ecd5d0812b7..85747d5a9ee 100644
--- a/src/include/catalog/pg_init_privs.h
+++ b/src/include/catalog/pg_init_privs.h
@@ -36,7 +36,7 @@
 #define PG_INIT_PRIVS_H
 
 #include "catalog/genbki.h"
-#include "catalog/pg_init_privs_d.h"
+#include "catalog/pg_init_privs_d.h"	/* IWYU pragma: export */
 
 /* ----------------
  *		pg_init_privs definition.  cpp turns this into
diff --git a/src/include/catalog/pg_language.h b/src/include/catalog/pg_language.h
index 7256908a95c..a9aebb41169 100644
--- a/src/include/catalog/pg_language.h
+++ b/src/include/catalog/pg_language.h
@@ -19,7 +19,7 @@
 #define PG_LANGUAGE_H
 
 #include "catalog/genbki.h"
-#include "catalog/pg_language_d.h"
+#include "catalog/pg_language_d.h"	/* IWYU pragma: export */
 
 /* ----------------
  *		pg_language definition.  cpp turns this into
diff --git a/src/include/catalog/pg_largeobject.h b/src/include/catalog/pg_largeobject.h
index e684c58ca95..53509529242 100644
--- a/src/include/catalog/pg_largeobject.h
+++ b/src/include/catalog/pg_largeobject.h
@@ -19,7 +19,7 @@
 #define PG_LARGEOBJECT_H
 
 #include "catalog/genbki.h"
-#include "catalog/pg_largeobject_d.h"
+#include "catalog/pg_largeobject_d.h"	/* IWYU pragma: export */
 #include "utils/snapshot.h"
 
 /* ----------------
diff --git a/src/include/catalog/pg_largeobject_metadata.h b/src/include/catalog/pg_largeobject_metadata.h
index 8a827442187..9cae8089385 100644
--- a/src/include/catalog/pg_largeobject_metadata.h
+++ b/src/include/catalog/pg_largeobject_metadata.h
@@ -20,7 +20,7 @@
 #define PG_LARGEOBJECT_METADATA_H
 
 #include "catalog/genbki.h"
-#include "catalog/pg_largeobject_metadata_d.h"
+#include "catalog/pg_largeobject_metadata_d.h"	/* IWYU pragma: export */
 
 /* ----------------
  *		pg_largeobject_metadata definition. cpp turns this into
diff --git a/src/include/catalog/pg_namespace.h b/src/include/catalog/pg_namespace.h
index e101808ae1e..316a950f61d 100644
--- a/src/include/catalog/pg_namespace.h
+++ b/src/include/catalog/pg_namespace.h
@@ -19,7 +19,7 @@
 #define PG_NAMESPACE_H
 
 #include "catalog/genbki.h"
-#include "catalog/pg_namespace_d.h"
+#include "catalog/pg_namespace_d.h" /* IWYU pragma: export */
 #include "utils/acl.h"
 
 /* ----------------------------------------------------------------
diff --git a/src/include/catalog/pg_opclass.h b/src/include/catalog/pg_opclass.h
index 05867d08f93..c99b29a1bd8 100644
--- a/src/include/catalog/pg_opclass.h
+++ b/src/include/catalog/pg_opclass.h
@@ -39,7 +39,7 @@
 #define PG_OPCLASS_H
 
 #include "catalog/genbki.h"
-#include "catalog/pg_opclass_d.h"
+#include "catalog/pg_opclass_d.h"	/* IWYU pragma: export */
 
 /* ----------------
  *		pg_opclass definition.  cpp turns this into
diff --git a/src/include/catalog/pg_operator.h b/src/include/catalog/pg_operator.h
index 3ff1acc37ef..a77ee9e805d 100644
--- a/src/include/catalog/pg_operator.h
+++ b/src/include/catalog/pg_operator.h
@@ -20,7 +20,7 @@
 
 #include "catalog/genbki.h"
 #include "catalog/objectaddress.h"
-#include "catalog/pg_operator_d.h"
+#include "catalog/pg_operator_d.h"	/* IWYU pragma: export */
 #include "nodes/pg_list.h"
 
 /* ----------------
diff --git a/src/include/catalog/pg_opfamily.h b/src/include/catalog/pg_opfamily.h
index 52f9c4acf97..9ebb9c2efec 100644
--- a/src/include/catalog/pg_opfamily.h
+++ b/src/include/catalog/pg_opfamily.h
@@ -19,7 +19,7 @@
 #define PG_OPFAMILY_H
 
 #include "catalog/genbki.h"
-#include "catalog/pg_opfamily_d.h"
+#include "catalog/pg_opfamily_d.h"	/* IWYU pragma: export */
 
 /* ----------------
  *		pg_opfamily definition. cpp turns this into
diff --git a/src/include/catalog/pg_parameter_acl.h b/src/include/catalog/pg_parameter_acl.h
index 8f6b6f92b3e..4818e66fa9f 100644
--- a/src/include/catalog/pg_parameter_acl.h
+++ b/src/include/catalog/pg_parameter_acl.h
@@ -20,7 +20,7 @@
 #define PG_PARAMETER_ACL_H
 
 #include "catalog/genbki.h"
-#include "catalog/pg_parameter_acl_d.h"
+#include "catalog/pg_parameter_acl_d.h" /* IWYU pragma: export */
 
 /* ----------------
  *		pg_parameter_acl definition.  cpp turns this into
diff --git a/src/include/catalog/pg_partitioned_table.h b/src/include/catalog/pg_partitioned_table.h
index daf57008b69..0654596b28f 100644
--- a/src/include/catalog/pg_partitioned_table.h
+++ b/src/include/catalog/pg_partitioned_table.h
@@ -20,7 +20,7 @@
 #define PG_PARTITIONED_TABLE_H
 
 #include "catalog/genbki.h"
-#include "catalog/pg_partitioned_table_d.h"
+#include "catalog/pg_partitioned_table_d.h" /* IWYU pragma: export */
 
 /* ----------------
  *		pg_partitioned_table definition.  cpp turns this into
diff --git a/src/include/catalog/pg_policy.h b/src/include/catalog/pg_policy.h
index 05d6398f7b8..3ed94f3cea5 100644
--- a/src/include/catalog/pg_policy.h
+++ b/src/include/catalog/pg_policy.h
@@ -19,7 +19,7 @@
 #define PG_POLICY_H
 
 #include "catalog/genbki.h"
-#include "catalog/pg_policy_d.h"
+#include "catalog/pg_policy_d.h"	/* IWYU pragma: export */
 
 /* ----------------
  *		pg_policy definition. cpp turns this into
diff --git a/src/include/catalog/pg_proc.h b/src/include/catalog/pg_proc.h
index 51f43092415..23cb114700e 100644
--- a/src/include/catalog/pg_proc.h
+++ b/src/include/catalog/pg_proc.h
@@ -19,7 +19,7 @@
 
 #include "catalog/genbki.h"
 #include "catalog/objectaddress.h"
-#include "catalog/pg_proc_d.h"
+#include "catalog/pg_proc_d.h"	/* IWYU pragma: export */
 #include "nodes/pg_list.h"
 
 /* ----------------
diff --git a/src/include/catalog/pg_publication.h b/src/include/catalog/pg_publication.h
index e2d894a2ff5..709c8c18ae6 100644
--- a/src/include/catalog/pg_publication.h
+++ b/src/include/catalog/pg_publication.h
@@ -19,7 +19,7 @@
 
 #include "catalog/genbki.h"
 #include "catalog/objectaddress.h"
-#include "catalog/pg_publication_d.h"
+#include "catalog/pg_publication_d.h"	/* IWYU pragma: export */
 
 /* ----------------
  *		pg_publication definition.  cpp turns this into
diff --git a/src/include/catalog/pg_publication_namespace.h b/src/include/catalog/pg_publication_namespace.h
index 1cfb557684f..0b1ba009688 100644
--- a/src/include/catalog/pg_publication_namespace.h
+++ b/src/include/catalog/pg_publication_namespace.h
@@ -19,7 +19,7 @@
 #define PG_PUBLICATION_NAMESPACE_H
 
 #include "catalog/genbki.h"
-#include "catalog/pg_publication_namespace_d.h"
+#include "catalog/pg_publication_namespace_d.h" /* IWYU pragma: export */
 
 
 /* ----------------
diff --git a/src/include/catalog/pg_publication_rel.h b/src/include/catalog/pg_publication_rel.h
index 25fa630675a..443ce637656 100644
--- a/src/include/catalog/pg_publication_rel.h
+++ b/src/include/catalog/pg_publication_rel.h
@@ -19,7 +19,7 @@
 #define PG_PUBLICATION_REL_H
 
 #include "catalog/genbki.h"
-#include "catalog/pg_publication_rel_d.h"
+#include "catalog/pg_publication_rel_d.h"	/* IWYU pragma: export */
 
 /* ----------------
  *		pg_publication_rel definition.  cpp turns this into
diff --git a/src/include/catalog/pg_range.h b/src/include/catalog/pg_range.h
index 0bd3ab688bd..5f8c1a0621f 100644
--- a/src/include/catalog/pg_range.h
+++ b/src/include/catalog/pg_range.h
@@ -19,7 +19,7 @@
 #define PG_RANGE_H
 
 #include "catalog/genbki.h"
-#include "catalog/pg_range_d.h"
+#include "catalog/pg_range_d.h" /* IWYU pragma: export */
 
 /* ----------------
  *		pg_range definition.  cpp turns this into
diff --git a/src/include/catalog/pg_replication_origin.h b/src/include/catalog/pg_replication_origin.h
index e9bc0209c26..ed0051d7f0b 100644
--- a/src/include/catalog/pg_replication_origin.h
+++ b/src/include/catalog/pg_replication_origin.h
@@ -20,7 +20,7 @@
 
 #include "access/xlogdefs.h"
 #include "catalog/genbki.h"
-#include "catalog/pg_replication_origin_d.h"
+#include "catalog/pg_replication_origin_d.h"	/* IWYU pragma: export */
 
 /* ----------------
  *		pg_replication_origin.  cpp turns this into
diff --git a/src/include/catalog/pg_rewrite.h b/src/include/catalog/pg_rewrite.h
index e42ff73d29c..cb1cafc1851 100644
--- a/src/include/catalog/pg_rewrite.h
+++ b/src/include/catalog/pg_rewrite.h
@@ -22,7 +22,7 @@
 #define PG_REWRITE_H
 
 #include "catalog/genbki.h"
-#include "catalog/pg_rewrite_d.h"
+#include "catalog/pg_rewrite_d.h"	/* IWYU pragma: export */
 
 /* ----------------
  *		pg_rewrite definition.  cpp turns this into
diff --git a/src/include/catalog/pg_seclabel.h b/src/include/catalog/pg_seclabel.h
index 5f6f5c9c059..0bde07fc1ac 100644
--- a/src/include/catalog/pg_seclabel.h
+++ b/src/include/catalog/pg_seclabel.h
@@ -18,7 +18,7 @@
 #define PG_SECLABEL_H
 
 #include "catalog/genbki.h"
-#include "catalog/pg_seclabel_d.h"
+#include "catalog/pg_seclabel_d.h"	/* IWYU pragma: export */
 
 /* ----------------
  *		pg_seclabel definition.  cpp turns this into
diff --git a/src/include/catalog/pg_sequence.h b/src/include/catalog/pg_sequence.h
index 8c3f0dd1ab8..aa1aed07cf4 100644
--- a/src/include/catalog/pg_sequence.h
+++ b/src/include/catalog/pg_sequence.h
@@ -18,7 +18,7 @@
 #define PG_SEQUENCE_H
 
 #include "catalog/genbki.h"
-#include "catalog/pg_sequence_d.h"
+#include "catalog/pg_sequence_d.h"	/* IWYU pragma: export */
 
 CATALOG(pg_sequence,2224,SequenceRelationId)
 {
diff --git a/src/include/catalog/pg_shdepend.h b/src/include/catalog/pg_shdepend.h
index 7bd48ab97cb..e310cb46774 100644
--- a/src/include/catalog/pg_shdepend.h
+++ b/src/include/catalog/pg_shdepend.h
@@ -28,7 +28,7 @@
 #define PG_SHDEPEND_H
 
 #include "catalog/genbki.h"
-#include "catalog/pg_shdepend_d.h"
+#include "catalog/pg_shdepend_d.h"	/* IWYU pragma: export */
 
 /* ----------------
  *		pg_shdepend definition.  cpp turns this into
diff --git a/src/include/catalog/pg_shdescription.h b/src/include/catalog/pg_shdescription.h
index c9433d229ef..7666d08c1c3 100644
--- a/src/include/catalog/pg_shdescription.h
+++ b/src/include/catalog/pg_shdescription.h
@@ -31,7 +31,7 @@
 #define PG_SHDESCRIPTION_H
 
 #include "catalog/genbki.h"
-#include "catalog/pg_shdescription_d.h"
+#include "catalog/pg_shdescription_d.h" /* IWYU pragma: export */
 
 /* ----------------
  *		pg_shdescription definition.    cpp turns this into
diff --git a/src/include/catalog/pg_shseclabel.h b/src/include/catalog/pg_shseclabel.h
index 478d46969c0..68c6456e88c 100644
--- a/src/include/catalog/pg_shseclabel.h
+++ b/src/include/catalog/pg_shseclabel.h
@@ -18,7 +18,7 @@
 #define PG_SHSECLABEL_H
 
 #include "catalog/genbki.h"
-#include "catalog/pg_shseclabel_d.h"
+#include "catalog/pg_shseclabel_d.h"	/* IWYU pragma: export */
 
 /* ----------------
  *		pg_shseclabel definition. cpp turns this into
diff --git a/src/include/catalog/pg_statistic.h b/src/include/catalog/pg_statistic.h
index 041e626390a..2222f96b77b 100644
--- a/src/include/catalog/pg_statistic.h
+++ b/src/include/catalog/pg_statistic.h
@@ -19,7 +19,7 @@
 #define PG_STATISTIC_H
 
 #include "catalog/genbki.h"
-#include "catalog/pg_statistic_d.h"
+#include "catalog/pg_statistic_d.h" /* IWYU pragma: export */
 
 /* ----------------
  *		pg_statistic definition.  cpp turns this into
diff --git a/src/include/catalog/pg_statistic_ext.h b/src/include/catalog/pg_statistic_ext.h
index 50a5c021edf..e15372c728a 100644
--- a/src/include/catalog/pg_statistic_ext.h
+++ b/src/include/catalog/pg_statistic_ext.h
@@ -23,7 +23,7 @@
 #define PG_STATISTIC_EXT_H
 
 #include "catalog/genbki.h"
-#include "catalog/pg_statistic_ext_d.h"
+#include "catalog/pg_statistic_ext_d.h" /* IWYU pragma: export */
 
 /* ----------------
  *		pg_statistic_ext definition.  cpp turns this into
diff --git a/src/include/catalog/pg_statistic_ext_data.h b/src/include/catalog/pg_statistic_ext_data.h
index 18b00ce8b52..67914123292 100644
--- a/src/include/catalog/pg_statistic_ext_data.h
+++ b/src/include/catalog/pg_statistic_ext_data.h
@@ -21,7 +21,7 @@
 #define PG_STATISTIC_EXT_DATA_H
 
 #include "catalog/genbki.h"
-#include "catalog/pg_statistic_ext_data_d.h"
+#include "catalog/pg_statistic_ext_data_d.h"	/* IWYU pragma: export */
 
 /* ----------------
  *		pg_statistic_ext_data definition.  cpp turns this into
diff --git a/src/include/catalog/pg_subscription.h b/src/include/catalog/pg_subscription.h
index beaff6578a6..86bcfcf43fc 100644
--- a/src/include/catalog/pg_subscription.h
+++ b/src/include/catalog/pg_subscription.h
@@ -19,7 +19,7 @@
 
 #include "access/xlogdefs.h"
 #include "catalog/genbki.h"
-#include "catalog/pg_subscription_d.h"
+#include "catalog/pg_subscription_d.h"	/* IWYU pragma: export */
 #include "lib/stringinfo.h"
 #include "nodes/pg_list.h"
 
diff --git a/src/include/catalog/pg_subscription_rel.h b/src/include/catalog/pg_subscription_rel.h
index 8244ad537ae..6290f5f440d 100644
--- a/src/include/catalog/pg_subscription_rel.h
+++ b/src/include/catalog/pg_subscription_rel.h
@@ -20,7 +20,7 @@
 
 #include "access/xlogdefs.h"
 #include "catalog/genbki.h"
-#include "catalog/pg_subscription_rel_d.h"
+#include "catalog/pg_subscription_rel_d.h"	/* IWYU pragma: export */
 #include "nodes/pg_list.h"
 
 /* ----------------
diff --git a/src/include/catalog/pg_tablespace.h b/src/include/catalog/pg_tablespace.h
index 6b9bdcf8b05..fc624132f10 100644
--- a/src/include/catalog/pg_tablespace.h
+++ b/src/include/catalog/pg_tablespace.h
@@ -19,7 +19,7 @@
 #define PG_TABLESPACE_H
 
 #include "catalog/genbki.h"
-#include "catalog/pg_tablespace_d.h"
+#include "catalog/pg_tablespace_d.h"	/* IWYU pragma: export */
 
 /* ----------------
  *		pg_tablespace definition.  cpp turns this into
diff --git a/src/include/catalog/pg_transform.h b/src/include/catalog/pg_transform.h
index 3b69960af60..e85a0beb7a3 100644
--- a/src/include/catalog/pg_transform.h
+++ b/src/include/catalog/pg_transform.h
@@ -19,7 +19,7 @@
 #define PG_TRANSFORM_H
 
 #include "catalog/genbki.h"
-#include "catalog/pg_transform_d.h"
+#include "catalog/pg_transform_d.h" /* IWYU pragma: export */
 
 /* ----------------
  *		pg_transform definition.  cpp turns this into
diff --git a/src/include/catalog/pg_trigger.h b/src/include/catalog/pg_trigger.h
index 7fdff161184..418f0d44df4 100644
--- a/src/include/catalog/pg_trigger.h
+++ b/src/include/catalog/pg_trigger.h
@@ -19,7 +19,7 @@
 #define PG_TRIGGER_H
 
 #include "catalog/genbki.h"
-#include "catalog/pg_trigger_d.h"
+#include "catalog/pg_trigger_d.h"	/* IWYU pragma: export */
 
 /* ----------------
  *		pg_trigger definition.  cpp turns this into
diff --git a/src/include/catalog/pg_ts_config.h b/src/include/catalog/pg_ts_config.h
index fc0bf447b1d..6983f976764 100644
--- a/src/include/catalog/pg_ts_config.h
+++ b/src/include/catalog/pg_ts_config.h
@@ -20,7 +20,7 @@
 #define PG_TS_CONFIG_H
 
 #include "catalog/genbki.h"
-#include "catalog/pg_ts_config_d.h"
+#include "catalog/pg_ts_config_d.h" /* IWYU pragma: export */
 
 /* ----------------
  *		pg_ts_config definition.  cpp turns this into
diff --git a/src/include/catalog/pg_ts_dict.h b/src/include/catalog/pg_ts_dict.h
index 1320468de0e..88dee457d21 100644
--- a/src/include/catalog/pg_ts_dict.h
+++ b/src/include/catalog/pg_ts_dict.h
@@ -19,7 +19,7 @@
 #define PG_TS_DICT_H
 
 #include "catalog/genbki.h"
-#include "catalog/pg_ts_dict_d.h"
+#include "catalog/pg_ts_dict_d.h"	/* IWYU pragma: export */
 
 /* ----------------
  *		pg_ts_dict definition.  cpp turns this into
diff --git a/src/include/catalog/pg_ts_parser.h b/src/include/catalog/pg_ts_parser.h
index 909644c96f2..9a9e2bff7bd 100644
--- a/src/include/catalog/pg_ts_parser.h
+++ b/src/include/catalog/pg_ts_parser.h
@@ -19,7 +19,7 @@
 #define PG_TS_PARSER_H
 
 #include "catalog/genbki.h"
-#include "catalog/pg_ts_parser_d.h"
+#include "catalog/pg_ts_parser_d.h" /* IWYU pragma: export */
 
 /* ----------------
  *		pg_ts_parser definition.  cpp turns this into
diff --git a/src/include/catalog/pg_ts_template.h b/src/include/catalog/pg_ts_template.h
index 0562a4a7583..9f155de7c94 100644
--- a/src/include/catalog/pg_ts_template.h
+++ b/src/include/catalog/pg_ts_template.h
@@ -19,7 +19,7 @@
 #define PG_TS_TEMPLATE_H
 
 #include "catalog/genbki.h"
-#include "catalog/pg_ts_template_d.h"
+#include "catalog/pg_ts_template_d.h"	/* IWYU pragma: export */
 
 /* ----------------
  *		pg_ts_template definition.  cpp turns this into
diff --git a/src/include/catalog/pg_type.h b/src/include/catalog/pg_type.h
index e9259697321..c33c03873d4 100644
--- a/src/include/catalog/pg_type.h
+++ b/src/include/catalog/pg_type.h
@@ -20,7 +20,7 @@
 
 #include "catalog/genbki.h"
 #include "catalog/objectaddress.h"
-#include "catalog/pg_type_d.h"
+#include "catalog/pg_type_d.h"	/* IWYU pragma: export */
 #include "nodes/nodes.h"
 
 /* ----------------
diff --git a/src/include/catalog/pg_user_mapping.h b/src/include/catalog/pg_user_mapping.h
index 3632448cce0..21c5c1c201e 100644
--- a/src/include/catalog/pg_user_mapping.h
+++ b/src/include/catalog/pg_user_mapping.h
@@ -18,7 +18,7 @@
 #define PG_USER_MAPPING_H
 
 #include "catalog/genbki.h"
-#include "catalog/pg_user_mapping_d.h"
+#include "catalog/pg_user_mapping_d.h"	/* IWYU pragma: export */
 
 /* ----------------
  *		pg_user_mapping definition.  cpp turns this into
-- 
2.47.1

#2Tom Lane
tgl@sss.pgh.pa.us
In reply to: Peter Eisentraut (#1)
Re: IWYU annotations

Peter Eisentraut <peter@eisentraut.org> writes:

I have done a pass over much of the source code with
include-what-you-use (IWYU) to remove superfluous includes (commits
dbbca2cf299, 9be4e5d293b, ecb5af77987). Along the way I have collected
some pragma annotations to deal with exceptions and special cases and
peculiarities of the PostgreSQL source code header structures (see [0]
for description). Here I'm proposing a set of patches to add such
annotations in commonly useful cases that should deal with most of the
noise.

This seems to be going in the direction that there will be Yet Another
tool that committers have to know everything about in order to not
commit bad code. I'm feeling resistant to that, mainly because I'm
far from convinced that IWYU brings us enough value to justify
everybody having to learn about it. (The fact that the predecessor
tool pgrminclude hasn't been used in a dozen years, and nobody seems
to care, speaks volumes here.)

In particular, this patchset introduces what seem like very
error-prone setups, such as in rmgrdesc.c where there's now one
group of #include's with "pragma: begin_keep/pragma: end_keep"
around it and another group without. Most of us are likely
to just blindly stick a new #include into alphabetical order
somewhere in there and not notice that there's now an additional
concern. The fact that that you've added precisely zero
documentation about what these pragmas are doesn't help.

regards, tom lane

#3Peter Eisentraut
peter@eisentraut.org
In reply to: Tom Lane (#2)
Re: IWYU annotations

On 09.12.24 17:37, Tom Lane wrote:

Peter Eisentraut <peter@eisentraut.org> writes:

I have done a pass over much of the source code with
include-what-you-use (IWYU) to remove superfluous includes (commits
dbbca2cf299, 9be4e5d293b, ecb5af77987). Along the way I have collected
some pragma annotations to deal with exceptions and special cases and
peculiarities of the PostgreSQL source code header structures (see [0]
for description). Here I'm proposing a set of patches to add such
annotations in commonly useful cases that should deal with most of the
noise.

This seems to be going in the direction that there will be Yet Another
tool that committers have to know everything about in order to not
commit bad code. I'm feeling resistant to that, mainly because I'm
far from convinced that IWYU brings us enough value to justify
everybody having to learn about it.

It's not realistic at the moment for it to be a tool that everyone needs
to use and everyone needs to keep 100% clean. We're certainly very far
from that being feasible at the moment.

I see it useful in two areas:

First, when you add new files or move lots of code around, you can have
it provide an informed opinion about what includes to keep and add.
Because in practice that's mostly a crapshoot nowadays. An example from
a current patch under review:

$ iwyu_tool.py -p build src/backend/libpq/auth-oauth.c
...
../src/backend/libpq/auth-oauth.c should remove these lines:
- #include <fcntl.h> // lines 19-19
- #include <unistd.h> // lines 18-18
- #include "storage/fd.h" // lines 28-28

Second, clangd (the language server) has support for this also, and so
depending on local configuration and preferences, it can highlight
missing or redundant includes or even add some automatically as you
edit. (The latter obviously needs some manual supervision, but it is
arguably kind of neat that you don't need to jump to the top and
manually add includes as you type in new code that needs an additional
header.)

But in order for either of this to work, it needs to have some
information about basic PostgreSQL code conventions. Otherwise, it will
also do this:

../src/backend/libpq/auth-oauth.c should add these lines:
...
#include <stdbool.h> // for false, bool, true
#include <stddef.h> // for NULL, size_t
#include "c.h" // for Assert, explicit_bzero,
pg_strncasecmp
...

because it doesn't know that the convention is that you are supposed to
include "postgres.h" (or one of the other always-first headers) and then
everything that it brings it should usually not be included again
directly. (Or conversely in some cases it will suggest to remove the
include of "postgres.h" because it doesn't provide anything of use.)

So right now you get a bunch of noise and misleading information for
each file and the whole clangd support is of limited use. That's what
my patch set is mainly trying to address.

In particular, this patchset introduces what seem like very
error-prone setups, such as in rmgrdesc.c where there's now one
group of #include's with "pragma: begin_keep/pragma: end_keep"
around it and another group without. Most of us are likely
to just blindly stick a new #include into alphabetical order
somewhere in there and not notice that there's now an additional
concern. The fact that that you've added precisely zero
documentation about what these pragmas are doesn't help.

It's a fair point that some documentation could be provided. I suppose
we don't want to verbosely explain each pragma individually. Should
there be some central explanation, maybe in src/tools/pginclude/README?

Note that if you google like "IWYU pragma: export" it will take you to
the upstream documentation as the first hit, so the full documentation
is pretty easy to find.

#4Tom Lane
tgl@sss.pgh.pa.us
In reply to: Peter Eisentraut (#3)
Re: IWYU annotations

Peter Eisentraut <peter@eisentraut.org> writes:

On 09.12.24 17:37, Tom Lane wrote:

In particular, this patchset introduces what seem like very
error-prone setups, such as in rmgrdesc.c where there's now one
group of #include's with "pragma: begin_keep/pragma: end_keep"
around it and another group without. Most of us are likely
to just blindly stick a new #include into alphabetical order
somewhere in there and not notice that there's now an additional
concern. The fact that that you've added precisely zero
documentation about what these pragmas are doesn't help.

It's a fair point that some documentation could be provided. I suppose
we don't want to verbosely explain each pragma individually. Should
there be some central explanation, maybe in src/tools/pginclude/README?

That might do, but perhaps instead in the "PostgreSQL Coding
Conventions" chapter of the SGML docs? Actually, I think we could do
with a centralized explanation of our inclusion conventions --- I'm
not sure that the whole business of "postgres.h or a sibling must be
first" is explained in any easy-to-find place. This topic would
likely fit well with such an explanation.

But really, the point I was trying to make above is that I don't
want this to break our very long-standing convention that headers
should be #include'd alphabetically and there is never a need to
impose some other order (at least not without lots of commentary
about it at the scene of the crime). The way you've done it here
is just asking for trouble, IMO. If that means redundant pragma
commands, so be it.

regards, tom lane

#5Peter Eisentraut
peter@eisentraut.org
In reply to: Tom Lane (#4)
3 attachment(s)
Re: IWYU annotations

On 02.01.25 17:15, Tom Lane wrote:

It's a fair point that some documentation could be provided. I suppose
we don't want to verbosely explain each pragma individually. Should
there be some central explanation, maybe in src/tools/pginclude/README?

That might do, but perhaps instead in the "PostgreSQL Coding
Conventions" chapter of the SGML docs? Actually, I think we could do
with a centralized explanation of our inclusion conventions --- I'm
not sure that the whole business of "postgres.h or a sibling must be
first" is explained in any easy-to-find place. This topic would
likely fit well with such an explanation.

In this updated patch set, I've just added a bit of info into
src/tools/pginclude/README. Updating the coding convention
documentation like you suggest also sounds like a good idea, but from my
perspective I would need to do further research to pin down what those
actually are, so I'm leaving that as a separate project.

(See for example the business in src/tools/pginclude/headerscheck about
guessing which the appropriate first header file should be for each
component. That kind of thing perhaps ought to be more formalized.)

But really, the point I was trying to make above is that I don't
want this to break our very long-standing convention that headers
should be #include'd alphabetically and there is never a need to
impose some other order (at least not without lots of commentary
about it at the scene of the crime). The way you've done it here
is just asking for trouble, IMO. If that means redundant pragma
commands, so be it.

Yeah, that's a fair point. I have removed that part from my patch set.

Attachments:

v2-0001-IWYU-widely-useful-pragmas.patchtext/plain; charset=UTF-8; name=v2-0001-IWYU-widely-useful-pragmas.patchDownload
From b185a841272ef14af7dcdf99759d0e6d775f6746 Mon Sep 17 00:00:00 2001
From: Peter Eisentraut <peter@eisentraut.org>
Date: Thu, 9 Jan 2025 12:34:09 +0100
Subject: [PATCH v2 1/3] IWYU widely useful pragmas

Add various widely useful "IWYU pragma" annotations, such as

- Common header files such as c.h, postgres.h should be "always_keep".

- System headers included in c.h, postgres.h etc. should be considered
  "export".

- Some portability headers such as getopt_long.h should be
  "always_keep", so they are not considered superfluous on some
  platforms.

- Certain system headers included from portability headers should be
  considered "export" because the purpose of the portability header is
  to wrap them.

- Superfluous includes marked as "for backward compatibility" get a
  formal IWYU annotation.

- Generated header included in utils/syscache.h is marked exported.
  This is a very commonly used include and this avoids lots of
  complaints.

Discussion: https://www.postgresql.org/message-id/flat/9395d484-eff4-47c2-b276-8e228526c8ae@eisentraut.org
---
 src/include/c.h                  | 5 +++++
 src/include/getopt_long.h        | 3 ++-
 src/include/pg_getopt.h          | 5 +++--
 src/include/pg_trace.h           | 2 +-
 src/include/pgstat.h             | 6 +++---
 src/include/port/pg_iovec.h      | 2 +-
 src/include/port/pg_pthread.h    | 2 +-
 src/include/postgres.h           | 5 +++++
 src/include/postgres_ext.h       | 1 +
 src/include/postgres_fe.h        | 5 +++++
 src/include/utils/syscache.h     | 2 +-
 src/interfaces/libpq/libpq-int.h | 2 ++
 12 files changed, 30 insertions(+), 10 deletions(-)

diff --git a/src/include/c.h b/src/include/c.h
index ab6a49aeca4..a14c6315162 100644
--- a/src/include/c.h
+++ b/src/include/c.h
@@ -16,6 +16,7 @@
  *
  *-------------------------------------------------------------------------
  */
+/* IWYU pragma: always_keep */
 /*
  *----------------------------------------------------------------
  *	 TABLE OF CONTENTS
@@ -46,6 +47,8 @@
 #ifndef C_H
 #define C_H
 
+/* IWYU pragma: begin_exports */
+
 /*
  * These headers must be included before any system headers, because on some
  * platforms they affect the behavior of the system headers (for example, by
@@ -1327,4 +1330,6 @@ typedef intptr_t sigjmp_buf[5];
 /* /port compatibility functions */
 #include "port.h"
 
+/* IWYU pragma: end_exports */
+
 #endif							/* C_H */
diff --git a/src/include/getopt_long.h b/src/include/getopt_long.h
index 33b4755a664..e7bdf909f7b 100644
--- a/src/include/getopt_long.h
+++ b/src/include/getopt_long.h
@@ -6,10 +6,11 @@
  *
  * src/include/getopt_long.h
  */
+/* IWYU pragma: always_keep */
 #ifndef GETOPT_LONG_H
 #define GETOPT_LONG_H
 
-#include "pg_getopt.h"
+#include "pg_getopt.h"			/* IWYU pragma: export */
 
 #ifndef HAVE_STRUCT_OPTION
 
diff --git a/src/include/pg_getopt.h b/src/include/pg_getopt.h
index 2e2d64f4a26..aad0886c054 100644
--- a/src/include/pg_getopt.h
+++ b/src/include/pg_getopt.h
@@ -15,15 +15,16 @@
  *
  * src/include/pg_getopt.h
  */
+/* IWYU pragma: always_keep */
 #ifndef PG_GETOPT_H
 #define PG_GETOPT_H
 
 /* POSIX says getopt() is provided by unistd.h */
-#include <unistd.h>
+#include <unistd.h>				/* IWYU pragma: export */
 
 /* rely on the system's getopt.h if present */
 #ifdef HAVE_GETOPT_H
-#include <getopt.h>
+#include <getopt.h>				/* IWYU pragma: export */
 #endif
 
 /*
diff --git a/src/include/pg_trace.h b/src/include/pg_trace.h
index aca6d727d30..c82f34726f7 100644
--- a/src/include/pg_trace.h
+++ b/src/include/pg_trace.h
@@ -12,6 +12,6 @@
 #ifndef PG_TRACE_H
 #define PG_TRACE_H
 
-#include "utils/probes.h"
+#include "utils/probes.h"		/* IWYU pragma: export */
 
 #endif							/* PG_TRACE_H */
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index 6475889c58c..8d1c8946b9d 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -16,10 +16,10 @@
 #include "portability/instr_time.h"
 #include "postmaster/pgarch.h"	/* for MAX_XFN_CHARS */
 #include "replication/conflict.h"
-#include "utils/backend_progress.h" /* for backward compatibility */
-#include "utils/backend_status.h"	/* for backward compatibility */
+#include "utils/backend_progress.h" /* for backward compatibility */	/* IWYU pragma: export */
+#include "utils/backend_status.h"	/* for backward compatibility */	/* IWYU pragma: export */
 #include "utils/relcache.h"
-#include "utils/wait_event.h"	/* for backward compatibility */
+#include "utils/wait_event.h"	/* for backward compatibility */	/* IWYU pragma: export */
 
 
 /* ----------
diff --git a/src/include/port/pg_iovec.h b/src/include/port/pg_iovec.h
index f3df9c94639..d9891d3805d 100644
--- a/src/include/port/pg_iovec.h
+++ b/src/include/port/pg_iovec.h
@@ -16,7 +16,7 @@
 #ifndef WIN32
 
 #include <limits.h>
-#include <sys/uio.h>
+#include <sys/uio.h>			/* IWYU pragma: export */
 #include <unistd.h>
 
 #else
diff --git a/src/include/port/pg_pthread.h b/src/include/port/pg_pthread.h
index d102ce9d6f3..4dbb3c8a52f 100644
--- a/src/include/port/pg_pthread.h
+++ b/src/include/port/pg_pthread.h
@@ -13,7 +13,7 @@
 #ifndef PG_PTHREAD_H
 #define PG_PTHREAD_H
 
-#include <pthread.h>
+#include <pthread.h>			/* IWYU pragma: export */
 
 #ifndef HAVE_PTHREAD_BARRIER_WAIT
 
diff --git a/src/include/postgres.h b/src/include/postgres.h
index cdce4823e7e..8a41a668687 100644
--- a/src/include/postgres.h
+++ b/src/include/postgres.h
@@ -14,6 +14,7 @@
  *
  *-------------------------------------------------------------------------
  */
+/* IWYU pragma: always_keep */
 /*
  *----------------------------------------------------------------
  *	 TABLE OF CONTENTS
@@ -42,10 +43,14 @@
 #ifndef POSTGRES_H
 #define POSTGRES_H
 
+/* IWYU pragma: begin_exports */
+
 #include "c.h"
 #include "utils/elog.h"
 #include "utils/palloc.h"
 
+/* IWYU pragma: end_exports */
+
 /* ----------------------------------------------------------------
  *				Section 1:	Datum type + support functions
  * ----------------------------------------------------------------
diff --git a/src/include/postgres_ext.h b/src/include/postgres_ext.h
index 202eb049622..9f2e3c52972 100644
--- a/src/include/postgres_ext.h
+++ b/src/include/postgres_ext.h
@@ -19,6 +19,7 @@
  *
  *-------------------------------------------------------------------------
  */
+/* IWYU pragma: always_keep */
 
 #ifndef POSTGRES_EXT_H
 #define POSTGRES_EXT_H
diff --git a/src/include/postgres_fe.h b/src/include/postgres_fe.h
index dc6dc6e812a..a3f65b1dca4 100644
--- a/src/include/postgres_fe.h
+++ b/src/include/postgres_fe.h
@@ -15,6 +15,7 @@
  *
  *-------------------------------------------------------------------------
  */
+/* IWYU pragma: always_keep */
 #ifndef POSTGRES_FE_H
 #define POSTGRES_FE_H
 
@@ -22,8 +23,12 @@
 #define FRONTEND 1
 #endif
 
+/* IWYU pragma: begin_exports */
+
 #include "c.h"
 
 #include "common/fe_memutils.h"
 
+/* IWYU pragma: end_exports */
+
 #endif							/* POSTGRES_FE_H */
diff --git a/src/include/utils/syscache.h b/src/include/utils/syscache.h
index 537fd03e8bd..3039713259e 100644
--- a/src/include/utils/syscache.h
+++ b/src/include/utils/syscache.h
@@ -20,7 +20,7 @@
 #include "access/htup.h"
 /* we intentionally do not include utils/catcache.h here */
 
-#include "catalog/syscache_ids.h"
+#include "catalog/syscache_ids.h"	/* IWYU pragma: export */
 
 extern void InitCatalogCache(void);
 extern void InitCatalogCachePhase2(void);
diff --git a/src/interfaces/libpq/libpq-int.h b/src/interfaces/libpq/libpq-int.h
index e9c74e1faf8..0a82e31d83a 100644
--- a/src/interfaces/libpq/libpq-int.h
+++ b/src/interfaces/libpq/libpq-int.h
@@ -41,6 +41,7 @@
 #include "fe-auth-sasl.h"
 #include "pqexpbuffer.h"
 
+/* IWYU pragma: begin_exports */
 #ifdef ENABLE_GSS
 #if defined(HAVE_GSSAPI_H)
 #include <gssapi.h>
@@ -48,6 +49,7 @@
 #include <gssapi/gssapi.h>
 #endif
 #endif
+/* IWYU pragma: end_exports */
 
 #ifdef ENABLE_SSPI
 #define SECURITY_WIN32
-- 
2.47.1

v2-0002-IWYU-pragmas-for-catalog-headers.patchtext/plain; charset=UTF-8; name=v2-0002-IWYU-pragmas-for-catalog-headers.patchDownload
From f9c33711a2b96ea0aefdfd36b04cfdfb0b5303be Mon Sep 17 00:00:00 2001
From: Peter Eisentraut <peter@eisentraut.org>
Date: Mon, 9 Dec 2024 12:25:25 +0100
Subject: [PATCH v2 2/3] IWYU pragmas for catalog headers

Add "IWYU pragma: export" annotations in each catalog header file so
that, for instance, including "catalog/pg_aggregate.h" is considered
acceptable in place of "catalog/pg_aggregate_d.h".  This is very
common and it seems better to silence IWYU about it than trying to fix
this up.

Discussion: https://www.postgresql.org/message-id/flat/9395d484-eff4-47c2-b276-8e228526c8ae@eisentraut.org
---
 src/include/catalog/pg_aggregate.h             | 2 +-
 src/include/catalog/pg_am.h                    | 2 +-
 src/include/catalog/pg_amop.h                  | 2 +-
 src/include/catalog/pg_amproc.h                | 2 +-
 src/include/catalog/pg_attrdef.h               | 2 +-
 src/include/catalog/pg_attribute.h             | 2 +-
 src/include/catalog/pg_auth_members.h          | 2 +-
 src/include/catalog/pg_authid.h                | 2 +-
 src/include/catalog/pg_cast.h                  | 2 +-
 src/include/catalog/pg_class.h                 | 2 +-
 src/include/catalog/pg_collation.h             | 2 +-
 src/include/catalog/pg_constraint.h            | 2 +-
 src/include/catalog/pg_conversion.h            | 2 +-
 src/include/catalog/pg_database.h              | 2 +-
 src/include/catalog/pg_db_role_setting.h       | 2 +-
 src/include/catalog/pg_default_acl.h           | 2 +-
 src/include/catalog/pg_depend.h                | 2 +-
 src/include/catalog/pg_description.h           | 2 +-
 src/include/catalog/pg_enum.h                  | 2 +-
 src/include/catalog/pg_event_trigger.h         | 2 +-
 src/include/catalog/pg_extension.h             | 2 +-
 src/include/catalog/pg_foreign_data_wrapper.h  | 2 +-
 src/include/catalog/pg_foreign_server.h        | 2 +-
 src/include/catalog/pg_foreign_table.h         | 2 +-
 src/include/catalog/pg_index.h                 | 2 +-
 src/include/catalog/pg_inherits.h              | 2 +-
 src/include/catalog/pg_init_privs.h            | 2 +-
 src/include/catalog/pg_language.h              | 2 +-
 src/include/catalog/pg_largeobject.h           | 2 +-
 src/include/catalog/pg_largeobject_metadata.h  | 2 +-
 src/include/catalog/pg_namespace.h             | 2 +-
 src/include/catalog/pg_opclass.h               | 2 +-
 src/include/catalog/pg_operator.h              | 2 +-
 src/include/catalog/pg_opfamily.h              | 2 +-
 src/include/catalog/pg_parameter_acl.h         | 2 +-
 src/include/catalog/pg_partitioned_table.h     | 2 +-
 src/include/catalog/pg_policy.h                | 2 +-
 src/include/catalog/pg_proc.h                  | 2 +-
 src/include/catalog/pg_publication.h           | 2 +-
 src/include/catalog/pg_publication_namespace.h | 2 +-
 src/include/catalog/pg_publication_rel.h       | 2 +-
 src/include/catalog/pg_range.h                 | 2 +-
 src/include/catalog/pg_replication_origin.h    | 2 +-
 src/include/catalog/pg_rewrite.h               | 2 +-
 src/include/catalog/pg_seclabel.h              | 2 +-
 src/include/catalog/pg_sequence.h              | 2 +-
 src/include/catalog/pg_shdepend.h              | 2 +-
 src/include/catalog/pg_shdescription.h         | 2 +-
 src/include/catalog/pg_shseclabel.h            | 2 +-
 src/include/catalog/pg_statistic.h             | 2 +-
 src/include/catalog/pg_statistic_ext.h         | 2 +-
 src/include/catalog/pg_statistic_ext_data.h    | 2 +-
 src/include/catalog/pg_subscription.h          | 2 +-
 src/include/catalog/pg_subscription_rel.h      | 2 +-
 src/include/catalog/pg_tablespace.h            | 2 +-
 src/include/catalog/pg_transform.h             | 2 +-
 src/include/catalog/pg_trigger.h               | 2 +-
 src/include/catalog/pg_ts_config.h             | 2 +-
 src/include/catalog/pg_ts_dict.h               | 2 +-
 src/include/catalog/pg_ts_parser.h             | 2 +-
 src/include/catalog/pg_ts_template.h           | 2 +-
 src/include/catalog/pg_type.h                  | 2 +-
 src/include/catalog/pg_user_mapping.h          | 2 +-
 63 files changed, 63 insertions(+), 63 deletions(-)

diff --git a/src/include/catalog/pg_aggregate.h b/src/include/catalog/pg_aggregate.h
index 80ae59716e4..c15f8d2c9fc 100644
--- a/src/include/catalog/pg_aggregate.h
+++ b/src/include/catalog/pg_aggregate.h
@@ -19,7 +19,7 @@
 #define PG_AGGREGATE_H
 
 #include "catalog/genbki.h"
-#include "catalog/pg_aggregate_d.h"
+#include "catalog/pg_aggregate_d.h" /* IWYU pragma: export */
 
 #include "catalog/objectaddress.h"
 #include "nodes/pg_list.h"
diff --git a/src/include/catalog/pg_am.h b/src/include/catalog/pg_am.h
index 603bb5b2dec..6e98a0930c2 100644
--- a/src/include/catalog/pg_am.h
+++ b/src/include/catalog/pg_am.h
@@ -19,7 +19,7 @@
 #define PG_AM_H
 
 #include "catalog/genbki.h"
-#include "catalog/pg_am_d.h"
+#include "catalog/pg_am_d.h"	/* IWYU pragma: export */
 
 /* ----------------
  *		pg_am definition.  cpp turns this into
diff --git a/src/include/catalog/pg_amop.h b/src/include/catalog/pg_amop.h
index a68fc5931b3..cc71cab498b 100644
--- a/src/include/catalog/pg_amop.h
+++ b/src/include/catalog/pg_amop.h
@@ -44,7 +44,7 @@
 #define PG_AMOP_H
 
 #include "catalog/genbki.h"
-#include "catalog/pg_amop_d.h"
+#include "catalog/pg_amop_d.h"	/* IWYU pragma: export */
 
 /* ----------------
  *		pg_amop definition.  cpp turns this into
diff --git a/src/include/catalog/pg_amproc.h b/src/include/catalog/pg_amproc.h
index 5490bdc079a..bf8de4618c7 100644
--- a/src/include/catalog/pg_amproc.h
+++ b/src/include/catalog/pg_amproc.h
@@ -33,7 +33,7 @@
 #define PG_AMPROC_H
 
 #include "catalog/genbki.h"
-#include "catalog/pg_amproc_d.h"
+#include "catalog/pg_amproc_d.h"	/* IWYU pragma: export */
 
 /* ----------------
  *		pg_amproc definition.  cpp turns this into
diff --git a/src/include/catalog/pg_attrdef.h b/src/include/catalog/pg_attrdef.h
index d38abb8d23c..192799cfed7 100644
--- a/src/include/catalog/pg_attrdef.h
+++ b/src/include/catalog/pg_attrdef.h
@@ -20,7 +20,7 @@
 
 #include "catalog/genbki.h"
 #include "catalog/objectaddress.h"
-#include "catalog/pg_attrdef_d.h"
+#include "catalog/pg_attrdef_d.h"	/* IWYU pragma: export */
 
 /* ----------------
  *		pg_attrdef definition.  cpp turns this into
diff --git a/src/include/catalog/pg_attribute.h b/src/include/catalog/pg_attribute.h
index 557286f0480..b33c315d233 100644
--- a/src/include/catalog/pg_attribute.h
+++ b/src/include/catalog/pg_attribute.h
@@ -23,7 +23,7 @@
 #define PG_ATTRIBUTE_H
 
 #include "catalog/genbki.h"
-#include "catalog/pg_attribute_d.h"
+#include "catalog/pg_attribute_d.h" /* IWYU pragma: export */
 
 /* ----------------
  *		pg_attribute definition.  cpp turns this into
diff --git a/src/include/catalog/pg_auth_members.h b/src/include/catalog/pg_auth_members.h
index 319960ac0e9..387316e44f0 100644
--- a/src/include/catalog/pg_auth_members.h
+++ b/src/include/catalog/pg_auth_members.h
@@ -20,7 +20,7 @@
 #define PG_AUTH_MEMBERS_H
 
 #include "catalog/genbki.h"
-#include "catalog/pg_auth_members_d.h"
+#include "catalog/pg_auth_members_d.h"	/* IWYU pragma: export */
 
 /* ----------------
  *		pg_auth_members definition.  cpp turns this into
diff --git a/src/include/catalog/pg_authid.h b/src/include/catalog/pg_authid.h
index 93090c5c0f8..b2f3e9d01ee 100644
--- a/src/include/catalog/pg_authid.h
+++ b/src/include/catalog/pg_authid.h
@@ -21,7 +21,7 @@
 #define PG_AUTHID_H
 
 #include "catalog/genbki.h"
-#include "catalog/pg_authid_d.h"
+#include "catalog/pg_authid_d.h"	/* IWYU pragma: export */
 
 /* ----------------
  *		pg_authid definition.  cpp turns this into
diff --git a/src/include/catalog/pg_cast.h b/src/include/catalog/pg_cast.h
index 69aa47922f7..6a0ca337153 100644
--- a/src/include/catalog/pg_cast.h
+++ b/src/include/catalog/pg_cast.h
@@ -22,7 +22,7 @@
 
 #include "catalog/dependency.h"
 #include "catalog/genbki.h"
-#include "catalog/pg_cast_d.h"
+#include "catalog/pg_cast_d.h"	/* IWYU pragma: export */
 
 /* ----------------
  *		pg_cast definition.  cpp turns this into
diff --git a/src/include/catalog/pg_class.h b/src/include/catalog/pg_class.h
index d394db207cb..f0d612ca487 100644
--- a/src/include/catalog/pg_class.h
+++ b/src/include/catalog/pg_class.h
@@ -19,7 +19,7 @@
 #define PG_CLASS_H
 
 #include "catalog/genbki.h"
-#include "catalog/pg_class_d.h"
+#include "catalog/pg_class_d.h" /* IWYU pragma: export */
 
 /* ----------------
  *		pg_class definition.  cpp turns this into
diff --git a/src/include/catalog/pg_collation.h b/src/include/catalog/pg_collation.h
index 1a774118edd..7c5d5b11300 100644
--- a/src/include/catalog/pg_collation.h
+++ b/src/include/catalog/pg_collation.h
@@ -19,7 +19,7 @@
 #define PG_COLLATION_H
 
 #include "catalog/genbki.h"
-#include "catalog/pg_collation_d.h"
+#include "catalog/pg_collation_d.h" /* IWYU pragma: export */
 
 /* ----------------
  *		pg_collation definition.  cpp turns this into
diff --git a/src/include/catalog/pg_constraint.h b/src/include/catalog/pg_constraint.h
index ba35d481db3..708e656e63a 100644
--- a/src/include/catalog/pg_constraint.h
+++ b/src/include/catalog/pg_constraint.h
@@ -20,7 +20,7 @@
 
 #include "catalog/dependency.h"
 #include "catalog/genbki.h"
-#include "catalog/pg_constraint_d.h"
+#include "catalog/pg_constraint_d.h"	/* IWYU pragma: export */
 #include "nodes/pg_list.h"
 
 /* ----------------
diff --git a/src/include/catalog/pg_conversion.h b/src/include/catalog/pg_conversion.h
index b365efbe8f7..477b8d09ae5 100644
--- a/src/include/catalog/pg_conversion.h
+++ b/src/include/catalog/pg_conversion.h
@@ -19,7 +19,7 @@
 
 #include "catalog/genbki.h"
 #include "catalog/objectaddress.h"
-#include "catalog/pg_conversion_d.h"
+#include "catalog/pg_conversion_d.h"	/* IWYU pragma: export */
 
 /* ----------------
  *		pg_conversion definition.  cpp turns this into
diff --git a/src/include/catalog/pg_database.h b/src/include/catalog/pg_database.h
index 9e34a091228..54f0d38c9c9 100644
--- a/src/include/catalog/pg_database.h
+++ b/src/include/catalog/pg_database.h
@@ -19,7 +19,7 @@
 #define PG_DATABASE_H
 
 #include "catalog/genbki.h"
-#include "catalog/pg_database_d.h"
+#include "catalog/pg_database_d.h"	/* IWYU pragma: export */
 
 /* ----------------
  *		pg_database definition.  cpp turns this into
diff --git a/src/include/catalog/pg_db_role_setting.h b/src/include/catalog/pg_db_role_setting.h
index c330941d7c3..be5cde02286 100644
--- a/src/include/catalog/pg_db_role_setting.h
+++ b/src/include/catalog/pg_db_role_setting.h
@@ -20,7 +20,7 @@
 #define PG_DB_ROLE_SETTING_H
 
 #include "catalog/genbki.h"
-#include "catalog/pg_db_role_setting_d.h"
+#include "catalog/pg_db_role_setting_d.h"	/* IWYU pragma: export */
 
 #include "utils/guc.h"
 #include "utils/relcache.h"
diff --git a/src/include/catalog/pg_default_acl.h b/src/include/catalog/pg_default_acl.h
index 6edf337253f..728024b1fa7 100644
--- a/src/include/catalog/pg_default_acl.h
+++ b/src/include/catalog/pg_default_acl.h
@@ -20,7 +20,7 @@
 #define PG_DEFAULT_ACL_H
 
 #include "catalog/genbki.h"
-#include "catalog/pg_default_acl_d.h"
+#include "catalog/pg_default_acl_d.h"	/* IWYU pragma: export */
 
 /* ----------------
  *		pg_default_acl definition.  cpp turns this into
diff --git a/src/include/catalog/pg_depend.h b/src/include/catalog/pg_depend.h
index e9b34a32c2b..8d0daa9bb7a 100644
--- a/src/include/catalog/pg_depend.h
+++ b/src/include/catalog/pg_depend.h
@@ -32,7 +32,7 @@
 #define PG_DEPEND_H
 
 #include "catalog/genbki.h"
-#include "catalog/pg_depend_d.h"
+#include "catalog/pg_depend_d.h"	/* IWYU pragma: export */
 
 /* ----------------
  *		pg_depend definition.  cpp turns this into
diff --git a/src/include/catalog/pg_description.h b/src/include/catalog/pg_description.h
index 0cbfd468aac..4cd2bf90430 100644
--- a/src/include/catalog/pg_description.h
+++ b/src/include/catalog/pg_description.h
@@ -38,7 +38,7 @@
 #define PG_DESCRIPTION_H
 
 #include "catalog/genbki.h"
-#include "catalog/pg_description_d.h"
+#include "catalog/pg_description_d.h"	/* IWYU pragma: export */
 
 /* ----------------
  *		pg_description definition.  cpp turns this into
diff --git a/src/include/catalog/pg_enum.h b/src/include/catalog/pg_enum.h
index ba5d003f5c0..7cb69ae013b 100644
--- a/src/include/catalog/pg_enum.h
+++ b/src/include/catalog/pg_enum.h
@@ -19,7 +19,7 @@
 #define PG_ENUM_H
 
 #include "catalog/genbki.h"
-#include "catalog/pg_enum_d.h"
+#include "catalog/pg_enum_d.h"	/* IWYU pragma: export */
 
 #include "nodes/pg_list.h"
 
diff --git a/src/include/catalog/pg_event_trigger.h b/src/include/catalog/pg_event_trigger.h
index 8a5dc5d209e..bcb516c4f2d 100644
--- a/src/include/catalog/pg_event_trigger.h
+++ b/src/include/catalog/pg_event_trigger.h
@@ -19,7 +19,7 @@
 #define PG_EVENT_TRIGGER_H
 
 #include "catalog/genbki.h"
-#include "catalog/pg_event_trigger_d.h"
+#include "catalog/pg_event_trigger_d.h" /* IWYU pragma: export */
 
 /* ----------------
  *		pg_event_trigger definition.    cpp turns this into
diff --git a/src/include/catalog/pg_extension.h b/src/include/catalog/pg_extension.h
index b9f921c0b4d..9214ebedafa 100644
--- a/src/include/catalog/pg_extension.h
+++ b/src/include/catalog/pg_extension.h
@@ -19,7 +19,7 @@
 #define PG_EXTENSION_H
 
 #include "catalog/genbki.h"
-#include "catalog/pg_extension_d.h"
+#include "catalog/pg_extension_d.h" /* IWYU pragma: export */
 
 /* ----------------
  *		pg_extension definition.  cpp turns this into
diff --git a/src/include/catalog/pg_foreign_data_wrapper.h b/src/include/catalog/pg_foreign_data_wrapper.h
index 6b8a89f466a..d03ab5a4f28 100644
--- a/src/include/catalog/pg_foreign_data_wrapper.h
+++ b/src/include/catalog/pg_foreign_data_wrapper.h
@@ -19,7 +19,7 @@
 #define PG_FOREIGN_DATA_WRAPPER_H
 
 #include "catalog/genbki.h"
-#include "catalog/pg_foreign_data_wrapper_d.h"
+#include "catalog/pg_foreign_data_wrapper_d.h"	/* IWYU pragma: export */
 
 /* ----------------
  *		pg_foreign_data_wrapper definition.  cpp turns this into
diff --git a/src/include/catalog/pg_foreign_server.h b/src/include/catalog/pg_foreign_server.h
index 3d9bd222792..d53f0974c68 100644
--- a/src/include/catalog/pg_foreign_server.h
+++ b/src/include/catalog/pg_foreign_server.h
@@ -18,7 +18,7 @@
 #define PG_FOREIGN_SERVER_H
 
 #include "catalog/genbki.h"
-#include "catalog/pg_foreign_server_d.h"
+#include "catalog/pg_foreign_server_d.h"	/* IWYU pragma: export */
 
 /* ----------------
  *		pg_foreign_server definition.  cpp turns this into
diff --git a/src/include/catalog/pg_foreign_table.h b/src/include/catalog/pg_foreign_table.h
index bc5c7c72b9c..aea94aa3faa 100644
--- a/src/include/catalog/pg_foreign_table.h
+++ b/src/include/catalog/pg_foreign_table.h
@@ -18,7 +18,7 @@
 #define PG_FOREIGN_TABLE_H
 
 #include "catalog/genbki.h"
-#include "catalog/pg_foreign_table_d.h"
+#include "catalog/pg_foreign_table_d.h" /* IWYU pragma: export */
 
 /* ----------------
  *		pg_foreign_table definition.  cpp turns this into
diff --git a/src/include/catalog/pg_index.h b/src/include/catalog/pg_index.h
index 9eb99d31fac..4392b9d221d 100644
--- a/src/include/catalog/pg_index.h
+++ b/src/include/catalog/pg_index.h
@@ -19,7 +19,7 @@
 #define PG_INDEX_H
 
 #include "catalog/genbki.h"
-#include "catalog/pg_index_d.h"
+#include "catalog/pg_index_d.h" /* IWYU pragma: export */
 
 /* ----------------
  *		pg_index definition.  cpp turns this into
diff --git a/src/include/catalog/pg_inherits.h b/src/include/catalog/pg_inherits.h
index b32758ef02e..1d6765ae911 100644
--- a/src/include/catalog/pg_inherits.h
+++ b/src/include/catalog/pg_inherits.h
@@ -19,7 +19,7 @@
 #define PG_INHERITS_H
 
 #include "catalog/genbki.h"
-#include "catalog/pg_inherits_d.h"
+#include "catalog/pg_inherits_d.h"	/* IWYU pragma: export */
 
 #include "nodes/pg_list.h"
 #include "storage/lock.h"
diff --git a/src/include/catalog/pg_init_privs.h b/src/include/catalog/pg_init_privs.h
index 8ac47c3c59b..594efffca8f 100644
--- a/src/include/catalog/pg_init_privs.h
+++ b/src/include/catalog/pg_init_privs.h
@@ -36,7 +36,7 @@
 #define PG_INIT_PRIVS_H
 
 #include "catalog/genbki.h"
-#include "catalog/pg_init_privs_d.h"
+#include "catalog/pg_init_privs_d.h"	/* IWYU pragma: export */
 
 /* ----------------
  *		pg_init_privs definition.  cpp turns this into
diff --git a/src/include/catalog/pg_language.h b/src/include/catalog/pg_language.h
index 22a0fd02e92..3558b99858a 100644
--- a/src/include/catalog/pg_language.h
+++ b/src/include/catalog/pg_language.h
@@ -19,7 +19,7 @@
 #define PG_LANGUAGE_H
 
 #include "catalog/genbki.h"
-#include "catalog/pg_language_d.h"
+#include "catalog/pg_language_d.h"	/* IWYU pragma: export */
 
 /* ----------------
  *		pg_language definition.  cpp turns this into
diff --git a/src/include/catalog/pg_largeobject.h b/src/include/catalog/pg_largeobject.h
index a89e93c6f88..42971bf3bbb 100644
--- a/src/include/catalog/pg_largeobject.h
+++ b/src/include/catalog/pg_largeobject.h
@@ -19,7 +19,7 @@
 #define PG_LARGEOBJECT_H
 
 #include "catalog/genbki.h"
-#include "catalog/pg_largeobject_d.h"
+#include "catalog/pg_largeobject_d.h"	/* IWYU pragma: export */
 #include "utils/snapshot.h"
 
 /* ----------------
diff --git a/src/include/catalog/pg_largeobject_metadata.h b/src/include/catalog/pg_largeobject_metadata.h
index 2278fc9d661..e618cd51e03 100644
--- a/src/include/catalog/pg_largeobject_metadata.h
+++ b/src/include/catalog/pg_largeobject_metadata.h
@@ -20,7 +20,7 @@
 #define PG_LARGEOBJECT_METADATA_H
 
 #include "catalog/genbki.h"
-#include "catalog/pg_largeobject_metadata_d.h"
+#include "catalog/pg_largeobject_metadata_d.h"	/* IWYU pragma: export */
 
 /* ----------------
  *		pg_largeobject_metadata definition. cpp turns this into
diff --git a/src/include/catalog/pg_namespace.h b/src/include/catalog/pg_namespace.h
index d1d00421a1c..affb36f1140 100644
--- a/src/include/catalog/pg_namespace.h
+++ b/src/include/catalog/pg_namespace.h
@@ -19,7 +19,7 @@
 #define PG_NAMESPACE_H
 
 #include "catalog/genbki.h"
-#include "catalog/pg_namespace_d.h"
+#include "catalog/pg_namespace_d.h" /* IWYU pragma: export */
 #include "utils/acl.h"
 
 /* ----------------------------------------------------------------
diff --git a/src/include/catalog/pg_opclass.h b/src/include/catalog/pg_opclass.h
index eef76e3931e..cb63bd9ced6 100644
--- a/src/include/catalog/pg_opclass.h
+++ b/src/include/catalog/pg_opclass.h
@@ -39,7 +39,7 @@
 #define PG_OPCLASS_H
 
 #include "catalog/genbki.h"
-#include "catalog/pg_opclass_d.h"
+#include "catalog/pg_opclass_d.h"	/* IWYU pragma: export */
 
 /* ----------------
  *		pg_opclass definition.  cpp turns this into
diff --git a/src/include/catalog/pg_operator.h b/src/include/catalog/pg_operator.h
index 9525742c7d2..c3ddfb28fa4 100644
--- a/src/include/catalog/pg_operator.h
+++ b/src/include/catalog/pg_operator.h
@@ -20,7 +20,7 @@
 
 #include "catalog/genbki.h"
 #include "catalog/objectaddress.h"
-#include "catalog/pg_operator_d.h"
+#include "catalog/pg_operator_d.h"	/* IWYU pragma: export */
 #include "nodes/pg_list.h"
 
 /* ----------------
diff --git a/src/include/catalog/pg_opfamily.h b/src/include/catalog/pg_opfamily.h
index 2e56d01523c..7472e7e9cfa 100644
--- a/src/include/catalog/pg_opfamily.h
+++ b/src/include/catalog/pg_opfamily.h
@@ -19,7 +19,7 @@
 #define PG_OPFAMILY_H
 
 #include "catalog/genbki.h"
-#include "catalog/pg_opfamily_d.h"
+#include "catalog/pg_opfamily_d.h"	/* IWYU pragma: export */
 
 /* ----------------
  *		pg_opfamily definition. cpp turns this into
diff --git a/src/include/catalog/pg_parameter_acl.h b/src/include/catalog/pg_parameter_acl.h
index dfbf5ab3004..ae4049ba756 100644
--- a/src/include/catalog/pg_parameter_acl.h
+++ b/src/include/catalog/pg_parameter_acl.h
@@ -20,7 +20,7 @@
 #define PG_PARAMETER_ACL_H
 
 #include "catalog/genbki.h"
-#include "catalog/pg_parameter_acl_d.h"
+#include "catalog/pg_parameter_acl_d.h" /* IWYU pragma: export */
 
 /* ----------------
  *		pg_parameter_acl definition.  cpp turns this into
diff --git a/src/include/catalog/pg_partitioned_table.h b/src/include/catalog/pg_partitioned_table.h
index 668547e77e4..0527f347690 100644
--- a/src/include/catalog/pg_partitioned_table.h
+++ b/src/include/catalog/pg_partitioned_table.h
@@ -20,7 +20,7 @@
 #define PG_PARTITIONED_TABLE_H
 
 #include "catalog/genbki.h"
-#include "catalog/pg_partitioned_table_d.h"
+#include "catalog/pg_partitioned_table_d.h" /* IWYU pragma: export */
 
 /* ----------------
  *		pg_partitioned_table definition.  cpp turns this into
diff --git a/src/include/catalog/pg_policy.h b/src/include/catalog/pg_policy.h
index 4fdb30a0a24..3c2498cdf11 100644
--- a/src/include/catalog/pg_policy.h
+++ b/src/include/catalog/pg_policy.h
@@ -19,7 +19,7 @@
 #define PG_POLICY_H
 
 #include "catalog/genbki.h"
-#include "catalog/pg_policy_d.h"
+#include "catalog/pg_policy_d.h"	/* IWYU pragma: export */
 
 /* ----------------
  *		pg_policy definition. cpp turns this into
diff --git a/src/include/catalog/pg_proc.h b/src/include/catalog/pg_proc.h
index fdb1e280711..7c2e8cb4bd3 100644
--- a/src/include/catalog/pg_proc.h
+++ b/src/include/catalog/pg_proc.h
@@ -19,7 +19,7 @@
 
 #include "catalog/genbki.h"
 #include "catalog/objectaddress.h"
-#include "catalog/pg_proc_d.h"
+#include "catalog/pg_proc_d.h"	/* IWYU pragma: export */
 #include "nodes/pg_list.h"
 
 /* ----------------
diff --git a/src/include/catalog/pg_publication.h b/src/include/catalog/pg_publication.h
index 30c0574e858..3c2ae2a960c 100644
--- a/src/include/catalog/pg_publication.h
+++ b/src/include/catalog/pg_publication.h
@@ -19,7 +19,7 @@
 
 #include "catalog/genbki.h"
 #include "catalog/objectaddress.h"
-#include "catalog/pg_publication_d.h"
+#include "catalog/pg_publication_d.h"	/* IWYU pragma: export */
 
 /* ----------------
  *		pg_publication definition.  cpp turns this into
diff --git a/src/include/catalog/pg_publication_namespace.h b/src/include/catalog/pg_publication_namespace.h
index e7f926bd437..3bf308d98bd 100644
--- a/src/include/catalog/pg_publication_namespace.h
+++ b/src/include/catalog/pg_publication_namespace.h
@@ -19,7 +19,7 @@
 #define PG_PUBLICATION_NAMESPACE_H
 
 #include "catalog/genbki.h"
-#include "catalog/pg_publication_namespace_d.h"
+#include "catalog/pg_publication_namespace_d.h" /* IWYU pragma: export */
 
 
 /* ----------------
diff --git a/src/include/catalog/pg_publication_rel.h b/src/include/catalog/pg_publication_rel.h
index 94eda9fe9dd..92cc36dfdf6 100644
--- a/src/include/catalog/pg_publication_rel.h
+++ b/src/include/catalog/pg_publication_rel.h
@@ -19,7 +19,7 @@
 #define PG_PUBLICATION_REL_H
 
 #include "catalog/genbki.h"
-#include "catalog/pg_publication_rel_d.h"
+#include "catalog/pg_publication_rel_d.h"	/* IWYU pragma: export */
 
 /* ----------------
  *		pg_publication_rel definition.  cpp turns this into
diff --git a/src/include/catalog/pg_range.h b/src/include/catalog/pg_range.h
index aa23a78dd6a..3bba6162782 100644
--- a/src/include/catalog/pg_range.h
+++ b/src/include/catalog/pg_range.h
@@ -19,7 +19,7 @@
 #define PG_RANGE_H
 
 #include "catalog/genbki.h"
-#include "catalog/pg_range_d.h"
+#include "catalog/pg_range_d.h" /* IWYU pragma: export */
 
 /* ----------------
  *		pg_range definition.  cpp turns this into
diff --git a/src/include/catalog/pg_replication_origin.h b/src/include/catalog/pg_replication_origin.h
index 92b4f720553..deb43065fe9 100644
--- a/src/include/catalog/pg_replication_origin.h
+++ b/src/include/catalog/pg_replication_origin.h
@@ -20,7 +20,7 @@
 
 #include "access/xlogdefs.h"
 #include "catalog/genbki.h"
-#include "catalog/pg_replication_origin_d.h"
+#include "catalog/pg_replication_origin_d.h"	/* IWYU pragma: export */
 
 /* ----------------
  *		pg_replication_origin.  cpp turns this into
diff --git a/src/include/catalog/pg_rewrite.h b/src/include/catalog/pg_rewrite.h
index fb7d4fbc212..c70bc45d1b3 100644
--- a/src/include/catalog/pg_rewrite.h
+++ b/src/include/catalog/pg_rewrite.h
@@ -22,7 +22,7 @@
 #define PG_REWRITE_H
 
 #include "catalog/genbki.h"
-#include "catalog/pg_rewrite_d.h"
+#include "catalog/pg_rewrite_d.h"	/* IWYU pragma: export */
 
 /* ----------------
  *		pg_rewrite definition.  cpp turns this into
diff --git a/src/include/catalog/pg_seclabel.h b/src/include/catalog/pg_seclabel.h
index ba07b86f70a..5b1b433600f 100644
--- a/src/include/catalog/pg_seclabel.h
+++ b/src/include/catalog/pg_seclabel.h
@@ -18,7 +18,7 @@
 #define PG_SECLABEL_H
 
 #include "catalog/genbki.h"
-#include "catalog/pg_seclabel_d.h"
+#include "catalog/pg_seclabel_d.h"	/* IWYU pragma: export */
 
 /* ----------------
  *		pg_seclabel definition.  cpp turns this into
diff --git a/src/include/catalog/pg_sequence.h b/src/include/catalog/pg_sequence.h
index 88a00b4a3a2..580c7f2cbe6 100644
--- a/src/include/catalog/pg_sequence.h
+++ b/src/include/catalog/pg_sequence.h
@@ -18,7 +18,7 @@
 #define PG_SEQUENCE_H
 
 #include "catalog/genbki.h"
-#include "catalog/pg_sequence_d.h"
+#include "catalog/pg_sequence_d.h"	/* IWYU pragma: export */
 
 CATALOG(pg_sequence,2224,SequenceRelationId)
 {
diff --git a/src/include/catalog/pg_shdepend.h b/src/include/catalog/pg_shdepend.h
index 3d68e12d453..62df9f757f6 100644
--- a/src/include/catalog/pg_shdepend.h
+++ b/src/include/catalog/pg_shdepend.h
@@ -28,7 +28,7 @@
 #define PG_SHDEPEND_H
 
 #include "catalog/genbki.h"
-#include "catalog/pg_shdepend_d.h"
+#include "catalog/pg_shdepend_d.h"	/* IWYU pragma: export */
 
 /* ----------------
  *		pg_shdepend definition.  cpp turns this into
diff --git a/src/include/catalog/pg_shdescription.h b/src/include/catalog/pg_shdescription.h
index 2b1da021011..ccd1f2ecb4c 100644
--- a/src/include/catalog/pg_shdescription.h
+++ b/src/include/catalog/pg_shdescription.h
@@ -31,7 +31,7 @@
 #define PG_SHDESCRIPTION_H
 
 #include "catalog/genbki.h"
-#include "catalog/pg_shdescription_d.h"
+#include "catalog/pg_shdescription_d.h" /* IWYU pragma: export */
 
 /* ----------------
  *		pg_shdescription definition.    cpp turns this into
diff --git a/src/include/catalog/pg_shseclabel.h b/src/include/catalog/pg_shseclabel.h
index a8bc9756115..523d6058b24 100644
--- a/src/include/catalog/pg_shseclabel.h
+++ b/src/include/catalog/pg_shseclabel.h
@@ -18,7 +18,7 @@
 #define PG_SHSECLABEL_H
 
 #include "catalog/genbki.h"
-#include "catalog/pg_shseclabel_d.h"
+#include "catalog/pg_shseclabel_d.h"	/* IWYU pragma: export */
 
 /* ----------------
  *		pg_shseclabel definition. cpp turns this into
diff --git a/src/include/catalog/pg_statistic.h b/src/include/catalog/pg_statistic.h
index dbef8ca88d2..4216e27a8a4 100644
--- a/src/include/catalog/pg_statistic.h
+++ b/src/include/catalog/pg_statistic.h
@@ -19,7 +19,7 @@
 #define PG_STATISTIC_H
 
 #include "catalog/genbki.h"
-#include "catalog/pg_statistic_d.h"
+#include "catalog/pg_statistic_d.h" /* IWYU pragma: export */
 
 /* ----------------
  *		pg_statistic definition.  cpp turns this into
diff --git a/src/include/catalog/pg_statistic_ext.h b/src/include/catalog/pg_statistic_ext.h
index 190322580df..d476095029c 100644
--- a/src/include/catalog/pg_statistic_ext.h
+++ b/src/include/catalog/pg_statistic_ext.h
@@ -23,7 +23,7 @@
 #define PG_STATISTIC_EXT_H
 
 #include "catalog/genbki.h"
-#include "catalog/pg_statistic_ext_d.h"
+#include "catalog/pg_statistic_ext_d.h" /* IWYU pragma: export */
 
 /* ----------------
  *		pg_statistic_ext definition.  cpp turns this into
diff --git a/src/include/catalog/pg_statistic_ext_data.h b/src/include/catalog/pg_statistic_ext_data.h
index 17d8c40ed13..809b5251994 100644
--- a/src/include/catalog/pg_statistic_ext_data.h
+++ b/src/include/catalog/pg_statistic_ext_data.h
@@ -21,7 +21,7 @@
 #define PG_STATISTIC_EXT_DATA_H
 
 #include "catalog/genbki.h"
-#include "catalog/pg_statistic_ext_data_d.h"
+#include "catalog/pg_statistic_ext_data_d.h"	/* IWYU pragma: export */
 
 /* ----------------
  *		pg_statistic_ext_data definition.  cpp turns this into
diff --git a/src/include/catalog/pg_subscription.h b/src/include/catalog/pg_subscription.h
index 6194b757d59..20fc329992d 100644
--- a/src/include/catalog/pg_subscription.h
+++ b/src/include/catalog/pg_subscription.h
@@ -19,7 +19,7 @@
 
 #include "access/xlogdefs.h"
 #include "catalog/genbki.h"
-#include "catalog/pg_subscription_d.h"
+#include "catalog/pg_subscription_d.h"	/* IWYU pragma: export */
 #include "lib/stringinfo.h"
 #include "nodes/pg_list.h"
 
diff --git a/src/include/catalog/pg_subscription_rel.h b/src/include/catalog/pg_subscription_rel.h
index 75d6fdf1951..c91797c869c 100644
--- a/src/include/catalog/pg_subscription_rel.h
+++ b/src/include/catalog/pg_subscription_rel.h
@@ -20,7 +20,7 @@
 
 #include "access/xlogdefs.h"
 #include "catalog/genbki.h"
-#include "catalog/pg_subscription_rel_d.h"
+#include "catalog/pg_subscription_rel_d.h"	/* IWYU pragma: export */
 #include "nodes/pg_list.h"
 
 /* ----------------
diff --git a/src/include/catalog/pg_tablespace.h b/src/include/catalog/pg_tablespace.h
index 45208ffd736..5293488c630 100644
--- a/src/include/catalog/pg_tablespace.h
+++ b/src/include/catalog/pg_tablespace.h
@@ -19,7 +19,7 @@
 #define PG_TABLESPACE_H
 
 #include "catalog/genbki.h"
-#include "catalog/pg_tablespace_d.h"
+#include "catalog/pg_tablespace_d.h"	/* IWYU pragma: export */
 
 /* ----------------
  *		pg_tablespace definition.  cpp turns this into
diff --git a/src/include/catalog/pg_transform.h b/src/include/catalog/pg_transform.h
index 18f7bd922be..bc3d943230f 100644
--- a/src/include/catalog/pg_transform.h
+++ b/src/include/catalog/pg_transform.h
@@ -19,7 +19,7 @@
 #define PG_TRANSFORM_H
 
 #include "catalog/genbki.h"
-#include "catalog/pg_transform_d.h"
+#include "catalog/pg_transform_d.h" /* IWYU pragma: export */
 
 /* ----------------
  *		pg_transform definition.  cpp turns this into
diff --git a/src/include/catalog/pg_trigger.h b/src/include/catalog/pg_trigger.h
index 4208e7182ea..24a91528061 100644
--- a/src/include/catalog/pg_trigger.h
+++ b/src/include/catalog/pg_trigger.h
@@ -19,7 +19,7 @@
 #define PG_TRIGGER_H
 
 #include "catalog/genbki.h"
-#include "catalog/pg_trigger_d.h"
+#include "catalog/pg_trigger_d.h"	/* IWYU pragma: export */
 
 /* ----------------
  *		pg_trigger definition.  cpp turns this into
diff --git a/src/include/catalog/pg_ts_config.h b/src/include/catalog/pg_ts_config.h
index ee5bd23398c..0f5df37f097 100644
--- a/src/include/catalog/pg_ts_config.h
+++ b/src/include/catalog/pg_ts_config.h
@@ -20,7 +20,7 @@
 #define PG_TS_CONFIG_H
 
 #include "catalog/genbki.h"
-#include "catalog/pg_ts_config_d.h"
+#include "catalog/pg_ts_config_d.h" /* IWYU pragma: export */
 
 /* ----------------
  *		pg_ts_config definition.  cpp turns this into
diff --git a/src/include/catalog/pg_ts_dict.h b/src/include/catalog/pg_ts_dict.h
index 1d32185c26c..86102c73a6b 100644
--- a/src/include/catalog/pg_ts_dict.h
+++ b/src/include/catalog/pg_ts_dict.h
@@ -19,7 +19,7 @@
 #define PG_TS_DICT_H
 
 #include "catalog/genbki.h"
-#include "catalog/pg_ts_dict_d.h"
+#include "catalog/pg_ts_dict_d.h"	/* IWYU pragma: export */
 
 /* ----------------
  *		pg_ts_dict definition.  cpp turns this into
diff --git a/src/include/catalog/pg_ts_parser.h b/src/include/catalog/pg_ts_parser.h
index 571a52d9671..f3a40e5d293 100644
--- a/src/include/catalog/pg_ts_parser.h
+++ b/src/include/catalog/pg_ts_parser.h
@@ -19,7 +19,7 @@
 #define PG_TS_PARSER_H
 
 #include "catalog/genbki.h"
-#include "catalog/pg_ts_parser_d.h"
+#include "catalog/pg_ts_parser_d.h" /* IWYU pragma: export */
 
 /* ----------------
  *		pg_ts_parser definition.  cpp turns this into
diff --git a/src/include/catalog/pg_ts_template.h b/src/include/catalog/pg_ts_template.h
index 3a5cb45d2e4..aa06b7a840a 100644
--- a/src/include/catalog/pg_ts_template.h
+++ b/src/include/catalog/pg_ts_template.h
@@ -19,7 +19,7 @@
 #define PG_TS_TEMPLATE_H
 
 #include "catalog/genbki.h"
-#include "catalog/pg_ts_template_d.h"
+#include "catalog/pg_ts_template_d.h"	/* IWYU pragma: export */
 
 /* ----------------
  *		pg_ts_template definition.  cpp turns this into
diff --git a/src/include/catalog/pg_type.h b/src/include/catalog/pg_type.h
index a020ebba044..ff666711a54 100644
--- a/src/include/catalog/pg_type.h
+++ b/src/include/catalog/pg_type.h
@@ -20,7 +20,7 @@
 
 #include "catalog/genbki.h"
 #include "catalog/objectaddress.h"
-#include "catalog/pg_type_d.h"
+#include "catalog/pg_type_d.h"	/* IWYU pragma: export */
 #include "nodes/nodes.h"
 
 /* ----------------
diff --git a/src/include/catalog/pg_user_mapping.h b/src/include/catalog/pg_user_mapping.h
index f6d447c8990..7a0465c4d97 100644
--- a/src/include/catalog/pg_user_mapping.h
+++ b/src/include/catalog/pg_user_mapping.h
@@ -18,7 +18,7 @@
 #define PG_USER_MAPPING_H
 
 #include "catalog/genbki.h"
-#include "catalog/pg_user_mapping_d.h"
+#include "catalog/pg_user_mapping_d.h"	/* IWYU pragma: export */
 
 /* ----------------
  *		pg_user_mapping definition.  cpp turns this into
-- 
2.47.1

v2-0003-Add-a-bit-of-documentation-related-to-IWYU.patchtext/plain; charset=UTF-8; name=v2-0003-Add-a-bit-of-documentation-related-to-IWYU.patchDownload
From 505da0262c1713afb0b700c1673dbbd882265d1f Mon Sep 17 00:00:00 2001
From: Peter Eisentraut <peter@eisentraut.org>
Date: Fri, 10 Jan 2025 09:01:00 +0100
Subject: [PATCH v2 3/3] Add a bit of documentation related to IWYU

Add some basic information about IWYU to src/tools/pginclude/README.

Discussion: https://www.postgresql.org/message-id/flat/9395d484-eff4-47c2-b276-8e228526c8ae@eisentraut.org
---
 src/tools/pginclude/README | 42 ++++++++++++++++++++++++++++++++++++++
 1 file changed, 42 insertions(+)

diff --git a/src/tools/pginclude/README b/src/tools/pginclude/README
index 007d0397e79..2f8fe6b78ba 100644
--- a/src/tools/pginclude/README
+++ b/src/tools/pginclude/README
@@ -1,5 +1,47 @@
 src/tools/pginclude/README
 
+This directory contains some scripts and information for managing
+header files and includes in PostgreSQL source code.
+
+
+include-what-you-use
+====================
+
+include-what-you-use (IWYU) (<https://include-what-you-use.org/>) is a
+tool for finding missing or superfluous includes in C source files.
+
+With a compilation database (compile_commands.json, produced by
+meson), it can be run like this, over the whole source tree:
+
+    iwyu_tool.py -p build .
+
+(this will likely be very noisy) or for individual files:
+
+    iwyu_tool.py -p build src/bin/psql/startup.c
+
+Various other invocation options are available.
+
+It is recommended to use at least version 0.23.  Earlier versions give
+advice that is incompatible with the compiler warning option
+-Wmissing-variable-declarations.
+
+clangd (the language server) can automatically give IWYU-style advice;
+see <https://clangd.llvm.org/guides/include-cleaner>.
+
+The source code contains some "IWYU pragma" comments to tell IWYU
+about some PostgreSQL include file conventions (such as that a header
+such as "postgres.h" should always be included, even if it doesn't
+contribute any symbols used by the particular source file) and to
+silence a few warnings that are difficult to fix.  See
+<https://github.com/include-what-you-use/include-what-you-use/blob/master/docs/IWYUPragmas.md>
+for documentation about those.
+
+Of course, any include changes suggested by this or other tools should
+be checked and verified carefully.  Note that some includes are only
+used on some platforms or with some compilation options, so blindly
+following the produced advice is not recommended.
+
+
 headerscheck
 ============
 
-- 
2.47.1

#6Peter Eisentraut
peter@eisentraut.org
In reply to: Peter Eisentraut (#5)
Re: IWYU annotations

On 10.01.25 09:10, Peter Eisentraut wrote:

On 02.01.25 17:15, Tom Lane wrote:

It's a fair point that some documentation could be provided.  I suppose
we don't want to verbosely explain each pragma individually.  Should
there be some central explanation, maybe in src/tools/pginclude/README?

That might do, but perhaps instead in the "PostgreSQL Coding
Conventions" chapter of the SGML docs?  Actually, I think we could do
with a centralized explanation of our inclusion conventions --- I'm
not sure that the whole business of "postgres.h or a sibling must be
first" is explained in any easy-to-find place.  This topic would
likely fit well with such an explanation.

In this updated patch set, I've just added a bit of info into src/tools/
pginclude/README.  Updating the coding convention documentation like you
suggest also sounds like a good idea, but from my perspective I would
need to do further research to pin down what those actually are, so I'm
leaving that as a separate project.

(See for example the business in src/tools/pginclude/headerscheck about
guessing which the appropriate first header file should be for each
component.  That kind of thing perhaps ought to be more formalized.)

But really, the point I was trying to make above is that I don't
want this to break our very long-standing convention that headers
should be #include'd alphabetically and there is never a need to
impose some other order (at least not without lots of commentary
about it at the scene of the crime).  The way you've done it here
is just asking for trouble, IMO.  If that means redundant pragma
commands, so be it.

Yeah, that's a fair point.  I have removed that part from my patch set.

I have committed this. Thanks for the feedback.

In reply to: Peter Eisentraut (#6)
Re: IWYU annotations

On Wed, Jan 15, 2025 at 2:21 PM Peter Eisentraut <peter@eisentraut.org> wrote:

I have committed this. Thanks for the feedback.

Thanks for working on this.

Is it worth documenting how to get clangd working sensibly with
"--header-insertion=iwyu"?

I enabled it just now. I find that I can now use completion with a
type name, and have clangd automatically include the necessary header
file. For example, if I use completion to pull in a "StringInfoData" I
find that clangd will automatically add the necessary #include
"lib/stringinfo.h", without any special directions from me -- no
context switching required. Importantly, now that we have these
annotations, clangd won't constantly be adding useless includes that
actually come from c.h -- that made IWYU header cleaning unusable
before now.

Note that I'm relying on my clang-tidy config for this. clangd is able
to respect our conventions around headers through clang-tidy, which
has been taught Postgres-specific rules around header conventions. So
we'd actually be documenting something about clang-tidy + clangd +
Postgres header conventions, if we went through with something like
this.

It might be worth holding off for now. It's possible that I'll find
--header-insertion=iwyu has big problems in some unforeseen way. But
offhand it looks like a real improvement, even though I foresee
certain minor downsides. What do you think?

--
Peter Geoghegan

#8Peter Eisentraut
peter@eisentraut.org
In reply to: Peter Geoghegan (#7)
Re: IWYU annotations

On 15.01.25 20:51, Peter Geoghegan wrote:

On Wed, Jan 15, 2025 at 2:21 PM Peter Eisentraut <peter@eisentraut.org> wrote:

I have committed this. Thanks for the feedback.

Thanks for working on this.

Is it worth documenting how to get clangd working sensibly with
"--header-insertion=iwyu"?

I enabled it just now. I find that I can now use completion with a
type name, and have clangd automatically include the necessary header
file. For example, if I use completion to pull in a "StringInfoData" I
find that clangd will automatically add the necessary #include
"lib/stringinfo.h", without any special directions from me -- no
context switching required. Importantly, now that we have these
annotations, clangd won't constantly be adding useless includes that
actually come from c.h -- that made IWYU header cleaning unusable
before now.

Note that I'm relying on my clang-tidy config for this. clangd is able
to respect our conventions around headers through clang-tidy, which
has been taught Postgres-specific rules around header conventions. So
we'd actually be documenting something about clang-tidy + clangd +
Postgres header conventions, if we went through with something like
this.

It might be worth holding off for now. It's possible that I'll find
--header-insertion=iwyu has big problems in some unforeseen way. But
offhand it looks like a real improvement, even though I foresee
certain minor downsides. What do you think?

I had turned automatic header insertion off until now and didn't think
to turn it back on yet. I'll give it another try sometime.

I'm unclear on what role clang-tidy would play in this.

In reply to: Peter Eisentraut (#8)
Re: IWYU annotations

On Wed, Jan 22, 2025 at 9:08 AM Peter Eisentraut <peter@eisentraut.org> wrote:

It might be worth holding off for now. It's possible that I'll find
--header-insertion=iwyu has big problems in some unforeseen way. But
offhand it looks like a real improvement, even though I foresee
certain minor downsides. What do you think?

I had turned automatic header insertion off until now and didn't think
to turn it back on yet. I'll give it another try sometime.

I'm now a week into this experiment. So far, the results have been mixed.

I'm tempted to turn --header-insertion=iwyu off now, since clangd
header insertion with completion is in fact still adding what seem to
me to be superfluous includes in some cases (though much less so
compared to before your recent work). So it's still useful, but it
might be more annoying than useful. Particularly compared to my
original approach of relying on clangd errors + quick-fix actions to
add required headers -- that doesn't have these problems (I seem to
only be offered the option of a quick-fix when I get certain compile
errors), and requires only minimal effort.

I'm unclear on what role clang-tidy would play in this.

Sorry, I meant clang-format.

The relevant section of my .clang-format file:

SortIncludes: true
IncludeIsMainSourceRegex: '(postgres\.h)$'
IncludeCategories:
- Regex: '^<.*\.h>'
Priority: 1
SortPriority: 1
- Regex: 'postgres.h'
Priority: 2
SortPriority: 2
- Regex: '.*'
Priority: 3
SortPriority: 3

I'm guessing that you already have something like this (I believe I
copied it from somebody else). This config is respected by clangd
whenever it adds a header file (whether it's fully automatic or
whether it's via a "missing header" quick-fix).

--
Peter Geoghegan