cypherlite_query/parser/ast.rs
1// AST node type definitions for openCypher subset
2
3/// A complete Cypher query.
4#[derive(Debug, Clone, PartialEq)]
5pub struct Query {
6 /// Ordered list of clauses that make up the query.
7 pub clauses: Vec<Clause>,
8}
9
10/// Top-level clause types.
11#[derive(Debug, Clone, PartialEq)]
12pub enum Clause {
13 /// `MATCH` clause.
14 Match(MatchClause),
15 /// `RETURN` clause.
16 Return(ReturnClause),
17 /// `CREATE` clause.
18 Create(CreateClause),
19 /// `SET` clause.
20 Set(SetClause),
21 /// `REMOVE` clause.
22 Remove(RemoveClause),
23 /// `DELETE` / `DETACH DELETE` clause.
24 Delete(DeleteClause),
25 /// `WITH` clause.
26 With(WithClause),
27 /// `MERGE` clause.
28 Merge(MergeClause),
29 /// `UNWIND` clause.
30 Unwind(UnwindClause),
31 /// `CREATE INDEX` clause.
32 CreateIndex(CreateIndexClause),
33 /// `DROP INDEX` clause.
34 DropIndex(DropIndexClause),
35 /// `CREATE SNAPSHOT` clause (subgraph feature).
36 #[cfg(feature = "subgraph")]
37 CreateSnapshot(CreateSnapshotClause),
38 /// `CREATE HYPEREDGE` clause (hypergraph feature).
39 #[cfg(feature = "hypergraph")]
40 CreateHyperedge(CreateHyperedgeClause),
41 /// `MATCH HYPEREDGE` clause (hypergraph feature).
42 #[cfg(feature = "hypergraph")]
43 MatchHyperedge(MatchHyperedgeClause),
44}
45
46/// Temporal predicate for time-travel queries.
47#[derive(Debug, Clone, PartialEq)]
48pub enum TemporalPredicate {
49 /// `AT TIME expr` -- find the version current at a specific point in time.
50 AsOf(Expression),
51 /// `BETWEEN TIME expr AND expr` -- find all versions within a time range.
52 Between(Expression, Expression),
53}
54
55/// A `MATCH` clause with optional temporal predicate and filter.
56#[derive(Debug, Clone, PartialEq)]
57pub struct MatchClause {
58 /// True when `OPTIONAL MATCH`.
59 pub optional: bool,
60 /// The graph pattern to match.
61 pub pattern: Pattern,
62 /// Optional temporal predicate (`AT TIME` / `BETWEEN TIME`).
63 pub temporal_predicate: Option<TemporalPredicate>,
64 /// Optional `WHERE` filter expression.
65 pub where_clause: Option<Expression>,
66}
67
68/// A `RETURN` clause with optional ordering, skip, and limit.
69#[derive(Debug, Clone, PartialEq)]
70pub struct ReturnClause {
71 /// Whether `DISTINCT` was specified.
72 pub distinct: bool,
73 /// Expressions to return.
74 pub items: Vec<ReturnItem>,
75 /// Optional `ORDER BY` items.
76 pub order_by: Option<Vec<OrderItem>>,
77 /// Optional `SKIP` expression.
78 pub skip: Option<Expression>,
79 /// Optional `LIMIT` expression.
80 pub limit: Option<Expression>,
81}
82
83/// A single item in a `RETURN` or `WITH` clause.
84#[derive(Debug, Clone, PartialEq)]
85pub struct ReturnItem {
86 /// The expression to evaluate.
87 pub expr: Expression,
88 /// Optional `AS` alias.
89 pub alias: Option<String>,
90}
91
92/// A single sort key in an `ORDER BY` clause.
93#[derive(Debug, Clone, PartialEq)]
94pub struct OrderItem {
95 /// The expression to sort by.
96 pub expr: Expression,
97 /// True for `ASC` (default), false for `DESC`.
98 pub ascending: bool,
99}
100
101/// A `CREATE` clause with a pattern to create.
102#[derive(Debug, Clone, PartialEq)]
103pub struct CreateClause {
104 /// The graph pattern to create.
105 pub pattern: Pattern,
106}
107
108/// A `SET` clause with property assignments.
109#[derive(Debug, Clone, PartialEq)]
110pub struct SetClause {
111 /// Property assignment items.
112 pub items: Vec<SetItem>,
113}
114
115/// A single property assignment in a `SET` clause.
116#[derive(Debug, Clone, PartialEq)]
117pub enum SetItem {
118 /// Set a property to a value: `target = value`.
119 Property {
120 /// The property access expression (e.g. `n.name`).
121 target: Expression,
122 /// The value expression.
123 value: Expression,
124 },
125}
126
127/// A `REMOVE` clause.
128#[derive(Debug, Clone, PartialEq)]
129pub struct RemoveClause {
130 /// Items to remove.
131 pub items: Vec<RemoveItem>,
132}
133
134/// A single item in a `REMOVE` clause.
135#[derive(Debug, Clone, PartialEq)]
136pub enum RemoveItem {
137 /// Remove a property (e.g. `n.name`).
138 Property(Expression),
139 /// Remove a label from a node (e.g. `n:Label`).
140 Label {
141 /// Variable name.
142 variable: String,
143 /// Label to remove.
144 label: String,
145 },
146}
147
148/// A `DELETE` or `DETACH DELETE` clause.
149#[derive(Debug, Clone, PartialEq)]
150pub struct DeleteClause {
151 /// True if `DETACH DELETE` (also deletes relationships).
152 pub detach: bool,
153 /// Expressions identifying entities to delete.
154 pub exprs: Vec<Expression>,
155}
156
157/// A `WITH` clause for intermediate result piping.
158#[derive(Debug, Clone, PartialEq)]
159pub struct WithClause {
160 /// Whether `DISTINCT` was specified.
161 pub distinct: bool,
162 /// Projected items.
163 pub items: Vec<ReturnItem>,
164 /// Optional `WHERE` filter.
165 pub where_clause: Option<Expression>,
166}
167
168/// A `MERGE` clause with optional `ON MATCH` / `ON CREATE` actions.
169#[derive(Debug, Clone, PartialEq)]
170pub struct MergeClause {
171 /// The pattern to match or create.
172 pub pattern: Pattern,
173 /// `SET` items to apply when the pattern matches.
174 pub on_match: Vec<SetItem>,
175 /// `SET` items to apply when the pattern is created.
176 pub on_create: Vec<SetItem>,
177}
178
179/// An `UNWIND` clause that expands a list into rows.
180#[derive(Debug, Clone, PartialEq)]
181pub struct UnwindClause {
182 /// The list expression to unwind.
183 pub expr: Expression,
184 /// The variable name bound to each element.
185 pub variable: String,
186}
187
188/// The target kind of a property index.
189#[derive(Debug, Clone, PartialEq)]
190pub enum IndexTarget {
191 /// Index on a node label.
192 NodeLabel(String),
193 /// Index on a relationship type.
194 RelationshipType(String),
195}
196
197/// `CREATE INDEX [name] ON :Label(property)` or `CREATE INDEX [name] ON :REL_TYPE(property)`
198#[derive(Debug, Clone, PartialEq)]
199pub struct CreateIndexClause {
200 /// Optional index name.
201 pub name: Option<String>,
202 /// Label or relationship type the index applies to.
203 pub target: IndexTarget,
204 /// Property key the index covers.
205 pub property: String,
206}
207
208/// DROP INDEX name
209#[derive(Debug, Clone, PartialEq)]
210pub struct DropIndexClause {
211 /// Name of the index to drop.
212 pub name: String,
213}
214
215// -- Patterns --
216
217/// A graph pattern consisting of one or more comma-separated chains.
218#[derive(Debug, Clone, PartialEq)]
219pub struct Pattern {
220 /// Comma-separated pattern chains.
221 pub chains: Vec<PatternChain>,
222}
223
224/// A single chain of alternating nodes and relationships.
225#[derive(Debug, Clone, PartialEq)]
226pub struct PatternChain {
227 /// Alternating node and relationship elements.
228 pub elements: Vec<PatternElement>,
229}
230
231/// An element within a pattern chain.
232#[derive(Debug, Clone, PartialEq)]
233pub enum PatternElement {
234 /// A node pattern (e.g. `(n:Person)`).
235 Node(NodePattern),
236 /// A relationship pattern (e.g. `-[:KNOWS]->`).
237 Relationship(RelationshipPattern),
238}
239
240/// A node pattern: `(variable:Label {properties})`.
241#[derive(Debug, Clone, PartialEq)]
242pub struct NodePattern {
243 /// Optional variable binding.
244 pub variable: Option<String>,
245 /// Zero or more labels.
246 pub labels: Vec<String>,
247 /// Optional inline property map.
248 pub properties: Option<MapLiteral>,
249}
250
251/// A relationship pattern: `-[variable:TYPE {props}]->`.
252#[derive(Debug, Clone, PartialEq)]
253pub struct RelationshipPattern {
254 /// Optional variable binding.
255 pub variable: Option<String>,
256 /// Relationship type filters.
257 pub rel_types: Vec<String>,
258 /// Arrow direction.
259 pub direction: RelDirection,
260 /// Optional inline property map.
261 pub properties: Option<MapLiteral>,
262 /// Minimum hops for variable-length paths. None means regular 1-hop.
263 pub min_hops: Option<u32>,
264 /// Maximum hops for variable-length paths. None means unbounded (capped by planner).
265 pub max_hops: Option<u32>,
266}
267
268/// Relationship arrow direction.
269#[derive(Debug, Clone, Copy, PartialEq, Eq)]
270pub enum RelDirection {
271 /// `-[...]->`
272 Outgoing,
273 /// `<-[...]-`
274 Incoming,
275 /// `-[...]-`
276 Undirected,
277}
278
279/// A map literal is a list of key-value pairs: `{key1: expr1, key2: expr2}`.
280pub type MapLiteral = Vec<(String, Expression)>;
281
282// -- Expressions --
283
284/// An expression node in the AST.
285#[derive(Debug, Clone, PartialEq)]
286pub enum Expression {
287 /// A literal value.
288 Literal(Literal),
289 /// A variable reference.
290 Variable(String),
291 /// Property access: `expr.prop`
292 Property(Box<Expression>, String),
293 /// Parameter reference: `$name`
294 Parameter(String),
295 /// Binary operation: `lhs op rhs`.
296 BinaryOp(BinaryOp, Box<Expression>, Box<Expression>),
297 /// Unary operation: `op expr`.
298 UnaryOp(UnaryOp, Box<Expression>),
299 /// Function call: `name(args)` or `name(DISTINCT args)`.
300 FunctionCall {
301 /// Function name.
302 name: String,
303 /// Whether `DISTINCT` was specified.
304 distinct: bool,
305 /// Function arguments.
306 args: Vec<Expression>,
307 },
308 /// `expr IS [NOT] NULL` -- bool is true when IS NOT NULL
309 IsNull(Box<Expression>, bool),
310 /// `count(*)`
311 CountStar,
312 /// List literal: `[expr, expr, ...]`
313 ListLiteral(Vec<Expression>),
314 /// Temporal reference: `expr AT TIME expr` in hyperedge participant lists.
315 #[cfg(feature = "hypergraph")]
316 TemporalRef {
317 /// The node expression.
318 node: Box<Expression>,
319 /// The timestamp expression.
320 timestamp: Box<Expression>,
321 },
322}
323
324/// A literal value in the AST.
325#[derive(Debug, Clone, PartialEq)]
326pub enum Literal {
327 /// Integer literal (e.g. `42`).
328 Integer(i64),
329 /// Floating-point literal (e.g. `3.14`).
330 Float(f64),
331 /// String literal (e.g. `'hello'`).
332 String(String),
333 /// Boolean literal (`true` / `false`).
334 Bool(bool),
335 /// `NULL` literal.
336 Null,
337}
338
339/// Binary operators.
340#[derive(Debug, Clone, Copy, PartialEq, Eq)]
341pub enum BinaryOp {
342 /// `+` addition.
343 Add,
344 /// `-` subtraction.
345 Sub,
346 /// `*` multiplication.
347 Mul,
348 /// `/` division.
349 Div,
350 /// `%` modulus.
351 Mod,
352 /// `=` equality.
353 Eq,
354 /// `<>` / `!=` inequality.
355 Neq,
356 /// `<` less than.
357 Lt,
358 /// `<=` less than or equal.
359 Lte,
360 /// `>` greater than.
361 Gt,
362 /// `>=` greater than or equal.
363 Gte,
364 /// `AND` logical conjunction.
365 And,
366 /// `OR` logical disjunction.
367 Or,
368}
369
370/// Unary operators.
371#[derive(Debug, Clone, Copy, PartialEq, Eq)]
372pub enum UnaryOp {
373 /// `NOT` logical negation.
374 Not,
375 /// `-` arithmetic negation.
376 Neg,
377}
378
379// -- Subgraph Snapshot --
380
381/// CREATE SNAPSHOT clause for materializing query results into a subgraph.
382///
383/// Syntax: CREATE SNAPSHOT (var:Label {props}) [AT TIME expr] FROM MATCH pattern [WHERE filter] RETURN items
384#[cfg(feature = "subgraph")]
385#[derive(Debug, Clone, PartialEq)]
386pub struct CreateSnapshotClause {
387 /// Optional variable name for the snapshot subgraph.
388 pub variable: Option<String>,
389 /// Labels for the snapshot subgraph.
390 pub labels: Vec<String>,
391 /// Properties to set on the snapshot subgraph.
392 pub properties: Option<MapLiteral>,
393 /// Optional temporal anchor (AT TIME expr).
394 pub temporal_anchor: Option<Expression>,
395 /// The FROM MATCH clause defining the source pattern.
396 pub from_match: MatchClause,
397 /// The FROM RETURN items defining what to capture.
398 pub from_return: Vec<ReturnItem>,
399}
400
401/// CREATE HYPEREDGE clause for creating a hyperedge connecting multiple sources and targets.
402///
403/// Syntax: CREATE HYPEREDGE (var:Label) FROM (expr, expr, ...) TO (expr, expr, ...)
404#[cfg(feature = "hypergraph")]
405#[derive(Debug, Clone, PartialEq)]
406pub struct CreateHyperedgeClause {
407 /// Optional variable name for the hyperedge.
408 pub variable: Option<String>,
409 /// Labels (relationship types) for the hyperedge.
410 pub labels: Vec<String>,
411 /// Source participant expressions (FROM list).
412 pub sources: Vec<Expression>,
413 /// Target participant expressions (TO list).
414 pub targets: Vec<Expression>,
415}
416
417/// MATCH HYPEREDGE clause for querying hyperedges.
418///
419/// Syntax: MATCH HYPEREDGE (var:Label)
420#[cfg(feature = "hypergraph")]
421#[derive(Debug, Clone, PartialEq)]
422pub struct MatchHyperedgeClause {
423 /// Optional variable name for the hyperedge.
424 pub variable: Option<String>,
425 /// Labels to filter by.
426 pub labels: Vec<String>,
427}