Skip to main content

open_cypher/
ast.rs

1//! A fully owned, syntax-oriented openCypher abstract syntax tree.
2//!
3//! The tree describes what was written; it does not perform name resolution,
4//! type checking, query planning, or execution. Every syntactic node carries a
5//! half-open UTF-8 byte [`Span`]. Trivia remains available from the lossless
6//! token stream and is not attached to AST nodes.
7
8use crate::span::Span;
9
10/// A syntax value and its source extent.
11#[derive(Clone, Debug, PartialEq, Eq, Hash)]
12#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
13pub struct Node<T> {
14    /// The syntax represented by this node.
15    pub kind: T,
16    /// The full source extent, excluding surrounding trivia.
17    pub span: Span,
18}
19
20impl<T> Node<T> {
21    /// Creates a spanned syntax node.
22    #[must_use]
23    pub const fn new(kind: T, span: Span) -> Self {
24        Self { kind, span }
25    }
26
27    /// Converts the contained value while preserving its span.
28    #[must_use]
29    pub fn map<U>(self, map: impl FnOnce(T) -> U) -> Node<U> {
30        Node::new(map(self.kind), self.span)
31    }
32
33    /// Borrows the contained value while preserving its span.
34    #[must_use]
35    pub const fn as_ref(&self) -> Node<&T> {
36        Node::new(&self.kind, self.span)
37    }
38}
39
40/// A complete source input containing zero or one query statement.
41///
42/// The parser accepts an optional trailing semicolon. The statement vector is
43/// empty for empty or trivia-only input and otherwise contains one statement.
44#[derive(Clone, Debug, Default, PartialEq, Eq, Hash)]
45#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
46pub struct Program {
47    /// Statements in source order.
48    pub statements: Vec<Statement>,
49    /// The complete non-trivia source extent.
50    pub span: Span,
51}
52
53impl Program {
54    /// Creates a program.
55    #[must_use]
56    pub const fn new(statements: Vec<Statement>, span: Span) -> Self {
57        Self { statements, span }
58    }
59
60    /// Returns `true` when the input contains no statements.
61    #[must_use]
62    pub fn is_empty(&self) -> bool {
63        self.statements.is_empty()
64    }
65}
66
67/// A top-level statement.
68pub type Statement = Node<StatementKind>;
69
70/// The syntactic form of a top-level statement.
71#[non_exhaustive]
72#[derive(Clone, Debug, PartialEq, Eq, Hash)]
73#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
74pub enum StatementKind {
75    /// A regular query, optionally prefixed by an execution mode.
76    Query(QueryStatement),
77    /// A placeholder emitted by recovery.
78    Error(ErrorNode),
79}
80
81/// A query statement and its optional execution prefix.
82#[derive(Clone, Debug, PartialEq, Eq, Hash)]
83#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
84pub struct QueryStatement {
85    /// `EXPLAIN` or `PROFILE`, when present.
86    pub mode: Option<Node<ExecutionMode>>,
87    /// The query body.
88    pub query: Query,
89    /// A trailing semicolon, when one was written.
90    pub terminator: Option<Span>,
91}
92
93/// A query execution prefix.
94#[non_exhaustive]
95#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
96#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
97pub enum ExecutionMode {
98    Explain,
99    Profile,
100}
101
102/// A regular query.
103pub type Query = Node<QueryKind>;
104
105/// The syntactic form of a query.
106#[non_exhaustive]
107#[derive(Clone, Debug, PartialEq, Eq, Hash)]
108#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
109pub enum QueryKind {
110    /// One single query followed by zero or more `UNION` branches.
111    Regular(RegularQuery),
112    /// A placeholder emitted by recovery.
113    Error(ErrorNode),
114}
115
116/// A query connected by zero or more set unions.
117#[derive(Clone, Debug, PartialEq, Eq, Hash)]
118#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
119pub struct RegularQuery {
120    /// The first single query.
121    pub head: SingleQuery,
122    /// Subsequent union branches.
123    pub unions: Vec<UnionBranch>,
124}
125
126/// A `UNION` operator and the query to its right.
127#[derive(Clone, Debug, PartialEq, Eq, Hash)]
128#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
129pub struct UnionBranch {
130    /// Union duplicate policy.
131    pub operator: Node<UnionOperator>,
132    /// Query on the right-hand side.
133    pub query: SingleQuery,
134}
135
136/// Duplicate handling for a query union.
137#[non_exhaustive]
138#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
139#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
140pub enum UnionOperator {
141    /// Bare `UNION`, whose duplicate behavior is the openCypher default.
142    Default,
143    /// `UNION ALL`.
144    All,
145    /// `UNION DISTINCT`.
146    Distinct,
147}
148
149/// Duplicate handling explicitly written for a projection or function call.
150///
151/// The absence of this node represents the grammar's default behavior. Keeping
152/// `ALL` distinct from absence preserves the source-level syntax for tools that
153/// inspect or rewrite queries.
154#[non_exhaustive]
155#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
156#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
157pub enum SetQuantifier {
158    All,
159    Distinct,
160}
161
162/// A sequence of query clauses evaluated from left to right.
163pub type SingleQuery = Node<SingleQueryKind>;
164
165/// The contents of a single query.
166#[derive(Clone, Debug, Default, PartialEq, Eq, Hash)]
167#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
168pub struct SingleQueryKind {
169    /// Clauses in source order.
170    pub clauses: Vec<Clause>,
171}
172
173/// A query clause.
174pub type Clause = Node<ClauseKind>;
175
176/// Any clause in an openCypher query.
177#[non_exhaustive]
178#[derive(Clone, Debug, PartialEq, Eq, Hash)]
179#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
180pub enum ClauseKind {
181    Use(UseClause),
182    Match(MatchClause),
183    Unwind(UnwindClause),
184    Let(LetClause),
185    Create(CreateClause),
186    Insert(InsertClause),
187    Merge(MergeClause),
188    Delete(DeleteClause),
189    Set(SetClause),
190    Remove(RemoveClause),
191    Foreach(ForeachClause),
192    LoadCsv(LoadCsvClause),
193    Call(CallClause),
194    With(WithClause),
195    Return(ReturnClause),
196    Select(ProjectionClause),
197    Next(ProjectionClause),
198    Filter(FilterClause),
199    Finish,
200    /// A placeholder emitted after synchronizing at a clause boundary.
201    Error(ErrorNode),
202}
203
204/// Selects the graph against which the following query runs.
205#[derive(Clone, Debug, PartialEq, Eq, Hash)]
206#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
207pub struct UseClause {
208    pub graph: Expr,
209}
210
211/// A `MATCH` clause.
212#[derive(Clone, Debug, PartialEq, Eq, Hash)]
213#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
214pub struct MatchClause {
215    pub optional: bool,
216    pub mode: Option<Node<PathMode>>,
217    pub pattern: Pattern,
218    pub hints: Vec<MatchHint>,
219    pub where_clause: Option<Expr>,
220}
221
222/// A planner hint attached to `MATCH`.
223pub type MatchHint = Node<MatchHintKind>;
224
225/// The form of a planner hint.
226#[non_exhaustive]
227#[derive(Clone, Debug, PartialEq, Eq, Hash)]
228#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
229pub enum MatchHintKind {
230    Index {
231        variable: Name,
232        label: Name,
233        properties: Vec<Name>,
234        seek: bool,
235    },
236    Scan {
237        variable: Name,
238        label: Name,
239    },
240    Join {
241        variables: Vec<Name>,
242    },
243}
244
245/// Expands a list expression into rows.
246#[derive(Clone, Debug, PartialEq, Eq, Hash)]
247#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
248pub struct UnwindClause {
249    pub expression: Expr,
250    pub variable: Name,
251}
252
253/// Introduces one or more variable bindings.
254#[derive(Clone, Debug, PartialEq, Eq, Hash)]
255#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
256pub struct LetClause {
257    pub bindings: Vec<Binding>,
258}
259
260/// An expression bound to a variable.
261#[derive(Clone, Debug, PartialEq, Eq, Hash)]
262#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
263pub struct Binding {
264    pub variable: Name,
265    pub expression: Expr,
266    pub span: Span,
267}
268
269/// Creates graph elements described by a pattern.
270#[derive(Clone, Debug, PartialEq, Eq, Hash)]
271#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
272pub struct CreateClause {
273    pub pattern: Pattern,
274}
275
276/// Inserts graph elements using GQL-aligned pattern syntax.
277#[derive(Clone, Debug, PartialEq, Eq, Hash)]
278#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
279pub struct InsertClause {
280    pub pattern: Pattern,
281}
282
283/// Matches or creates a single pattern and applies conditional updates.
284#[derive(Clone, Debug, PartialEq, Eq, Hash)]
285#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
286pub struct MergeClause {
287    pub pattern: PatternPart,
288    pub actions: Vec<MergeAction>,
289}
290
291/// An `ON MATCH` or `ON CREATE` action.
292#[derive(Clone, Debug, PartialEq, Eq, Hash)]
293#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
294pub struct MergeAction {
295    pub trigger: Node<MergeTrigger>,
296    pub set: SetClause,
297    pub span: Span,
298}
299
300/// The event that triggers a merge action.
301#[non_exhaustive]
302#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
303#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
304pub enum MergeTrigger {
305    Match,
306    Create,
307}
308
309/// Deletes values or graph elements.
310#[derive(Clone, Debug, PartialEq, Eq, Hash)]
311#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
312pub struct DeleteClause {
313    pub mode: Node<DeleteMode>,
314    pub expressions: Vec<Expr>,
315}
316
317/// Relationship handling for a delete operation.
318#[non_exhaustive]
319#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
320#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
321pub enum DeleteMode {
322    Normal,
323    Detach,
324    Nodetach,
325}
326
327/// A collection of assignments following `SET`.
328#[derive(Clone, Debug, PartialEq, Eq, Hash)]
329#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
330pub struct SetClause {
331    pub items: Vec<SetItem>,
332}
333
334/// A single `SET` assignment.
335pub type SetItem = Node<SetItemKind>;
336
337/// The form of an assignment.
338#[non_exhaustive]
339#[derive(Clone, Debug, PartialEq, Eq, Hash)]
340#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
341pub enum SetItemKind {
342    Property {
343        target: Expr,
344        value: Expr,
345    },
346    ReplaceProperties {
347        target: Name,
348        value: Expr,
349    },
350    MergeProperties {
351        target: Name,
352        value: Expr,
353    },
354    Labels {
355        target: Name,
356        labels: LabelExpression,
357    },
358}
359
360/// A collection of removals following `REMOVE`.
361#[derive(Clone, Debug, PartialEq, Eq, Hash)]
362#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
363pub struct RemoveClause {
364    pub items: Vec<RemoveItem>,
365}
366
367/// A single `REMOVE` operation.
368pub type RemoveItem = Node<RemoveItemKind>;
369
370/// The form of a removal.
371#[non_exhaustive]
372#[derive(Clone, Debug, PartialEq, Eq, Hash)]
373#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
374pub enum RemoveItemKind {
375    Property(Expr),
376    Labels {
377        target: Name,
378        labels: LabelExpression,
379    },
380}
381
382/// Applies updating clauses for each item in a list.
383#[derive(Clone, Debug, PartialEq, Eq, Hash)]
384#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
385pub struct ForeachClause {
386    pub variable: Name,
387    pub list: Expr,
388    pub clauses: Vec<Clause>,
389}
390
391/// Loads delimited records from a URL expression.
392#[derive(Clone, Debug, PartialEq, Eq, Hash)]
393#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
394pub struct LoadCsvClause {
395    pub with_headers: bool,
396    pub source: Expr,
397    pub variable: Name,
398    pub field_terminator: Option<Node<StringLiteral>>,
399}
400
401/// Invokes a procedure or a subquery.
402#[derive(Clone, Debug, PartialEq, Eq, Hash)]
403#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
404pub struct CallClause {
405    pub optional: bool,
406    pub target: CallTarget,
407    pub yield_clause: Option<YieldClause>,
408}
409
410/// The target of a `CALL` clause.
411#[non_exhaustive]
412#[derive(Clone, Debug, PartialEq, Eq, Hash)]
413#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
414pub enum CallTarget {
415    Procedure {
416        name: QualifiedName,
417        arguments: Option<Vec<Expr>>,
418    },
419    Subquery {
420        scope: Option<SubqueryScope>,
421        query: Box<Query>,
422        in_transactions: Option<Box<InTransactions>>,
423    },
424}
425
426/// Variables imported into a `CALL { ... }` subquery.
427#[derive(Clone, Debug, PartialEq, Eq, Hash)]
428#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
429pub struct SubqueryScope {
430    pub import_all: bool,
431    pub variables: Vec<Name>,
432    pub span: Span,
433}
434
435/// Batched transaction behavior for a subquery call.
436#[derive(Clone, Debug, PartialEq, Eq, Hash)]
437#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
438pub struct InTransactions {
439    pub rows: Option<Expr>,
440    pub on_error: Option<Node<TransactionErrorBehavior>>,
441    pub report_status_as: Option<Name>,
442    pub span: Span,
443}
444
445/// Error handling for `CALL { ... } IN TRANSACTIONS`.
446#[non_exhaustive]
447#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
448#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
449pub enum TransactionErrorBehavior {
450    Continue,
451    Break,
452    Fail,
453}
454
455/// Selects values produced by a procedure call.
456#[derive(Clone, Debug, PartialEq, Eq, Hash)]
457#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
458pub struct YieldClause {
459    pub all: bool,
460    pub items: Vec<ProjectionItem>,
461    pub where_clause: Option<Expr>,
462    pub span: Span,
463}
464
465/// Projects intermediate values and continues a query.
466#[derive(Clone, Debug, PartialEq, Eq, Hash)]
467#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
468pub struct WithClause {
469    pub projection: ProjectionClause,
470    pub where_clause: Option<Expr>,
471}
472
473/// Produces the final rows from a query.
474#[derive(Clone, Debug, PartialEq, Eq, Hash)]
475#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
476pub struct ReturnClause {
477    pub projection: ProjectionClause,
478}
479
480/// A projection body shared by `RETURN`, `WITH`, and GQL-aligned `SELECT`.
481#[derive(Clone, Debug, PartialEq, Eq, Hash)]
482#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
483pub struct ProjectionClause {
484    /// An explicitly written `ALL` or `DISTINCT` modifier.
485    pub quantifier: Option<Node<SetQuantifier>>,
486    pub items: Vec<ProjectionItem>,
487    pub order_by: Option<OrderBy>,
488    pub offset: Option<Expr>,
489    pub skip: Option<Expr>,
490    pub limit: Option<Expr>,
491    pub span: Span,
492}
493
494/// One expression or wildcard in a projection.
495pub type ProjectionItem = Node<ProjectionItemKind>;
496
497/// The form of a projection item.
498#[non_exhaustive]
499#[derive(Clone, Debug, PartialEq, Eq, Hash)]
500#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
501pub enum ProjectionItemKind {
502    Wildcard,
503    Expression {
504        expression: Expr,
505        alias: Option<Name>,
506    },
507}
508
509/// Sort specifications following `ORDER BY`.
510#[derive(Clone, Debug, PartialEq, Eq, Hash)]
511#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
512pub struct OrderBy {
513    pub items: Vec<SortItem>,
514    pub span: Span,
515}
516
517/// One expression and its requested ordering.
518#[derive(Clone, Debug, PartialEq, Eq, Hash)]
519#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
520pub struct SortItem {
521    pub expression: Expr,
522    pub direction: Option<Node<SortDirection>>,
523    pub nulls: Option<Node<NullOrder>>,
524    pub span: Span,
525}
526
527/// Sort direction.
528#[non_exhaustive]
529#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
530#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
531pub enum SortDirection {
532    Ascending,
533    Descending,
534}
535
536/// Placement of null values in sorted output.
537#[non_exhaustive]
538#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
539#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
540pub enum NullOrder {
541    First,
542    Last,
543}
544
545/// Keeps rows satisfying an expression.
546#[derive(Clone, Debug, PartialEq, Eq, Hash)]
547#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
548pub struct FilterClause {
549    pub predicate: Expr,
550}
551
552/// A graph pattern.
553#[derive(Clone, Debug, PartialEq, Eq, Hash)]
554#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
555pub struct Pattern {
556    pub parts: Vec<PatternPart>,
557    pub span: Span,
558}
559
560/// A selected path pattern and optional path-variable binding.
561pub type PatternPart = Node<PatternPartKind>;
562
563/// The contents of a pattern part.
564#[derive(Clone, Debug, PartialEq, Eq, Hash)]
565#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
566pub struct PatternPartKind {
567    pub binding: Option<Name>,
568    pub selector: Option<Node<PathSelector>>,
569    pub path: PathPattern,
570}
571
572/// A path pattern composed from node, relationship, and grouped factors.
573pub type PathPattern = Node<PathPatternKind>;
574
575/// Ordered factors in a path pattern.
576#[derive(Clone, Debug, PartialEq, Eq, Hash)]
577#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
578pub struct PathPatternKind {
579    pub factors: Vec<PathFactor>,
580}
581
582/// One factor in a path pattern.
583pub type PathFactor = Node<PathFactorKind>;
584
585/// The form of a path factor.
586#[non_exhaustive]
587#[derive(Clone, Debug, PartialEq, Eq, Hash)]
588#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
589pub enum PathFactorKind {
590    Node(NodePattern),
591    /// A node pattern followed by a graph-pattern quantifier.
592    QuantifiedNode {
593        pattern: NodePattern,
594        quantifier: Quantifier,
595    },
596    Relationship(RelationshipPattern),
597    Parenthesized {
598        pattern: Box<PathPattern>,
599        where_clause: Option<Box<Expr>>,
600        quantifier: Option<Quantifier>,
601    },
602    /// A parenthesized path factor with a subpath-variable binding.
603    Subpath {
604        binding: Name,
605        pattern: Box<PathPattern>,
606        where_clause: Option<Box<Expr>>,
607        quantifier: Option<Quantifier>,
608    },
609    /// A legacy `shortestPath(...)` or `allShortestPaths(...)` path factor.
610    LegacyShortest {
611        all: bool,
612        pattern: Box<PathPattern>,
613    },
614    Error(ErrorNode),
615}
616
617/// A node pattern `(variable:Label {properties})`.
618#[derive(Clone, Debug, PartialEq, Eq, Hash)]
619#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
620pub struct NodePattern {
621    pub variable: Option<Name>,
622    pub labels: Option<LabelExpression>,
623    pub properties: Option<Box<Expr>>,
624    pub where_clause: Option<Box<Expr>>,
625}
626
627/// A relationship pattern between two nodes.
628#[derive(Clone, Debug, PartialEq, Eq, Hash)]
629#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
630pub struct RelationshipPattern {
631    pub direction: Node<RelationshipDirection>,
632    pub variable: Option<Name>,
633    pub labels: Option<LabelExpression>,
634    /// A legacy variable-length relationship quantifier written inside `[]`.
635    pub legacy_quantifier: Option<Quantifier>,
636    /// A graph-pattern quantifier written after the relationship pattern.
637    pub graph_quantifier: Option<Quantifier>,
638    pub properties: Option<Box<Expr>>,
639    pub where_clause: Option<Box<Expr>>,
640}
641
642/// Direction indicated by a relationship pattern's arrows.
643#[non_exhaustive]
644#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
645#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
646pub enum RelationshipDirection {
647    Left,
648    Right,
649    Undirected,
650    Both,
651}
652
653/// Repetition applied to a node, relationship, or parenthesized path.
654#[derive(Clone, Debug, PartialEq, Eq, Hash)]
655#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
656pub struct Quantifier {
657    pub kind: QuantifierKind,
658    pub span: Span,
659}
660
661/// A path repetition form. Bounds retain their original decimal spelling.
662#[non_exhaustive]
663#[derive(Clone, Debug, PartialEq, Eq, Hash)]
664#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
665pub enum QuantifierKind {
666    ZeroOrMore,
667    OneOrMore,
668    Optional,
669    Fixed(String),
670    Range {
671        lower: Option<String>,
672        upper: Option<String>,
673    },
674}
675
676/// Restrictions on repeated elements in a path.
677#[non_exhaustive]
678#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
679#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
680pub enum PathMode {
681    Walk,
682    Trail,
683    Simple,
684    Acyclic,
685}
686
687/// Selection applied to matching paths.
688#[non_exhaustive]
689#[derive(Clone, Debug, PartialEq, Eq, Hash)]
690#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
691pub enum PathSelector {
692    All,
693    Any { count: Option<String> },
694    AnyShortest,
695    AllShortest,
696    Shortest { count: Option<String>, groups: bool },
697}
698
699/// A label/type boolean expression.
700pub type LabelExpression = Node<LabelExpressionKind>;
701
702/// The form of a label/type boolean expression.
703#[non_exhaustive]
704#[derive(Clone, Debug, PartialEq, Eq, Hash)]
705#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
706pub enum LabelExpressionKind {
707    Name(Name),
708    Wildcard,
709    Not(Box<LabelExpression>),
710    And(Vec<LabelExpression>),
711    Or(Vec<LabelExpression>),
712    Parenthesized(Box<LabelExpression>),
713    Error(ErrorNode),
714}
715
716/// An expression.
717pub type Expr = Node<ExprKind>;
718
719/// Any expression in openCypher 2024.3.
720#[non_exhaustive]
721#[derive(Clone, Debug, PartialEq, Eq, Hash)]
722#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
723pub enum ExprKind {
724    Literal(Literal),
725    Variable(Name),
726    Parameter(Parameter),
727    Wildcard,
728    List(Vec<Expr>),
729    Map(Vec<MapEntry>),
730    MapProjection(MapProjection),
731    Unary {
732        operator: Node<UnaryOperator>,
733        operand: Box<Expr>,
734    },
735    Binary {
736        left: Box<Expr>,
737        operator: Node<BinaryOperator>,
738        right: Box<Expr>,
739    },
740    Is {
741        expression: Box<Expr>,
742        negated: bool,
743        predicate: IsPredicate,
744    },
745    Property {
746        expression: Box<Expr>,
747        key: Name,
748    },
749    DynamicProperty {
750        expression: Box<Expr>,
751        key: Box<Expr>,
752    },
753    Index {
754        expression: Box<Expr>,
755        index: Box<Expr>,
756    },
757    Slice {
758        expression: Box<Expr>,
759        lower: Option<Box<Expr>>,
760        upper: Option<Box<Expr>>,
761    },
762    Function(FunctionInvocation),
763    Case(CaseExpression),
764    ListComprehension(ListComprehension),
765    PatternComprehension(PatternComprehension),
766    Reduce(ReduceExpression),
767    QuantifiedPredicate(QuantifiedPredicate),
768    Subquery(SubqueryExpression),
769    Pattern(Pattern),
770    Parenthesized(Box<Expr>),
771    Error(ErrorNode),
772}
773
774/// A prefix operator.
775#[non_exhaustive]
776#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
777#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
778pub enum UnaryOperator {
779    Plus,
780    Minus,
781    Not,
782}
783
784/// An infix operator, ordered by the grammar's precedence rules.
785#[non_exhaustive]
786#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
787#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
788pub enum BinaryOperator {
789    Or,
790    Xor,
791    And,
792    Equal,
793    NotEqual,
794    Less,
795    LessEqual,
796    Greater,
797    GreaterEqual,
798    RegexMatch,
799    In,
800    StartsWith,
801    EndsWith,
802    Contains,
803    Add,
804    Subtract,
805    Multiply,
806    Divide,
807    Remainder,
808    Power,
809    Concat,
810}
811
812/// A predicate following `IS` or `IS NOT`.
813#[non_exhaustive]
814#[derive(Clone, Debug, PartialEq, Eq, Hash)]
815#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
816pub enum IsPredicate {
817    Null,
818    Typed(TypeRef),
819    Normalized(Option<Node<NormalizationForm>>),
820    Label(LabelExpression),
821}
822
823/// Unicode normalization requested by an expression predicate.
824#[non_exhaustive]
825#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
826#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
827pub enum NormalizationForm {
828    Nfc,
829    Nfd,
830    Nfkc,
831    Nfkd,
832}
833
834/// A function call.
835#[derive(Clone, Debug, PartialEq, Eq, Hash)]
836#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
837pub struct FunctionInvocation {
838    pub name: QualifiedName,
839    /// An explicitly written `ALL` or `DISTINCT` modifier.
840    pub quantifier: Option<Node<SetQuantifier>>,
841    pub arguments: Vec<Expr>,
842}
843
844/// A searched or simple `CASE` expression.
845#[derive(Clone, Debug, PartialEq, Eq, Hash)]
846#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
847pub struct CaseExpression {
848    pub operand: Option<Box<Expr>>,
849    pub alternatives: Vec<CaseAlternative>,
850    pub else_expression: Option<Box<Expr>>,
851}
852
853/// One `WHEN ... THEN ...` arm.
854#[derive(Clone, Debug, PartialEq, Eq, Hash)]
855#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
856pub struct CaseAlternative {
857    /// One or more operands following `WHEN`.
858    pub when: Vec<Expr>,
859    pub then: Expr,
860    pub span: Span,
861}
862
863/// A list comprehension.
864#[derive(Clone, Debug, PartialEq, Eq, Hash)]
865#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
866pub struct ListComprehension {
867    pub variable: Name,
868    pub list: Box<Expr>,
869    pub predicate: Option<Box<Expr>>,
870    pub projection: Option<Box<Expr>>,
871}
872
873/// A pattern comprehension.
874#[derive(Clone, Debug, PartialEq, Eq, Hash)]
875#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
876pub struct PatternComprehension {
877    pub binding: Option<Name>,
878    pub pattern: Pattern,
879    pub predicate: Option<Box<Expr>>,
880    pub projection: Box<Expr>,
881}
882
883/// A left fold over a list.
884#[derive(Clone, Debug, PartialEq, Eq, Hash)]
885#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
886pub struct ReduceExpression {
887    pub accumulator: Name,
888    pub initial: Box<Expr>,
889    pub variable: Name,
890    pub list: Box<Expr>,
891    pub expression: Box<Expr>,
892}
893
894/// An `ALL`, `ANY`, `NONE`, or `SINGLE` predicate over a list.
895#[derive(Clone, Debug, PartialEq, Eq, Hash)]
896#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
897pub struct QuantifiedPredicate {
898    pub kind: Node<QuantifiedPredicateKind>,
899    pub variable: Name,
900    pub list: Box<Expr>,
901    pub predicate: Box<Expr>,
902}
903
904/// Quantification applied to a list predicate.
905#[non_exhaustive]
906#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
907#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
908pub enum QuantifiedPredicateKind {
909    All,
910    Any,
911    None,
912    Single,
913}
914
915/// A query nested inside an expression.
916#[derive(Clone, Debug, PartialEq, Eq, Hash)]
917#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
918pub struct SubqueryExpression {
919    pub kind: Node<SubqueryExpressionKind>,
920    pub query: Box<Query>,
921}
922
923/// The value produced by a subquery expression.
924#[non_exhaustive]
925#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
926#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
927pub enum SubqueryExpressionKind {
928    Exists,
929    Count,
930    Collect,
931}
932
933/// A map entry.
934#[derive(Clone, Debug, PartialEq, Eq, Hash)]
935#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
936pub struct MapEntry {
937    pub key: Name,
938    pub value: Expr,
939    pub span: Span,
940}
941
942/// A projection derived from an existing map or graph element.
943#[derive(Clone, Debug, PartialEq, Eq, Hash)]
944#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
945pub struct MapProjection {
946    pub base: Box<Expr>,
947    pub items: Vec<MapProjectionItem>,
948}
949
950/// One item in a map projection.
951pub type MapProjectionItem = Node<MapProjectionItemKind>;
952
953/// The form of a map projection item.
954#[non_exhaustive]
955#[derive(Clone, Debug, PartialEq, Eq, Hash)]
956#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
957pub enum MapProjectionItemKind {
958    Property(Name),
959    AllProperties,
960    Variable(Name),
961    Entry(MapEntry),
962}
963
964/// A literal expression.
965pub type Literal = Node<LiteralKind>;
966
967/// A literal value as represented in source.
968#[non_exhaustive]
969#[derive(Clone, Debug, PartialEq, Eq, Hash)]
970#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
971pub enum LiteralKind {
972    Null,
973    Boolean(bool),
974    Integer(IntegerLiteral),
975    Float(FloatLiteral),
976    String(StringLiteral),
977}
978
979/// An integer spelling and its radix.
980#[derive(Clone, Debug, PartialEq, Eq, Hash)]
981#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
982pub struct IntegerLiteral {
983    /// Digits exactly as written, including any radix prefix.
984    pub text: String,
985    pub radix: IntegerRadix,
986}
987
988/// The radix of an integer literal.
989#[non_exhaustive]
990#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
991#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
992pub enum IntegerRadix {
993    Decimal,
994    Hexadecimal,
995    Octal,
996}
997
998/// A floating-point spelling preserved without rounding.
999#[derive(Clone, Debug, PartialEq, Eq, Hash)]
1000#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1001pub struct FloatLiteral {
1002    pub text: String,
1003}
1004
1005/// A decoded string value and its delimiter style.
1006#[derive(Clone, Debug, PartialEq, Eq, Hash)]
1007#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1008pub struct StringLiteral {
1009    pub value: String,
1010    pub quote: QuoteStyle,
1011}
1012
1013/// Quote style used for a string literal.
1014#[non_exhaustive]
1015#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
1016#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1017pub enum QuoteStyle {
1018    Single,
1019    Double,
1020}
1021
1022/// A parameter reference without its leading `$`.
1023#[derive(Clone, Debug, PartialEq, Eq, Hash)]
1024#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1025pub struct Parameter {
1026    pub name: ParameterName,
1027}
1028
1029/// The form of a parameter name.
1030#[non_exhaustive]
1031#[derive(Clone, Debug, PartialEq, Eq, Hash)]
1032#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1033pub enum ParameterName {
1034    Named(String),
1035    Positional(String),
1036}
1037
1038/// An identifier and whether it was backtick escaped.
1039#[derive(Clone, Debug, PartialEq, Eq, Hash)]
1040#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1041pub struct Identifier {
1042    /// Decoded, case-preserving identifier text.
1043    pub text: String,
1044    /// Whether the source used backtick delimiters.
1045    pub escaped: bool,
1046}
1047
1048impl Identifier {
1049    /// Creates an identifier.
1050    #[must_use]
1051    pub fn new(text: impl Into<String>, escaped: bool) -> Self {
1052        Self {
1053            text: text.into(),
1054            escaped,
1055        }
1056    }
1057}
1058
1059/// A spanned identifier.
1060pub type Name = Node<Identifier>;
1061
1062/// A dot-separated name such as a procedure or function name.
1063#[derive(Clone, Debug, PartialEq, Eq, Hash)]
1064#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1065pub struct QualifiedName {
1066    pub parts: Vec<Name>,
1067    pub span: Span,
1068}
1069
1070/// A value type used by typed predicates.
1071pub type TypeRef = Node<TypeRefKind>;
1072
1073/// A type expression and its nullability marker.
1074#[derive(Clone, Debug, PartialEq, Eq, Hash)]
1075#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1076pub struct TypeRefKind {
1077    pub value: ValueType,
1078    pub nullable: Option<bool>,
1079}
1080
1081/// A value type named by the grammar.
1082#[non_exhaustive]
1083#[derive(Clone, Debug, PartialEq, Eq, Hash)]
1084#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1085pub enum ValueType {
1086    Nothing,
1087    Null,
1088    Boolean,
1089    String,
1090    Integer,
1091    Float,
1092    Decimal,
1093    Number,
1094    Date,
1095    LocalTime,
1096    ZonedTime,
1097    LocalDateTime,
1098    ZonedDateTime,
1099    Duration,
1100    Point,
1101    Node,
1102    Relationship,
1103    Map,
1104    Path,
1105    List(Box<TypeRef>),
1106    Any,
1107    Named(QualifiedName),
1108}
1109
1110/// A marker inserted where error recovery skipped malformed syntax.
1111#[derive(Clone, Debug, Default, PartialEq, Eq, Hash)]
1112#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1113pub struct ErrorNode;