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/263413.1669513145@sss.pgh.pa.us
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

Lines changed: 33 additions & 7 deletions
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

Lines changed: 6 additions & 0 deletions
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

Lines changed: 10 additions & 7 deletions
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)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy