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)
>From 30d4c9cf79e10a019a1de62e71d36edce2fa0c98 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=C3=81lvaro=20Herrera?= <[email protected]>
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
>From 6969dbfe045c58444eff9138b45c24c8873a0b53 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=C3=81lvaro=20Herrera?= <[email protected]>
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
>From 658e5842435528ce1f6c02ff5262f092fd4489be Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=C3=81lvaro=20Herrera?= <[email protected]>
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
>From 8991f2138f371519a2f24221c1fe275045771ba4 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=C3=81lvaro=20Herrera?= <[email protected]>
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
#!/bin/bash
# Create schema for this report. Its name is based on the current git commit.
# We set search_path for this user for the below psql calls, which we'll reset
# at the end.
hash=$(git show --format=format:%h --no-patch)
psql -c "create schema git_$hash"
psql -c "alter user current_user set search_path to git_$hash"
psql -c "create table if not exists includes (type text, file text, header
text); truncate table includes;"
IFS=$'\n'
# Grep all the backend .c files for the "#include" lines and insert them into
the
# includes table.
for i in $(find src/backend \( -path "*libstemmer*" -prune \) -o -name \*.c
-print); do
insert_lines=""
for line in $(git grep -h '^#include ".*\.h"' $i); do
file=$(echo $i | sed -e 's/src.backend.//')
line=$(echo $line | sed -e 's/#include "\([^"]*\)".*/\1/')
if [ ! -z "$insert_lines" ]; then
insert_lines=$insert_lines,
fi
insert_lines="$insert_lines ('source', '$file', '$line')"
done
# Insert in batches; too slow otherwise
if [ ! -z "$insert_lines" ]; then
psql -c "insert into includes values $insert_lines"
fi
done
# Grep the .h files for the #include lines. This code is almost identical to
# above, could stand refactoring.
for i in $(find src/include \( -path "*libstemmer*" -prune \) -o -name \*.h
-print); do
insert_lines=""
for line in $(git grep -h '^#include ".*\.h"' $i); do
file=$(echo $i | sed -e 's/src.include.//')
line=$(echo $line | sed -e 's/#include "\([^"]*\)".*/\1/')
if [ ! -z "$insert_lines" ]; then
insert_lines=$insert_lines,
fi
insert_lines="$insert_lines ('header', '$file', '$line')"
done
if [ ! -z "$insert_lines" ]; then
psql -c "insert into includes values $insert_lines"
fi
done
# Some header files are not interesting
psql -c "delete from includes where header in ('c.h', 'postgres.h',
'postgres_fe.h', 'utils/elog.h')"
# Create a table with all the direct and indirect dependencies between header
# files
psql -c "create table allheaderdeps as
with recursive headertree(file, include, depth) as (
select file, header as include, 1 from includes where type = 'header'
union
select headertree.file, header, depth+1
from headertree, includes
where includes.file = headertree.include
)
select * from headertree"
# Create a table with all the dependencies -- as above, but also consider all
# .c files.
psql -c "create table alldeps as
with recursive headertree(file, include, depth) as (
select file, header as include, 1 from includes
union select headertree.file, header, depth+1
from headertree, includes
where includes.file = headertree.include
)
select * from headertree"
# Create a view to show the includes most used altogether.
# XXX I think this is slightly bogus ... perhaps the `alldeps` table should
# really include only .c files? Not sure.
psql -c "create view topheaders as select a.*, b.numincludes from (select
include, count(*) as used_by_source
from alldeps group by include) a join
(select file, count(*) as numincludes from allheaderdeps group by file)
b on (b.file = a.include) /* where used_by_source >= 0 */ order by 2 desc"
# reset search_path
psql -c "alter user current_user reset search_path"