1use smallvec::SmallVec;
2
3#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
4pub struct Span {
5 pub start: usize,
6 pub end: usize,
7}
8
9impl Span {
10 #[must_use]
11 pub const fn new(start: usize, end: usize) -> Self {
12 Self { start, end }
13 }
14}
15
16#[derive(Debug, Clone)]
17pub struct Document {
18 pub statement: Statement,
19 pub span: Span,
20}
21
22#[derive(Debug, Clone)]
23pub enum Statement {
24 Query(Query),
25 Schema(SchemaCommand),
26}
27
28#[derive(Debug, Clone)]
29pub enum SchemaCommand {
30 CreateIndex(CreateIndex),
31 DropIndex(DropIndex),
32 ShowIndexes(ShowIndexes),
33 CreateConstraint(CreateConstraint),
34 DropConstraint(DropConstraint),
35 ShowConstraints(ShowConstraints),
36}
37
38#[derive(Debug, Clone)]
39pub struct CreateConstraint {
40 pub name: ConstraintNameSpec,
41 pub if_not_exists: bool,
42 pub entity: IndexEntityKind,
43 pub variable: String,
45 pub label: String,
48 pub properties: Vec<String>,
49 pub kind: ConstraintKind,
50 pub span: Span,
51}
52
53#[derive(Debug, Clone)]
54pub struct DropConstraint {
55 pub name: ConstraintNameSpec,
56 pub if_exists: bool,
57 pub span: Span,
58}
59
60#[derive(Debug, Clone)]
61pub struct ShowConstraints {
62 pub pipeline: Option<ShowPipeline>,
63 pub span: Span,
64}
65
66#[derive(Debug, Clone)]
72pub struct ShowPipeline {
73 pub yield_part: ShowYield,
74 pub where_: Option<Expr>,
75 pub return_part: Option<ShowReturn>,
76 pub span: Span,
77}
78
79#[derive(Debug, Clone)]
80pub struct ShowYield {
81 pub star: bool,
83 pub items: Vec<YieldItem>,
85 pub order: Vec<SortItem>,
86 pub skip: Option<Expr>,
87 pub limit: Option<Expr>,
88 pub span: Span,
89}
90
91#[derive(Debug, Clone)]
92pub struct ShowReturn {
93 pub items: Vec<ProjectionItem>,
94 pub order: Vec<SortItem>,
95 pub skip: Option<Expr>,
96 pub limit: Option<Expr>,
97 pub span: Span,
98}
99
100#[derive(Debug, Clone, Copy, PartialEq, Eq)]
105pub enum IndexKindFilter {
106 All,
107 Range,
108 Text,
109 Point,
110 Lookup,
111 Fulltext,
112 Vector,
113}
114
115#[derive(Debug, Clone)]
116pub enum ConstraintNameSpec {
117 Literal(String),
118 Parameter(String),
119}
120
121#[derive(Debug, Clone, PartialEq)]
122pub enum ConstraintKind {
123 Unique,
125 Existence,
127 NodeKey,
129 RelationshipKey,
131 PropertyType(PropertyTypeExpr),
133}
134
135impl ConstraintKind {
136 #[must_use]
138 pub fn type_tag(&self, entity: IndexEntityKind) -> &'static str {
139 match (self, entity) {
140 (ConstraintKind::Unique, IndexEntityKind::Node) => "NODE_PROPERTY_UNIQUENESS",
141 (ConstraintKind::Unique, IndexEntityKind::Relationship) => {
142 "RELATIONSHIP_PROPERTY_UNIQUENESS"
143 }
144 (ConstraintKind::Existence, IndexEntityKind::Node) => "NODE_PROPERTY_EXISTENCE",
145 (ConstraintKind::Existence, IndexEntityKind::Relationship) => {
146 "RELATIONSHIP_PROPERTY_EXISTENCE"
147 }
148 (ConstraintKind::NodeKey, _) => "NODE_KEY",
149 (ConstraintKind::RelationshipKey, _) => "RELATIONSHIP_KEY",
150 (ConstraintKind::PropertyType(_), IndexEntityKind::Node) => "NODE_PROPERTY_TYPE",
151 (ConstraintKind::PropertyType(_), IndexEntityKind::Relationship) => {
152 "RELATIONSHIP_PROPERTY_TYPE"
153 }
154 }
155 }
156}
157
158#[derive(Debug, Clone, PartialEq)]
161pub struct PropertyTypeExpr {
162 pub alternatives: Vec<PropertyTypeTerm>,
163}
164
165#[derive(Debug, Clone, PartialEq)]
166pub enum PropertyTypeTerm {
167 Scalar(ScalarType),
168 List {
169 inner: Box<PropertyTypeTerm>,
170 not_null: bool,
175 },
176 Vector {
177 coord: VectorCoordType,
178 dimension: u32,
179 },
180}
181
182#[derive(Debug, Clone, Copy, PartialEq, Eq)]
183pub enum ScalarType {
184 Boolean,
185 String,
186 Integer,
187 Float,
188 Date,
189 LocalTime,
190 ZonedTime,
191 LocalDateTime,
192 ZonedDateTime,
193 Duration,
194 Point,
195 Map,
196 Any,
197}
198
199impl ScalarType {
200 #[must_use]
201 pub const fn as_str(self) -> &'static str {
202 match self {
203 ScalarType::Boolean => "BOOLEAN",
204 ScalarType::String => "STRING",
205 ScalarType::Integer => "INTEGER",
206 ScalarType::Float => "FLOAT",
207 ScalarType::Date => "DATE",
208 ScalarType::LocalTime => "LOCAL TIME",
209 ScalarType::ZonedTime => "ZONED TIME",
210 ScalarType::LocalDateTime => "LOCAL DATETIME",
211 ScalarType::ZonedDateTime => "ZONED DATETIME",
212 ScalarType::Duration => "DURATION",
213 ScalarType::Point => "POINT",
214 ScalarType::Map => "MAP",
215 ScalarType::Any => "ANY",
216 }
217 }
218}
219
220#[derive(Debug, Clone, Copy, PartialEq, Eq)]
221pub enum VectorCoordType {
222 Int8,
223 Int16,
224 Int32,
225 Int64,
226 Float32,
227 Float64,
228}
229
230impl VectorCoordType {
231 #[must_use]
232 pub const fn as_str(self) -> &'static str {
233 match self {
234 VectorCoordType::Int8 => "INT8",
235 VectorCoordType::Int16 => "INT16",
236 VectorCoordType::Int32 => "INT32",
237 VectorCoordType::Int64 => "INT64",
238 VectorCoordType::Float32 => "FLOAT32",
239 VectorCoordType::Float64 => "FLOAT64",
240 }
241 }
242}
243
244#[derive(Debug, Clone)]
245pub struct DropIndex {
246 pub name: IndexNameSpec,
247 pub if_exists: bool,
248 pub span: Span,
249}
250
251#[derive(Debug, Clone)]
252pub struct CreateIndex {
253 pub kind: IndexKind,
254 pub name: Option<IndexNameSpec>,
255 pub if_not_exists: bool,
256 pub entity: IndexEntityKind,
257 pub variable: String,
259 pub label: Option<String>,
264 pub additional_labels: Vec<String>,
267 pub properties: Vec<String>,
269 pub options: Option<IndexOptions>,
270 pub span: Span,
271}
272
273#[derive(Debug, Clone, Copy, PartialEq, Eq)]
274pub enum IndexKind {
275 Range,
276 Text,
277 Point,
278 Lookup,
279 Vector,
280 Fulltext,
281}
282
283impl IndexKind {
284 #[must_use]
285 pub const fn as_str(self) -> &'static str {
286 match self {
287 IndexKind::Range => "RANGE",
288 IndexKind::Text => "TEXT",
289 IndexKind::Point => "POINT",
290 IndexKind::Lookup => "LOOKUP",
291 IndexKind::Vector => "VECTOR",
292 IndexKind::Fulltext => "FULLTEXT",
293 }
294 }
295}
296
297#[derive(Debug, Clone, Copy, PartialEq, Eq)]
298pub enum IndexEntityKind {
299 Node,
300 Relationship,
301}
302
303impl IndexEntityKind {
304 #[must_use]
305 pub const fn as_str(self) -> &'static str {
306 match self {
307 IndexEntityKind::Node => "NODE",
308 IndexEntityKind::Relationship => "RELATIONSHIP",
309 }
310 }
311}
312
313#[derive(Debug, Clone)]
314pub enum IndexNameSpec {
315 Literal(String),
316 Parameter(String),
317}
318
319#[derive(Debug, Clone)]
320pub struct IndexOptions {
321 pub config: Vec<(String, Expr)>,
322 pub span: Span,
323}
324
325#[derive(Debug, Clone)]
326pub struct ShowIndexes {
327 pub filter: Option<IndexKindFilter>,
331 pub pipeline: Option<ShowPipeline>,
332 pub span: Span,
333}
334
335#[derive(Debug, Clone)]
336pub enum Query {
337 Regular(RegularQuery),
338 StandaloneCall(StandaloneCall),
339}
340
341#[derive(Debug, Clone)]
342pub struct RegularQuery {
343 pub head: SingleQuery,
344 pub unions: Vec<UnionPart>,
345 pub span: Span,
346}
347
348#[derive(Debug, Clone)]
349pub struct UnionPart {
350 pub all: bool,
351 pub query: SingleQuery,
352 pub span: Span,
353}
354
355#[derive(Debug, Clone)]
356pub enum SingleQuery {
357 SinglePart(SinglePartQuery),
358 MultiPart(MultiPartQuery),
359}
360
361#[derive(Debug, Clone)]
362pub struct SinglePartQuery {
363 pub reading_clauses: Vec<ReadingClause>,
364 pub updating_clauses: Vec<UpdatingClause>,
365 pub return_clause: Option<Return>,
366 pub span: Span,
367}
368
369#[derive(Debug, Clone)]
370pub struct MultiPartQuery {
371 pub parts: Vec<QueryPart>,
372 pub tail: Box<SinglePartQuery>,
373 pub span: Span,
374}
375
376#[derive(Debug, Clone)]
377pub struct QueryPart {
378 pub reading_clauses: Vec<ReadingClause>,
379 pub updating_clauses: Vec<UpdatingClause>,
380 pub with_clause: With,
381 pub span: Span,
382}
383
384#[derive(Debug, Clone)]
385pub enum ReadingClause {
386 Match(Match),
387 Unwind(Unwind),
388 InQueryCall(InQueryCall),
389 CallSubquery(CallSubquery),
390}
391
392#[derive(Debug, Clone)]
393pub struct CallSubquery {
394 pub body: Box<RegularQuery>,
395 pub span: Span,
396}
397
398#[derive(Debug, Clone)]
399pub enum UpdatingClause {
400 Create(Create),
401 Merge(Merge),
402 Delete(Delete),
403 Set(Set),
404 Remove(Remove),
405 Foreach(Foreach),
406}
407
408#[derive(Debug, Clone)]
409pub struct Match {
410 pub optional: bool,
411 pub pattern: Pattern,
412 pub where_: Option<Expr>,
413 pub span: Span,
414}
415
416#[derive(Debug, Clone)]
417pub struct Unwind {
418 pub expr: Expr,
419 pub alias: Variable,
420 pub span: Span,
421}
422
423#[derive(Debug, Clone)]
424pub struct Create {
425 pub pattern: Pattern,
426 pub span: Span,
427}
428
429#[derive(Debug, Clone)]
430pub struct Merge {
431 pub pattern_part: PatternPart,
432 pub actions: Vec<MergeAction>,
433 pub span: Span,
434}
435
436#[derive(Debug, Clone)]
437pub struct MergeAction {
438 pub on_match: bool,
439 pub set: Set,
440 pub span: Span,
441}
442
443#[derive(Debug, Clone)]
444pub struct Delete {
445 pub detach: bool,
446 pub expressions: Vec<Expr>,
447 pub span: Span,
448}
449
450#[derive(Debug, Clone)]
451pub struct Set {
452 pub items: Vec<SetItem>,
453 pub span: Span,
454}
455
456#[derive(Debug, Clone)]
457pub enum SetItem {
458 SetProperty {
459 target: Expr,
460 value: Expr,
461 span: Span,
462 },
463 SetVariable {
464 variable: Variable,
465 value: Expr,
466 span: Span,
467 },
468 MutateVariable {
469 variable: Variable,
470 value: Expr,
471 span: Span,
472 },
473 SetLabels {
474 variable: Variable,
475 labels: Vec<String>,
476 span: Span,
477 },
478}
479
480#[derive(Debug, Clone)]
481pub struct Remove {
482 pub items: Vec<RemoveItem>,
483 pub span: Span,
484}
485
486#[derive(Debug, Clone)]
491pub struct Foreach {
492 pub variable: Variable,
493 pub list: Expr,
494 pub body: Vec<UpdatingClause>,
495 pub span: Span,
496}
497
498#[derive(Debug, Clone)]
499pub enum RemoveItem {
500 Labels {
501 variable: Variable,
502 labels: Vec<String>,
503 span: Span,
504 },
505 Property {
506 expr: Expr,
507 span: Span,
508 },
509}
510
511#[derive(Debug, Clone)]
512pub struct InQueryCall {
513 pub procedure: ProcedureInvocation,
514 pub yield_items: Vec<YieldItem>,
515 pub where_: Option<Expr>,
516 pub span: Span,
517}
518
519#[derive(Debug, Clone)]
520pub struct StandaloneCall {
521 pub procedure: ProcedureInvocationKind,
522 pub yield_items: Vec<YieldItem>,
523 pub yield_all: bool,
524 pub span: Span,
525}
526
527#[derive(Debug, Clone)]
528pub enum ProcedureInvocationKind {
529 Explicit(ProcedureInvocation),
530 Implicit(ProcedureName),
531}
532
533#[derive(Debug, Clone)]
534pub struct ProcedureInvocation {
535 pub name: ProcedureName,
536 pub args: Vec<Expr>,
537 pub span: Span,
538}
539
540#[derive(Debug, Clone)]
541pub struct YieldItem {
542 pub field: Option<String>,
543 pub alias: Variable,
544 pub span: Span,
545}
546
547#[derive(Debug, Clone)]
548pub struct With {
549 pub body: ProjectionBody,
550 pub where_: Option<Expr>,
551 pub span: Span,
552}
553
554#[derive(Debug, Clone)]
555pub struct Return {
556 pub body: ProjectionBody,
557 pub span: Span,
558}
559
560#[derive(Debug, Clone)]
561pub struct ProjectionBody {
562 pub distinct: bool,
563 pub items: Vec<ProjectionItem>,
564 pub order: Vec<SortItem>,
565 pub skip: Option<Expr>,
566 pub limit: Option<Expr>,
567 pub span: Span,
568}
569
570#[derive(Debug, Clone)]
571pub enum ProjectionItem {
572 Expr {
573 expr: Expr,
574 alias: Option<Variable>,
575 span: Span,
576 },
577 Star {
578 span: Span,
579 },
580}
581
582#[derive(Debug, Clone)]
583pub struct SortItem {
584 pub expr: Expr,
585 pub direction: SortDirection,
586 pub span: Span,
587}
588
589#[derive(Debug, Clone, Copy, PartialEq, Eq)]
590pub enum SortDirection {
591 Asc,
592 Desc,
593}
594
595#[derive(Debug, Clone)]
596pub struct Pattern {
597 pub parts: Vec<PatternPart>,
598 pub span: Span,
599}
600
601#[derive(Debug, Clone)]
602pub struct PatternPart {
603 pub binding: Option<Variable>,
604 pub element: PatternElement,
605 pub span: Span,
606}
607
608#[derive(Debug, Clone)]
609pub enum PatternElement {
610 NodeChain {
611 head: NodePattern,
612 chain: Vec<PatternElementChain>,
613 span: Span,
614 },
615 Parenthesized(Box<PatternElement>, Span),
616 ShortestPath {
617 all: bool,
618 element: Box<PatternElement>,
619 span: Span,
620 },
621}
622
623#[derive(Debug, Clone)]
624pub struct PatternElementChain {
625 pub relationship: RelationshipPattern,
626 pub node: NodePattern,
627 pub span: Span,
628}
629
630#[derive(Debug, Clone)]
631pub struct NodePattern {
632 pub variable: Option<Variable>,
633 pub labels: SmallVec<SmallVec<String, 2>, 2>,
637 pub properties: Option<Expr>,
638 pub span: Span,
639}
640
641#[derive(Debug, Clone)]
642pub struct RelationshipPattern {
643 pub direction: Direction,
644 pub detail: Option<RelationshipDetail>,
645 pub span: Span,
646}
647
648#[derive(Debug, Clone)]
649pub struct RelationshipDetail {
650 pub variable: Option<Variable>,
651 pub types: SmallVec<String, 2>,
652 pub range: Option<RangeLiteral>,
653 pub properties: Option<Expr>,
654 pub span: Span,
655}
656
657#[derive(Debug, Clone, Copy, PartialEq, Eq)]
658pub enum Direction {
659 Left,
660 Right,
661 Undirected,
662}
663
664#[derive(Debug, Clone)]
665pub struct RangeLiteral {
666 pub start: Option<u64>,
667 pub end: Option<u64>,
668 pub span: Span,
669}
670
671#[derive(Debug, Clone)]
672pub struct Variable {
673 pub name: String,
674 pub span: Span,
675}
676
677#[derive(Debug, Clone)]
678pub struct ProcedureName {
679 pub parts: Vec<String>,
680 pub span: Span,
681}
682
683#[derive(Debug, Clone)]
684pub enum Expr {
685 Variable(Variable),
686 Integer(i64, Span),
687 Float(f64, Span),
688 String(String, Span),
689 Bool(bool, Span),
690 Null(Span),
691 Parameter(String, Span),
692 List(Vec<Expr>, Span),
693 Map(Vec<(String, Expr)>, Span),
694 Property {
695 expr: Box<Expr>,
696 key: String,
697 span: Span,
698 },
699 Binary {
700 lhs: Box<Expr>,
701 op: BinaryOp,
702 rhs: Box<Expr>,
703 span: Span,
704 },
705 Unary {
706 op: UnaryOp,
707 expr: Box<Expr>,
708 span: Span,
709 },
710 FunctionCall {
711 name: Vec<String>,
712 distinct: bool,
713 args: Vec<Expr>,
714 span: Span,
715 },
716 TypeCast {
717 expr: Box<Expr>,
718 target: LiteralTypeExpr,
719 try_cast: bool,
720 span: Span,
721 },
722 Case {
723 input: Option<Box<Expr>>,
724 alternatives: Vec<(Expr, Expr)>,
725 else_expr: Option<Box<Expr>>,
726 span: Span,
727 },
728 ListPredicate {
729 kind: ListPredicateKind,
730 variable: Variable,
731 list: Box<Expr>,
732 predicate: Box<Expr>,
733 span: Span,
734 },
735 ListComprehension {
736 variable: Variable,
737 list: Box<Expr>,
738 filter: Option<Box<Expr>>,
739 map_expr: Option<Box<Expr>>,
740 span: Span,
741 },
742 Reduce {
743 accumulator: Variable,
744 init: Box<Expr>,
745 variable: Variable,
746 list: Box<Expr>,
747 expr: Box<Expr>,
748 span: Span,
749 },
750 MapProjection {
751 base: Box<Expr>,
752 selectors: Vec<MapProjectionSelector>,
753 span: Span,
754 },
755 Index {
756 expr: Box<Expr>,
757 index: Box<Expr>,
758 span: Span,
759 },
760 Slice {
761 expr: Box<Expr>,
762 from: Option<Box<Expr>>,
763 to: Option<Box<Expr>>,
764 span: Span,
765 },
766 ExistsSubquery {
767 pattern: Pattern,
768 where_: Option<Box<Expr>>,
769 span: Span,
770 },
771 PatternComprehension {
772 pattern: Box<PatternElement>,
773 where_: Option<Box<Expr>>,
774 map_expr: Box<Expr>,
775 span: Span,
776 },
777}
778
779#[derive(Debug, Clone, PartialEq)]
780pub enum LiteralTypeExpr {
781 Named {
782 name: String,
783 span: Span,
784 },
785 List {
786 inner: Box<LiteralTypeExpr>,
787 span: Span,
788 },
789 Vector {
790 coordinate: String,
791 dimension: u32,
792 span: Span,
793 },
794}
795
796impl LiteralTypeExpr {
797 #[must_use]
798 pub fn span(&self) -> Span {
799 match self {
800 LiteralTypeExpr::Named { span, .. }
801 | LiteralTypeExpr::List { span, .. }
802 | LiteralTypeExpr::Vector { span, .. } => *span,
803 }
804 }
805}
806
807#[derive(Debug, Clone)]
808pub enum MapProjectionSelector {
809 Property(String),
811 AllProperties,
813 Literal(String, Expr),
815}
816
817#[derive(Debug, Clone, Copy, PartialEq, Eq)]
818pub enum ListPredicateKind {
819 Any,
820 All,
821 None,
822 Single,
823}
824
825impl Expr {
826 #[must_use]
827 pub fn span(&self) -> Span {
828 match self {
829 Expr::Variable(v) => v.span,
830 Expr::Integer(_, s)
831 | Expr::Float(_, s)
832 | Expr::String(_, s)
833 | Expr::Bool(_, s)
834 | Expr::Null(s)
835 | Expr::Parameter(_, s)
836 | Expr::List(_, s)
837 | Expr::Map(_, s)
838 | Expr::Property { span: s, .. }
839 | Expr::Binary { span: s, .. }
840 | Expr::Unary { span: s, .. }
841 | Expr::FunctionCall { span: s, .. }
842 | Expr::TypeCast { span: s, .. }
843 | Expr::Case { span: s, .. }
844 | Expr::ListPredicate { span: s, .. }
845 | Expr::ListComprehension { span: s, .. }
846 | Expr::Reduce { span: s, .. }
847 | Expr::MapProjection { span: s, .. }
848 | Expr::Index { span: s, .. }
849 | Expr::Slice { span: s, .. }
850 | Expr::ExistsSubquery { span: s, .. }
851 | Expr::PatternComprehension { span: s, .. } => *s,
852 }
853 }
854}
855
856#[derive(Debug, Clone, Copy, PartialEq, Eq)]
857pub enum BinaryOp {
858 Or,
859 Xor,
860 And,
861 Eq,
862 Ne,
863 Lt,
864 Gt,
865 Le,
866 Ge,
867 Add,
868 Sub,
869 Mul,
870 Div,
871 Mod,
872 Pow,
873 In,
874 StartsWith,
875 EndsWith,
876 Contains,
877 IsNull,
878 IsNotNull,
879 RegexMatch,
880}
881
882#[derive(Debug, Clone, Copy, PartialEq, Eq)]
883pub enum UnaryOp {
884 Not,
885 Pos,
886 Neg,
887}