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

Commit7c0eb3c

Browse files
committed
Tighten up parsing logic in gen_node_support.pl.
Teach this script to handle function pointer fields honestly.Previously they were just silently ignored, but that's not likely tobe a behavior we can accept indefinitely. This mostly entails fixingit so that a field declaration spanning multiple lines can be parsed,because we have a bunch of such fields that're laid out that way.But that's a good improvement in its own right.With that change and a minor regex adjustment, the only struct itfails to parse in the node-defining headers is A_Const, becauseof the embedded union. The path of least resistance is to movethat union declaration outside the struct.Having done those things, we can make it error out if it findsany within-struct syntax it doesn't understand, which seems likea pretty important property for robustness.This commit doesn't change the output files at all; it's just inthe way of future-proofing.Discussion:https://postgr.es/m/2593369.1657759779@sss.pgh.pa.us
1 parent5794491 commit7c0eb3c

File tree

3 files changed

+90
-20
lines changed

3 files changed

+90
-20
lines changed

‎src/backend/nodes/gen_node_support.pl

Lines changed: 73 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -213,15 +213,39 @@ sub elem
213213
}
214214
$file_content .=$raw_file_content;
215215

216-
my$lineno = 0;
216+
my$lineno = 0;
217+
my$prevline ='';
217218
foreachmy$line (split /\n/,$file_content)
218219
{
220+
# per-physical-line processing
219221
$lineno++;
220222
chomp$line;
221223
$line =~s/\s*$//;
222224
nextif$lineeq'';
223225
nextif$line =~/^#(define|ifdef|endif)/;
224226

227+
# within a struct, don't process until we have whole logical line
228+
if ($in_struct &&$subline > 0)
229+
{
230+
if ($line =~/;$/)
231+
{
232+
# found the end, re-attach any previous line(s)
233+
$line =$prevline .$line;
234+
$prevline ='';
235+
}
236+
elsif ($prevlineeq''
237+
&&$line =~/^\s*pg_node_attr\(([\w(), ]*)\)$/)
238+
{
239+
# special case: node-attributes line doesn't end with semi
240+
}
241+
else
242+
{
243+
# set it aside for a moment
244+
$prevline .=$line .'';
245+
next;
246+
}
247+
}
248+
225249
# we are analyzing a struct definition
226250
if ($in_struct)
227251
{
@@ -394,7 +418,7 @@ sub elem
394418
}
395419
# normal struct field
396420
elsif ($line =~
397-
/^\s*(.+)\s*\b(\w+)(\[\w+\])?\s*(?:pg_node_attr\(([\w(), ]*)\))?;/
421+
/^\s*(.+)\s*\b(\w+)(\[[\w\s+]+\])?\s*(?:pg_node_attr\(([\w(), ]*)\))?;/
398422
)
399423
{
400424
if ($is_node_struct)
@@ -441,13 +465,46 @@ sub elem
441465
$my_field_attrs{$name} = \@attrs;
442466
}
443467
}
444-
else
468+
# function pointer field
469+
elsif ($line =~
470+
/^\s*([\w\s*]+)\s*\(\*(\w+)\)\s*\((.*)\)\s*(?:pg_node_attr\(([\w(), ]*)\))?;/
471+
)
445472
{
446473
if ($is_node_struct)
447474
{
448-
#warn "$infile:$lineno: could not parse \"$line\"\n";
475+
my$type =$1;
476+
my$name =$2;
477+
my$args =$3;
478+
my$attrs =$4;
479+
480+
my@attrs;
481+
if ($attrs)
482+
{
483+
@attrs =split /,\s*/,$attrs;
484+
foreachmy$attr (@attrs)
485+
{
486+
if ($attr !~/^copy_as\(\w+\)$/
487+
&&$attr !~/^read_as\(\w+\)$/
488+
&& !elem$attr,
489+
qw(equal_ignore read_write_ignore))
490+
{
491+
die
492+
"$infile:$lineno: unrecognized attribute\"$attr\"\n";
493+
}
494+
}
495+
}
496+
497+
push@my_fields,$name;
498+
$my_field_types{$name} ='function pointer';
499+
$my_field_attrs{$name} = \@attrs;
449500
}
450501
}
502+
else
503+
{
504+
# We're not too picky about what's outside structs,
505+
# but we'd better understand everything inside.
506+
die"$infile:$lineno: could not parse\"$line\"\n";
507+
}
451508
}
452509
# not in a struct
453510
else
@@ -709,6 +766,12 @@ sub elem
709766
unless$equal_ignore;
710767
}
711768
}
769+
elsif ($teq'function pointer')
770+
{
771+
# we can copy and compare as a scalar
772+
print$cff"\tCOPY_SCALAR_FIELD($f);\n"unless$copy_ignore;
773+
print$eff"\tCOMPARE_SCALAR_FIELD($f);\n"unless$equal_ignore;
774+
}
712775
# node type
713776
elsif ($t =~/(\w+)\*/and elem$1,@node_types)
714777
{
@@ -980,6 +1043,12 @@ sub elem
9801043
unless$no_read;
9811044
}
9821045
}
1046+
elsif ($teq'function pointer')
1047+
{
1048+
# We don't print these, and we can't read them either
1049+
die"cannot read function pointer in struct\"$n\" field\"$f\"\n"
1050+
unless$no_read;
1051+
}
9831052
# Special treatments of several Path node fields
9841053
elsif ($teq'RelOptInfo*' && elem'write_only_relids',@a)
9851054
{

‎src/include/nodes/parsenodes.h

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -303,26 +303,26 @@ typedef struct A_Expr
303303

304304
/*
305305
* A_Const - a literal constant
306+
*
307+
* Value nodes are inline for performance. You can treat 'val' as a node,
308+
* as in IsA(&val, Integer). 'val' is not valid if isnull is true.
306309
*/
310+
unionValUnion
311+
{
312+
Nodenode;
313+
Integerival;
314+
Floatfval;
315+
Booleanboolval;
316+
Stringsval;
317+
BitStringbsval;
318+
};
319+
307320
typedefstructA_Const
308321
{
309322
pg_node_attr(custom_copy_equal,custom_read_write,no_read)
310323

311324
NodeTagtype;
312-
313-
/*
314-
* Value nodes are inline for performance. You can treat 'val' as a node,
315-
* as in IsA(&val, Integer). 'val' is not valid if isnull is true.
316-
*/
317-
unionValUnion
318-
{
319-
Nodenode;
320-
Integerival;
321-
Floatfval;
322-
Booleanboolval;
323-
Stringsval;
324-
BitStringbsval;
325-
}val;
325+
unionValUnionval;
326326
boolisnull;/* SQL NULL constant */
327327
intlocation;/* token location, or -1 if unknown */
328328
}A_Const;

‎src/include/nodes/pathnodes.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1098,7 +1098,7 @@ struct IndexOptInfo
10981098

10991099
/*
11001100
* Remaining fields are copied from the index AM's API struct
1101-
* (IndexAmRoutine)
1101+
* (IndexAmRoutine). We don't bother to dump them.
11021102
*/
11031103
boolamcanorderbyoppg_node_attr(read_write_ignore);
11041104
boolamoptionalkeypg_node_attr(read_write_ignore);
@@ -1111,8 +1111,9 @@ struct IndexOptInfo
11111111
boolamcanparallelpg_node_attr(read_write_ignore);
11121112
/* does AM have ammarkpos interface? */
11131113
boolamcanmarkpospg_node_attr(read_write_ignore);
1114+
/* AM's cost estimator */
11141115
/* Rather than include amapi.h here, we declare amcostestimate like this */
1115-
void(*amcostestimate) ();/* AM's cost estimator */
1116+
void(*amcostestimate) ()pg_node_attr(read_write_ignore);
11161117
};
11171118

11181119
/*

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp