Skip to content

Commit 4c689a6

Browse files
committed
Remove gen_node_support.pl's special treatment of EquivalenceClasses.
It seems better to deal with this by explicit annotations on the fields in question, instead of magic knowledge embedded in the script. While that creates a risk-of-omission from failing to annotate fields, the preceding commit should catch any such oversights. Discussion: https://postgr.es/m/[email protected]
1 parent b6bd5de commit 4c689a6

File tree

3 files changed

+49
-14
lines changed

3 files changed

+49
-14
lines changed

src/backend/nodes/gen_node_support.pl

+33-7
Original file line numberDiff line numberDiff line change
@@ -171,9 +171,6 @@ sub elem
171171
# Track node types with manually assigned NodeTag numbers.
172172
my %manual_nodetag_number;
173173

174-
# EquivalenceClasses are never moved, so just shallow-copy the pointer
175-
push @scalar_types, qw(EquivalenceClass* EquivalenceMember*);
176-
177174
# This is a struct, so we can copy it by assignment. Equal support is
178175
# currently not required.
179176
push @scalar_types, qw(QualCost);
@@ -454,9 +451,14 @@ sub elem
454451
&& $attr !~ /^copy_as\(\w+\)$/
455452
&& $attr !~ /^read_as\(\w+\)$/
456453
&& !elem $attr,
457-
qw(equal_ignore equal_ignore_if_zero read_write_ignore
458-
write_only_relids write_only_nondefault_pathtarget write_only_req_outer)
459-
)
454+
qw(copy_as_scalar
455+
equal_as_scalar
456+
equal_ignore
457+
equal_ignore_if_zero
458+
read_write_ignore
459+
write_only_relids
460+
write_only_nondefault_pathtarget
461+
write_only_req_outer))
460462
{
461463
die
462464
"$infile:$lineno: unrecognized attribute \"$attr\"\n";
@@ -691,6 +693,8 @@ sub elem
691693
# extract per-field attributes
692694
my $array_size_field;
693695
my $copy_as_field;
696+
my $copy_as_scalar = 0;
697+
my $equal_as_scalar = 0;
694698
foreach my $a (@a)
695699
{
696700
if ($a =~ /^array_size\(([\w.]+)\)$/)
@@ -705,19 +709,41 @@ sub elem
705709
{
706710
$copy_as_field = $1;
707711
}
712+
elsif ($a eq 'copy_as_scalar')
713+
{
714+
$copy_as_scalar = 1;
715+
}
716+
elsif ($a eq 'equal_as_scalar')
717+
{
718+
$equal_as_scalar = 1;
719+
}
708720
elsif ($a eq 'equal_ignore')
709721
{
710722
$equal_ignore = 1;
711723
}
712724
}
713725

714-
# override type-specific copy method if copy_as is specified
726+
# override type-specific copy method if requested
715727
if (defined $copy_as_field)
716728
{
717729
print $cff "\tnewnode->$f = $copy_as_field;\n"
718730
unless $copy_ignore;
719731
$copy_ignore = 1;
720732
}
733+
elsif ($copy_as_scalar)
734+
{
735+
print $cff "\tCOPY_SCALAR_FIELD($f);\n"
736+
unless $copy_ignore;
737+
$copy_ignore = 1;
738+
}
739+
740+
# override type-specific equal method if requested
741+
if ($equal_as_scalar)
742+
{
743+
print $eff "\tCOMPARE_SCALAR_FIELD($f);\n"
744+
unless $equal_ignore;
745+
$equal_ignore = 1;
746+
}
721747

722748
# select instructions by field type
723749
if ($t eq 'char*')

src/include/nodes/nodes.h

+6
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,12 @@ typedef enum NodeTag
8686
*
8787
* - copy_as(VALUE): In copyObject(), replace the field's value with VALUE.
8888
*
89+
* - copy_as_scalar: In copyObject(), copy the field as a scalar value
90+
* (e.g. a pointer) even if it is a node-type pointer.
91+
*
92+
* - equal_as_scalar: In equal(), compare the field as a scalar value
93+
* even if it is a node-type pointer.
94+
*
8995
* - equal_ignore: Ignore the field for equality.
9096
*
9197
* - equal_ignore_if_zero: Ignore the field for equality if it is zero.

src/include/nodes/pathnodes.h

+10-7
Original file line numberDiff line numberDiff line change
@@ -1279,7 +1279,9 @@ typedef struct StatisticExtInfo
12791279
*
12801280
* NB: EquivalenceClasses are never copied after creation. Therefore,
12811281
* copyObject() copies pointers to them as pointers, and equal() compares
1282-
* pointers to EquivalenceClasses via pointer equality.
1282+
* pointers to EquivalenceClasses via pointer equality. This is implemented
1283+
* by putting copy_as_scalar and equal_as_scalar attributes on fields that
1284+
* are pointers to EquivalenceClasses. The same goes for EquivalenceMembers.
12831285
*/
12841286
typedef struct EquivalenceClass
12851287
{
@@ -1370,7 +1372,8 @@ typedef struct PathKey
13701372

13711373
NodeTag type;
13721374

1373-
EquivalenceClass *pk_eclass; /* the value that is ordered */
1375+
/* the value that is ordered */
1376+
EquivalenceClass *pk_eclass pg_node_attr(copy_as_scalar, equal_as_scalar);
13741377
Oid pk_opfamily; /* btree opfamily defining the ordering */
13751378
int pk_strategy; /* sort direction (ASC or DESC) */
13761379
bool pk_nulls_first; /* do NULLs come before normal values? */
@@ -2478,7 +2481,7 @@ typedef struct RestrictInfo
24782481
* Generating EquivalenceClass. This field is NULL unless clause is
24792482
* potentially redundant.
24802483
*/
2481-
EquivalenceClass *parent_ec pg_node_attr(equal_ignore, read_write_ignore);
2484+
EquivalenceClass *parent_ec pg_node_attr(copy_as_scalar, equal_ignore, read_write_ignore);
24822485

24832486
/*
24842487
* cache space for cost and selectivity
@@ -2506,13 +2509,13 @@ typedef struct RestrictInfo
25062509
*/
25072510

25082511
/* EquivalenceClass containing lefthand */
2509-
EquivalenceClass *left_ec pg_node_attr(equal_ignore, read_write_ignore);
2512+
EquivalenceClass *left_ec pg_node_attr(copy_as_scalar, equal_ignore, read_write_ignore);
25102513
/* EquivalenceClass containing righthand */
2511-
EquivalenceClass *right_ec pg_node_attr(equal_ignore, read_write_ignore);
2514+
EquivalenceClass *right_ec pg_node_attr(copy_as_scalar, equal_ignore, read_write_ignore);
25122515
/* EquivalenceMember for lefthand */
2513-
EquivalenceMember *left_em pg_node_attr(equal_ignore);
2516+
EquivalenceMember *left_em pg_node_attr(copy_as_scalar, equal_ignore);
25142517
/* EquivalenceMember for righthand */
2515-
EquivalenceMember *right_em pg_node_attr(equal_ignore);
2518+
EquivalenceMember *right_em pg_node_attr(copy_as_scalar, equal_ignore);
25162519

25172520
/*
25182521
* List of MergeScanSelCache structs. Those aren't Nodes, so hard to

0 commit comments

Comments
 (0)