WHERE filter + RETURN projection
# grade this stage (from your course directory)
npx theinference test --stage where-and-return --watchAdd the two clauses that turn bindings into a result table: WHERE filters, RETURN projects and aliases (plus DISTINCT, ORDER BY, LIMIT). Evaluate each predicate against each binding, project the return items, then apply distinct → order → limit in that order.
Implement the full single-segment pipeline
Evaluate a.prop OP literal (AND-chained, type-aware), project RETURN a.prop AS alias, then DISTINCT, ORDER BY (stable, type-aware compare), LIMIT. The fixture: WHERE m.released > 2000 ... ORDER BY actor, movie LIMIT 8.
// where: rows.filter(r => evalPredicate(where, r)) // a.prop OP literal, type-aware
// return: rows.map(r => ({ [alias]: resolveValue(r, variable, property) }))
// distinct: dedupe by canonicalized JSON of the row
// orderBy: stable sort by each key (numbers numerically, strings lexically)
// limit: slice(0, n)
your_program.sh query {fixture}/fixtures/data/nodes.json {fixture}/fixtures/data/relationships.json "MATCH (p:Person)-[:ACTED_IN]->(m:Movie) WHERE m.released > 2000 RETURN p.name AS actor, m.title AS movie ORDER BY actor, movie LIMIT 8"
m.released > 2000 must compare numbers; ORDER BY actor must sort strings. Comparing a number against a string should yield no match (Cypher's three-valued-ish behavior) rather than a JavaScript coercion surprise. Guard with typeof a === typeof b before comparing.
Process mode, stdout_json_match. With ORDER BY present the output order is fully determined, so it's graded as an exact ordered list (the given cli.ts preserves order when the query has ORDER BY). LIMIT 8 trims to the first 8 rows after ordering.