Expand description
§Abstract Syntax Tree (AST) for OpenCypher Queries
An Abstract Syntax Tree is a tree-shaped data structure that represents the semantic structure of source code. It is “abstract” because it discards syntactic noise that matters to the parser but not to the compiler – parentheses for grouping, semicolons, whitespace, and comments are all gone. What remains is a clean hierarchy of language constructs: clauses, patterns, expressions, and literals.
§Cypher AST and Graph Patterns
Cypher’s pattern syntax maps naturally to a tree:
(a:Person)-[:KNOWS]->(b:Person)
| | |
PatternNode PatternEdge PatternNode
\__________|__________/
PatternPath
|
MatchClause
|
Query (root of the tree)The Query struct is the root node of every AST. Its fields are all optional
because Cypher allows many clause combinations: CREATE without MATCH, MATCH
without RETURN, standalone MERGE, and so on. The planner inspects which fields
are populated to decide what execution plan to build.
§Recursive Types and Box<T> in Rust
ASTs are inherently recursive – an Expression can contain sub-expressions
(1 + (2 * 3)), and a Query can contain sub-queries (CALL { ... }). Rust
requires every type to have a known size at compile time, but a recursive type like
Expression { left: Expression, right: Expression } would be infinitely large.
The solution is Box<T> – a heap-allocated pointer with a fixed size (8 bytes
on 64-bit systems). By writing Box<Expression> instead of Expression, we break
the infinite-size cycle. The AST nodes in this module use Box extensively:
Box<Expression> in binary operations, Box<Query> in CALL subqueries, and
Box<WhereClause> in EXISTS subqueries (the Option<Box<WhereClause>> pattern
also breaks a recursive type cycle between Expression and WhereClause).
Structs§
- Call
Clause - CALL clause: CALL db.index.vector.queryNodes(‘Person’, ‘embedding’, […], 10) YIELD node, score
- Create
Clause - CREATE clause
- Create
Constraint Clause - Unique constraint clause
- Create
Index Clause - CREATE INDEX clause
- Create
Vector Index Clause - CREATE VECTOR INDEX clause
- Delete
Clause - DELETE clause
- Drop
Index Clause - DROP INDEX clause
- Edge
Pattern - Edge pattern: -[:KNOWS|FOLLOWS*1..5]->
- Foreach
Clause - FOREACH clause: FOREACH (x IN list | SET x.prop = val)
- Length
Pattern - Variable length pattern: *1..5 or * or *3
- Match
Clause - MATCH clause:
MATCH (n:Person)-[:KNOWS]->(m) - Merge
Clause - MERGE clause: MERGE (n:Person {name: “Alice”}) ON CREATE SET … ON MATCH SET …
- Node
Pattern - Node pattern: (n:Person:Employee {name: “Alice”})
- Order
ByClause - ORDER BY clause
- Order
ByItem - Order by item
- Path
Pattern - Path pattern:
(n:Person)-[:KNOWS*1..3]->(m:Person) - Path
Segment - Segment of a path (edge + node)
- Pattern
- Graph pattern
- Query
- The root AST node representing a complete Cypher query.
- Remove
Clause - REMOVE clause
- Return
Clause - RETURN clause
- Return
Item - Return item: n, n.name AS name, count(n)
- SetClause
- SET clause
- SetItem
- SET item: n.name = “Alice”
- Unwind
Clause - UNWIND clause:
UNWIND [1,2,3] AS x - Where
Clause - WHERE clause with predicates
- With
Clause - WITH clause
- Yield
Item - YIELD item: node AS n, score
Enums§
- Binary
Op - Binary operators
- Direction
- Edge direction
- Expression
- Expression in WHERE or RETURN
- Path
Type - Path type for path patterns (normal, shortest, allShortest)
- Remove
Item - REMOVE item: n.name or n:Label
- UnaryOp
- Unary operators