Skip to content

fix(exec): preserve all node labels in variable-length path values #705

Description

@DecisionNerd

Problem

Confirmed on current main at 6dc51fa47a9658d26a3f6e51e8a8261aaf9b4b86.

Storage defines type_ids as the authoritative full label set and type_id as legacy primary at crates/graphforge-storage/src/schemas.rs:124-139. Variable-length path hydration reads only type_id and constructs a one-element label list at crates/graphforge-rel/src/expr.rs:12044-12092.

Ordinary node hydration consumes full type_ids at crates/graphforge-rel/src/expr.rs:5214-5238. Thus nodes(p) can turn multi-label nodes into single-label values, making labels() and predicates report false graph state.

Objective

Make variable-length path node values carry the same complete canonical label set as direct node values.

Requirements

  • Hydrate labels from authoritative type_ids.
  • Resolve IDs through the correct ontology/runtime catalog domain.
  • Preserve canonical ordering, null/error behavior, and Arrow list representation.
  • Match direct-node semantics before and after reopen.
  • Keep Rust authoritative and bindings thin.

Acceptance Criteria

  • A Person:Employee node retains both labels through nodes(p) for bounded and unbounded variable-length patterns.
  • labels(x) and label predicates match the same node returned directly.
  • Single-label, advisory, mixed ontology/runtime, repeated-node, empty-path, and missing-catalog cases have explicit tests.
  • Label order and Arrow schema are deterministic across runs and reopen.
  • Fixed-hop and variable-length path values have semantic parity.
  • Applicable Rust/Python/Node/Cypher acceptance remains green.

BDD Completion Scenarios

Scenario: Multi-label path nodes remain truthful

Given a Person:Employee node on a variable-length path
When Cypher evaluates nodes(p) and labels()
Then both labels are present in canonical order
And match a direct result for that node.

Scenario: Reopen preserves path labels

Given a committed multi-label graph
When reopened and queried through the same path
Then full label sets and schema remain identical
And no runtime catalog ID substitutes for an ontology ID.

Implementation Notes

Likely surfaces include crates/graphforge-rel/src/expr.rs, storage catalog readers, path-value tests, and facade/binding Cypher tests. Reuse full-label hydration logic or a shared helper.

Observability

No new telemetry expected. Tests must assert complete label lists, not only primary label or row count.

Security And Privacy

Do not expose properties or UUIDs in diagnostics beyond deterministic fixtures.

Testing

Add direct-node versus variable-path parity with multiple labels. Cover bounded/unbounded paths, repeated nodes, reopen, mixed identity domains, and ordering. Assert full Arrow values and schema; no weakened checks.

Documentation

Update path semantics only if current docs describe a different label contract.

Non-Goals

  • Optimizing whole-graph hydration; that is a dependent issue.
  • Changing stored label meaning/order.
  • Binding-side reconstruction.

Related Issues

  • The path-hydration performance issue depends on this correctness contract.
  • Parent tracker will be attached through GitHub's native sub-issue relationship.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingcoreCore source code changesexecutorChanges to query executor

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions