Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitdf0b4af

Browse files
tglsfdcpull[bot]
authored andcommitted
Dump more fields when dumping planner internal data structures.
Commit964d01a marked a lot of fields as read_write_ignoreto stay consistent with what was dumped by the manually-maintainedoutfuncs.c code. However, it seems that a pretty fair numberof those omissions were either flat-out oversights, or a shortcuttaken 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 andoutfuncs.c for variable-length arrays of Node pointers. That'spretty straightforward given the model of the existing codefor arrays of scalars, but I found I needed to tighten thetype-recognizing regexes in gen_node_support.pl. (As theystood, they mistook "foo **" for "foo *". Make sure they'reall fully anchored to prevent additional problems.)The main thing left un-done here is that a lot of partitioning-relatedstructs are still not dumped, because they are bare structs not Nodes.I'm not sure about the wisdom of that choice ... but changing it wouldbe fairly invasive, so it probably requires more justification thanjust making planner node dumps more complete.Discussion:https://postgr.es/m/1295668.1658258637@sss.pgh.pa.us
1 parent5fe1085 commitdf0b4af

File tree

3 files changed

+123
-61
lines changed

3 files changed

+123
-61
lines changed

‎src/backend/nodes/gen_node_support.pl

Lines changed: 47 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,7 @@
2828

2929
my$output_path ='.';
3030

31-
GetOptions(
32-
'outdir:s'=> \$output_path)
31+
GetOptions('outdir:s'=> \$output_path)
3332
ordie"$0: wrong arguments";
3433

3534

@@ -441,6 +440,8 @@ sub elem
441440
$type =~s/\s*$//;
442441
# strip space between type and "*" (pointer) */
443442
$type =~s/\s+\*$/*/;
443+
# strip space between type and "**" (array of pointers) */
444+
$type =~s/\s+\*\*$/**/;
444445

445446
die
446447
"$infile:$lineno: cannot parse data type in\"$line\"\n"
@@ -583,7 +584,8 @@ sub elem
583584
# nodetags.h
584585

585586
push@output_files,'nodetags.h';
586-
openmy$nt,'>',"$output_path/nodetags.h$tmpext"ordie"$output_path/nodetags.h$tmpext:$!";
587+
openmy$nt,'>',"$output_path/nodetags.h$tmpext"
588+
ordie"$output_path/nodetags.h$tmpext:$!";
587589

588590
printf$nt$header_comment,'nodetags.h';
589591

@@ -745,8 +747,8 @@ sub elem
745747
unless$equal_ignore ||$teq'CoercionForm';
746748
}
747749
}
748-
#scalar type pointer
749-
elsif ($t =~/(\w+)\*/and elem$1,@scalar_types)
750+
#arrays of scalar types
751+
elsif ($t =~/^(\w+)\*$/and elem$1,@scalar_types)
750752
{
751753
my$tt =$1;
752754
if (!defined$array_size_field)
@@ -780,13 +782,14 @@ sub elem
780782
print$eff"\tCOMPARE_SCALAR_FIELD($f);\n"unless$equal_ignore;
781783
}
782784
# node type
783-
elsif ($t =~/(\w+)\*/and elem$1,@node_types)
785+
elsif (($t =~/^(\w+)\*$/or$t =~/^struct\s+(\w+)\*$/)
786+
and elem$1,@node_types)
784787
{
785788
print$cff"\tCOPY_NODE_FIELD($f);\n"unless$copy_ignore;
786789
print$eff"\tCOMPARE_NODE_FIELD($f);\n"unless$equal_ignore;
787790
}
788791
# array (inline)
789-
elsif ($t =~/\w+\[/)
792+
elsif ($t =~/^\w+\[\w+\]$/)
790793
{
791794
print$cff"\tCOPY_ARRAY_FIELD($f);\n"unless$copy_ignore;
792795
print$eff"\tCOMPARE_ARRAY_FIELD($f);\n"unless$equal_ignore;
@@ -894,11 +897,16 @@ sub elem
894897
my@a = @{$node_type_info{$n}->{field_attrs}{$f} };
895898

896899
# extract per-field attributes
897-
my$read_write_ignore = 0;
900+
my$array_size_field;
898901
my$read_as_field;
902+
my$read_write_ignore = 0;
899903
foreachmy$a (@a)
900904
{
901-
if ($a =~/^read_as\(([\w.]+)\)$/)
905+
if ($a =~/^array_size\(([\w.]+)\)$/)
906+
{
907+
$array_size_field =$1;
908+
}
909+
elsif ($a =~/^read_as\(([\w.]+)\)$/)
902910
{
903911
$read_as_field =$1;
904912
}
@@ -1015,19 +1023,10 @@ sub elem
10151023
print$off"\tWRITE_ENUM_FIELD($f,$t);\n";
10161024
print$rff"\tREAD_ENUM_FIELD($f,$t);\n"unless$no_read;
10171025
}
1018-
# arrays
1019-
elsif ($t =~/(\w+)(\*|\[)/and elem$1,@scalar_types)
1026+
# arrays of scalar types
1027+
elsif ($t =~/^(\w+)(\*|\[\w+\])$/and elem$1,@scalar_types)
10201028
{
10211029
my$tt =uc$1;
1022-
my$array_size_field;
1023-
foreachmy$a (@a)
1024-
{
1025-
if ($a =~/^array_size\(([\w.]+)\)$/)
1026-
{
1027-
$array_size_field =$1;
1028-
last;
1029-
}
1030-
}
10311030
if (!defined$array_size_field)
10321031
{
10331032
die"no array size defined for$n.$f of type$t\n";
@@ -1080,11 +1079,38 @@ sub elem
10801079
."\t\toutBitmapset(str, NULL);\n";
10811080
}
10821081
# node type
1083-
elsif ($t =~/(\w+)\*/and elem$1,@node_types)
1082+
elsif (($t =~/^(\w+)\*$/or$t =~/^struct\s+(\w+)\*$/)
1083+
and elem$1,@node_types)
10841084
{
10851085
print$off"\tWRITE_NODE_FIELD($f);\n";
10861086
print$rff"\tREAD_NODE_FIELD($f);\n"unless$no_read;
10871087
}
1088+
# arrays of node pointers (currently supported for write only)
1089+
elsif (($t =~/^(\w+)\*\*$/or$t =~/^struct\s+(\w+)\*\*$/)
1090+
and elem($1,@node_types))
1091+
{
1092+
if (!defined$array_size_field)
1093+
{
1094+
die"no array size defined for$n.$f of type$t\n";
1095+
}
1096+
if ($node_type_info{$n}->{field_types}{$array_size_field}eq
1097+
'List*')
1098+
{
1099+
print$off
1100+
"\tWRITE_NODE_ARRAY($f, list_length(node->$array_size_field));\n";
1101+
print$rff
1102+
"\tREAD_NODE_ARRAY($f, list_length(local_node->$array_size_field));\n"
1103+
unless$no_read;
1104+
}
1105+
else
1106+
{
1107+
print$off
1108+
"\tWRITE_NODE_ARRAY($f, node->$array_size_field);\n";
1109+
print$rff
1110+
"\tREAD_NODE_ARRAY($f, local_node->$array_size_field);\n"
1111+
unless$no_read;
1112+
}
1113+
}
10881114
elsif ($teq'struct CustomPathMethods*'
10891115
||$teq'struct CustomScanMethods*')
10901116
{

‎src/backend/nodes/outfuncs.c

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,11 @@ static void outChar(StringInfo str, char c);
9797
(appendStringInfoString(str, " :" CppAsString(fldname) " "), \
9898
outBitmapset(str, node->fldname))
9999

100+
/* Write a variable-length array (not a List) of Node pointers */
101+
#defineWRITE_NODE_ARRAY(fldname,len) \
102+
(appendStringInfoString(str, " :" CppAsString(fldname) " "), \
103+
writeNodeArray(str, (const Node * const *) node->fldname, len))
104+
100105
/* Write a variable-length array of AttrNumber */
101106
#defineWRITE_ATTRNUMBER_ARRAY(fldname,len) \
102107
(appendStringInfoString(str, " :" CppAsString(fldname) " "), \
@@ -208,6 +213,29 @@ WRITE_SCALAR_ARRAY(writeIndexCols, Index, " %u",)
208213
WRITE_SCALAR_ARRAY(writeIntCols,int," %d",)
209214
WRITE_SCALAR_ARRAY(writeBoolCols,bool," %s",booltostr)
210215

216+
/*
217+
* Print an array (not a List) of Node pointers.
218+
*
219+
* The decoration is identical to that of scalar arrays, but we can't
220+
* quite use appendStringInfo() in the loop.
221+
*/
222+
staticvoid
223+
writeNodeArray(StringInfostr,constNode*const*arr,intlen)
224+
{
225+
if (arr!=NULL)
226+
{
227+
appendStringInfoChar(str,'(');
228+
for (inti=0;i<len;i++)
229+
{
230+
appendStringInfoChar(str,' ');
231+
outNode(str,arr[i]);
232+
}
233+
appendStringInfoChar(str,')');
234+
}
235+
else
236+
appendStringInfoString(str,"<>");
237+
}
238+
211239
/*
212240
* Print a List.
213241
*/

‎src/include/nodes/pathnodes.h

Lines changed: 48 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ typedef enum UpperRelationKind
8989
* planned.
9090
*
9191
* Not all fields are printed. (In some cases, there is no print support for
92-
* the field type.)
92+
* the field type; in others, doing so would lead to infinite recursion.)
9393
*----------
9494
*/
9595
typedefstructPlannerGlobal
@@ -177,7 +177,8 @@ typedef struct PlannerGlobal
177177
* either here or in that header, whichever is read first.
178178
*
179179
* Not all fields are printed. (In some cases, there is no print support for
180-
* the field type.)
180+
* the field type; in others, doing so would lead to infinite recursion or
181+
* bloat dump output more than seems useful.)
181182
*----------
182183
*/
183184
#ifndefHAVE_PLANNERINFO_TYPEDEF
@@ -220,22 +221,24 @@ struct PlannerInfo
220221
* does not correspond to a base relation, such as a join RTE or an
221222
* unreferenced view RTE; or if the RelOptInfo hasn't been made yet.
222223
*/
223-
structRelOptInfo**simple_rel_arraypg_node_attr(read_write_ignore);
224+
structRelOptInfo**simple_rel_arraypg_node_attr(array_size(simple_rel_array_size));
224225
/* allocated size of array */
225-
intsimple_rel_array_sizepg_node_attr(read_write_ignore);
226+
intsimple_rel_array_size;
226227

227228
/*
228229
* simple_rte_array is the same length as simple_rel_array and holds
229230
* pointers to the associated rangetable entries. Using this is a shade
230-
* faster than using rt_fetch(), mostly due to fewer indirections.
231+
* faster than using rt_fetch(), mostly due to fewer indirections. (Not
232+
* printed because it'd be redundant with parse->rtable.)
231233
*/
232234
RangeTblEntry**simple_rte_arraypg_node_attr(read_write_ignore);
233235

234236
/*
235237
* append_rel_array is the same length as the above arrays, and holds
236238
* pointers to the corresponding AppendRelInfo entry indexed by
237239
* child_relid, or NULL if the rel is not an appendrel child. The array
238-
* itself is not allocated if append_rel_list is empty.
240+
* itself is not allocated if append_rel_list is empty. (Not printed
241+
* because it'd be redundant with append_rel_list.)
239242
*/
240243
structAppendRelInfo**append_rel_arraypg_node_attr(read_write_ignore);
241244

@@ -273,6 +276,9 @@ struct PlannerInfo
273276
* join_cur_level is the current level. New join-relation RelOptInfos are
274277
* automatically added to the join_rel_level[join_cur_level] list.
275278
* join_rel_level is NULL if not in use.
279+
*
280+
* Note: we've already printed all baserel and joinrel RelOptInfos above,
281+
* so we don't dump join_rel_level or other lists of RelOptInfos.
276282
*/
277283
/* lists of join-relation RelOptInfos */
278284
List**join_rel_levelpg_node_attr(read_write_ignore);
@@ -403,8 +409,8 @@ struct PlannerInfo
403409
/*
404410
* Fields filled during create_plan() for use in setrefs.c
405411
*/
406-
/* for GroupingFunc fixup */
407-
AttrNumber*grouping_mappg_node_attr(array_size(update_colnos),read_write_ignore);
412+
/* for GroupingFunc fixup(can't print: array length not known here)*/
413+
AttrNumber*grouping_mappg_node_attr(read_write_ignore);
408414
/* List of MinMaxAggInfos */
409415
List*minmax_aggs;
410416

@@ -458,7 +464,7 @@ struct PlannerInfo
458464
/* PARAM_EXEC ID for the work table */
459465
intwt_param_id;
460466
/* a path for non-recursive term */
461-
structPath*non_recursive_pathpg_node_attr(read_write_ignore);
467+
structPath*non_recursive_path;
462468

463469
/*
464470
* These fields are workspace for createplan.c
@@ -470,7 +476,9 @@ struct PlannerInfo
470476

471477
/*
472478
* These fields are workspace for setrefs.c. Each is an array
473-
* corresponding to glob->subplans.
479+
* corresponding to glob->subplans. (We could probably teach
480+
* gen_node_support.pl how to determine the array length, but it doesn't
481+
* seem worth the trouble, so just mark them read_write_ignore.)
474482
*/
475483
bool*isAltSubplanpg_node_attr(read_write_ignore);
476484
bool*isUsedSubplanpg_node_attr(read_write_ignore);
@@ -928,16 +936,17 @@ typedef struct RelOptInfo
928936
* Number of partitions; -1 if not yet set; in case of a join relation 0
929937
* means it's considered unpartitioned
930938
*/
931-
intnpartspg_node_attr(read_write_ignore);
939+
intnparts;
932940
/* Partition bounds */
933941
structPartitionBoundInfoData*boundinfopg_node_attr(read_write_ignore);
934942
/* True if partition bounds were created by partition_bounds_merge() */
935943
boolpartbounds_merged;
936944
/* Partition constraint, if not the root */
937-
List*partition_qualpg_node_attr(read_write_ignore);
945+
List*partition_qual;
938946

939947
/*
940948
* Array of RelOptInfos of partitions, stored in the same order as bounds
949+
* (don't print, too bulky and duplicative)
941950
*/
942951
structRelOptInfo**part_relspg_node_attr(read_write_ignore);
943952

@@ -948,6 +957,12 @@ typedef struct RelOptInfo
948957
Bitmapset*live_parts;
949958
/* Relids set of all partition relids */
950959
Relidsall_partrels;
960+
961+
/*
962+
* These arrays are of length partkey->partnatts, which we don't have at
963+
* hand, so don't try to print
964+
*/
965+
951966
/* Non-nullable partition key expressions */
952967
List**partexprspg_node_attr(read_write_ignore);
953968
/* Nullable partition key expressions */
@@ -1042,30 +1057,26 @@ struct IndexOptInfo
10421057
intnkeycolumns;
10431058

10441059
/*
1045-
* array fields aren't really worth the trouble to print
1046-
*/
1047-
1048-
/*
1049-
* column numbers of index's attributes both key and included columns, or
1050-
* 0
1060+
* table column numbers of index's columns (both key and included
1061+
* columns), or 0 for expression columns
10511062
*/
1052-
int*indexkeyspg_node_attr(read_write_ignore);
1063+
int*indexkeyspg_node_attr(array_size(ncolumns));
10531064
/* OIDs of collations of index columns */
1054-
Oid*indexcollationspg_node_attr(read_write_ignore);
1065+
Oid*indexcollationspg_node_attr(array_size(nkeycolumns));
10551066
/* OIDs of operator families for columns */
1056-
Oid*opfamilypg_node_attr(read_write_ignore);
1067+
Oid*opfamilypg_node_attr(array_size(nkeycolumns));
10571068
/* OIDs of opclass declared input data types */
1058-
Oid*opcintypepg_node_attr(read_write_ignore);
1069+
Oid*opcintypepg_node_attr(array_size(nkeycolumns));
10591070
/* OIDs of btree opfamilies, if orderable */
1060-
Oid*sortopfamilypg_node_attr(read_write_ignore);
1071+
Oid*sortopfamilypg_node_attr(array_size(nkeycolumns));
10611072
/* is sort order descending? */
1062-
bool*reverse_sortpg_node_attr(read_write_ignore);
1073+
bool*reverse_sortpg_node_attr(array_size(nkeycolumns));
10631074
/* do NULLs come first in the sort order? */
1064-
bool*nulls_firstpg_node_attr(read_write_ignore);
1075+
bool*nulls_firstpg_node_attr(array_size(nkeycolumns));
10651076
/* opclass-specific options for columns */
10661077
bytea**opclassoptionspg_node_attr(read_write_ignore);
10671078
/* which index cols can be returned in an index-only scan? */
1068-
bool*canreturnpg_node_attr(read_write_ignore);
1079+
bool*canreturnpg_node_attr(array_size(ncolumns));
10691080
/* OID of the access method (in pg_am) */
10701081
Oidrelam;
10711082

@@ -1098,19 +1109,19 @@ struct IndexOptInfo
10981109

10991110
/*
11001111
* Remaining fields are copied from the index AM's API struct
1101-
* (IndexAmRoutine). We don't bother to dump them.
1112+
* (IndexAmRoutine).
11021113
*/
1103-
boolamcanorderbyoppg_node_attr(read_write_ignore);
1104-
boolamoptionalkeypg_node_attr(read_write_ignore);
1105-
boolamsearcharraypg_node_attr(read_write_ignore);
1106-
boolamsearchnullspg_node_attr(read_write_ignore);
1114+
boolamcanorderbyop;
1115+
boolamoptionalkey;
1116+
boolamsearcharray;
1117+
boolamsearchnulls;
11071118
/* does AM have amgettuple interface? */
1108-
boolamhasgettuplepg_node_attr(read_write_ignore);
1119+
boolamhasgettuple;
11091120
/* does AM have amgetbitmap interface? */
1110-
boolamhasgetbitmappg_node_attr(read_write_ignore);
1111-
boolamcanparallelpg_node_attr(read_write_ignore);
1121+
boolamhasgetbitmap;
1122+
boolamcanparallel;
11121123
/* does AM have ammarkpos interface? */
1113-
boolamcanmarkpospg_node_attr(read_write_ignore);
1124+
boolamcanmarkpos;
11141125
/* AM's cost estimator */
11151126
/* Rather than include amapi.h here, we declare amcostestimate like this */
11161127
void(*amcostestimate) ()pg_node_attr(read_write_ignore);
@@ -1184,12 +1195,9 @@ typedef struct StatisticExtInfo
11841195
OidstatOid;
11851196

11861197
/* includes child relations */
1187-
boolinheritpg_node_attr(read_write_ignore);
1198+
boolinherit;
11881199

1189-
/*
1190-
* back-link to statistic's table; don't print, infinite recursion on plan
1191-
* tree dump
1192-
*/
1200+
/* back-link to statistic's table; don't print, else infinite recursion */
11931201
RelOptInfo*relpg_node_attr(read_write_ignore);
11941202

11951203
/* statistics kind of this entry */

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp