Unused header file inclusion

Started by vignesh Cover 6 years ago30 messages
#1vignesh C
vignesh21@gmail.com
1 attachment(s)

Hi,

I noticed that there are many header files being
included which need not be included.
I have tried this in a few files and found the
compilation and regression to be working.
I have attached the patch for the files that
I tried.
I tried this in CentOS, I did not find the header
files to be platform specific.
Should we pursue this further and cleanup in
all the files?

Regards,
Vignesh
EnterpriseDB: http://www.enterprisedb.com

Attachments:

unused_header_file_exclusion.patchapplication/octet-stream; name=unused_header_file_exclusion.patchDownload
diff --git a/src/backend/utils/mmgr/dsa.c b/src/backend/utils/mmgr/dsa.c
index 6590e55..0c7b8e2 100644
--- a/src/backend/utils/mmgr/dsa.c
+++ b/src/backend/utils/mmgr/dsa.c
@@ -50,11 +50,6 @@
 
 #include "postgres.h"
 
-#include "port/atomics.h"
-#include "storage/dsm.h"
-#include "storage/ipc.h"
-#include "storage/lwlock.h"
-#include "storage/shmem.h"
 #include "utils/dsa.h"
 #include "utils/freepage.h"
 #include "utils/memutils.h"
diff --git a/src/backend/utils/mmgr/freepage.c b/src/backend/utils/mmgr/freepage.c
index 9a1ae13..160a78d 100644
--- a/src/backend/utils/mmgr/freepage.c
+++ b/src/backend/utils/mmgr/freepage.c
@@ -56,7 +56,6 @@
 #include "miscadmin.h"
 
 #include "utils/freepage.h"
-#include "utils/relptr.h"
 
 
 /* Magic numbers to identify various page types */
diff --git a/src/backend/utils/mmgr/portalmem.c b/src/backend/utils/mmgr/portalmem.c
index 334e35b..67268fd 100644
--- a/src/backend/utils/mmgr/portalmem.c
+++ b/src/backend/utils/mmgr/portalmem.c
@@ -26,7 +26,6 @@
 #include "utils/builtins.h"
 #include "utils/memutils.h"
 #include "utils/snapmgr.h"
-#include "utils/timestamp.h"
 
 /*
  * Estimate of the maximum number of open portals a user would have,
diff --git a/src/backend/utils/resowner/resowner.c b/src/backend/utils/resowner/resowner.c
index 7be11c4..84870ec 100644
--- a/src/backend/utils/resowner/resowner.c
+++ b/src/backend/utils/resowner/resowner.c
@@ -29,7 +29,6 @@
 #include "utils/memutils.h"
 #include "utils/rel.h"
 #include "utils/resowner_private.h"
-#include "utils/snapmgr.h"
 
 
 /*
diff --git a/src/backend/utils/sort/sharedtuplestore.c b/src/backend/utils/sort/sharedtuplestore.c
index 8f74e8d..42aaada 100644
--- a/src/backend/utils/sort/sharedtuplestore.c
+++ b/src/backend/utils/sort/sharedtuplestore.c
@@ -21,16 +21,11 @@
 
 #include "postgres.h"
 
-#include "access/htup.h"
 #include "access/htup_details.h"
-#include "miscadmin.h"
 #include "storage/buffile.h"
 #include "storage/lwlock.h"
-#include "storage/sharedfileset.h"
 #include "utils/sharedtuplestore.h"
 
-#include <limits.h>
-
 /*
  * The size of chunks, in pages.  This is somewhat arbitrarily set to match
  * the size of HASH_CHUNK, so that Parallel Hash obtains new chunks of tuples
diff --git a/src/backend/utils/sort/sortsupport.c b/src/backend/utils/sort/sortsupport.c
index 9a77121..8590810 100644
--- a/src/backend/utils/sort/sortsupport.c
+++ b/src/backend/utils/sort/sortsupport.c
@@ -17,7 +17,6 @@
 
 #include "access/nbtree.h"
 #include "catalog/pg_am.h"
-#include "fmgr.h"
 #include "utils/lsyscache.h"
 #include "utils/rel.h"
 #include "utils/sortsupport.h"
diff --git a/src/backend/utils/sort/tuplesort.c b/src/backend/utils/sort/tuplesort.c
index 7b8e678..bdf008c 100644
--- a/src/backend/utils/sort/tuplesort.c
+++ b/src/backend/utils/sort/tuplesort.c
@@ -94,10 +94,7 @@
 
 #include "postgres.h"
 
-#include <limits.h>
-
 #include "access/hash.h"
-#include "access/htup_details.h"
 #include "access/nbtree.h"
 #include "catalog/index.h"
 #include "catalog/pg_am.h"
@@ -111,8 +108,6 @@
 #include "utils/memutils.h"
 #include "utils/pg_rusage.h"
 #include "utils/rel.h"
-#include "utils/sortsupport.h"
-#include "utils/tuplesort.h"
 
 
 /* sort-type codes for sort__start probes */
diff --git a/src/backend/utils/sort/tuplestore.c b/src/backend/utils/sort/tuplestore.c
index 3fc7f92..b461b55 100644
--- a/src/backend/utils/sort/tuplestore.c
+++ b/src/backend/utils/sort/tuplestore.c
@@ -54,9 +54,6 @@
 
 #include "postgres.h"
 
-#include <limits.h>
-
-#include "access/htup_details.h"
 #include "commands/tablespace.h"
 #include "executor/executor.h"
 #include "miscadmin.h"
diff --git a/src/backend/utils/time/combocid.c b/src/backend/utils/time/combocid.c
index deb9af5..0b8931e 100644
--- a/src/backend/utils/time/combocid.c
+++ b/src/backend/utils/time/combocid.c
@@ -46,7 +46,6 @@
 #include "access/xact.h"
 #include "storage/shmem.h"
 #include "utils/combocid.h"
-#include "utils/hsearch.h"
 #include "utils/memutils.h"
 
 
diff --git a/src/backend/utils/time/snapmgr.c b/src/backend/utils/time/snapmgr.c
index 40fe6ed..7f4aff2 100644
--- a/src/backend/utils/time/snapmgr.c
+++ b/src/backend/utils/time/snapmgr.c
@@ -49,17 +49,12 @@
 #include <unistd.h>
 
 #include "access/subtrans.h"
-#include "access/transam.h"
 #include "access/xact.h"
-#include "access/xlog.h"
 #include "catalog/catalog.h"
-#include "lib/pairingheap.h"
 #include "miscadmin.h"
 #include "storage/predicate.h"
 #include "storage/proc.h"
 #include "storage/procarray.h"
-#include "storage/sinval.h"
-#include "storage/sinvaladt.h"
 #include "storage/spin.h"
 #include "utils/builtins.h"
 #include "utils/memutils.h"
#2Michael Paquier
michael@paquier.xyz
In reply to: vignesh C (#1)
Re: Unused header file inclusion

On Wed, Jul 31, 2019 at 11:19:08AM +0530, vignesh C wrote:

I noticed that there are many header files being included which need
not be included. I have tried this in a few files and found the
compilation and regression to be working. I have attached the patch
for the files that I tried. I tried this in CentOS, I did not find
the header files to be platform specific.
Should we pursue this further and cleanup in all the files?

Do you use a particular method here or just manual deduction after
looking at each file individually? If this can be cleaned up a bit, I
think that's welcome. The removal of headers is easily forgotten when
moving code from one file to another...
--
Michael

#3vignesh C
vignesh21@gmail.com
In reply to: Michael Paquier (#2)
Re: Unused header file inclusion

On Wed, Jul 31, 2019 at 11:26 AM Michael Paquier <michael@paquier.xyz> wrote:

On Wed, Jul 31, 2019 at 11:19:08AM +0530, vignesh C wrote:

I noticed that there are many header files being included which need
not be included. I have tried this in a few files and found the
compilation and regression to be working. I have attached the patch
for the files that I tried. I tried this in CentOS, I did not find
the header files to be platform specific.
Should we pursue this further and cleanup in all the files?

Do you use a particular method here or just manual deduction after
looking at each file individually? If this can be cleaned up a bit, I
think that's welcome. The removal of headers is easily forgotten when
moving code from one file to another...

Thanks Michael.
I'm writing some perl scripts to identify this.
The script will scan through all the files, make changes,
and verify.
Finally it will give the changed files.

Regards,
Vignesh
EnterpriseDB: http://www.enterprisedb.com

#4Amit Kapila
amit.kapila16@gmail.com
In reply to: vignesh C (#3)
Re: Unused header file inclusion

On Wed, Jul 31, 2019 at 11:31 AM vignesh C <vignesh21@gmail.com> wrote:

On Wed, Jul 31, 2019 at 11:26 AM Michael Paquier <michael@paquier.xyz> wrote:

On Wed, Jul 31, 2019 at 11:19:08AM +0530, vignesh C wrote:

I noticed that there are many header files being included which need
not be included. I have tried this in a few files and found the
compilation and regression to be working. I have attached the patch
for the files that I tried. I tried this in CentOS, I did not find
the header files to be platform specific.
Should we pursue this further and cleanup in all the files?

Do you use a particular method here or just manual deduction after
looking at each file individually? If this can be cleaned up a bit, I
think that's welcome. The removal of headers is easily forgotten when
moving code from one file to another...

Thanks Michael.
I'm writing some perl scripts to identify this.
The script will scan through all the files, make changes,
and verify.

If we can come up with some such tool, we might be able to integrate
it with Thomas's patch tester [1]http://commitfest.cputube.org/ wherein it can apply the patch,
verify if there are unnecessary includes in the patch and report the
same.

[1]: http://commitfest.cputube.org/

--
With Regards,
Amit Kapila.
EnterpriseDB: http://www.enterprisedb.com

#5vignesh C
vignesh21@gmail.com
In reply to: Amit Kapila (#4)
Re: Unused header file inclusion

On Wed, Jul 31, 2019 at 11:55 AM Amit Kapila <amit.kapila16@gmail.com> wrote:

On Wed, Jul 31, 2019 at 11:31 AM vignesh C <vignesh21@gmail.com> wrote:

On Wed, Jul 31, 2019 at 11:26 AM Michael Paquier <michael@paquier.xyz> wrote:

On Wed, Jul 31, 2019 at 11:19:08AM +0530, vignesh C wrote:

I noticed that there are many header files being included which need
not be included. I have tried this in a few files and found the
compilation and regression to be working. I have attached the patch
for the files that I tried. I tried this in CentOS, I did not find
the header files to be platform specific.
Should we pursue this further and cleanup in all the files?

Do you use a particular method here or just manual deduction after
looking at each file individually? If this can be cleaned up a bit, I
think that's welcome. The removal of headers is easily forgotten when
moving code from one file to another...

Thanks Michael.
I'm writing some perl scripts to identify this.
The script will scan through all the files, make changes,
and verify.

If we can come up with some such tool, we might be able to integrate
it with Thomas's patch tester [1] wherein it can apply the patch,
verify if there are unnecessary includes in the patch and report the
same.

[1] - http://commitfest.cputube.org/

Thanks Amit.
I will post the tool along with the patch once I complete this activity. We
can enhance the tool further based on feedback and take it forward.

Regards,
Vignesh
EnterpriseDB: http://www.enterprisedb.com

#6Michael Paquier
michael@paquier.xyz
In reply to: Amit Kapila (#4)
Re: Unused header file inclusion

On Wed, Jul 31, 2019 at 11:55:37AM +0530, Amit Kapila wrote:

If we can come up with some such tool, we might be able to integrate
it with Thomas's patch tester [1] wherein it can apply the patch,
verify if there are unnecessary includes in the patch and report the
same.

[1] - http://commitfest.cputube.org/

Or even get something into src/tools/? If the produced result is
clean enough, that could be interesting.
--
Michael

#7Andres Freund
andres@anarazel.de
In reply to: vignesh C (#1)
Re: Unused header file inclusion

Hi,

On 2019-07-31 11:19:08 +0530, vignesh C wrote:

I noticed that there are many header files being
included which need not be included.
I have tried this in a few files and found the
compilation and regression to be working.
I have attached the patch for the files that
I tried.
I tried this in CentOS, I did not find the header
files to be platform specific.
Should we pursue this further and cleanup in
all the files?

These type of changes imo have a good chance of making things more
fragile. A lot of the includes in header files are purely due to needing
one or two definitions (which often could even be avoided by forward
declarations). If you remove all the includes directly from the c files
that are also included from some .h file, you increase the reliance on
the indirect includes - making it harder to clean up.

If anything, we should *increase* the number of includes, so we don't
rely on indirect includes. But that's also not necessarily the right
choice, because it adds unnecessary dependencies.

--- a/src/backend/utils/mmgr/freepage.c
+++ b/src/backend/utils/mmgr/freepage.c
@@ -56,7 +56,6 @@
#include "miscadmin.h"

#include "utils/freepage.h"
-#include "utils/relptr.h"

I don't think it's a good idea to remove this header, for example. A
*lot* of code in freepage.c relies on it. The fact that freepage.h also
includes it here is just due to needing other parts of it

/* Magic numbers to identify various page types */
diff --git a/src/backend/utils/mmgr/portalmem.c b/src/backend/utils/mmgr/portalmem.c
index 334e35b..67268fd 100644
--- a/src/backend/utils/mmgr/portalmem.c
+++ b/src/backend/utils/mmgr/portalmem.c
@@ -26,7 +26,6 @@
#include "utils/builtins.h"
#include "utils/memutils.h"
#include "utils/snapmgr.h"
-#include "utils/timestamp.h"

Similarly, this file uses timestamp.h functions directly. The fact that
timestamp.h already is included is just due to implementation details of
xact.h that this file shouldn't depend on.

Greetings,

Andres Freund

#8Tom Lane
tgl@sss.pgh.pa.us
In reply to: Michael Paquier (#6)
Re: Unused header file inclusion

Michael Paquier <michael@paquier.xyz> writes:

On Wed, Jul 31, 2019 at 11:55:37AM +0530, Amit Kapila wrote:

If we can come up with some such tool, we might be able to integrate
it with Thomas's patch tester [1] wherein it can apply the patch,
verify if there are unnecessary includes in the patch and report the
same.

Or even get something into src/tools/? If the produced result is
clean enough, that could be interesting.

I take it nobody has actually bothered to *look* in src/tools.

src/tools/pginclude/README

Note that our experience with this sort of thing has not been very good.
See particularly 1609797c2.

regards, tom lane

#9Alvaro Herrera
alvherre@2ndquadrant.com
In reply to: vignesh C (#1)
Re: Unused header file inclusion

On 2019-Jul-31, vignesh C wrote:

I noticed that there are many header files being
included which need not be included.

Yeah, we have tooling for this already in src/tools/pginclude. It's
been used before, and it has wreaked considerable havoc; see "git log
--grep pgrminclude".

I think doing this sort of cleanup is useful to a point -- as Andres
mentions, some includes are somewhat more "important" than others, so
judgement is needed in each case.

I think removing unnecessary include lines from header files is much
more useful than from .c files. However, nowadays even I am not very
convinced that that is a very fruitful use of time, since many/most
developers use ccache which will reduce the compile times anyway in many
cases; and development machines are typically much faster than ten years
ago.

Also, I think addition of new include lines to existing .c files should
be a point worth specific attention in patch review, to avoid breaking
reasonable modularity boundaries unnecessarily.

--
�lvaro Herrera https://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services

#10Andres Freund
andres@anarazel.de
In reply to: Alvaro Herrera (#9)
Re: Unused header file inclusion

Hi,

On 2019-07-31 11:23:22 -0400, Alvaro Herrera wrote:

I think removing unnecessary include lines from header files is much
more useful than from .c files. However, nowadays even I am not very
convinced that that is a very fruitful use of time, since many/most
developers use ccache which will reduce the compile times anyway in many
cases; and development machines are typically much faster than ten years
ago.

IDK, I find the compilation times annoying. And it's gotten quite
noticably worse with all the speculative execution mitigations. Although
to some degree that's not really the fault of individual compilations,
but our buildsystem being pretty slow.

I think there's also just modularity reasons for removing includes from
headers. We've some pretty oddly interlinked systems, often without good
reason (*). Cleaning those up imo is well worth the time - but hardly
can be automated.

If one really wanted to automate removal of header files, it'd need to
be a lot smarter than just checking whether a file fails to compile if
one header is removed. In the general case we'd have to test if the .c
file itself uses any of the symbols from the possibly-to-be-removed
header. That's hard to do without using something like llvm's
libclang. The one case that's perhaps a bit easier to automate, and
possibly worthwhile: If a header is not indirectly included (possibly
testable via #ifndef HEADER_NAME_H #error 'already included' etc), and
compilation doesn't fail with it removed, *then* it's actually likely
useless (except for portability cases).

* I think a lot of the interlinking stems from the bad idea to use
typedef's everywhere. In contrast to structs they cannot be forward
declared portably in our version of C. We should use a lot more struct
forward declarations, and just not use the typedef.

Greetings,

Andres Freund

#11Alvaro Herrera
alvherre@2ndquadrant.com
In reply to: Andres Freund (#10)
Re: Unused header file inclusion

On 2019-Jul-31, Andres Freund wrote:

IDK, I find the compilation times annoying. And it's gotten quite
noticably worse with all the speculative execution mitigations. Although
to some degree that's not really the fault of individual compilations,
but our buildsystem being pretty slow.

We're in a much better position now than a decade ago, in terms of clock
time. Back then I would resort to many tricks to avoid spurious
compiles, even manually touching some files to dates in the past to
avoid them. Nowadays I never bother with such things. But yes,
reducing the build time even more would be welcome for sure.

* I think a lot of the interlinking stems from the bad idea to use
typedef's everywhere. In contrast to structs they cannot be forward
declared portably in our version of C. We should use a lot more struct
forward declarations, and just not use the typedef.

I don't know about that ... I think the problem is that we both declare
the typedef *and* define the struct in the same place. If we were to
split those things to separate files, the required rebuilds would be
much less, I think, because changing a struct would no longer require
recompiles of files that merely pass those structs around (that's very
common for Node-derived structs). Forward-declaring structs in
unrelated header files just because they need them, feels a bit like
cheating to me.

--
�lvaro Herrera https://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services

#12Tom Lane
tgl@sss.pgh.pa.us
In reply to: Alvaro Herrera (#11)
Re: Unused header file inclusion

Alvaro Herrera <alvherre@2ndquadrant.com> writes:

On 2019-Jul-31, Andres Freund wrote:

* I think a lot of the interlinking stems from the bad idea to use
typedef's everywhere. In contrast to structs they cannot be forward
declared portably in our version of C. We should use a lot more struct
forward declarations, and just not use the typedef.

I don't know about that ... I think the problem is that we both declare
the typedef *and* define the struct in the same place. If we were to
split those things to separate files, the required rebuilds would be
much less, I think, because changing a struct would no longer require
recompiles of files that merely pass those structs around (that's very
common for Node-derived structs). Forward-declaring structs in
unrelated header files just because they need them, feels a bit like
cheating to me.

Yeah. I seem to recall a proposal that nodes.h should contain

typedef struct Foo Foo;

for every node type Foo, and then the other headers would just
fill in the structs, and we could get rid of a lot of ad-hoc
forward struct declarations and other hackery.

regards, tom lane

#13Andres Freund
andres@anarazel.de
In reply to: Tom Lane (#12)
Re: Unused header file inclusion

Hi,

On 2019-07-31 16:55:31 -0400, Tom Lane wrote:

Alvaro Herrera <alvherre@2ndquadrant.com> writes:

On 2019-Jul-31, Andres Freund wrote:

* I think a lot of the interlinking stems from the bad idea to use
typedef's everywhere. In contrast to structs they cannot be forward
declared portably in our version of C. We should use a lot more struct
forward declarations, and just not use the typedef.

I don't know about that ... I think the problem is that we both declare
the typedef *and* define the struct in the same place. If we were to
split those things to separate files, the required rebuilds would be
much less, I think, because changing a struct would no longer require
recompiles of files that merely pass those structs around (that's very
common for Node-derived structs). Forward-declaring structs in
unrelated header files just because they need them, feels a bit like
cheating to me.

Yeah. I seem to recall a proposal that nodes.h should contain

typedef struct Foo Foo;

for every node type Foo, and then the other headers would just
fill in the structs, and we could get rid of a lot of ad-hoc
forward struct declarations and other hackery.

That to me just seems objectively worse. Now adding a new struct as a
minor implementation detail of some subsystem doesn't just require
recompiling the relevant files, but just about all of pg. And just about
every header would acquire a nodes.h include - there's still a lot of them
that today don't.

I don't understand why you guys consider forward declaring structs
ugly. It's what just about every other C project does. The only reason
it's sometimes problematic in postgres is that we "hide the pointer"
within some typedefs, making it not as obvious which type we're
referring to (because the struct usage will be struct FooData*, instead
of just Foo). But we also have confusion due to that in a lot of other
places, so I don't really buy that this is a significant issue.

Right now we really have weird dependencies between largely independent
subsystem. Some are partially because functions aren't always in the
right file, but it's also not often clear what the right one would
be. E.g. snapmgr.h depending on relcache.h (for
TransactionIdLimitedForOldSnapshots() having a Relation parameter), on
resowner.h (for RegisterSnapshotOnOwner()) is imo not good. For one
they lead to a number of .c files that actually use functionality from
resowner.h to not have the necessary includes. There's a lot of things
like that.

.oO(the fmgr.h include in snapmgr.h has been unnecessary since 352a24a1f9)

We could of course be super rigorous and have an accompanying
foo_structs.h or something for every foo.h. But that seems to add no
actual advantages, and makes things more complicated.

The only reason the explicit forward declaration is needed in the common
case of a 'struct foo*' parameter is that C has weird visibility rules
about the scope of forward declarations in paramters. If you instead
first have e.g. a function *return* type of that struct type, the
explicit forward declaration isn't even needed - it's visible
afterwards. But for parameters it's basically a *different* struct, that
cannot be referenced again. Note that in C++ the visibility routines are
more consistent, and you don't need an explicit forward declaration in
either case (I'd also be OK with requiring it in both cases, it's just
weird to only need them in one).

Greetings,

Andres Freund

#14Tom Lane
tgl@sss.pgh.pa.us
In reply to: Andres Freund (#13)
Re: Unused header file inclusion

Andres Freund <andres@anarazel.de> writes:

On 2019-07-31 16:55:31 -0400, Tom Lane wrote:

Yeah. I seem to recall a proposal that nodes.h should contain

typedef struct Foo Foo;

for every node type Foo, and then the other headers would just
fill in the structs, and we could get rid of a lot of ad-hoc
forward struct declarations and other hackery.

That to me just seems objectively worse. Now adding a new struct as a
minor implementation detail of some subsystem doesn't just require
recompiling the relevant files, but just about all of pg.

Er, what? This list of typedefs would change exactly when enum NodeTag
changes, so AFAICS your objection is bogus.

It's true that this proposal doesn't help for structs that aren't Nodes,
but my sense is that > 90% of our ad-hoc struct references are for Nodes.

Right now we really have weird dependencies between largely independent
subsystem.

Agreed, but I think fixing that will take some actually serious design
work. It's not going to mechanically fall out of changing typedef rules.

The only reason the explicit forward declaration is needed in the common
case of a 'struct foo*' parameter is that C has weird visibility rules
about the scope of forward declarations in paramters.

Yeah, but there's not much we can do about that, nor is getting rid
of typedefs in favor of "struct" going to make it even a little bit
better.

regards, tom lane

#15Andres Freund
andres@anarazel.de
In reply to: Tom Lane (#14)
4 attachment(s)
Re: Unused header file inclusion

Hi,

On 2019-07-31 19:25:01 -0400, Tom Lane wrote:

Andres Freund <andres@anarazel.de> writes:

On 2019-07-31 16:55:31 -0400, Tom Lane wrote:

Yeah. I seem to recall a proposal that nodes.h should contain

typedef struct Foo Foo;

for every node type Foo, and then the other headers would just
fill in the structs, and we could get rid of a lot of ad-hoc
forward struct declarations and other hackery.

That to me just seems objectively worse. Now adding a new struct as a
minor implementation detail of some subsystem doesn't just require
recompiling the relevant files, but just about all of pg.

Er, what? This list of typedefs would change exactly when enum NodeTag
changes, so AFAICS your objection is bogus.

It's true that this proposal doesn't help for structs that aren't Nodes,
but my sense is that > 90% of our ad-hoc struct references are for Nodes.

Ah, well, I somehow assumed you were talking about all nodes. I don't
think I agree with the 90% figure. In headers I feel like most the
references are to things like Relation, Snapshot, HeapTuple, etc.

Right now we really have weird dependencies between largely independent
subsystem.

Agreed, but I think fixing that will take some actually serious design
work. It's not going to mechanically fall out of changing typedef rules.

No, but without finding a more workable approach than what we're doing
often doing now wrt includes and forward declares, we'll have a lot
harder time to separate subsystems out more.

The only reason the explicit forward declaration is needed in the common
case of a 'struct foo*' parameter is that C has weird visibility rules
about the scope of forward declarations in paramters.

Yeah, but there's not much we can do about that, nor is getting rid
of typedefs in favor of "struct" going to make it even a little bit
better.

It imo pretty fundamentally does. You cannot redefine typedefs, but you
can forward declare structs.

E.g. in the attached series of patches, I'm removing a good portion of
unnecessary dependencies to fmgr.h. But to actually make a difference
that requires referencing two structs without including the header - and
I don't think restructing fmgr.h into two headers is a particularly
attractive alternative (would make it a lot more work and a lot more
invasive).

Think the first three are pretty clearly a good idea, I'm a bit less
sanguine about the fourth:
Headers like utils/timestamp.h are often included just because we need a
TimestampTz type somewhere, or call GetCurrentTimestamp(). Approximately
none of these need the PG_GETARG_* macros, which are the only reason for
including fmgr.h in these headers. As they're macros that's not
actually needed, although I think normally good style. But I' think here
avoiding exposing fmgr.h to more headers is a bigger win.

Greetings,

Andres Freund

Attachments:

v1-0001-Remove-redundant-prototypes-for-SQL-callable-func.patchtext/x-diff; charset=us-asciiDownload
From 1b45edcb73e4b407cf6449246e57788c5a283b99 Mon Sep 17 00:00:00 2001
From: Andres Freund <andres@anarazel.de>
Date: Sat, 3 Aug 2019 12:19:41 -0700
Subject: [PATCH v1 1/4] Remove redundant prototypes for SQL callable
 functions.

These aren't needed after 352a24a1f9d6. The ones remaining after this
are not defined on the SQL level.

Author:
Reviewed-By:
Discussion: https://postgr.es/m/
Backpatch:
---
 src/include/catalog/pg_publication.h | 1 -
 src/include/executor/nodeAgg.h       | 2 --
 2 files changed, 3 deletions(-)

diff --git a/src/include/catalog/pg_publication.h b/src/include/catalog/pg_publication.h
index d4bf5b1e2fa..20a2f0ac1bf 100644
--- a/src/include/catalog/pg_publication.h
+++ b/src/include/catalog/pg_publication.h
@@ -92,6 +92,5 @@ extern ObjectAddress publication_add_relation(Oid pubid, Relation targetrel,
 extern Oid	get_publication_oid(const char *pubname, bool missing_ok);
 extern char *get_publication_name(Oid pubid, bool missing_ok);
 
-extern Datum pg_get_publication_tables(PG_FUNCTION_ARGS);
 
 #endif							/* PG_PUBLICATION_H */
diff --git a/src/include/executor/nodeAgg.h b/src/include/executor/nodeAgg.h
index 1a8ca98a8c3..68c9e5f5400 100644
--- a/src/include/executor/nodeAgg.h
+++ b/src/include/executor/nodeAgg.h
@@ -311,6 +311,4 @@ extern void ExecReScanAgg(AggState *node);
 
 extern Size hash_agg_entry_size(int numAggs);
 
-extern Datum aggregate_dummy(PG_FUNCTION_ARGS);
-
 #endif							/* NODEAGG_H */
-- 
2.22.0.545.g9c9b961d7e

v1-0002-Don-t-include-utils-array.h-from-acl.h.patchtext/x-diff; charset=us-asciiDownload
From d34cb9a51e4c35630012a0a85cc51d2d4c29d367 Mon Sep 17 00:00:00 2001
From: Andres Freund <andres@anarazel.de>
Date: Sat, 3 Aug 2019 11:51:43 -0700
Subject: [PATCH v1 2/4] Don't include utils/array.h from acl.h.

For most uses of acl.h the details of how "Acl" internally looks like
is irrelevant. In fact, it might make sense to move a lot of the
implementation details into a separate header.

The main motivation of this change is to avoid including fmgr.h (via
array.h, which needs it for exposed structs) in a lot of files that
otherwise don't need it. A future commit will remove fmgr.h from a lot
of files.

Directly include utils/array.h and utils/expandeddatum.h from the
files that need them, but previously included them indirectly, via
acl.h.

Author:
Reviewed-By:
Discussion: https://postgr.es/m/
Backpatch:
---
 contrib/pageinspect/hashfuncs.c         | 1 +
 src/backend/executor/execExpr.c         | 1 +
 src/backend/executor/execExprInterp.c   | 1 +
 src/backend/executor/execTuples.c       | 1 +
 src/backend/executor/nodeAgg.c          | 1 +
 src/backend/executor/nodeWindowAgg.c    | 1 +
 src/backend/partitioning/partprune.c    | 1 +
 src/backend/statistics/extended_stats.c | 1 +
 src/backend/statistics/mcv.c            | 1 +
 src/backend/utils/adt/acl.c             | 1 +
 src/backend/utils/adt/tsvector_op.c     | 1 +
 src/include/catalog/objectaddress.h     | 2 +-
 src/include/utils/acl.h                 | 3 +--
 src/include/utils/array.h               | 2 +-
 14 files changed, 14 insertions(+), 4 deletions(-)

diff --git a/contrib/pageinspect/hashfuncs.c b/contrib/pageinspect/hashfuncs.c
index e69913302ac..9374c4aabc4 100644
--- a/contrib/pageinspect/hashfuncs.c
+++ b/contrib/pageinspect/hashfuncs.c
@@ -18,6 +18,7 @@
 #include "catalog/pg_am.h"
 #include "funcapi.h"
 #include "miscadmin.h"
+#include "utils/array.h"
 #include "utils/builtins.h"
 #include "utils/rel.h"
 
diff --git a/src/backend/executor/execExpr.c b/src/backend/executor/execExpr.c
index 6d09f2a2181..58e2432aac7 100644
--- a/src/backend/executor/execExpr.c
+++ b/src/backend/executor/execExpr.c
@@ -42,6 +42,7 @@
 #include "nodes/nodeFuncs.h"
 #include "optimizer/optimizer.h"
 #include "pgstat.h"
+#include "utils/array.h"
 #include "utils/builtins.h"
 #include "utils/datum.h"
 #include "utils/lsyscache.h"
diff --git a/src/backend/executor/execExprInterp.c b/src/backend/executor/execExprInterp.c
index 66a67c72b29..d61f75bc3b6 100644
--- a/src/backend/executor/execExprInterp.c
+++ b/src/backend/executor/execExprInterp.c
@@ -62,6 +62,7 @@
 #include "executor/execExpr.h"
 #include "executor/nodeSubplan.h"
 #include "funcapi.h"
+#include "utils/array.h"
 #include "utils/memutils.h"
 #include "miscadmin.h"
 #include "nodes/nodeFuncs.h"
diff --git a/src/backend/executor/execTuples.c b/src/backend/executor/execTuples.c
index 5ee2a464bb4..697f1fed71d 100644
--- a/src/backend/executor/execTuples.c
+++ b/src/backend/executor/execTuples.c
@@ -65,6 +65,7 @@
 #include "nodes/nodeFuncs.h"
 #include "storage/bufmgr.h"
 #include "utils/builtins.h"
+#include "utils/expandeddatum.h"
 #include "utils/lsyscache.h"
 #include "utils/typcache.h"
 
diff --git a/src/backend/executor/nodeAgg.c b/src/backend/executor/nodeAgg.c
index a9a1fd022a5..58c376aeb74 100644
--- a/src/backend/executor/nodeAgg.c
+++ b/src/backend/executor/nodeAgg.c
@@ -231,6 +231,7 @@
 #include "parser/parse_coerce.h"
 #include "utils/acl.h"
 #include "utils/builtins.h"
+#include "utils/expandeddatum.h"
 #include "utils/lsyscache.h"
 #include "utils/memutils.h"
 #include "utils/syscache.h"
diff --git a/src/backend/executor/nodeWindowAgg.c b/src/backend/executor/nodeWindowAgg.c
index def00cd7c5f..6a71c1295d2 100644
--- a/src/backend/executor/nodeWindowAgg.c
+++ b/src/backend/executor/nodeWindowAgg.c
@@ -46,6 +46,7 @@
 #include "parser/parse_coerce.h"
 #include "utils/acl.h"
 #include "utils/builtins.h"
+#include "utils/expandeddatum.h"
 #include "utils/datum.h"
 #include "utils/lsyscache.h"
 #include "utils/memutils.h"
diff --git a/src/backend/partitioning/partprune.c b/src/backend/partitioning/partprune.c
index 6d3751d44a6..0feb8f4a115 100644
--- a/src/backend/partitioning/partprune.c
+++ b/src/backend/partitioning/partprune.c
@@ -53,6 +53,7 @@
 #include "partitioning/partbounds.h"
 #include "partitioning/partprune.h"
 #include "rewrite/rewriteManip.h"
+#include "utils/array.h"
 #include "utils/lsyscache.h"
 
 
diff --git a/src/backend/statistics/extended_stats.c b/src/backend/statistics/extended_stats.c
index 23c74f7d90a..48f17ba8d56 100644
--- a/src/backend/statistics/extended_stats.c
+++ b/src/backend/statistics/extended_stats.c
@@ -31,6 +31,7 @@
 #include "postmaster/autovacuum.h"
 #include "statistics/extended_stats_internal.h"
 #include "statistics/statistics.h"
+#include "utils/array.h"
 #include "utils/builtins.h"
 #include "utils/fmgroids.h"
 #include "utils/lsyscache.h"
diff --git a/src/backend/statistics/mcv.c b/src/backend/statistics/mcv.c
index cec06f8c444..bae6f219684 100644
--- a/src/backend/statistics/mcv.c
+++ b/src/backend/statistics/mcv.c
@@ -26,6 +26,7 @@
 #include "optimizer/clauses.h"
 #include "statistics/extended_stats_internal.h"
 #include "statistics/statistics.h"
+#include "utils/array.h"
 #include "utils/builtins.h"
 #include "utils/bytea.h"
 #include "utils/fmgroids.h"
diff --git a/src/backend/utils/adt/acl.c b/src/backend/utils/adt/acl.c
index cfd139e6e92..d7e6100ccbf 100644
--- a/src/backend/utils/adt/acl.c
+++ b/src/backend/utils/adt/acl.c
@@ -30,6 +30,7 @@
 #include "funcapi.h"
 #include "miscadmin.h"
 #include "utils/acl.h"
+#include "utils/array.h"
 #include "utils/builtins.h"
 #include "utils/catcache.h"
 #include "utils/hashutils.h"
diff --git a/src/backend/utils/adt/tsvector_op.c b/src/backend/utils/adt/tsvector_op.c
index 696a7fdf914..28d042273e3 100644
--- a/src/backend/utils/adt/tsvector_op.c
+++ b/src/backend/utils/adt/tsvector_op.c
@@ -25,6 +25,7 @@
 #include "miscadmin.h"
 #include "parser/parse_coerce.h"
 #include "tsearch/ts_utils.h"
+#include "utils/array.h"
 #include "utils/builtins.h"
 #include "utils/lsyscache.h"
 #include "utils/regproc.h"
diff --git a/src/include/catalog/objectaddress.h b/src/include/catalog/objectaddress.h
index 95cc3158683..7e61569f9fe 100644
--- a/src/include/catalog/objectaddress.h
+++ b/src/include/catalog/objectaddress.h
@@ -77,7 +77,7 @@ extern char *getObjectTypeDescription(const ObjectAddress *object);
 extern char *getObjectIdentity(const ObjectAddress *address);
 extern char *getObjectIdentityParts(const ObjectAddress *address,
 									List **objname, List **objargs);
-extern ArrayType *strlist_to_textarray(List *list);
+extern struct ArrayType *strlist_to_textarray(List *list);
 
 extern ObjectType get_relkind_objtype(char relkind);
 
diff --git a/src/include/utils/acl.h b/src/include/utils/acl.h
index f4c160ee723..b99da737283 100644
--- a/src/include/utils/acl.h
+++ b/src/include/utils/acl.h
@@ -35,7 +35,6 @@
 #include "access/htup.h"
 #include "nodes/parsenodes.h"
 #include "parser/parse_node.h"
-#include "utils/array.h"
 #include "utils/snapshot.h"
 
 
@@ -104,7 +103,7 @@ typedef struct AclItem
 /*
  * Acl			a one-dimensional array of AclItem
  */
-typedef ArrayType Acl;
+typedef struct ArrayType Acl;
 
 #define ACL_NUM(ACL)			(ARR_DIMS(ACL)[0])
 #define ACL_DAT(ACL)			((AclItem *) ARR_DATA_PTR(ACL))
diff --git a/src/include/utils/array.h b/src/include/utils/array.h
index b441eb452b9..5cfafe00457 100644
--- a/src/include/utils/array.h
+++ b/src/include/utils/array.h
@@ -77,7 +77,7 @@ struct ExprContext;
  * CAUTION: if you change the header for ordinary arrays you will also
  * need to change the headers for oidvector and int2vector!
  */
-typedef struct
+typedef struct ArrayType
 {
 	int32		vl_len_;		/* varlena header (do not touch directly!) */
 	int			ndim;			/* # of dimensions */
-- 
2.22.0.545.g9c9b961d7e

v1-0003-Remove-fmgr.h-includes-from-headers-that-don-t-re.patchtext/x-diff; charset=us-asciiDownload
From ffa727a9be04392491cde988eedf72ed47d7643b Mon Sep 17 00:00:00 2001
From: Andres Freund <andres@anarazel.de>
Date: Sat, 3 Aug 2019 12:17:19 -0700
Subject: [PATCH v1 3/4] Remove fmgr.h includes from headers that don't really
 need it.

Most of the fmgr.h includes were obsoleted by 352a24a1f9d6f7d4abb1. A
few others can be obsoleted using the underlying struct type in an
implementation detail.

Author:
Reviewed-By:
Discussion: https://postgr.es/m/
Backpatch:
---
 src/backend/access/common/printsimple.c     | 1 -
 src/backend/nodes/makefuncs.c               | 1 -
 src/backend/replication/logical/logical.c   | 1 +
 src/backend/replication/pgoutput/pgoutput.c | 2 ++
 src/include/access/brin.h                   | 1 -
 src/include/access/gist_private.h           | 1 -
 src/include/access/hash.h                   | 1 -
 src/include/access/spgist.h                 | 1 -
 src/include/commands/async.h                | 2 --
 src/include/executor/executor.h             | 1 +
 src/include/jit/llvmjit_emit.h              | 1 -
 src/include/nodes/execnodes.h               | 1 +
 src/include/nodes/pathnodes.h               | 3 +--
 src/include/pgstat.h                        | 4 ++--
 src/include/replication/origin.h            | 1 -
 src/include/replication/slot.h              | 1 -
 src/include/replication/walreceiver.h       | 1 -
 src/include/replication/walsender.h         | 2 --
 src/include/utils/bytea.h                   | 1 -
 src/include/utils/formatting.h              | 2 --
 src/include/utils/rel.h                     | 3 +--
 src/include/utils/snapmgr.h                 | 1 -
 src/include/utils/tuplesort.h               | 1 -
 23 files changed, 9 insertions(+), 25 deletions(-)

diff --git a/src/backend/access/common/printsimple.c b/src/backend/access/common/printsimple.c
index 3ea188d701c..651ade14dd2 100644
--- a/src/backend/access/common/printsimple.c
+++ b/src/backend/access/common/printsimple.c
@@ -20,7 +20,6 @@
 
 #include "access/printsimple.h"
 #include "catalog/pg_type.h"
-#include "fmgr.h"
 #include "libpq/pqformat.h"
 #include "utils/builtins.h"
 
diff --git a/src/backend/nodes/makefuncs.c b/src/backend/nodes/makefuncs.c
index 5c11b5472e5..18466ac5687 100644
--- a/src/backend/nodes/makefuncs.c
+++ b/src/backend/nodes/makefuncs.c
@@ -17,7 +17,6 @@
 
 #include "catalog/pg_class.h"
 #include "catalog/pg_type.h"
-#include "fmgr.h"
 #include "nodes/makefuncs.h"
 #include "nodes/nodeFuncs.h"
 #include "utils/lsyscache.h"
diff --git a/src/backend/replication/logical/logical.c b/src/backend/replication/logical/logical.c
index 9853be6d1c2..f8b9020081e 100644
--- a/src/backend/replication/logical/logical.c
+++ b/src/backend/replication/logical/logical.c
@@ -28,6 +28,7 @@
 
 #include "postgres.h"
 
+#include "fmgr.h"
 #include "miscadmin.h"
 
 #include "access/xact.h"
diff --git a/src/backend/replication/pgoutput/pgoutput.c b/src/backend/replication/pgoutput/pgoutput.c
index d317fd70063..9c08757fcaf 100644
--- a/src/backend/replication/pgoutput/pgoutput.c
+++ b/src/backend/replication/pgoutput/pgoutput.c
@@ -14,6 +14,8 @@
 
 #include "catalog/pg_publication.h"
 
+#include "fmgr.h"
+
 #include "replication/logical.h"
 #include "replication/logicalproto.h"
 #include "replication/origin.h"
diff --git a/src/include/access/brin.h b/src/include/access/brin.h
index 612721baf3a..fb351b36e03 100644
--- a/src/include/access/brin.h
+++ b/src/include/access/brin.h
@@ -10,7 +10,6 @@
 #ifndef BRIN_H
 #define BRIN_H
 
-#include "fmgr.h"
 #include "nodes/execnodes.h"
 #include "utils/relcache.h"
 
diff --git a/src/include/access/gist_private.h b/src/include/access/gist_private.h
index 664f322df3a..fc1a3115565 100644
--- a/src/include/access/gist_private.h
+++ b/src/include/access/gist_private.h
@@ -17,7 +17,6 @@
 #include "access/amapi.h"
 #include "access/gist.h"
 #include "access/itup.h"
-#include "fmgr.h"
 #include "lib/pairingheap.h"
 #include "storage/bufmgr.h"
 #include "storage/buffile.h"
diff --git a/src/include/access/hash.h b/src/include/access/hash.h
index 107c3d01ae4..85982e0e404 100644
--- a/src/include/access/hash.h
+++ b/src/include/access/hash.h
@@ -20,7 +20,6 @@
 #include "access/amapi.h"
 #include "access/itup.h"
 #include "access/sdir.h"
-#include "fmgr.h"
 #include "lib/stringinfo.h"
 #include "storage/bufmgr.h"
 #include "storage/lockdefs.h"
diff --git a/src/include/access/spgist.h b/src/include/access/spgist.h
index 02c87949cee..d787ab213dc 100644
--- a/src/include/access/spgist.h
+++ b/src/include/access/spgist.h
@@ -16,7 +16,6 @@
 
 #include "access/amapi.h"
 #include "access/xlogreader.h"
-#include "fmgr.h"
 #include "lib/stringinfo.h"
 
 
diff --git a/src/include/commands/async.h b/src/include/commands/async.h
index d132fd59991..c295dc67c64 100644
--- a/src/include/commands/async.h
+++ b/src/include/commands/async.h
@@ -15,8 +15,6 @@
 
 #include <signal.h>
 
-#include "fmgr.h"
-
 /*
  * The number of SLRU page buffers we use for the notification queue.
  */
diff --git a/src/include/executor/executor.h b/src/include/executor/executor.h
index 1fb28b4596b..254db49a3ce 100644
--- a/src/include/executor/executor.h
+++ b/src/include/executor/executor.h
@@ -15,6 +15,7 @@
 #define EXECUTOR_H
 
 #include "executor/execdesc.h"
+#include "fmgr.h"
 #include "nodes/lockoptions.h"
 #include "nodes/parsenodes.h"
 #include "utils/memutils.h"
diff --git a/src/include/jit/llvmjit_emit.h b/src/include/jit/llvmjit_emit.h
index 71a8625efe4..cdfa0dc7214 100644
--- a/src/include/jit/llvmjit_emit.h
+++ b/src/include/jit/llvmjit_emit.h
@@ -17,7 +17,6 @@
 
 #include <llvm-c/Core.h>
 
-#include "fmgr.h"
 #include "jit/llvmjit.h"
 
 
diff --git a/src/include/nodes/execnodes.h b/src/include/nodes/execnodes.h
index 4ec78491f6f..c682e86de7d 100644
--- a/src/include/nodes/execnodes.h
+++ b/src/include/nodes/execnodes.h
@@ -16,6 +16,7 @@
 
 #include "access/tupconvert.h"
 #include "executor/instrument.h"
+#include "fmgr.h"
 #include "lib/pairingheap.h"
 #include "nodes/params.h"
 #include "nodes/plannodes.h"
diff --git a/src/include/nodes/pathnodes.h b/src/include/nodes/pathnodes.h
index e3c579ee443..510f41a4049 100644
--- a/src/include/nodes/pathnodes.h
+++ b/src/include/nodes/pathnodes.h
@@ -15,7 +15,6 @@
 #define PATHNODES_H
 
 #include "access/sdir.h"
-#include "fmgr.h"
 #include "lib/stringinfo.h"
 #include "nodes/params.h"
 #include "nodes/parsenodes.h"
@@ -401,7 +400,7 @@ typedef struct PartitionSchemeData
 	bool	   *parttypbyval;
 
 	/* Cached information about partition comparison functions. */
-	FmgrInfo   *partsupfunc;
+	struct FmgrInfo *partsupfunc;
 }			PartitionSchemeData;
 
 typedef struct PartitionSchemeData *PartitionScheme;
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index 0a3ad3a1883..fe076d823db 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -12,7 +12,6 @@
 #define PGSTAT_H
 
 #include "datatype/timestamp.h"
-#include "fmgr.h"
 #include "libpq/pqcomm.h"
 #include "port/atomics.h"
 #include "portability/instr_time.h"
@@ -1402,7 +1401,8 @@ extern void pgstat_count_heap_delete(Relation rel);
 extern void pgstat_count_truncate(Relation rel);
 extern void pgstat_update_heap_dead_tuples(Relation rel, int delta);
 
-extern void pgstat_init_function_usage(FunctionCallInfo fcinfo,
+struct FunctionCallInfoBaseData;
+extern void pgstat_init_function_usage(struct FunctionCallInfoBaseData *fcinfo,
 									   PgStat_FunctionCallUsage *fcu);
 extern void pgstat_end_function_usage(PgStat_FunctionCallUsage *fcu,
 									  bool finalize);
diff --git a/src/include/replication/origin.h b/src/include/replication/origin.h
index 7422b26a6d8..dccf48418ff 100644
--- a/src/include/replication/origin.h
+++ b/src/include/replication/origin.h
@@ -10,7 +10,6 @@
 #ifndef PG_ORIGIN_H
 #define PG_ORIGIN_H
 
-#include "fmgr.h"
 #include "access/xlog.h"
 #include "access/xlogdefs.h"
 #include "access/xlogreader.h"
diff --git a/src/include/replication/slot.h b/src/include/replication/slot.h
index 8fbddea78fd..3a5763fb07a 100644
--- a/src/include/replication/slot.h
+++ b/src/include/replication/slot.h
@@ -9,7 +9,6 @@
 #ifndef SLOT_H
 #define SLOT_H
 
-#include "fmgr.h"
 #include "access/xlog.h"
 #include "access/xlogreader.h"
 #include "storage/condition_variable.h"
diff --git a/src/include/replication/walreceiver.h b/src/include/replication/walreceiver.h
index 86a81300517..bc9468b519e 100644
--- a/src/include/replication/walreceiver.h
+++ b/src/include/replication/walreceiver.h
@@ -14,7 +14,6 @@
 
 #include "access/xlog.h"
 #include "access/xlogdefs.h"
-#include "fmgr.h"
 #include "getaddrinfo.h"		/* for NI_MAXHOST */
 #include "replication/logicalproto.h"
 #include "replication/walsender.h"
diff --git a/src/include/replication/walsender.h b/src/include/replication/walsender.h
index 4a60893a3bc..61223aecbc1 100644
--- a/src/include/replication/walsender.h
+++ b/src/include/replication/walsender.h
@@ -14,8 +14,6 @@
 
 #include <signal.h>
 
-#include "fmgr.h"
-
 /*
  * What to do with a snapshot in create replication slot command.
  */
diff --git a/src/include/utils/bytea.h b/src/include/utils/bytea.h
index c96011fae84..72224ca95f3 100644
--- a/src/include/utils/bytea.h
+++ b/src/include/utils/bytea.h
@@ -14,7 +14,6 @@
 #ifndef BYTEA_H
 #define BYTEA_H
 
-#include "fmgr.h"
 
 
 typedef enum
diff --git a/src/include/utils/formatting.h b/src/include/utils/formatting.h
index 741c5f4809f..0117144779e 100644
--- a/src/include/utils/formatting.h
+++ b/src/include/utils/formatting.h
@@ -17,8 +17,6 @@
 #ifndef _FORMATTING_H_
 #define _FORMATTING_H_
 
-#include "fmgr.h"
-
 
 extern char *str_tolower(const char *buff, size_t nbytes, Oid collid);
 extern char *str_toupper(const char *buff, size_t nbytes, Oid collid);
diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h
index b0fe19ebc54..302dfff1f3d 100644
--- a/src/include/utils/rel.h
+++ b/src/include/utils/rel.h
@@ -19,7 +19,6 @@
 #include "catalog/pg_class.h"
 #include "catalog/pg_index.h"
 #include "catalog/pg_publication.h"
-#include "fmgr.h"
 #include "nodes/bitmapset.h"
 #include "rewrite/prs2lock.h"
 #include "storage/block.h"
@@ -159,7 +158,7 @@ typedef struct RelationData
 	Oid		   *rd_opfamily;	/* OIDs of op families for each index col */
 	Oid		   *rd_opcintype;	/* OIDs of opclass declared input data types */
 	RegProcedure *rd_support;	/* OIDs of support procedures */
-	FmgrInfo   *rd_supportinfo; /* lookup info for support procedures */
+	struct FmgrInfo *rd_supportinfo; /* lookup info for support procedures */
 	int16	   *rd_indoption;	/* per-column AM-specific flags */
 	List	   *rd_indexprs;	/* index expression trees, if any */
 	List	   *rd_indpred;		/* index predicate tree, if any */
diff --git a/src/include/utils/snapmgr.h b/src/include/utils/snapmgr.h
index 6641ee510a1..8c070d7f412 100644
--- a/src/include/utils/snapmgr.h
+++ b/src/include/utils/snapmgr.h
@@ -14,7 +14,6 @@
 #define SNAPMGR_H
 
 #include "access/transam.h"
-#include "fmgr.h"
 #include "utils/relcache.h"
 #include "utils/resowner.h"
 #include "utils/snapshot.h"
diff --git a/src/include/utils/tuplesort.h b/src/include/utils/tuplesort.h
index 4521de18e13..d774bc1152f 100644
--- a/src/include/utils/tuplesort.h
+++ b/src/include/utils/tuplesort.h
@@ -23,7 +23,6 @@
 
 #include "access/itup.h"
 #include "executor/tuptable.h"
-#include "fmgr.h"
 #include "storage/dsm.h"
 #include "utils/relcache.h"
 
-- 
2.22.0.545.g9c9b961d7e

v1-0004-Remove-fmgr.h-includes-from-headers-that-have-mac.patchtext/x-diff; charset=us-asciiDownload
From 18c7d6760aadd033f84e799bb6ac8c94edbf2435 Mon Sep 17 00:00:00 2001
From: Andres Freund <andres@anarazel.de>
Date: Sat, 3 Aug 2019 12:21:27 -0700
Subject: [PATCH v1 4/4] Remove fmgr.h includes from headers that have macro
 only dependencies.

These headers all just include fmgr.h because they define macros that
in turn use fmgr.h macros, like PG_GETARG_DATUM. Most include sites
for these headers however just want to reference the type defined in
the respective header. Where needed fmgr.h can be included.

Author:
Reviewed-By:
Discussion: https://postgr.es/m/
Backpatch:
---
 contrib/earthdistance/earthdistance.c | 2 ++
 src/include/utils/cash.h              | 2 --
 src/include/utils/date.h              | 1 -
 src/include/utils/expandedrecord.h    | 1 -
 src/include/utils/geo_decls.h         | 2 --
 src/include/utils/inet.h              | 2 --
 src/include/utils/jsonpath.h          | 1 -
 src/include/utils/numeric.h           | 2 --
 src/include/utils/pg_lsn.h            | 1 -
 src/include/utils/timestamp.h         | 1 -
 src/include/utils/varbit.h            | 2 --
 src/include/utils/xml.h               | 1 -
 12 files changed, 2 insertions(+), 16 deletions(-)

diff --git a/contrib/earthdistance/earthdistance.c b/contrib/earthdistance/earthdistance.c
index e6ebfd11ad4..d6825a83721 100644
--- a/contrib/earthdistance/earthdistance.c
+++ b/contrib/earthdistance/earthdistance.c
@@ -4,6 +4,8 @@
 
 #include <math.h>
 
+#include "fmgr.h"
+
 #include "utils/geo_decls.h"	/* for Point */
 
 #ifndef M_PI
diff --git a/src/include/utils/cash.h b/src/include/utils/cash.h
index 2e332d83b1c..ae158e2dcd0 100644
--- a/src/include/utils/cash.h
+++ b/src/include/utils/cash.h
@@ -12,8 +12,6 @@
 #ifndef CASH_H
 #define CASH_H
 
-#include "fmgr.h"
-
 typedef int64 Cash;
 
 /* Cash is pass-by-reference if and only if int64 is */
diff --git a/src/include/utils/date.h b/src/include/utils/date.h
index bec129aff1c..df6af8dc660 100644
--- a/src/include/utils/date.h
+++ b/src/include/utils/date.h
@@ -16,7 +16,6 @@
 
 #include <math.h>
 
-#include "fmgr.h"
 #include "pgtime.h"
 #include "datatype/timestamp.h"
 
diff --git a/src/include/utils/expandedrecord.h b/src/include/utils/expandedrecord.h
index 84e6aae23fe..ff97effc2f9 100644
--- a/src/include/utils/expandedrecord.h
+++ b/src/include/utils/expandedrecord.h
@@ -15,7 +15,6 @@
 
 #include "access/htup.h"
 #include "access/tupdesc.h"
-#include "fmgr.h"
 #include "utils/expandeddatum.h"
 
 
diff --git a/src/include/utils/geo_decls.h b/src/include/utils/geo_decls.h
index 4b0353cf0f2..cdb350527ba 100644
--- a/src/include/utils/geo_decls.h
+++ b/src/include/utils/geo_decls.h
@@ -18,8 +18,6 @@
 #ifndef GEO_DECLS_H
 #define GEO_DECLS_H
 
-#include "fmgr.h"
-
 /*--------------------------------------------------------------------
  * Useful floating point utilities and constants.
  *-------------------------------------------------------------------
diff --git a/src/include/utils/inet.h b/src/include/utils/inet.h
index 998593e956f..231fb423448 100644
--- a/src/include/utils/inet.h
+++ b/src/include/utils/inet.h
@@ -14,8 +14,6 @@
 #ifndef INET_H
 #define INET_H
 
-#include "fmgr.h"
-
 /*
  *	This is the internal storage format for IP addresses
  *	(both INET and CIDR datatypes):
diff --git a/src/include/utils/jsonpath.h b/src/include/utils/jsonpath.h
index 40ad5fda928..3e7497182e3 100644
--- a/src/include/utils/jsonpath.h
+++ b/src/include/utils/jsonpath.h
@@ -14,7 +14,6 @@
 #ifndef JSONPATH_H
 #define JSONPATH_H
 
-#include "fmgr.h"
 #include "utils/jsonb.h"
 #include "nodes/pg_list.h"
 
diff --git a/src/include/utils/numeric.h b/src/include/utils/numeric.h
index 7cc597d7b09..7bb56f12916 100644
--- a/src/include/utils/numeric.h
+++ b/src/include/utils/numeric.h
@@ -14,8 +14,6 @@
 #ifndef _PG_NUMERIC_H_
 #define _PG_NUMERIC_H_
 
-#include "fmgr.h"
-
 /*
  * Limit on the precision (and hence scale) specifiable in a NUMERIC typmod.
  * Note that the implementation limit on the length of a numeric value is
diff --git a/src/include/utils/pg_lsn.h b/src/include/utils/pg_lsn.h
index 70d8640ef3e..77eff0c15f1 100644
--- a/src/include/utils/pg_lsn.h
+++ b/src/include/utils/pg_lsn.h
@@ -15,7 +15,6 @@
 #ifndef PG_LSN_H
 #define PG_LSN_H
 
-#include "fmgr.h"
 #include "access/xlogdefs.h"
 
 #define DatumGetLSN(X) ((XLogRecPtr) DatumGetInt64(X))
diff --git a/src/include/utils/timestamp.h b/src/include/utils/timestamp.h
index ea16190ec3d..e6489180675 100644
--- a/src/include/utils/timestamp.h
+++ b/src/include/utils/timestamp.h
@@ -14,7 +14,6 @@
 #define TIMESTAMP_H
 
 #include "datatype/timestamp.h"
-#include "fmgr.h"
 #include "pgtime.h"
 
 
diff --git a/src/include/utils/varbit.h b/src/include/utils/varbit.h
index 641731c4177..0db45b8f95a 100644
--- a/src/include/utils/varbit.h
+++ b/src/include/utils/varbit.h
@@ -17,8 +17,6 @@
 
 #include <limits.h>
 
-#include "fmgr.h"
-
 /*
  * Modeled on struct varlena from postgres.h, but data type is bits8.
  */
diff --git a/src/include/utils/xml.h b/src/include/utils/xml.h
index 90d08b1fcf2..5f96364bc21 100644
--- a/src/include/utils/xml.h
+++ b/src/include/utils/xml.h
@@ -15,7 +15,6 @@
 #ifndef XML_H
 #define XML_H
 
-#include "fmgr.h"
 #include "nodes/execnodes.h"
 #include "nodes/primnodes.h"
 #include "executor/tablefunc.h"
-- 
2.22.0.545.g9c9b961d7e

#16vignesh C
vignesh21@gmail.com
In reply to: Andres Freund (#7)
1 attachment(s)
Re: Unused header file inclusion

On Wed, Jul 31, 2019 at 12:26 PM Andres Freund <andres@anarazel.de> wrote:

Hi,

On 2019-07-31 11:19:08 +0530, vignesh C wrote:

I noticed that there are many header files being
included which need not be included.
I have tried this in a few files and found the
compilation and regression to be working.
I have attached the patch for the files that
I tried.
I tried this in CentOS, I did not find the header
files to be platform specific.
Should we pursue this further and cleanup in
all the files?

These type of changes imo have a good chance of making things more
fragile. A lot of the includes in header files are purely due to needing
one or two definitions (which often could even be avoided by forward
declarations). If you remove all the includes directly from the c files
that are also included from some .h file, you increase the reliance on
the indirect includes - making it harder to clean up.

If anything, we should *increase* the number of includes, so we don't
rely on indirect includes. But that's also not necessarily the right
choice, because it adds unnecessary dependencies.

--- a/src/backend/utils/mmgr/freepage.c
+++ b/src/backend/utils/mmgr/freepage.c
@@ -56,7 +56,6 @@
#include "miscadmin.h"

#include "utils/freepage.h"
-#include "utils/relptr.h"

I don't think it's a good idea to remove this header, for example. A
*lot* of code in freepage.c relies on it. The fact that freepage.h also
includes it here is just due to needing other parts of it

Fixed this.

/* Magic numbers to identify various page types */
diff --git a/src/backend/utils/mmgr/portalmem.c b/src/backend/utils/mmgr/portalmem.c
index 334e35b..67268fd 100644
--- a/src/backend/utils/mmgr/portalmem.c
+++ b/src/backend/utils/mmgr/portalmem.c
@@ -26,7 +26,6 @@
#include "utils/builtins.h"
#include "utils/memutils.h"
#include "utils/snapmgr.h"
-#include "utils/timestamp.h"

Similarly, this file uses timestamp.h functions directly. The fact that
timestamp.h already is included is just due to implementation details of
xact.h that this file shouldn't depend on.

Fixed this.

Made the fixes based on your comments, updated patch has the changes
for the same.

Regards,
Vignesh
EnterpriseDB: http://www.enterprisedb.com

Attachments:

v2-0001-Unused-header-file-removal.patchapplication/octet-stream; name=v2-0001-Unused-header-file-removal.patchDownload
From c885c4925e28a5f994e2a9ec73c2c85bfaf32685 Mon Sep 17 00:00:00 2001
From: Vigneshwaran c <vignesh21@gmail.com>
Date: Sun, 4 Aug 2019 14:53:42 +0530
Subject: [PATCH] 	Unused header file removal

	Removed header files that are not needed
---
 src/backend/utils/mmgr/dsa.c              | 5 -----
 src/backend/utils/resowner/resowner.c     | 1 -
 src/backend/utils/sort/sharedtuplestore.c | 5 -----
 src/backend/utils/sort/sortsupport.c      | 1 -
 src/backend/utils/sort/tuplesort.c        | 5 -----
 src/backend/utils/sort/tuplestore.c       | 3 ---
 src/backend/utils/time/combocid.c         | 1 -
 src/backend/utils/time/snapmgr.c          | 5 -----
 8 files changed, 26 deletions(-)

diff --git a/src/backend/utils/mmgr/dsa.c b/src/backend/utils/mmgr/dsa.c
index 6590e55..0c7b8e2 100644
--- a/src/backend/utils/mmgr/dsa.c
+++ b/src/backend/utils/mmgr/dsa.c
@@ -50,11 +50,6 @@
 
 #include "postgres.h"
 
-#include "port/atomics.h"
-#include "storage/dsm.h"
-#include "storage/ipc.h"
-#include "storage/lwlock.h"
-#include "storage/shmem.h"
 #include "utils/dsa.h"
 #include "utils/freepage.h"
 #include "utils/memutils.h"
diff --git a/src/backend/utils/resowner/resowner.c b/src/backend/utils/resowner/resowner.c
index 7be11c4..84870ec 100644
--- a/src/backend/utils/resowner/resowner.c
+++ b/src/backend/utils/resowner/resowner.c
@@ -29,7 +29,6 @@
 #include "utils/memutils.h"
 #include "utils/rel.h"
 #include "utils/resowner_private.h"
-#include "utils/snapmgr.h"
 
 
 /*
diff --git a/src/backend/utils/sort/sharedtuplestore.c b/src/backend/utils/sort/sharedtuplestore.c
index 8f74e8d..42aaada 100644
--- a/src/backend/utils/sort/sharedtuplestore.c
+++ b/src/backend/utils/sort/sharedtuplestore.c
@@ -21,16 +21,11 @@
 
 #include "postgres.h"
 
-#include "access/htup.h"
 #include "access/htup_details.h"
-#include "miscadmin.h"
 #include "storage/buffile.h"
 #include "storage/lwlock.h"
-#include "storage/sharedfileset.h"
 #include "utils/sharedtuplestore.h"
 
-#include <limits.h>
-
 /*
  * The size of chunks, in pages.  This is somewhat arbitrarily set to match
  * the size of HASH_CHUNK, so that Parallel Hash obtains new chunks of tuples
diff --git a/src/backend/utils/sort/sortsupport.c b/src/backend/utils/sort/sortsupport.c
index 9a77121..8590810 100644
--- a/src/backend/utils/sort/sortsupport.c
+++ b/src/backend/utils/sort/sortsupport.c
@@ -17,7 +17,6 @@
 
 #include "access/nbtree.h"
 #include "catalog/pg_am.h"
-#include "fmgr.h"
 #include "utils/lsyscache.h"
 #include "utils/rel.h"
 #include "utils/sortsupport.h"
diff --git a/src/backend/utils/sort/tuplesort.c b/src/backend/utils/sort/tuplesort.c
index 7b8e678..bdf008c 100644
--- a/src/backend/utils/sort/tuplesort.c
+++ b/src/backend/utils/sort/tuplesort.c
@@ -94,10 +94,7 @@
 
 #include "postgres.h"
 
-#include <limits.h>
-
 #include "access/hash.h"
-#include "access/htup_details.h"
 #include "access/nbtree.h"
 #include "catalog/index.h"
 #include "catalog/pg_am.h"
@@ -111,8 +108,6 @@
 #include "utils/memutils.h"
 #include "utils/pg_rusage.h"
 #include "utils/rel.h"
-#include "utils/sortsupport.h"
-#include "utils/tuplesort.h"
 
 
 /* sort-type codes for sort__start probes */
diff --git a/src/backend/utils/sort/tuplestore.c b/src/backend/utils/sort/tuplestore.c
index 3fc7f92..b461b55 100644
--- a/src/backend/utils/sort/tuplestore.c
+++ b/src/backend/utils/sort/tuplestore.c
@@ -54,9 +54,6 @@
 
 #include "postgres.h"
 
-#include <limits.h>
-
-#include "access/htup_details.h"
 #include "commands/tablespace.h"
 #include "executor/executor.h"
 #include "miscadmin.h"
diff --git a/src/backend/utils/time/combocid.c b/src/backend/utils/time/combocid.c
index deb9af5..0b8931e 100644
--- a/src/backend/utils/time/combocid.c
+++ b/src/backend/utils/time/combocid.c
@@ -46,7 +46,6 @@
 #include "access/xact.h"
 #include "storage/shmem.h"
 #include "utils/combocid.h"
-#include "utils/hsearch.h"
 #include "utils/memutils.h"
 
 
diff --git a/src/backend/utils/time/snapmgr.c b/src/backend/utils/time/snapmgr.c
index 40fe6ed..7f4aff2 100644
--- a/src/backend/utils/time/snapmgr.c
+++ b/src/backend/utils/time/snapmgr.c
@@ -49,17 +49,12 @@
 #include <unistd.h>
 
 #include "access/subtrans.h"
-#include "access/transam.h"
 #include "access/xact.h"
-#include "access/xlog.h"
 #include "catalog/catalog.h"
-#include "lib/pairingheap.h"
 #include "miscadmin.h"
 #include "storage/predicate.h"
 #include "storage/proc.h"
 #include "storage/procarray.h"
-#include "storage/sinval.h"
-#include "storage/sinvaladt.h"
 #include "storage/spin.h"
 #include "utils/builtins.h"
 #include "utils/memutils.h"
-- 
1.8.3.1

#17Alvaro Herrera
alvherre@2ndquadrant.com
In reply to: vignesh C (#16)
Re: Unused header file inclusion

On 2019-Aug-04, vignesh C wrote:

Made the fixes based on your comments, updated patch has the changes
for the same.

Well, you fixed the two things that seem to me quoted as examples of
problems, but you didn't fix other occurrences of the same issues
elsewhere. For example, you remove lwlock.h from dsa.c but there are
structs there that have LWLocks as members. That's just the first hunk
of the patch; didn't look at the others but it wouldn't surprise that
they have similar issues. I suggest this patch should be rejected.

Then there's the <limits.h> removal, which is in tuplesort.c because of
INT_MAX as added by commit d26559dbf356 and still present ...

FWIW sharedtuplestore.c, a very young file, also includes <limits.h> but
that appears to be copy-paste of includes from some other file (and also
in an inappropriate place), so I have no objections to obliterating that
one. But other than that one line, this patch needs more "adult
supervision".

--
�lvaro Herrera https://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services

#18Tom Lane
tgl@sss.pgh.pa.us
In reply to: Alvaro Herrera (#17)
Re: Unused header file inclusion

Alvaro Herrera <alvherre@2ndquadrant.com> writes:

Then there's the <limits.h> removal, which is in tuplesort.c because of
INT_MAX as added by commit d26559dbf356 and still present ...

One has to be especially wary of removing system-header inclusions;
the fact that they don't seem to be needed on your own machine doesn't
prove they aren't needed elsewhere.

... I suggest this patch should be rejected.

Yeah. If we do anything along this line it should be based on
pgrminclude results, and even then I think it'd require manual
review, especially for changes in header files.

The big picture here is that removing #includes is seldom worth
the effort it takes :-(

regards, tom lane

#19Alvaro Herrera
alvherre@2ndquadrant.com
In reply to: Tom Lane (#18)
Re: Unused header file inclusion

On 2019-Aug-05, Tom Lane wrote:

Alvaro Herrera <alvherre@2ndquadrant.com> writes:

Then there's the <limits.h> removal, which is in tuplesort.c because of
INT_MAX as added by commit d26559dbf356 and still present ...

One has to be especially wary of removing system-header inclusions;
the fact that they don't seem to be needed on your own machine doesn't
prove they aren't needed elsewhere.

As far as I can see, this line was just carried over from tuplestore.c,
but that file uses INT_MAX and this one doesn't use any of those macros
as far as I can tell.

I pushed this change and hereby consider this to be over.

--
�lvaro Herrera https://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services

#20Thomas Munro
thomas.munro@gmail.com
In reply to: Alvaro Herrera (#19)
Re: Unused header file inclusion

On Thu, Aug 8, 2019 at 9:00 AM Alvaro Herrera <alvherre@2ndquadrant.com> wrote:

On 2019-Aug-05, Tom Lane wrote:

Alvaro Herrera <alvherre@2ndquadrant.com> writes:

Then there's the <limits.h> removal, which is in tuplesort.c because of
INT_MAX as added by commit d26559dbf356 and still present ...

One has to be especially wary of removing system-header inclusions;
the fact that they don't seem to be needed on your own machine doesn't
prove they aren't needed elsewhere.

As far as I can see, this line was just carried over from tuplestore.c,
but that file uses INT_MAX and this one doesn't use any of those macros
as far as I can tell.

Yeah, probably, or maybe I used one of those sorts of macros in an
earlier version of the patch.

By the way, I see now that I had put the offending #include <limits.h>
*after* project headers, which is a convention I picked up from other
projects, mentors and authors, but not what PostgreSQL usually does.
In my own code I do that to maximise the chances that project headers
will fail to compile if they themselves forget to include the system
headers they depend on. Of course an attempt to compile every header
in the project individually as a transaction unit also achieves that.

/me runs away

--
Thomas Munro
https://enterprisedb.com

#21Thomas Munro
thomas.munro@gmail.com
In reply to: Thomas Munro (#20)
Re: Unused header file inclusion

On Thu, Aug 8, 2019 at 9:47 AM Thomas Munro <thomas.munro@gmail.com> wrote:

transaction unit

*translation unit

--
Thomas Munro
https://enterprisedb.com

#22Andres Freund
andres@anarazel.de
In reply to: Andres Freund (#15)
Re: Unused header file inclusion

Hi,

On 2019-08-03 12:37:33 -0700, Andres Freund wrote:

Think the first three are pretty clearly a good idea, I'm a bit less
sanguine about the fourth:
Headers like utils/timestamp.h are often included just because we need a
TimestampTz type somewhere, or call GetCurrentTimestamp(). Approximately
none of these need the PG_GETARG_* macros, which are the only reason for
including fmgr.h in these headers. As they're macros that's not
actually needed, although I think normally good style. But I' think here
avoiding exposing fmgr.h to more headers is a bigger win.

I still think the fourth is probably worthwhile, but I don't feel
confident enough to do it without somebody else +0.5'ing it...

I've pushed the other ones.

Greetings,

Andres Freund

#23Tom Lane
tgl@sss.pgh.pa.us
In reply to: Andres Freund (#22)
1 attachment(s)
Re: Unused header file inclusion

Andres Freund <andres@anarazel.de> writes:

I've pushed the other ones.

Checking whether header files compile standalone shows you were overly
aggressive about removing fmgr.h includes:

In file included from /tmp/headerscheck.Ss8bVx/test.c:3:
./src/include/utils/selfuncs.h:143: error: expected declaration specifiers or '...' before 'FmgrInfo'
./src/include/utils/selfuncs.h:146: error: expected declaration specifiers or '...' before 'FmgrInfo'
./src/include/utils/selfuncs.h:152: error: expected declaration specifiers or '...' before 'FmgrInfo'

That's with a script I use that's like cpluspluscheck except it tests
with plain gcc not g++. I attached it for the archives' sake.

Oddly, cpluspluscheck does not complain about those cases, but it
does complain about

In file included from /tmp/cpluspluscheck.FgX2SW/test.cpp:4:
./src/bin/scripts/scripts_parallel.h:18: error: ISO C++ forbids declaration of 'PGconn' with no type
./src/bin/scripts/scripts_parallel.h:18: error: expected ';' before '*' token
./src/bin/scripts/scripts_parallel.h:29: error: 'PGconn' has not been declared

(My headerscheck script is missing that header; I need to update it to
match the latest version of cpluspluscheck.)

regards, tom lane

Attachments:

headerschecktext/x-shellscript; charset=us-ascii; name=headerscheckDownload
#24Tom Lane
tgl@sss.pgh.pa.us
In reply to: Tom Lane (#23)
1 attachment(s)
Re: Unused header file inclusion

I wrote:

(My headerscheck script is missing that header; I need to update it to
match the latest version of cpluspluscheck.)

I did that, and ended up with the attached. I'm rather tempted to stick
this into src/tools/ alongside cpluspluscheck, because it seems to find
rather different trouble spots than cpluspluscheck does. Thoughts?

As of HEAD (927f34ce8), I get clean passes from both this and
cpluspluscheck, except for the FmgrInfo references in selfuncs.h.
I tried it on RHEL/Fedora, FreeBSD 12, and current macOS.

regards, tom lane

Attachments:

headerschecktext/x-shellscript; charset=us-ascii; name=headerscheckDownload
#25Alvaro Herrera
alvherre@2ndquadrant.com
In reply to: Tom Lane (#24)
Re: Unused header file inclusion

On 2019-Aug-18, Tom Lane wrote:

I wrote:

(My headerscheck script is missing that header; I need to update it to
match the latest version of cpluspluscheck.)

I did that, and ended up with the attached. I'm rather tempted to stick
this into src/tools/ alongside cpluspluscheck, because it seems to find
rather different trouble spots than cpluspluscheck does. Thoughts?

Yeah, let's include this. I've written its equivalent a couple of times
already. (My strategy is just to compile the .h file directly though,
which creates a .gch file, rather than writing a temp .c file.)

--
�lvaro Herrera https://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services

#26Tom Lane
tgl@sss.pgh.pa.us
In reply to: Alvaro Herrera (#25)
Re: Unused header file inclusion

Alvaro Herrera <alvherre@2ndquadrant.com> writes:

On 2019-Aug-18, Tom Lane wrote:

I did that, and ended up with the attached. I'm rather tempted to stick
this into src/tools/ alongside cpluspluscheck, because it seems to find
rather different trouble spots than cpluspluscheck does. Thoughts?

Yeah, let's include this.

Done.

regards, tom lane

#27Andres Freund
andres@anarazel.de
In reply to: Tom Lane (#23)
Re: Unused header file inclusion

Hi,

On 2019-08-18 14:37:34 -0400, Tom Lane wrote:

Andres Freund <andres@anarazel.de> writes:

I've pushed the other ones.

Checking whether header files compile standalone shows you were overly
aggressive about removing fmgr.h includes:

In file included from /tmp/headerscheck.Ss8bVx/test.c:3:
./src/include/utils/selfuncs.h:143: error: expected declaration specifiers or '...' before 'FmgrInfo'
./src/include/utils/selfuncs.h:146: error: expected declaration specifiers or '...' before 'FmgrInfo'
./src/include/utils/selfuncs.h:152: error: expected declaration specifiers or '...' before 'FmgrInfo'

Darn. Pushed the obvious fix of adding a direct fmgr.h include, rather
than the preivous indirect include.

That's with a script I use that's like cpluspluscheck except it tests
with plain gcc not g++. I attached it for the archives' sake.

Oddly, cpluspluscheck does not complain about those cases, but it
does complain about

Hm. I don't understand why it's not complaining. Wonder if it's a
question of the flags or such.

In file included from /tmp/cpluspluscheck.FgX2SW/test.cpp:4:
./src/bin/scripts/scripts_parallel.h:18: error: ISO C++ forbids declaration of 'PGconn' with no type
./src/bin/scripts/scripts_parallel.h:18: error: expected ';' before '*' token
./src/bin/scripts/scripts_parallel.h:29: error: 'PGconn' has not been declared

I noticed that "manually" earlier, when looking at the openbsd issue.

(My headerscheck script is missing that header; I need to update it to
match the latest version of cpluspluscheck.)

I wonder if we should just add a #ifndef HEADERCHECK or such to the
headers that we don't want to process as standalone headers (or #ifndef
NOT_STANDALONE or whatever). That way multiple tools can rely on these markers,
rather than copying knowledge about that kind of information into
multiple places.

I wish we could move the whole logic of those scripts into makefiles, so
we could employ parallelism.

Greetings,

Andres Freund

#28Andres Freund
andres@anarazel.de
In reply to: Andres Freund (#27)
Re: Unused header file inclusion

Hi,

On 2019-08-19 13:07:50 -0700, Andres Freund wrote:

On 2019-08-18 14:37:34 -0400, Tom Lane wrote:

That's with a script I use that's like cpluspluscheck except it tests
with plain gcc not g++. I attached it for the archives' sake.

Oddly, cpluspluscheck does not complain about those cases, but it
does complain about

Hm. I don't understand why it's not complaining. Wonder if it's a
question of the flags or such.

I'ts caused by -fsyntax-only

# These switches are g++ specific, you may override if necessary.
CXXFLAGS=${CXXFLAGS:- -fsyntax-only -Wall}

which also explains why your headercheck doesn't have that problem, it
doesn't use -fsyntax-only.

(My headerscheck script is missing that header; I need to update it to
match the latest version of cpluspluscheck.)

I wonder if we should just add a #ifndef HEADERCHECK or such to the
headers that we don't want to process as standalone headers (or #ifndef
NOT_STANDALONE or whatever). That way multiple tools can rely on these markers,
rather than copying knowledge about that kind of information into
multiple places.

I wish we could move the whole logic of those scripts into makefiles, so
we could employ parallelism.

Hm. Perhaps the way to do that would be to use gcc's -include to include
postgres.h, and use -Wc++-compat to detect c++ issues, rather than using
g++. Without tempfiles it ought to be a lot easier to just do all of the
relevant work in make, without a separate shell script. The
python/perl/ecpg logic would b e abit annoying, but probably not too
bad? Think we could just always add all of them?

Greetings,

Andres Freund

#29Alvaro Herrera
alvherre@2ndquadrant.com
In reply to: Andres Freund (#28)
Re: Unused header file inclusion

On 2019-Aug-19, Andres Freund wrote:

I wish we could move the whole logic of those scripts into makefiles, so
we could employ parallelism.

Hm. Perhaps the way to do that would be to use gcc's -include to include
postgres.h, and use -Wc++-compat to detect c++ issues, rather than using
g++. Without tempfiles it ought to be a lot easier to just do all of the
relevant work in make, without a separate shell script.

I used to have this:
/messages/by-id/1293469595-sup-1462@alvh.no-ip.org
Not sure how much this helps, since it's a shell line in make, so not
very paralellizable. And you still have to build the exclusions
somehow.

--
�lvaro Herrera https://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services

#30Tom Lane
tgl@sss.pgh.pa.us
In reply to: Andres Freund (#28)
Re: Unused header file inclusion

Andres Freund <andres@anarazel.de> writes:

On 2019-08-19 13:07:50 -0700, Andres Freund wrote:

On 2019-08-18 14:37:34 -0400, Tom Lane wrote:

Oddly, cpluspluscheck does not complain about those cases, but it
does complain about

Hm. I don't understand why it's not complaining. Wonder if it's a
question of the flags or such.

I'ts caused by -fsyntax-only

Ah-hah. Should we change that to something else? That's probably
a hangover from thinking that all we had to do was check for C++
keywords.

I wish we could move the whole logic of those scripts into makefiles, so
we could employ parallelism.

I can't really get excited about expending a whole bunch of additional
work on these scripts.

regards, tom lane