1#![allow(missing_docs)]
13
14use graphforge_core::Span;
15use serde::{Deserialize, Serialize};
16use std::collections::HashMap;
17
18#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, Default)]
24pub enum DialectVersion {
25 #[default]
27 OpenCypher9,
28}
29
30#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
34pub struct AstQuery {
35 pub dialect: DialectVersion,
37 pub clauses: Vec<AstClause>,
39 pub span: Span,
41}
42
43#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
49#[non_exhaustive]
50pub enum AstClause {
51 Match(MatchClause),
52 OptionalMatch(MatchClause),
53 Where(WhereClause),
54 With(WithClause),
55 Return(ReturnClause),
56 Create(CreateClause),
57 Merge(MergeClause),
58 Set(SetClause),
59 Remove(RemoveClause),
60 Delete(DeleteClause),
61 Unwind(UnwindClause),
62 Call(CallClause),
63 Union(UnionClause),
64}
65
66impl AstClause {
67 #[must_use]
69 pub fn span(&self) -> Span {
70 match self {
71 Self::Match(c) | Self::OptionalMatch(c) => c.span,
72 Self::Where(c) => c.span,
73 Self::With(c) => c.span,
74 Self::Return(c) => c.span,
75 Self::Create(c) => c.span,
76 Self::Merge(c) => c.span,
77 Self::Set(c) => c.span,
78 Self::Remove(c) => c.span,
79 Self::Delete(c) => c.span,
80 Self::Unwind(c) => c.span,
81 Self::Call(c) => c.span,
82 Self::Union(c) => c.span,
83 }
84 }
85}
86
87#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
93pub struct MatchClause {
94 pub patterns: Vec<PathPattern>,
96 pub where_clause: Option<WhereClause>,
98 pub span: Span,
99}
100
101#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
107pub struct WhereClause {
108 pub predicate: Expr,
109 pub span: Span,
110}
111
112#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
118pub struct WithClause {
119 pub distinct: bool,
120 pub items: Vec<ReturnItem>,
121 pub order_by: Option<OrderByClause>,
122 pub skip: Option<Expr>,
123 pub limit: Option<Expr>,
124 pub where_clause: Option<WhereClause>,
125 pub span: Span,
126}
127
128#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
134pub struct ReturnClause {
135 pub distinct: bool,
136 pub items: Vec<ReturnItem>,
137 pub order_by: Option<OrderByClause>,
138 pub skip: Option<Expr>,
139 pub limit: Option<Expr>,
140 pub span: Span,
141}
142
143#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
145pub struct ReturnItem {
146 pub expr: Expr,
147 pub alias: Option<String>,
149 #[serde(default)]
155 pub display: Option<String>,
156 pub span: Span,
157}
158
159#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
165pub struct OrderByClause {
166 pub items: Vec<SortItem>,
167 pub span: Span,
168}
169
170#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
172pub struct SortItem {
173 pub expr: Expr,
174 pub order: SortOrder,
175 pub span: Span,
176}
177
178#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, Default)]
180pub enum SortOrder {
181 #[default]
182 Ascending,
183 Descending,
184}
185
186#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
192pub struct CreateClause {
193 pub patterns: Vec<PathPattern>,
194 pub span: Span,
195}
196
197#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
199pub struct MergeClause {
200 pub pattern: PathPattern,
201 pub on_create: Vec<SetItem>,
202 pub on_match: Vec<SetItem>,
203 pub span: Span,
204}
205
206#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
212pub struct SetClause {
213 pub items: Vec<SetItem>,
214 pub span: Span,
215}
216
217#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
219#[non_exhaustive]
220pub enum SetItem {
221 Property {
223 target: PropertyAccess,
224 value: Expr,
225 span: Span,
226 },
227 PropertyMerge { var: String, map: Expr, span: Span },
229 PropertyReplace { var: String, map: Expr, span: Span },
231 Label {
233 var: String,
234 labels: Vec<String>,
235 span: Span,
236 },
237}
238
239#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
241pub struct RemoveClause {
242 pub items: Vec<RemoveItem>,
243 pub span: Span,
244}
245
246#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
248#[non_exhaustive]
249pub enum RemoveItem {
250 Property(PropertyAccess, Span),
252 Label {
254 var: String,
255 labels: Vec<String>,
256 span: Span,
257 },
258}
259
260#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
262pub struct DeleteClause {
263 pub detach: bool,
264 pub exprs: Vec<Expr>,
265 pub span: Span,
266}
267
268#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
274pub struct UnwindClause {
275 pub expr: Expr,
276 pub alias: String,
277 pub span: Span,
278}
279
280#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
286pub struct CallClause {
287 pub procedure: Vec<String>,
288 pub args: Vec<Expr>,
289 #[serde(default)]
291 pub args_explicit: bool,
292 pub yield_items: Vec<ReturnItem>,
293 pub span: Span,
294}
295
296#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
302pub struct UnionClause {
303 pub all: bool,
304 pub span: Span,
305}
306
307#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
313pub struct PathPattern {
314 pub var: Option<String>,
316 pub elements: Vec<PathElement>,
319 pub span: Span,
320}
321
322#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
324pub enum PathElement {
325 Node(NodePattern),
326 Rel(RelPattern),
327}
328
329#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
331pub struct NodePattern {
332 pub var: Option<String>,
334 pub labels: Vec<String>,
336 pub properties: Option<Expr>,
338 pub span: Span,
339}
340
341#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
343pub struct RelPattern {
344 pub var: Option<String>,
345 pub types: Vec<String>,
347 pub direction: Direction,
348 pub min_hops: Option<u32>,
350 pub max_hops: Option<u32>,
352 pub properties: Option<Expr>,
353 pub span: Span,
354}
355
356#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
358pub enum Direction {
359 Out,
361 In,
363 Undirected,
365}
366
367#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
376#[non_exhaustive]
377pub enum Expr {
378 Literal(Literal),
380 Var(VarRef),
382 Property(PropertyAccess),
384 BinaryOp(BinaryOp),
386 UnaryOp(UnaryOp),
388 FunctionCall(FunctionCall),
390 List(ListLiteral),
392 Map(MapLiteral),
394 Param(ParamRef),
396 Case(CaseExpr),
398 ListComprehension(ListComprehension),
400 Quantifier(Quantifier),
402 PatternComprehension(PatternComprehension),
404 PatternPredicate(PatternPredicate),
406 ExistentialSubquery(ExistentialSubquery),
409 LabelPredicate(LabelPredicate),
411 IsNull {
413 expr: Box<Expr>,
414 negated: bool,
415 span: Span,
416 },
417 InList {
419 expr: Box<Expr>,
420 list: Box<Expr>,
421 negated: bool,
422 span: Span,
423 },
424 StringOp {
426 expr: Box<Expr>,
427 op: StringOpKind,
428 pattern: Box<Expr>,
429 span: Span,
430 },
431 RegexMatch {
433 expr: Box<Expr>,
434 pattern: Box<Expr>,
435 span: Span,
436 },
437 Parenthesized { inner: Box<Expr>, span: Span },
439}
440
441impl Expr {
442 #[must_use]
444 pub fn span(&self) -> Span {
445 match self {
446 Self::Literal(l) => l.span(),
447 Self::Var(v) => v.span,
448 Self::Property(p) => p.span,
449 Self::BinaryOp(b) => b.span,
450 Self::UnaryOp(u) => u.span,
451 Self::FunctionCall(f) => f.span,
452 Self::List(l) => l.span,
453 Self::Map(m) => m.span,
454 Self::Param(p) => p.span,
455 Self::Case(c) => c.span,
456 Self::ListComprehension(lc) => lc.span,
457 Self::Quantifier(q) => q.span,
458 Self::PatternComprehension(pc) => pc.span,
459 Self::PatternPredicate(pp) => pp.span,
460 Self::ExistentialSubquery(es) => es.span,
461 Self::LabelPredicate(lp) => lp.span,
462 Self::IsNull { span, .. }
463 | Self::InList { span, .. }
464 | Self::StringOp { span, .. }
465 | Self::RegexMatch { span, .. }
466 | Self::Parenthesized { span, .. } => *span,
467 }
468 }
469}
470
471#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
477pub enum Literal {
478 Int(i64, Span),
479 Float(f64, Span),
480 Str(String, Span),
481 Bool(bool, Span),
482 Null(Span),
483}
484
485impl Literal {
486 #[must_use]
487 pub fn span(&self) -> Span {
488 match self {
489 Self::Int(_, s)
490 | Self::Float(_, s)
491 | Self::Str(_, s)
492 | Self::Bool(_, s)
493 | Self::Null(s) => *s,
494 }
495 }
496}
497
498#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
504pub struct VarRef {
505 pub name: String,
506 pub span: Span,
507}
508
509#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
511pub struct PropertyAccess {
512 pub object: Box<Expr>,
513 pub key: String,
514 pub span: Span,
515}
516
517#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
519pub struct ParamRef {
520 pub name: String,
521 pub span: Span,
522}
523
524#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
526pub struct LabelPredicate {
527 pub var: String,
528 pub labels: Vec<String>,
529 pub span: Span,
530}
531
532#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
538pub struct BinaryOp {
539 pub op: BinaryOpKind,
540 pub left: Box<Expr>,
541 pub right: Box<Expr>,
542 pub span: Span,
543}
544
545#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
547pub enum BinaryOpKind {
548 Eq,
550 Neq,
551 Lt,
552 Lte,
553 Gt,
554 Gte,
555 And,
557 Or,
558 Xor,
559 Add,
561 Sub,
562 Mul,
563 Div,
564 Mod,
565 Pow,
566 Concat,
568}
569
570#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
572pub struct UnaryOp {
573 pub op: UnaryOpKind,
574 pub expr: Box<Expr>,
575 pub span: Span,
576}
577
578#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
580pub enum UnaryOpKind {
581 Not,
582 Neg,
583}
584
585#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
587pub struct FunctionCall {
588 pub name: Vec<String>,
590 pub distinct: bool,
591 pub star: bool,
593 pub args: Vec<Expr>,
594 pub span: Span,
595}
596
597#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
599pub struct ListLiteral {
600 pub elements: Vec<Expr>,
601 pub span: Span,
602}
603
604#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
606pub struct MapLiteral {
607 pub entries: HashMap<String, Expr>,
608 #[serde(default)]
611 pub key_spans: HashMap<String, Span>,
612 pub span: Span,
613}
614
615#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
621pub struct CaseExpr {
622 pub subject: Option<Box<Expr>>,
624 pub when_clauses: Vec<WhenClause>,
625 pub else_expr: Option<Box<Expr>>,
626 pub span: Span,
627}
628
629#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
631pub struct WhenClause {
632 pub condition: Expr,
633 pub result: Expr,
634 pub span: Span,
635}
636
637#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
643pub struct ListComprehension {
644 pub var: String,
645 pub list: Box<Expr>,
646 pub filter: Option<Box<Expr>>,
647 pub projection: Option<Box<Expr>>,
648 pub span: Span,
649}
650
651#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
653pub enum QuantifierKind {
654 All,
656 Any,
658 None,
660 Single,
662}
663
664#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
666pub struct Quantifier {
667 pub kind: QuantifierKind,
668 pub var: String,
669 pub list: Box<Expr>,
670 pub predicate: Box<Expr>,
671 pub span: Span,
672}
673
674#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
676pub struct PatternComprehension {
677 pub var: Option<String>,
678 pub pattern: PathPattern,
679 pub filter: Option<Box<Expr>>,
680 pub projection: Box<Expr>,
681 pub span: Span,
682}
683
684#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
686pub struct PatternPredicate {
687 pub pattern: PathPattern,
688 pub span: Span,
689}
690
691#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
693pub struct ExistentialSubquery {
694 pub body: ExistentialSubqueryBody,
695 pub span: Span,
696}
697
698#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
699pub enum ExistentialSubqueryBody {
700 Simple {
701 pattern: PathPattern,
702 filter: Option<Box<Expr>>,
703 },
704 Full(Box<AstQuery>),
705}
706
707#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
713pub enum StringOpKind {
714 StartsWith,
715 EndsWith,
716 Contains,
717}