allow benign typedef redefinitions (C11)

Started by Peter Eisentraut5 months ago23 messages
#1Peter Eisentraut
peter@eisentraut.org
7 attachment(s)

Here is the first of several (to come at a later date) patch sets to
take some advantage of C11 features.

This is, I hope, a very gentle start that shouldn't stress even older
compilers very much, and should bring some tangible benefits that had
already been asked for around here.

In C11, typedef redefinitions are allowed, as long as they are the same. So

typedef int foo;
typedef int foo;

is allowed, where the second occurrence would have led to a diagnostic
in previous C versions.

(C++ also allows this, so this will preserve C++ compatibility of the
headers.)

What is not allowed is something like this of course:

typedef int foo;
typedef double foo;

This will continue to be an error.

This facility is often useful to untangle dependencies between header
files. So instead of having one header include another, now the first
header can just make its own typedef of whatever types it needs. If the
two headers are later included together, then this will not (any more)
be a conflict. This often works together with declaring incomplete
types using struct.

The PostgreSQL code already contains a couple of places that wanted to
do something like this but had to install manual workarounds with #ifdef
guards. These can now be removed. There are also a bunch of struct
forward declarations that can be "upgraded" to full typedefs. This
makes the function prototypes look more consistent.

In this patch set, 0001 is a prerequisite for 0002, 0002 and 0003 remove
some existing workarounds, the remaining patches are additional
opportunities for cleanup and simplification.

All of this is only notational, there are no include changes or API
changes or changes in behavior.

(After this, it would probably be possible to undertake some deeper
efforts to untangle header files, with the help of IWYU. But that is a
separate project.)

Attachments:

0001-Improve-pgbench-definition-of-yyscan_t.patchtext/plain; charset=UTF-8; name=0001-Improve-pgbench-definition-of-yyscan_t.patchDownload
From 9cca8a11e0c5107cc4577cd0d14c79a3cd154d62 Mon Sep 17 00:00:00 2001
From: Peter Eisentraut <peter@eisentraut.org>
Date: Fri, 29 Aug 2025 13:18:50 +0200
Subject: [PATCH 1/7] Improve pgbench definition of yyscan_t

It was defining yyscan_t as a macro while the rest of the code uses a
typedef with #ifdef guards around it.  The latter is also what the
flex generated code uses.  So it seems best to make it look like those
other places for consistency.

The old way also had a potential for conflict if some code included
multiple headers providing yyscan_t.  exprscan.l includes

    #include "fe_utils/psqlscan_int.h"
    #include "pgbench.h"

and fe_utils/psqlscan_int.h contains

    #ifndef YY_TYPEDEF_YY_SCANNER_T
    #define YY_TYPEDEF_YY_SCANNER_T
    typedef void *yyscan_t;
    #endif

which was then followed by pgbench.h

    #define yyscan_t  void *

and then the generated code in exprscan.c

    #ifndef YY_TYPEDEF_YY_SCANNER_T
    #define YY_TYPEDEF_YY_SCANNER_T
    typedef void* yyscan_t;
    #endif

This works, but if the #ifdef guard in psqlscan_int.h is removed, this
fails.

We want to move toward allowing repeat typedefs, per C11, but for that
we need to make sure they are all the same.
---
 src/bin/pgbench/pgbench.h | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/src/bin/pgbench/pgbench.h b/src/bin/pgbench/pgbench.h
index e053c9e2eb6..f8b7b497d1e 100644
--- a/src/bin/pgbench/pgbench.h
+++ b/src/bin/pgbench/pgbench.h
@@ -16,11 +16,14 @@
 /*
  * This file is included outside exprscan.l, in places where we can't see
  * flex's definition of typedef yyscan_t.  Fortunately, it's documented as
- * being "void *", so we can use a macro to keep the function declarations
+ * being "void *", so we can use typedef to keep the function declarations
  * here looking like the definitions in exprscan.l.  exprparse.y and
  * pgbench.c also use this to be able to declare things as "yyscan_t".
  */
-#define yyscan_t  void *
+#ifndef YY_TYPEDEF_YY_SCANNER_T
+#define YY_TYPEDEF_YY_SCANNER_T
+typedef void *yyscan_t;
+#endif
 
 /*
  * Likewise, we can't see exprparse.y's definition of union YYSTYPE here,

base-commit: 5d7f58848ce59d9e09b7214d2541ab3ec853f89c
-- 
2.51.0

0002-Allow-redeclaration-of-typedef-yyscan_t.patchtext/plain; charset=UTF-8; name=0002-Allow-redeclaration-of-typedef-yyscan_t.patchDownload
From fe3cd22fef977d763baf21c346de73e00c116754 Mon Sep 17 00:00:00 2001
From: Peter Eisentraut <peter@eisentraut.org>
Date: Fri, 29 Aug 2025 13:18:51 +0200
Subject: [PATCH 2/7] Allow redeclaration of typedef yyscan_t

This is allowed in C11, so we don't need the workaround guards against
it anymore.  This effectively reverts commit 382092a0cd2 that put
these guards in place.
---
 contrib/cube/cubedata.h                     | 3 ---
 contrib/seg/segdata.h                       | 3 ---
 src/backend/utils/adt/jsonpath_internal.h   | 3 ---
 src/bin/pgbench/pgbench.h                   | 3 ---
 src/include/bootstrap/bootstrap.h           | 3 ---
 src/include/fe_utils/psqlscan_int.h         | 6 ------
 src/include/replication/syncrep.h           | 3 ---
 src/include/replication/walsender_private.h | 3 ---
 src/pl/plpgsql/src/plpgsql.h                | 3 ---
 9 files changed, 30 deletions(-)

diff --git a/contrib/cube/cubedata.h b/contrib/cube/cubedata.h
index ad1e2bd6998..8bfcc6e99a2 100644
--- a/contrib/cube/cubedata.h
+++ b/contrib/cube/cubedata.h
@@ -62,10 +62,7 @@ typedef struct NDBOX
 /* for cubescan.l and cubeparse.y */
 /* All grammar constructs return strings */
 #define YYSTYPE char *
-#ifndef YY_TYPEDEF_YY_SCANNER_T
-#define YY_TYPEDEF_YY_SCANNER_T
 typedef void *yyscan_t;
-#endif
 
 /* in cubescan.l */
 extern int	cube_yylex(YYSTYPE *yylval_param, yyscan_t yyscanner);
diff --git a/contrib/seg/segdata.h b/contrib/seg/segdata.h
index 4347c31c28e..7bc7c83dca3 100644
--- a/contrib/seg/segdata.h
+++ b/contrib/seg/segdata.h
@@ -16,10 +16,7 @@ extern int	significant_digits(const char *s);
 
 /* for segscan.l and segparse.y */
 union YYSTYPE;
-#ifndef YY_TYPEDEF_YY_SCANNER_T
-#define YY_TYPEDEF_YY_SCANNER_T
 typedef void *yyscan_t;
-#endif
 
 /* in segscan.l */
 extern int	seg_yylex(union YYSTYPE *yylval_param, yyscan_t yyscanner);
diff --git a/src/backend/utils/adt/jsonpath_internal.h b/src/backend/utils/adt/jsonpath_internal.h
index f78069857d0..19567aca6f7 100644
--- a/src/backend/utils/adt/jsonpath_internal.h
+++ b/src/backend/utils/adt/jsonpath_internal.h
@@ -22,10 +22,7 @@ typedef struct JsonPathString
 	int			total;
 } JsonPathString;
 
-#ifndef YY_TYPEDEF_YY_SCANNER_T
-#define YY_TYPEDEF_YY_SCANNER_T
 typedef void *yyscan_t;
-#endif
 
 #include "utils/jsonpath.h"
 #include "jsonpath_gram.h"
diff --git a/src/bin/pgbench/pgbench.h b/src/bin/pgbench/pgbench.h
index f8b7b497d1e..d55d30e0ef9 100644
--- a/src/bin/pgbench/pgbench.h
+++ b/src/bin/pgbench/pgbench.h
@@ -20,10 +20,7 @@
  * here looking like the definitions in exprscan.l.  exprparse.y and
  * pgbench.c also use this to be able to declare things as "yyscan_t".
  */
-#ifndef YY_TYPEDEF_YY_SCANNER_T
-#define YY_TYPEDEF_YY_SCANNER_T
 typedef void *yyscan_t;
-#endif
 
 /*
  * Likewise, we can't see exprparse.y's definition of union YYSTYPE here,
diff --git a/src/include/bootstrap/bootstrap.h b/src/include/bootstrap/bootstrap.h
index befc4fa1b3d..5ad347ec290 100644
--- a/src/include/bootstrap/bootstrap.h
+++ b/src/include/bootstrap/bootstrap.h
@@ -56,10 +56,7 @@ extern void boot_get_type_io_data(Oid typid,
 								  Oid *typoutput);
 
 union YYSTYPE;
-#ifndef YY_TYPEDEF_YY_SCANNER_T
-#define YY_TYPEDEF_YY_SCANNER_T
 typedef void *yyscan_t;
-#endif
 
 extern int	boot_yyparse(yyscan_t yyscanner);
 extern int	boot_yylex_init(yyscan_t *yyscannerp);
diff --git a/src/include/fe_utils/psqlscan_int.h b/src/include/fe_utils/psqlscan_int.h
index 2a3a9d7c82a..a1ebf226cf4 100644
--- a/src/include/fe_utils/psqlscan_int.h
+++ b/src/include/fe_utils/psqlscan_int.h
@@ -51,14 +51,8 @@
  * validity checking; in actual use, this file should always be included
  * from the body of a flex file, where these symbols are already defined.
  */
-#ifndef YY_TYPEDEF_YY_BUFFER_STATE
-#define YY_TYPEDEF_YY_BUFFER_STATE
 typedef struct yy_buffer_state *YY_BUFFER_STATE;
-#endif
-#ifndef YY_TYPEDEF_YY_SCANNER_T
-#define YY_TYPEDEF_YY_SCANNER_T
 typedef void *yyscan_t;
-#endif
 
 /*
  * We use a stack of flex buffers to handle substitution of psql variables.
diff --git a/src/include/replication/syncrep.h b/src/include/replication/syncrep.h
index 675669a79f7..dc2b118b166 100644
--- a/src/include/replication/syncrep.h
+++ b/src/include/replication/syncrep.h
@@ -97,10 +97,7 @@ extern void SyncRepUpdateSyncStandbysDefined(void);
  * in syncrep_gram.y and syncrep_scanner.l
  */
 union YYSTYPE;
-#ifndef YY_TYPEDEF_YY_SCANNER_T
-#define YY_TYPEDEF_YY_SCANNER_T
 typedef void *yyscan_t;
-#endif
 extern int	syncrep_yyparse(SyncRepConfigData **syncrep_parse_result_p, char **syncrep_parse_error_msg_p, yyscan_t yyscanner);
 extern int	syncrep_yylex(union YYSTYPE *yylval_param, char **syncrep_parse_error_msg_p, yyscan_t yyscanner);
 extern void syncrep_yyerror(SyncRepConfigData **syncrep_parse_result_p, char **syncrep_parse_error_msg_p, yyscan_t yyscanner, const char *str);
diff --git a/src/include/replication/walsender_private.h b/src/include/replication/walsender_private.h
index e98701038f5..384b8a78b94 100644
--- a/src/include/replication/walsender_private.h
+++ b/src/include/replication/walsender_private.h
@@ -141,10 +141,7 @@ extern void WalSndSetState(WalSndState state);
  * repl_scanner.l
  */
 union YYSTYPE;
-#ifndef YY_TYPEDEF_YY_SCANNER_T
-#define YY_TYPEDEF_YY_SCANNER_T
 typedef void *yyscan_t;
-#endif
 extern int	replication_yyparse(Node **replication_parse_result_p, yyscan_t yyscanner);
 extern int	replication_yylex(union YYSTYPE *yylval_param, yyscan_t yyscanner);
 pg_noreturn extern void replication_yyerror(Node **replication_parse_result_p, yyscan_t yyscanner, const char *message);
diff --git a/src/pl/plpgsql/src/plpgsql.h b/src/pl/plpgsql/src/plpgsql.h
index 41e52b8ce71..5f193a37183 100644
--- a/src/pl/plpgsql/src/plpgsql.h
+++ b/src/pl/plpgsql/src/plpgsql.h
@@ -1307,10 +1307,7 @@ extern void plpgsql_dumptree(PLpgSQL_function *func);
  */
 union YYSTYPE;
 #define YYLTYPE int
-#ifndef YY_TYPEDEF_YY_SCANNER_T
-#define YY_TYPEDEF_YY_SCANNER_T
 typedef void *yyscan_t;
-#endif
 extern int	plpgsql_yylex(union YYSTYPE *yylvalp, YYLTYPE *yyllocp, yyscan_t yyscanner);
 extern int	plpgsql_token_length(yyscan_t yyscanner);
 extern void plpgsql_push_back_token(int token, union YYSTYPE *yylvalp, YYLTYPE *yyllocp, yyscan_t yyscanner);
-- 
2.51.0

0003-Remove-workarounds-against-repeat-typedefs.patchtext/plain; charset=UTF-8; name=0003-Remove-workarounds-against-repeat-typedefs.patchDownload
From 7f69eb3293cc7ce8b00e0891250581863373d12a Mon Sep 17 00:00:00 2001
From: Peter Eisentraut <peter@eisentraut.org>
Date: Fri, 29 Aug 2025 13:18:51 +0200
Subject: [PATCH 3/7] Remove workarounds against repeat typedefs

This is allowed in C11, so we don't need the workarounds anymore.
---
 src/include/nodes/pathnodes.h     | 23 ++++-------------------
 src/include/optimizer/optimizer.h | 13 +------------
 2 files changed, 5 insertions(+), 31 deletions(-)

diff --git a/src/include/nodes/pathnodes.h b/src/include/nodes/pathnodes.h
index 4a903d1ec18..b12a2508d8c 100644
--- a/src/include/nodes/pathnodes.h
+++ b/src/include/nodes/pathnodes.h
@@ -198,9 +198,6 @@ typedef struct PlannerGlobal
  * original Query.  Note that at present the planner extensively modifies
  * the passed-in Query data structure; someday that should stop.
  *
- * For reasons explained in optimizer/optimizer.h, we define the typedef
- * either here or in that header, whichever is read first.
- *
  * Not all fields are printed.  (In some cases, there is no print support for
  * the field type; in others, doing so would lead to infinite recursion or
  * bloat dump output more than seems useful.)
@@ -211,10 +208,7 @@ typedef struct PlannerGlobal
  * correctly replaced with the keeping one.
  *----------
  */
-#ifndef HAVE_PLANNERINFO_TYPEDEF
 typedef struct PlannerInfo PlannerInfo;
-#define HAVE_PLANNERINFO_TYPEDEF 1
-#endif
 
 struct PlannerInfo
 {
@@ -1161,14 +1155,10 @@ typedef struct RelOptInfo
  *		(by plancat.c), indrestrictinfo and predOK are set later, in
  *		check_index_predicates().
  */
-#ifndef HAVE_INDEXOPTINFO_TYPEDEF
-typedef struct IndexOptInfo IndexOptInfo;
-#define HAVE_INDEXOPTINFO_TYPEDEF 1
-#endif
 
 struct IndexPath;				/* forward declaration */
 
-struct IndexOptInfo
+typedef struct IndexOptInfo
 {
 	pg_node_attr(no_copy_equal, no_read, no_query_jumble)
 
@@ -1270,7 +1260,7 @@ struct IndexOptInfo
 	/* AM's cost estimator */
 	/* Rather than include amapi.h here, we declare amcostestimate like this */
 	void		(*amcostestimate) (struct PlannerInfo *, struct IndexPath *, double, Cost *, Cost *, Selectivity *, double *, double *) pg_node_attr(read_write_ignore);
-};
+} IndexOptInfo;
 
 /*
  * ForeignKeyOptInfo
@@ -3031,12 +3021,7 @@ typedef struct PlaceHolderVar
  * We also create transient SpecialJoinInfos for child joins during
  * partitionwise join planning, which are also not present in join_info_list.
  */
-#ifndef HAVE_SPECIALJOININFO_TYPEDEF
-typedef struct SpecialJoinInfo SpecialJoinInfo;
-#define HAVE_SPECIALJOININFO_TYPEDEF 1
-#endif
-
-struct SpecialJoinInfo
+typedef struct SpecialJoinInfo
 {
 	pg_node_attr(no_read, no_query_jumble)
 
@@ -3057,7 +3042,7 @@ struct SpecialJoinInfo
 	bool		semi_can_hash;	/* true if semi_operators are all hash */
 	List	   *semi_operators; /* OIDs of equality join operators */
 	List	   *semi_rhs_exprs; /* righthand-side expressions of these ops */
-};
+} SpecialJoinInfo;
 
 /*
  * Transient outer-join clause info.
diff --git a/src/include/optimizer/optimizer.h b/src/include/optimizer/optimizer.h
index 37bc13c2cbd..03b214755c2 100644
--- a/src/include/optimizer/optimizer.h
+++ b/src/include/optimizer/optimizer.h
@@ -28,22 +28,11 @@
  * We don't want to include nodes/pathnodes.h here, because non-planner
  * code should generally treat PlannerInfo as an opaque typedef.
  * But we'd like such code to use that typedef name, so define the
- * typedef either here or in pathnodes.h, whichever is read first.
+ * typedef both here or in pathnodes.h.
  */
-#ifndef HAVE_PLANNERINFO_TYPEDEF
 typedef struct PlannerInfo PlannerInfo;
-#define HAVE_PLANNERINFO_TYPEDEF 1
-#endif
-
-/* Likewise for IndexOptInfo and SpecialJoinInfo. */
-#ifndef HAVE_INDEXOPTINFO_TYPEDEF
 typedef struct IndexOptInfo IndexOptInfo;
-#define HAVE_INDEXOPTINFO_TYPEDEF 1
-#endif
-#ifndef HAVE_SPECIALJOININFO_TYPEDEF
 typedef struct SpecialJoinInfo SpecialJoinInfo;
-#define HAVE_SPECIALJOININFO_TYPEDEF 1
-#endif
 
 /* It also seems best not to include plannodes.h, params.h, or htup.h here */
 struct PlannedStmt;
-- 
2.51.0

0004-Improve-ExplainState-type-handling-in-header-files.patchtext/plain; charset=UTF-8; name=0004-Improve-ExplainState-type-handling-in-header-files.patchDownload
From c46b45b7e638f4d9fbf2dab97f7f69d57ea9c03f Mon Sep 17 00:00:00 2001
From: Peter Eisentraut <peter@eisentraut.org>
Date: Fri, 29 Aug 2025 13:18:51 +0200
Subject: [PATCH 4/7] Improve ExplainState type handling in header files

Now that we can have repeat typedefs with C11, we don't need to use
"struct ExplainState" anymore but can instead make a typedef where
necessary.  This doesn't change anything but makes it look nicer.

(There are more opportunities for similar changes, but this is broken
out because there was a separate discussion about it, and it's
somewhat bulky on its own.)

Discussion: https://www.postgresql.org/message-id/flat/f36c0a45-98cd-40b2-a7cc-f2bf02b12890%40eisentraut.org#a12fb1a2c1089d6d03010f6268871b00
---
 doc/src/sgml/fdwhandler.sgml          |  2 +-
 src/include/commands/explain.h        | 24 +++++++++---------
 src/include/commands/explain_dr.h     |  4 +--
 src/include/commands/explain_format.h | 36 +++++++++++++--------------
 src/include/commands/explain_state.h  |  2 +-
 src/include/foreign/fdwapi.h          | 10 ++++----
 6 files changed, 39 insertions(+), 39 deletions(-)

diff --git a/doc/src/sgml/fdwhandler.sgml b/doc/src/sgml/fdwhandler.sgml
index b80320504d6..c6d66414b8e 100644
--- a/doc/src/sgml/fdwhandler.sgml
+++ b/doc/src/sgml/fdwhandler.sgml
@@ -1320,7 +1320,7 @@ <title>FDW Routines for <command>EXPLAIN</command></title>
                      ResultRelInfo *rinfo,
                      List *fdw_private,
                      int subplan_index,
-                     struct ExplainState *es);
+                     ExplainState *es);
 </programlisting>
 
      Print additional <command>EXPLAIN</command> output for a foreign table update.
diff --git a/src/include/commands/explain.h b/src/include/commands/explain.h
index 3b122f79ed8..6e51d50efc7 100644
--- a/src/include/commands/explain.h
+++ b/src/include/commands/explain.h
@@ -16,13 +16,13 @@
 #include "executor/executor.h"
 #include "parser/parse_node.h"
 
-struct ExplainState;			/* defined in explain_state.h */
+typedef struct ExplainState ExplainState;	/* defined in explain_state.h */
 
 /* Hook for plugins to get control in ExplainOneQuery() */
 typedef void (*ExplainOneQuery_hook_type) (Query *query,
 										   int cursorOptions,
 										   IntoClause *into,
-										   struct ExplainState *es,
+										   ExplainState *es,
 										   const char *queryString,
 										   ParamListInfo params,
 										   QueryEnvironment *queryEnv);
@@ -31,7 +31,7 @@ extern PGDLLIMPORT ExplainOneQuery_hook_type ExplainOneQuery_hook;
 /* Hook for EXPLAIN plugins to print extra information for each plan */
 typedef void (*explain_per_plan_hook_type) (PlannedStmt *plannedstmt,
 											IntoClause *into,
-											struct ExplainState *es,
+											ExplainState *es,
 											const char *queryString,
 											ParamListInfo params,
 											QueryEnvironment *queryEnv);
@@ -42,7 +42,7 @@ typedef void (*explain_per_node_hook_type) (PlanState *planstate,
 											List *ancestors,
 											const char *relationship,
 											const char *plan_name,
-											struct ExplainState *es);
+											ExplainState *es);
 extern PGDLLIMPORT explain_per_node_hook_type explain_per_node_hook;
 
 /* Hook for plugins to get control in explain_get_index_name() */
@@ -53,32 +53,32 @@ extern PGDLLIMPORT explain_get_index_name_hook_type explain_get_index_name_hook;
 extern void ExplainQuery(ParseState *pstate, ExplainStmt *stmt,
 						 ParamListInfo params, DestReceiver *dest);
 extern void standard_ExplainOneQuery(Query *query, int cursorOptions,
-									 IntoClause *into, struct ExplainState *es,
+									 IntoClause *into, ExplainState *es,
 									 const char *queryString, ParamListInfo params,
 									 QueryEnvironment *queryEnv);
 
 extern TupleDesc ExplainResultDesc(ExplainStmt *stmt);
 
 extern void ExplainOneUtility(Node *utilityStmt, IntoClause *into,
-							  struct ExplainState *es, ParseState *pstate,
+							  ExplainState *es, ParseState *pstate,
 							  ParamListInfo params);
 
 extern void ExplainOnePlan(PlannedStmt *plannedstmt, IntoClause *into,
-						   struct ExplainState *es, const char *queryString,
+						   ExplainState *es, const char *queryString,
 						   ParamListInfo params, QueryEnvironment *queryEnv,
 						   const instr_time *planduration,
 						   const BufferUsage *bufusage,
 						   const MemoryContextCounters *mem_counters);
 
-extern void ExplainPrintPlan(struct ExplainState *es, QueryDesc *queryDesc);
-extern void ExplainPrintTriggers(struct ExplainState *es,
+extern void ExplainPrintPlan(ExplainState *es, QueryDesc *queryDesc);
+extern void ExplainPrintTriggers(ExplainState *es,
 								 QueryDesc *queryDesc);
 
-extern void ExplainPrintJITSummary(struct ExplainState *es,
+extern void ExplainPrintJITSummary(ExplainState *es,
 								   QueryDesc *queryDesc);
 
-extern void ExplainQueryText(struct ExplainState *es, QueryDesc *queryDesc);
-extern void ExplainQueryParameters(struct ExplainState *es,
+extern void ExplainQueryText(ExplainState *es, QueryDesc *queryDesc);
+extern void ExplainQueryParameters(ExplainState *es,
 								   ParamListInfo params, int maxlen);
 
 #endif							/* EXPLAIN_H */
diff --git a/src/include/commands/explain_dr.h b/src/include/commands/explain_dr.h
index 55da63d66bd..ce424aa2a55 100644
--- a/src/include/commands/explain_dr.h
+++ b/src/include/commands/explain_dr.h
@@ -16,7 +16,7 @@
 #include "executor/instrument.h"
 #include "tcop/dest.h"
 
-struct ExplainState;			/* avoid including explain.h here */
+typedef struct ExplainState ExplainState;	/* avoid including explain.h here */
 
 /* Instrumentation data for EXPLAIN's SERIALIZE option */
 typedef struct SerializeMetrics
@@ -26,7 +26,7 @@ typedef struct SerializeMetrics
 	BufferUsage bufferUsage;	/* buffers accessed during serialization */
 } SerializeMetrics;
 
-extern DestReceiver *CreateExplainSerializeDestReceiver(struct ExplainState *es);
+extern DestReceiver *CreateExplainSerializeDestReceiver(ExplainState *es);
 extern SerializeMetrics GetSerializationMetrics(DestReceiver *dest);
 
 #endif
diff --git a/src/include/commands/explain_format.h b/src/include/commands/explain_format.h
index 05045bf8cb4..b4466c9b131 100644
--- a/src/include/commands/explain_format.h
+++ b/src/include/commands/explain_format.h
@@ -15,44 +15,44 @@
 
 #include "nodes/pg_list.h"
 
-struct ExplainState;			/* avoid including explain.h here */
+typedef struct ExplainState ExplainState;	/* avoid including explain.h here */
 
 extern void ExplainPropertyList(const char *qlabel, List *data,
-								struct ExplainState *es);
+								ExplainState *es);
 extern void ExplainPropertyListNested(const char *qlabel, List *data,
-									  struct ExplainState *es);
+									  ExplainState *es);
 extern void ExplainPropertyText(const char *qlabel, const char *value,
-								struct ExplainState *es);
+								ExplainState *es);
 extern void ExplainPropertyInteger(const char *qlabel, const char *unit,
-								   int64 value, struct ExplainState *es);
+								   int64 value, ExplainState *es);
 extern void ExplainPropertyUInteger(const char *qlabel, const char *unit,
-									uint64 value, struct ExplainState *es);
+									uint64 value, ExplainState *es);
 extern void ExplainPropertyFloat(const char *qlabel, const char *unit,
 								 double value, int ndigits,
-								 struct ExplainState *es);
+								 ExplainState *es);
 extern void ExplainPropertyBool(const char *qlabel, bool value,
-								struct ExplainState *es);
+								ExplainState *es);
 
 extern void ExplainOpenGroup(const char *objtype, const char *labelname,
-							 bool labeled, struct ExplainState *es);
+							 bool labeled, ExplainState *es);
 extern void ExplainCloseGroup(const char *objtype, const char *labelname,
-							  bool labeled, struct ExplainState *es);
+							  bool labeled, ExplainState *es);
 
 extern void ExplainOpenSetAsideGroup(const char *objtype, const char *labelname,
 									 bool labeled, int depth,
-									 struct ExplainState *es);
-extern void ExplainSaveGroup(struct ExplainState *es, int depth,
+									 ExplainState *es);
+extern void ExplainSaveGroup(ExplainState *es, int depth,
 							 int *state_save);
-extern void ExplainRestoreGroup(struct ExplainState *es, int depth,
+extern void ExplainRestoreGroup(ExplainState *es, int depth,
 								int *state_save);
 
 extern void ExplainDummyGroup(const char *objtype, const char *labelname,
-							  struct ExplainState *es);
+							  ExplainState *es);
 
-extern void ExplainBeginOutput(struct ExplainState *es);
-extern void ExplainEndOutput(struct ExplainState *es);
-extern void ExplainSeparatePlans(struct ExplainState *es);
+extern void ExplainBeginOutput(ExplainState *es);
+extern void ExplainEndOutput(ExplainState *es);
+extern void ExplainSeparatePlans(ExplainState *es);
 
-extern void ExplainIndentText(struct ExplainState *es);
+extern void ExplainIndentText(ExplainState *es);
 
 #endif
diff --git a/src/include/commands/explain_state.h b/src/include/commands/explain_state.h
index 32728f5d1a1..ba073b86918 100644
--- a/src/include/commands/explain_state.h
+++ b/src/include/commands/explain_state.h
@@ -79,7 +79,7 @@ typedef struct ExplainState
 typedef void (*ExplainOptionHandler) (ExplainState *, DefElem *, ParseState *);
 
 /* Hook to perform additional EXPLAIN options validation */
-typedef void (*explain_validate_options_hook_type) (struct ExplainState *es, List *options,
+typedef void (*explain_validate_options_hook_type) (ExplainState *es, List *options,
 													ParseState *pstate);
 extern PGDLLIMPORT explain_validate_options_hook_type explain_validate_options_hook;
 
diff --git a/src/include/foreign/fdwapi.h b/src/include/foreign/fdwapi.h
index b4da4e6a16a..a686887978d 100644
--- a/src/include/foreign/fdwapi.h
+++ b/src/include/foreign/fdwapi.h
@@ -16,8 +16,8 @@
 #include "nodes/execnodes.h"
 #include "nodes/pathnodes.h"
 
-/* To avoid including explain.h here, reference ExplainState thus: */
-struct ExplainState;
+/* avoid including explain.h here */
+typedef struct ExplainState ExplainState;
 
 
 /*
@@ -137,16 +137,16 @@ typedef void (*RefetchForeignRow_function) (EState *estate,
 											bool *updated);
 
 typedef void (*ExplainForeignScan_function) (ForeignScanState *node,
-											 struct ExplainState *es);
+											 ExplainState *es);
 
 typedef void (*ExplainForeignModify_function) (ModifyTableState *mtstate,
 											   ResultRelInfo *rinfo,
 											   List *fdw_private,
 											   int subplan_index,
-											   struct ExplainState *es);
+											   ExplainState *es);
 
 typedef void (*ExplainDirectModify_function) (ForeignScanState *node,
-											  struct ExplainState *es);
+											  ExplainState *es);
 
 typedef int (*AcquireSampleRowsFunc) (Relation relation, int elevel,
 									  HeapTuple *rows, int targrows,
-- 
2.51.0

0005-Update-various-forward-declarations-to-use-typedef.patchtext/plain; charset=UTF-8; name=0005-Update-various-forward-declarations-to-use-typedef.patchDownload
From 8b70a03986274cb8c1353ef13521e47a3308cf5e Mon Sep 17 00:00:00 2001
From: Peter Eisentraut <peter@eisentraut.org>
Date: Fri, 29 Aug 2025 13:18:51 +0200
Subject: [PATCH 5/7] Update various forward declarations to use typedef

There are a number of forward declarations that use struct but not the
customary typedef, because that could have led to repeat typedefs,
which was not allowed.  This is now allowed in C11, so we can update
these to provide the typedefs as well, so that the later uses of the
types look more consistent.
---
 src/include/commands/tablecmds.h      |  5 ++--
 src/include/common/string.h           |  7 +++--
 src/include/executor/executor.h       |  4 +--
 src/include/executor/tablefunc.h      | 18 ++++++------
 src/include/nodes/execnodes.h         | 40 +++++++++++++--------------
 src/include/nodes/nodeFuncs.h         |  6 ++--
 src/include/nodes/params.h            | 17 ++++++------
 src/include/nodes/subscripting.h      | 14 +++++-----
 src/include/nodes/supportnodes.h      | 26 ++++++++---------
 src/include/optimizer/optimizer.h     | 14 +++++-----
 src/include/parser/parse_utilcmd.h    |  4 +--
 src/include/partitioning/partbounds.h |  6 ++--
 src/include/partitioning/partprune.h  | 10 +++----
 src/include/rewrite/rewriteManip.h    |  4 +--
 src/include/storage/bufmgr.h          | 24 ++++++++--------
 src/include/storage/bulk_write.h      |  4 +--
 src/include/storage/dsm.h             |  4 +--
 src/include/storage/shmem.h           |  5 ++--
 src/include/tcop/pquery.h             |  4 +--
 src/include/utils/array.h             |  6 ++--
 src/include/utils/lsyscache.h         |  6 ++--
 src/include/utils/plancache.h         | 14 +++++-----
 src/include/utils/ruleutils.h         |  8 +++---
 src/tools/pgindent/typedefs.list      |  1 +
 24 files changed, 126 insertions(+), 125 deletions(-)

diff --git a/src/include/commands/tablecmds.h b/src/include/commands/tablecmds.h
index 6832470d387..e9b0fab0767 100644
--- a/src/include/commands/tablecmds.h
+++ b/src/include/commands/tablecmds.h
@@ -21,7 +21,8 @@
 #include "storage/lock.h"
 #include "utils/relcache.h"
 
-struct AlterTableUtilityContext;	/* avoid including tcop/utility.h here */
+typedef struct AlterTableUtilityContext AlterTableUtilityContext;	/* avoid including
+																	 * tcop/utility.h here */
 
 
 extern ObjectAddress DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId,
@@ -34,7 +35,7 @@ extern void RemoveRelations(DropStmt *drop);
 extern Oid	AlterTableLookupRelation(AlterTableStmt *stmt, LOCKMODE lockmode);
 
 extern void AlterTable(AlterTableStmt *stmt, LOCKMODE lockmode,
-					   struct AlterTableUtilityContext *context);
+					   AlterTableUtilityContext *context);
 
 extern LOCKMODE AlterTableGetLockLevel(List *cmds);
 
diff --git a/src/include/common/string.h b/src/include/common/string.h
index ffe5ed51c5d..55ed8774364 100644
--- a/src/include/common/string.h
+++ b/src/include/common/string.h
@@ -12,7 +12,8 @@
 
 #include <signal.h>
 
-struct StringInfoData;			/* avoid including stringinfo.h here */
+typedef struct StringInfoData *StringInfo;	/* avoid including stringinfo.h
+											 * here */
 
 typedef struct PromptInterruptContext
 {
@@ -32,8 +33,8 @@ extern bool pg_is_ascii(const char *str);
 
 /* functions in src/common/pg_get_line.c */
 extern char *pg_get_line(FILE *stream, PromptInterruptContext *prompt_ctx);
-extern bool pg_get_line_buf(FILE *stream, struct StringInfoData *buf);
-extern bool pg_get_line_append(FILE *stream, struct StringInfoData *buf,
+extern bool pg_get_line_buf(FILE *stream, StringInfo buf);
+extern bool pg_get_line_append(FILE *stream, StringInfo buf,
 							   PromptInterruptContext *prompt_ctx);
 
 /* functions in src/common/sprompt.c */
diff --git a/src/include/executor/executor.h b/src/include/executor/executor.h
index 10dcea037c3..e7330ae61a7 100644
--- a/src/include/executor/executor.h
+++ b/src/include/executor/executor.h
@@ -100,12 +100,12 @@ extern PGDLLIMPORT ExecutorCheckPerms_hook_type ExecutorCheckPerms_hook;
 /*
  * prototypes from functions in execAmi.c
  */
-struct Path;					/* avoid including pathnodes.h here */
+typedef struct Path Path;		/* avoid including pathnodes.h here */
 
 extern void ExecReScan(PlanState *node);
 extern void ExecMarkPos(PlanState *node);
 extern void ExecRestrPos(PlanState *node);
-extern bool ExecSupportsMarkRestore(struct Path *pathnode);
+extern bool ExecSupportsMarkRestore(Path *pathnode);
 extern bool ExecSupportsBackwardScan(Plan *node);
 extern bool ExecMaterializesOutput(NodeTag plantype);
 
diff --git a/src/include/executor/tablefunc.h b/src/include/executor/tablefunc.h
index 2c4498c5955..4dd5fef4aea 100644
--- a/src/include/executor/tablefunc.h
+++ b/src/include/executor/tablefunc.h
@@ -14,7 +14,7 @@
 #define _TABLEFUNC_H
 
 /* Forward-declare this to avoid including execnodes.h here */
-struct TableFuncScanState;
+typedef struct TableFuncScanState TableFuncScanState;
 
 /*
  * TableFuncRoutine holds function pointers used for generating content of
@@ -51,17 +51,17 @@ struct TableFuncScanState;
  */
 typedef struct TableFuncRoutine
 {
-	void		(*InitOpaque) (struct TableFuncScanState *state, int natts);
-	void		(*SetDocument) (struct TableFuncScanState *state, Datum value);
-	void		(*SetNamespace) (struct TableFuncScanState *state, const char *name,
+	void		(*InitOpaque) (TableFuncScanState *state, int natts);
+	void		(*SetDocument) (TableFuncScanState *state, Datum value);
+	void		(*SetNamespace) (TableFuncScanState *state, const char *name,
 								 const char *uri);
-	void		(*SetRowFilter) (struct TableFuncScanState *state, const char *path);
-	void		(*SetColumnFilter) (struct TableFuncScanState *state,
+	void		(*SetRowFilter) (TableFuncScanState *state, const char *path);
+	void		(*SetColumnFilter) (TableFuncScanState *state,
 									const char *path, int colnum);
-	bool		(*FetchRow) (struct TableFuncScanState *state);
-	Datum		(*GetValue) (struct TableFuncScanState *state, int colnum,
+	bool		(*FetchRow) (TableFuncScanState *state);
+	Datum		(*GetValue) (TableFuncScanState *state, int colnum,
 							 Oid typid, int32 typmod, bool *isnull);
-	void		(*DestroyOpaque) (struct TableFuncScanState *state);
+	void		(*DestroyOpaque) (TableFuncScanState *state);
 } TableFuncRoutine;
 
 #endif							/* _TABLEFUNC_H */
diff --git a/src/include/nodes/execnodes.h b/src/include/nodes/execnodes.h
index de782014b2d..9623e53e591 100644
--- a/src/include/nodes/execnodes.h
+++ b/src/include/nodes/execnodes.h
@@ -49,15 +49,13 @@
 #include "utils/tuplesort.h"
 #include "utils/tuplestore.h"
 
-struct PlanState;				/* forward references in this file */
-struct ParallelHashJoinState;
-struct ExecRowMark;
-struct ExprState;
-struct ExprContext;
-struct RangeTblEntry;			/* avoid including parsenodes.h here */
-struct ExprEvalStep;			/* avoid including execExpr.h everywhere */
-struct CopyMultiInsertBuffer;
-struct LogicalTapeSet;
+/*
+ * forward references in this file
+ */
+typedef struct PlanState PlanState;
+typedef struct ExecRowMark ExecRowMark;
+typedef struct ExprState ExprState;
+typedef struct ExprContext ExprContext;
 
 
 /* ----------------
@@ -67,8 +65,8 @@ struct LogicalTapeSet;
  * It contains instructions (in ->steps) to evaluate the expression.
  * ----------------
  */
-typedef Datum (*ExprStateEvalFunc) (struct ExprState *expression,
-									struct ExprContext *econtext,
+typedef Datum (*ExprStateEvalFunc) (ExprState *expression,
+									ExprContext *econtext,
 									bool *isNull);
 
 /* Bits in ExprState->flags (see also execExpr.h for private flag bits): */
@@ -131,7 +129,7 @@ typedef struct ExprState
 	int			steps_alloc;	/* allocated length of steps array */
 
 #define FIELDNO_EXPRSTATE_PARENT 11
-	struct PlanState *parent;	/* parent PlanState node, if any */
+	PlanState  *parent;			/* parent PlanState node, if any */
 	ParamListInfo ext_params;	/* for compiling PARAM_EXTERN nodes */
 
 	Datum	   *innermost_caseval;
@@ -638,8 +636,8 @@ typedef struct ResultRelInfo
  */
 typedef struct AsyncRequest
 {
-	struct PlanState *requestor;	/* Node that wants a tuple */
-	struct PlanState *requestee;	/* Node from which a tuple is wanted */
+	PlanState  *requestor;		/* Node that wants a tuple */
+	PlanState  *requestee;		/* Node from which a tuple is wanted */
 	int			request_index;	/* Scratch space for requestor */
 	bool		callback_pending;	/* Callback is needed */
 	bool		request_complete;	/* Request complete, result valid */
@@ -665,8 +663,8 @@ typedef struct EState
 	Index		es_range_table_size;	/* size of the range table arrays */
 	Relation   *es_relations;	/* Array of per-range-table-entry Relation
 								 * pointers, or NULL if not yet opened */
-	struct ExecRowMark **es_rowmarks;	/* Array of per-range-table-entry
-										 * ExecRowMarks, or NULL if none */
+	ExecRowMark **es_rowmarks;	/* Array of per-range-table-entry
+								 * ExecRowMarks, or NULL if none */
 	List	   *es_rteperminfos;	/* List of RTEPermissionInfo */
 	PlannedStmt *es_plannedstmt;	/* link to top of plan tree */
 	List	   *es_part_prune_infos;	/* List of PartitionPruneInfo */
@@ -1006,8 +1004,8 @@ typedef struct SubPlanState
 {
 	NodeTag		type;
 	SubPlan    *subplan;		/* expression plan node */
-	struct PlanState *planstate;	/* subselect plan's state tree */
-	struct PlanState *parent;	/* parent plan node's state tree */
+	PlanState  *planstate;		/* subselect plan's state tree */
+	PlanState  *parent;			/* parent plan node's state tree */
 	ExprState  *testexpr;		/* state of combining expression */
 	HeapTuple	curTuple;		/* copy of most recent tuple from subplan */
 	Datum		curArray;		/* most recent array from ARRAY() subplan */
@@ -1144,7 +1142,7 @@ typedef struct JsonExprState
  * if no more tuples are available.
  * ----------------
  */
-typedef TupleTableSlot *(*ExecProcNodeMtd) (struct PlanState *pstate);
+typedef TupleTableSlot *(*ExecProcNodeMtd) (PlanState *pstate);
 
 /* ----------------
  *		PlanState node
@@ -1181,8 +1179,8 @@ typedef struct PlanState
 	 * subPlan list, which does not exist in the plan tree).
 	 */
 	ExprState  *qual;			/* boolean qual condition */
-	struct PlanState *lefttree; /* input plan tree(s) */
-	struct PlanState *righttree;
+	PlanState  *lefttree;		/* input plan tree(s) */
+	PlanState  *righttree;
 
 	List	   *initPlan;		/* Init SubPlanState nodes (un-correlated expr
 								 * subselects) */
diff --git a/src/include/nodes/nodeFuncs.h b/src/include/nodes/nodeFuncs.h
index 5653fec8cbe..11c1c140ec4 100644
--- a/src/include/nodes/nodeFuncs.h
+++ b/src/include/nodes/nodeFuncs.h
@@ -15,7 +15,7 @@
 
 #include "nodes/parsenodes.h"
 
-struct PlanState;				/* avoid including execnodes.h too */
+typedef struct PlanState PlanState; /* avoid including execnodes.h too */
 
 
 /* flags bits for query_tree_walker and query_tree_mutator */
@@ -38,7 +38,7 @@ typedef bool (*check_function_callback) (Oid func_id, void *context);
 
 /* callback functions for tree walkers */
 typedef bool (*tree_walker_callback) (Node *node, void *context);
-typedef bool (*planstate_tree_walker_callback) (struct PlanState *planstate,
+typedef bool (*planstate_tree_walker_callback) (PlanState *planstate,
 												void *context);
 
 /* callback functions for tree mutators */
@@ -217,7 +217,7 @@ extern bool raw_expression_tree_walker_impl(Node *node,
 											tree_walker_callback walker,
 											void *context);
 
-extern bool planstate_tree_walker_impl(struct PlanState *planstate,
+extern bool planstate_tree_walker_impl(PlanState *planstate,
 									   planstate_tree_walker_callback walker,
 									   void *context);
 
diff --git a/src/include/nodes/params.h b/src/include/nodes/params.h
index 4321ca6329b..3c84df3f79a 100644
--- a/src/include/nodes/params.h
+++ b/src/include/nodes/params.h
@@ -14,11 +14,10 @@
 #ifndef PARAMS_H
 #define PARAMS_H
 
-/* Forward declarations, to avoid including other headers */
-struct Bitmapset;
-struct ExprState;
-struct Param;
-struct ParseState;
+/* to avoid including other headers */
+typedef struct ExprState ExprState;
+typedef struct Param Param;
+typedef struct ParseState ParseState;
 
 
 /*
@@ -101,11 +100,11 @@ typedef ParamExternData *(*ParamFetchHook) (ParamListInfo params,
 											int paramid, bool speculative,
 											ParamExternData *workspace);
 
-typedef void (*ParamCompileHook) (ParamListInfo params, struct Param *param,
-								  struct ExprState *state,
+typedef void (*ParamCompileHook) (ParamListInfo params, Param *param,
+								  ExprState *state,
 								  Datum *resv, bool *resnull);
 
-typedef void (*ParserSetupHook) (struct ParseState *pstate, void *arg);
+typedef void (*ParserSetupHook) (ParseState *pstate, void *arg);
 
 typedef struct ParamListInfoData
 {
@@ -123,7 +122,7 @@ typedef struct ParamListInfoData
 	 * must be of length numParams.
 	 */
 	ParamExternData params[FLEXIBLE_ARRAY_MEMBER];
-}			ParamListInfoData;
+} ParamListInfoData;
 
 
 /* ----------------
diff --git a/src/include/nodes/subscripting.h b/src/include/nodes/subscripting.h
index 234e8ad8012..e991f4bf826 100644
--- a/src/include/nodes/subscripting.h
+++ b/src/include/nodes/subscripting.h
@@ -15,10 +15,10 @@
 
 #include "nodes/primnodes.h"
 
-/* Forward declarations, to avoid including other headers */
-struct ParseState;
-struct SubscriptingRefState;
-struct SubscriptExecSteps;
+/* to avoid including other headers */
+typedef struct ParseState ParseState;
+typedef struct SubscriptingRefState SubscriptingRefState;
+typedef struct SubscriptExecSteps SubscriptExecSteps;
 
 /*
  * The SQL-visible function that defines a subscripting method is declared
@@ -94,7 +94,7 @@ struct SubscriptExecSteps;
  */
 typedef void (*SubscriptTransform) (SubscriptingRef *sbsref,
 									List *indirection,
-									struct ParseState *pstate,
+									ParseState *pstate,
 									bool isSlice,
 									bool isAssignment);
 
@@ -151,8 +151,8 @@ typedef void (*SubscriptTransform) (SubscriptingRef *sbsref,
  * Set the relevant pointers to NULL for any omitted methods.
  */
 typedef void (*SubscriptExecSetup) (const SubscriptingRef *sbsref,
-									struct SubscriptingRefState *sbsrefstate,
-									struct SubscriptExecSteps *methods);
+									SubscriptingRefState *sbsrefstate,
+									SubscriptExecSteps *methods);
 
 /* Struct returned by the SQL-visible subscript handler function */
 typedef struct SubscriptRoutines
diff --git a/src/include/nodes/supportnodes.h b/src/include/nodes/supportnodes.h
index 9c047cc401b..7b623d54058 100644
--- a/src/include/nodes/supportnodes.h
+++ b/src/include/nodes/supportnodes.h
@@ -35,10 +35,10 @@
 
 #include "nodes/plannodes.h"
 
-struct PlannerInfo;				/* avoid including pathnodes.h here */
-struct IndexOptInfo;
-struct SpecialJoinInfo;
-struct WindowClause;
+typedef struct PlannerInfo PlannerInfo; /* avoid including pathnodes.h here */
+typedef struct IndexOptInfo IndexOptInfo;
+typedef struct SpecialJoinInfo SpecialJoinInfo;
+typedef struct WindowClause WindowClause;
 
 /*
  * The Simplify request allows the support function to perform plan-time
@@ -65,7 +65,7 @@ typedef struct SupportRequestSimplify
 {
 	NodeTag		type;
 
-	struct PlannerInfo *root;	/* Planner's infrastructure */
+	PlannerInfo *root;			/* Planner's infrastructure */
 	FuncExpr   *fcall;			/* Function call to be simplified */
 } SupportRequestSimplify;
 
@@ -93,14 +93,14 @@ typedef struct SupportRequestSelectivity
 	NodeTag		type;
 
 	/* Input fields: */
-	struct PlannerInfo *root;	/* Planner's infrastructure */
+	PlannerInfo *root;			/* Planner's infrastructure */
 	Oid			funcid;			/* function we are inquiring about */
 	List	   *args;			/* pre-simplified arguments to function */
 	Oid			inputcollid;	/* function's input collation */
 	bool		is_join;		/* is this a join or restriction case? */
 	int			varRelid;		/* if restriction, RTI of target relation */
 	JoinType	jointype;		/* if join, outer join type */
-	struct SpecialJoinInfo *sjinfo; /* if outer join, info about join */
+	SpecialJoinInfo *sjinfo;	/* if outer join, info about join */
 
 	/* Output fields: */
 	Selectivity selectivity;	/* returned selectivity estimate */
@@ -133,7 +133,7 @@ typedef struct SupportRequestCost
 	NodeTag		type;
 
 	/* Input fields: */
-	struct PlannerInfo *root;	/* Planner's infrastructure (could be NULL) */
+	PlannerInfo *root;			/* Planner's infrastructure (could be NULL) */
 	Oid			funcid;			/* function we are inquiring about */
 	Node	   *node;			/* parse node invoking function, or NULL */
 
@@ -160,7 +160,7 @@ typedef struct SupportRequestRows
 	NodeTag		type;
 
 	/* Input fields: */
-	struct PlannerInfo *root;	/* Planner's infrastructure (could be NULL) */
+	PlannerInfo *root;			/* Planner's infrastructure (could be NULL) */
 	Oid			funcid;			/* function we are inquiring about */
 	Node	   *node;			/* parse node invoking function */
 
@@ -225,11 +225,11 @@ typedef struct SupportRequestIndexCondition
 	NodeTag		type;
 
 	/* Input fields: */
-	struct PlannerInfo *root;	/* Planner's infrastructure */
+	PlannerInfo *root;			/* Planner's infrastructure */
 	Oid			funcid;			/* function we are inquiring about */
 	Node	   *node;			/* parse node invoking function */
 	int			indexarg;		/* index of function arg matching indexcol */
-	struct IndexOptInfo *index; /* planner's info about target index */
+	IndexOptInfo *index;		/* planner's info about target index */
 	int			indexcol;		/* index of target index column (0-based) */
 	Oid			opfamily;		/* index column's operator family */
 	Oid			indexcollation; /* index column's collation */
@@ -293,7 +293,7 @@ typedef struct SupportRequestWFuncMonotonic
 
 	/* Input fields: */
 	WindowFunc *window_func;	/* Pointer to the window function data */
-	struct WindowClause *window_clause; /* Pointer to the window clause data */
+	WindowClause *window_clause;	/* Pointer to the window clause data */
 
 	/* Output fields: */
 	MonotonicFunction monotonic;
@@ -336,7 +336,7 @@ typedef struct SupportRequestOptimizeWindowClause
 
 	/* Input fields: */
 	WindowFunc *window_func;	/* Pointer to the window function data */
-	struct WindowClause *window_clause; /* Pointer to the window clause data */
+	WindowClause *window_clause;	/* Pointer to the window clause data */
 
 	/* Input/Output fields: */
 	int			frameOptions;	/* New frameOptions, or left untouched if no
diff --git a/src/include/optimizer/optimizer.h b/src/include/optimizer/optimizer.h
index 03b214755c2..d490ef3b506 100644
--- a/src/include/optimizer/optimizer.h
+++ b/src/include/optimizer/optimizer.h
@@ -35,9 +35,9 @@ typedef struct IndexOptInfo IndexOptInfo;
 typedef struct SpecialJoinInfo SpecialJoinInfo;
 
 /* It also seems best not to include plannodes.h, params.h, or htup.h here */
-struct PlannedStmt;
-struct ParamListInfoData;
-struct HeapTupleData;
+typedef struct PlannedStmt PlannedStmt;
+typedef struct ParamListInfoData ParamListInfoData;
+typedef struct HeapTupleData *HeapTuple;
 
 
 /* in path/clausesel.c: */
@@ -102,9 +102,9 @@ extern PGDLLIMPORT int debug_parallel_query;
 extern PGDLLIMPORT bool parallel_leader_participation;
 extern PGDLLIMPORT bool enable_distinct_reordering;
 
-extern struct PlannedStmt *planner(Query *parse, const char *query_string,
-								   int cursorOptions,
-								   struct ParamListInfoData *boundParams);
+extern PlannedStmt *planner(Query *parse, const char *query_string,
+							int cursorOptions,
+							ParamListInfoData *boundParams);
 
 extern Expr *expression_planner(Expr *expr);
 extern Expr *expression_planner_with_deps(Expr *expr,
@@ -147,7 +147,7 @@ extern bool var_is_nonnullable(PlannerInfo *root, Var *var, bool use_rel_info);
 
 extern List *expand_function_arguments(List *args, bool include_out_arguments,
 									   Oid result_type,
-									   struct HeapTupleData *func_tuple);
+									   HeapTuple func_tuple);
 
 extern ScalarArrayOpExpr *make_SAOP_expr(Oid oper, Node *leftexpr,
 										 Oid coltype, Oid arraycollid,
diff --git a/src/include/parser/parse_utilcmd.h b/src/include/parser/parse_utilcmd.h
index 9f2b58de797..4965fac4495 100644
--- a/src/include/parser/parse_utilcmd.h
+++ b/src/include/parser/parse_utilcmd.h
@@ -16,7 +16,7 @@
 
 #include "parser/parse_node.h"
 
-struct AttrMap;					/* avoid including attmap.h here */
+typedef struct AttrMap AttrMap; /* avoid including attmap.h here */
 
 
 extern List *transformCreateStmt(CreateStmt *stmt, const char *queryString);
@@ -38,7 +38,7 @@ extern List *expandTableLikeClause(RangeVar *heapRel,
 								   TableLikeClause *table_like_clause);
 extern IndexStmt *generateClonedIndexStmt(RangeVar *heapRel,
 										  Relation source_idx,
-										  const struct AttrMap *attmap,
+										  const AttrMap *attmap,
 										  Oid *constraintOid);
 
 #endif							/* PARSE_UTILCMD_H */
diff --git a/src/include/partitioning/partbounds.h b/src/include/partitioning/partbounds.h
index 65f161f7188..083b6e3a88a 100644
--- a/src/include/partitioning/partbounds.h
+++ b/src/include/partitioning/partbounds.h
@@ -15,7 +15,7 @@
 #include "parser/parse_node.h"
 #include "partitioning/partdefs.h"
 
-struct RelOptInfo;				/* avoid including pathnodes.h here */
+typedef struct RelOptInfo RelOptInfo;	/* avoid including pathnodes.h here */
 
 
 /*
@@ -114,8 +114,8 @@ extern PartitionBoundInfo partition_bounds_copy(PartitionBoundInfo src,
 extern PartitionBoundInfo partition_bounds_merge(int partnatts,
 												 FmgrInfo *partsupfunc,
 												 Oid *partcollation,
-												 struct RelOptInfo *outer_rel,
-												 struct RelOptInfo *inner_rel,
+												 RelOptInfo *outer_rel,
+												 RelOptInfo *inner_rel,
 												 JoinType jointype,
 												 List **outer_parts,
 												 List **inner_parts);
diff --git a/src/include/partitioning/partprune.h b/src/include/partitioning/partprune.h
index c413734789a..657b436d958 100644
--- a/src/include/partitioning/partprune.h
+++ b/src/include/partitioning/partprune.h
@@ -17,8 +17,8 @@
 #include "nodes/execnodes.h"
 #include "partitioning/partdefs.h"
 
-struct PlannerInfo;				/* avoid including pathnodes.h here */
-struct RelOptInfo;
+typedef struct PlannerInfo PlannerInfo; /* avoid including pathnodes.h here */
+typedef struct RelOptInfo RelOptInfo;
 
 
 /*
@@ -70,11 +70,11 @@ typedef struct PartitionPruneContext
 #define PruneCxtStateIdx(partnatts, step_id, keyno) \
 	((partnatts) * (step_id) + (keyno))
 
-extern int	make_partition_pruneinfo(struct PlannerInfo *root,
-									 struct RelOptInfo *parentrel,
+extern int	make_partition_pruneinfo(PlannerInfo *root,
+									 RelOptInfo *parentrel,
 									 List *subpaths,
 									 List *prunequal);
-extern Bitmapset *prune_append_rel_partitions(struct RelOptInfo *rel);
+extern Bitmapset *prune_append_rel_partitions(RelOptInfo *rel);
 extern Bitmapset *get_matching_partitions(PartitionPruneContext *context,
 										  List *pruning_steps);
 
diff --git a/src/include/rewrite/rewriteManip.h b/src/include/rewrite/rewriteManip.h
index 7c018f2a4e3..74de195deeb 100644
--- a/src/include/rewrite/rewriteManip.h
+++ b/src/include/rewrite/rewriteManip.h
@@ -17,7 +17,7 @@
 #include "nodes/parsenodes.h"
 #include "nodes/pathnodes.h"
 
-struct AttrMap;					/* avoid including attmap.h here */
+typedef struct AttrMap AttrMap; /* avoid including attmap.h here */
 
 
 typedef struct replace_rte_variables_context replace_rte_variables_context;
@@ -101,7 +101,7 @@ extern Node *replace_rte_variables_mutator(Node *node,
 
 extern Node *map_variable_attnos(Node *node,
 								 int target_varno, int sublevels_up,
-								 const struct AttrMap *attno_map,
+								 const AttrMap *attno_map,
 								 Oid to_rowtype, bool *found_whole_row);
 
 extern Node *ReplaceVarFromTargetList(Var *var,
diff --git a/src/include/storage/bufmgr.h b/src/include/storage/bufmgr.h
index 41fdc1e7693..47360a3d3d8 100644
--- a/src/include/storage/bufmgr.h
+++ b/src/include/storage/bufmgr.h
@@ -93,6 +93,9 @@ typedef enum ExtendBufferedFlags
 	EB_LOCK_TARGET = (1 << 5),
 }			ExtendBufferedFlags;
 
+/* forward declared, to avoid including smgr.h here */
+typedef struct SMgrRelationData *SMgrRelation;
+
 /*
  * Some functions identify relations either by relation or smgr +
  * relpersistence.  Used via the BMR_REL()/BMR_SMGR() macros below.  This
@@ -101,7 +104,7 @@ typedef enum ExtendBufferedFlags
 typedef struct BufferManagerRelation
 {
 	Relation	rel;
-	struct SMgrRelationData *smgr;
+	SMgrRelation smgr;
 	char		relpersistence;
 } BufferManagerRelation;
 
@@ -122,7 +125,7 @@ struct ReadBuffersOperation
 {
 	/* The following members should be set by the caller. */
 	Relation	rel;			/* optional */
-	struct SMgrRelationData *smgr;
+	SMgrRelation smgr;
 	char		persistence;
 	ForkNumber	forknum;
 	BufferAccessStrategy strategy;
@@ -143,11 +146,8 @@ struct ReadBuffersOperation
 
 typedef struct ReadBuffersOperation ReadBuffersOperation;
 
-/* forward declared, to avoid having to expose buf_internals.h here */
-struct WritebackContext;
-
-/* forward declared, to avoid including smgr.h here */
-struct SMgrRelationData;
+/* to avoid having to expose buf_internals.h here */
+typedef struct WritebackContext WritebackContext;
 
 /* in globals.c ... this duplicates miscadmin.h */
 extern PGDLLIMPORT int NBuffers;
@@ -201,7 +201,7 @@ extern PGDLLIMPORT int32 *LocalRefCount;
 /*
  * prototypes for functions in bufmgr.c
  */
-extern PrefetchBufferResult PrefetchSharedBuffer(struct SMgrRelationData *smgr_reln,
+extern PrefetchBufferResult PrefetchSharedBuffer(SMgrRelation smgr_reln,
 												 ForkNumber forkNum,
 												 BlockNumber blockNum);
 extern PrefetchBufferResult PrefetchBuffer(Relation reln, ForkNumber forkNum,
@@ -268,15 +268,15 @@ extern BlockNumber RelationGetNumberOfBlocksInFork(Relation relation,
 												   ForkNumber forkNum);
 extern void FlushOneBuffer(Buffer buffer);
 extern void FlushRelationBuffers(Relation rel);
-extern void FlushRelationsAllBuffers(struct SMgrRelationData **smgrs, int nrels);
+extern void FlushRelationsAllBuffers(SMgrRelation *smgrs, int nrels);
 extern void CreateAndCopyRelationData(RelFileLocator src_rlocator,
 									  RelFileLocator dst_rlocator,
 									  bool permanent);
 extern void FlushDatabaseBuffers(Oid dbid);
-extern void DropRelationBuffers(struct SMgrRelationData *smgr_reln,
+extern void DropRelationBuffers(SMgrRelation smgr_reln,
 								ForkNumber *forkNum,
 								int nforks, BlockNumber *firstDelBlock);
-extern void DropRelationsAllBuffers(struct SMgrRelationData **smgr_reln,
+extern void DropRelationsAllBuffers(SMgrRelation *smgr_reln,
 									int nlocators);
 extern void DropDatabaseBuffers(Oid dbid);
 
@@ -298,7 +298,7 @@ extern bool ConditionalLockBufferForCleanup(Buffer buffer);
 extern bool IsBufferCleanupOK(Buffer buffer);
 extern bool HoldingBufferPinThatDelaysRecovery(void);
 
-extern bool BgBufferSync(struct WritebackContext *wb_context);
+extern bool BgBufferSync(WritebackContext *wb_context);
 
 extern uint32 GetPinLimit(void);
 extern uint32 GetLocalPinLimit(void);
diff --git a/src/include/storage/bulk_write.h b/src/include/storage/bulk_write.h
index 7885415f6cb..ca359784016 100644
--- a/src/include/storage/bulk_write.h
+++ b/src/include/storage/bulk_write.h
@@ -28,10 +28,10 @@ typedef struct BulkWriteState BulkWriteState;
 typedef PGIOAlignedBlock *BulkWriteBuffer;
 
 /* forward declared from smgr.h */
-struct SMgrRelationData;
+typedef struct SMgrRelationData *SMgrRelation;
 
 extern BulkWriteState *smgr_bulk_start_rel(Relation rel, ForkNumber forknum);
-extern BulkWriteState *smgr_bulk_start_smgr(struct SMgrRelationData *smgr, ForkNumber forknum, bool use_wal);
+extern BulkWriteState *smgr_bulk_start_smgr(SMgrRelation smgr, ForkNumber forknum, bool use_wal);
 
 extern BulkWriteBuffer smgr_bulk_get_buf(BulkWriteState *bulkstate);
 extern void smgr_bulk_write(BulkWriteState *bulkstate, BlockNumber blocknum, BulkWriteBuffer buf, bool page_std);
diff --git a/src/include/storage/dsm.h b/src/include/storage/dsm.h
index 2302cc7f40b..88cf0962957 100644
--- a/src/include/storage/dsm.h
+++ b/src/include/storage/dsm.h
@@ -20,9 +20,9 @@ typedef struct dsm_segment dsm_segment;
 #define DSM_CREATE_NULL_IF_MAXSEGMENTS			0x0001
 
 /* Startup and shutdown functions. */
-struct PGShmemHeader;			/* avoid including pg_shmem.h */
+typedef struct PGShmemHeader PGShmemHeader; /* avoid including pg_shmem.h */
 extern void dsm_cleanup_using_control_segment(dsm_handle old_control_handle);
-extern void dsm_postmaster_startup(struct PGShmemHeader *);
+extern void dsm_postmaster_startup(PGShmemHeader *);
 extern void dsm_backend_shutdown(void);
 extern void dsm_detach_all(void);
 
diff --git a/src/include/storage/shmem.h b/src/include/storage/shmem.h
index 8604feca93b..cd683a9d2d9 100644
--- a/src/include/storage/shmem.h
+++ b/src/include/storage/shmem.h
@@ -27,8 +27,9 @@
 
 /* shmem.c */
 extern PGDLLIMPORT slock_t *ShmemLock;
-struct PGShmemHeader;			/* avoid including storage/pg_shmem.h here */
-extern void InitShmemAccess(struct PGShmemHeader *seghdr);
+typedef struct PGShmemHeader PGShmemHeader; /* avoid including
+											 * storage/pg_shmem.h here */
+extern void InitShmemAccess(PGShmemHeader *seghdr);
 extern void InitShmemAllocation(void);
 extern void *ShmemAlloc(Size size);
 extern void *ShmemAllocNoError(Size size);
diff --git a/src/include/tcop/pquery.h b/src/include/tcop/pquery.h
index fa3cc5f2dfc..ccd995fc88e 100644
--- a/src/include/tcop/pquery.h
+++ b/src/include/tcop/pquery.h
@@ -17,7 +17,7 @@
 #include "nodes/parsenodes.h"
 #include "utils/portal.h"
 
-struct PlannedStmt;				/* avoid including plannodes.h here */
+typedef struct PlannedStmt PlannedStmt; /* avoid including plannodes.h here */
 
 
 extern PGDLLIMPORT Portal ActivePortal;
@@ -44,7 +44,7 @@ extern uint64 PortalRunFetch(Portal portal,
 							 long count,
 							 DestReceiver *dest);
 
-extern bool PlannedStmtRequiresSnapshot(struct PlannedStmt *pstmt);
+extern bool PlannedStmtRequiresSnapshot(PlannedStmt *pstmt);
 
 extern void EnsurePortalSnapshotExists(void);
 
diff --git a/src/include/utils/array.h b/src/include/utils/array.h
index 52f1fbf8d43..3383f16a3bb 100644
--- a/src/include/utils/array.h
+++ b/src/include/utils/array.h
@@ -65,8 +65,8 @@
 #include "utils/expandeddatum.h"
 
 /* avoid including execnodes.h here */
-struct ExprState;
-struct ExprContext;
+typedef struct ExprState ExprState;
+typedef struct ExprContext ExprContext;
 
 
 /*
@@ -384,7 +384,7 @@ extern ArrayType *array_set(ArrayType *array, int nSubscripts, int *indx,
 							int arraytyplen, int elmlen, bool elmbyval, char elmalign);
 
 extern Datum array_map(Datum arrayd,
-					   struct ExprState *exprstate, struct ExprContext *econtext,
+					   ExprState *exprstate, ExprContext *econtext,
 					   Oid retType, ArrayMapState *amstate);
 
 extern void array_bitmap_copy(bits8 *destbitmap, int destoffset,
diff --git a/src/include/utils/lsyscache.h b/src/include/utils/lsyscache.h
index c65cee4f24c..50fb149e9ac 100644
--- a/src/include/utils/lsyscache.h
+++ b/src/include/utils/lsyscache.h
@@ -19,7 +19,7 @@
 #include "nodes/pg_list.h"
 
 /* avoid including subscripting.h here */
-struct SubscriptRoutines;
+typedef struct SubscriptRoutines SubscriptRoutines;
 
 /* Result list element for get_op_index_interpretation */
 typedef struct OpIndexInterpretation
@@ -187,8 +187,8 @@ extern Oid	get_typmodin(Oid typid);
 extern Oid	get_typcollation(Oid typid);
 extern bool type_is_collatable(Oid typid);
 extern RegProcedure get_typsubscript(Oid typid, Oid *typelemp);
-extern const struct SubscriptRoutines *getSubscriptingRoutines(Oid typid,
-															   Oid *typelemp);
+extern const SubscriptRoutines *getSubscriptingRoutines(Oid typid,
+														Oid *typelemp);
 extern Oid	getBaseType(Oid typid);
 extern Oid	getBaseTypeAndTypmod(Oid typid, int32 *typmod);
 extern int32 get_typavgwidth(Oid typid, int32 typmod);
diff --git a/src/include/utils/plancache.h b/src/include/utils/plancache.h
index 1baa6d50bfd..a82b66d4bc2 100644
--- a/src/include/utils/plancache.h
+++ b/src/include/utils/plancache.h
@@ -24,8 +24,8 @@
 
 
 /* Forward declarations, to avoid including parsenodes.h here */
-struct Query;
-struct RawStmt;
+typedef struct Query Query;
+typedef struct RawStmt RawStmt;
 
 /* possible values for plan_cache_mode */
 typedef enum
@@ -105,8 +105,8 @@ typedef void (*PostRewriteHook) (List *querytree_list, void *arg);
 typedef struct CachedPlanSource
 {
 	int			magic;			/* should equal CACHEDPLANSOURCE_MAGIC */
-	struct RawStmt *raw_parse_tree; /* output of raw_parser(), or NULL */
-	struct Query *analyzed_parse_tree;	/* analyzed parse tree, or NULL */
+	RawStmt    *raw_parse_tree; /* output of raw_parser(), or NULL */
+	Query	   *analyzed_parse_tree;	/* analyzed parse tree, or NULL */
 	const char *query_string;	/* source text of query */
 	CommandTag	commandTag;		/* command tag for query */
 	Oid		   *param_types;	/* array of parameter type OIDs, or NULL */
@@ -202,13 +202,13 @@ extern void ResetPlanCache(void);
 
 extern void ReleaseAllPlanCacheRefsInOwner(ResourceOwner owner);
 
-extern CachedPlanSource *CreateCachedPlan(struct RawStmt *raw_parse_tree,
+extern CachedPlanSource *CreateCachedPlan(RawStmt *raw_parse_tree,
 										  const char *query_string,
 										  CommandTag commandTag);
-extern CachedPlanSource *CreateCachedPlanForQuery(struct Query *analyzed_parse_tree,
+extern CachedPlanSource *CreateCachedPlanForQuery(Query *analyzed_parse_tree,
 												  const char *query_string,
 												  CommandTag commandTag);
-extern CachedPlanSource *CreateOneShotCachedPlan(struct RawStmt *raw_parse_tree,
+extern CachedPlanSource *CreateOneShotCachedPlan(RawStmt *raw_parse_tree,
 												 const char *query_string,
 												 CommandTag commandTag);
 extern void CompleteCachedPlan(CachedPlanSource *plansource,
diff --git a/src/include/utils/ruleutils.h b/src/include/utils/ruleutils.h
index 5f2ea2e4d0e..7ba7d887914 100644
--- a/src/include/utils/ruleutils.h
+++ b/src/include/utils/ruleutils.h
@@ -17,8 +17,8 @@
 #include "nodes/parsenodes.h"
 #include "nodes/pg_list.h"
 
-struct Plan;					/* avoid including plannodes.h here */
-struct PlannedStmt;
+typedef struct Plan Plan;		/* avoid including plannodes.h here */
+typedef struct PlannedStmt PlannedStmt;
 
 /* Flags for pg_get_indexdef_columns_extended() */
 #define RULE_INDEXDEF_PRETTY		0x01
@@ -37,10 +37,10 @@ extern char *pg_get_constraintdef_command(Oid constraintId);
 extern char *deparse_expression(Node *expr, List *dpcontext,
 								bool forceprefix, bool showimplicit);
 extern List *deparse_context_for(const char *aliasname, Oid relid);
-extern List *deparse_context_for_plan_tree(struct PlannedStmt *pstmt,
+extern List *deparse_context_for_plan_tree(PlannedStmt *pstmt,
 										   List *rtable_names);
 extern List *set_deparse_context_plan(List *dpcontext,
-									  struct Plan *plan, List *ancestors);
+									  Plan *plan, List *ancestors);
 extern List *select_rtable_names_for_explain(List *rtable,
 											 Bitmapset *rels_used);
 extern char *get_window_frame_options_for_explain(int frameOptions,
diff --git a/src/tools/pgindent/typedefs.list b/src/tools/pgindent/typedefs.list
index a13e8162890..d918eda4aaf 100644
--- a/src/tools/pgindent/typedefs.list
+++ b/src/tools/pgindent/typedefs.list
@@ -2083,6 +2083,7 @@ ParamExternData
 ParamFetchHook
 ParamKind
 ParamListInfo
+ParamListInfoData
 ParamPathInfo
 ParamRef
 ParamsErrorCbData
-- 
2.51.0

0006-Remove-hbaPort-type.patchtext/plain; charset=UTF-8; name=0006-Remove-hbaPort-type.patchDownload
From 4505dd4e62776770076f582a3ad01b9c35eafe6c Mon Sep 17 00:00:00 2001
From: Peter Eisentraut <peter@eisentraut.org>
Date: Fri, 29 Aug 2025 13:18:51 +0200
Subject: [PATCH 6/7] Remove hbaPort type

This was just a workaround to avoid including the header file that
defines the Port type.  With C11, we can now just re-define the Port
type without the possibility of a conflict.
---
 src/backend/libpq/auth.c         | 8 ++++----
 src/backend/libpq/hba.c          | 6 +++---
 src/include/libpq/hba.h          | 6 +++---
 src/tools/pgindent/typedefs.list | 1 -
 4 files changed, 10 insertions(+), 11 deletions(-)

diff --git a/src/backend/libpq/auth.c b/src/backend/libpq/auth.c
index 4da46666439..ec4dbacf015 100644
--- a/src/backend/libpq/auth.c
+++ b/src/backend/libpq/auth.c
@@ -70,14 +70,14 @@ static int	CheckMD5Auth(Port *port, char *shadow_pass,
 /* Standard TCP port number for Ident service.  Assigned by IANA */
 #define IDENT_PORT 113
 
-static int	ident_inet(hbaPort *port);
+static int	ident_inet(Port *port);
 
 
 /*----------------------------------------------------------------
  * Peer authentication
  *----------------------------------------------------------------
  */
-static int	auth_peer(hbaPort *port);
+static int	auth_peer(Port *port);
 
 
 /*----------------------------------------------------------------
@@ -1668,7 +1668,7 @@ interpret_ident_response(const char *ident_response,
  *	latch was set would improve the responsiveness to timeouts/cancellations.
  */
 static int
-ident_inet(hbaPort *port)
+ident_inet(Port *port)
 {
 	const SockAddr remote_addr = port->raddr;
 	const SockAddr local_addr = port->laddr;
@@ -1853,7 +1853,7 @@ ident_inet(hbaPort *port)
  *	Iff authorized, return STATUS_OK, otherwise return STATUS_ERROR.
  */
 static int
-auth_peer(hbaPort *port)
+auth_peer(Port *port)
 {
 	uid_t		uid;
 	gid_t		gid;
diff --git a/src/backend/libpq/hba.c b/src/backend/libpq/hba.c
index fecee8224d0..97a3586000b 100644
--- a/src/backend/libpq/hba.c
+++ b/src/backend/libpq/hba.c
@@ -1075,7 +1075,7 @@ hostname_match(const char *pattern, const char *actual_hostname)
  * Check to see if a connecting IP matches a given host name.
  */
 static bool
-check_hostname(hbaPort *port, const char *hostname)
+check_hostname(Port *port, const char *hostname)
 {
 	struct addrinfo *gai_result,
 			   *gai;
@@ -2528,7 +2528,7 @@ parse_hba_auth_opt(char *name, char *val, HbaLine *hbaline,
  *	request.
  */
 static void
-check_hba(hbaPort *port)
+check_hba(Port *port)
 {
 	Oid			roleid;
 	ListCell   *line;
@@ -3125,7 +3125,7 @@ load_ident(void)
  *	method = uaImplicitReject.
  */
 void
-hba_getauthmethod(hbaPort *port)
+hba_getauthmethod(Port *port)
 {
 	check_hba(port);
 }
diff --git a/src/include/libpq/hba.h b/src/include/libpq/hba.h
index 3657f182db3..e3748d3c8c9 100644
--- a/src/include/libpq/hba.h
+++ b/src/include/libpq/hba.h
@@ -169,13 +169,13 @@ typedef struct TokenizedAuthLine
 	char	   *err_msg;		/* Error message if any */
 } TokenizedAuthLine;
 
-/* kluge to avoid including libpq/libpq-be.h here */
-typedef struct Port hbaPort;
+/* avoid including libpq/libpq-be.h here */
+typedef struct Port Port;
 
 extern bool load_hba(void);
 extern bool load_ident(void);
 extern const char *hba_authname(UserAuth auth_method);
-extern void hba_getauthmethod(hbaPort *port);
+extern void hba_getauthmethod(Port *port);
 extern int	check_usermap(const char *usermap_name,
 						  const char *pg_user, const char *system_user,
 						  bool case_insensitive);
diff --git a/src/tools/pgindent/typedefs.list b/src/tools/pgindent/typedefs.list
index d918eda4aaf..0f4974b5fcb 100644
--- a/src/tools/pgindent/typedefs.list
+++ b/src/tools/pgindent/typedefs.list
@@ -3688,7 +3688,6 @@ gss_key_value_set_desc
 gss_name_t
 gtrgm_consistent_cache
 gzFile
-hbaPort
 heap_page_items_state
 help_handler
 hlCheck
-- 
2.51.0

0007-Change-fmgr.h-typedefs-to-use-original-names.patchtext/plain; charset=UTF-8; name=0007-Change-fmgr.h-typedefs-to-use-original-names.patchDownload
From 92c1e5672f97eb545f7c561f07f502ad19ab5e06 Mon Sep 17 00:00:00 2001
From: Peter Eisentraut <peter@eisentraut.org>
Date: Fri, 29 Aug 2025 13:18:51 +0200
Subject: [PATCH 7/7] Change fmgr.h typedefs to use original names

fmgr.h defined some types such as fmNodePtr which is just Node *, but
it made its own types to avoid having to include various header files.
With C11, we can now instead typedef the original names without fear
of conflicts.
---
 src/backend/utils/fmgr/fmgr.c    |  5 ++---
 src/include/fmgr.h               | 30 +++++++++++++++---------------
 src/include/utils/builtins.h     |  2 +-
 src/tools/pgindent/typedefs.list |  4 ----
 4 files changed, 18 insertions(+), 23 deletions(-)

diff --git a/src/backend/utils/fmgr/fmgr.c b/src/backend/utils/fmgr/fmgr.c
index 5543440a33e..b4c1e2c4b21 100644
--- a/src/backend/utils/fmgr/fmgr.c
+++ b/src/backend/utils/fmgr/fmgr.c
@@ -1570,7 +1570,6 @@ InputFunctionCall(FmgrInfo *flinfo, char *str, Oid typioparam, int32 typmod)
  * This is basically like InputFunctionCall, but the converted Datum is
  * returned into *result while the function result is true for success or
  * false for failure.  Also, the caller may pass an ErrorSaveContext node.
- * (We declare that as "fmNodePtr" to avoid including nodes.h in fmgr.h.)
  *
  * If escontext points to an ErrorSaveContext, any "soft" errors detected by
  * the input function will be reported by filling the escontext struct and
@@ -1584,7 +1583,7 @@ InputFunctionCall(FmgrInfo *flinfo, char *str, Oid typioparam, int32 typmod)
 bool
 InputFunctionCallSafe(FmgrInfo *flinfo, char *str,
 					  Oid typioparam, int32 typmod,
-					  fmNodePtr escontext,
+					  Node *escontext,
 					  Datum *result)
 {
 	LOCAL_FCINFO(fcinfo, 3);
@@ -1639,7 +1638,7 @@ InputFunctionCallSafe(FmgrInfo *flinfo, char *str,
 bool
 DirectInputFunctionCallSafe(PGFunction func, char *str,
 							Oid typioparam, int32 typmod,
-							fmNodePtr escontext,
+							Node *escontext,
 							Datum *result)
 {
 	LOCAL_FCINFO(fcinfo, 3);
diff --git a/src/include/fmgr.h b/src/include/fmgr.h
index c7236e42972..74fe3ea0575 100644
--- a/src/include/fmgr.h
+++ b/src/include/fmgr.h
@@ -19,14 +19,14 @@
 #define FMGR_H
 
 /* We don't want to include primnodes.h here, so make some stub references */
-typedef struct Node *fmNodePtr;
-typedef struct Aggref *fmAggrefPtr;
+typedef struct Node Node;
+typedef struct Aggref Aggref;
 
 /* Likewise, avoid including execnodes.h here */
-typedef void (*fmExprContextCallbackFunction) (Datum arg);
+typedef void (*ExprContextCallbackFunction) (Datum arg);
 
 /* Likewise, avoid including stringinfo.h here */
-typedef struct StringInfoData *fmStringInfo;
+typedef struct StringInfoData *StringInfo;
 
 
 /*
@@ -63,7 +63,7 @@ typedef struct FmgrInfo
 	unsigned char fn_stats;		/* collect stats if track_functions > this */
 	void	   *fn_extra;		/* extra space for use by handler */
 	MemoryContext fn_mcxt;		/* memory context to store fn_extra in */
-	fmNodePtr	fn_expr;		/* expression parse tree for call, or NULL */
+	Node	   *fn_expr;		/* expression parse tree for call, or NULL */
 } FmgrInfo;
 
 /*
@@ -85,8 +85,8 @@ typedef struct FmgrInfo
 typedef struct FunctionCallInfoBaseData
 {
 	FmgrInfo   *flinfo;			/* ptr to lookup info used for this call */
-	fmNodePtr	context;		/* pass info about context of call */
-	fmNodePtr	resultinfo;		/* pass or return extra info about result */
+	Node	   *context;		/* pass info about context of call */
+	Node	   *resultinfo;		/* pass or return extra info about result */
 	Oid			fncollation;	/* collation for function to use */
 #define FIELDNO_FUNCTIONCALLINFODATA_ISNULL 4
 	bool		isnull;			/* function must set true if result is NULL */
@@ -742,19 +742,19 @@ extern Datum InputFunctionCall(FmgrInfo *flinfo, char *str,
 							   Oid typioparam, int32 typmod);
 extern bool InputFunctionCallSafe(FmgrInfo *flinfo, char *str,
 								  Oid typioparam, int32 typmod,
-								  fmNodePtr escontext,
+								  Node *escontext,
 								  Datum *result);
 extern bool DirectInputFunctionCallSafe(PGFunction func, char *str,
 										Oid typioparam, int32 typmod,
-										fmNodePtr escontext,
+										Node *escontext,
 										Datum *result);
 extern Datum OidInputFunctionCall(Oid functionId, char *str,
 								  Oid typioparam, int32 typmod);
 extern char *OutputFunctionCall(FmgrInfo *flinfo, Datum val);
 extern char *OidOutputFunctionCall(Oid functionId, Datum val);
-extern Datum ReceiveFunctionCall(FmgrInfo *flinfo, fmStringInfo buf,
+extern Datum ReceiveFunctionCall(FmgrInfo *flinfo, StringInfo buf,
 								 Oid typioparam, int32 typmod);
-extern Datum OidReceiveFunctionCall(Oid functionId, fmStringInfo buf,
+extern Datum OidReceiveFunctionCall(Oid functionId, StringInfo buf,
 									Oid typioparam, int32 typmod);
 extern bytea *SendFunctionCall(FmgrInfo *flinfo, Datum val);
 extern bytea *OidSendFunctionCall(Oid functionId, Datum val);
@@ -767,9 +767,9 @@ extern const Pg_finfo_record *fetch_finfo_record(void *filehandle, const char *f
 extern Oid	fmgr_internal_function(const char *proname);
 extern Oid	get_fn_expr_rettype(FmgrInfo *flinfo);
 extern Oid	get_fn_expr_argtype(FmgrInfo *flinfo, int argnum);
-extern Oid	get_call_expr_argtype(fmNodePtr expr, int argnum);
+extern Oid	get_call_expr_argtype(Node *expr, int argnum);
 extern bool get_fn_expr_arg_stable(FmgrInfo *flinfo, int argnum);
-extern bool get_call_expr_arg_stable(fmNodePtr expr, int argnum);
+extern bool get_call_expr_arg_stable(Node *expr, int argnum);
 extern bool get_fn_expr_variadic(FmgrInfo *flinfo);
 extern bytea *get_fn_opclass_options(FmgrInfo *flinfo);
 extern bool has_fn_opclass_options(FmgrInfo *flinfo);
@@ -814,11 +814,11 @@ extern void RestoreLibraryState(char *start_address);
 
 extern int	AggCheckCallContext(FunctionCallInfo fcinfo,
 								MemoryContext *aggcontext);
-extern fmAggrefPtr AggGetAggref(FunctionCallInfo fcinfo);
+extern Aggref *AggGetAggref(FunctionCallInfo fcinfo);
 extern MemoryContext AggGetTempMemoryContext(FunctionCallInfo fcinfo);
 extern bool AggStateIsShared(FunctionCallInfo fcinfo);
 extern void AggRegisterCallback(FunctionCallInfo fcinfo,
-								fmExprContextCallbackFunction func,
+								ExprContextCallbackFunction func,
 								Datum arg);
 
 /*
diff --git a/src/include/utils/builtins.h b/src/include/utils/builtins.h
index 1c98c7d2255..ce6285a2c03 100644
--- a/src/include/utils/builtins.h
+++ b/src/include/utils/builtins.h
@@ -80,7 +80,7 @@ extern PGDLLIMPORT bool quote_all_identifiers;
 extern const char *quote_identifier(const char *ident);
 extern char *quote_qualified_identifier(const char *qualifier,
 										const char *ident);
-extern void generate_operator_clause(fmStringInfo buf,
+extern void generate_operator_clause(StringInfo buf,
 									 const char *leftop, Oid leftoptype,
 									 Oid opoid,
 									 const char *rightop, Oid rightoptype);
diff --git a/src/tools/pgindent/typedefs.list b/src/tools/pgindent/typedefs.list
index 0f4974b5fcb..5736a41c91a 100644
--- a/src/tools/pgindent/typedefs.list
+++ b/src/tools/pgindent/typedefs.list
@@ -3636,10 +3636,6 @@ float8
 float8KEY
 floating_decimal_32
 floating_decimal_64
-fmAggrefPtr
-fmExprContextCallbackFunction
-fmNodePtr
-fmStringInfo
 fmgr_hook_type
 foreign_glob_cxt
 foreign_loc_cxt
-- 
2.51.0

#2Tom Lane
tgl@sss.pgh.pa.us
In reply to: Peter Eisentraut (#1)
Re: allow benign typedef redefinitions (C11)

Peter Eisentraut <peter@eisentraut.org> writes:

Here is the first of several (to come at a later date) patch sets to
take some advantage of C11 features.

I haven't checked this line-by-line, but +1 for concept (assuming the
build farm is actually happy with it). 0006 and 0007, in particular,
clean up some very messy hacks.

regards, tom lane

#3Chao Li
li.evan.chao@gmail.com
In reply to: Peter Eisentraut (#1)
Re: allow benign typedef redefinitions (C11)

On Aug 29, 2025, at 20:45, Peter Eisentraut <peter@eisentraut.org> wrote:

(After this, it would probably be possible to undertake some deeper efforts to untangle header files, with the help of IWYU. But that is a separate project.)
<0001-Improve-pgbench-definition-of-yyscan_t.patch><0002-Allow-redeclaration-of-typedef-yyscan_t.patch><0003-Remove-workarounds-against-repeat-typedefs.patch><0004-Improve-ExplainState-type-handling-in-header-files.patch><0005-Update-various-forward-declarations-to-use-typedef.patch><0006-Remove-hbaPort-type.patch><0007-Change-fmgr.h-typedefs-to-use-original-names.patch>

I applied the patch files and build passed without any error and warning on my MacBook.

Just a few small comments:

1. For 0001, I think “#ifdef YY_TYPEDEF_YY_SCANNER_T” is not needed, but I see you have removed that in 0002, so this is not a comment now.

2. For 0002, looks like som duplicate code for definitions of

Union YYSTYPE;
#define YYLTYPE int
Typedef void *yyscan_t;

Can we put them into a separate header file say src/include/yy_types.h?

3. For 0002, this is not your change, I am just pointing it out: “#define YYSTYPE char *”, where “YYSTYPE” is defined as “union” everywhere else. Can we rename it to something like “YYSTYPE_CHARPTR” here to avoid confusion? I tried to rename it and build still passed.

4. For 0004

diff --git a/src/include/commands/explain_dr.h b/src/include/commands/explain_dr.h
index 55da63d66bd..ce424aa2a55 100644
--- a/src/include/commands/explain_dr.h
+++ b/src/include/commands/explain_dr.h
@@ -16,7 +16,7 @@
 #include "executor/instrument.h"
 #include "tcop/dest.h"
-struct ExplainState;                   /* avoid including explain.h here */
+typedef struct ExplainState ExplainState;      /* avoid including explain.h here */

“Struct ExplainState” is defined in explain_state.h, so the comment here should be “avoid including explain_state.h here”.

Same thing applies to explain_format.h and fdwapi.h.

5. For 0005

diff --git a/src/include/optimizer/optimizer.h b/src/include/optimizer/optimizer.h
index 03b214755c2..d490ef3b506 100644
--- a/src/include/optimizer/optimizer.h
+++ b/src/include/optimizer/optimizer.h
@@ -35,9 +35,9 @@ typedef struct IndexOptInfo IndexOptInfo;
 typedef struct SpecialJoinInfo SpecialJoinInfo;
 /* It also seems best not to include plannodes.h, params.h, or htup.h here */
-struct PlannedStmt;
-struct ParamListInfoData;
-struct HeapTupleData;
+typedef struct PlannedStmt PlannedStmt;
+typedef struct ParamListInfoData ParamListInfoData;
+typedef struct HeapTupleData *HeapTuple;

Why don’t define ParamListInfo in the same way as HeapTuple like “typedef structure ParamListInfoData *ParamListInfo”. I tried that in my local and build still passed.

Best regards,
--
Chao Li (Evan)
HighGo Software Co., Ltd.
https://www.highgo.com/

#4Peter Eisentraut
peter@eisentraut.org
In reply to: Chao Li (#3)
7 attachment(s)
Re: allow benign typedef redefinitions (C11)

On 01.09.25 05:32, Chao Li wrote:

1. For 0001, I think “#ifdef YY_TYPEDEF_YY_SCANNER_T” is not needed, but
I see you have removed that in 0002, so this is not a comment now.

Yes, this is just so that the code after applying patch 0001 still
works, even if some code is later removed.

2. For 0002, looks like som duplicate code for definitions of

Union YYSTYPE;
#define YYLTYPE int
Typedef void *yyscan_t;

Can we put them into a separate header file say src/include/yy_types.h?

Each scanner/parser might have its own idea of what type it wants to
use, so this might not work. It's better not to get into the
complications of this for this patch set.

3. For 0002, this is not your change, I am just pointing it out:
“#define YYSTYPE char *”, where “YYSTYPE” is defined as “union”
everywhere else. Can we rename it to something like “YYSTYPE_CHARPTR”
here to avoid confusion? I tried to rename it and build still passed.

The name YYSTYPE is required by bison. I'm not sure how it still works
without it. But anyway, see above, it's probably better not to crack
open the bison/flex mess again here.

4. For 0004

diff --git a/src/include/commands/explain_dr.h b/src/include/commands/ 
explain_dr.h
index 55da63d66bd..ce424aa2a55 100644
--- a/src/include/commands/explain_dr.h
+++ b/src/include/commands/explain_dr.h
@@ -16,7 +16,7 @@
 #include "executor/instrument.h"
 #include "tcop/dest.h"
-struct ExplainState;                   /* avoid including explain.h here */
+typedef struct ExplainState ExplainState;      /* avoid including 
explain.h here */

“Struct ExplainState” is defined in explain_state.h, so the comment here
should be “avoid including explain_state.h here”.

Same thing applies to explain_format.h and fdwapi.h.

Yes, good catch. The original patch that introduced these comments
actually did replace an include of explain.h, but arguably even that was
already too broad. So I agree we should fix these comments.

5. For 0005

diff --git a/src/include/optimizer/optimizer.h b/src/include/optimizer/ 
optimizer.h
index 03b214755c2..d490ef3b506 100644
--- a/src/include/optimizer/optimizer.h
+++ b/src/include/optimizer/optimizer.h
@@ -35,9 +35,9 @@ typedef struct IndexOptInfo IndexOptInfo;
 typedef struct SpecialJoinInfo SpecialJoinInfo;
 /* It also seems best not to include plannodes.h, params.h, or htup.h 
here */
-struct PlannedStmt;
-struct ParamListInfoData;
-struct HeapTupleData;
+typedef struct PlannedStmt PlannedStmt;
+typedef struct ParamListInfoData ParamListInfoData;
+typedef struct HeapTupleData *HeapTuple;

Why don’t define ParamListInfo in the same way as HeapTuple like
“typedef structure ParamListInfoData *ParamListInfo”. I tried that in my
local and build still passed.

Yes, that seems more correct.

Thanks. New patch set attached.

Attachments:

v2-0001-Improve-pgbench-definition-of-yyscan_t.patchtext/plain; charset=UTF-8; name=v2-0001-Improve-pgbench-definition-of-yyscan_t.patchDownload
From c05c89f6975888dd0ccaaf4199f95ee955f63ee9 Mon Sep 17 00:00:00 2001
From: Peter Eisentraut <peter@eisentraut.org>
Date: Fri, 29 Aug 2025 13:18:50 +0200
Subject: [PATCH v2 1/7] Improve pgbench definition of yyscan_t

It was defining yyscan_t as a macro while the rest of the code uses a
typedef with #ifdef guards around it.  The latter is also what the
flex generated code uses.  So it seems best to make it look like those
other places for consistency.

The old way also had a potential for conflict if some code included
multiple headers providing yyscan_t.  exprscan.l includes

    #include "fe_utils/psqlscan_int.h"
    #include "pgbench.h"

and fe_utils/psqlscan_int.h contains

    #ifndef YY_TYPEDEF_YY_SCANNER_T
    #define YY_TYPEDEF_YY_SCANNER_T
    typedef void *yyscan_t;
    #endif

which was then followed by pgbench.h

    #define yyscan_t  void *

and then the generated code in exprscan.c

    #ifndef YY_TYPEDEF_YY_SCANNER_T
    #define YY_TYPEDEF_YY_SCANNER_T
    typedef void* yyscan_t;
    #endif

This works, but if the #ifdef guard in psqlscan_int.h is removed, this
fails.

We want to move toward allowing repeat typedefs, per C11, but for that
we need to make sure they are all the same.

Discussion: https://www.postgresql.org/message-id/flat/10d32190-f31b-40a5-b177-11db55597355@eisentraut.org
---
 src/bin/pgbench/pgbench.h | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/src/bin/pgbench/pgbench.h b/src/bin/pgbench/pgbench.h
index e053c9e2eb6..f8b7b497d1e 100644
--- a/src/bin/pgbench/pgbench.h
+++ b/src/bin/pgbench/pgbench.h
@@ -16,11 +16,14 @@
 /*
  * This file is included outside exprscan.l, in places where we can't see
  * flex's definition of typedef yyscan_t.  Fortunately, it's documented as
- * being "void *", so we can use a macro to keep the function declarations
+ * being "void *", so we can use typedef to keep the function declarations
  * here looking like the definitions in exprscan.l.  exprparse.y and
  * pgbench.c also use this to be able to declare things as "yyscan_t".
  */
-#define yyscan_t  void *
+#ifndef YY_TYPEDEF_YY_SCANNER_T
+#define YY_TYPEDEF_YY_SCANNER_T
+typedef void *yyscan_t;
+#endif
 
 /*
  * Likewise, we can't see exprparse.y's definition of union YYSTYPE here,

base-commit: e6da68a6e1d60a037b63a9c9ed36e5ef0a996769
-- 
2.51.0

v2-0002-Allow-redeclaration-of-typedef-yyscan_t.patchtext/plain; charset=UTF-8; name=v2-0002-Allow-redeclaration-of-typedef-yyscan_t.patchDownload
From f0a05f8db2430d9c598834e82c4d22098d64459d Mon Sep 17 00:00:00 2001
From: Peter Eisentraut <peter@eisentraut.org>
Date: Fri, 29 Aug 2025 13:18:51 +0200
Subject: [PATCH v2 2/7] Allow redeclaration of typedef yyscan_t

This is allowed in C11, so we don't need the workaround guards against
it anymore.  This effectively reverts commit 382092a0cd2 that put
these guards in place.

Discussion: https://www.postgresql.org/message-id/flat/10d32190-f31b-40a5-b177-11db55597355@eisentraut.org
---
 contrib/cube/cubedata.h                     | 3 ---
 contrib/seg/segdata.h                       | 3 ---
 src/backend/utils/adt/jsonpath_internal.h   | 3 ---
 src/bin/pgbench/pgbench.h                   | 3 ---
 src/include/bootstrap/bootstrap.h           | 3 ---
 src/include/fe_utils/psqlscan_int.h         | 6 ------
 src/include/replication/syncrep.h           | 3 ---
 src/include/replication/walsender_private.h | 3 ---
 src/pl/plpgsql/src/plpgsql.h                | 3 ---
 9 files changed, 30 deletions(-)

diff --git a/contrib/cube/cubedata.h b/contrib/cube/cubedata.h
index ad1e2bd6998..8bfcc6e99a2 100644
--- a/contrib/cube/cubedata.h
+++ b/contrib/cube/cubedata.h
@@ -62,10 +62,7 @@ typedef struct NDBOX
 /* for cubescan.l and cubeparse.y */
 /* All grammar constructs return strings */
 #define YYSTYPE char *
-#ifndef YY_TYPEDEF_YY_SCANNER_T
-#define YY_TYPEDEF_YY_SCANNER_T
 typedef void *yyscan_t;
-#endif
 
 /* in cubescan.l */
 extern int	cube_yylex(YYSTYPE *yylval_param, yyscan_t yyscanner);
diff --git a/contrib/seg/segdata.h b/contrib/seg/segdata.h
index 4347c31c28e..7bc7c83dca3 100644
--- a/contrib/seg/segdata.h
+++ b/contrib/seg/segdata.h
@@ -16,10 +16,7 @@ extern int	significant_digits(const char *s);
 
 /* for segscan.l and segparse.y */
 union YYSTYPE;
-#ifndef YY_TYPEDEF_YY_SCANNER_T
-#define YY_TYPEDEF_YY_SCANNER_T
 typedef void *yyscan_t;
-#endif
 
 /* in segscan.l */
 extern int	seg_yylex(union YYSTYPE *yylval_param, yyscan_t yyscanner);
diff --git a/src/backend/utils/adt/jsonpath_internal.h b/src/backend/utils/adt/jsonpath_internal.h
index f78069857d0..19567aca6f7 100644
--- a/src/backend/utils/adt/jsonpath_internal.h
+++ b/src/backend/utils/adt/jsonpath_internal.h
@@ -22,10 +22,7 @@ typedef struct JsonPathString
 	int			total;
 } JsonPathString;
 
-#ifndef YY_TYPEDEF_YY_SCANNER_T
-#define YY_TYPEDEF_YY_SCANNER_T
 typedef void *yyscan_t;
-#endif
 
 #include "utils/jsonpath.h"
 #include "jsonpath_gram.h"
diff --git a/src/bin/pgbench/pgbench.h b/src/bin/pgbench/pgbench.h
index f8b7b497d1e..d55d30e0ef9 100644
--- a/src/bin/pgbench/pgbench.h
+++ b/src/bin/pgbench/pgbench.h
@@ -20,10 +20,7 @@
  * here looking like the definitions in exprscan.l.  exprparse.y and
  * pgbench.c also use this to be able to declare things as "yyscan_t".
  */
-#ifndef YY_TYPEDEF_YY_SCANNER_T
-#define YY_TYPEDEF_YY_SCANNER_T
 typedef void *yyscan_t;
-#endif
 
 /*
  * Likewise, we can't see exprparse.y's definition of union YYSTYPE here,
diff --git a/src/include/bootstrap/bootstrap.h b/src/include/bootstrap/bootstrap.h
index befc4fa1b3d..5ad347ec290 100644
--- a/src/include/bootstrap/bootstrap.h
+++ b/src/include/bootstrap/bootstrap.h
@@ -56,10 +56,7 @@ extern void boot_get_type_io_data(Oid typid,
 								  Oid *typoutput);
 
 union YYSTYPE;
-#ifndef YY_TYPEDEF_YY_SCANNER_T
-#define YY_TYPEDEF_YY_SCANNER_T
 typedef void *yyscan_t;
-#endif
 
 extern int	boot_yyparse(yyscan_t yyscanner);
 extern int	boot_yylex_init(yyscan_t *yyscannerp);
diff --git a/src/include/fe_utils/psqlscan_int.h b/src/include/fe_utils/psqlscan_int.h
index 2a3a9d7c82a..a1ebf226cf4 100644
--- a/src/include/fe_utils/psqlscan_int.h
+++ b/src/include/fe_utils/psqlscan_int.h
@@ -51,14 +51,8 @@
  * validity checking; in actual use, this file should always be included
  * from the body of a flex file, where these symbols are already defined.
  */
-#ifndef YY_TYPEDEF_YY_BUFFER_STATE
-#define YY_TYPEDEF_YY_BUFFER_STATE
 typedef struct yy_buffer_state *YY_BUFFER_STATE;
-#endif
-#ifndef YY_TYPEDEF_YY_SCANNER_T
-#define YY_TYPEDEF_YY_SCANNER_T
 typedef void *yyscan_t;
-#endif
 
 /*
  * We use a stack of flex buffers to handle substitution of psql variables.
diff --git a/src/include/replication/syncrep.h b/src/include/replication/syncrep.h
index 675669a79f7..dc2b118b166 100644
--- a/src/include/replication/syncrep.h
+++ b/src/include/replication/syncrep.h
@@ -97,10 +97,7 @@ extern void SyncRepUpdateSyncStandbysDefined(void);
  * in syncrep_gram.y and syncrep_scanner.l
  */
 union YYSTYPE;
-#ifndef YY_TYPEDEF_YY_SCANNER_T
-#define YY_TYPEDEF_YY_SCANNER_T
 typedef void *yyscan_t;
-#endif
 extern int	syncrep_yyparse(SyncRepConfigData **syncrep_parse_result_p, char **syncrep_parse_error_msg_p, yyscan_t yyscanner);
 extern int	syncrep_yylex(union YYSTYPE *yylval_param, char **syncrep_parse_error_msg_p, yyscan_t yyscanner);
 extern void syncrep_yyerror(SyncRepConfigData **syncrep_parse_result_p, char **syncrep_parse_error_msg_p, yyscan_t yyscanner, const char *str);
diff --git a/src/include/replication/walsender_private.h b/src/include/replication/walsender_private.h
index e98701038f5..384b8a78b94 100644
--- a/src/include/replication/walsender_private.h
+++ b/src/include/replication/walsender_private.h
@@ -141,10 +141,7 @@ extern void WalSndSetState(WalSndState state);
  * repl_scanner.l
  */
 union YYSTYPE;
-#ifndef YY_TYPEDEF_YY_SCANNER_T
-#define YY_TYPEDEF_YY_SCANNER_T
 typedef void *yyscan_t;
-#endif
 extern int	replication_yyparse(Node **replication_parse_result_p, yyscan_t yyscanner);
 extern int	replication_yylex(union YYSTYPE *yylval_param, yyscan_t yyscanner);
 pg_noreturn extern void replication_yyerror(Node **replication_parse_result_p, yyscan_t yyscanner, const char *message);
diff --git a/src/pl/plpgsql/src/plpgsql.h b/src/pl/plpgsql/src/plpgsql.h
index 41e52b8ce71..5f193a37183 100644
--- a/src/pl/plpgsql/src/plpgsql.h
+++ b/src/pl/plpgsql/src/plpgsql.h
@@ -1307,10 +1307,7 @@ extern void plpgsql_dumptree(PLpgSQL_function *func);
  */
 union YYSTYPE;
 #define YYLTYPE int
-#ifndef YY_TYPEDEF_YY_SCANNER_T
-#define YY_TYPEDEF_YY_SCANNER_T
 typedef void *yyscan_t;
-#endif
 extern int	plpgsql_yylex(union YYSTYPE *yylvalp, YYLTYPE *yyllocp, yyscan_t yyscanner);
 extern int	plpgsql_token_length(yyscan_t yyscanner);
 extern void plpgsql_push_back_token(int token, union YYSTYPE *yylvalp, YYLTYPE *yyllocp, yyscan_t yyscanner);
-- 
2.51.0

v2-0003-Remove-workarounds-against-repeat-typedefs.patchtext/plain; charset=UTF-8; name=v2-0003-Remove-workarounds-against-repeat-typedefs.patchDownload
From 67e929fea004d31e0dacd77b09244278c107089c Mon Sep 17 00:00:00 2001
From: Peter Eisentraut <peter@eisentraut.org>
Date: Fri, 29 Aug 2025 13:18:51 +0200
Subject: [PATCH v2 3/7] Remove workarounds against repeat typedefs

This is allowed in C11, so we don't need the workarounds anymore.

Discussion: https://www.postgresql.org/message-id/flat/10d32190-f31b-40a5-b177-11db55597355@eisentraut.org
---
 src/include/nodes/pathnodes.h     | 23 ++++-------------------
 src/include/optimizer/optimizer.h | 13 +------------
 2 files changed, 5 insertions(+), 31 deletions(-)

diff --git a/src/include/nodes/pathnodes.h b/src/include/nodes/pathnodes.h
index 4a903d1ec18..b12a2508d8c 100644
--- a/src/include/nodes/pathnodes.h
+++ b/src/include/nodes/pathnodes.h
@@ -198,9 +198,6 @@ typedef struct PlannerGlobal
  * original Query.  Note that at present the planner extensively modifies
  * the passed-in Query data structure; someday that should stop.
  *
- * For reasons explained in optimizer/optimizer.h, we define the typedef
- * either here or in that header, whichever is read first.
- *
  * Not all fields are printed.  (In some cases, there is no print support for
  * the field type; in others, doing so would lead to infinite recursion or
  * bloat dump output more than seems useful.)
@@ -211,10 +208,7 @@ typedef struct PlannerGlobal
  * correctly replaced with the keeping one.
  *----------
  */
-#ifndef HAVE_PLANNERINFO_TYPEDEF
 typedef struct PlannerInfo PlannerInfo;
-#define HAVE_PLANNERINFO_TYPEDEF 1
-#endif
 
 struct PlannerInfo
 {
@@ -1161,14 +1155,10 @@ typedef struct RelOptInfo
  *		(by plancat.c), indrestrictinfo and predOK are set later, in
  *		check_index_predicates().
  */
-#ifndef HAVE_INDEXOPTINFO_TYPEDEF
-typedef struct IndexOptInfo IndexOptInfo;
-#define HAVE_INDEXOPTINFO_TYPEDEF 1
-#endif
 
 struct IndexPath;				/* forward declaration */
 
-struct IndexOptInfo
+typedef struct IndexOptInfo
 {
 	pg_node_attr(no_copy_equal, no_read, no_query_jumble)
 
@@ -1270,7 +1260,7 @@ struct IndexOptInfo
 	/* AM's cost estimator */
 	/* Rather than include amapi.h here, we declare amcostestimate like this */
 	void		(*amcostestimate) (struct PlannerInfo *, struct IndexPath *, double, Cost *, Cost *, Selectivity *, double *, double *) pg_node_attr(read_write_ignore);
-};
+} IndexOptInfo;
 
 /*
  * ForeignKeyOptInfo
@@ -3031,12 +3021,7 @@ typedef struct PlaceHolderVar
  * We also create transient SpecialJoinInfos for child joins during
  * partitionwise join planning, which are also not present in join_info_list.
  */
-#ifndef HAVE_SPECIALJOININFO_TYPEDEF
-typedef struct SpecialJoinInfo SpecialJoinInfo;
-#define HAVE_SPECIALJOININFO_TYPEDEF 1
-#endif
-
-struct SpecialJoinInfo
+typedef struct SpecialJoinInfo
 {
 	pg_node_attr(no_read, no_query_jumble)
 
@@ -3057,7 +3042,7 @@ struct SpecialJoinInfo
 	bool		semi_can_hash;	/* true if semi_operators are all hash */
 	List	   *semi_operators; /* OIDs of equality join operators */
 	List	   *semi_rhs_exprs; /* righthand-side expressions of these ops */
-};
+} SpecialJoinInfo;
 
 /*
  * Transient outer-join clause info.
diff --git a/src/include/optimizer/optimizer.h b/src/include/optimizer/optimizer.h
index 37bc13c2cbd..03b214755c2 100644
--- a/src/include/optimizer/optimizer.h
+++ b/src/include/optimizer/optimizer.h
@@ -28,22 +28,11 @@
  * We don't want to include nodes/pathnodes.h here, because non-planner
  * code should generally treat PlannerInfo as an opaque typedef.
  * But we'd like such code to use that typedef name, so define the
- * typedef either here or in pathnodes.h, whichever is read first.
+ * typedef both here or in pathnodes.h.
  */
-#ifndef HAVE_PLANNERINFO_TYPEDEF
 typedef struct PlannerInfo PlannerInfo;
-#define HAVE_PLANNERINFO_TYPEDEF 1
-#endif
-
-/* Likewise for IndexOptInfo and SpecialJoinInfo. */
-#ifndef HAVE_INDEXOPTINFO_TYPEDEF
 typedef struct IndexOptInfo IndexOptInfo;
-#define HAVE_INDEXOPTINFO_TYPEDEF 1
-#endif
-#ifndef HAVE_SPECIALJOININFO_TYPEDEF
 typedef struct SpecialJoinInfo SpecialJoinInfo;
-#define HAVE_SPECIALJOININFO_TYPEDEF 1
-#endif
 
 /* It also seems best not to include plannodes.h, params.h, or htup.h here */
 struct PlannedStmt;
-- 
2.51.0

v2-0004-Improve-ExplainState-type-handling-in-header-file.patchtext/plain; charset=UTF-8; name=v2-0004-Improve-ExplainState-type-handling-in-header-file.patchDownload
From 91bc877ffb8064d4426622938088c67e9dc1950e Mon Sep 17 00:00:00 2001
From: Peter Eisentraut <peter@eisentraut.org>
Date: Wed, 10 Sep 2025 08:06:43 +0200
Subject: [PATCH v2 4/7] Improve ExplainState type handling in header files

Now that we can have repeat typedefs with C11, we don't need to use
"struct ExplainState" anymore but can instead make a typedef where
necessary.  This doesn't change anything but makes it look nicer.

(There are more opportunities for similar changes, but this is broken
out because there was a separate discussion about it, and it's
somewhat bulky on its own.)

Discussion: https://www.postgresql.org/message-id/flat/f36c0a45-98cd-40b2-a7cc-f2bf02b12890%40eisentraut.org#a12fb1a2c1089d6d03010f6268871b00
Discussion: https://www.postgresql.org/message-id/flat/10d32190-f31b-40a5-b177-11db55597355@eisentraut.org
---
 doc/src/sgml/fdwhandler.sgml          |  2 +-
 src/include/commands/explain.h        | 24 ++++++++---------
 src/include/commands/explain_dr.h     |  5 ++--
 src/include/commands/explain_format.h | 37 ++++++++++++++-------------
 src/include/commands/explain_state.h  |  2 +-
 src/include/foreign/fdwapi.h          | 10 ++++----
 6 files changed, 41 insertions(+), 39 deletions(-)

diff --git a/doc/src/sgml/fdwhandler.sgml b/doc/src/sgml/fdwhandler.sgml
index b80320504d6..c6d66414b8e 100644
--- a/doc/src/sgml/fdwhandler.sgml
+++ b/doc/src/sgml/fdwhandler.sgml
@@ -1320,7 +1320,7 @@ <title>FDW Routines for <command>EXPLAIN</command></title>
                      ResultRelInfo *rinfo,
                      List *fdw_private,
                      int subplan_index,
-                     struct ExplainState *es);
+                     ExplainState *es);
 </programlisting>
 
      Print additional <command>EXPLAIN</command> output for a foreign table update.
diff --git a/src/include/commands/explain.h b/src/include/commands/explain.h
index 3b122f79ed8..6e51d50efc7 100644
--- a/src/include/commands/explain.h
+++ b/src/include/commands/explain.h
@@ -16,13 +16,13 @@
 #include "executor/executor.h"
 #include "parser/parse_node.h"
 
-struct ExplainState;			/* defined in explain_state.h */
+typedef struct ExplainState ExplainState;	/* defined in explain_state.h */
 
 /* Hook for plugins to get control in ExplainOneQuery() */
 typedef void (*ExplainOneQuery_hook_type) (Query *query,
 										   int cursorOptions,
 										   IntoClause *into,
-										   struct ExplainState *es,
+										   ExplainState *es,
 										   const char *queryString,
 										   ParamListInfo params,
 										   QueryEnvironment *queryEnv);
@@ -31,7 +31,7 @@ extern PGDLLIMPORT ExplainOneQuery_hook_type ExplainOneQuery_hook;
 /* Hook for EXPLAIN plugins to print extra information for each plan */
 typedef void (*explain_per_plan_hook_type) (PlannedStmt *plannedstmt,
 											IntoClause *into,
-											struct ExplainState *es,
+											ExplainState *es,
 											const char *queryString,
 											ParamListInfo params,
 											QueryEnvironment *queryEnv);
@@ -42,7 +42,7 @@ typedef void (*explain_per_node_hook_type) (PlanState *planstate,
 											List *ancestors,
 											const char *relationship,
 											const char *plan_name,
-											struct ExplainState *es);
+											ExplainState *es);
 extern PGDLLIMPORT explain_per_node_hook_type explain_per_node_hook;
 
 /* Hook for plugins to get control in explain_get_index_name() */
@@ -53,32 +53,32 @@ extern PGDLLIMPORT explain_get_index_name_hook_type explain_get_index_name_hook;
 extern void ExplainQuery(ParseState *pstate, ExplainStmt *stmt,
 						 ParamListInfo params, DestReceiver *dest);
 extern void standard_ExplainOneQuery(Query *query, int cursorOptions,
-									 IntoClause *into, struct ExplainState *es,
+									 IntoClause *into, ExplainState *es,
 									 const char *queryString, ParamListInfo params,
 									 QueryEnvironment *queryEnv);
 
 extern TupleDesc ExplainResultDesc(ExplainStmt *stmt);
 
 extern void ExplainOneUtility(Node *utilityStmt, IntoClause *into,
-							  struct ExplainState *es, ParseState *pstate,
+							  ExplainState *es, ParseState *pstate,
 							  ParamListInfo params);
 
 extern void ExplainOnePlan(PlannedStmt *plannedstmt, IntoClause *into,
-						   struct ExplainState *es, const char *queryString,
+						   ExplainState *es, const char *queryString,
 						   ParamListInfo params, QueryEnvironment *queryEnv,
 						   const instr_time *planduration,
 						   const BufferUsage *bufusage,
 						   const MemoryContextCounters *mem_counters);
 
-extern void ExplainPrintPlan(struct ExplainState *es, QueryDesc *queryDesc);
-extern void ExplainPrintTriggers(struct ExplainState *es,
+extern void ExplainPrintPlan(ExplainState *es, QueryDesc *queryDesc);
+extern void ExplainPrintTriggers(ExplainState *es,
 								 QueryDesc *queryDesc);
 
-extern void ExplainPrintJITSummary(struct ExplainState *es,
+extern void ExplainPrintJITSummary(ExplainState *es,
 								   QueryDesc *queryDesc);
 
-extern void ExplainQueryText(struct ExplainState *es, QueryDesc *queryDesc);
-extern void ExplainQueryParameters(struct ExplainState *es,
+extern void ExplainQueryText(ExplainState *es, QueryDesc *queryDesc);
+extern void ExplainQueryParameters(ExplainState *es,
 								   ParamListInfo params, int maxlen);
 
 #endif							/* EXPLAIN_H */
diff --git a/src/include/commands/explain_dr.h b/src/include/commands/explain_dr.h
index 55da63d66bd..b62f1f8542c 100644
--- a/src/include/commands/explain_dr.h
+++ b/src/include/commands/explain_dr.h
@@ -16,7 +16,8 @@
 #include "executor/instrument.h"
 #include "tcop/dest.h"
 
-struct ExplainState;			/* avoid including explain.h here */
+/* avoid including explain_state.h here */
+typedef struct ExplainState ExplainState;
 
 /* Instrumentation data for EXPLAIN's SERIALIZE option */
 typedef struct SerializeMetrics
@@ -26,7 +27,7 @@ typedef struct SerializeMetrics
 	BufferUsage bufferUsage;	/* buffers accessed during serialization */
 } SerializeMetrics;
 
-extern DestReceiver *CreateExplainSerializeDestReceiver(struct ExplainState *es);
+extern DestReceiver *CreateExplainSerializeDestReceiver(ExplainState *es);
 extern SerializeMetrics GetSerializationMetrics(DestReceiver *dest);
 
 #endif
diff --git a/src/include/commands/explain_format.h b/src/include/commands/explain_format.h
index 05045bf8cb4..f849a3938ce 100644
--- a/src/include/commands/explain_format.h
+++ b/src/include/commands/explain_format.h
@@ -15,44 +15,45 @@
 
 #include "nodes/pg_list.h"
 
-struct ExplainState;			/* avoid including explain.h here */
+/* avoid including explain_state.h here */
+typedef struct ExplainState ExplainState;
 
 extern void ExplainPropertyList(const char *qlabel, List *data,
-								struct ExplainState *es);
+								ExplainState *es);
 extern void ExplainPropertyListNested(const char *qlabel, List *data,
-									  struct ExplainState *es);
+									  ExplainState *es);
 extern void ExplainPropertyText(const char *qlabel, const char *value,
-								struct ExplainState *es);
+								ExplainState *es);
 extern void ExplainPropertyInteger(const char *qlabel, const char *unit,
-								   int64 value, struct ExplainState *es);
+								   int64 value, ExplainState *es);
 extern void ExplainPropertyUInteger(const char *qlabel, const char *unit,
-									uint64 value, struct ExplainState *es);
+									uint64 value, ExplainState *es);
 extern void ExplainPropertyFloat(const char *qlabel, const char *unit,
 								 double value, int ndigits,
-								 struct ExplainState *es);
+								 ExplainState *es);
 extern void ExplainPropertyBool(const char *qlabel, bool value,
-								struct ExplainState *es);
+								ExplainState *es);
 
 extern void ExplainOpenGroup(const char *objtype, const char *labelname,
-							 bool labeled, struct ExplainState *es);
+							 bool labeled, ExplainState *es);
 extern void ExplainCloseGroup(const char *objtype, const char *labelname,
-							  bool labeled, struct ExplainState *es);
+							  bool labeled, ExplainState *es);
 
 extern void ExplainOpenSetAsideGroup(const char *objtype, const char *labelname,
 									 bool labeled, int depth,
-									 struct ExplainState *es);
-extern void ExplainSaveGroup(struct ExplainState *es, int depth,
+									 ExplainState *es);
+extern void ExplainSaveGroup(ExplainState *es, int depth,
 							 int *state_save);
-extern void ExplainRestoreGroup(struct ExplainState *es, int depth,
+extern void ExplainRestoreGroup(ExplainState *es, int depth,
 								int *state_save);
 
 extern void ExplainDummyGroup(const char *objtype, const char *labelname,
-							  struct ExplainState *es);
+							  ExplainState *es);
 
-extern void ExplainBeginOutput(struct ExplainState *es);
-extern void ExplainEndOutput(struct ExplainState *es);
-extern void ExplainSeparatePlans(struct ExplainState *es);
+extern void ExplainBeginOutput(ExplainState *es);
+extern void ExplainEndOutput(ExplainState *es);
+extern void ExplainSeparatePlans(ExplainState *es);
 
-extern void ExplainIndentText(struct ExplainState *es);
+extern void ExplainIndentText(ExplainState *es);
 
 #endif
diff --git a/src/include/commands/explain_state.h b/src/include/commands/explain_state.h
index 32728f5d1a1..ba073b86918 100644
--- a/src/include/commands/explain_state.h
+++ b/src/include/commands/explain_state.h
@@ -79,7 +79,7 @@ typedef struct ExplainState
 typedef void (*ExplainOptionHandler) (ExplainState *, DefElem *, ParseState *);
 
 /* Hook to perform additional EXPLAIN options validation */
-typedef void (*explain_validate_options_hook_type) (struct ExplainState *es, List *options,
+typedef void (*explain_validate_options_hook_type) (ExplainState *es, List *options,
 													ParseState *pstate);
 extern PGDLLIMPORT explain_validate_options_hook_type explain_validate_options_hook;
 
diff --git a/src/include/foreign/fdwapi.h b/src/include/foreign/fdwapi.h
index b4da4e6a16a..fcd7e7027f3 100644
--- a/src/include/foreign/fdwapi.h
+++ b/src/include/foreign/fdwapi.h
@@ -16,8 +16,8 @@
 #include "nodes/execnodes.h"
 #include "nodes/pathnodes.h"
 
-/* To avoid including explain.h here, reference ExplainState thus: */
-struct ExplainState;
+/* avoid including explain_state.h here */
+typedef struct ExplainState ExplainState;
 
 
 /*
@@ -137,16 +137,16 @@ typedef void (*RefetchForeignRow_function) (EState *estate,
 											bool *updated);
 
 typedef void (*ExplainForeignScan_function) (ForeignScanState *node,
-											 struct ExplainState *es);
+											 ExplainState *es);
 
 typedef void (*ExplainForeignModify_function) (ModifyTableState *mtstate,
 											   ResultRelInfo *rinfo,
 											   List *fdw_private,
 											   int subplan_index,
-											   struct ExplainState *es);
+											   ExplainState *es);
 
 typedef void (*ExplainDirectModify_function) (ForeignScanState *node,
-											  struct ExplainState *es);
+											  ExplainState *es);
 
 typedef int (*AcquireSampleRowsFunc) (Relation relation, int elevel,
 									  HeapTuple *rows, int targrows,
-- 
2.51.0

v2-0005-Update-various-forward-declarations-to-use-typede.patchtext/plain; charset=UTF-8; name=v2-0005-Update-various-forward-declarations-to-use-typede.patchDownload
From 02208def8e646992bbf649f1792ac6529ae98521 Mon Sep 17 00:00:00 2001
From: Peter Eisentraut <peter@eisentraut.org>
Date: Wed, 10 Sep 2025 08:12:05 +0200
Subject: [PATCH v2 5/7] Update various forward declarations to use typedef

There are a number of forward declarations that use struct but not the
customary typedef, because that could have led to repeat typedefs,
which was not allowed.  This is now allowed in C11, so we can update
these to provide the typedefs as well, so that the later uses of the
types look more consistent.

Discussion: https://www.postgresql.org/message-id/flat/10d32190-f31b-40a5-b177-11db55597355@eisentraut.org
---
 src/include/commands/tablecmds.h      |  5 ++--
 src/include/common/string.h           |  7 +++--
 src/include/executor/executor.h       |  4 +--
 src/include/executor/tablefunc.h      | 18 ++++++------
 src/include/nodes/execnodes.h         | 40 +++++++++++++--------------
 src/include/nodes/nodeFuncs.h         |  6 ++--
 src/include/nodes/params.h            | 15 +++++-----
 src/include/nodes/subscripting.h      | 14 +++++-----
 src/include/nodes/supportnodes.h      | 26 ++++++++---------
 src/include/optimizer/optimizer.h     | 14 +++++-----
 src/include/parser/parse_utilcmd.h    |  4 +--
 src/include/partitioning/partbounds.h |  6 ++--
 src/include/partitioning/partprune.h  | 10 +++----
 src/include/rewrite/rewriteManip.h    |  4 +--
 src/include/storage/bufmgr.h          | 24 ++++++++--------
 src/include/storage/bulk_write.h      |  4 +--
 src/include/storage/dsm.h             |  4 +--
 src/include/storage/shmem.h           |  5 ++--
 src/include/tcop/pquery.h             |  4 +--
 src/include/utils/array.h             |  6 ++--
 src/include/utils/lsyscache.h         |  6 ++--
 src/include/utils/plancache.h         | 14 +++++-----
 src/include/utils/ruleutils.h         |  8 +++---
 23 files changed, 124 insertions(+), 124 deletions(-)

diff --git a/src/include/commands/tablecmds.h b/src/include/commands/tablecmds.h
index 6832470d387..e9b0fab0767 100644
--- a/src/include/commands/tablecmds.h
+++ b/src/include/commands/tablecmds.h
@@ -21,7 +21,8 @@
 #include "storage/lock.h"
 #include "utils/relcache.h"
 
-struct AlterTableUtilityContext;	/* avoid including tcop/utility.h here */
+typedef struct AlterTableUtilityContext AlterTableUtilityContext;	/* avoid including
+																	 * tcop/utility.h here */
 
 
 extern ObjectAddress DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId,
@@ -34,7 +35,7 @@ extern void RemoveRelations(DropStmt *drop);
 extern Oid	AlterTableLookupRelation(AlterTableStmt *stmt, LOCKMODE lockmode);
 
 extern void AlterTable(AlterTableStmt *stmt, LOCKMODE lockmode,
-					   struct AlterTableUtilityContext *context);
+					   AlterTableUtilityContext *context);
 
 extern LOCKMODE AlterTableGetLockLevel(List *cmds);
 
diff --git a/src/include/common/string.h b/src/include/common/string.h
index ffe5ed51c5d..55ed8774364 100644
--- a/src/include/common/string.h
+++ b/src/include/common/string.h
@@ -12,7 +12,8 @@
 
 #include <signal.h>
 
-struct StringInfoData;			/* avoid including stringinfo.h here */
+typedef struct StringInfoData *StringInfo;	/* avoid including stringinfo.h
+											 * here */
 
 typedef struct PromptInterruptContext
 {
@@ -32,8 +33,8 @@ extern bool pg_is_ascii(const char *str);
 
 /* functions in src/common/pg_get_line.c */
 extern char *pg_get_line(FILE *stream, PromptInterruptContext *prompt_ctx);
-extern bool pg_get_line_buf(FILE *stream, struct StringInfoData *buf);
-extern bool pg_get_line_append(FILE *stream, struct StringInfoData *buf,
+extern bool pg_get_line_buf(FILE *stream, StringInfo buf);
+extern bool pg_get_line_append(FILE *stream, StringInfo buf,
 							   PromptInterruptContext *prompt_ctx);
 
 /* functions in src/common/sprompt.c */
diff --git a/src/include/executor/executor.h b/src/include/executor/executor.h
index 31133514e84..3248e78cd28 100644
--- a/src/include/executor/executor.h
+++ b/src/include/executor/executor.h
@@ -100,12 +100,12 @@ extern PGDLLIMPORT ExecutorCheckPerms_hook_type ExecutorCheckPerms_hook;
 /*
  * prototypes from functions in execAmi.c
  */
-struct Path;					/* avoid including pathnodes.h here */
+typedef struct Path Path;		/* avoid including pathnodes.h here */
 
 extern void ExecReScan(PlanState *node);
 extern void ExecMarkPos(PlanState *node);
 extern void ExecRestrPos(PlanState *node);
-extern bool ExecSupportsMarkRestore(struct Path *pathnode);
+extern bool ExecSupportsMarkRestore(Path *pathnode);
 extern bool ExecSupportsBackwardScan(Plan *node);
 extern bool ExecMaterializesOutput(NodeTag plantype);
 
diff --git a/src/include/executor/tablefunc.h b/src/include/executor/tablefunc.h
index 2c4498c5955..4dd5fef4aea 100644
--- a/src/include/executor/tablefunc.h
+++ b/src/include/executor/tablefunc.h
@@ -14,7 +14,7 @@
 #define _TABLEFUNC_H
 
 /* Forward-declare this to avoid including execnodes.h here */
-struct TableFuncScanState;
+typedef struct TableFuncScanState TableFuncScanState;
 
 /*
  * TableFuncRoutine holds function pointers used for generating content of
@@ -51,17 +51,17 @@ struct TableFuncScanState;
  */
 typedef struct TableFuncRoutine
 {
-	void		(*InitOpaque) (struct TableFuncScanState *state, int natts);
-	void		(*SetDocument) (struct TableFuncScanState *state, Datum value);
-	void		(*SetNamespace) (struct TableFuncScanState *state, const char *name,
+	void		(*InitOpaque) (TableFuncScanState *state, int natts);
+	void		(*SetDocument) (TableFuncScanState *state, Datum value);
+	void		(*SetNamespace) (TableFuncScanState *state, const char *name,
 								 const char *uri);
-	void		(*SetRowFilter) (struct TableFuncScanState *state, const char *path);
-	void		(*SetColumnFilter) (struct TableFuncScanState *state,
+	void		(*SetRowFilter) (TableFuncScanState *state, const char *path);
+	void		(*SetColumnFilter) (TableFuncScanState *state,
 									const char *path, int colnum);
-	bool		(*FetchRow) (struct TableFuncScanState *state);
-	Datum		(*GetValue) (struct TableFuncScanState *state, int colnum,
+	bool		(*FetchRow) (TableFuncScanState *state);
+	Datum		(*GetValue) (TableFuncScanState *state, int colnum,
 							 Oid typid, int32 typmod, bool *isnull);
-	void		(*DestroyOpaque) (struct TableFuncScanState *state);
+	void		(*DestroyOpaque) (TableFuncScanState *state);
 } TableFuncRoutine;
 
 #endif							/* _TABLEFUNC_H */
diff --git a/src/include/nodes/execnodes.h b/src/include/nodes/execnodes.h
index de782014b2d..9623e53e591 100644
--- a/src/include/nodes/execnodes.h
+++ b/src/include/nodes/execnodes.h
@@ -49,15 +49,13 @@
 #include "utils/tuplesort.h"
 #include "utils/tuplestore.h"
 
-struct PlanState;				/* forward references in this file */
-struct ParallelHashJoinState;
-struct ExecRowMark;
-struct ExprState;
-struct ExprContext;
-struct RangeTblEntry;			/* avoid including parsenodes.h here */
-struct ExprEvalStep;			/* avoid including execExpr.h everywhere */
-struct CopyMultiInsertBuffer;
-struct LogicalTapeSet;
+/*
+ * forward references in this file
+ */
+typedef struct PlanState PlanState;
+typedef struct ExecRowMark ExecRowMark;
+typedef struct ExprState ExprState;
+typedef struct ExprContext ExprContext;
 
 
 /* ----------------
@@ -67,8 +65,8 @@ struct LogicalTapeSet;
  * It contains instructions (in ->steps) to evaluate the expression.
  * ----------------
  */
-typedef Datum (*ExprStateEvalFunc) (struct ExprState *expression,
-									struct ExprContext *econtext,
+typedef Datum (*ExprStateEvalFunc) (ExprState *expression,
+									ExprContext *econtext,
 									bool *isNull);
 
 /* Bits in ExprState->flags (see also execExpr.h for private flag bits): */
@@ -131,7 +129,7 @@ typedef struct ExprState
 	int			steps_alloc;	/* allocated length of steps array */
 
 #define FIELDNO_EXPRSTATE_PARENT 11
-	struct PlanState *parent;	/* parent PlanState node, if any */
+	PlanState  *parent;			/* parent PlanState node, if any */
 	ParamListInfo ext_params;	/* for compiling PARAM_EXTERN nodes */
 
 	Datum	   *innermost_caseval;
@@ -638,8 +636,8 @@ typedef struct ResultRelInfo
  */
 typedef struct AsyncRequest
 {
-	struct PlanState *requestor;	/* Node that wants a tuple */
-	struct PlanState *requestee;	/* Node from which a tuple is wanted */
+	PlanState  *requestor;		/* Node that wants a tuple */
+	PlanState  *requestee;		/* Node from which a tuple is wanted */
 	int			request_index;	/* Scratch space for requestor */
 	bool		callback_pending;	/* Callback is needed */
 	bool		request_complete;	/* Request complete, result valid */
@@ -665,8 +663,8 @@ typedef struct EState
 	Index		es_range_table_size;	/* size of the range table arrays */
 	Relation   *es_relations;	/* Array of per-range-table-entry Relation
 								 * pointers, or NULL if not yet opened */
-	struct ExecRowMark **es_rowmarks;	/* Array of per-range-table-entry
-										 * ExecRowMarks, or NULL if none */
+	ExecRowMark **es_rowmarks;	/* Array of per-range-table-entry
+								 * ExecRowMarks, or NULL if none */
 	List	   *es_rteperminfos;	/* List of RTEPermissionInfo */
 	PlannedStmt *es_plannedstmt;	/* link to top of plan tree */
 	List	   *es_part_prune_infos;	/* List of PartitionPruneInfo */
@@ -1006,8 +1004,8 @@ typedef struct SubPlanState
 {
 	NodeTag		type;
 	SubPlan    *subplan;		/* expression plan node */
-	struct PlanState *planstate;	/* subselect plan's state tree */
-	struct PlanState *parent;	/* parent plan node's state tree */
+	PlanState  *planstate;		/* subselect plan's state tree */
+	PlanState  *parent;			/* parent plan node's state tree */
 	ExprState  *testexpr;		/* state of combining expression */
 	HeapTuple	curTuple;		/* copy of most recent tuple from subplan */
 	Datum		curArray;		/* most recent array from ARRAY() subplan */
@@ -1144,7 +1142,7 @@ typedef struct JsonExprState
  * if no more tuples are available.
  * ----------------
  */
-typedef TupleTableSlot *(*ExecProcNodeMtd) (struct PlanState *pstate);
+typedef TupleTableSlot *(*ExecProcNodeMtd) (PlanState *pstate);
 
 /* ----------------
  *		PlanState node
@@ -1181,8 +1179,8 @@ typedef struct PlanState
 	 * subPlan list, which does not exist in the plan tree).
 	 */
 	ExprState  *qual;			/* boolean qual condition */
-	struct PlanState *lefttree; /* input plan tree(s) */
-	struct PlanState *righttree;
+	PlanState  *lefttree;		/* input plan tree(s) */
+	PlanState  *righttree;
 
 	List	   *initPlan;		/* Init SubPlanState nodes (un-correlated expr
 								 * subselects) */
diff --git a/src/include/nodes/nodeFuncs.h b/src/include/nodes/nodeFuncs.h
index 5653fec8cbe..11c1c140ec4 100644
--- a/src/include/nodes/nodeFuncs.h
+++ b/src/include/nodes/nodeFuncs.h
@@ -15,7 +15,7 @@
 
 #include "nodes/parsenodes.h"
 
-struct PlanState;				/* avoid including execnodes.h too */
+typedef struct PlanState PlanState; /* avoid including execnodes.h too */
 
 
 /* flags bits for query_tree_walker and query_tree_mutator */
@@ -38,7 +38,7 @@ typedef bool (*check_function_callback) (Oid func_id, void *context);
 
 /* callback functions for tree walkers */
 typedef bool (*tree_walker_callback) (Node *node, void *context);
-typedef bool (*planstate_tree_walker_callback) (struct PlanState *planstate,
+typedef bool (*planstate_tree_walker_callback) (PlanState *planstate,
 												void *context);
 
 /* callback functions for tree mutators */
@@ -217,7 +217,7 @@ extern bool raw_expression_tree_walker_impl(Node *node,
 											tree_walker_callback walker,
 											void *context);
 
-extern bool planstate_tree_walker_impl(struct PlanState *planstate,
+extern bool planstate_tree_walker_impl(PlanState *planstate,
 									   planstate_tree_walker_callback walker,
 									   void *context);
 
diff --git a/src/include/nodes/params.h b/src/include/nodes/params.h
index 4321ca6329b..ca4117b1449 100644
--- a/src/include/nodes/params.h
+++ b/src/include/nodes/params.h
@@ -14,11 +14,10 @@
 #ifndef PARAMS_H
 #define PARAMS_H
 
-/* Forward declarations, to avoid including other headers */
-struct Bitmapset;
-struct ExprState;
-struct Param;
-struct ParseState;
+/* to avoid including other headers */
+typedef struct ExprState ExprState;
+typedef struct Param Param;
+typedef struct ParseState ParseState;
 
 
 /*
@@ -101,11 +100,11 @@ typedef ParamExternData *(*ParamFetchHook) (ParamListInfo params,
 											int paramid, bool speculative,
 											ParamExternData *workspace);
 
-typedef void (*ParamCompileHook) (ParamListInfo params, struct Param *param,
-								  struct ExprState *state,
+typedef void (*ParamCompileHook) (ParamListInfo params, Param *param,
+								  ExprState *state,
 								  Datum *resv, bool *resnull);
 
-typedef void (*ParserSetupHook) (struct ParseState *pstate, void *arg);
+typedef void (*ParserSetupHook) (ParseState *pstate, void *arg);
 
 typedef struct ParamListInfoData
 {
diff --git a/src/include/nodes/subscripting.h b/src/include/nodes/subscripting.h
index 234e8ad8012..e991f4bf826 100644
--- a/src/include/nodes/subscripting.h
+++ b/src/include/nodes/subscripting.h
@@ -15,10 +15,10 @@
 
 #include "nodes/primnodes.h"
 
-/* Forward declarations, to avoid including other headers */
-struct ParseState;
-struct SubscriptingRefState;
-struct SubscriptExecSteps;
+/* to avoid including other headers */
+typedef struct ParseState ParseState;
+typedef struct SubscriptingRefState SubscriptingRefState;
+typedef struct SubscriptExecSteps SubscriptExecSteps;
 
 /*
  * The SQL-visible function that defines a subscripting method is declared
@@ -94,7 +94,7 @@ struct SubscriptExecSteps;
  */
 typedef void (*SubscriptTransform) (SubscriptingRef *sbsref,
 									List *indirection,
-									struct ParseState *pstate,
+									ParseState *pstate,
 									bool isSlice,
 									bool isAssignment);
 
@@ -151,8 +151,8 @@ typedef void (*SubscriptTransform) (SubscriptingRef *sbsref,
  * Set the relevant pointers to NULL for any omitted methods.
  */
 typedef void (*SubscriptExecSetup) (const SubscriptingRef *sbsref,
-									struct SubscriptingRefState *sbsrefstate,
-									struct SubscriptExecSteps *methods);
+									SubscriptingRefState *sbsrefstate,
+									SubscriptExecSteps *methods);
 
 /* Struct returned by the SQL-visible subscript handler function */
 typedef struct SubscriptRoutines
diff --git a/src/include/nodes/supportnodes.h b/src/include/nodes/supportnodes.h
index 9c047cc401b..7b623d54058 100644
--- a/src/include/nodes/supportnodes.h
+++ b/src/include/nodes/supportnodes.h
@@ -35,10 +35,10 @@
 
 #include "nodes/plannodes.h"
 
-struct PlannerInfo;				/* avoid including pathnodes.h here */
-struct IndexOptInfo;
-struct SpecialJoinInfo;
-struct WindowClause;
+typedef struct PlannerInfo PlannerInfo; /* avoid including pathnodes.h here */
+typedef struct IndexOptInfo IndexOptInfo;
+typedef struct SpecialJoinInfo SpecialJoinInfo;
+typedef struct WindowClause WindowClause;
 
 /*
  * The Simplify request allows the support function to perform plan-time
@@ -65,7 +65,7 @@ typedef struct SupportRequestSimplify
 {
 	NodeTag		type;
 
-	struct PlannerInfo *root;	/* Planner's infrastructure */
+	PlannerInfo *root;			/* Planner's infrastructure */
 	FuncExpr   *fcall;			/* Function call to be simplified */
 } SupportRequestSimplify;
 
@@ -93,14 +93,14 @@ typedef struct SupportRequestSelectivity
 	NodeTag		type;
 
 	/* Input fields: */
-	struct PlannerInfo *root;	/* Planner's infrastructure */
+	PlannerInfo *root;			/* Planner's infrastructure */
 	Oid			funcid;			/* function we are inquiring about */
 	List	   *args;			/* pre-simplified arguments to function */
 	Oid			inputcollid;	/* function's input collation */
 	bool		is_join;		/* is this a join or restriction case? */
 	int			varRelid;		/* if restriction, RTI of target relation */
 	JoinType	jointype;		/* if join, outer join type */
-	struct SpecialJoinInfo *sjinfo; /* if outer join, info about join */
+	SpecialJoinInfo *sjinfo;	/* if outer join, info about join */
 
 	/* Output fields: */
 	Selectivity selectivity;	/* returned selectivity estimate */
@@ -133,7 +133,7 @@ typedef struct SupportRequestCost
 	NodeTag		type;
 
 	/* Input fields: */
-	struct PlannerInfo *root;	/* Planner's infrastructure (could be NULL) */
+	PlannerInfo *root;			/* Planner's infrastructure (could be NULL) */
 	Oid			funcid;			/* function we are inquiring about */
 	Node	   *node;			/* parse node invoking function, or NULL */
 
@@ -160,7 +160,7 @@ typedef struct SupportRequestRows
 	NodeTag		type;
 
 	/* Input fields: */
-	struct PlannerInfo *root;	/* Planner's infrastructure (could be NULL) */
+	PlannerInfo *root;			/* Planner's infrastructure (could be NULL) */
 	Oid			funcid;			/* function we are inquiring about */
 	Node	   *node;			/* parse node invoking function */
 
@@ -225,11 +225,11 @@ typedef struct SupportRequestIndexCondition
 	NodeTag		type;
 
 	/* Input fields: */
-	struct PlannerInfo *root;	/* Planner's infrastructure */
+	PlannerInfo *root;			/* Planner's infrastructure */
 	Oid			funcid;			/* function we are inquiring about */
 	Node	   *node;			/* parse node invoking function */
 	int			indexarg;		/* index of function arg matching indexcol */
-	struct IndexOptInfo *index; /* planner's info about target index */
+	IndexOptInfo *index;		/* planner's info about target index */
 	int			indexcol;		/* index of target index column (0-based) */
 	Oid			opfamily;		/* index column's operator family */
 	Oid			indexcollation; /* index column's collation */
@@ -293,7 +293,7 @@ typedef struct SupportRequestWFuncMonotonic
 
 	/* Input fields: */
 	WindowFunc *window_func;	/* Pointer to the window function data */
-	struct WindowClause *window_clause; /* Pointer to the window clause data */
+	WindowClause *window_clause;	/* Pointer to the window clause data */
 
 	/* Output fields: */
 	MonotonicFunction monotonic;
@@ -336,7 +336,7 @@ typedef struct SupportRequestOptimizeWindowClause
 
 	/* Input fields: */
 	WindowFunc *window_func;	/* Pointer to the window function data */
-	struct WindowClause *window_clause; /* Pointer to the window clause data */
+	WindowClause *window_clause;	/* Pointer to the window clause data */
 
 	/* Input/Output fields: */
 	int			frameOptions;	/* New frameOptions, or left untouched if no
diff --git a/src/include/optimizer/optimizer.h b/src/include/optimizer/optimizer.h
index 03b214755c2..5d981fe7d6b 100644
--- a/src/include/optimizer/optimizer.h
+++ b/src/include/optimizer/optimizer.h
@@ -35,9 +35,9 @@ typedef struct IndexOptInfo IndexOptInfo;
 typedef struct SpecialJoinInfo SpecialJoinInfo;
 
 /* It also seems best not to include plannodes.h, params.h, or htup.h here */
-struct PlannedStmt;
-struct ParamListInfoData;
-struct HeapTupleData;
+typedef struct PlannedStmt PlannedStmt;
+typedef struct ParamListInfoData *ParamListInfo;
+typedef struct HeapTupleData *HeapTuple;
 
 
 /* in path/clausesel.c: */
@@ -102,9 +102,9 @@ extern PGDLLIMPORT int debug_parallel_query;
 extern PGDLLIMPORT bool parallel_leader_participation;
 extern PGDLLIMPORT bool enable_distinct_reordering;
 
-extern struct PlannedStmt *planner(Query *parse, const char *query_string,
-								   int cursorOptions,
-								   struct ParamListInfoData *boundParams);
+extern PlannedStmt *planner(Query *parse, const char *query_string,
+							int cursorOptions,
+							ParamListInfo boundParams);
 
 extern Expr *expression_planner(Expr *expr);
 extern Expr *expression_planner_with_deps(Expr *expr,
@@ -147,7 +147,7 @@ extern bool var_is_nonnullable(PlannerInfo *root, Var *var, bool use_rel_info);
 
 extern List *expand_function_arguments(List *args, bool include_out_arguments,
 									   Oid result_type,
-									   struct HeapTupleData *func_tuple);
+									   HeapTuple func_tuple);
 
 extern ScalarArrayOpExpr *make_SAOP_expr(Oid oper, Node *leftexpr,
 										 Oid coltype, Oid arraycollid,
diff --git a/src/include/parser/parse_utilcmd.h b/src/include/parser/parse_utilcmd.h
index 9f2b58de797..4965fac4495 100644
--- a/src/include/parser/parse_utilcmd.h
+++ b/src/include/parser/parse_utilcmd.h
@@ -16,7 +16,7 @@
 
 #include "parser/parse_node.h"
 
-struct AttrMap;					/* avoid including attmap.h here */
+typedef struct AttrMap AttrMap; /* avoid including attmap.h here */
 
 
 extern List *transformCreateStmt(CreateStmt *stmt, const char *queryString);
@@ -38,7 +38,7 @@ extern List *expandTableLikeClause(RangeVar *heapRel,
 								   TableLikeClause *table_like_clause);
 extern IndexStmt *generateClonedIndexStmt(RangeVar *heapRel,
 										  Relation source_idx,
-										  const struct AttrMap *attmap,
+										  const AttrMap *attmap,
 										  Oid *constraintOid);
 
 #endif							/* PARSE_UTILCMD_H */
diff --git a/src/include/partitioning/partbounds.h b/src/include/partitioning/partbounds.h
index 65f161f7188..083b6e3a88a 100644
--- a/src/include/partitioning/partbounds.h
+++ b/src/include/partitioning/partbounds.h
@@ -15,7 +15,7 @@
 #include "parser/parse_node.h"
 #include "partitioning/partdefs.h"
 
-struct RelOptInfo;				/* avoid including pathnodes.h here */
+typedef struct RelOptInfo RelOptInfo;	/* avoid including pathnodes.h here */
 
 
 /*
@@ -114,8 +114,8 @@ extern PartitionBoundInfo partition_bounds_copy(PartitionBoundInfo src,
 extern PartitionBoundInfo partition_bounds_merge(int partnatts,
 												 FmgrInfo *partsupfunc,
 												 Oid *partcollation,
-												 struct RelOptInfo *outer_rel,
-												 struct RelOptInfo *inner_rel,
+												 RelOptInfo *outer_rel,
+												 RelOptInfo *inner_rel,
 												 JoinType jointype,
 												 List **outer_parts,
 												 List **inner_parts);
diff --git a/src/include/partitioning/partprune.h b/src/include/partitioning/partprune.h
index c413734789a..657b436d958 100644
--- a/src/include/partitioning/partprune.h
+++ b/src/include/partitioning/partprune.h
@@ -17,8 +17,8 @@
 #include "nodes/execnodes.h"
 #include "partitioning/partdefs.h"
 
-struct PlannerInfo;				/* avoid including pathnodes.h here */
-struct RelOptInfo;
+typedef struct PlannerInfo PlannerInfo; /* avoid including pathnodes.h here */
+typedef struct RelOptInfo RelOptInfo;
 
 
 /*
@@ -70,11 +70,11 @@ typedef struct PartitionPruneContext
 #define PruneCxtStateIdx(partnatts, step_id, keyno) \
 	((partnatts) * (step_id) + (keyno))
 
-extern int	make_partition_pruneinfo(struct PlannerInfo *root,
-									 struct RelOptInfo *parentrel,
+extern int	make_partition_pruneinfo(PlannerInfo *root,
+									 RelOptInfo *parentrel,
 									 List *subpaths,
 									 List *prunequal);
-extern Bitmapset *prune_append_rel_partitions(struct RelOptInfo *rel);
+extern Bitmapset *prune_append_rel_partitions(RelOptInfo *rel);
 extern Bitmapset *get_matching_partitions(PartitionPruneContext *context,
 										  List *pruning_steps);
 
diff --git a/src/include/rewrite/rewriteManip.h b/src/include/rewrite/rewriteManip.h
index 7c018f2a4e3..74de195deeb 100644
--- a/src/include/rewrite/rewriteManip.h
+++ b/src/include/rewrite/rewriteManip.h
@@ -17,7 +17,7 @@
 #include "nodes/parsenodes.h"
 #include "nodes/pathnodes.h"
 
-struct AttrMap;					/* avoid including attmap.h here */
+typedef struct AttrMap AttrMap; /* avoid including attmap.h here */
 
 
 typedef struct replace_rte_variables_context replace_rte_variables_context;
@@ -101,7 +101,7 @@ extern Node *replace_rte_variables_mutator(Node *node,
 
 extern Node *map_variable_attnos(Node *node,
 								 int target_varno, int sublevels_up,
-								 const struct AttrMap *attno_map,
+								 const AttrMap *attno_map,
 								 Oid to_rowtype, bool *found_whole_row);
 
 extern Node *ReplaceVarFromTargetList(Var *var,
diff --git a/src/include/storage/bufmgr.h b/src/include/storage/bufmgr.h
index 41fdc1e7693..47360a3d3d8 100644
--- a/src/include/storage/bufmgr.h
+++ b/src/include/storage/bufmgr.h
@@ -93,6 +93,9 @@ typedef enum ExtendBufferedFlags
 	EB_LOCK_TARGET = (1 << 5),
 }			ExtendBufferedFlags;
 
+/* forward declared, to avoid including smgr.h here */
+typedef struct SMgrRelationData *SMgrRelation;
+
 /*
  * Some functions identify relations either by relation or smgr +
  * relpersistence.  Used via the BMR_REL()/BMR_SMGR() macros below.  This
@@ -101,7 +104,7 @@ typedef enum ExtendBufferedFlags
 typedef struct BufferManagerRelation
 {
 	Relation	rel;
-	struct SMgrRelationData *smgr;
+	SMgrRelation smgr;
 	char		relpersistence;
 } BufferManagerRelation;
 
@@ -122,7 +125,7 @@ struct ReadBuffersOperation
 {
 	/* The following members should be set by the caller. */
 	Relation	rel;			/* optional */
-	struct SMgrRelationData *smgr;
+	SMgrRelation smgr;
 	char		persistence;
 	ForkNumber	forknum;
 	BufferAccessStrategy strategy;
@@ -143,11 +146,8 @@ struct ReadBuffersOperation
 
 typedef struct ReadBuffersOperation ReadBuffersOperation;
 
-/* forward declared, to avoid having to expose buf_internals.h here */
-struct WritebackContext;
-
-/* forward declared, to avoid including smgr.h here */
-struct SMgrRelationData;
+/* to avoid having to expose buf_internals.h here */
+typedef struct WritebackContext WritebackContext;
 
 /* in globals.c ... this duplicates miscadmin.h */
 extern PGDLLIMPORT int NBuffers;
@@ -201,7 +201,7 @@ extern PGDLLIMPORT int32 *LocalRefCount;
 /*
  * prototypes for functions in bufmgr.c
  */
-extern PrefetchBufferResult PrefetchSharedBuffer(struct SMgrRelationData *smgr_reln,
+extern PrefetchBufferResult PrefetchSharedBuffer(SMgrRelation smgr_reln,
 												 ForkNumber forkNum,
 												 BlockNumber blockNum);
 extern PrefetchBufferResult PrefetchBuffer(Relation reln, ForkNumber forkNum,
@@ -268,15 +268,15 @@ extern BlockNumber RelationGetNumberOfBlocksInFork(Relation relation,
 												   ForkNumber forkNum);
 extern void FlushOneBuffer(Buffer buffer);
 extern void FlushRelationBuffers(Relation rel);
-extern void FlushRelationsAllBuffers(struct SMgrRelationData **smgrs, int nrels);
+extern void FlushRelationsAllBuffers(SMgrRelation *smgrs, int nrels);
 extern void CreateAndCopyRelationData(RelFileLocator src_rlocator,
 									  RelFileLocator dst_rlocator,
 									  bool permanent);
 extern void FlushDatabaseBuffers(Oid dbid);
-extern void DropRelationBuffers(struct SMgrRelationData *smgr_reln,
+extern void DropRelationBuffers(SMgrRelation smgr_reln,
 								ForkNumber *forkNum,
 								int nforks, BlockNumber *firstDelBlock);
-extern void DropRelationsAllBuffers(struct SMgrRelationData **smgr_reln,
+extern void DropRelationsAllBuffers(SMgrRelation *smgr_reln,
 									int nlocators);
 extern void DropDatabaseBuffers(Oid dbid);
 
@@ -298,7 +298,7 @@ extern bool ConditionalLockBufferForCleanup(Buffer buffer);
 extern bool IsBufferCleanupOK(Buffer buffer);
 extern bool HoldingBufferPinThatDelaysRecovery(void);
 
-extern bool BgBufferSync(struct WritebackContext *wb_context);
+extern bool BgBufferSync(WritebackContext *wb_context);
 
 extern uint32 GetPinLimit(void);
 extern uint32 GetLocalPinLimit(void);
diff --git a/src/include/storage/bulk_write.h b/src/include/storage/bulk_write.h
index 7885415f6cb..ca359784016 100644
--- a/src/include/storage/bulk_write.h
+++ b/src/include/storage/bulk_write.h
@@ -28,10 +28,10 @@ typedef struct BulkWriteState BulkWriteState;
 typedef PGIOAlignedBlock *BulkWriteBuffer;
 
 /* forward declared from smgr.h */
-struct SMgrRelationData;
+typedef struct SMgrRelationData *SMgrRelation;
 
 extern BulkWriteState *smgr_bulk_start_rel(Relation rel, ForkNumber forknum);
-extern BulkWriteState *smgr_bulk_start_smgr(struct SMgrRelationData *smgr, ForkNumber forknum, bool use_wal);
+extern BulkWriteState *smgr_bulk_start_smgr(SMgrRelation smgr, ForkNumber forknum, bool use_wal);
 
 extern BulkWriteBuffer smgr_bulk_get_buf(BulkWriteState *bulkstate);
 extern void smgr_bulk_write(BulkWriteState *bulkstate, BlockNumber blocknum, BulkWriteBuffer buf, bool page_std);
diff --git a/src/include/storage/dsm.h b/src/include/storage/dsm.h
index 2302cc7f40b..88cf0962957 100644
--- a/src/include/storage/dsm.h
+++ b/src/include/storage/dsm.h
@@ -20,9 +20,9 @@ typedef struct dsm_segment dsm_segment;
 #define DSM_CREATE_NULL_IF_MAXSEGMENTS			0x0001
 
 /* Startup and shutdown functions. */
-struct PGShmemHeader;			/* avoid including pg_shmem.h */
+typedef struct PGShmemHeader PGShmemHeader; /* avoid including pg_shmem.h */
 extern void dsm_cleanup_using_control_segment(dsm_handle old_control_handle);
-extern void dsm_postmaster_startup(struct PGShmemHeader *);
+extern void dsm_postmaster_startup(PGShmemHeader *);
 extern void dsm_backend_shutdown(void);
 extern void dsm_detach_all(void);
 
diff --git a/src/include/storage/shmem.h b/src/include/storage/shmem.h
index 8604feca93b..cd683a9d2d9 100644
--- a/src/include/storage/shmem.h
+++ b/src/include/storage/shmem.h
@@ -27,8 +27,9 @@
 
 /* shmem.c */
 extern PGDLLIMPORT slock_t *ShmemLock;
-struct PGShmemHeader;			/* avoid including storage/pg_shmem.h here */
-extern void InitShmemAccess(struct PGShmemHeader *seghdr);
+typedef struct PGShmemHeader PGShmemHeader; /* avoid including
+											 * storage/pg_shmem.h here */
+extern void InitShmemAccess(PGShmemHeader *seghdr);
 extern void InitShmemAllocation(void);
 extern void *ShmemAlloc(Size size);
 extern void *ShmemAllocNoError(Size size);
diff --git a/src/include/tcop/pquery.h b/src/include/tcop/pquery.h
index fa3cc5f2dfc..ccd995fc88e 100644
--- a/src/include/tcop/pquery.h
+++ b/src/include/tcop/pquery.h
@@ -17,7 +17,7 @@
 #include "nodes/parsenodes.h"
 #include "utils/portal.h"
 
-struct PlannedStmt;				/* avoid including plannodes.h here */
+typedef struct PlannedStmt PlannedStmt; /* avoid including plannodes.h here */
 
 
 extern PGDLLIMPORT Portal ActivePortal;
@@ -44,7 +44,7 @@ extern uint64 PortalRunFetch(Portal portal,
 							 long count,
 							 DestReceiver *dest);
 
-extern bool PlannedStmtRequiresSnapshot(struct PlannedStmt *pstmt);
+extern bool PlannedStmtRequiresSnapshot(PlannedStmt *pstmt);
 
 extern void EnsurePortalSnapshotExists(void);
 
diff --git a/src/include/utils/array.h b/src/include/utils/array.h
index 52f1fbf8d43..3383f16a3bb 100644
--- a/src/include/utils/array.h
+++ b/src/include/utils/array.h
@@ -65,8 +65,8 @@
 #include "utils/expandeddatum.h"
 
 /* avoid including execnodes.h here */
-struct ExprState;
-struct ExprContext;
+typedef struct ExprState ExprState;
+typedef struct ExprContext ExprContext;
 
 
 /*
@@ -384,7 +384,7 @@ extern ArrayType *array_set(ArrayType *array, int nSubscripts, int *indx,
 							int arraytyplen, int elmlen, bool elmbyval, char elmalign);
 
 extern Datum array_map(Datum arrayd,
-					   struct ExprState *exprstate, struct ExprContext *econtext,
+					   ExprState *exprstate, ExprContext *econtext,
 					   Oid retType, ArrayMapState *amstate);
 
 extern void array_bitmap_copy(bits8 *destbitmap, int destoffset,
diff --git a/src/include/utils/lsyscache.h b/src/include/utils/lsyscache.h
index c65cee4f24c..50fb149e9ac 100644
--- a/src/include/utils/lsyscache.h
+++ b/src/include/utils/lsyscache.h
@@ -19,7 +19,7 @@
 #include "nodes/pg_list.h"
 
 /* avoid including subscripting.h here */
-struct SubscriptRoutines;
+typedef struct SubscriptRoutines SubscriptRoutines;
 
 /* Result list element for get_op_index_interpretation */
 typedef struct OpIndexInterpretation
@@ -187,8 +187,8 @@ extern Oid	get_typmodin(Oid typid);
 extern Oid	get_typcollation(Oid typid);
 extern bool type_is_collatable(Oid typid);
 extern RegProcedure get_typsubscript(Oid typid, Oid *typelemp);
-extern const struct SubscriptRoutines *getSubscriptingRoutines(Oid typid,
-															   Oid *typelemp);
+extern const SubscriptRoutines *getSubscriptingRoutines(Oid typid,
+														Oid *typelemp);
 extern Oid	getBaseType(Oid typid);
 extern Oid	getBaseTypeAndTypmod(Oid typid, int32 *typmod);
 extern int32 get_typavgwidth(Oid typid, int32 typmod);
diff --git a/src/include/utils/plancache.h b/src/include/utils/plancache.h
index 1baa6d50bfd..a82b66d4bc2 100644
--- a/src/include/utils/plancache.h
+++ b/src/include/utils/plancache.h
@@ -24,8 +24,8 @@
 
 
 /* Forward declarations, to avoid including parsenodes.h here */
-struct Query;
-struct RawStmt;
+typedef struct Query Query;
+typedef struct RawStmt RawStmt;
 
 /* possible values for plan_cache_mode */
 typedef enum
@@ -105,8 +105,8 @@ typedef void (*PostRewriteHook) (List *querytree_list, void *arg);
 typedef struct CachedPlanSource
 {
 	int			magic;			/* should equal CACHEDPLANSOURCE_MAGIC */
-	struct RawStmt *raw_parse_tree; /* output of raw_parser(), or NULL */
-	struct Query *analyzed_parse_tree;	/* analyzed parse tree, or NULL */
+	RawStmt    *raw_parse_tree; /* output of raw_parser(), or NULL */
+	Query	   *analyzed_parse_tree;	/* analyzed parse tree, or NULL */
 	const char *query_string;	/* source text of query */
 	CommandTag	commandTag;		/* command tag for query */
 	Oid		   *param_types;	/* array of parameter type OIDs, or NULL */
@@ -202,13 +202,13 @@ extern void ResetPlanCache(void);
 
 extern void ReleaseAllPlanCacheRefsInOwner(ResourceOwner owner);
 
-extern CachedPlanSource *CreateCachedPlan(struct RawStmt *raw_parse_tree,
+extern CachedPlanSource *CreateCachedPlan(RawStmt *raw_parse_tree,
 										  const char *query_string,
 										  CommandTag commandTag);
-extern CachedPlanSource *CreateCachedPlanForQuery(struct Query *analyzed_parse_tree,
+extern CachedPlanSource *CreateCachedPlanForQuery(Query *analyzed_parse_tree,
 												  const char *query_string,
 												  CommandTag commandTag);
-extern CachedPlanSource *CreateOneShotCachedPlan(struct RawStmt *raw_parse_tree,
+extern CachedPlanSource *CreateOneShotCachedPlan(RawStmt *raw_parse_tree,
 												 const char *query_string,
 												 CommandTag commandTag);
 extern void CompleteCachedPlan(CachedPlanSource *plansource,
diff --git a/src/include/utils/ruleutils.h b/src/include/utils/ruleutils.h
index 5f2ea2e4d0e..7ba7d887914 100644
--- a/src/include/utils/ruleutils.h
+++ b/src/include/utils/ruleutils.h
@@ -17,8 +17,8 @@
 #include "nodes/parsenodes.h"
 #include "nodes/pg_list.h"
 
-struct Plan;					/* avoid including plannodes.h here */
-struct PlannedStmt;
+typedef struct Plan Plan;		/* avoid including plannodes.h here */
+typedef struct PlannedStmt PlannedStmt;
 
 /* Flags for pg_get_indexdef_columns_extended() */
 #define RULE_INDEXDEF_PRETTY		0x01
@@ -37,10 +37,10 @@ extern char *pg_get_constraintdef_command(Oid constraintId);
 extern char *deparse_expression(Node *expr, List *dpcontext,
 								bool forceprefix, bool showimplicit);
 extern List *deparse_context_for(const char *aliasname, Oid relid);
-extern List *deparse_context_for_plan_tree(struct PlannedStmt *pstmt,
+extern List *deparse_context_for_plan_tree(PlannedStmt *pstmt,
 										   List *rtable_names);
 extern List *set_deparse_context_plan(List *dpcontext,
-									  struct Plan *plan, List *ancestors);
+									  Plan *plan, List *ancestors);
 extern List *select_rtable_names_for_explain(List *rtable,
 											 Bitmapset *rels_used);
 extern char *get_window_frame_options_for_explain(int frameOptions,
-- 
2.51.0

v2-0006-Remove-hbaPort-type.patchtext/plain; charset=UTF-8; name=v2-0006-Remove-hbaPort-type.patchDownload
From c2f328658e90fad073510234e2631fde546fe601 Mon Sep 17 00:00:00 2001
From: Peter Eisentraut <peter@eisentraut.org>
Date: Fri, 29 Aug 2025 13:18:51 +0200
Subject: [PATCH v2 6/7] Remove hbaPort type

This was just a workaround to avoid including the header file that
defines the Port type.  With C11, we can now just re-define the Port
type without the possibility of a conflict.

Discussion: https://www.postgresql.org/message-id/flat/10d32190-f31b-40a5-b177-11db55597355@eisentraut.org
---
 src/backend/libpq/auth.c         | 8 ++++----
 src/backend/libpq/hba.c          | 6 +++---
 src/include/libpq/hba.h          | 6 +++---
 src/tools/pgindent/typedefs.list | 1 -
 4 files changed, 10 insertions(+), 11 deletions(-)

diff --git a/src/backend/libpq/auth.c b/src/backend/libpq/auth.c
index 4da46666439..ec4dbacf015 100644
--- a/src/backend/libpq/auth.c
+++ b/src/backend/libpq/auth.c
@@ -70,14 +70,14 @@ static int	CheckMD5Auth(Port *port, char *shadow_pass,
 /* Standard TCP port number for Ident service.  Assigned by IANA */
 #define IDENT_PORT 113
 
-static int	ident_inet(hbaPort *port);
+static int	ident_inet(Port *port);
 
 
 /*----------------------------------------------------------------
  * Peer authentication
  *----------------------------------------------------------------
  */
-static int	auth_peer(hbaPort *port);
+static int	auth_peer(Port *port);
 
 
 /*----------------------------------------------------------------
@@ -1668,7 +1668,7 @@ interpret_ident_response(const char *ident_response,
  *	latch was set would improve the responsiveness to timeouts/cancellations.
  */
 static int
-ident_inet(hbaPort *port)
+ident_inet(Port *port)
 {
 	const SockAddr remote_addr = port->raddr;
 	const SockAddr local_addr = port->laddr;
@@ -1853,7 +1853,7 @@ ident_inet(hbaPort *port)
  *	Iff authorized, return STATUS_OK, otherwise return STATUS_ERROR.
  */
 static int
-auth_peer(hbaPort *port)
+auth_peer(Port *port)
 {
 	uid_t		uid;
 	gid_t		gid;
diff --git a/src/backend/libpq/hba.c b/src/backend/libpq/hba.c
index fecee8224d0..97a3586000b 100644
--- a/src/backend/libpq/hba.c
+++ b/src/backend/libpq/hba.c
@@ -1075,7 +1075,7 @@ hostname_match(const char *pattern, const char *actual_hostname)
  * Check to see if a connecting IP matches a given host name.
  */
 static bool
-check_hostname(hbaPort *port, const char *hostname)
+check_hostname(Port *port, const char *hostname)
 {
 	struct addrinfo *gai_result,
 			   *gai;
@@ -2528,7 +2528,7 @@ parse_hba_auth_opt(char *name, char *val, HbaLine *hbaline,
  *	request.
  */
 static void
-check_hba(hbaPort *port)
+check_hba(Port *port)
 {
 	Oid			roleid;
 	ListCell   *line;
@@ -3125,7 +3125,7 @@ load_ident(void)
  *	method = uaImplicitReject.
  */
 void
-hba_getauthmethod(hbaPort *port)
+hba_getauthmethod(Port *port)
 {
 	check_hba(port);
 }
diff --git a/src/include/libpq/hba.h b/src/include/libpq/hba.h
index 3657f182db3..e3748d3c8c9 100644
--- a/src/include/libpq/hba.h
+++ b/src/include/libpq/hba.h
@@ -169,13 +169,13 @@ typedef struct TokenizedAuthLine
 	char	   *err_msg;		/* Error message if any */
 } TokenizedAuthLine;
 
-/* kluge to avoid including libpq/libpq-be.h here */
-typedef struct Port hbaPort;
+/* avoid including libpq/libpq-be.h here */
+typedef struct Port Port;
 
 extern bool load_hba(void);
 extern bool load_ident(void);
 extern const char *hba_authname(UserAuth auth_method);
-extern void hba_getauthmethod(hbaPort *port);
+extern void hba_getauthmethod(Port *port);
 extern int	check_usermap(const char *usermap_name,
 						  const char *pg_user, const char *system_user,
 						  bool case_insensitive);
diff --git a/src/tools/pgindent/typedefs.list b/src/tools/pgindent/typedefs.list
index a13e8162890..9db8e2424c0 100644
--- a/src/tools/pgindent/typedefs.list
+++ b/src/tools/pgindent/typedefs.list
@@ -3687,7 +3687,6 @@ gss_key_value_set_desc
 gss_name_t
 gtrgm_consistent_cache
 gzFile
-hbaPort
 heap_page_items_state
 help_handler
 hlCheck
-- 
2.51.0

v2-0007-Change-fmgr.h-typedefs-to-use-original-names.patchtext/plain; charset=UTF-8; name=v2-0007-Change-fmgr.h-typedefs-to-use-original-names.patchDownload
From d2c46ae200ecd37b59b26fb985bc17a4984cdc3a Mon Sep 17 00:00:00 2001
From: Peter Eisentraut <peter@eisentraut.org>
Date: Fri, 29 Aug 2025 13:18:51 +0200
Subject: [PATCH v2 7/7] Change fmgr.h typedefs to use original names

fmgr.h defined some types such as fmNodePtr which is just Node *, but
it made its own types to avoid having to include various header files.
With C11, we can now instead typedef the original names without fear
of conflicts.

Discussion: https://www.postgresql.org/message-id/flat/10d32190-f31b-40a5-b177-11db55597355@eisentraut.org
---
 src/backend/utils/fmgr/fmgr.c    |  5 ++---
 src/include/fmgr.h               | 30 +++++++++++++++---------------
 src/include/utils/builtins.h     |  2 +-
 src/tools/pgindent/typedefs.list |  4 ----
 4 files changed, 18 insertions(+), 23 deletions(-)

diff --git a/src/backend/utils/fmgr/fmgr.c b/src/backend/utils/fmgr/fmgr.c
index 5543440a33e..b4c1e2c4b21 100644
--- a/src/backend/utils/fmgr/fmgr.c
+++ b/src/backend/utils/fmgr/fmgr.c
@@ -1570,7 +1570,6 @@ InputFunctionCall(FmgrInfo *flinfo, char *str, Oid typioparam, int32 typmod)
  * This is basically like InputFunctionCall, but the converted Datum is
  * returned into *result while the function result is true for success or
  * false for failure.  Also, the caller may pass an ErrorSaveContext node.
- * (We declare that as "fmNodePtr" to avoid including nodes.h in fmgr.h.)
  *
  * If escontext points to an ErrorSaveContext, any "soft" errors detected by
  * the input function will be reported by filling the escontext struct and
@@ -1584,7 +1583,7 @@ InputFunctionCall(FmgrInfo *flinfo, char *str, Oid typioparam, int32 typmod)
 bool
 InputFunctionCallSafe(FmgrInfo *flinfo, char *str,
 					  Oid typioparam, int32 typmod,
-					  fmNodePtr escontext,
+					  Node *escontext,
 					  Datum *result)
 {
 	LOCAL_FCINFO(fcinfo, 3);
@@ -1639,7 +1638,7 @@ InputFunctionCallSafe(FmgrInfo *flinfo, char *str,
 bool
 DirectInputFunctionCallSafe(PGFunction func, char *str,
 							Oid typioparam, int32 typmod,
-							fmNodePtr escontext,
+							Node *escontext,
 							Datum *result)
 {
 	LOCAL_FCINFO(fcinfo, 3);
diff --git a/src/include/fmgr.h b/src/include/fmgr.h
index c7236e42972..74fe3ea0575 100644
--- a/src/include/fmgr.h
+++ b/src/include/fmgr.h
@@ -19,14 +19,14 @@
 #define FMGR_H
 
 /* We don't want to include primnodes.h here, so make some stub references */
-typedef struct Node *fmNodePtr;
-typedef struct Aggref *fmAggrefPtr;
+typedef struct Node Node;
+typedef struct Aggref Aggref;
 
 /* Likewise, avoid including execnodes.h here */
-typedef void (*fmExprContextCallbackFunction) (Datum arg);
+typedef void (*ExprContextCallbackFunction) (Datum arg);
 
 /* Likewise, avoid including stringinfo.h here */
-typedef struct StringInfoData *fmStringInfo;
+typedef struct StringInfoData *StringInfo;
 
 
 /*
@@ -63,7 +63,7 @@ typedef struct FmgrInfo
 	unsigned char fn_stats;		/* collect stats if track_functions > this */
 	void	   *fn_extra;		/* extra space for use by handler */
 	MemoryContext fn_mcxt;		/* memory context to store fn_extra in */
-	fmNodePtr	fn_expr;		/* expression parse tree for call, or NULL */
+	Node	   *fn_expr;		/* expression parse tree for call, or NULL */
 } FmgrInfo;
 
 /*
@@ -85,8 +85,8 @@ typedef struct FmgrInfo
 typedef struct FunctionCallInfoBaseData
 {
 	FmgrInfo   *flinfo;			/* ptr to lookup info used for this call */
-	fmNodePtr	context;		/* pass info about context of call */
-	fmNodePtr	resultinfo;		/* pass or return extra info about result */
+	Node	   *context;		/* pass info about context of call */
+	Node	   *resultinfo;		/* pass or return extra info about result */
 	Oid			fncollation;	/* collation for function to use */
 #define FIELDNO_FUNCTIONCALLINFODATA_ISNULL 4
 	bool		isnull;			/* function must set true if result is NULL */
@@ -742,19 +742,19 @@ extern Datum InputFunctionCall(FmgrInfo *flinfo, char *str,
 							   Oid typioparam, int32 typmod);
 extern bool InputFunctionCallSafe(FmgrInfo *flinfo, char *str,
 								  Oid typioparam, int32 typmod,
-								  fmNodePtr escontext,
+								  Node *escontext,
 								  Datum *result);
 extern bool DirectInputFunctionCallSafe(PGFunction func, char *str,
 										Oid typioparam, int32 typmod,
-										fmNodePtr escontext,
+										Node *escontext,
 										Datum *result);
 extern Datum OidInputFunctionCall(Oid functionId, char *str,
 								  Oid typioparam, int32 typmod);
 extern char *OutputFunctionCall(FmgrInfo *flinfo, Datum val);
 extern char *OidOutputFunctionCall(Oid functionId, Datum val);
-extern Datum ReceiveFunctionCall(FmgrInfo *flinfo, fmStringInfo buf,
+extern Datum ReceiveFunctionCall(FmgrInfo *flinfo, StringInfo buf,
 								 Oid typioparam, int32 typmod);
-extern Datum OidReceiveFunctionCall(Oid functionId, fmStringInfo buf,
+extern Datum OidReceiveFunctionCall(Oid functionId, StringInfo buf,
 									Oid typioparam, int32 typmod);
 extern bytea *SendFunctionCall(FmgrInfo *flinfo, Datum val);
 extern bytea *OidSendFunctionCall(Oid functionId, Datum val);
@@ -767,9 +767,9 @@ extern const Pg_finfo_record *fetch_finfo_record(void *filehandle, const char *f
 extern Oid	fmgr_internal_function(const char *proname);
 extern Oid	get_fn_expr_rettype(FmgrInfo *flinfo);
 extern Oid	get_fn_expr_argtype(FmgrInfo *flinfo, int argnum);
-extern Oid	get_call_expr_argtype(fmNodePtr expr, int argnum);
+extern Oid	get_call_expr_argtype(Node *expr, int argnum);
 extern bool get_fn_expr_arg_stable(FmgrInfo *flinfo, int argnum);
-extern bool get_call_expr_arg_stable(fmNodePtr expr, int argnum);
+extern bool get_call_expr_arg_stable(Node *expr, int argnum);
 extern bool get_fn_expr_variadic(FmgrInfo *flinfo);
 extern bytea *get_fn_opclass_options(FmgrInfo *flinfo);
 extern bool has_fn_opclass_options(FmgrInfo *flinfo);
@@ -814,11 +814,11 @@ extern void RestoreLibraryState(char *start_address);
 
 extern int	AggCheckCallContext(FunctionCallInfo fcinfo,
 								MemoryContext *aggcontext);
-extern fmAggrefPtr AggGetAggref(FunctionCallInfo fcinfo);
+extern Aggref *AggGetAggref(FunctionCallInfo fcinfo);
 extern MemoryContext AggGetTempMemoryContext(FunctionCallInfo fcinfo);
 extern bool AggStateIsShared(FunctionCallInfo fcinfo);
 extern void AggRegisterCallback(FunctionCallInfo fcinfo,
-								fmExprContextCallbackFunction func,
+								ExprContextCallbackFunction func,
 								Datum arg);
 
 /*
diff --git a/src/include/utils/builtins.h b/src/include/utils/builtins.h
index 1c98c7d2255..ce6285a2c03 100644
--- a/src/include/utils/builtins.h
+++ b/src/include/utils/builtins.h
@@ -80,7 +80,7 @@ extern PGDLLIMPORT bool quote_all_identifiers;
 extern const char *quote_identifier(const char *ident);
 extern char *quote_qualified_identifier(const char *qualifier,
 										const char *ident);
-extern void generate_operator_clause(fmStringInfo buf,
+extern void generate_operator_clause(StringInfo buf,
 									 const char *leftop, Oid leftoptype,
 									 Oid opoid,
 									 const char *rightop, Oid rightoptype);
diff --git a/src/tools/pgindent/typedefs.list b/src/tools/pgindent/typedefs.list
index 9db8e2424c0..e90af5b2ad3 100644
--- a/src/tools/pgindent/typedefs.list
+++ b/src/tools/pgindent/typedefs.list
@@ -3635,10 +3635,6 @@ float8
 float8KEY
 floating_decimal_32
 floating_decimal_64
-fmAggrefPtr
-fmExprContextCallbackFunction
-fmNodePtr
-fmStringInfo
 fmgr_hook_type
 foreign_glob_cxt
 foreign_loc_cxt
-- 
2.51.0

#5Chao Li
li.evan.chao@gmail.com
In reply to: Peter Eisentraut (#4)
Re: allow benign typedef redefinitions (C11)

On Sep 10, 2025, at 14:28, Peter Eisentraut <peter@eisentraut.org> wrote:

Thanks. New patch set attached.
<v2-0001-Improve-pgbench-definition-of-yyscan_t.patch><v2-0002-Allow-redeclaration-of-typedef-yyscan_t.patch><v2-0003-Remove-workarounds-against-repeat-typedefs.patch><v2-0004-Improve-ExplainState-type-handling-in-header-file.patch><v2-0005-Update-various-forward-declarations-to-use-typede.patch><v2-0006-Remove-hbaPort-type.patch><v2-0007-Change-fmgr.h-typedefs-to-use-original-names.patch>

v5 looks good to me.

Best regards,
--
Chao Li (Evan)
HighGo Software Co., Ltd.
https://www.highgo.com/

#6Peter Eisentraut
peter@eisentraut.org
In reply to: Chao Li (#5)
Re: allow benign typedef redefinitions (C11)

On 10.09.25 14:08, Chao Li wrote:

On Sep 10, 2025, at 14:28, Peter Eisentraut <peter@eisentraut.org> wrote:

Thanks.  New patch set attached.
<v2-0001-Improve-pgbench-definition-of-yyscan_t.patch><v2-0002-Allow-
redeclaration-of-typedef-yyscan_t.patch><v2-0003-Remove-workarounds-
against-repeat-typedefs.patch><v2-0004-Improve-ExplainState-type-
handling-in-header-file.patch><v2-0005-Update-various-forward-
declarations-to-use-typede.patch><v2-0006-Remove-hbaPort-
type.patch><v2-0007-Change-fmgr.h-typedefs-to-use-original-names.patch>

v5 looks good to me.

Committed, thanks.

#7Álvaro Herrera
alvherre@kurilemu.de
In reply to: Peter Eisentraut (#1)
1 attachment(s)
Re: allow benign typedef redefinitions (C11)

Here's a few more forward struct declarations turned into typedefs, for
cleanliness sake.

struct VacuumCutoffs could use a typedef, by the way ...

--
Álvaro Herrera 48°01'N 7°57'E — https://www.EnterpriseDB.com/
"La espina, desde que nace, ya pincha" (Proverbio africano)

Attachments:

0001-Update-some-more-forward-declarations-to-use-typedef.patchtext/x-diff; charset=utf-8Download
From 7eb407542b034bb8226da1ea7e6891dab99b5730 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=C3=81lvaro=20Herrera?= <alvherre@kurilemu.de>
Date: Wed, 17 Sep 2025 12:38:35 +0200
Subject: [PATCH] Update some more forward declarations to use typedef

As in commit d4d1fc527bdb.
---
 src/backend/access/table/tableam.c |  2 +-
 src/include/access/amapi.h         | 16 ++++----
 src/include/access/brin_internal.h |  6 +--
 src/include/access/genam.h         | 15 ++++----
 src/include/access/heapam.h        | 17 ++++----
 src/include/access/tableam.h       | 62 +++++++++++++++---------------
 src/include/nodes/execnodes.h      | 14 +++----
 7 files changed, 66 insertions(+), 66 deletions(-)

diff --git a/src/backend/access/table/tableam.c b/src/backend/access/table/tableam.c
index a56c5eceb14..5e41404937e 100644
--- a/src/backend/access/table/tableam.c
+++ b/src/backend/access/table/tableam.c
@@ -110,7 +110,7 @@ table_slot_create(Relation relation, List **reglist)
  */
 
 TableScanDesc
-table_beginscan_catalog(Relation relation, int nkeys, struct ScanKeyData *key)
+table_beginscan_catalog(Relation relation, int nkeys, ScanKeyData *key)
 {
 	uint32		flags = SO_TYPE_SEQSCAN |
 		SO_ALLOW_STRAT | SO_ALLOW_SYNC | SO_ALLOW_PAGEMODE | SO_TEMP_SNAPSHOT;
diff --git a/src/include/access/amapi.h b/src/include/access/amapi.h
index 70949de56ac..2b4482dc1e6 100644
--- a/src/include/access/amapi.h
+++ b/src/include/access/amapi.h
@@ -21,11 +21,11 @@
  * AM's implementation isn't concerned with those data structures.  To allow
  * declaring amcostestimate_function here, use forward struct references.
  */
-struct PlannerInfo;
-struct IndexPath;
+typedef struct PlannerInfo PlannerInfo;
+typedef struct IndexPath IndexPath;
 
 /* Likewise, this file shouldn't depend on execnodes.h. */
-struct IndexInfo;
+typedef struct IndexInfo IndexInfo;
 
 
 /*
@@ -110,7 +110,7 @@ typedef StrategyNumber (*amtranslate_cmptype_function) (CompareType cmptype, Oid
 /* build new index */
 typedef IndexBuildResult *(*ambuild_function) (Relation heapRelation,
 											   Relation indexRelation,
-											   struct IndexInfo *indexInfo);
+											   IndexInfo *indexInfo);
 
 /* build empty index */
 typedef void (*ambuildempty_function) (Relation indexRelation);
@@ -123,11 +123,11 @@ typedef bool (*aminsert_function) (Relation indexRelation,
 								   Relation heapRelation,
 								   IndexUniqueCheck checkUnique,
 								   bool indexUnchanged,
-								   struct IndexInfo *indexInfo);
+								   IndexInfo *indexInfo);
 
 /* cleanup after insert */
 typedef void (*aminsertcleanup_function) (Relation indexRelation,
-										  struct IndexInfo *indexInfo);
+										  IndexInfo *indexInfo);
 
 /* bulk delete */
 typedef IndexBulkDeleteResult *(*ambulkdelete_function) (IndexVacuumInfo *info,
@@ -143,8 +143,8 @@ typedef IndexBulkDeleteResult *(*amvacuumcleanup_function) (IndexVacuumInfo *inf
 typedef bool (*amcanreturn_function) (Relation indexRelation, int attno);
 
 /* estimate cost of an indexscan */
-typedef void (*amcostestimate_function) (struct PlannerInfo *root,
-										 struct IndexPath *path,
+typedef void (*amcostestimate_function) (PlannerInfo *root,
+										 IndexPath *path,
 										 double loop_count,
 										 Cost *indexStartupCost,
 										 Cost *indexTotalCost,
diff --git a/src/include/access/brin_internal.h b/src/include/access/brin_internal.h
index d093a0bf130..452c646a088 100644
--- a/src/include/access/brin_internal.h
+++ b/src/include/access/brin_internal.h
@@ -89,14 +89,14 @@ typedef struct BrinDesc
 extern BrinDesc *brin_build_desc(Relation rel);
 extern void brin_free_desc(BrinDesc *bdesc);
 extern IndexBuildResult *brinbuild(Relation heap, Relation index,
-								   struct IndexInfo *indexInfo);
+								   IndexInfo *indexInfo);
 extern void brinbuildempty(Relation index);
 extern bool brininsert(Relation idxRel, Datum *values, bool *nulls,
 					   ItemPointer heaptid, Relation heapRel,
 					   IndexUniqueCheck checkUnique,
 					   bool indexUnchanged,
-					   struct IndexInfo *indexInfo);
-extern void brininsertcleanup(Relation index, struct IndexInfo *indexInfo);
+					   IndexInfo *indexInfo);
+extern void brininsertcleanup(Relation index, IndexInfo *indexInfo);
 extern IndexScanDesc brinbeginscan(Relation r, int nkeys, int norderbys);
 extern int64 bringetbitmap(IndexScanDesc scan, TIDBitmap *tbm);
 extern void brinrescan(IndexScanDesc scan, ScanKey scankey, int nscankeys,
diff --git a/src/include/access/genam.h b/src/include/access/genam.h
index 5b2ab181b5f..a43f6c78ee4 100644
--- a/src/include/access/genam.h
+++ b/src/include/access/genam.h
@@ -23,8 +23,10 @@
 #include "utils/relcache.h"
 #include "utils/snapshot.h"
 
-/* We don't want this file to depend on execnodes.h. */
-struct IndexInfo;
+/* forward references in this file */
+typedef struct IndexInfo IndexInfo;
+typedef struct TupleTableSlot TupleTableSlot;
+
 
 /*
  * Struct for statistics maintained by amgettuple and amgetbitmap
@@ -171,9 +173,9 @@ extern bool index_insert(Relation indexRelation,
 						 Relation heapRelation,
 						 IndexUniqueCheck checkUnique,
 						 bool indexUnchanged,
-						 struct IndexInfo *indexInfo);
+						 IndexInfo *indexInfo);
 extern void index_insert_cleanup(Relation indexRelation,
-								 struct IndexInfo *indexInfo);
+								 IndexInfo *indexInfo);
 
 extern IndexScanDesc index_beginscan(Relation heapRelation,
 									 Relation indexRelation,
@@ -208,10 +210,9 @@ extern IndexScanDesc index_beginscan_parallel(Relation heaprel,
 											  ParallelIndexScanDesc pscan);
 extern ItemPointer index_getnext_tid(IndexScanDesc scan,
 									 ScanDirection direction);
-struct TupleTableSlot;
-extern bool index_fetch_heap(IndexScanDesc scan, struct TupleTableSlot *slot);
+extern bool index_fetch_heap(IndexScanDesc scan, TupleTableSlot *slot);
 extern bool index_getnext_slot(IndexScanDesc scan, ScanDirection direction,
-							   struct TupleTableSlot *slot);
+							   TupleTableSlot *slot);
 extern int64 index_getbitmap(IndexScanDesc scan, TIDBitmap *bitmap);
 
 extern IndexBulkDeleteResult *index_bulk_delete(IndexVacuumInfo *info,
diff --git a/src/include/access/heapam.h b/src/include/access/heapam.h
index a2bd5a897f8..592ed0827fe 100644
--- a/src/include/access/heapam.h
+++ b/src/include/access/heapam.h
@@ -44,7 +44,7 @@
 #define HEAP_PAGE_PRUNE_FREEZE				(1 << 1)
 
 typedef struct BulkInsertStateData *BulkInsertState;
-struct TupleTableSlot;
+typedef struct GlobalVisState GlobalVisState;
 struct VacuumCutoffs;
 
 #define MaxLockTupleMode	LockTupleExclusive
@@ -298,7 +298,7 @@ extern void heap_rescan(TableScanDesc sscan, ScanKey key, bool set_params,
 extern void heap_endscan(TableScanDesc sscan);
 extern HeapTuple heap_getnext(TableScanDesc sscan, ScanDirection direction);
 extern bool heap_getnextslot(TableScanDesc sscan,
-							 ScanDirection direction, struct TupleTableSlot *slot);
+							 ScanDirection direction, TupleTableSlot *slot);
 extern void heap_set_tidrange(TableScanDesc sscan, ItemPointer mintid,
 							  ItemPointer maxtid);
 extern bool heap_getnextslot_tidrange(TableScanDesc sscan,
@@ -318,23 +318,23 @@ extern void ReleaseBulkInsertStatePin(BulkInsertState bistate);
 
 extern void heap_insert(Relation relation, HeapTuple tup, CommandId cid,
 						int options, BulkInsertState bistate);
-extern void heap_multi_insert(Relation relation, struct TupleTableSlot **slots,
+extern void heap_multi_insert(Relation relation, TupleTableSlot **slots,
 							  int ntuples, CommandId cid, int options,
 							  BulkInsertState bistate);
 extern TM_Result heap_delete(Relation relation, ItemPointer tid,
 							 CommandId cid, Snapshot crosscheck, bool wait,
-							 struct TM_FailureData *tmfd, bool changingPart);
+							 TM_FailureData *tmfd, bool changingPart);
 extern void heap_finish_speculative(Relation relation, ItemPointer tid);
 extern void heap_abort_speculative(Relation relation, ItemPointer tid);
 extern TM_Result heap_update(Relation relation, ItemPointer otid,
 							 HeapTuple newtup,
 							 CommandId cid, Snapshot crosscheck, bool wait,
-							 struct TM_FailureData *tmfd, LockTupleMode *lockmode,
+							 TM_FailureData *tmfd, LockTupleMode *lockmode,
 							 TU_UpdateIndexes *update_indexes);
 extern TM_Result heap_lock_tuple(Relation relation, HeapTuple tuple,
 								 CommandId cid, LockTupleMode mode, LockWaitPolicy wait_policy,
 								 bool follow_updates,
-								 Buffer *buffer, struct TM_FailureData *tmfd);
+								 Buffer *buffer, TM_FailureData *tmfd);
 
 extern bool heap_inplace_lock(Relation relation,
 							  HeapTuple oldtup_ptr, Buffer buffer,
@@ -371,10 +371,9 @@ extern TransactionId heap_index_delete_tuples(Relation rel,
 											  TM_IndexDeleteOp *delstate);
 
 /* in heap/pruneheap.c */
-struct GlobalVisState;
 extern void heap_page_prune_opt(Relation relation, Buffer buffer);
 extern void heap_page_prune_and_freeze(Relation relation, Buffer buffer,
-									   struct GlobalVisState *vistest,
+									   GlobalVisState *vistest,
 									   int options,
 									   struct VacuumCutoffs *cutoffs,
 									   PruneFreezeResult *presult,
@@ -413,7 +412,7 @@ extern void HeapTupleSetHintBits(HeapTupleHeader tuple, Buffer buffer,
 								 uint16 infomask, TransactionId xid);
 extern bool HeapTupleHeaderIsOnlyLocked(HeapTupleHeader tuple);
 extern bool HeapTupleIsSurelyDead(HeapTuple htup,
-								  struct GlobalVisState *vistest);
+								  GlobalVisState *vistest);
 
 /*
  * To avoid leaking too much knowledge about reorderbuffer implementation
diff --git a/src/include/access/tableam.h b/src/include/access/tableam.h
index b2ce35e2a34..ce097d61d3c 100644
--- a/src/include/access/tableam.h
+++ b/src/include/access/tableam.h
@@ -34,10 +34,11 @@ extern PGDLLIMPORT char *default_table_access_method;
 extern PGDLLIMPORT bool synchronize_seqscans;
 
 
-struct BulkInsertStateData;
-struct IndexInfo;
-struct SampleScanState;
-struct ValidateIndexState;
+/* forward references in this file */
+typedef struct BulkInsertStateData BulkInsertStateData;
+typedef struct IndexInfo IndexInfo;
+typedef struct SampleScanState SampleScanState;
+typedef struct ValidateIndexState ValidateIndexState;
 
 /*
  * Bitmask values for the flags argument to the scan_begin callback.
@@ -325,7 +326,7 @@ typedef struct TableAmRoutine
 	 */
 	TableScanDesc (*scan_begin) (Relation rel,
 								 Snapshot snapshot,
-								 int nkeys, struct ScanKeyData *key,
+								 int nkeys, ScanKeyData *key,
 								 ParallelTableScanDesc pscan,
 								 uint32 flags);
 
@@ -339,7 +340,7 @@ typedef struct TableAmRoutine
 	 * Restart relation scan.  If set_params is set to true, allow_{strat,
 	 * sync, pagemode} (see scan_begin) changes should be taken into account.
 	 */
-	void		(*scan_rescan) (TableScanDesc scan, struct ScanKeyData *key,
+	void		(*scan_rescan) (TableScanDesc scan, ScanKeyData *key,
 								bool set_params, bool allow_strat,
 								bool allow_sync, bool allow_pagemode);
 
@@ -508,14 +509,14 @@ typedef struct TableAmRoutine
 	/* see table_tuple_insert() for reference about parameters */
 	void		(*tuple_insert) (Relation rel, TupleTableSlot *slot,
 								 CommandId cid, int options,
-								 struct BulkInsertStateData *bistate);
+								 BulkInsertStateData *bistate);
 
 	/* see table_tuple_insert_speculative() for reference about parameters */
 	void		(*tuple_insert_speculative) (Relation rel,
 											 TupleTableSlot *slot,
 											 CommandId cid,
 											 int options,
-											 struct BulkInsertStateData *bistate,
+											 BulkInsertStateData *bistate,
 											 uint32 specToken);
 
 	/* see table_tuple_complete_speculative() for reference about parameters */
@@ -526,7 +527,7 @@ typedef struct TableAmRoutine
 
 	/* see table_multi_insert() for reference about parameters */
 	void		(*multi_insert) (Relation rel, TupleTableSlot **slots, int nslots,
-								 CommandId cid, int options, struct BulkInsertStateData *bistate);
+								 CommandId cid, int options, BulkInsertStateData *bistate);
 
 	/* see table_tuple_delete() for reference about parameters */
 	TM_Result	(*tuple_delete) (Relation rel,
@@ -690,7 +691,7 @@ typedef struct TableAmRoutine
 	/* see table_index_build_range_scan for reference about parameters */
 	double		(*index_build_range_scan) (Relation table_rel,
 										   Relation index_rel,
-										   struct IndexInfo *index_info,
+										   IndexInfo *index_info,
 										   bool allow_sync,
 										   bool anyvisible,
 										   bool progress,
@@ -703,9 +704,9 @@ typedef struct TableAmRoutine
 	/* see table_index_validate_scan for reference about parameters */
 	void		(*index_validate_scan) (Relation table_rel,
 										Relation index_rel,
-										struct IndexInfo *index_info,
+										IndexInfo *index_info,
 										Snapshot snapshot,
-										struct ValidateIndexState *state);
+										ValidateIndexState *state);
 
 
 	/* ------------------------------------------------------------------------
@@ -821,7 +822,7 @@ typedef struct TableAmRoutine
 	 * scans. If infeasible to implement, the AM may raise an error.
 	 */
 	bool		(*scan_sample_next_block) (TableScanDesc scan,
-										   struct SampleScanState *scanstate);
+										   SampleScanState *scanstate);
 
 	/*
 	 * This callback, only called after scan_sample_next_block has returned
@@ -837,7 +838,7 @@ typedef struct TableAmRoutine
 	 * assumption somehow.
 	 */
 	bool		(*scan_sample_next_tuple) (TableScanDesc scan,
-										   struct SampleScanState *scanstate,
+										   SampleScanState *scanstate,
 										   TupleTableSlot *slot);
 
 } TableAmRoutine;
@@ -873,7 +874,7 @@ extern TupleTableSlot *table_slot_create(Relation relation, List **reglist);
  */
 static inline TableScanDesc
 table_beginscan(Relation rel, Snapshot snapshot,
-				int nkeys, struct ScanKeyData *key)
+				int nkeys, ScanKeyData *key)
 {
 	uint32		flags = SO_TYPE_SEQSCAN |
 		SO_ALLOW_STRAT | SO_ALLOW_SYNC | SO_ALLOW_PAGEMODE;
@@ -886,7 +887,7 @@ table_beginscan(Relation rel, Snapshot snapshot,
  * snapshot appropriate for scanning catalog relations.
  */
 extern TableScanDesc table_beginscan_catalog(Relation relation, int nkeys,
-											 struct ScanKeyData *key);
+											 ScanKeyData *key);
 
 /*
  * Like table_beginscan(), but table_beginscan_strat() offers an extended API
@@ -897,7 +898,7 @@ extern TableScanDesc table_beginscan_catalog(Relation relation, int nkeys,
  */
 static inline TableScanDesc
 table_beginscan_strat(Relation rel, Snapshot snapshot,
-					  int nkeys, struct ScanKeyData *key,
+					  int nkeys, ScanKeyData *key,
 					  bool allow_strat, bool allow_sync)
 {
 	uint32		flags = SO_TYPE_SEQSCAN | SO_ALLOW_PAGEMODE;
@@ -918,7 +919,7 @@ table_beginscan_strat(Relation rel, Snapshot snapshot,
  */
 static inline TableScanDesc
 table_beginscan_bm(Relation rel, Snapshot snapshot,
-				   int nkeys, struct ScanKeyData *key)
+				   int nkeys, ScanKeyData *key)
 {
 	uint32		flags = SO_TYPE_BITMAPSCAN | SO_ALLOW_PAGEMODE;
 
@@ -935,7 +936,7 @@ table_beginscan_bm(Relation rel, Snapshot snapshot,
  */
 static inline TableScanDesc
 table_beginscan_sampling(Relation rel, Snapshot snapshot,
-						 int nkeys, struct ScanKeyData *key,
+						 int nkeys, ScanKeyData *key,
 						 bool allow_strat, bool allow_sync,
 						 bool allow_pagemode)
 {
@@ -990,8 +991,7 @@ table_endscan(TableScanDesc scan)
  * Restart a relation scan.
  */
 static inline void
-table_rescan(TableScanDesc scan,
-			 struct ScanKeyData *key)
+table_rescan(TableScanDesc scan, ScanKeyData *key)
 {
 	scan->rs_rd->rd_tableam->scan_rescan(scan, key, false, false, false, false);
 }
@@ -1005,7 +1005,7 @@ table_rescan(TableScanDesc scan,
  * previously selected startblock will be kept.
  */
 static inline void
-table_rescan_set_params(TableScanDesc scan, struct ScanKeyData *key,
+table_rescan_set_params(TableScanDesc scan, ScanKeyData *key,
 						bool allow_strat, bool allow_sync, bool allow_pagemode)
 {
 	scan->rs_rd->rd_tableam->scan_rescan(scan, key, true,
@@ -1365,7 +1365,7 @@ table_index_delete_tuples(Relation rel, TM_IndexDeleteOp *delstate)
  */
 static inline void
 table_tuple_insert(Relation rel, TupleTableSlot *slot, CommandId cid,
-				   int options, struct BulkInsertStateData *bistate)
+				   int options, BulkInsertStateData *bistate)
 {
 	rel->rd_tableam->tuple_insert(rel, slot, cid, options,
 								  bistate);
@@ -1385,7 +1385,7 @@ table_tuple_insert(Relation rel, TupleTableSlot *slot, CommandId cid,
 static inline void
 table_tuple_insert_speculative(Relation rel, TupleTableSlot *slot,
 							   CommandId cid, int options,
-							   struct BulkInsertStateData *bistate,
+							   BulkInsertStateData *bistate,
 							   uint32 specToken)
 {
 	rel->rd_tableam->tuple_insert_speculative(rel, slot, cid, options,
@@ -1420,7 +1420,7 @@ table_tuple_complete_speculative(Relation rel, TupleTableSlot *slot,
  */
 static inline void
 table_multi_insert(Relation rel, TupleTableSlot **slots, int nslots,
-				   CommandId cid, int options, struct BulkInsertStateData *bistate)
+				   CommandId cid, int options, BulkInsertStateData *bistate)
 {
 	rel->rd_tableam->multi_insert(rel, slots, nslots,
 								  cid, options, bistate);
@@ -1741,7 +1741,7 @@ table_scan_analyze_next_tuple(TableScanDesc scan, TransactionId OldestXmin,
 static inline double
 table_index_build_scan(Relation table_rel,
 					   Relation index_rel,
-					   struct IndexInfo *index_info,
+					   IndexInfo *index_info,
 					   bool allow_sync,
 					   bool progress,
 					   IndexBuildCallback callback,
@@ -1774,7 +1774,7 @@ table_index_build_scan(Relation table_rel,
 static inline double
 table_index_build_range_scan(Relation table_rel,
 							 Relation index_rel,
-							 struct IndexInfo *index_info,
+							 IndexInfo *index_info,
 							 bool allow_sync,
 							 bool anyvisible,
 							 bool progress,
@@ -1805,9 +1805,9 @@ table_index_build_range_scan(Relation table_rel,
 static inline void
 table_index_validate_scan(Relation table_rel,
 						  Relation index_rel,
-						  struct IndexInfo *index_info,
+						  IndexInfo *index_info,
 						  Snapshot snapshot,
-						  struct ValidateIndexState *state)
+						  ValidateIndexState *state)
 {
 	table_rel->rd_tableam->index_validate_scan(table_rel,
 											   index_rel,
@@ -1961,7 +1961,7 @@ table_scan_bitmap_next_tuple(TableScanDesc scan,
  */
 static inline bool
 table_scan_sample_next_block(TableScanDesc scan,
-							 struct SampleScanState *scanstate)
+							 SampleScanState *scanstate)
 {
 	/*
 	 * We don't expect direct calls to table_scan_sample_next_block with valid
@@ -1983,7 +1983,7 @@ table_scan_sample_next_block(TableScanDesc scan,
  */
 static inline bool
 table_scan_sample_next_tuple(TableScanDesc scan,
-							 struct SampleScanState *scanstate,
+							 SampleScanState *scanstate,
 							 TupleTableSlot *slot)
 {
 	/*
diff --git a/src/include/nodes/execnodes.h b/src/include/nodes/execnodes.h
index 3a920cc7d17..a36653c37f9 100644
--- a/src/include/nodes/execnodes.h
+++ b/src/include/nodes/execnodes.h
@@ -1656,14 +1656,14 @@ typedef struct SampleScanState
  */
 typedef struct
 {
-	struct ScanKeyData *scan_key;	/* scankey to put value into */
+	ScanKeyData *scan_key;		/* scankey to put value into */
 	ExprState  *key_expr;		/* expr to evaluate to get value */
 	bool		key_toastable;	/* is expr's result a toastable datatype? */
 } IndexRuntimeKeyInfo;
 
 typedef struct
 {
-	struct ScanKeyData *scan_key;	/* scankey to put value into */
+	ScanKeyData *scan_key;		/* scankey to put value into */
 	ExprState  *array_expr;		/* expr to evaluate to get array value */
 	int			next_elem;		/* next array element to use */
 	int			num_elems;		/* number of elems in current array value */
@@ -1704,9 +1704,9 @@ typedef struct IndexScanState
 	ScanState	ss;				/* its first field is NodeTag */
 	ExprState  *indexqualorig;
 	List	   *indexorderbyorig;
-	struct ScanKeyData *iss_ScanKeys;
+	ScanKeyData *iss_ScanKeys;
 	int			iss_NumScanKeys;
-	struct ScanKeyData *iss_OrderByKeys;
+	ScanKeyData *iss_OrderByKeys;
 	int			iss_NumOrderByKeys;
 	IndexRuntimeKeyInfo *iss_RuntimeKeys;
 	int			iss_NumRuntimeKeys;
@@ -1755,9 +1755,9 @@ typedef struct IndexOnlyScanState
 {
 	ScanState	ss;				/* its first field is NodeTag */
 	ExprState  *recheckqual;
-	struct ScanKeyData *ioss_ScanKeys;
+	ScanKeyData *ioss_ScanKeys;
 	int			ioss_NumScanKeys;
-	struct ScanKeyData *ioss_OrderByKeys;
+	ScanKeyData *ioss_OrderByKeys;
 	int			ioss_NumOrderByKeys;
 	IndexRuntimeKeyInfo *ioss_RuntimeKeys;
 	int			ioss_NumRuntimeKeys;
@@ -1796,7 +1796,7 @@ typedef struct BitmapIndexScanState
 {
 	ScanState	ss;				/* its first field is NodeTag */
 	TIDBitmap  *biss_result;
-	struct ScanKeyData *biss_ScanKeys;
+	ScanKeyData *biss_ScanKeys;
 	int			biss_NumScanKeys;
 	IndexRuntimeKeyInfo *biss_RuntimeKeys;
 	int			biss_NumRuntimeKeys;
-- 
2.47.3

#8Álvaro Herrera
alvherre@kurilemu.de
In reply to: Álvaro Herrera (#7)
1 attachment(s)
Re: allow benign typedef redefinitions (C11)

I happened to realize that brin_tuple.h (a somewhat nasty header which
was only supposed to be used by BRIN itself and stuff like amcheck)
recently somehow snuck into tuplesort.h with some nefarious
consequences: that one has polluted execnodes.h, which means that header
now depends on struct definitions that appear in genam.h. We should fix
this. This patch is not the full solution, just a way to show the
problem; for a definitive solution, IMO the definitions of structs
IndexScanInstrumentation and SharedIndexScanInstrumentation should be
elsewhere so that execnodes.h doesn't have to include genam.h.

(gin_tuple.h is also there, but that one's much less of a problem.)

Oh, and replication/conflict.h including all of execnodes.h is kind of
ridiculous. Looks like that's easily solved with something like this
though:

diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index f402b17295c..7bcb4c68e18 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -11,6 +11,7 @@
 #ifndef PGSTAT_H
 #define PGSTAT_H
+#include "access/transam.h"
 #include "datatype/timestamp.h"
 #include "portability/instr_time.h"
 #include "postmaster/pgarch.h" /* for MAX_XFN_CHARS */
diff --git a/src/include/replication/conflict.h b/src/include/replication/conflict.h
index e516caa5c73..e71b3c8f3d3 100644
--- a/src/include/replication/conflict.h
+++ b/src/include/replication/conflict.h
@@ -9,9 +9,14 @@
 #ifndef CONFLICT_H
 #define CONFLICT_H
-#include "nodes/execnodes.h"
+#include "access/xlogdefs.h"
+#include "nodes/pg_list.h"
 #include "utils/timestamp.h"
+typedef struct EState EState;
+typedef struct ResultRelInfo ResultRelInfo;
+typedef struct TupleTableSlot TupleTableSlot;
+
 /*
  * Conflict types that could occur while applying remote changes.
  *

--
Álvaro Herrera PostgreSQL Developer — https://www.EnterpriseDB.com/
"La espina, desde que nace, ya pincha" (Proverbio africano)

Attachments:

nobrintuple.patchtext/x-diff; charset=utf-8Download
diff --git a/src/backend/access/gin/gininsert.c b/src/backend/access/gin/gininsert.c
index e9d4b27427e..43c007b6204 100644
--- a/src/backend/access/gin/gininsert.c
+++ b/src/backend/access/gin/gininsert.c
@@ -29,10 +29,11 @@
 #include "storage/bufmgr.h"
 #include "storage/predicate.h"
 #include "tcop/tcopprot.h"
+#include "utils/builtins.h"
 #include "utils/datum.h"
 #include "utils/memutils.h"
 #include "utils/rel.h"
-#include "utils/builtins.h"
+#include "utils/typcache.h"
 
 
 /* Magic numbers for parallel state sharing */
diff --git a/src/backend/executor/execReplication.c b/src/backend/executor/execReplication.c
index b409d4ecbf5..ab585aa9819 100644
--- a/src/backend/executor/execReplication.c
+++ b/src/backend/executor/execReplication.c
@@ -14,6 +14,7 @@
 
 #include "postgres.h"
 
+#include "access/amapi.h"
 #include "access/commit_ts.h"
 #include "access/genam.h"
 #include "access/gist.h"
diff --git a/src/backend/parser/parse_expr.c b/src/backend/parser/parse_expr.c
index e1979a80c19..eebea694dda 100644
--- a/src/backend/parser/parse_expr.c
+++ b/src/backend/parser/parse_expr.c
@@ -37,6 +37,7 @@
 #include "utils/fmgroids.h"
 #include "utils/lsyscache.h"
 #include "utils/timestamp.h"
+#include "utils/typcache.h"
 #include "utils/xml.h"
 
 /* GUC parameters */
diff --git a/src/backend/replication/logical/relation.c b/src/backend/replication/logical/relation.c
index f59046ad620..85f55b75c66 100644
--- a/src/backend/replication/logical/relation.c
+++ b/src/backend/replication/logical/relation.c
@@ -29,6 +29,7 @@
 #include "utils/inval.h"
 #include "utils/lsyscache.h"
 #include "utils/syscache.h"
+#include "utils/typcache.h"
 
 
 static MemoryContext LogicalRepRelMapContext = NULL;
diff --git a/src/backend/statistics/attribute_stats.c b/src/backend/statistics/attribute_stats.c
index 1db6a7f784c..4e8efcdf55b 100644
--- a/src/backend/statistics/attribute_stats.c
+++ b/src/backend/statistics/attribute_stats.c
@@ -29,6 +29,7 @@
 #include "utils/fmgroids.h"
 #include "utils/lsyscache.h"
 #include "utils/syscache.h"
+#include "utils/typcache.h"
 
 #define DEFAULT_NULL_FRAC      Float4GetDatum(0.0)
 #define DEFAULT_AVG_WIDTH      Int32GetDatum(0) /* unknown */
diff --git a/src/include/nodes/execnodes.h b/src/include/nodes/execnodes.h
index daa6c44a9ac..b72084b7aaa 100644
--- a/src/include/nodes/execnodes.h
+++ b/src/include/nodes/execnodes.h
@@ -29,6 +29,7 @@
 #ifndef EXECNODES_H
 #define EXECNODES_H
 
+#include "access/genam.h"		/* FIXME */
 #include "access/tupconvert.h"
 #include "executor/instrument.h"
 #include "fmgr.h"
@@ -59,6 +60,10 @@ struct ExprEvalStep;			/* avoid including execExpr.h everywhere */
 struct CopyMultiInsertBuffer;
 struct LogicalTapeSet;
 
+typedef struct ScanKeyData ScanKeyData;
+typedef struct SharedIndexScanInstrumentation SharedIndexScanInstrumentation;
+typedef struct IndexScanInstrumentation IndexScanInstrumentation;
+
 
 /* ----------------
  *		ExprState node
diff --git a/src/include/utils/tuplesort.h b/src/include/utils/tuplesort.h
index ef79f259f93..38821b5cdbb 100644
--- a/src/include/utils/tuplesort.h
+++ b/src/include/utils/tuplesort.h
@@ -21,7 +21,6 @@
 #ifndef TUPLESORT_H
 #define TUPLESORT_H
 
-#include "access/brin_tuple.h"
 #include "access/gin_tuple.h"
 #include "access/itup.h"
 #include "executor/tuptable.h"
@@ -38,6 +37,9 @@
 typedef struct Tuplesortstate Tuplesortstate;
 typedef struct Sharedsort Sharedsort;
 
+/* avoid including brin_tuple.h here */
+typedef struct BrinTuple BrinTuple;
+
 /*
  * Tuplesort parallel coordination state, allocated by each participant in
  * local memory.  Participant caller initializes everything.  See usage notes
#9Tom Lane
tgl@sss.pgh.pa.us
In reply to: Álvaro Herrera (#8)
Re: allow benign typedef redefinitions (C11)

=?utf-8?Q?=C3=81lvaro?= Herrera <alvherre@kurilemu.de> writes:

Oh, and replication/conflict.h including all of execnodes.h is kind of
ridiculous.

Sooner or later we need to work out a subsystem hierarchy that
can define which headers should be allowed to include which
other ones. I have no clear ideas about what that should look
like, but I think the need for it gets ever more urgent.

regards, tom lane

#10Álvaro Herrera
alvherre@kurilemu.de
In reply to: Tom Lane (#9)
1 attachment(s)
Re: allow benign typedef redefinitions (C11)

On 2025-Sep-19, Tom Lane wrote:

Sooner or later we need to work out a subsystem hierarchy that
can define which headers should be allowed to include which
other ones. I have no clear ideas about what that should look
like, but I think the need for it gets ever more urgent.

I agree, we should do that. In the meantime, it would help if people
were a tiny bit more careful with what headers they add to other
headers.

Here's a proposed fix.

--
Álvaro Herrera PostgreSQL Developer — https://www.EnterpriseDB.com/
<Schwern> It does it in a really, really complicated way
<crab> why does it need to be complicated?
<Schwern> Because it's MakeMaker.

Attachments:

0001-Don-t-include-execnodes.h-in-replication-conflict.h.patchtext/x-diff; charset=utf-8Download
From 6a5170aea0f0c0e783b681537b077a2d7de51537 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=C3=81lvaro=20Herrera?= <alvherre@kurilemu.de>
Date: Sat, 20 Sep 2025 15:07:58 +0200
Subject: [PATCH] Don't include execnodes.h in replication/conflict.h

... which silently propagates a lot of headers into many places
via pgstat.h, as evidenced by the variety of headers that this patch
needs to add to seemingly random places.  Add a minimum of typedefs to
conflict.h to be able to remove execnodes.h, and fix the fallout.

Discussion: https://postgr.es/m/202509191927.uj2ijwmho7nv@alvherre.pgsql
---
 src/backend/access/transam/multixact.c      | 1 +
 src/backend/access/transam/xlogrecovery.c   | 1 +
 src/backend/storage/ipc/waiteventset.c      | 1 +
 src/backend/utils/activity/pgstat_backend.c | 1 +
 src/include/pgstat.h                        | 1 +
 src/include/replication/conflict.h          | 9 ++++++++-
 6 files changed, 13 insertions(+), 1 deletion(-)

diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c
index 8bf59d369f8..9d5f130af7e 100644
--- a/src/backend/access/transam/multixact.c
+++ b/src/backend/access/transam/multixact.c
@@ -79,6 +79,7 @@
 #include "pg_trace.h"
 #include "pgstat.h"
 #include "postmaster/autovacuum.h"
+#include "storage/condition_variable.h"
 #include "storage/pmsignal.h"
 #include "storage/proc.h"
 #include "storage/procarray.h"
diff --git a/src/backend/access/transam/xlogrecovery.c b/src/backend/access/transam/xlogrecovery.c
index 346319338a0..52ff4d119e6 100644
--- a/src/backend/access/transam/xlogrecovery.c
+++ b/src/backend/access/transam/xlogrecovery.c
@@ -45,6 +45,7 @@
 #include "commands/tablespace.h"
 #include "common/file_utils.h"
 #include "miscadmin.h"
+#include "nodes/miscnodes.h"
 #include "pgstat.h"
 #include "postmaster/bgwriter.h"
 #include "postmaster/startup.h"
diff --git a/src/backend/storage/ipc/waiteventset.c b/src/backend/storage/ipc/waiteventset.c
index 7c0e66900f9..b0746521ae4 100644
--- a/src/backend/storage/ipc/waiteventset.c
+++ b/src/backend/storage/ipc/waiteventset.c
@@ -67,6 +67,7 @@
 #include "libpq/pqsignal.h"
 #include "miscadmin.h"
 #include "pgstat.h"
+#include "port/atomics.h"
 #include "portability/instr_time.h"
 #include "postmaster/postmaster.h"
 #include "storage/fd.h"
diff --git a/src/backend/utils/activity/pgstat_backend.c b/src/backend/utils/activity/pgstat_backend.c
index 07a1116671b..a864ae8e6a6 100644
--- a/src/backend/utils/activity/pgstat_backend.c
+++ b/src/backend/utils/activity/pgstat_backend.c
@@ -25,6 +25,7 @@
 #include "postgres.h"
 
 #include "access/xlog.h"
+#include "executor/instrument.h"
 #include "storage/bufmgr.h"
 #include "storage/proc.h"
 #include "storage/procarray.h"
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index f402b17295c..e4a59a30b8c 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -11,6 +11,7 @@
 #ifndef PGSTAT_H
 #define PGSTAT_H
 
+#include "access/transam.h"		/* for FullTransactionId */
 #include "datatype/timestamp.h"
 #include "portability/instr_time.h"
 #include "postmaster/pgarch.h"	/* for MAX_XFN_CHARS */
diff --git a/src/include/replication/conflict.h b/src/include/replication/conflict.h
index e516caa5c73..c8fbf9e51b8 100644
--- a/src/include/replication/conflict.h
+++ b/src/include/replication/conflict.h
@@ -9,9 +9,16 @@
 #ifndef CONFLICT_H
 #define CONFLICT_H
 
-#include "nodes/execnodes.h"
+#include "access/xlogdefs.h"
+#include "nodes/pg_list.h"
 #include "utils/timestamp.h"
 
+/* Avoid including execnodes.h here */
+typedef struct EState EState;
+typedef struct ResultRelInfo ResultRelInfo;
+typedef struct TupleTableSlot TupleTableSlot;
+
+
 /*
  * Conflict types that could occur while applying remote changes.
  *
-- 
2.47.3

#11Tom Lane
tgl@sss.pgh.pa.us
In reply to: Álvaro Herrera (#10)
Re: allow benign typedef redefinitions (C11)

=?utf-8?Q?=C3=81lvaro?= Herrera <alvherre@kurilemu.de> writes:

Here's a proposed fix.

I didn't test this, but it passes an eyeball sanity check
and looks like an improvement overall.

regards, tom lane

#12Peter Eisentraut
peter@eisentraut.org
In reply to: Álvaro Herrera (#7)
Re: allow benign typedef redefinitions (C11)

On 19.09.25 12:52, Álvaro Herrera wrote:

Here's a few more forward struct declarations turned into typedefs, for
cleanliness sake.

Two comments; the rest looks okay to me.

* src/include/access/heapam.h

You are removing the declaration of struct TupleTableSlot and then go
on to use just TupleTableSlot; apparently that works, but that creates
an implicit dependency on typedef TupleTableSlot from somewhere else.
It might be better to change the existing struct TupleTableSlot
declaration into a typedef and keep it.

* src/include/nodes/execnodes.h

In this file, you are changing several times struct ScanKeyData to
just ScanKeyData, but there is no typedef of ScanKeyData in this file.
The struct ScanKeyData can exist by itself (it becomes declared as
soon as you use it), but the typedef needs to come from somewhere. So
this change introduces a new dependency between this header and some
other header that provides that typedef. I suggest you fix that by
adding a typedef in this file.

#13Álvaro Herrera
alvherre@kurilemu.de
In reply to: Peter Eisentraut (#12)
Re: allow benign typedef redefinitions (C11)

On 2025-Sep-23, Peter Eisentraut wrote:

On 19.09.25 12:52, Álvaro Herrera wrote:

Here's a few more forward struct declarations turned into typedefs, for
cleanliness sake.

Two comments; the rest looks okay to me.

Thanks, pushed.

--
Álvaro Herrera Breisgau, Deutschland — https://www.EnterpriseDB.com/
"After a quick R of TFM, all I can say is HOLY CR** THAT IS COOL! PostgreSQL was
amazing when I first started using it at 7.2, and I'm continually astounded by
learning new features and techniques made available by the continuing work of
the development team."
Berend Tober, http://archives.postgresql.org/pgsql-hackers/2007-08/msg01009.php

#14Álvaro Herrera
alvherre@kurilemu.de
In reply to: Tom Lane (#11)
Re: allow benign typedef redefinitions (C11)

On 2025-Sep-20, Tom Lane wrote:

=?utf-8?Q?=C3=81lvaro?= Herrera <alvherre@kurilemu.de> writes:

Here's a proposed fix.

I didn't test this, but it passes an eyeball sanity check
and looks like an improvement overall.

Thanks, pushed now.

--
Álvaro Herrera PostgreSQL Developer — https://www.EnterpriseDB.com/
"El miedo atento y previsor es la madre de la seguridad" (E. Burke)

#15Álvaro Herrera
alvherre@kurilemu.de
In reply to: Peter Eisentraut (#1)
1 attachment(s)
Re: allow benign typedef redefinitions (C11)

Hello,

Here's another simple piece that I noticed while fooling around with the doxygen report -- genam.h was including tidbitmap.h and relcache.h for the sake of one typedefs each, and this was bleeding in other places in a rather random fashion, particularly through amapi.h. I propose the following to fix it. The changes to inet.h and varbit.h are surprising, but required. (It's possible that we should be including varatt.h in more datatype headers than just those two, but at least these are the ones that complained. So another option would be to include varatt.h in the files that include those headers. However, that seems to me to be the wrong direction).

--
Álvaro Herrera

Attachments:

0001-Remove-genam.h-s-dependency-on-relcache.h-and-tidbit.patchtext/x-patch; name="=?UTF-8?Q?0001-Remove-genam.h-s-dependency-on-relcache.h-and-tidbit.patc?= =?UTF-8?Q?h?="Download
From 32ad7228b3073e296f87670d6e4d8a0dbfdd100a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=C3=81lvaro=20Herrera?= <alvherre@kurilemu.de>
Date: Sun, 28 Sep 2025 11:15:51 +0200
Subject: [PATCH] Remove genam.h's dependency on relcache.h and tidbitmap.h

---
 src/include/access/amapi.h  | 2 ++
 src/include/access/genam.h  | 6 ++++--
 src/include/access/nbtree.h | 1 +
 src/include/utils/inet.h    | 1 +
 src/include/utils/varbit.h  | 1 +
 5 files changed, 9 insertions(+), 2 deletions(-)

diff --git a/src/include/access/amapi.h b/src/include/access/amapi.h
index 2b4482dc1e6..63dd41c1f21 100644
--- a/src/include/access/amapi.h
+++ b/src/include/access/amapi.h
@@ -15,6 +15,8 @@
 #include "access/cmptype.h"
 #include "access/genam.h"
 #include "access/stratnum.h"
+#include "nodes/nodes.h"
+#include "nodes/pg_list.h"
 
 /*
  * We don't wish to include planner header files here, since most of an index
diff --git a/src/include/access/genam.h b/src/include/access/genam.h
index ac62f6a6abd..e23eb04650b 100644
--- a/src/include/access/genam.h
+++ b/src/include/access/genam.h
@@ -17,15 +17,17 @@
 #include "access/htup.h"
 #include "access/sdir.h"
 #include "access/skey.h"
-#include "nodes/tidbitmap.h"
 #include "storage/buf.h"
 #include "storage/lockdefs.h"
-#include "utils/relcache.h"
 #include "utils/snapshot.h"
 
 /* We don't want this file to depend on execnodes.h. */
 typedef struct IndexInfo IndexInfo;
 typedef struct TupleTableSlot TupleTableSlot;
+/* or tidbitmap.h */
+typedef struct TIDBitmap TIDBitmap;
+/* or relcache.h */
+typedef struct RelationData *Relation;
 
 
 /*
diff --git a/src/include/access/nbtree.h b/src/include/access/nbtree.h
index 9ab467cb8fd..db1345f54c8 100644
--- a/src/include/access/nbtree.h
+++ b/src/include/access/nbtree.h
@@ -22,6 +22,7 @@
 #include "catalog/pg_index.h"
 #include "lib/stringinfo.h"
 #include "storage/bufmgr.h"
+#include "storage/dsm.h"
 #include "storage/shm_toc.h"
 #include "utils/skipsupport.h"
 
diff --git a/src/include/utils/inet.h b/src/include/utils/inet.h
index ace8957f220..f08cf2abc95 100644
--- a/src/include/utils/inet.h
+++ b/src/include/utils/inet.h
@@ -15,6 +15,7 @@
 #define INET_H
 
 #include "fmgr.h"
+#include "varatt.h"
 
 /*
  *	This is the internal storage format for IP addresses
diff --git a/src/include/utils/varbit.h b/src/include/utils/varbit.h
index 7b81e8e6bbc..f633e232502 100644
--- a/src/include/utils/varbit.h
+++ b/src/include/utils/varbit.h
@@ -18,6 +18,7 @@
 #include <limits.h>
 
 #include "fmgr.h"
+#include "varatt.h"
 
 /*
  * Modeled on struct varlena from c.h, but data type is bits8.
-- 
2.47.3

#16Tom Lane
tgl@sss.pgh.pa.us
In reply to: Álvaro Herrera (#15)
Re: allow benign typedef redefinitions (C11)

=?UTF-8?Q?=C3=81lvaro_Herrera?= <alvherre@kurilemu.de> writes:

The changes to inet.h and varbit.h are surprising, but required.

Why? Those headers compile now, and you've not removed any includes
that they might indirectly depend on.

(It's possible that we should be including varatt.h in more datatype headers than just those two, but at least these are the ones that complained. So another option would be to include varatt.h in the files that include those headers. However, that seems to me to be the wrong direction).

If what you mean is that some of the macros in these headers require
varatt.h to be used, I do not agree that that means we should put
varatt.h into these headers. We've frequently relied on exactly
that property of macro definitions to avoid excessive or circular
inclusions. Moreover, even if we wanted to change that policy,
I know of no simple way to check it.

Furthermore, this whole business of using "typedef struct foo foo;"
to avoid including foo.h is predicated on the assumption that the
ultimate consumer (some .c file) will itself include foo.h, because
otherwise it's most likely gonna have problems with the incomplete
typedef. So changing the rules about macros seems to me to be going
in quite the wrong direction.

I think what we're trying to do here is reduce the #includes of
header files to be just enough to compile the headers themselves.
That will bleed out into more #include's required in .c files,
but that's fine by me.

regards, tom lane

#17Álvaro Herrera
alvherre@kurilemu.de
In reply to: Tom Lane (#16)
1 attachment(s)
Re: allow benign typedef redefinitions (C11)

On 2025-Sep-28, Tom Lane wrote:

=?UTF-8?Q?=C3=81lvaro_Herrera?= <alvherre@kurilemu.de> writes:

The changes to inet.h and varbit.h are surprising, but required.

Why? Those headers compile now, and you've not removed any includes
that they might indirectly depend on.

That's true.

If what you mean is that some of the macros in these headers require
varatt.h to be used, I do not agree that that means we should put
varatt.h into these headers. We've frequently relied on exactly
that property of macro definitions to avoid excessive or circular
inclusions. Moreover, even if we wanted to change that policy,
I know of no simple way to check it.

We used to have a script called pgdefine that would create a .c file
that would expand all macros defined in a header, and then ensure that
the C file compiled. It was removed only recently (Dec. 2024), in
commit 5af699066f81, though it's true that apparently nobody had used in
a while.

I think what we're trying to do here is reduce the #includes of
header files to be just enough to compile the headers themselves.
That will bleed out into more #include's required in .c files,
but that's fine by me.

Ok, that requires adding varatt.h to just two .c files -- attached.

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

Attachments:

v2-0001-Remove-genam.h-s-dependency-on-relcache.h-and-tid.patchtext/x-diff; charset=utf-8Download
From 5860cc0d4a1e4f9eace2eb521f0f7416e97709ed Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=C3=81lvaro=20Herrera?= <alvherre@kurilemu.de>
Date: Sun, 28 Sep 2025 11:15:51 +0200
Subject: [PATCH v2] Remove genam.h's dependency on relcache.h and tidbitmap.h

---
 contrib/btree_gist/btree_bit.c         | 1 +
 src/backend/utils/adt/network_spgist.c | 1 +
 src/include/access/amapi.h             | 2 ++
 src/include/access/genam.h             | 6 ++++--
 src/include/access/nbtree.h            | 1 +
 5 files changed, 9 insertions(+), 2 deletions(-)

diff --git a/contrib/btree_gist/btree_bit.c b/contrib/btree_gist/btree_bit.c
index 0df2ae20d8b..9199f886097 100644
--- a/contrib/btree_gist/btree_bit.c
+++ b/contrib/btree_gist/btree_bit.c
@@ -8,6 +8,7 @@
 #include "utils/fmgrprotos.h"
 #include "utils/sortsupport.h"
 #include "utils/varbit.h"
+#include "varatt.h"
 
 /* GiST support functions */
 PG_FUNCTION_INFO_V1(gbt_bit_compress);
diff --git a/src/backend/utils/adt/network_spgist.c b/src/backend/utils/adt/network_spgist.c
index 602276a35c3..a84747d9275 100644
--- a/src/backend/utils/adt/network_spgist.c
+++ b/src/backend/utils/adt/network_spgist.c
@@ -37,6 +37,7 @@
 #include "catalog/pg_type.h"
 #include "utils/fmgrprotos.h"
 #include "utils/inet.h"
+#include "varatt.h"
 
 
 static int	inet_spg_node_number(const inet *val, int commonbits);
diff --git a/src/include/access/amapi.h b/src/include/access/amapi.h
index 2b4482dc1e6..63dd41c1f21 100644
--- a/src/include/access/amapi.h
+++ b/src/include/access/amapi.h
@@ -15,6 +15,8 @@
 #include "access/cmptype.h"
 #include "access/genam.h"
 #include "access/stratnum.h"
+#include "nodes/nodes.h"
+#include "nodes/pg_list.h"
 
 /*
  * We don't wish to include planner header files here, since most of an index
diff --git a/src/include/access/genam.h b/src/include/access/genam.h
index ac62f6a6abd..e23eb04650b 100644
--- a/src/include/access/genam.h
+++ b/src/include/access/genam.h
@@ -17,15 +17,17 @@
 #include "access/htup.h"
 #include "access/sdir.h"
 #include "access/skey.h"
-#include "nodes/tidbitmap.h"
 #include "storage/buf.h"
 #include "storage/lockdefs.h"
-#include "utils/relcache.h"
 #include "utils/snapshot.h"
 
 /* We don't want this file to depend on execnodes.h. */
 typedef struct IndexInfo IndexInfo;
 typedef struct TupleTableSlot TupleTableSlot;
+/* or tidbitmap.h */
+typedef struct TIDBitmap TIDBitmap;
+/* or relcache.h */
+typedef struct RelationData *Relation;
 
 
 /*
diff --git a/src/include/access/nbtree.h b/src/include/access/nbtree.h
index 9ab467cb8fd..db1345f54c8 100644
--- a/src/include/access/nbtree.h
+++ b/src/include/access/nbtree.h
@@ -22,6 +22,7 @@
 #include "catalog/pg_index.h"
 #include "lib/stringinfo.h"
 #include "storage/bufmgr.h"
+#include "storage/dsm.h"
 #include "storage/shm_toc.h"
 #include "utils/skipsupport.h"
 
-- 
2.47.3

#18Álvaro Herrera
alvherre@kurilemu.de
In reply to: Álvaro Herrera (#17)
2 attachment(s)
Re: allow benign typedef redefinitions (C11)

Hello,

I was thinking about your (Tom's) idea of having some sort of header
inclusion policy. Our current situation is that cross-module inclusions
are quite widespread and the dependencies can probably be seen as a
tight web (modules probably being defined as our subdirectories inside
src/include). A blanket prohibition of inclusion of headers of other
modules would certainly not work, but if we imagine that within each
module we have a hierarchy of sorts, then it would make sense to have a
policy that other modules can include high level headers of other
modules, but not lower-level headers. For instance, it's okay if
files in src/include/executor include high-level brin.h, but it's not
okay if it has to include brin_tuple.h which is supposed to be
lower-level.

With that in mind, I gave another long stare to the doxygen reports for
some of these files. It now seems to me that removing tidbitmap.h from
genam.h is somewhat bogus, because after all tidbitmap.h is a legitimate
"library" which is okay to be included in other headers, and the real
bug here is the fact that only very recently (commit bfe56cdf9a4e in Feb
2025) it acquired htup_details.h just in order to be able to define
TBM_MAX_TUPLES_PER_PAGE. If we remove htup_details.h from tidbitmap.h,
and we also remove the inclusion of relcache.h by adding a typedef for
Relation, then genam.h is a much better behaved header than before.
Hence the attached patches.

I've been looking at removing some includes from a few more headers, but
I'm not happy with the overall achievement, or at least I don't have a
good metric to present as a win. So I'll leave that for another day and
maybe present a different way to look at the problem. One thing we
should certainly do is fix the inclusion of brin_tuple.h and gin_tuple.h
into tuplesort.h, as I mentioned upthread. That is definitely a mess,
but I think it requires a new file.

Another thing we should look into is splitting the ObjectType enum out
of parsenodes.h into a new file of its own. We have objectaddress.h
depending on the whole of parsenodes.h just to have that enum, for
instance. I think that would be useful. I have the basic patch for
that and I kinda like it, but I want to analyze it a bit more before
posting to avoid rushing to conclusions.

Thanks

--
Álvaro Herrera Breisgau, Deutschland — https://www.EnterpriseDB.com/
Thou shalt study thy libraries and strive not to reinvent them without
cause, that thy code may be short and readable and thy days pleasant
and productive. (7th Commandment for C Programmers)

Attachments:

0001-Remove-genam.h-s-dependency-on-relcache.h.patchtext/x-diff; charset=utf-8Download
From 75b7c0c7a270066ab8ccd448265b6dddd7224d09 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=C3=81lvaro=20Herrera?= <alvherre@kurilemu.de>
Date: Sun, 28 Sep 2025 11:15:51 +0200
Subject: [PATCH 1/2] Remove genam.h's dependency on relcache.h

---
 contrib/btree_gist/btree_bit.c         | 1 +
 src/backend/utils/adt/network_spgist.c | 1 +
 src/include/access/amapi.h             | 2 ++
 src/include/access/genam.h             | 4 +++-
 src/include/access/nbtree.h            | 1 +
 5 files changed, 8 insertions(+), 1 deletion(-)

diff --git a/contrib/btree_gist/btree_bit.c b/contrib/btree_gist/btree_bit.c
index 0df2ae20d8b..9199f886097 100644
--- a/contrib/btree_gist/btree_bit.c
+++ b/contrib/btree_gist/btree_bit.c
@@ -8,6 +8,7 @@
 #include "utils/fmgrprotos.h"
 #include "utils/sortsupport.h"
 #include "utils/varbit.h"
+#include "varatt.h"
 
 /* GiST support functions */
 PG_FUNCTION_INFO_V1(gbt_bit_compress);
diff --git a/src/backend/utils/adt/network_spgist.c b/src/backend/utils/adt/network_spgist.c
index 602276a35c3..a84747d9275 100644
--- a/src/backend/utils/adt/network_spgist.c
+++ b/src/backend/utils/adt/network_spgist.c
@@ -37,6 +37,7 @@
 #include "catalog/pg_type.h"
 #include "utils/fmgrprotos.h"
 #include "utils/inet.h"
+#include "varatt.h"
 
 
 static int	inet_spg_node_number(const inet *val, int commonbits);
diff --git a/src/include/access/amapi.h b/src/include/access/amapi.h
index 2b4482dc1e6..63dd41c1f21 100644
--- a/src/include/access/amapi.h
+++ b/src/include/access/amapi.h
@@ -15,6 +15,8 @@
 #include "access/cmptype.h"
 #include "access/genam.h"
 #include "access/stratnum.h"
+#include "nodes/nodes.h"
+#include "nodes/pg_list.h"
 
 /*
  * We don't wish to include planner header files here, since most of an index
diff --git a/src/include/access/genam.h b/src/include/access/genam.h
index ac62f6a6abd..9200a22bd9f 100644
--- a/src/include/access/genam.h
+++ b/src/include/access/genam.h
@@ -20,13 +20,15 @@
 #include "nodes/tidbitmap.h"
 #include "storage/buf.h"
 #include "storage/lockdefs.h"
-#include "utils/relcache.h"
 #include "utils/snapshot.h"
 
 /* We don't want this file to depend on execnodes.h. */
 typedef struct IndexInfo IndexInfo;
 typedef struct TupleTableSlot TupleTableSlot;
 
+/* or relcache.h */
+typedef struct RelationData *Relation;
+
 
 /*
  * Struct for statistics maintained by amgettuple and amgetbitmap
diff --git a/src/include/access/nbtree.h b/src/include/access/nbtree.h
index 9ab467cb8fd..db1345f54c8 100644
--- a/src/include/access/nbtree.h
+++ b/src/include/access/nbtree.h
@@ -22,6 +22,7 @@
 #include "catalog/pg_index.h"
 #include "lib/stringinfo.h"
 #include "storage/bufmgr.h"
+#include "storage/dsm.h"
 #include "storage/shm_toc.h"
 #include "utils/skipsupport.h"
 
-- 
2.47.3

0002-don-t-include-htup_details.h-in-tidbitmap.h.patchtext/x-diff; charset=utf-8Download
From 79dabe8fa189be1ee084e60a1c1b2bf68fbbed3e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=C3=81lvaro=20Herrera?= <alvherre@kurilemu.de>
Date: Mon, 29 Sep 2025 15:52:06 +0200
Subject: [PATCH 2/2] don't include htup_details.h in tidbitmap.h

---
 src/backend/nodes/tidbitmap.c | 1 +
 src/include/nodes/tidbitmap.h | 1 -
 2 files changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/backend/nodes/tidbitmap.c b/src/backend/nodes/tidbitmap.c
index 41031aa8f2f..fac2ba5d0ca 100644
--- a/src/backend/nodes/tidbitmap.c
+++ b/src/backend/nodes/tidbitmap.c
@@ -40,6 +40,7 @@
 
 #include <limits.h>
 
+#include "access/htup_details.h"
 #include "common/hashfn.h"
 #include "common/int.h"
 #include "nodes/bitmapset.h"
diff --git a/src/include/nodes/tidbitmap.h b/src/include/nodes/tidbitmap.h
index 99f795ceab5..f54e61c7190 100644
--- a/src/include/nodes/tidbitmap.h
+++ b/src/include/nodes/tidbitmap.h
@@ -22,7 +22,6 @@
 #ifndef TIDBITMAP_H
 #define TIDBITMAP_H
 
-#include "access/htup_details.h"
 #include "storage/itemptr.h"
 #include "utils/dsa.h"
 
-- 
2.47.3

#19Tom Lane
tgl@sss.pgh.pa.us
In reply to: Álvaro Herrera (#18)
Re: allow benign typedef redefinitions (C11)

=?utf-8?Q?=C3=81lvaro?= Herrera <alvherre@kurilemu.de> writes:

I was thinking about your (Tom's) idea of having some sort of header
inclusion policy. Our current situation is that cross-module inclusions
are quite widespread and the dependencies can probably be seen as a
tight web (modules probably being defined as our subdirectories inside
src/include). A blanket prohibition of inclusion of headers of other
modules would certainly not work, but if we imagine that within each
module we have a hierarchy of sorts, then it would make sense to have a
policy that other modules can include high level headers of other
modules, but not lower-level headers. For instance, it's okay if
files in src/include/executor include high-level brin.h, but it's not
okay if it has to include brin_tuple.h which is supposed to be
lower-level.

Yeah, I've been thinking about that off-and-on, and don't have
anything to present yet either.

With that in mind, I gave another long stare to the doxygen reports for
some of these files. It now seems to me that removing tidbitmap.h from
genam.h is somewhat bogus, because after all tidbitmap.h is a legitimate
"library" which is okay to be included in other headers, and the real
bug here is the fact that only very recently (commit bfe56cdf9a4e in Feb
2025) it acquired htup_details.h just in order to be able to define
TBM_MAX_TUPLES_PER_PAGE. If we remove htup_details.h from tidbitmap.h,
and we also remove the inclusion of relcache.h by adding a typedef for
Relation, then genam.h is a much better behaved header than before.
Hence the attached patches.

These patches seem fine to me.

Another thing we should look into is splitting the ObjectType enum out
of parsenodes.h into a new file of its own. We have objectaddress.h
depending on the whole of parsenodes.h just to have that enum, for
instance. I think that would be useful.

+1. I think that primnodes.h and parsenodes.h are always going to
need to be included by a whole lot of things, but to the extent that
we can remove those inclusions from relatively low-level headers,
it can't hurt.

regards, tom lane

#20Álvaro Herrera
alvherre@kurilemu.de
In reply to: Álvaro Herrera (#8)
1 attachment(s)
Re: allow benign typedef redefinitions (C11)

On 2025-Sep-19, Álvaro Herrera wrote:

I happened to realize that brin_tuple.h (a somewhat nasty header which
was only supposed to be used by BRIN itself and stuff like amcheck)
recently somehow snuck into tuplesort.h with some nefarious
consequences: that one has polluted execnodes.h, which means that header
now depends on struct definitions that appear in genam.h. We should fix
this. This patch is not the full solution, just a way to show the
problem; for a definitive solution, IMO the definitions of structs
IndexScanInstrumentation and SharedIndexScanInstrumentation should be
elsewhere so that execnodes.h doesn't have to include genam.h.

(gin_tuple.h is also there, but that one's much less of a problem.)

Here's a proposed fix for this issue, wherein I move the
IndexScanInstrumentation and SharedIndexScanInstrumentation struct
definitions from genam.h to a new file executor/instrument_node.h.
I think there's room to argue that we should also move
BitmapHeapScanInstrumentation and SharedBitmapHeapInstrumentation
(currently defined in execnodes.h) to the new file; any opinions on
this? I think these structs belong together, so I'm leaning towards
yes.

Also, does anybody strongly dislike the proposed name? I admit it looks
unlike the existing names there:

$ ls src/include/executor
execAsync.h nodeFunctionscan.h nodeSamplescan.h
execdebug.h nodeGather.h nodeSeqscan.h
execdesc.h nodeGatherMerge.h nodeSetOp.h
execExpr.h nodeGroup.h nodeSort.h
execParallel.h nodeHash.h nodeSubplan.h
execPartition.h nodeHashjoin.h nodeSubqueryscan.h
execScan.h nodeIncrementalSort.h nodeTableFuncscan.h
executor.h nodeIndexonlyscan.h nodeTidrangescan.h
functions.h nodeIndexscan.h nodeTidscan.h
hashjoin.h nodeLimit.h nodeUnique.h
instrument.h nodeLockRows.h nodeValuesscan.h
instrument_node.h nodeMaterial.h nodeWindowAgg.h
nodeAgg.h nodeMemoize.h nodeWorktablescan.h
nodeAppend.h nodeMergeAppend.h spi.h
nodeBitmapAnd.h nodeMergejoin.h spi_priv.h
nodeBitmapHeapscan.h nodeModifyTable.h tablefunc.h
nodeBitmapIndexscan.h nodeNamedtuplestorescan.h tqueue.h
nodeBitmapOr.h nodeNestloop.h tstoreReceiver.h
nodeCtescan.h nodeProjectSet.h tuptable.h
nodeCustom.h nodeRecursiveunion.h
nodeForeignscan.h nodeResult.h

It's not the *first* name lacking camelCase or with an underscore, but
almost. Note that there's already an instrument.h, which has a
completely unrelated charter.

I also left an XXX comment on genam.h about including instrument_node.h
there or adding the typedefs. I think I prefer the typedefs myself.

CC'ing Peter G because of 0fbceae841cb and David because of
5a1e6df3b84c.

Thanks,

--
Álvaro Herrera PostgreSQL Developer — https://www.EnterpriseDB.com/
"Small aircraft do not crash frequently ... usually only once!"
(ponder, http://thedailywtf.com/)

Attachments:

0001-Remove-brin-gin_tuple.h-from-tuplesort.h.patchtext/x-diff; charset=utf-8Download
From d37153de91e0dec508b19d2e6d8ae8be76f7c2a6 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=C3=81lvaro=20Herrera?= <alvherre@kurilemu.de>
Date: Tue, 30 Sep 2025 12:36:49 +0200
Subject: [PATCH] Remove brin/gin_tuple.h from tuplesort.h

Because execnodes.h depends on struct definitions that were in genam.h,
which it no longer gets because of the aforementioned removal, split
those struct definitions to a separate header file.
---
 contrib/bloom/blscan.c                     |  1 +
 contrib/pageinspect/gistfuncs.c            |  1 +
 src/backend/access/gin/gininsert.c         |  3 +-
 src/backend/access/gist/gistget.c          |  1 +
 src/backend/access/hash/hashsearch.c       |  1 +
 src/backend/access/nbtree/nbtsearch.c      |  1 +
 src/backend/access/spgist/spgscan.c        |  1 +
 src/backend/catalog/pg_attrdef.c           |  1 +
 src/backend/catalog/pg_largeobject.c       |  1 +
 src/backend/executor/execReplication.c     |  1 +
 src/backend/parser/parse_expr.c            |  1 +
 src/backend/replication/logical/relation.c |  1 +
 src/backend/statistics/attribute_stats.c   |  1 +
 src/include/access/genam.h                 | 24 ++-----------
 src/include/executor/instrument_node.h     | 40 ++++++++++++++++++++++
 src/include/nodes/execnodes.h              |  2 ++
 src/include/utils/tuplesort.h              |  6 ++--
 17 files changed, 63 insertions(+), 24 deletions(-)
 create mode 100644 src/include/executor/instrument_node.h

diff --git a/contrib/bloom/blscan.c b/contrib/bloom/blscan.c
index d072f47fe28..5f8378d1f44 100644
--- a/contrib/bloom/blscan.c
+++ b/contrib/bloom/blscan.c
@@ -14,6 +14,7 @@
 
 #include "access/relscan.h"
 #include "bloom.h"
+#include "executor/instrument_node.h"
 #include "miscadmin.h"
 #include "pgstat.h"
 #include "storage/bufmgr.h"
diff --git a/contrib/pageinspect/gistfuncs.c b/contrib/pageinspect/gistfuncs.c
index 1b299374890..fab6e8d35ad 100644
--- a/contrib/pageinspect/gistfuncs.c
+++ b/contrib/pageinspect/gistfuncs.c
@@ -9,6 +9,7 @@
  */
 #include "postgres.h"
 
+#include "access/genam.h"
 #include "access/gist.h"
 #include "access/htup.h"
 #include "access/relation.h"
diff --git a/src/backend/access/gin/gininsert.c b/src/backend/access/gin/gininsert.c
index e9d4b27427e..43c007b6204 100644
--- a/src/backend/access/gin/gininsert.c
+++ b/src/backend/access/gin/gininsert.c
@@ -29,10 +29,11 @@
 #include "storage/bufmgr.h"
 #include "storage/predicate.h"
 #include "tcop/tcopprot.h"
+#include "utils/builtins.h"
 #include "utils/datum.h"
 #include "utils/memutils.h"
 #include "utils/rel.h"
-#include "utils/builtins.h"
+#include "utils/typcache.h"
 
 
 /* Magic numbers for parallel state sharing */
diff --git a/src/backend/access/gist/gistget.c b/src/backend/access/gist/gistget.c
index 387d9972345..aa56ef430a9 100644
--- a/src/backend/access/gist/gistget.c
+++ b/src/backend/access/gist/gistget.c
@@ -17,6 +17,7 @@
 #include "access/genam.h"
 #include "access/gist_private.h"
 #include "access/relscan.h"
+#include "executor/instrument_node.h"
 #include "lib/pairingheap.h"
 #include "miscadmin.h"
 #include "pgstat.h"
diff --git a/src/backend/access/hash/hashsearch.c b/src/backend/access/hash/hashsearch.c
index 92c15a65be2..00395b01f60 100644
--- a/src/backend/access/hash/hashsearch.c
+++ b/src/backend/access/hash/hashsearch.c
@@ -17,6 +17,7 @@
 #include "access/hash.h"
 #include "access/relscan.h"
 #include "miscadmin.h"
+#include "executor/instrument_node.h"
 #include "pgstat.h"
 #include "storage/predicate.h"
 #include "utils/rel.h"
diff --git a/src/backend/access/nbtree/nbtsearch.c b/src/backend/access/nbtree/nbtsearch.c
index d69798795b4..5c6dc3b183e 100644
--- a/src/backend/access/nbtree/nbtsearch.c
+++ b/src/backend/access/nbtree/nbtsearch.c
@@ -18,6 +18,7 @@
 #include "access/nbtree.h"
 #include "access/relscan.h"
 #include "access/xact.h"
+#include "executor/instrument_node.h"
 #include "miscadmin.h"
 #include "pgstat.h"
 #include "storage/predicate.h"
diff --git a/src/backend/access/spgist/spgscan.c b/src/backend/access/spgist/spgscan.c
index 25893050c58..abfb3555af5 100644
--- a/src/backend/access/spgist/spgscan.c
+++ b/src/backend/access/spgist/spgscan.c
@@ -18,6 +18,7 @@
 #include "access/genam.h"
 #include "access/relscan.h"
 #include "access/spgist_private.h"
+#include "executor/instrument_node.h"
 #include "miscadmin.h"
 #include "pgstat.h"
 #include "storage/bufmgr.h"
diff --git a/src/backend/catalog/pg_attrdef.c b/src/backend/catalog/pg_attrdef.c
index 1b6270b1213..4db4ffd657c 100644
--- a/src/backend/catalog/pg_attrdef.c
+++ b/src/backend/catalog/pg_attrdef.c
@@ -14,6 +14,7 @@
  */
 #include "postgres.h"
 
+#include "access/genam.h"
 #include "access/relation.h"
 #include "access/table.h"
 #include "catalog/dependency.h"
diff --git a/src/backend/catalog/pg_largeobject.c b/src/backend/catalog/pg_largeobject.c
index 89fc8102150..471f82f51a8 100644
--- a/src/backend/catalog/pg_largeobject.c
+++ b/src/backend/catalog/pg_largeobject.c
@@ -14,6 +14,7 @@
  */
 #include "postgres.h"
 
+#include "access/genam.h"
 #include "access/table.h"
 #include "catalog/catalog.h"
 #include "catalog/indexing.h"
diff --git a/src/backend/executor/execReplication.c b/src/backend/executor/execReplication.c
index b409d4ecbf5..ab585aa9819 100644
--- a/src/backend/executor/execReplication.c
+++ b/src/backend/executor/execReplication.c
@@ -14,6 +14,7 @@
 
 #include "postgres.h"
 
+#include "access/amapi.h"
 #include "access/commit_ts.h"
 #include "access/genam.h"
 #include "access/gist.h"
diff --git a/src/backend/parser/parse_expr.c b/src/backend/parser/parse_expr.c
index e1979a80c19..eebea694dda 100644
--- a/src/backend/parser/parse_expr.c
+++ b/src/backend/parser/parse_expr.c
@@ -37,6 +37,7 @@
 #include "utils/fmgroids.h"
 #include "utils/lsyscache.h"
 #include "utils/timestamp.h"
+#include "utils/typcache.h"
 #include "utils/xml.h"
 
 /* GUC parameters */
diff --git a/src/backend/replication/logical/relation.c b/src/backend/replication/logical/relation.c
index f59046ad620..85f55b75c66 100644
--- a/src/backend/replication/logical/relation.c
+++ b/src/backend/replication/logical/relation.c
@@ -29,6 +29,7 @@
 #include "utils/inval.h"
 #include "utils/lsyscache.h"
 #include "utils/syscache.h"
+#include "utils/typcache.h"
 
 
 static MemoryContext LogicalRepRelMapContext = NULL;
diff --git a/src/backend/statistics/attribute_stats.c b/src/backend/statistics/attribute_stats.c
index 1db6a7f784c..4e8efcdf55b 100644
--- a/src/backend/statistics/attribute_stats.c
+++ b/src/backend/statistics/attribute_stats.c
@@ -29,6 +29,7 @@
 #include "utils/fmgroids.h"
 #include "utils/lsyscache.h"
 #include "utils/syscache.h"
+#include "utils/typcache.h"
 
 #define DEFAULT_NULL_FRAC      Float4GetDatum(0.0)
 #define DEFAULT_AVG_WIDTH      Int32GetDatum(0) /* unknown */
diff --git a/src/include/access/genam.h b/src/include/access/genam.h
index 9200a22bd9f..b18a7e4f5db 100644
--- a/src/include/access/genam.h
+++ b/src/include/access/genam.h
@@ -29,27 +29,9 @@ typedef struct TupleTableSlot TupleTableSlot;
 /* or relcache.h */
 typedef struct RelationData *Relation;
 
-
-/*
- * Struct for statistics maintained by amgettuple and amgetbitmap
- *
- * Note: IndexScanInstrumentation can't contain any pointers, since it is
- * copied into a SharedIndexScanInstrumentation during parallel scans
- */
-typedef struct IndexScanInstrumentation
-{
-	/* Index search count (incremented with pgstat_count_index_scan call) */
-	uint64		nsearches;
-} IndexScanInstrumentation;
-
-/*
- * Struct for every worker's IndexScanInstrumentation, stored in shared memory
- */
-typedef struct SharedIndexScanInstrumentation
-{
-	int			num_workers;
-	IndexScanInstrumentation winstrument[FLEXIBLE_ARRAY_MEMBER];
-} SharedIndexScanInstrumentation;
+/* XXX maybe include the other file here instead of this? */
+typedef struct IndexScanInstrumentation IndexScanInstrumentation;
+typedef struct SharedIndexScanInstrumentation SharedIndexScanInstrumentation;
 
 /*
  * Struct for statistics returned by ambuild
diff --git a/src/include/executor/instrument_node.h b/src/include/executor/instrument_node.h
new file mode 100644
index 00000000000..1af07c03a3e
--- /dev/null
+++ b/src/include/executor/instrument_node.h
@@ -0,0 +1,40 @@
+/*-------------------------------------------------------------------------
+ *
+ * instrument_node.h
+ *	  Definitions for node-specific instrumentation
+ *
+ *
+ * Portions Copyright (c) 1996-2025, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1994, Regents of the University of California
+ *
+ * src/include/executor/instrument_node.h
+ *
+ *-------------------------------------------------------------------------
+ */
+#ifndef INSTRUMENT_NODE_H
+#define INSTRUMENT_NODE_H
+
+
+/*
+ * Struct for statistics maintained by amgettuple and amgetbitmap
+ *
+ * Note: IndexScanInstrumentation can't contain any pointers, since it is
+ * copied into a SharedIndexScanInstrumentation during parallel scans
+ */
+typedef struct IndexScanInstrumentation
+{
+	/* Index search count (incremented with pgstat_count_index_scan call) */
+	uint64		nsearches;
+} IndexScanInstrumentation;
+
+/*
+ * Struct for every worker's IndexScanInstrumentation, stored in shared memory
+ */
+typedef struct SharedIndexScanInstrumentation
+{
+	int			num_workers;
+	IndexScanInstrumentation winstrument[FLEXIBLE_ARRAY_MEMBER];
+} SharedIndexScanInstrumentation;
+
+
+#endif							/* INSTRUMENT_NODE_H */
diff --git a/src/include/nodes/execnodes.h b/src/include/nodes/execnodes.h
index a36653c37f9..4bf733bc8e1 100644
--- a/src/include/nodes/execnodes.h
+++ b/src/include/nodes/execnodes.h
@@ -29,8 +29,10 @@
 #ifndef EXECNODES_H
 #define EXECNODES_H
 
+#include "access/skey.h"
 #include "access/tupconvert.h"
 #include "executor/instrument.h"
+#include "executor/instrument_node.h"
 #include "fmgr.h"
 #include "lib/ilist.h"
 #include "lib/pairingheap.h"
diff --git a/src/include/utils/tuplesort.h b/src/include/utils/tuplesort.h
index ef79f259f93..8278beea5ec 100644
--- a/src/include/utils/tuplesort.h
+++ b/src/include/utils/tuplesort.h
@@ -21,8 +21,6 @@
 #ifndef TUPLESORT_H
 #define TUPLESORT_H
 
-#include "access/brin_tuple.h"
-#include "access/gin_tuple.h"
 #include "access/itup.h"
 #include "executor/tuptable.h"
 #include "storage/dsm.h"
@@ -31,6 +29,10 @@
 #include "utils/sortsupport.h"
 
 
+/* We don't want this file to depend on AM-specific header files */
+typedef struct BrinTuple BrinTuple;
+typedef struct GinTuple GinTuple;
+
 /*
  * Tuplesortstate and Sharedsort are opaque types whose details are not
  * known outside tuplesort.c.
-- 
2.47.3

#21Álvaro Herrera
alvherre@kurilemu.de
In reply to: Álvaro Herrera (#20)
2 attachment(s)
Re: allow benign typedef redefinitions (C11)

I happened to realize that we still have one small "layering violation"
in executor/tuptable.h which is currently including htup_details.h for
no reason (I suspect it was a simple mistake in commit 5408e233f066),
and this bleeds via execnodes.h to a lot of places. Patch 0002 here
removes that and fixes the affected .c files in the minimal way
required. Patch 0001 is the same as before.

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

Attachments:

0001-Remove-brin-gin_tuple.h-from-tuplesort.h.patchtext/x-diff; charset=utf-8Download
From 03a36f00360c81f82daf66ff1c8514fbf68c5702 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=C3=81lvaro=20Herrera?= <alvherre@kurilemu.de>
Date: Tue, 30 Sep 2025 12:36:49 +0200
Subject: [PATCH 1/2] Remove brin/gin_tuple.h from tuplesort.h

Because execnodes.h depends on struct definitions that were in genam.h,
which it no longer gets because of the aforementioned removal, split
those struct definitions to a separate header file.
---
 contrib/bloom/blscan.c                     |  1 +
 contrib/pageinspect/gistfuncs.c            |  1 +
 src/backend/access/gin/gininsert.c         |  3 +-
 src/backend/access/gist/gistget.c          |  1 +
 src/backend/access/hash/hashsearch.c       |  1 +
 src/backend/access/nbtree/nbtsearch.c      |  1 +
 src/backend/access/spgist/spgscan.c        |  1 +
 src/backend/catalog/pg_attrdef.c           |  1 +
 src/backend/catalog/pg_largeobject.c       |  1 +
 src/backend/executor/execReplication.c     |  1 +
 src/backend/parser/parse_expr.c            |  1 +
 src/backend/replication/logical/relation.c |  1 +
 src/backend/statistics/attribute_stats.c   |  1 +
 src/include/access/genam.h                 | 24 ++-----------
 src/include/executor/instrument_node.h     | 40 ++++++++++++++++++++++
 src/include/nodes/execnodes.h              |  2 ++
 src/include/utils/tuplesort.h              |  6 ++--
 17 files changed, 63 insertions(+), 24 deletions(-)
 create mode 100644 src/include/executor/instrument_node.h

diff --git a/contrib/bloom/blscan.c b/contrib/bloom/blscan.c
index d072f47fe28..5f8378d1f44 100644
--- a/contrib/bloom/blscan.c
+++ b/contrib/bloom/blscan.c
@@ -14,6 +14,7 @@
 
 #include "access/relscan.h"
 #include "bloom.h"
+#include "executor/instrument_node.h"
 #include "miscadmin.h"
 #include "pgstat.h"
 #include "storage/bufmgr.h"
diff --git a/contrib/pageinspect/gistfuncs.c b/contrib/pageinspect/gistfuncs.c
index 1b299374890..fab6e8d35ad 100644
--- a/contrib/pageinspect/gistfuncs.c
+++ b/contrib/pageinspect/gistfuncs.c
@@ -9,6 +9,7 @@
  */
 #include "postgres.h"
 
+#include "access/genam.h"
 #include "access/gist.h"
 #include "access/htup.h"
 #include "access/relation.h"
diff --git a/src/backend/access/gin/gininsert.c b/src/backend/access/gin/gininsert.c
index e9d4b27427e..43c007b6204 100644
--- a/src/backend/access/gin/gininsert.c
+++ b/src/backend/access/gin/gininsert.c
@@ -29,10 +29,11 @@
 #include "storage/bufmgr.h"
 #include "storage/predicate.h"
 #include "tcop/tcopprot.h"
+#include "utils/builtins.h"
 #include "utils/datum.h"
 #include "utils/memutils.h"
 #include "utils/rel.h"
-#include "utils/builtins.h"
+#include "utils/typcache.h"
 
 
 /* Magic numbers for parallel state sharing */
diff --git a/src/backend/access/gist/gistget.c b/src/backend/access/gist/gistget.c
index 387d9972345..aa56ef430a9 100644
--- a/src/backend/access/gist/gistget.c
+++ b/src/backend/access/gist/gistget.c
@@ -17,6 +17,7 @@
 #include "access/genam.h"
 #include "access/gist_private.h"
 #include "access/relscan.h"
+#include "executor/instrument_node.h"
 #include "lib/pairingheap.h"
 #include "miscadmin.h"
 #include "pgstat.h"
diff --git a/src/backend/access/hash/hashsearch.c b/src/backend/access/hash/hashsearch.c
index 92c15a65be2..00395b01f60 100644
--- a/src/backend/access/hash/hashsearch.c
+++ b/src/backend/access/hash/hashsearch.c
@@ -17,6 +17,7 @@
 #include "access/hash.h"
 #include "access/relscan.h"
 #include "miscadmin.h"
+#include "executor/instrument_node.h"
 #include "pgstat.h"
 #include "storage/predicate.h"
 #include "utils/rel.h"
diff --git a/src/backend/access/nbtree/nbtsearch.c b/src/backend/access/nbtree/nbtsearch.c
index d69798795b4..5c6dc3b183e 100644
--- a/src/backend/access/nbtree/nbtsearch.c
+++ b/src/backend/access/nbtree/nbtsearch.c
@@ -18,6 +18,7 @@
 #include "access/nbtree.h"
 #include "access/relscan.h"
 #include "access/xact.h"
+#include "executor/instrument_node.h"
 #include "miscadmin.h"
 #include "pgstat.h"
 #include "storage/predicate.h"
diff --git a/src/backend/access/spgist/spgscan.c b/src/backend/access/spgist/spgscan.c
index 25893050c58..abfb3555af5 100644
--- a/src/backend/access/spgist/spgscan.c
+++ b/src/backend/access/spgist/spgscan.c
@@ -18,6 +18,7 @@
 #include "access/genam.h"
 #include "access/relscan.h"
 #include "access/spgist_private.h"
+#include "executor/instrument_node.h"
 #include "miscadmin.h"
 #include "pgstat.h"
 #include "storage/bufmgr.h"
diff --git a/src/backend/catalog/pg_attrdef.c b/src/backend/catalog/pg_attrdef.c
index 1b6270b1213..4db4ffd657c 100644
--- a/src/backend/catalog/pg_attrdef.c
+++ b/src/backend/catalog/pg_attrdef.c
@@ -14,6 +14,7 @@
  */
 #include "postgres.h"
 
+#include "access/genam.h"
 #include "access/relation.h"
 #include "access/table.h"
 #include "catalog/dependency.h"
diff --git a/src/backend/catalog/pg_largeobject.c b/src/backend/catalog/pg_largeobject.c
index 89fc8102150..471f82f51a8 100644
--- a/src/backend/catalog/pg_largeobject.c
+++ b/src/backend/catalog/pg_largeobject.c
@@ -14,6 +14,7 @@
  */
 #include "postgres.h"
 
+#include "access/genam.h"
 #include "access/table.h"
 #include "catalog/catalog.h"
 #include "catalog/indexing.h"
diff --git a/src/backend/executor/execReplication.c b/src/backend/executor/execReplication.c
index b409d4ecbf5..ab585aa9819 100644
--- a/src/backend/executor/execReplication.c
+++ b/src/backend/executor/execReplication.c
@@ -14,6 +14,7 @@
 
 #include "postgres.h"
 
+#include "access/amapi.h"
 #include "access/commit_ts.h"
 #include "access/genam.h"
 #include "access/gist.h"
diff --git a/src/backend/parser/parse_expr.c b/src/backend/parser/parse_expr.c
index e1979a80c19..eebea694dda 100644
--- a/src/backend/parser/parse_expr.c
+++ b/src/backend/parser/parse_expr.c
@@ -37,6 +37,7 @@
 #include "utils/fmgroids.h"
 #include "utils/lsyscache.h"
 #include "utils/timestamp.h"
+#include "utils/typcache.h"
 #include "utils/xml.h"
 
 /* GUC parameters */
diff --git a/src/backend/replication/logical/relation.c b/src/backend/replication/logical/relation.c
index f59046ad620..85f55b75c66 100644
--- a/src/backend/replication/logical/relation.c
+++ b/src/backend/replication/logical/relation.c
@@ -29,6 +29,7 @@
 #include "utils/inval.h"
 #include "utils/lsyscache.h"
 #include "utils/syscache.h"
+#include "utils/typcache.h"
 
 
 static MemoryContext LogicalRepRelMapContext = NULL;
diff --git a/src/backend/statistics/attribute_stats.c b/src/backend/statistics/attribute_stats.c
index 1db6a7f784c..4e8efcdf55b 100644
--- a/src/backend/statistics/attribute_stats.c
+++ b/src/backend/statistics/attribute_stats.c
@@ -29,6 +29,7 @@
 #include "utils/fmgroids.h"
 #include "utils/lsyscache.h"
 #include "utils/syscache.h"
+#include "utils/typcache.h"
 
 #define DEFAULT_NULL_FRAC      Float4GetDatum(0.0)
 #define DEFAULT_AVG_WIDTH      Int32GetDatum(0) /* unknown */
diff --git a/src/include/access/genam.h b/src/include/access/genam.h
index 9200a22bd9f..b18a7e4f5db 100644
--- a/src/include/access/genam.h
+++ b/src/include/access/genam.h
@@ -29,27 +29,9 @@ typedef struct TupleTableSlot TupleTableSlot;
 /* or relcache.h */
 typedef struct RelationData *Relation;
 
-
-/*
- * Struct for statistics maintained by amgettuple and amgetbitmap
- *
- * Note: IndexScanInstrumentation can't contain any pointers, since it is
- * copied into a SharedIndexScanInstrumentation during parallel scans
- */
-typedef struct IndexScanInstrumentation
-{
-	/* Index search count (incremented with pgstat_count_index_scan call) */
-	uint64		nsearches;
-} IndexScanInstrumentation;
-
-/*
- * Struct for every worker's IndexScanInstrumentation, stored in shared memory
- */
-typedef struct SharedIndexScanInstrumentation
-{
-	int			num_workers;
-	IndexScanInstrumentation winstrument[FLEXIBLE_ARRAY_MEMBER];
-} SharedIndexScanInstrumentation;
+/* XXX maybe include the other file here instead of this? */
+typedef struct IndexScanInstrumentation IndexScanInstrumentation;
+typedef struct SharedIndexScanInstrumentation SharedIndexScanInstrumentation;
 
 /*
  * Struct for statistics returned by ambuild
diff --git a/src/include/executor/instrument_node.h b/src/include/executor/instrument_node.h
new file mode 100644
index 00000000000..1af07c03a3e
--- /dev/null
+++ b/src/include/executor/instrument_node.h
@@ -0,0 +1,40 @@
+/*-------------------------------------------------------------------------
+ *
+ * instrument_node.h
+ *	  Definitions for node-specific instrumentation
+ *
+ *
+ * Portions Copyright (c) 1996-2025, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1994, Regents of the University of California
+ *
+ * src/include/executor/instrument_node.h
+ *
+ *-------------------------------------------------------------------------
+ */
+#ifndef INSTRUMENT_NODE_H
+#define INSTRUMENT_NODE_H
+
+
+/*
+ * Struct for statistics maintained by amgettuple and amgetbitmap
+ *
+ * Note: IndexScanInstrumentation can't contain any pointers, since it is
+ * copied into a SharedIndexScanInstrumentation during parallel scans
+ */
+typedef struct IndexScanInstrumentation
+{
+	/* Index search count (incremented with pgstat_count_index_scan call) */
+	uint64		nsearches;
+} IndexScanInstrumentation;
+
+/*
+ * Struct for every worker's IndexScanInstrumentation, stored in shared memory
+ */
+typedef struct SharedIndexScanInstrumentation
+{
+	int			num_workers;
+	IndexScanInstrumentation winstrument[FLEXIBLE_ARRAY_MEMBER];
+} SharedIndexScanInstrumentation;
+
+
+#endif							/* INSTRUMENT_NODE_H */
diff --git a/src/include/nodes/execnodes.h b/src/include/nodes/execnodes.h
index a36653c37f9..4bf733bc8e1 100644
--- a/src/include/nodes/execnodes.h
+++ b/src/include/nodes/execnodes.h
@@ -29,8 +29,10 @@
 #ifndef EXECNODES_H
 #define EXECNODES_H
 
+#include "access/skey.h"
 #include "access/tupconvert.h"
 #include "executor/instrument.h"
+#include "executor/instrument_node.h"
 #include "fmgr.h"
 #include "lib/ilist.h"
 #include "lib/pairingheap.h"
diff --git a/src/include/utils/tuplesort.h b/src/include/utils/tuplesort.h
index ef79f259f93..8278beea5ec 100644
--- a/src/include/utils/tuplesort.h
+++ b/src/include/utils/tuplesort.h
@@ -21,8 +21,6 @@
 #ifndef TUPLESORT_H
 #define TUPLESORT_H
 
-#include "access/brin_tuple.h"
-#include "access/gin_tuple.h"
 #include "access/itup.h"
 #include "executor/tuptable.h"
 #include "storage/dsm.h"
@@ -31,6 +29,10 @@
 #include "utils/sortsupport.h"
 
 
+/* We don't want this file to depend on AM-specific header files */
+typedef struct BrinTuple BrinTuple;
+typedef struct GinTuple GinTuple;
+
 /*
  * Tuplesortstate and Sharedsort are opaque types whose details are not
  * known outside tuplesort.c.
-- 
2.47.3

0002-Don-t-include-access-htup_details.h-in-executor-tupt.patchtext/x-diff; charset=utf-8Download
From 1be86af11472243fdc14d5d5460505ade1034426 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=C3=81lvaro=20Herrera?= <alvherre@kurilemu.de>
Date: Tue, 30 Sep 2025 16:16:04 +0200
Subject: [PATCH 2/2] Don't include access/htup_details.h in
 executor/tuptable.h

This is not at all needed; I suspect it was a simple mistake in commit
5408e233f066.  It causes htup_details.h to bleed into a huge number of
places via execnodes.h.  Remove it and fix fallout.
---
 contrib/pageinspect/btreefuncs.c                          | 1 +
 contrib/pageinspect/gistfuncs.c                           | 1 +
 contrib/pg_stat_statements/pg_stat_statements.c           | 1 +
 contrib/pg_walinspect/pg_walinspect.c                     | 1 +
 contrib/postgres_fdw/connection.c                         | 1 +
 contrib/xml2/xslt_proc.c                                  | 1 +
 src/backend/access/common/printsimple.c                   | 1 +
 src/backend/access/common/printtup.c                      | 1 +
 src/backend/access/common/tupconvert.c                    | 1 +
 src/backend/backup/walsummaryfuncs.c                      | 1 +
 src/backend/catalog/pg_attrdef.c                          | 1 +
 src/backend/catalog/pg_largeobject.c                      | 1 +
 src/backend/catalog/pg_parameter_acl.c                    | 1 +
 src/backend/commands/explain_dr.c                         | 1 +
 src/backend/commands/proclang.c                           | 1 +
 src/backend/commands/statscmds.c                          | 1 +
 src/backend/executor/nodeGatherMerge.c                    | 1 +
 src/backend/executor/nodeMemoize.c                        | 1 +
 src/backend/executor/tstoreReceiver.c                     | 1 +
 src/backend/optimizer/path/indxpath.c                     | 1 +
 src/backend/optimizer/util/pathnode.c                     | 1 +
 src/backend/parser/parse_coerce.c                         | 1 +
 src/backend/parser/parse_expr.c                           | 1 +
 src/backend/utils/adt/arrayfuncs.c                        | 1 +
 src/backend/utils/adt/hbafuncs.c                          | 1 +
 src/backend/utils/adt/json.c                              | 1 +
 src/backend/utils/adt/misc.c                              | 1 +
 src/backend/utils/adt/rangetypes.c                        | 1 +
 src/backend/utils/adt/xid8funcs.c                         | 1 +
 src/backend/utils/fmgr/fmgr.c                             | 1 +
 src/backend/utils/misc/guc.c                              | 1 +
 src/include/access/gin_private.h                          | 1 +
 src/include/executor/tuptable.h                           | 1 -
 src/test/modules/injection_points/injection_stats_fixed.c | 1 +
 34 files changed, 33 insertions(+), 1 deletion(-)

diff --git a/contrib/pageinspect/btreefuncs.c b/contrib/pageinspect/btreefuncs.c
index 4e2e8891cdd..2e67c9adf5a 100644
--- a/contrib/pageinspect/btreefuncs.c
+++ b/contrib/pageinspect/btreefuncs.c
@@ -27,6 +27,7 @@
 
 #include "postgres.h"
 
+#include "access/htup_details.h"
 #include "access/nbtree.h"
 #include "access/relation.h"
 #include "catalog/namespace.h"
diff --git a/contrib/pageinspect/gistfuncs.c b/contrib/pageinspect/gistfuncs.c
index fab6e8d35ad..190353ec354 100644
--- a/contrib/pageinspect/gistfuncs.c
+++ b/contrib/pageinspect/gistfuncs.c
@@ -12,6 +12,7 @@
 #include "access/genam.h"
 #include "access/gist.h"
 #include "access/htup.h"
+#include "access/htup_details.h"
 #include "access/relation.h"
 #include "catalog/pg_am_d.h"
 #include "funcapi.h"
diff --git a/contrib/pg_stat_statements/pg_stat_statements.c b/contrib/pg_stat_statements/pg_stat_statements.c
index 0bb0f933399..db1af36a705 100644
--- a/contrib/pg_stat_statements/pg_stat_statements.c
+++ b/contrib/pg_stat_statements/pg_stat_statements.c
@@ -47,6 +47,7 @@
 #include <sys/stat.h>
 #include <unistd.h>
 
+#include "access/htup_details.h"
 #include "access/parallel.h"
 #include "catalog/pg_authid.h"
 #include "common/int.h"
diff --git a/contrib/pg_walinspect/pg_walinspect.c b/contrib/pg_walinspect/pg_walinspect.c
index 0398ad82cec..501cea8fc1a 100644
--- a/contrib/pg_walinspect/pg_walinspect.c
+++ b/contrib/pg_walinspect/pg_walinspect.c
@@ -12,6 +12,7 @@
  */
 #include "postgres.h"
 
+#include "access/htup_details.h"
 #include "access/xlog.h"
 #include "access/xlog_internal.h"
 #include "access/xlogreader.h"
diff --git a/contrib/postgres_fdw/connection.c b/contrib/postgres_fdw/connection.c
index 4fbb6c182b8..953c2e0ab82 100644
--- a/contrib/postgres_fdw/connection.c
+++ b/contrib/postgres_fdw/connection.c
@@ -16,6 +16,7 @@
 #include <poll.h>
 #endif
 
+#include "access/htup_details.h"
 #include "access/xact.h"
 #include "catalog/pg_user_mapping.h"
 #include "commands/defrem.h"
diff --git a/contrib/xml2/xslt_proc.c b/contrib/xml2/xslt_proc.c
index 53550c7dc24..36578b82e4d 100644
--- a/contrib/xml2/xslt_proc.c
+++ b/contrib/xml2/xslt_proc.c
@@ -10,6 +10,7 @@
 #include "fmgr.h"
 #include "utils/builtins.h"
 #include "utils/xml.h"
+#include "varatt.h"
 
 #ifdef USE_LIBXSLT
 
diff --git a/src/backend/access/common/printsimple.c b/src/backend/access/common/printsimple.c
index a09c8fcd332..756f1c4822d 100644
--- a/src/backend/access/common/printsimple.c
+++ b/src/backend/access/common/printsimple.c
@@ -23,6 +23,7 @@
 #include "libpq/pqformat.h"
 #include "libpq/protocol.h"
 #include "utils/builtins.h"
+#include "varatt.h"
 
 /*
  * At startup time, send a RowDescription message.
diff --git a/src/backend/access/common/printtup.c b/src/backend/access/common/printtup.c
index 6d3045e2332..9f05e1d15bd 100644
--- a/src/backend/access/common/printtup.c
+++ b/src/backend/access/common/printtup.c
@@ -22,6 +22,7 @@
 #include "utils/lsyscache.h"
 #include "utils/memdebug.h"
 #include "utils/memutils.h"
+#include "varatt.h"
 
 
 static void printtup_startup(DestReceiver *self, int operation,
diff --git a/src/backend/access/common/tupconvert.c b/src/backend/access/common/tupconvert.c
index 54dc2f4ab80..1df0c2d2f98 100644
--- a/src/backend/access/common/tupconvert.c
+++ b/src/backend/access/common/tupconvert.c
@@ -18,6 +18,7 @@
  */
 #include "postgres.h"
 
+#include "access/htup_details.h"
 #include "access/tupconvert.h"
 #include "executor/tuptable.h"
 
diff --git a/src/backend/backup/walsummaryfuncs.c b/src/backend/backup/walsummaryfuncs.c
index d6dd131da14..29e2cb83ff4 100644
--- a/src/backend/backup/walsummaryfuncs.c
+++ b/src/backend/backup/walsummaryfuncs.c
@@ -12,6 +12,7 @@
 
 #include "postgres.h"
 
+#include "access/htup_details.h"
 #include "backup/walsummary.h"
 #include "common/blkreftable.h"
 #include "funcapi.h"
diff --git a/src/backend/catalog/pg_attrdef.c b/src/backend/catalog/pg_attrdef.c
index 4db4ffd657c..e8bdb52cb00 100644
--- a/src/backend/catalog/pg_attrdef.c
+++ b/src/backend/catalog/pg_attrdef.c
@@ -15,6 +15,7 @@
 #include "postgres.h"
 
 #include "access/genam.h"
+#include "access/htup_details.h"
 #include "access/relation.h"
 #include "access/table.h"
 #include "catalog/dependency.h"
diff --git a/src/backend/catalog/pg_largeobject.c b/src/backend/catalog/pg_largeobject.c
index 471f82f51a8..ada4c3685e0 100644
--- a/src/backend/catalog/pg_largeobject.c
+++ b/src/backend/catalog/pg_largeobject.c
@@ -15,6 +15,7 @@
 #include "postgres.h"
 
 #include "access/genam.h"
+#include "access/htup_details.h"
 #include "access/table.h"
 #include "catalog/catalog.h"
 #include "catalog/indexing.h"
diff --git a/src/backend/catalog/pg_parameter_acl.c b/src/backend/catalog/pg_parameter_acl.c
index 62a05783eb3..dcdf49ea408 100644
--- a/src/backend/catalog/pg_parameter_acl.c
+++ b/src/backend/catalog/pg_parameter_acl.c
@@ -14,6 +14,7 @@
  */
 #include "postgres.h"
 
+#include "access/htup_details.h"
 #include "access/table.h"
 #include "catalog/catalog.h"
 #include "catalog/indexing.h"
diff --git a/src/backend/commands/explain_dr.c b/src/backend/commands/explain_dr.c
index d6084077be7..95685d7e88d 100644
--- a/src/backend/commands/explain_dr.c
+++ b/src/backend/commands/explain_dr.c
@@ -19,6 +19,7 @@
 #include "libpq/pqformat.h"
 #include "libpq/protocol.h"
 #include "utils/lsyscache.h"
+#include "varatt.h"
 
 /*
  * DestReceiver functions for SERIALIZE option
diff --git a/src/backend/commands/proclang.c b/src/backend/commands/proclang.c
index 5036ac03639..d75e2fa74b2 100644
--- a/src/backend/commands/proclang.c
+++ b/src/backend/commands/proclang.c
@@ -13,6 +13,7 @@
  */
 #include "postgres.h"
 
+#include "access/htup_details.h"
 #include "access/table.h"
 #include "catalog/catalog.h"
 #include "catalog/dependency.h"
diff --git a/src/backend/commands/statscmds.c b/src/backend/commands/statscmds.c
index e24d540cd45..27bf67e7c4b 100644
--- a/src/backend/commands/statscmds.c
+++ b/src/backend/commands/statscmds.c
@@ -14,6 +14,7 @@
  */
 #include "postgres.h"
 
+#include "access/htup_details.h"
 #include "access/relation.h"
 #include "access/table.h"
 #include "catalog/catalog.h"
diff --git a/src/backend/executor/nodeGatherMerge.c b/src/backend/executor/nodeGatherMerge.c
index 15f84597067..93f3dbc6cf4 100644
--- a/src/backend/executor/nodeGatherMerge.c
+++ b/src/backend/executor/nodeGatherMerge.c
@@ -14,6 +14,7 @@
 
 #include "postgres.h"
 
+#include "access/htup_details.h"
 #include "executor/executor.h"
 #include "executor/execParallel.h"
 #include "executor/nodeGatherMerge.h"
diff --git a/src/backend/executor/nodeMemoize.c b/src/backend/executor/nodeMemoize.c
index 609deb12afb..d652663cb6a 100644
--- a/src/backend/executor/nodeMemoize.c
+++ b/src/backend/executor/nodeMemoize.c
@@ -66,6 +66,7 @@
 
 #include "postgres.h"
 
+#include "access/htup_details.h"
 #include "common/hashfn.h"
 #include "executor/executor.h"
 #include "executor/nodeMemoize.h"
diff --git a/src/backend/executor/tstoreReceiver.c b/src/backend/executor/tstoreReceiver.c
index 562de676457..02a3ad3aa68 100644
--- a/src/backend/executor/tstoreReceiver.c
+++ b/src/backend/executor/tstoreReceiver.c
@@ -25,6 +25,7 @@
 #include "access/detoast.h"
 #include "access/tupconvert.h"
 #include "executor/tstoreReceiver.h"
+#include "varatt.h"
 
 
 typedef struct
diff --git a/src/backend/optimizer/path/indxpath.c b/src/backend/optimizer/path/indxpath.c
index 3a3f55a236d..edc6d2ac1d3 100644
--- a/src/backend/optimizer/path/indxpath.c
+++ b/src/backend/optimizer/path/indxpath.c
@@ -19,6 +19,7 @@
 
 #include "access/stratnum.h"
 #include "access/sysattr.h"
+#include "access/transam.h"
 #include "catalog/pg_am.h"
 #include "catalog/pg_amop.h"
 #include "catalog/pg_operator.h"
diff --git a/src/backend/optimizer/util/pathnode.c b/src/backend/optimizer/util/pathnode.c
index b0da28150d3..bca51b4067b 100644
--- a/src/backend/optimizer/util/pathnode.c
+++ b/src/backend/optimizer/util/pathnode.c
@@ -16,6 +16,7 @@
 
 #include <math.h>
 
+#include "access/htup_details.h"
 #include "foreign/fdwapi.h"
 #include "miscadmin.h"
 #include "nodes/extensible.h"
diff --git a/src/backend/parser/parse_coerce.c b/src/backend/parser/parse_coerce.c
index 0b5b81c7f27..78b1e366ad7 100644
--- a/src/backend/parser/parse_coerce.c
+++ b/src/backend/parser/parse_coerce.c
@@ -14,6 +14,7 @@
  */
 #include "postgres.h"
 
+#include "access/htup_details.h"
 #include "catalog/pg_cast.h"
 #include "catalog/pg_class.h"
 #include "catalog/pg_inherits.h"
diff --git a/src/backend/parser/parse_expr.c b/src/backend/parser/parse_expr.c
index eebea694dda..72625a94dcc 100644
--- a/src/backend/parser/parse_expr.c
+++ b/src/backend/parser/parse_expr.c
@@ -15,6 +15,7 @@
 
 #include "postgres.h"
 
+#include "access/htup_details.h"
 #include "catalog/pg_aggregate.h"
 #include "catalog/pg_type.h"
 #include "miscadmin.h"
diff --git a/src/backend/utils/adt/arrayfuncs.c b/src/backend/utils/adt/arrayfuncs.c
index e5f3e2da35c..a8951f55b93 100644
--- a/src/backend/utils/adt/arrayfuncs.c
+++ b/src/backend/utils/adt/arrayfuncs.c
@@ -17,6 +17,7 @@
 #include <ctype.h>
 #include <math.h>
 
+#include "access/transam.h"
 #include "catalog/pg_type.h"
 #include "common/int.h"
 #include "funcapi.h"
diff --git a/src/backend/utils/adt/hbafuncs.c b/src/backend/utils/adt/hbafuncs.c
index b62c3d944cf..1614d6d2302 100644
--- a/src/backend/utils/adt/hbafuncs.c
+++ b/src/backend/utils/adt/hbafuncs.c
@@ -14,6 +14,7 @@
  */
 #include "postgres.h"
 
+#include "access/htup_details.h"
 #include "catalog/objectaddress.h"
 #include "common/ip.h"
 #include "funcapi.h"
diff --git a/src/backend/utils/adt/json.c b/src/backend/utils/adt/json.c
index e9d370cb3da..14f5cb498fc 100644
--- a/src/backend/utils/adt/json.c
+++ b/src/backend/utils/adt/json.c
@@ -13,6 +13,7 @@
  */
 #include "postgres.h"
 
+#include "access/htup_details.h"
 #include "catalog/pg_proc.h"
 #include "catalog/pg_type.h"
 #include "common/hashfn.h"
diff --git a/src/backend/utils/adt/misc.c b/src/backend/utils/adt/misc.c
index 2c5a7ee9ddc..7cb7716e58b 100644
--- a/src/backend/utils/adt/misc.c
+++ b/src/backend/utils/adt/misc.c
@@ -21,6 +21,7 @@
 #include <math.h>
 #include <unistd.h>
 
+#include "access/htup_details.h"
 #include "access/sysattr.h"
 #include "access/table.h"
 #include "catalog/pg_tablespace.h"
diff --git a/src/backend/utils/adt/rangetypes.c b/src/backend/utils/adt/rangetypes.c
index 18e467bccd3..0b2ad8b0975 100644
--- a/src/backend/utils/adt/rangetypes.c
+++ b/src/backend/utils/adt/rangetypes.c
@@ -45,6 +45,7 @@
 #include "utils/rangetypes.h"
 #include "utils/sortsupport.h"
 #include "utils/timestamp.h"
+#include "varatt.h"
 
 
 /* fn_extra cache entry for one of the range I/O functions */
diff --git a/src/backend/utils/adt/xid8funcs.c b/src/backend/utils/adt/xid8funcs.c
index 1da3964ca6f..a211a107767 100644
--- a/src/backend/utils/adt/xid8funcs.c
+++ b/src/backend/utils/adt/xid8funcs.c
@@ -39,6 +39,7 @@
 #include "utils/memutils.h"
 #include "utils/snapmgr.h"
 #include "utils/xid8.h"
+#include "varatt.h"
 
 
 /*
diff --git a/src/backend/utils/fmgr/fmgr.c b/src/backend/utils/fmgr/fmgr.c
index b4c1e2c4b21..0fe63c6bb83 100644
--- a/src/backend/utils/fmgr/fmgr.c
+++ b/src/backend/utils/fmgr/fmgr.c
@@ -16,6 +16,7 @@
 #include "postgres.h"
 
 #include "access/detoast.h"
+#include "access/htup_details.h"
 #include "catalog/pg_language.h"
 #include "catalog/pg_proc.h"
 #include "catalog/pg_type.h"
diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c
index 46fdefebe35..107b5a273a2 100644
--- a/src/backend/utils/misc/guc.c
+++ b/src/backend/utils/misc/guc.c
@@ -34,6 +34,7 @@
 #include "catalog/objectaccess.h"
 #include "catalog/pg_authid.h"
 #include "catalog/pg_parameter_acl.h"
+#include "catalog/pg_type.h"
 #include "guc_internal.h"
 #include "libpq/pqformat.h"
 #include "libpq/protocol.h"
diff --git a/src/include/access/gin_private.h b/src/include/access/gin_private.h
index aee1f70c22e..9ea303a7c1b 100644
--- a/src/include/access/gin_private.h
+++ b/src/include/access/gin_private.h
@@ -13,6 +13,7 @@
 #include "access/amapi.h"
 #include "access/gin.h"
 #include "access/ginblock.h"
+#include "access/htup_details.h"
 #include "access/itup.h"
 #include "common/int.h"
 #include "catalog/pg_am_d.h"
diff --git a/src/include/executor/tuptable.h b/src/include/executor/tuptable.h
index 095e4cc82e3..43f1d999b91 100644
--- a/src/include/executor/tuptable.h
+++ b/src/include/executor/tuptable.h
@@ -15,7 +15,6 @@
 #define TUPTABLE_H
 
 #include "access/htup.h"
-#include "access/htup_details.h"
 #include "access/sysattr.h"
 #include "access/tupdesc.h"
 #include "storage/buf.h"
diff --git a/src/test/modules/injection_points/injection_stats_fixed.c b/src/test/modules/injection_points/injection_stats_fixed.c
index 74c35fcbfa7..b493e8f77a3 100644
--- a/src/test/modules/injection_points/injection_stats_fixed.c
+++ b/src/test/modules/injection_points/injection_stats_fixed.c
@@ -16,6 +16,7 @@
 
 #include "fmgr.h"
 
+#include "access/htup_details.h"
 #include "common/hashfn.h"
 #include "funcapi.h"
 #include "injection_stats.h"
-- 
2.47.3

#22Álvaro Herrera
alvherre@kurilemu.de
In reply to: Álvaro Herrera (#18)
5 attachment(s)
Re: allow benign typedef redefinitions (C11)

On 2025-Sep-29, Álvaro Herrera wrote:

I've been looking at removing some includes from a few more headers, but
I'm not happy with the overall achievement, or at least I don't have a
good metric to present as a win. So I'll leave that for another day and
maybe present a different way to look at the problem.

Okay, I couldn't put this down. I wrote a script that greps for all the
"#include" lines in headers and in backend .c files, and put them in a
database. With that I can figure out the complete list of headers used
by each source file (recursively), which allows to me know how many
source files are including each header file. The script is attached, in
case anyone is curious. I didn't bother to optimize it, because I
wasn't going to run it many times anyway.

Using the numbers so obtained and the patches I've been looking at, I
can quantify the reduction in total header usage for each commit, so I
know whether any particular change is quantitatively worthwhile or not,
beyond qualitative modularity considerations.

So, for patch 0001, we can see a massive decrease of .c files that use
each of a bunch of .h files (the first column is the number of .c files
that include that particular .h file before patch; the second column is
the same number, after patch; third column is the difference):

include │ orig # included │ final # included │ difference
────────────────────────┼─────────────────┼──────────────────┼────────────
nodes/nodes.h │ 5501 │ 5130 │ 371
nodes/pg_list.h │ 4463 │ 4092 │ 371
storage/off.h │ 3943 │ 3424 │ 519
common/relpath.h │ 3917 │ 3600 │ 317
nodes/bitmapset.h │ 3888 │ 3562 │ 326
storage/itemptr.h │ 3638 │ 3119 │ 519
catalog/pg_attribute.h │ 3575 │ 3207 │ 368
access/tupdesc.h │ 3573 │ 3205 │ 368
access/htup.h │ 3297 │ 2778 │ 519
storage/dsm.h │ 3273 │ 1972 │ 1301
utils/relcache.h │ 2767 │ 2389 │ 378
port/atomics.h │ 2734 │ 1751 │ 983
lib/pairingheap.h │ 2211 │ 1629 │ 582
utils/dsa.h │ 2163 │ 1082 │ 1081
utils/snapshot.h │ 1863 │ 1282 │ 581
nodes/tidbitmap.h │ 1508 │ 924 │ 584
utils/sortsupport.h │ 1489 │ 1076 │ 413
access/skey.h │ 1020 │ 909 │ 111
access/genam.h │ 976 │ 393 │ 583
access/amapi.h │ 725 │ 140 │ 585
utils/typcache.h │ 667 │ 85 │ 582
access/brin_internal.h │ 607 │ 21 │ 586
access/ginblock.h │ 606 │ 20 │ 586
access/brin_tuple.h │ 601 │ 15 │ 586
access/gin_tuple.h │ 588 │ 2 │ 586
(25 filas)

Patch 0002 doesn't cause a reduction in as many header files, but it's
still quite impressive that htup_details.h is no longer included by a
thousand header files:

include │ orig # included │ final # included │ difference
────────────────────────┼─────────────────┼──────────────────┼────────────
nodes/nodes.h │ 5130 │ 5050 │ 80
nodes/pg_list.h │ 4092 │ 4007 │ 85
storage/off.h │ 3424 │ 2957 │ 467
catalog/pg_attribute.h │ 3207 │ 3110 │ 97
access/tupdesc.h │ 3205 │ 3108 │ 97
storage/itemptr.h │ 3119 │ 2636 │ 483
access/htup.h │ 2778 │ 2283 │ 495
access/transam.h │ 2540 │ 1923 │ 617
storage/bufpage.h │ 1882 │ 1268 │ 614
access/tupmacs.h │ 1692 │ 1077 │ 615
access/htup_details.h │ 1375 │ 500 │ 875

Patch 0003 has a negiglible impact though (which makes sense given what
it does):

include │ orig # included │ final # included │ difference
─────────────────────┼─────────────────┼──────────────────┼────────────
storage/off.h │ 2957 │ 2954 │ 3
storage/itemptr.h │ 2636 │ 2633 │ 3
access/htup.h │ 2283 │ 2280 │ 3
executor/tuptable.h │ 1115 │ 1112 │ 3
(4 filas)

But patch 0004 again removes inclusion of a large number of headers,
though from not as many .c files:

include │ orig # included │ final # included │ difference
──────────────────────────────┼─────────────────┼──────────────────┼────────────
nodes/nodes.h │ 5050 │ 5008 │ 42
nodes/pg_list.h │ 4007 │ 3964 │ 43
common/relpath.h │ 3600 │ 3574 │ 26
nodes/bitmapset.h │ 3562 │ 3531 │ 31
catalog/pg_attribute.h │ 3110 │ 3067 │ 43
access/tupdesc.h │ 3108 │ 3065 │ 43
storage/off.h │ 2954 │ 2913 │ 41
storage/itemptr.h │ 2633 │ 2592 │ 41
utils/relcache.h │ 2389 │ 2350 │ 39
access/htup.h │ 2280 │ 2243 │ 37
storage/spin.h │ 2217 │ 2177 │ 40
nodes/primnodes.h │ 1975 │ 1965 │ 10
storage/dsm.h │ 1972 │ 1952 │ 20
storage/fd.h │ 1948 │ 1863 │ 85
port/atomics.h │ 1751 │ 1746 │ 5
lib/pairingheap.h │ 1629 │ 1606 │ 23
storage/proclist_types.h │ 1508 │ 1492 │ 16
utils/snapshot.h │ 1282 │ 1275 │ 7
storage/bufpage.h │ 1268 │ 1246 │ 22
executor/tuptable.h │ 1112 │ 1090 │ 22
utils/dsa.h │ 1082 │ 1077 │ 5
access/tupmacs.h │ 1077 │ 1055 │ 22
utils/sortsupport.h │ 1076 │ 1033 │ 43
storage/fileset.h │ 1073 │ 1030 │ 43
nodes/memnodes.h │ 1028 │ 1007 │ 21
storage/sharedfileset.h │ 1027 │ 984 │ 43
utils/memutils.h │ 1026 │ 1005 │ 21
nodes/tidbitmap.h │ 924 │ 917 │ 7
utils/queryenvironment.h │ 913 │ 892 │ 21
access/skey.h │ 909 │ 902 │ 7
access/itup.h │ 785 │ 763 │ 22
nodes/plannodes.h │ 694 │ 672 │ 22
storage/condition_variable.h │ 676 │ 654 │ 22
utils/tuplestore.h │ 635 │ 613 │ 22
executor/instrument.h │ 601 │ 579 │ 22
nodes/miscnodes.h │ 600 │ 578 │ 22
access/attmap.h │ 593 │ 571 │ 22
utils/logtape.h │ 588 │ 566 │ 22
utils/tuplesort.h │ 585 │ 563 │ 22
lib/simplehash.h │ 581 │ 559 │ 22
access/tupconvert.h │ 575 │ 553 │ 22
utils/sharedtuplestore.h │ 573 │ 551 │ 22
nodes/execnodes.h │ 570 │ 548 │ 22
(43 filas)

My inclination at this point is to apply all four, because the
modularity wins are pretty obvious. Of course there are other ways to
look at the data (in particular: number of .h files that each other .h
cascades to), but I'm going to stop here.

--
Álvaro Herrera PostgreSQL Developer — https://www.EnterpriseDB.com/
"Oh, great altar of passive entertainment, bestow upon me thy discordant images
at such speed as to render linear thought impossible" (Calvin a la TV)

Attachments:

0001-Remove-brin-gin_tuple.h-from-tuplesort.h.patchtext/x-diff; charset=utf-8Download
From 30d4c9cf79e10a019a1de62e71d36edce2fa0c98 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=C3=81lvaro=20Herrera?= <alvherre@kurilemu.de>
Date: Tue, 30 Sep 2025 12:36:49 +0200
Subject: [PATCH 1/4] Remove brin/gin_tuple.h from tuplesort.h

Because execnodes.h depends on struct definitions that were in genam.h,
which it no longer gets because of the aforementioned removal, split
those struct definitions to a separate header file.
---
 contrib/bloom/blscan.c                     |  1 +
 contrib/pageinspect/gistfuncs.c            |  1 +
 src/backend/access/gin/gininsert.c         |  3 +-
 src/backend/access/gist/gistget.c          |  1 +
 src/backend/access/hash/hashsearch.c       |  1 +
 src/backend/access/nbtree/nbtsearch.c      |  1 +
 src/backend/access/spgist/spgscan.c        |  1 +
 src/backend/catalog/pg_attrdef.c           |  1 +
 src/backend/catalog/pg_largeobject.c       |  1 +
 src/backend/executor/execReplication.c     |  1 +
 src/backend/parser/parse_expr.c            |  1 +
 src/backend/replication/logical/relation.c |  1 +
 src/backend/statistics/attribute_stats.c   |  1 +
 src/include/access/genam.h                 | 24 ++-----------
 src/include/executor/instrument_node.h     | 40 ++++++++++++++++++++++
 src/include/nodes/execnodes.h              |  2 ++
 src/include/utils/tuplesort.h              |  6 ++--
 17 files changed, 63 insertions(+), 24 deletions(-)
 create mode 100644 src/include/executor/instrument_node.h

diff --git a/contrib/bloom/blscan.c b/contrib/bloom/blscan.c
index d072f47fe28..5f8378d1f44 100644
--- a/contrib/bloom/blscan.c
+++ b/contrib/bloom/blscan.c
@@ -14,6 +14,7 @@
 
 #include "access/relscan.h"
 #include "bloom.h"
+#include "executor/instrument_node.h"
 #include "miscadmin.h"
 #include "pgstat.h"
 #include "storage/bufmgr.h"
diff --git a/contrib/pageinspect/gistfuncs.c b/contrib/pageinspect/gistfuncs.c
index 1b299374890..fab6e8d35ad 100644
--- a/contrib/pageinspect/gistfuncs.c
+++ b/contrib/pageinspect/gistfuncs.c
@@ -9,6 +9,7 @@
  */
 #include "postgres.h"
 
+#include "access/genam.h"
 #include "access/gist.h"
 #include "access/htup.h"
 #include "access/relation.h"
diff --git a/src/backend/access/gin/gininsert.c b/src/backend/access/gin/gininsert.c
index e9d4b27427e..43c007b6204 100644
--- a/src/backend/access/gin/gininsert.c
+++ b/src/backend/access/gin/gininsert.c
@@ -29,10 +29,11 @@
 #include "storage/bufmgr.h"
 #include "storage/predicate.h"
 #include "tcop/tcopprot.h"
+#include "utils/builtins.h"
 #include "utils/datum.h"
 #include "utils/memutils.h"
 #include "utils/rel.h"
-#include "utils/builtins.h"
+#include "utils/typcache.h"
 
 
 /* Magic numbers for parallel state sharing */
diff --git a/src/backend/access/gist/gistget.c b/src/backend/access/gist/gistget.c
index 387d9972345..aa56ef430a9 100644
--- a/src/backend/access/gist/gistget.c
+++ b/src/backend/access/gist/gistget.c
@@ -17,6 +17,7 @@
 #include "access/genam.h"
 #include "access/gist_private.h"
 #include "access/relscan.h"
+#include "executor/instrument_node.h"
 #include "lib/pairingheap.h"
 #include "miscadmin.h"
 #include "pgstat.h"
diff --git a/src/backend/access/hash/hashsearch.c b/src/backend/access/hash/hashsearch.c
index 92c15a65be2..00395b01f60 100644
--- a/src/backend/access/hash/hashsearch.c
+++ b/src/backend/access/hash/hashsearch.c
@@ -17,6 +17,7 @@
 #include "access/hash.h"
 #include "access/relscan.h"
 #include "miscadmin.h"
+#include "executor/instrument_node.h"
 #include "pgstat.h"
 #include "storage/predicate.h"
 #include "utils/rel.h"
diff --git a/src/backend/access/nbtree/nbtsearch.c b/src/backend/access/nbtree/nbtsearch.c
index d69798795b4..5c6dc3b183e 100644
--- a/src/backend/access/nbtree/nbtsearch.c
+++ b/src/backend/access/nbtree/nbtsearch.c
@@ -18,6 +18,7 @@
 #include "access/nbtree.h"
 #include "access/relscan.h"
 #include "access/xact.h"
+#include "executor/instrument_node.h"
 #include "miscadmin.h"
 #include "pgstat.h"
 #include "storage/predicate.h"
diff --git a/src/backend/access/spgist/spgscan.c b/src/backend/access/spgist/spgscan.c
index 25893050c58..abfb3555af5 100644
--- a/src/backend/access/spgist/spgscan.c
+++ b/src/backend/access/spgist/spgscan.c
@@ -18,6 +18,7 @@
 #include "access/genam.h"
 #include "access/relscan.h"
 #include "access/spgist_private.h"
+#include "executor/instrument_node.h"
 #include "miscadmin.h"
 #include "pgstat.h"
 #include "storage/bufmgr.h"
diff --git a/src/backend/catalog/pg_attrdef.c b/src/backend/catalog/pg_attrdef.c
index 1b6270b1213..4db4ffd657c 100644
--- a/src/backend/catalog/pg_attrdef.c
+++ b/src/backend/catalog/pg_attrdef.c
@@ -14,6 +14,7 @@
  */
 #include "postgres.h"
 
+#include "access/genam.h"
 #include "access/relation.h"
 #include "access/table.h"
 #include "catalog/dependency.h"
diff --git a/src/backend/catalog/pg_largeobject.c b/src/backend/catalog/pg_largeobject.c
index 89fc8102150..471f82f51a8 100644
--- a/src/backend/catalog/pg_largeobject.c
+++ b/src/backend/catalog/pg_largeobject.c
@@ -14,6 +14,7 @@
  */
 #include "postgres.h"
 
+#include "access/genam.h"
 #include "access/table.h"
 #include "catalog/catalog.h"
 #include "catalog/indexing.h"
diff --git a/src/backend/executor/execReplication.c b/src/backend/executor/execReplication.c
index b409d4ecbf5..ab585aa9819 100644
--- a/src/backend/executor/execReplication.c
+++ b/src/backend/executor/execReplication.c
@@ -14,6 +14,7 @@
 
 #include "postgres.h"
 
+#include "access/amapi.h"
 #include "access/commit_ts.h"
 #include "access/genam.h"
 #include "access/gist.h"
diff --git a/src/backend/parser/parse_expr.c b/src/backend/parser/parse_expr.c
index e1979a80c19..eebea694dda 100644
--- a/src/backend/parser/parse_expr.c
+++ b/src/backend/parser/parse_expr.c
@@ -37,6 +37,7 @@
 #include "utils/fmgroids.h"
 #include "utils/lsyscache.h"
 #include "utils/timestamp.h"
+#include "utils/typcache.h"
 #include "utils/xml.h"
 
 /* GUC parameters */
diff --git a/src/backend/replication/logical/relation.c b/src/backend/replication/logical/relation.c
index f59046ad620..85f55b75c66 100644
--- a/src/backend/replication/logical/relation.c
+++ b/src/backend/replication/logical/relation.c
@@ -29,6 +29,7 @@
 #include "utils/inval.h"
 #include "utils/lsyscache.h"
 #include "utils/syscache.h"
+#include "utils/typcache.h"
 
 
 static MemoryContext LogicalRepRelMapContext = NULL;
diff --git a/src/backend/statistics/attribute_stats.c b/src/backend/statistics/attribute_stats.c
index 1db6a7f784c..4e8efcdf55b 100644
--- a/src/backend/statistics/attribute_stats.c
+++ b/src/backend/statistics/attribute_stats.c
@@ -29,6 +29,7 @@
 #include "utils/fmgroids.h"
 #include "utils/lsyscache.h"
 #include "utils/syscache.h"
+#include "utils/typcache.h"
 
 #define DEFAULT_NULL_FRAC      Float4GetDatum(0.0)
 #define DEFAULT_AVG_WIDTH      Int32GetDatum(0) /* unknown */
diff --git a/src/include/access/genam.h b/src/include/access/genam.h
index 9200a22bd9f..b18a7e4f5db 100644
--- a/src/include/access/genam.h
+++ b/src/include/access/genam.h
@@ -29,27 +29,9 @@ typedef struct TupleTableSlot TupleTableSlot;
 /* or relcache.h */
 typedef struct RelationData *Relation;
 
-
-/*
- * Struct for statistics maintained by amgettuple and amgetbitmap
- *
- * Note: IndexScanInstrumentation can't contain any pointers, since it is
- * copied into a SharedIndexScanInstrumentation during parallel scans
- */
-typedef struct IndexScanInstrumentation
-{
-	/* Index search count (incremented with pgstat_count_index_scan call) */
-	uint64		nsearches;
-} IndexScanInstrumentation;
-
-/*
- * Struct for every worker's IndexScanInstrumentation, stored in shared memory
- */
-typedef struct SharedIndexScanInstrumentation
-{
-	int			num_workers;
-	IndexScanInstrumentation winstrument[FLEXIBLE_ARRAY_MEMBER];
-} SharedIndexScanInstrumentation;
+/* XXX maybe include the other file here instead of this? */
+typedef struct IndexScanInstrumentation IndexScanInstrumentation;
+typedef struct SharedIndexScanInstrumentation SharedIndexScanInstrumentation;
 
 /*
  * Struct for statistics returned by ambuild
diff --git a/src/include/executor/instrument_node.h b/src/include/executor/instrument_node.h
new file mode 100644
index 00000000000..1af07c03a3e
--- /dev/null
+++ b/src/include/executor/instrument_node.h
@@ -0,0 +1,40 @@
+/*-------------------------------------------------------------------------
+ *
+ * instrument_node.h
+ *	  Definitions for node-specific instrumentation
+ *
+ *
+ * Portions Copyright (c) 1996-2025, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1994, Regents of the University of California
+ *
+ * src/include/executor/instrument_node.h
+ *
+ *-------------------------------------------------------------------------
+ */
+#ifndef INSTRUMENT_NODE_H
+#define INSTRUMENT_NODE_H
+
+
+/*
+ * Struct for statistics maintained by amgettuple and amgetbitmap
+ *
+ * Note: IndexScanInstrumentation can't contain any pointers, since it is
+ * copied into a SharedIndexScanInstrumentation during parallel scans
+ */
+typedef struct IndexScanInstrumentation
+{
+	/* Index search count (incremented with pgstat_count_index_scan call) */
+	uint64		nsearches;
+} IndexScanInstrumentation;
+
+/*
+ * Struct for every worker's IndexScanInstrumentation, stored in shared memory
+ */
+typedef struct SharedIndexScanInstrumentation
+{
+	int			num_workers;
+	IndexScanInstrumentation winstrument[FLEXIBLE_ARRAY_MEMBER];
+} SharedIndexScanInstrumentation;
+
+
+#endif							/* INSTRUMENT_NODE_H */
diff --git a/src/include/nodes/execnodes.h b/src/include/nodes/execnodes.h
index a36653c37f9..4bf733bc8e1 100644
--- a/src/include/nodes/execnodes.h
+++ b/src/include/nodes/execnodes.h
@@ -29,8 +29,10 @@
 #ifndef EXECNODES_H
 #define EXECNODES_H
 
+#include "access/skey.h"
 #include "access/tupconvert.h"
 #include "executor/instrument.h"
+#include "executor/instrument_node.h"
 #include "fmgr.h"
 #include "lib/ilist.h"
 #include "lib/pairingheap.h"
diff --git a/src/include/utils/tuplesort.h b/src/include/utils/tuplesort.h
index ef79f259f93..8278beea5ec 100644
--- a/src/include/utils/tuplesort.h
+++ b/src/include/utils/tuplesort.h
@@ -21,8 +21,6 @@
 #ifndef TUPLESORT_H
 #define TUPLESORT_H
 
-#include "access/brin_tuple.h"
-#include "access/gin_tuple.h"
 #include "access/itup.h"
 #include "executor/tuptable.h"
 #include "storage/dsm.h"
@@ -31,6 +29,10 @@
 #include "utils/sortsupport.h"
 
 
+/* We don't want this file to depend on AM-specific header files */
+typedef struct BrinTuple BrinTuple;
+typedef struct GinTuple GinTuple;
+
 /*
  * Tuplesortstate and Sharedsort are opaque types whose details are not
  * known outside tuplesort.c.
-- 
2.47.3

0002-Don-t-include-access-htup_details.h-in-executor-tupt.patchtext/x-diff; charset=utf-8Download
From 6969dbfe045c58444eff9138b45c24c8873a0b53 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=C3=81lvaro=20Herrera?= <alvherre@kurilemu.de>
Date: Tue, 30 Sep 2025 16:16:04 +0200
Subject: [PATCH 2/4] Don't include access/htup_details.h in
 executor/tuptable.h

This is not at all needed; I suspect it was a simple mistake in commit
5408e233f066.  It causes htup_details.h to bleed into a huge number of
places via execnodes.h.  Remove it and fix fallout.
---
 contrib/pageinspect/btreefuncs.c                          | 1 +
 contrib/pageinspect/gistfuncs.c                           | 1 +
 contrib/pg_stat_statements/pg_stat_statements.c           | 1 +
 contrib/pg_walinspect/pg_walinspect.c                     | 1 +
 contrib/postgres_fdw/connection.c                         | 1 +
 contrib/xml2/xslt_proc.c                                  | 1 +
 src/backend/access/common/printsimple.c                   | 1 +
 src/backend/access/common/printtup.c                      | 1 +
 src/backend/access/common/tupconvert.c                    | 1 +
 src/backend/backup/walsummaryfuncs.c                      | 1 +
 src/backend/catalog/pg_attrdef.c                          | 1 +
 src/backend/catalog/pg_largeobject.c                      | 1 +
 src/backend/catalog/pg_parameter_acl.c                    | 1 +
 src/backend/commands/explain_dr.c                         | 1 +
 src/backend/commands/proclang.c                           | 1 +
 src/backend/commands/statscmds.c                          | 1 +
 src/backend/executor/nodeGatherMerge.c                    | 1 +
 src/backend/executor/nodeMemoize.c                        | 1 +
 src/backend/executor/tstoreReceiver.c                     | 1 +
 src/backend/optimizer/path/indxpath.c                     | 1 +
 src/backend/optimizer/util/pathnode.c                     | 1 +
 src/backend/parser/parse_coerce.c                         | 1 +
 src/backend/parser/parse_expr.c                           | 1 +
 src/backend/utils/adt/arrayfuncs.c                        | 1 +
 src/backend/utils/adt/hbafuncs.c                          | 1 +
 src/backend/utils/adt/json.c                              | 1 +
 src/backend/utils/adt/misc.c                              | 1 +
 src/backend/utils/adt/rangetypes.c                        | 1 +
 src/backend/utils/adt/xid8funcs.c                         | 1 +
 src/backend/utils/fmgr/fmgr.c                             | 1 +
 src/backend/utils/misc/guc.c                              | 1 +
 src/include/access/gin_private.h                          | 1 +
 src/include/executor/tuptable.h                           | 1 -
 src/test/modules/injection_points/injection_stats_fixed.c | 1 +
 34 files changed, 33 insertions(+), 1 deletion(-)

diff --git a/contrib/pageinspect/btreefuncs.c b/contrib/pageinspect/btreefuncs.c
index 4e2e8891cdd..2e67c9adf5a 100644
--- a/contrib/pageinspect/btreefuncs.c
+++ b/contrib/pageinspect/btreefuncs.c
@@ -27,6 +27,7 @@
 
 #include "postgres.h"
 
+#include "access/htup_details.h"
 #include "access/nbtree.h"
 #include "access/relation.h"
 #include "catalog/namespace.h"
diff --git a/contrib/pageinspect/gistfuncs.c b/contrib/pageinspect/gistfuncs.c
index fab6e8d35ad..190353ec354 100644
--- a/contrib/pageinspect/gistfuncs.c
+++ b/contrib/pageinspect/gistfuncs.c
@@ -12,6 +12,7 @@
 #include "access/genam.h"
 #include "access/gist.h"
 #include "access/htup.h"
+#include "access/htup_details.h"
 #include "access/relation.h"
 #include "catalog/pg_am_d.h"
 #include "funcapi.h"
diff --git a/contrib/pg_stat_statements/pg_stat_statements.c b/contrib/pg_stat_statements/pg_stat_statements.c
index 0bb0f933399..db1af36a705 100644
--- a/contrib/pg_stat_statements/pg_stat_statements.c
+++ b/contrib/pg_stat_statements/pg_stat_statements.c
@@ -47,6 +47,7 @@
 #include <sys/stat.h>
 #include <unistd.h>
 
+#include "access/htup_details.h"
 #include "access/parallel.h"
 #include "catalog/pg_authid.h"
 #include "common/int.h"
diff --git a/contrib/pg_walinspect/pg_walinspect.c b/contrib/pg_walinspect/pg_walinspect.c
index 0398ad82cec..501cea8fc1a 100644
--- a/contrib/pg_walinspect/pg_walinspect.c
+++ b/contrib/pg_walinspect/pg_walinspect.c
@@ -12,6 +12,7 @@
  */
 #include "postgres.h"
 
+#include "access/htup_details.h"
 #include "access/xlog.h"
 #include "access/xlog_internal.h"
 #include "access/xlogreader.h"
diff --git a/contrib/postgres_fdw/connection.c b/contrib/postgres_fdw/connection.c
index 4fbb6c182b8..953c2e0ab82 100644
--- a/contrib/postgres_fdw/connection.c
+++ b/contrib/postgres_fdw/connection.c
@@ -16,6 +16,7 @@
 #include <poll.h>
 #endif
 
+#include "access/htup_details.h"
 #include "access/xact.h"
 #include "catalog/pg_user_mapping.h"
 #include "commands/defrem.h"
diff --git a/contrib/xml2/xslt_proc.c b/contrib/xml2/xslt_proc.c
index 53550c7dc24..36578b82e4d 100644
--- a/contrib/xml2/xslt_proc.c
+++ b/contrib/xml2/xslt_proc.c
@@ -10,6 +10,7 @@
 #include "fmgr.h"
 #include "utils/builtins.h"
 #include "utils/xml.h"
+#include "varatt.h"
 
 #ifdef USE_LIBXSLT
 
diff --git a/src/backend/access/common/printsimple.c b/src/backend/access/common/printsimple.c
index a09c8fcd332..756f1c4822d 100644
--- a/src/backend/access/common/printsimple.c
+++ b/src/backend/access/common/printsimple.c
@@ -23,6 +23,7 @@
 #include "libpq/pqformat.h"
 #include "libpq/protocol.h"
 #include "utils/builtins.h"
+#include "varatt.h"
 
 /*
  * At startup time, send a RowDescription message.
diff --git a/src/backend/access/common/printtup.c b/src/backend/access/common/printtup.c
index 6d3045e2332..9f05e1d15bd 100644
--- a/src/backend/access/common/printtup.c
+++ b/src/backend/access/common/printtup.c
@@ -22,6 +22,7 @@
 #include "utils/lsyscache.h"
 #include "utils/memdebug.h"
 #include "utils/memutils.h"
+#include "varatt.h"
 
 
 static void printtup_startup(DestReceiver *self, int operation,
diff --git a/src/backend/access/common/tupconvert.c b/src/backend/access/common/tupconvert.c
index 54dc2f4ab80..1df0c2d2f98 100644
--- a/src/backend/access/common/tupconvert.c
+++ b/src/backend/access/common/tupconvert.c
@@ -18,6 +18,7 @@
  */
 #include "postgres.h"
 
+#include "access/htup_details.h"
 #include "access/tupconvert.h"
 #include "executor/tuptable.h"
 
diff --git a/src/backend/backup/walsummaryfuncs.c b/src/backend/backup/walsummaryfuncs.c
index d6dd131da14..29e2cb83ff4 100644
--- a/src/backend/backup/walsummaryfuncs.c
+++ b/src/backend/backup/walsummaryfuncs.c
@@ -12,6 +12,7 @@
 
 #include "postgres.h"
 
+#include "access/htup_details.h"
 #include "backup/walsummary.h"
 #include "common/blkreftable.h"
 #include "funcapi.h"
diff --git a/src/backend/catalog/pg_attrdef.c b/src/backend/catalog/pg_attrdef.c
index 4db4ffd657c..e8bdb52cb00 100644
--- a/src/backend/catalog/pg_attrdef.c
+++ b/src/backend/catalog/pg_attrdef.c
@@ -15,6 +15,7 @@
 #include "postgres.h"
 
 #include "access/genam.h"
+#include "access/htup_details.h"
 #include "access/relation.h"
 #include "access/table.h"
 #include "catalog/dependency.h"
diff --git a/src/backend/catalog/pg_largeobject.c b/src/backend/catalog/pg_largeobject.c
index 471f82f51a8..ada4c3685e0 100644
--- a/src/backend/catalog/pg_largeobject.c
+++ b/src/backend/catalog/pg_largeobject.c
@@ -15,6 +15,7 @@
 #include "postgres.h"
 
 #include "access/genam.h"
+#include "access/htup_details.h"
 #include "access/table.h"
 #include "catalog/catalog.h"
 #include "catalog/indexing.h"
diff --git a/src/backend/catalog/pg_parameter_acl.c b/src/backend/catalog/pg_parameter_acl.c
index 62a05783eb3..dcdf49ea408 100644
--- a/src/backend/catalog/pg_parameter_acl.c
+++ b/src/backend/catalog/pg_parameter_acl.c
@@ -14,6 +14,7 @@
  */
 #include "postgres.h"
 
+#include "access/htup_details.h"
 #include "access/table.h"
 #include "catalog/catalog.h"
 #include "catalog/indexing.h"
diff --git a/src/backend/commands/explain_dr.c b/src/backend/commands/explain_dr.c
index d6084077be7..95685d7e88d 100644
--- a/src/backend/commands/explain_dr.c
+++ b/src/backend/commands/explain_dr.c
@@ -19,6 +19,7 @@
 #include "libpq/pqformat.h"
 #include "libpq/protocol.h"
 #include "utils/lsyscache.h"
+#include "varatt.h"
 
 /*
  * DestReceiver functions for SERIALIZE option
diff --git a/src/backend/commands/proclang.c b/src/backend/commands/proclang.c
index 5036ac03639..d75e2fa74b2 100644
--- a/src/backend/commands/proclang.c
+++ b/src/backend/commands/proclang.c
@@ -13,6 +13,7 @@
  */
 #include "postgres.h"
 
+#include "access/htup_details.h"
 #include "access/table.h"
 #include "catalog/catalog.h"
 #include "catalog/dependency.h"
diff --git a/src/backend/commands/statscmds.c b/src/backend/commands/statscmds.c
index e24d540cd45..27bf67e7c4b 100644
--- a/src/backend/commands/statscmds.c
+++ b/src/backend/commands/statscmds.c
@@ -14,6 +14,7 @@
  */
 #include "postgres.h"
 
+#include "access/htup_details.h"
 #include "access/relation.h"
 #include "access/table.h"
 #include "catalog/catalog.h"
diff --git a/src/backend/executor/nodeGatherMerge.c b/src/backend/executor/nodeGatherMerge.c
index 15f84597067..93f3dbc6cf4 100644
--- a/src/backend/executor/nodeGatherMerge.c
+++ b/src/backend/executor/nodeGatherMerge.c
@@ -14,6 +14,7 @@
 
 #include "postgres.h"
 
+#include "access/htup_details.h"
 #include "executor/executor.h"
 #include "executor/execParallel.h"
 #include "executor/nodeGatherMerge.h"
diff --git a/src/backend/executor/nodeMemoize.c b/src/backend/executor/nodeMemoize.c
index 609deb12afb..d652663cb6a 100644
--- a/src/backend/executor/nodeMemoize.c
+++ b/src/backend/executor/nodeMemoize.c
@@ -66,6 +66,7 @@
 
 #include "postgres.h"
 
+#include "access/htup_details.h"
 #include "common/hashfn.h"
 #include "executor/executor.h"
 #include "executor/nodeMemoize.h"
diff --git a/src/backend/executor/tstoreReceiver.c b/src/backend/executor/tstoreReceiver.c
index 562de676457..02a3ad3aa68 100644
--- a/src/backend/executor/tstoreReceiver.c
+++ b/src/backend/executor/tstoreReceiver.c
@@ -25,6 +25,7 @@
 #include "access/detoast.h"
 #include "access/tupconvert.h"
 #include "executor/tstoreReceiver.h"
+#include "varatt.h"
 
 
 typedef struct
diff --git a/src/backend/optimizer/path/indxpath.c b/src/backend/optimizer/path/indxpath.c
index 3a3f55a236d..edc6d2ac1d3 100644
--- a/src/backend/optimizer/path/indxpath.c
+++ b/src/backend/optimizer/path/indxpath.c
@@ -19,6 +19,7 @@
 
 #include "access/stratnum.h"
 #include "access/sysattr.h"
+#include "access/transam.h"
 #include "catalog/pg_am.h"
 #include "catalog/pg_amop.h"
 #include "catalog/pg_operator.h"
diff --git a/src/backend/optimizer/util/pathnode.c b/src/backend/optimizer/util/pathnode.c
index b0da28150d3..bca51b4067b 100644
--- a/src/backend/optimizer/util/pathnode.c
+++ b/src/backend/optimizer/util/pathnode.c
@@ -16,6 +16,7 @@
 
 #include <math.h>
 
+#include "access/htup_details.h"
 #include "foreign/fdwapi.h"
 #include "miscadmin.h"
 #include "nodes/extensible.h"
diff --git a/src/backend/parser/parse_coerce.c b/src/backend/parser/parse_coerce.c
index 0b5b81c7f27..78b1e366ad7 100644
--- a/src/backend/parser/parse_coerce.c
+++ b/src/backend/parser/parse_coerce.c
@@ -14,6 +14,7 @@
  */
 #include "postgres.h"
 
+#include "access/htup_details.h"
 #include "catalog/pg_cast.h"
 #include "catalog/pg_class.h"
 #include "catalog/pg_inherits.h"
diff --git a/src/backend/parser/parse_expr.c b/src/backend/parser/parse_expr.c
index eebea694dda..72625a94dcc 100644
--- a/src/backend/parser/parse_expr.c
+++ b/src/backend/parser/parse_expr.c
@@ -15,6 +15,7 @@
 
 #include "postgres.h"
 
+#include "access/htup_details.h"
 #include "catalog/pg_aggregate.h"
 #include "catalog/pg_type.h"
 #include "miscadmin.h"
diff --git a/src/backend/utils/adt/arrayfuncs.c b/src/backend/utils/adt/arrayfuncs.c
index e5f3e2da35c..a8951f55b93 100644
--- a/src/backend/utils/adt/arrayfuncs.c
+++ b/src/backend/utils/adt/arrayfuncs.c
@@ -17,6 +17,7 @@
 #include <ctype.h>
 #include <math.h>
 
+#include "access/transam.h"
 #include "catalog/pg_type.h"
 #include "common/int.h"
 #include "funcapi.h"
diff --git a/src/backend/utils/adt/hbafuncs.c b/src/backend/utils/adt/hbafuncs.c
index b62c3d944cf..1614d6d2302 100644
--- a/src/backend/utils/adt/hbafuncs.c
+++ b/src/backend/utils/adt/hbafuncs.c
@@ -14,6 +14,7 @@
  */
 #include "postgres.h"
 
+#include "access/htup_details.h"
 #include "catalog/objectaddress.h"
 #include "common/ip.h"
 #include "funcapi.h"
diff --git a/src/backend/utils/adt/json.c b/src/backend/utils/adt/json.c
index e9d370cb3da..14f5cb498fc 100644
--- a/src/backend/utils/adt/json.c
+++ b/src/backend/utils/adt/json.c
@@ -13,6 +13,7 @@
  */
 #include "postgres.h"
 
+#include "access/htup_details.h"
 #include "catalog/pg_proc.h"
 #include "catalog/pg_type.h"
 #include "common/hashfn.h"
diff --git a/src/backend/utils/adt/misc.c b/src/backend/utils/adt/misc.c
index 2c5a7ee9ddc..7cb7716e58b 100644
--- a/src/backend/utils/adt/misc.c
+++ b/src/backend/utils/adt/misc.c
@@ -21,6 +21,7 @@
 #include <math.h>
 #include <unistd.h>
 
+#include "access/htup_details.h"
 #include "access/sysattr.h"
 #include "access/table.h"
 #include "catalog/pg_tablespace.h"
diff --git a/src/backend/utils/adt/rangetypes.c b/src/backend/utils/adt/rangetypes.c
index 18e467bccd3..0b2ad8b0975 100644
--- a/src/backend/utils/adt/rangetypes.c
+++ b/src/backend/utils/adt/rangetypes.c
@@ -45,6 +45,7 @@
 #include "utils/rangetypes.h"
 #include "utils/sortsupport.h"
 #include "utils/timestamp.h"
+#include "varatt.h"
 
 
 /* fn_extra cache entry for one of the range I/O functions */
diff --git a/src/backend/utils/adt/xid8funcs.c b/src/backend/utils/adt/xid8funcs.c
index 1da3964ca6f..a211a107767 100644
--- a/src/backend/utils/adt/xid8funcs.c
+++ b/src/backend/utils/adt/xid8funcs.c
@@ -39,6 +39,7 @@
 #include "utils/memutils.h"
 #include "utils/snapmgr.h"
 #include "utils/xid8.h"
+#include "varatt.h"
 
 
 /*
diff --git a/src/backend/utils/fmgr/fmgr.c b/src/backend/utils/fmgr/fmgr.c
index b4c1e2c4b21..0fe63c6bb83 100644
--- a/src/backend/utils/fmgr/fmgr.c
+++ b/src/backend/utils/fmgr/fmgr.c
@@ -16,6 +16,7 @@
 #include "postgres.h"
 
 #include "access/detoast.h"
+#include "access/htup_details.h"
 #include "catalog/pg_language.h"
 #include "catalog/pg_proc.h"
 #include "catalog/pg_type.h"
diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c
index 46fdefebe35..107b5a273a2 100644
--- a/src/backend/utils/misc/guc.c
+++ b/src/backend/utils/misc/guc.c
@@ -34,6 +34,7 @@
 #include "catalog/objectaccess.h"
 #include "catalog/pg_authid.h"
 #include "catalog/pg_parameter_acl.h"
+#include "catalog/pg_type.h"
 #include "guc_internal.h"
 #include "libpq/pqformat.h"
 #include "libpq/protocol.h"
diff --git a/src/include/access/gin_private.h b/src/include/access/gin_private.h
index aee1f70c22e..9ea303a7c1b 100644
--- a/src/include/access/gin_private.h
+++ b/src/include/access/gin_private.h
@@ -13,6 +13,7 @@
 #include "access/amapi.h"
 #include "access/gin.h"
 #include "access/ginblock.h"
+#include "access/htup_details.h"
 #include "access/itup.h"
 #include "common/int.h"
 #include "catalog/pg_am_d.h"
diff --git a/src/include/executor/tuptable.h b/src/include/executor/tuptable.h
index 095e4cc82e3..43f1d999b91 100644
--- a/src/include/executor/tuptable.h
+++ b/src/include/executor/tuptable.h
@@ -15,7 +15,6 @@
 #define TUPTABLE_H
 
 #include "access/htup.h"
-#include "access/htup_details.h"
 #include "access/sysattr.h"
 #include "access/tupdesc.h"
 #include "storage/buf.h"
diff --git a/src/test/modules/injection_points/injection_stats_fixed.c b/src/test/modules/injection_points/injection_stats_fixed.c
index 74c35fcbfa7..b493e8f77a3 100644
--- a/src/test/modules/injection_points/injection_stats_fixed.c
+++ b/src/test/modules/injection_points/injection_stats_fixed.c
@@ -16,6 +16,7 @@
 
 #include "fmgr.h"
 
+#include "access/htup_details.h"
 #include "common/hashfn.h"
 #include "funcapi.h"
 #include "injection_stats.h"
-- 
2.47.3

0003-don-t-include-executor-tuptable.h-in-access-tupconve.patchtext/x-diff; charset=utf-8Download
From 658e5842435528ce1f6c02ff5262f092fd4489be Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=C3=81lvaro=20Herrera?= <alvherre@kurilemu.de>
Date: Wed, 1 Oct 2025 19:34:46 +0200
Subject: [PATCH 3/4] don't include executor/tuptable.h in access/tupconvert.h

---
 src/include/access/tupconvert.h | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/src/include/access/tupconvert.h b/src/include/access/tupconvert.h
index 2ab3936f22e..5dd52153931 100644
--- a/src/include/access/tupconvert.h
+++ b/src/include/access/tupconvert.h
@@ -17,9 +17,10 @@
 #include "access/attmap.h"
 #include "access/htup.h"
 #include "access/tupdesc.h"
-#include "executor/tuptable.h"
 #include "nodes/bitmapset.h"
 
+/* We don't want to include tuptables.h here */
+typedef struct TupleTableSlot TupleTableSlot;
 
 typedef struct TupleConversionMap
 {
-- 
2.47.3

0004-Don-t-include-execnodes.h-in-brin.h-or-gin.h.patchtext/x-diff; charset=utf-8Download
From 8991f2138f371519a2f24221c1fe275045771ba4 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=C3=81lvaro=20Herrera?= <alvherre@kurilemu.de>
Date: Wed, 1 Oct 2025 19:47:35 +0200
Subject: [PATCH 4/4] Don't include execnodes.h in brin.h or gin.h

---
 src/backend/access/brin/brin_bloom.c | 1 +
 src/backend/access/gin/ginscan.c     | 1 +
 src/include/access/brin.h            | 3 ++-
 src/include/access/gin.h             | 4 ++--
 4 files changed, 6 insertions(+), 3 deletions(-)

diff --git a/src/backend/access/brin/brin_bloom.c b/src/backend/access/brin/brin_bloom.c
index 7c3f7d454fc..d6da3abc8de 100644
--- a/src/backend/access/brin/brin_bloom.c
+++ b/src/backend/access/brin/brin_bloom.c
@@ -126,6 +126,7 @@
 #include "catalog/pg_am.h"
 #include "catalog/pg_type.h"
 #include "common/hashfn.h"
+#include "port/pg_bitutils.h"
 #include "utils/fmgrprotos.h"
 #include "utils/rel.h"
 
diff --git a/src/backend/access/gin/ginscan.c b/src/backend/access/gin/ginscan.c
index 26081693383..1c9a8cb4df8 100644
--- a/src/backend/access/gin/ginscan.c
+++ b/src/backend/access/gin/ginscan.c
@@ -16,6 +16,7 @@
 
 #include "access/gin_private.h"
 #include "access/relscan.h"
+#include "executor/instrument_node.h"
 #include "pgstat.h"
 #include "utils/memutils.h"
 #include "utils/rel.h"
diff --git a/src/include/access/brin.h b/src/include/access/brin.h
index 821f1e02806..91ec498bda0 100644
--- a/src/include/access/brin.h
+++ b/src/include/access/brin.h
@@ -10,7 +10,8 @@
 #ifndef BRIN_H
 #define BRIN_H
 
-#include "nodes/execnodes.h"
+#include "storage/block.h"
+#include "storage/dsm.h"
 #include "storage/shm_toc.h"
 #include "utils/relcache.h"
 
diff --git a/src/include/access/gin.h b/src/include/access/gin.h
index 2e1076a0499..13ea91922ef 100644
--- a/src/include/access/gin.h
+++ b/src/include/access/gin.h
@@ -12,9 +12,9 @@
 
 #include "access/xlogreader.h"
 #include "lib/stringinfo.h"
-#include "nodes/execnodes.h"
-#include "storage/shm_toc.h"
 #include "storage/block.h"
+#include "storage/dsm.h"
+#include "storage/shm_toc.h"
 #include "utils/relcache.h"
 
 
-- 
2.47.3

build-include-databasetext/plain; charset=utf-8Download
#23Álvaro Herrera
alvherre@kurilemu.de
In reply to: Álvaro Herrera (#22)
2 attachment(s)
Re: allow benign typedef redefinitions (C11)

I have applied 0002 and 0004, which are the straightforward ones.
I decided not to pursue 0003 because I think a much better idea is to
remove the inclusion of tupconvert.h in execnodes.h.

Here's 0001 again. I mentioned a possible move of a few instrumentation
structs from elsewhere into the new file, just so that they're all
together in one place. The new 0002 here does that, but I'm feeling
quite unsure about it.

--
Álvaro Herrera Breisgau, Deutschland — https://www.EnterpriseDB.com/
"Uno puede defenderse de los ataques; contra los elogios se esta indefenso"

Attachments:

v2-0001-Remove-brin-gin_tuple.h-from-tuplesort.h.patchtext/x-diff; charset=utf-8Download
From 101e6db9f33378da784fd74bc8cea841454adeb4 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=C3=81lvaro=20Herrera?= <alvherre@kurilemu.de>
Date: Sun, 5 Oct 2025 18:54:56 +0200
Subject: [PATCH v2 1/2] Remove brin/gin_tuple.h from tuplesort.h

Because execnodes.h depends on struct definitions that were in genam.h,
which it no longer gets because of the aforementioned removal, split
those struct definitions to a separate header file.
---
 contrib/bloom/blscan.c                     |  1 +
 contrib/pageinspect/gistfuncs.c            |  1 +
 src/backend/access/gin/gininsert.c         |  3 +-
 src/backend/access/gin/ginscan.c           |  1 +
 src/backend/access/gist/gistget.c          |  1 +
 src/backend/access/hash/hashsearch.c       |  1 +
 src/backend/access/nbtree/nbtsearch.c      |  1 +
 src/backend/access/spgist/spgscan.c        |  1 +
 src/backend/catalog/pg_attrdef.c           |  1 +
 src/backend/catalog/pg_largeobject.c       |  1 +
 src/backend/executor/execReplication.c     |  1 +
 src/backend/parser/parse_expr.c            |  1 +
 src/backend/replication/logical/relation.c |  1 +
 src/backend/statistics/attribute_stats.c   |  1 +
 src/include/access/genam.h                 | 23 +-------
 src/include/executor/instrument_node.h     | 64 ++++++++++++++++++++++
 src/include/nodes/execnodes.h              | 29 +---------
 src/include/utils/tuplesort.h              |  6 +-
 18 files changed, 86 insertions(+), 52 deletions(-)
 create mode 100644 src/include/executor/instrument_node.h

diff --git a/contrib/bloom/blscan.c b/contrib/bloom/blscan.c
index d072f47fe28..5f8378d1f44 100644
--- a/contrib/bloom/blscan.c
+++ b/contrib/bloom/blscan.c
@@ -14,6 +14,7 @@
 
 #include "access/relscan.h"
 #include "bloom.h"
+#include "executor/instrument_node.h"
 #include "miscadmin.h"
 #include "pgstat.h"
 #include "storage/bufmgr.h"
diff --git a/contrib/pageinspect/gistfuncs.c b/contrib/pageinspect/gistfuncs.c
index de3746a156b..190353ec354 100644
--- a/contrib/pageinspect/gistfuncs.c
+++ b/contrib/pageinspect/gistfuncs.c
@@ -9,6 +9,7 @@
  */
 #include "postgres.h"
 
+#include "access/genam.h"
 #include "access/gist.h"
 #include "access/htup.h"
 #include "access/htup_details.h"
diff --git a/src/backend/access/gin/gininsert.c b/src/backend/access/gin/gininsert.c
index e9d4b27427e..43c007b6204 100644
--- a/src/backend/access/gin/gininsert.c
+++ b/src/backend/access/gin/gininsert.c
@@ -29,10 +29,11 @@
 #include "storage/bufmgr.h"
 #include "storage/predicate.h"
 #include "tcop/tcopprot.h"
+#include "utils/builtins.h"
 #include "utils/datum.h"
 #include "utils/memutils.h"
 #include "utils/rel.h"
-#include "utils/builtins.h"
+#include "utils/typcache.h"
 
 
 /* Magic numbers for parallel state sharing */
diff --git a/src/backend/access/gin/ginscan.c b/src/backend/access/gin/ginscan.c
index 26081693383..1c9a8cb4df8 100644
--- a/src/backend/access/gin/ginscan.c
+++ b/src/backend/access/gin/ginscan.c
@@ -16,6 +16,7 @@
 
 #include "access/gin_private.h"
 #include "access/relscan.h"
+#include "executor/instrument_node.h"
 #include "pgstat.h"
 #include "utils/memutils.h"
 #include "utils/rel.h"
diff --git a/src/backend/access/gist/gistget.c b/src/backend/access/gist/gistget.c
index 387d9972345..aa56ef430a9 100644
--- a/src/backend/access/gist/gistget.c
+++ b/src/backend/access/gist/gistget.c
@@ -17,6 +17,7 @@
 #include "access/genam.h"
 #include "access/gist_private.h"
 #include "access/relscan.h"
+#include "executor/instrument_node.h"
 #include "lib/pairingheap.h"
 #include "miscadmin.h"
 #include "pgstat.h"
diff --git a/src/backend/access/hash/hashsearch.c b/src/backend/access/hash/hashsearch.c
index 92c15a65be2..00395b01f60 100644
--- a/src/backend/access/hash/hashsearch.c
+++ b/src/backend/access/hash/hashsearch.c
@@ -17,6 +17,7 @@
 #include "access/hash.h"
 #include "access/relscan.h"
 #include "miscadmin.h"
+#include "executor/instrument_node.h"
 #include "pgstat.h"
 #include "storage/predicate.h"
 #include "utils/rel.h"
diff --git a/src/backend/access/nbtree/nbtsearch.c b/src/backend/access/nbtree/nbtsearch.c
index d69798795b4..5c6dc3b183e 100644
--- a/src/backend/access/nbtree/nbtsearch.c
+++ b/src/backend/access/nbtree/nbtsearch.c
@@ -18,6 +18,7 @@
 #include "access/nbtree.h"
 #include "access/relscan.h"
 #include "access/xact.h"
+#include "executor/instrument_node.h"
 #include "miscadmin.h"
 #include "pgstat.h"
 #include "storage/predicate.h"
diff --git a/src/backend/access/spgist/spgscan.c b/src/backend/access/spgist/spgscan.c
index 25893050c58..abfb3555af5 100644
--- a/src/backend/access/spgist/spgscan.c
+++ b/src/backend/access/spgist/spgscan.c
@@ -18,6 +18,7 @@
 #include "access/genam.h"
 #include "access/relscan.h"
 #include "access/spgist_private.h"
+#include "executor/instrument_node.h"
 #include "miscadmin.h"
 #include "pgstat.h"
 #include "storage/bufmgr.h"
diff --git a/src/backend/catalog/pg_attrdef.c b/src/backend/catalog/pg_attrdef.c
index 29f5691bee9..e8bdb52cb00 100644
--- a/src/backend/catalog/pg_attrdef.c
+++ b/src/backend/catalog/pg_attrdef.c
@@ -14,6 +14,7 @@
  */
 #include "postgres.h"
 
+#include "access/genam.h"
 #include "access/htup_details.h"
 #include "access/relation.h"
 #include "access/table.h"
diff --git a/src/backend/catalog/pg_largeobject.c b/src/backend/catalog/pg_largeobject.c
index 33e8fa96a65..ada4c3685e0 100644
--- a/src/backend/catalog/pg_largeobject.c
+++ b/src/backend/catalog/pg_largeobject.c
@@ -14,6 +14,7 @@
  */
 #include "postgres.h"
 
+#include "access/genam.h"
 #include "access/htup_details.h"
 #include "access/table.h"
 #include "catalog/catalog.h"
diff --git a/src/backend/executor/execReplication.c b/src/backend/executor/execReplication.c
index b409d4ecbf5..ab585aa9819 100644
--- a/src/backend/executor/execReplication.c
+++ b/src/backend/executor/execReplication.c
@@ -14,6 +14,7 @@
 
 #include "postgres.h"
 
+#include "access/amapi.h"
 #include "access/commit_ts.h"
 #include "access/genam.h"
 #include "access/gist.h"
diff --git a/src/backend/parser/parse_expr.c b/src/backend/parser/parse_expr.c
index 9d95c7140ee..72625a94dcc 100644
--- a/src/backend/parser/parse_expr.c
+++ b/src/backend/parser/parse_expr.c
@@ -38,6 +38,7 @@
 #include "utils/fmgroids.h"
 #include "utils/lsyscache.h"
 #include "utils/timestamp.h"
+#include "utils/typcache.h"
 #include "utils/xml.h"
 
 /* GUC parameters */
diff --git a/src/backend/replication/logical/relation.c b/src/backend/replication/logical/relation.c
index f59046ad620..85f55b75c66 100644
--- a/src/backend/replication/logical/relation.c
+++ b/src/backend/replication/logical/relation.c
@@ -29,6 +29,7 @@
 #include "utils/inval.h"
 #include "utils/lsyscache.h"
 #include "utils/syscache.h"
+#include "utils/typcache.h"
 
 
 static MemoryContext LogicalRepRelMapContext = NULL;
diff --git a/src/backend/statistics/attribute_stats.c b/src/backend/statistics/attribute_stats.c
index 1db6a7f784c..4e8efcdf55b 100644
--- a/src/backend/statistics/attribute_stats.c
+++ b/src/backend/statistics/attribute_stats.c
@@ -29,6 +29,7 @@
 #include "utils/fmgroids.h"
 #include "utils/lsyscache.h"
 #include "utils/syscache.h"
+#include "utils/typcache.h"
 
 #define DEFAULT_NULL_FRAC      Float4GetDatum(0.0)
 #define DEFAULT_AVG_WIDTH      Int32GetDatum(0) /* unknown */
diff --git a/src/include/access/genam.h b/src/include/access/genam.h
index 9200a22bd9f..87d744eff07 100644
--- a/src/include/access/genam.h
+++ b/src/include/access/genam.h
@@ -17,6 +17,7 @@
 #include "access/htup.h"
 #include "access/sdir.h"
 #include "access/skey.h"
+#include "executor/instrument_node.h"
 #include "nodes/tidbitmap.h"
 #include "storage/buf.h"
 #include "storage/lockdefs.h"
@@ -29,28 +30,6 @@ typedef struct TupleTableSlot TupleTableSlot;
 /* or relcache.h */
 typedef struct RelationData *Relation;
 
-
-/*
- * Struct for statistics maintained by amgettuple and amgetbitmap
- *
- * Note: IndexScanInstrumentation can't contain any pointers, since it is
- * copied into a SharedIndexScanInstrumentation during parallel scans
- */
-typedef struct IndexScanInstrumentation
-{
-	/* Index search count (incremented with pgstat_count_index_scan call) */
-	uint64		nsearches;
-} IndexScanInstrumentation;
-
-/*
- * Struct for every worker's IndexScanInstrumentation, stored in shared memory
- */
-typedef struct SharedIndexScanInstrumentation
-{
-	int			num_workers;
-	IndexScanInstrumentation winstrument[FLEXIBLE_ARRAY_MEMBER];
-} SharedIndexScanInstrumentation;
-
 /*
  * Struct for statistics returned by ambuild
  */
diff --git a/src/include/executor/instrument_node.h b/src/include/executor/instrument_node.h
new file mode 100644
index 00000000000..8937ebbcf21
--- /dev/null
+++ b/src/include/executor/instrument_node.h
@@ -0,0 +1,64 @@
+/*-------------------------------------------------------------------------
+ *
+ * instrument_node.h
+ *	  Definitions for node-specific instrumentation
+ *
+ *
+ * Portions Copyright (c) 1996-2025, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1994, Regents of the University of California
+ *
+ * src/include/executor/instrument_node.h
+ *
+ *-------------------------------------------------------------------------
+ */
+#ifndef INSTRUMENT_NODE_H
+#define INSTRUMENT_NODE_H
+
+
+/*
+ * Struct for statistics maintained by amgettuple and amgetbitmap
+ *
+ * Note: IndexScanInstrumentation can't contain any pointers, since it is
+ * copied into a SharedIndexScanInstrumentation during parallel scans
+ */
+typedef struct IndexScanInstrumentation
+{
+	/* Index search count (incremented with pgstat_count_index_scan call) */
+	uint64		nsearches;
+} IndexScanInstrumentation;
+
+/*
+ * Struct for every worker's IndexScanInstrumentation, stored in shared memory
+ */
+typedef struct SharedIndexScanInstrumentation
+{
+	int			num_workers;
+	IndexScanInstrumentation winstrument[FLEXIBLE_ARRAY_MEMBER];
+} SharedIndexScanInstrumentation;
+
+/*
+ *	 BitmapHeapScanInstrumentation information
+ *
+ *		exact_pages		   total number of exact pages retrieved
+ *		lossy_pages		   total number of lossy pages retrieved
+ */
+typedef struct BitmapHeapScanInstrumentation
+{
+	uint64		exact_pages;
+	uint64		lossy_pages;
+} BitmapHeapScanInstrumentation;
+
+/*
+ *	 Instrumentation data for a parallel bitmap heap scan.
+ *
+ * A shared memory struct that each parallel worker copies its
+ * BitmapHeapScanInstrumentation information into at executor shutdown to
+ * allow the leader to display the information in EXPLAIN ANALYZE.
+ */
+typedef struct SharedBitmapHeapInstrumentation
+{
+	int			num_workers;
+	BitmapHeapScanInstrumentation sinstrument[FLEXIBLE_ARRAY_MEMBER];
+} SharedBitmapHeapInstrumentation;
+
+#endif							/* INSTRUMENT_NODE_H */
diff --git a/src/include/nodes/execnodes.h b/src/include/nodes/execnodes.h
index a36653c37f9..857488c56fc 100644
--- a/src/include/nodes/execnodes.h
+++ b/src/include/nodes/execnodes.h
@@ -29,8 +29,10 @@
 #ifndef EXECNODES_H
 #define EXECNODES_H
 
+#include "access/skey.h"
 #include "access/tupconvert.h"
 #include "executor/instrument.h"
+#include "executor/instrument_node.h"
 #include "fmgr.h"
 #include "lib/ilist.h"
 #include "lib/pairingheap.h"
@@ -1810,19 +1812,6 @@ typedef struct BitmapIndexScanState
 	SharedIndexScanInstrumentation *biss_SharedInfo;
 } BitmapIndexScanState;
 
-/* ----------------
- *	 BitmapHeapScanInstrumentation information
- *
- *		exact_pages		   total number of exact pages retrieved
- *		lossy_pages		   total number of lossy pages retrieved
- * ----------------
- */
-typedef struct BitmapHeapScanInstrumentation
-{
-	uint64		exact_pages;
-	uint64		lossy_pages;
-} BitmapHeapScanInstrumentation;
-
 /* ----------------
  *	 SharedBitmapState information
  *
@@ -1859,20 +1848,6 @@ typedef struct ParallelBitmapHeapState
 	ConditionVariable cv;
 } ParallelBitmapHeapState;
 
-/* ----------------
- *	 Instrumentation data for a parallel bitmap heap scan.
- *
- * A shared memory struct that each parallel worker copies its
- * BitmapHeapScanInstrumentation information into at executor shutdown to
- * allow the leader to display the information in EXPLAIN ANALYZE.
- * ----------------
- */
-typedef struct SharedBitmapHeapInstrumentation
-{
-	int			num_workers;
-	BitmapHeapScanInstrumentation sinstrument[FLEXIBLE_ARRAY_MEMBER];
-} SharedBitmapHeapInstrumentation;
-
 /* ----------------
  *	 BitmapHeapScanState information
  *
diff --git a/src/include/utils/tuplesort.h b/src/include/utils/tuplesort.h
index ef79f259f93..8278beea5ec 100644
--- a/src/include/utils/tuplesort.h
+++ b/src/include/utils/tuplesort.h
@@ -21,8 +21,6 @@
 #ifndef TUPLESORT_H
 #define TUPLESORT_H
 
-#include "access/brin_tuple.h"
-#include "access/gin_tuple.h"
 #include "access/itup.h"
 #include "executor/tuptable.h"
 #include "storage/dsm.h"
@@ -31,6 +29,10 @@
 #include "utils/sortsupport.h"
 
 
+/* We don't want this file to depend on AM-specific header files */
+typedef struct BrinTuple BrinTuple;
+typedef struct GinTuple GinTuple;
+
 /*
  * Tuplesortstate and Sharedsort are opaque types whose details are not
  * known outside tuplesort.c.
-- 
2.47.3

v2-0002-move-some-other-structs-into-instrument_node.h.patchtext/x-diff; charset=utf-8Download
From f64e65892e264a42648318686f06ad3adf0c3c22 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=C3=81lvaro=20Herrera?= <alvherre@kurilemu.de>
Date: Sun, 5 Oct 2025 19:22:13 +0200
Subject: [PATCH v2 2/2] move some other structs into instrument_node.h

---
 src/backend/utils/sort/tuplesort.c     |   1 +
 src/include/executor/instrument_node.h | 145 +++++++++++++++++++++++++
 src/include/nodes/execnodes.h          | 108 ------------------
 src/include/utils/tuplesort.h          |  36 +-----
 4 files changed, 147 insertions(+), 143 deletions(-)

diff --git a/src/backend/utils/sort/tuplesort.c b/src/backend/utils/sort/tuplesort.c
index 5d4411dc33f..dee5e13ab0e 100644
--- a/src/backend/utils/sort/tuplesort.c
+++ b/src/backend/utils/sort/tuplesort.c
@@ -102,6 +102,7 @@
 #include <limits.h>
 
 #include "commands/tablespace.h"
+#include "executor/instrument_node.h"
 #include "miscadmin.h"
 #include "pg_trace.h"
 #include "storage/shmem.h"
diff --git a/src/include/executor/instrument_node.h b/src/include/executor/instrument_node.h
index 8937ebbcf21..a05616f44da 100644
--- a/src/include/executor/instrument_node.h
+++ b/src/include/executor/instrument_node.h
@@ -61,4 +61,149 @@ typedef struct SharedBitmapHeapInstrumentation
 	BitmapHeapScanInstrumentation sinstrument[FLEXIBLE_ARRAY_MEMBER];
 } SharedBitmapHeapInstrumentation;
 
+typedef struct MemoizeInstrumentation
+{
+	uint64		cache_hits;		/* number of rescans where we've found the
+								 * scan parameter values to be cached */
+	uint64		cache_misses;	/* number of rescans where we've not found the
+								 * scan parameter values to be cached. */
+	uint64		cache_evictions;	/* number of cache entries removed due to
+									 * the need to free memory */
+	uint64		cache_overflows;	/* number of times we've had to bypass the
+									 * cache when filling it due to not being
+									 * able to free enough space to store the
+									 * current scan's tuples. */
+	uint64		mem_peak;		/* peak memory usage in bytes */
+} MemoizeInstrumentation;
+
+/* ----------------
+ *	 Shared memory container for per-worker memoize information
+ * ----------------
+ */
+typedef struct SharedMemoizeInfo
+{
+	int			num_workers;
+	MemoizeInstrumentation sinstrument[FLEXIBLE_ARRAY_MEMBER];
+} SharedMemoizeInfo;
+
+/*
+ * Data structures for reporting sort statistics.  Note that
+ * TuplesortInstrumentation can't contain any pointers because we
+ * sometimes put it in shared memory.
+ *
+ * The parallel-sort infrastructure relies on having a zero TuplesortMethod
+ * to indicate that a worker never did anything, so we assign zero to
+ * SORT_TYPE_STILL_IN_PROGRESS.  The other values of this enum can be
+ * OR'ed together to represent a situation where different workers used
+ * different methods, so we need a separate bit for each one.  Keep the
+ * NUM_TUPLESORTMETHODS constant in sync with the number of bits!
+ */
+typedef enum
+{
+	SORT_TYPE_STILL_IN_PROGRESS = 0,
+	SORT_TYPE_TOP_N_HEAPSORT = 1 << 0,
+	SORT_TYPE_QUICKSORT = 1 << 1,
+	SORT_TYPE_EXTERNAL_SORT = 1 << 2,
+	SORT_TYPE_EXTERNAL_MERGE = 1 << 3,
+} TuplesortMethod;
+
+#define NUM_TUPLESORTMETHODS 4
+
+typedef enum
+{
+	SORT_SPACE_TYPE_DISK,
+	SORT_SPACE_TYPE_MEMORY,
+} TuplesortSpaceType;
+
+typedef struct TuplesortInstrumentation
+{
+	TuplesortMethod sortMethod; /* sort algorithm used */
+	TuplesortSpaceType spaceType;	/* type of space spaceUsed represents */
+	int64		spaceUsed;		/* space consumption, in kB */
+} TuplesortInstrumentation;
+
+/* ----------------
+ *	 Shared memory container for per-worker sort information
+ * ----------------
+ */
+typedef struct SharedSortInfo
+{
+	int			num_workers;
+	TuplesortInstrumentation sinstrument[FLEXIBLE_ARRAY_MEMBER];
+} SharedSortInfo;
+
+/* ----------------
+ *	 Instrumentation information for IncrementalSort
+ * ----------------
+ */
+typedef struct IncrementalSortGroupInfo
+{
+	int64		groupCount;
+	int64		maxDiskSpaceUsed;
+	int64		totalDiskSpaceUsed;
+	int64		maxMemorySpaceUsed;
+	int64		totalMemorySpaceUsed;
+	bits32		sortMethods;	/* bitmask of TuplesortMethod */
+} IncrementalSortGroupInfo;
+
+typedef struct IncrementalSortInfo
+{
+	IncrementalSortGroupInfo fullsortGroupInfo;
+	IncrementalSortGroupInfo prefixsortGroupInfo;
+} IncrementalSortInfo;
+
+/* ----------------
+ *	 Shared memory container for per-worker incremental sort information
+ * ----------------
+ */
+typedef struct SharedIncrementalSortInfo
+{
+	int			num_workers;
+	IncrementalSortInfo sinfo[FLEXIBLE_ARRAY_MEMBER];
+} SharedIncrementalSortInfo;
+
+/* ---------------------
+ *	per-worker aggregate information
+ * ---------------------
+ */
+typedef struct AggregateInstrumentation
+{
+	Size		hash_mem_peak;	/* peak hash table memory usage */
+	uint64		hash_disk_used; /* kB of disk space used */
+	int			hash_batches_used;	/* batches used during entire execution */
+} AggregateInstrumentation;
+
+/* ----------------
+ *	 Shared memory container for per-worker aggregate information
+ * ----------------
+ */
+typedef struct SharedAggInfo
+{
+	int			num_workers;
+	AggregateInstrumentation sinstrument[FLEXIBLE_ARRAY_MEMBER];
+} SharedAggInfo;
+
+/* ----------------
+ *	 Values displayed by EXPLAIN ANALYZE
+ * ----------------
+ */
+typedef struct HashInstrumentation
+{
+	int			nbuckets;		/* number of buckets at end of execution */
+	int			nbuckets_original;	/* planned number of buckets */
+	int			nbatch;			/* number of batches at end of execution */
+	int			nbatch_original;	/* planned number of batches */
+	Size		space_peak;		/* peak memory usage in bytes */
+} HashInstrumentation;
+
+/* ----------------
+ *	 Shared memory container for per-worker hash information
+ * ----------------
+ */
+typedef struct SharedHashInfo
+{
+	int			num_workers;
+	HashInstrumentation hinstrument[FLEXIBLE_ARRAY_MEMBER];
+} SharedHashInfo;
+
 #endif							/* INSTRUMENT_NODE_H */
diff --git a/src/include/nodes/execnodes.h b/src/include/nodes/execnodes.h
index 857488c56fc..1b46dd0dbeb 100644
--- a/src/include/nodes/execnodes.h
+++ b/src/include/nodes/execnodes.h
@@ -2272,31 +2272,6 @@ struct MemoizeEntry;
 struct MemoizeTuple;
 struct MemoizeKey;
 
-typedef struct MemoizeInstrumentation
-{
-	uint64		cache_hits;		/* number of rescans where we've found the
-								 * scan parameter values to be cached */
-	uint64		cache_misses;	/* number of rescans where we've not found the
-								 * scan parameter values to be cached. */
-	uint64		cache_evictions;	/* number of cache entries removed due to
-									 * the need to free memory */
-	uint64		cache_overflows;	/* number of times we've had to bypass the
-									 * cache when filling it due to not being
-									 * able to free enough space to store the
-									 * current scan's tuples. */
-	uint64		mem_peak;		/* peak memory usage in bytes */
-} MemoizeInstrumentation;
-
-/* ----------------
- *	 Shared memory container for per-worker memoize information
- * ----------------
- */
-typedef struct SharedMemoizeInfo
-{
-	int			num_workers;
-	MemoizeInstrumentation sinstrument[FLEXIBLE_ARRAY_MEMBER];
-} SharedMemoizeInfo;
-
 /* ----------------
  *	 MemoizeState information
  *
@@ -2352,16 +2327,6 @@ typedef struct PresortedKeyData
 	OffsetNumber attno;			/* attribute number in tuple */
 } PresortedKeyData;
 
-/* ----------------
- *	 Shared memory container for per-worker sort information
- * ----------------
- */
-typedef struct SharedSortInfo
-{
-	int			num_workers;
-	TuplesortInstrumentation sinstrument[FLEXIBLE_ARRAY_MEMBER];
-} SharedSortInfo;
-
 /* ----------------
  *	 SortState information
  * ----------------
@@ -2381,35 +2346,6 @@ typedef struct SortState
 	SharedSortInfo *shared_info;	/* one entry per worker */
 } SortState;
 
-/* ----------------
- *	 Instrumentation information for IncrementalSort
- * ----------------
- */
-typedef struct IncrementalSortGroupInfo
-{
-	int64		groupCount;
-	int64		maxDiskSpaceUsed;
-	int64		totalDiskSpaceUsed;
-	int64		maxMemorySpaceUsed;
-	int64		totalMemorySpaceUsed;
-	bits32		sortMethods;	/* bitmask of TuplesortMethod */
-} IncrementalSortGroupInfo;
-
-typedef struct IncrementalSortInfo
-{
-	IncrementalSortGroupInfo fullsortGroupInfo;
-	IncrementalSortGroupInfo prefixsortGroupInfo;
-} IncrementalSortInfo;
-
-/* ----------------
- *	 Shared memory container for per-worker incremental sort information
- * ----------------
- */
-typedef struct SharedIncrementalSortInfo
-{
-	int			num_workers;
-	IncrementalSortInfo sinfo[FLEXIBLE_ARRAY_MEMBER];
-} SharedIncrementalSortInfo;
 
 /* ----------------
  *	 IncrementalSortState information
@@ -2457,27 +2393,6 @@ typedef struct GroupState
 	bool		grp_done;		/* indicates completion of Group scan */
 } GroupState;
 
-/* ---------------------
- *	per-worker aggregate information
- * ---------------------
- */
-typedef struct AggregateInstrumentation
-{
-	Size		hash_mem_peak;	/* peak hash table memory usage */
-	uint64		hash_disk_used; /* kB of disk space used */
-	int			hash_batches_used;	/* batches used during entire execution */
-} AggregateInstrumentation;
-
-/* ----------------
- *	 Shared memory container for per-worker aggregate information
- * ----------------
- */
-typedef struct SharedAggInfo
-{
-	int			num_workers;
-	AggregateInstrumentation sinstrument[FLEXIBLE_ARRAY_MEMBER];
-} SharedAggInfo;
-
 /* ---------------------
  *	AggState information
  *
@@ -2754,29 +2669,6 @@ typedef struct GatherMergeState
 	struct binaryheap *gm_heap; /* binary heap of slot indices */
 } GatherMergeState;
 
-/* ----------------
- *	 Values displayed by EXPLAIN ANALYZE
- * ----------------
- */
-typedef struct HashInstrumentation
-{
-	int			nbuckets;		/* number of buckets at end of execution */
-	int			nbuckets_original;	/* planned number of buckets */
-	int			nbatch;			/* number of batches at end of execution */
-	int			nbatch_original;	/* planned number of batches */
-	Size		space_peak;		/* peak memory usage in bytes */
-} HashInstrumentation;
-
-/* ----------------
- *	 Shared memory container for per-worker hash information
- * ----------------
- */
-typedef struct SharedHashInfo
-{
-	int			num_workers;
-	HashInstrumentation hinstrument[FLEXIBLE_ARRAY_MEMBER];
-} SharedHashInfo;
-
 /* ----------------
  *	 HashState information
  * ----------------
diff --git a/src/include/utils/tuplesort.h b/src/include/utils/tuplesort.h
index 8278beea5ec..c47d7cdfc75 100644
--- a/src/include/utils/tuplesort.h
+++ b/src/include/utils/tuplesort.h
@@ -22,6 +22,7 @@
 #define TUPLESORT_H
 
 #include "access/itup.h"
+#include "executor/instrument_node.h"
 #include "executor/tuptable.h"
 #include "storage/dsm.h"
 #include "utils/logtape.h"
@@ -63,35 +64,6 @@ typedef struct SortCoordinateData
 
 typedef struct SortCoordinateData *SortCoordinate;
 
-/*
- * Data structures for reporting sort statistics.  Note that
- * TuplesortInstrumentation can't contain any pointers because we
- * sometimes put it in shared memory.
- *
- * The parallel-sort infrastructure relies on having a zero TuplesortMethod
- * to indicate that a worker never did anything, so we assign zero to
- * SORT_TYPE_STILL_IN_PROGRESS.  The other values of this enum can be
- * OR'ed together to represent a situation where different workers used
- * different methods, so we need a separate bit for each one.  Keep the
- * NUM_TUPLESORTMETHODS constant in sync with the number of bits!
- */
-typedef enum
-{
-	SORT_TYPE_STILL_IN_PROGRESS = 0,
-	SORT_TYPE_TOP_N_HEAPSORT = 1 << 0,
-	SORT_TYPE_QUICKSORT = 1 << 1,
-	SORT_TYPE_EXTERNAL_SORT = 1 << 2,
-	SORT_TYPE_EXTERNAL_MERGE = 1 << 3,
-} TuplesortMethod;
-
-#define NUM_TUPLESORTMETHODS 4
-
-typedef enum
-{
-	SORT_SPACE_TYPE_DISK,
-	SORT_SPACE_TYPE_MEMORY,
-} TuplesortSpaceType;
-
 /* Bitwise option flags for tuple sorts */
 #define TUPLESORT_NONE					0
 
@@ -110,12 +82,6 @@ typedef enum
  */
 #define TupleSortUseBumpTupleCxt(opt) (((opt) & TUPLESORT_ALLOWBOUNDED) == 0)
 
-typedef struct TuplesortInstrumentation
-{
-	TuplesortMethod sortMethod; /* sort algorithm used */
-	TuplesortSpaceType spaceType;	/* type of space spaceUsed represents */
-	int64		spaceUsed;		/* space consumption, in kB */
-} TuplesortInstrumentation;
 
 /*
  * The objects we actually sort are SortTuple structs.  These contain
-- 
2.47.3