# Track node types with manually assigned NodeTag numbers.
my %manual_nodetag_number;
-# EquivalenceClasses are never moved, so just shallow-copy the pointer
-push @scalar_types, qw(EquivalenceClass* EquivalenceMember*);
-
# This is a struct, so we can copy it by assignment. Equal support is
# currently not required.
push @scalar_types, qw(QualCost);
&& $attr !~ /^copy_as\(\w+\)$/
&& $attr !~ /^read_as\(\w+\)$/
&& !elem $attr,
- qw(equal_ignore equal_ignore_if_zero read_write_ignore
- write_only_relids write_only_nondefault_pathtarget write_only_req_outer)
- )
+ qw(copy_as_scalar
+ equal_as_scalar
+ equal_ignore
+ equal_ignore_if_zero
+ read_write_ignore
+ write_only_relids
+ write_only_nondefault_pathtarget
+ write_only_req_outer))
{
die
"$infile:$lineno: unrecognized attribute \"$attr\"\n";
# extract per-field attributes
my $array_size_field;
my $copy_as_field;
+ my $copy_as_scalar = 0;
+ my $equal_as_scalar = 0;
foreach my $a (@a)
{
if ($a =~ /^array_size\(([\w.]+)\)$/)
{
$copy_as_field = $1;
}
+ elsif ($a eq 'copy_as_scalar')
+ {
+ $copy_as_scalar = 1;
+ }
+ elsif ($a eq 'equal_as_scalar')
+ {
+ $equal_as_scalar = 1;
+ }
elsif ($a eq 'equal_ignore')
{
$equal_ignore = 1;
}
}
- # override type-specific copy method if copy_as is specified
+ # override type-specific copy method if requested
if (defined $copy_as_field)
{
print $cff "\tnewnode->$f = $copy_as_field;\n"
unless $copy_ignore;
$copy_ignore = 1;
}
+ elsif ($copy_as_scalar)
+ {
+ print $cff "\tCOPY_SCALAR_FIELD($f);\n"
+ unless $copy_ignore;
+ $copy_ignore = 1;
+ }
+
+ # override type-specific equal method if requested
+ if ($equal_as_scalar)
+ {
+ print $eff "\tCOMPARE_SCALAR_FIELD($f);\n"
+ unless $equal_ignore;
+ $equal_ignore = 1;
+ }
# select instructions by field type
if ($t eq 'char*')
*
* - copy_as(VALUE): In copyObject(), replace the field's value with VALUE.
*
+ * - copy_as_scalar: In copyObject(), copy the field as a scalar value
+ * (e.g. a pointer) even if it is a node-type pointer.
+ *
+ * - equal_as_scalar: In equal(), compare the field as a scalar value
+ * even if it is a node-type pointer.
+ *
* - equal_ignore: Ignore the field for equality.
*
* - equal_ignore_if_zero: Ignore the field for equality if it is zero.
*
* NB: EquivalenceClasses are never copied after creation. Therefore,
* copyObject() copies pointers to them as pointers, and equal() compares
- * pointers to EquivalenceClasses via pointer equality.
+ * pointers to EquivalenceClasses via pointer equality. This is implemented
+ * by putting copy_as_scalar and equal_as_scalar attributes on fields that
+ * are pointers to EquivalenceClasses. The same goes for EquivalenceMembers.
*/
typedef struct EquivalenceClass
{
NodeTag type;
- EquivalenceClass *pk_eclass; /* the value that is ordered */
+ /* the value that is ordered */
+ EquivalenceClass *pk_eclass pg_node_attr(copy_as_scalar, equal_as_scalar);
Oid pk_opfamily; /* btree opfamily defining the ordering */
int pk_strategy; /* sort direction (ASC or DESC) */
bool pk_nulls_first; /* do NULLs come before normal values? */
* Generating EquivalenceClass. This field is NULL unless clause is
* potentially redundant.
*/
- EquivalenceClass *parent_ec pg_node_attr(equal_ignore, read_write_ignore);
+ EquivalenceClass *parent_ec pg_node_attr(copy_as_scalar, equal_ignore, read_write_ignore);
/*
* cache space for cost and selectivity
*/
/* EquivalenceClass containing lefthand */
- EquivalenceClass *left_ec pg_node_attr(equal_ignore, read_write_ignore);
+ EquivalenceClass *left_ec pg_node_attr(copy_as_scalar, equal_ignore, read_write_ignore);
/* EquivalenceClass containing righthand */
- EquivalenceClass *right_ec pg_node_attr(equal_ignore, read_write_ignore);
+ EquivalenceClass *right_ec pg_node_attr(copy_as_scalar, equal_ignore, read_write_ignore);
/* EquivalenceMember for lefthand */
- EquivalenceMember *left_em pg_node_attr(equal_ignore);
+ EquivalenceMember *left_em pg_node_attr(copy_as_scalar, equal_ignore);
/* EquivalenceMember for righthand */
- EquivalenceMember *right_em pg_node_attr(equal_ignore);
+ EquivalenceMember *right_em pg_node_attr(copy_as_scalar, equal_ignore);
/*
* List of MergeScanSelCache structs. Those aren't Nodes, so hard to