Skip to content

Make count rel degree optimizer orientation-independent #529

@adsharma

Description

@adsharma

Background

OptimizerTest.CountRelTableOptimizer is currently skipped on Windows because the test asserts a specific logical plan shape for degree-count rewrites. A query such as MATCH (u)-[:r]->(v) RETURN count(DISTINCT u.id) fixes the logical relationship direction, but not the physical plan orientation.

The planner can validly choose either:

  • SCAN u, then EXTEND FWD from u to v
  • SCAN v, then EXTEND BWD from v back to u

Windows can pick the reverse orientation due to nondeterministic or tie-dependent join enumeration order. This is not known to be a query correctness issue; the current failure is a plan-shape assertion before result validation.

Current limitation

CountRelTableOptimizer::tryRewriteActiveBoundCount() only recognizes the case where the counted distinct node primary key belongs to extend.getBoundNode(). If the planner chooses the equivalent reverse physical orientation, the counted node is extend.getNbrNode(), so the optimizer misses the REL_DEGREE_TABLE rewrite.

Desired fix

Make the active-bound count rewrite orientation-independent:

  • Detect whether count(DISTINCT node.pk) refers to the extend bound node or neighbor node.
  • Select the rel data direction based on the counted node logical role in the relationship: source means RelDataDirection::FWD, destination means RelDataDirection::BWD.
  • Collect matching rel table IDs using the original source/destination table pairs, not just the physical extend bound side.
  • Preserve existing safety checks: single-label counted node, primary-key distinct count, no rel properties, simple scan/extend/aggregate shape.
  • Add tests covering both physical orientations, including multi-rel-table groups where duplicate active bound nodes need to be merged.

Acceptance criteria

  • Re-enable OptimizerTest.CountRelTableOptimizer on Windows.
  • The optimizer rewrites both forward-bound and reverse-bound physical plans when they are semantically equivalent for active-bound counting.
  • Existing result checks continue to pass for single rel table and multi-rel-table cases.

Related temporary skip PR: #528

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions