mirror of
https://github.com/postgres/postgres.git
synced 2025-11-06 07:49:08 +03:00
Dump more fields when dumping planner internal data structures.
Commit 964d01ae9 marked a lot of fields as read_write_ignore
to stay consistent with what was dumped by the manually-maintained
outfuncs.c code. However, it seems that a pretty fair number
of those omissions were either flat-out oversights, or a shortcut
taken because hand-written code seemed like it'd be too much trouble.
Let's upgrade things where it seems to make sense to dump.
To do this, we need to add support to gen_node_support.pl and
outfuncs.c for variable-length arrays of Node pointers. That's
pretty straightforward given the model of the existing code
for arrays of scalars, but I found I needed to tighten the
type-recognizing regexes in gen_node_support.pl. (As they
stood, they mistook "foo **" for "foo *". Make sure they're
all fully anchored to prevent additional problems.)
The main thing left un-done here is that a lot of partitioning-related
structs are still not dumped, because they are bare structs not Nodes.
I'm not sure about the wisdom of that choice ... but changing it would
be fairly invasive, so it probably requires more justification than
just making planner node dumps more complete.
Discussion: https://postgr.es/m/1295668.1658258637@sss.pgh.pa.us
This commit is contained in:
@@ -28,8 +28,7 @@ use Catalog; # for RenameTempFile
|
||||
|
||||
my $output_path = '.';
|
||||
|
||||
GetOptions(
|
||||
'outdir:s' => \$output_path)
|
||||
GetOptions('outdir:s' => \$output_path)
|
||||
or die "$0: wrong arguments";
|
||||
|
||||
|
||||
@@ -441,6 +440,8 @@ foreach my $infile (@ARGV)
|
||||
$type =~ s/\s*$//;
|
||||
# strip space between type and "*" (pointer) */
|
||||
$type =~ s/\s+\*$/*/;
|
||||
# strip space between type and "**" (array of pointers) */
|
||||
$type =~ s/\s+\*\*$/**/;
|
||||
|
||||
die
|
||||
"$infile:$lineno: cannot parse data type in \"$line\"\n"
|
||||
@@ -583,7 +584,8 @@ my $header_comment =
|
||||
# nodetags.h
|
||||
|
||||
push @output_files, 'nodetags.h';
|
||||
open my $nt, '>', "$output_path/nodetags.h$tmpext" or die "$output_path/nodetags.h$tmpext: $!";
|
||||
open my $nt, '>', "$output_path/nodetags.h$tmpext"
|
||||
or die "$output_path/nodetags.h$tmpext: $!";
|
||||
|
||||
printf $nt $header_comment, 'nodetags.h';
|
||||
|
||||
@@ -745,8 +747,8 @@ _equal${n}(const $n *a, const $n *b)
|
||||
unless $equal_ignore || $t eq 'CoercionForm';
|
||||
}
|
||||
}
|
||||
# scalar type pointer
|
||||
elsif ($t =~ /(\w+)\*/ and elem $1, @scalar_types)
|
||||
# arrays of scalar types
|
||||
elsif ($t =~ /^(\w+)\*$/ and elem $1, @scalar_types)
|
||||
{
|
||||
my $tt = $1;
|
||||
if (!defined $array_size_field)
|
||||
@@ -780,13 +782,14 @@ _equal${n}(const $n *a, const $n *b)
|
||||
print $eff "\tCOMPARE_SCALAR_FIELD($f);\n" unless $equal_ignore;
|
||||
}
|
||||
# node type
|
||||
elsif ($t =~ /(\w+)\*/ and elem $1, @node_types)
|
||||
elsif (($t =~ /^(\w+)\*$/ or $t =~ /^struct\s+(\w+)\*$/)
|
||||
and elem $1, @node_types)
|
||||
{
|
||||
print $cff "\tCOPY_NODE_FIELD($f);\n" unless $copy_ignore;
|
||||
print $eff "\tCOMPARE_NODE_FIELD($f);\n" unless $equal_ignore;
|
||||
}
|
||||
# array (inline)
|
||||
elsif ($t =~ /\w+\[/)
|
||||
elsif ($t =~ /^\w+\[\w+\]$/)
|
||||
{
|
||||
print $cff "\tCOPY_ARRAY_FIELD($f);\n" unless $copy_ignore;
|
||||
print $eff "\tCOMPARE_ARRAY_FIELD($f);\n" unless $equal_ignore;
|
||||
@@ -894,11 +897,16 @@ _read${n}(void)
|
||||
my @a = @{ $node_type_info{$n}->{field_attrs}{$f} };
|
||||
|
||||
# extract per-field attributes
|
||||
my $read_write_ignore = 0;
|
||||
my $array_size_field;
|
||||
my $read_as_field;
|
||||
my $read_write_ignore = 0;
|
||||
foreach my $a (@a)
|
||||
{
|
||||
if ($a =~ /^read_as\(([\w.]+)\)$/)
|
||||
if ($a =~ /^array_size\(([\w.]+)\)$/)
|
||||
{
|
||||
$array_size_field = $1;
|
||||
}
|
||||
elsif ($a =~ /^read_as\(([\w.]+)\)$/)
|
||||
{
|
||||
$read_as_field = $1;
|
||||
}
|
||||
@@ -1015,19 +1023,10 @@ _read${n}(void)
|
||||
print $off "\tWRITE_ENUM_FIELD($f, $t);\n";
|
||||
print $rff "\tREAD_ENUM_FIELD($f, $t);\n" unless $no_read;
|
||||
}
|
||||
# arrays
|
||||
elsif ($t =~ /(\w+)(\*|\[)/ and elem $1, @scalar_types)
|
||||
# arrays of scalar types
|
||||
elsif ($t =~ /^(\w+)(\*|\[\w+\])$/ and elem $1, @scalar_types)
|
||||
{
|
||||
my $tt = uc $1;
|
||||
my $array_size_field;
|
||||
foreach my $a (@a)
|
||||
{
|
||||
if ($a =~ /^array_size\(([\w.]+)\)$/)
|
||||
{
|
||||
$array_size_field = $1;
|
||||
last;
|
||||
}
|
||||
}
|
||||
if (!defined $array_size_field)
|
||||
{
|
||||
die "no array size defined for $n.$f of type $t\n";
|
||||
@@ -1080,11 +1079,38 @@ _read${n}(void)
|
||||
. "\t\toutBitmapset(str, NULL);\n";
|
||||
}
|
||||
# node type
|
||||
elsif ($t =~ /(\w+)\*/ and elem $1, @node_types)
|
||||
elsif (($t =~ /^(\w+)\*$/ or $t =~ /^struct\s+(\w+)\*$/)
|
||||
and elem $1, @node_types)
|
||||
{
|
||||
print $off "\tWRITE_NODE_FIELD($f);\n";
|
||||
print $rff "\tREAD_NODE_FIELD($f);\n" unless $no_read;
|
||||
}
|
||||
# arrays of node pointers (currently supported for write only)
|
||||
elsif (($t =~ /^(\w+)\*\*$/ or $t =~ /^struct\s+(\w+)\*\*$/)
|
||||
and elem($1, @node_types))
|
||||
{
|
||||
if (!defined $array_size_field)
|
||||
{
|
||||
die "no array size defined for $n.$f of type $t\n";
|
||||
}
|
||||
if ($node_type_info{$n}->{field_types}{$array_size_field} eq
|
||||
'List*')
|
||||
{
|
||||
print $off
|
||||
"\tWRITE_NODE_ARRAY($f, list_length(node->$array_size_field));\n";
|
||||
print $rff
|
||||
"\tREAD_NODE_ARRAY($f, list_length(local_node->$array_size_field));\n"
|
||||
unless $no_read;
|
||||
}
|
||||
else
|
||||
{
|
||||
print $off
|
||||
"\tWRITE_NODE_ARRAY($f, node->$array_size_field);\n";
|
||||
print $rff
|
||||
"\tREAD_NODE_ARRAY($f, local_node->$array_size_field);\n"
|
||||
unless $no_read;
|
||||
}
|
||||
}
|
||||
elsif ($t eq 'struct CustomPathMethods*'
|
||||
|| $t eq 'struct CustomScanMethods*')
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user