Skip to content

[ALGO-04] CALL…YIELD composes with WHERE but not with ORDER BY or a following MATCH — top-k by PageRank is unexpressible #483

Description

@sandeepkunkunuru

Goal this serves

ALGO-04in-query composition: MATCH … CALL algo.x(subgraph) YIELD … WHERE … RETURN in one statement, no explicit projection step. Recorded as 🔴 blocked by the CALL…YIELD gap.

That status is stale, but not by as much as it looks

#439 fixed the leading-CALL/YIELD deferral, and basic composition now works. Measured on this build:

Form Result
CALL algo.pageRank(...) YIELD nodeId, score WHERE score > 0.1 RETURN count(*) ✅ works
MATCH (p:P) CALL algo.pageRank(...) YIELD nodeId, score RETURN count(*) ✅ works
CALL algo.pageRank(...) YIELD nodeId AS n, score AS sc RETURN count(sc) ✅ works
CALL algo.wcc() YIELD nodeId, componentId MATCH (p:P) WHERE id(p) = nodeId RETURN count(*) Variable not found: nodeId
CALL algo.pageRank(...) YIELD nodeId, score RETURN nodeId ORDER BY score DESC LIMIT 3 ❌ Parse error --> 1:71

So the spec should read 🟡, not 🔴 — and the two that fail are the two that matter most.

Why these two specifically

ORDER BY after YIELD is the canonical algorithm query. "Give me the top 10 nodes by PageRank" is what every user runs first, and it is a parse error. The workaround is to stream every score to the client and sort there, which defeats running the algorithm in the database at all — on a 1B-edge graph that is a billion rows over the wire to get ten.

YIELD variables not reaching a following MATCH is the other half of composition. CALL algo.wcc() YIELD nodeId, componentId MATCH (p) WHERE id(p) = nodeId is how you turn algorithm output back into graph entities. Without it, algorithm results cannot be joined to the graph they came from inside one statement — which is precisely the "no explicit projection step" property ALGO-04 exists to assert.

Definition of done

  • CALL … YIELD … RETURN … ORDER BY … [SKIP] [LIMIT] parses and executes, sorting on any yielded column including ones not in the RETURN list
  • CALL … YIELD … MATCH (…) WHERE <uses a yielded variable> binds correctly; yielded variables are in scope for every subsequent clause, the same way UNWIND variables are
  • Both work with aliased yields (YIELD score AS s … ORDER BY s)
  • WITH after YIELD also composes, or is rejected with a typed error rather than a bare parse failure — today CALL {} … WITH fails at 1:89 with no explanation
  • Tests for each form in tests/cypher_projection_semantics.rs
  • docs/CYPHER_COMPATIBILITY.md rows updated and examples/cypher_matrix_probe.rs gains a probe per form, so the matrix reflects it
  • The spec's ALGO-04 baseline is corrected from 🔴 to what is actually true

Note on ordering with the other algorithm work

This is a prerequisite for ALGO-06 (write-back modes) being useful and for ALGO-05 (named projections): both assume algorithm output can be composed with the rest of a query. Worth doing before either.

Found while auditing the spec's algorithm requirements against the engine.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions