>> Move the definition of RelationData into utils/rel_internal.h. Otherwise,
>> gen_node_support.pl cannot process rel.h after the anonymous unions are
>> introduced by the following commit, because the script does not support
>> parsing anonymous unions.
>
> I really dislike this. Why not do it the other way around, and put the
> one struct that gen_node_support.pl wants in a separate file instead?
> As in the attached WIP. New file name TBD, of course.
That's indeed nicer.
I had moved struct RelationData to rel_internal.h as a quick workaround
when I started to be able to make progress without bothering. Now it's
time to fix this properly.
We can do what you suggest, or alternatively, teach gen_node_support.pl
to skip anonymous structs/unions in non-node structs. Then we can keep
all code as before in rel.h. See attached patch.
Once we settle on how to go forward, I'll update the main patch set.
--
David Geier
From 1f4b8568604b80f401044b8faa7a0bee567e2037 Mon Sep 17 00:00:00 2001
From: David Geier <[email protected]>
Date: Sun, 18 Oct 2026 13:33:35 +0200
Subject: [PATCH v1] gen_node_support.pl skips anonymous structs/unions
---
src/backend/nodes/gen_node_support.pl | 33 +++++++++++++++++++++++++++
src/include/utils/rel.h | 13 +++++++++++
2 files changed, 46 insertions(+)
diff --git a/src/backend/nodes/gen_node_support.pl
b/src/backend/nodes/gen_node_support.pl
index 0b766272018..a2d198f72b3 100644
--- a/src/backend/nodes/gen_node_support.pl
+++ b/src/backend/nodes/gen_node_support.pl
@@ -193,6 +193,9 @@ foreach my $infile (@ARGV)
my %my_field_types;
my %my_field_attrs;
+ # nesting depth of an anonymous union/struct; the outermost level is 1
+ my $anon_nest = 0;
+
# open file with name from command line, which may have a path prefix
open my $ifh, '<', $infile or die "could not open \"$infile\": $!";
@@ -229,6 +232,34 @@ foreach my $infile (@ARGV)
next if $line eq '';
next if $line =~ /^#(define|ifdef|endif)/;
+ # Skip anonymous union/struct blocks. These are only allowed in
+ # non-node structs, whose fields we do not process. Anonymous
unions
+ # are not supported in node structs because their copy, equal,
and
+ # serialization functions cannot be generated automatically.
+ if ($in_struct)
+ {
+ if ($anon_nest > 0)
+ {
+ $anon_nest += ($line =~ tr/{//) - ($line =~
tr/}//);
+ next;
+ }
+ elsif ($anon_nest == -1)
+ {
+ die "$infile:$lineno: expected '{' after
anonymous union/struct\n"
+ unless $line =~ /^\s*\{\s*$/;
+ $anon_nest = 1;
+ next;
+ }
+ elsif ($line =~ /^\s*(?:union|struct)(?:\s*\{)?\s*$/)
+ {
+ die
+ "$infile:$lineno: anonymous union/struct not
supported in node struct \"$in_struct\"\n"
+ if $is_node_struct;
+ $anon_nest = ($line =~ /\{/) ? 1 : -1;
+ next;
+ }
+ }
+
# within a struct, don't process until we have whole logical
line
if ($in_struct && $subline > 0)
{
@@ -421,6 +452,7 @@ foreach my $infile (@ARGV)
@my_fields = ();
%my_field_types = ();
%my_field_attrs = ();
+ $anon_nest = 0;
}
# normal struct field
elsif ($line =~
@@ -532,6 +564,7 @@ foreach my $infile (@ARGV)
$in_struct = $1;
$in_struct_lineno = $lineno;
$subline = 0;
+ $anon_nest = 0;
}
# one node type typedef'ed directly from another
elsif ($line =~ /^typedef (\w+) (\w+);$/ and elem $1,
@node_types)
diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h
index 7b8c2b1e362..54d1b653133 100644
--- a/src/include/utils/rel.h
+++ b/src/include/utils/rel.h
@@ -54,6 +54,19 @@ typedef LockInfoData *LockInfo;
typedef struct RelationData
{
+ union
+ {
+ struct
+ {
+ int Foo;
+ };
+
+ struct
+ {
+ long Bar;
+ };
+ };
+
RelFileLocator rd_locator; /* relation physical identifier */
SMgrRelation rd_smgr; /* cached file handle, or NULL */
int rd_refcnt; /* reference count */
--
2.55.0