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}
406
407#[derive(Debug, Clone)]
408pub struct Match {
409 pub optional: bool,
410 pub pattern: Pattern,
411 pub where_: Option<Expr>,
412 pub span: Span,
413}
414
415#[derive(Debug, Clone)]
416pub struct Unwind {
417 pub expr: Expr,
418 pub alias: Variable,
419 pub span: Span,
420}
421
422#[derive(Debug, Clone)]
423pub struct Create {
424 pub pattern: Pattern,
425 pub span: Span,
426}
427
428#[derive(Debug, Clone)]
429pub struct Merge {
430 pub pattern_part: PatternPart,
431 pub actions: Vec<MergeAction>,
432 pub span: Span,
433}
434
435#[derive(Debug, Clone)]
436pub struct MergeAction {
437 pub on_match: bool,
438 pub set: Set,
439 pub span: Span,
440}
441
442#[derive(Debug, Clone)]
443pub struct Delete {
444 pub detach: bool,
445 pub expressions: Vec<Expr>,
446 pub span: Span,
447}
448
449#[derive(Debug, Clone)]
450pub struct Set {
451 pub items: Vec<SetItem>,
452 pub span: Span,
453}
454
455#[derive(Debug, Clone)]
456pub enum SetItem {
457 SetProperty {
458 target: Expr,
459 value: Expr,
460 span: Span,
461 },
462 SetVariable {
463 variable: Variable,
464 value: Expr,
465 span: Span,
466 },
467 MutateVariable {
468 variable: Variable,
469 value: Expr,
470 span: Span,
471 },
472 SetLabels {
473 variable: Variable,
474 labels: Vec<String>,
475 span: Span,
476 },
477}
478
479#[derive(Debug, Clone)]
480pub struct Remove {
481 pub items: Vec<RemoveItem>,
482 pub span: Span,
483}
484
485#[derive(Debug, Clone)]
486pub enum RemoveItem {
487 Labels {
488 variable: Variable,
489 labels: Vec<String>,
490 span: Span,
491 },
492 Property {
493 expr: Expr,
494 span: Span,
495 },
496}
497
498#[derive(Debug, Clone)]
499pub struct InQueryCall {
500 pub procedure: ProcedureInvocation,
501 pub yield_items: Vec<YieldItem>,
502 pub where_: Option<Expr>,
503 pub span: Span,
504}
505
506#[derive(Debug, Clone)]
507pub struct StandaloneCall {
508 pub procedure: ProcedureInvocationKind,
509 pub yield_items: Vec<YieldItem>,
510 pub yield_all: bool,
511 pub span: Span,
512}
513
514#[derive(Debug, Clone)]
515pub enum ProcedureInvocationKind {
516 Explicit(ProcedureInvocation),
517 Implicit(ProcedureName),
518}
519
520#[derive(Debug, Clone)]
521pub struct ProcedureInvocation {
522 pub name: ProcedureName,
523 pub args: Vec<Expr>,
524 pub span: Span,
525}
526
527#[derive(Debug, Clone)]
528pub struct YieldItem {
529 pub field: Option<String>,
530 pub alias: Variable,
531 pub span: Span,
532}
533
534#[derive(Debug, Clone)]
535pub struct With {
536 pub body: ProjectionBody,
537 pub where_: Option<Expr>,
538 pub span: Span,
539}
540
541#[derive(Debug, Clone)]
542pub struct Return {
543 pub body: ProjectionBody,
544 pub span: Span,
545}
546
547#[derive(Debug, Clone)]
548pub struct ProjectionBody {
549 pub distinct: bool,
550 pub items: Vec<ProjectionItem>,
551 pub order: Vec<SortItem>,
552 pub skip: Option<Expr>,
553 pub limit: Option<Expr>,
554 pub span: Span,
555}
556
557#[derive(Debug, Clone)]
558pub enum ProjectionItem {
559 Expr {
560 expr: Expr,
561 alias: Option<Variable>,
562 span: Span,
563 },
564 Star {
565 span: Span,
566 },
567}
568
569#[derive(Debug, Clone)]
570pub struct SortItem {
571 pub expr: Expr,
572 pub direction: SortDirection,
573 pub span: Span,
574}
575
576#[derive(Debug, Clone, Copy, PartialEq, Eq)]
577pub enum SortDirection {
578 Asc,
579 Desc,
580}
581
582#[derive(Debug, Clone)]
583pub struct Pattern {
584 pub parts: Vec<PatternPart>,
585 pub span: Span,
586}
587
588#[derive(Debug, Clone)]
589pub struct PatternPart {
590 pub binding: Option<Variable>,
591 pub element: PatternElement,
592 pub span: Span,
593}
594
595#[derive(Debug, Clone)]
596pub enum PatternElement {
597 NodeChain {
598 head: NodePattern,
599 chain: Vec<PatternElementChain>,
600 span: Span,
601 },
602 Parenthesized(Box<PatternElement>, Span),
603 ShortestPath {
604 all: bool,
605 element: Box<PatternElement>,
606 span: Span,
607 },
608}
609
610#[derive(Debug, Clone)]
611pub struct PatternElementChain {
612 pub relationship: RelationshipPattern,
613 pub node: NodePattern,
614 pub span: Span,
615}
616
617#[derive(Debug, Clone)]
618pub struct NodePattern {
619 pub variable: Option<Variable>,
620 pub labels: SmallVec<SmallVec<String, 2>, 2>,
624 pub properties: Option<Expr>,
625 pub span: Span,
626}
627
628#[derive(Debug, Clone)]
629pub struct RelationshipPattern {
630 pub direction: Direction,
631 pub detail: Option<RelationshipDetail>,
632 pub span: Span,
633}
634
635#[derive(Debug, Clone)]
636pub struct RelationshipDetail {
637 pub variable: Option<Variable>,
638 pub types: SmallVec<String, 2>,
639 pub range: Option<RangeLiteral>,
640 pub properties: Option<Expr>,
641 pub span: Span,
642}
643
644#[derive(Debug, Clone, Copy, PartialEq, Eq)]
645pub enum Direction {
646 Left,
647 Right,
648 Undirected,
649}
650
651#[derive(Debug, Clone)]
652pub struct RangeLiteral {
653 pub start: Option<u64>,
654 pub end: Option<u64>,
655 pub span: Span,
656}
657
658#[derive(Debug, Clone)]
659pub struct Variable {
660 pub name: String,
661 pub span: Span,
662}
663
664#[derive(Debug, Clone)]
665pub struct ProcedureName {
666 pub parts: Vec<String>,
667 pub span: Span,
668}
669
670#[derive(Debug, Clone)]
671pub enum Expr {
672 Variable(Variable),
673 Integer(i64, Span),
674 Float(f64, Span),
675 String(String, Span),
676 Bool(bool, Span),
677 Null(Span),
678 Parameter(String, Span),
679 List(Vec<Expr>, Span),
680 Map(Vec<(String, Expr)>, Span),
681 Property {
682 expr: Box<Expr>,
683 key: String,
684 span: Span,
685 },
686 Binary {
687 lhs: Box<Expr>,
688 op: BinaryOp,
689 rhs: Box<Expr>,
690 span: Span,
691 },
692 Unary {
693 op: UnaryOp,
694 expr: Box<Expr>,
695 span: Span,
696 },
697 FunctionCall {
698 name: Vec<String>,
699 distinct: bool,
700 args: Vec<Expr>,
701 span: Span,
702 },
703 TypeCast {
704 expr: Box<Expr>,
705 target: LiteralTypeExpr,
706 try_cast: bool,
707 span: Span,
708 },
709 Case {
710 input: Option<Box<Expr>>,
711 alternatives: Vec<(Expr, Expr)>,
712 else_expr: Option<Box<Expr>>,
713 span: Span,
714 },
715 ListPredicate {
716 kind: ListPredicateKind,
717 variable: Variable,
718 list: Box<Expr>,
719 predicate: Box<Expr>,
720 span: Span,
721 },
722 ListComprehension {
723 variable: Variable,
724 list: Box<Expr>,
725 filter: Option<Box<Expr>>,
726 map_expr: Option<Box<Expr>>,
727 span: Span,
728 },
729 Reduce {
730 accumulator: Variable,
731 init: Box<Expr>,
732 variable: Variable,
733 list: Box<Expr>,
734 expr: Box<Expr>,
735 span: Span,
736 },
737 MapProjection {
738 base: Box<Expr>,
739 selectors: Vec<MapProjectionSelector>,
740 span: Span,
741 },
742 Index {
743 expr: Box<Expr>,
744 index: Box<Expr>,
745 span: Span,
746 },
747 Slice {
748 expr: Box<Expr>,
749 from: Option<Box<Expr>>,
750 to: Option<Box<Expr>>,
751 span: Span,
752 },
753 ExistsSubquery {
754 pattern: Pattern,
755 where_: Option<Box<Expr>>,
756 span: Span,
757 },
758 PatternComprehension {
759 pattern: Box<PatternElement>,
760 where_: Option<Box<Expr>>,
761 map_expr: Box<Expr>,
762 span: Span,
763 },
764}
765
766#[derive(Debug, Clone, PartialEq)]
767pub enum LiteralTypeExpr {
768 Named {
769 name: String,
770 span: Span,
771 },
772 List {
773 inner: Box<LiteralTypeExpr>,
774 span: Span,
775 },
776 Vector {
777 coordinate: String,
778 dimension: u32,
779 span: Span,
780 },
781}
782
783impl LiteralTypeExpr {
784 #[must_use]
785 pub fn span(&self) -> Span {
786 match self {
787 LiteralTypeExpr::Named { span, .. }
788 | LiteralTypeExpr::List { span, .. }
789 | LiteralTypeExpr::Vector { span, .. } => *span,
790 }
791 }
792}
793
794#[derive(Debug, Clone)]
795pub enum MapProjectionSelector {
796 Property(String),
798 AllProperties,
800 Literal(String, Expr),
802}
803
804#[derive(Debug, Clone, Copy, PartialEq, Eq)]
805pub enum ListPredicateKind {
806 Any,
807 All,
808 None,
809 Single,
810}
811
812impl Expr {
813 #[must_use]
814 pub fn span(&self) -> Span {
815 match self {
816 Expr::Variable(v) => v.span,
817 Expr::Integer(_, s)
818 | Expr::Float(_, s)
819 | Expr::String(_, s)
820 | Expr::Bool(_, s)
821 | Expr::Null(s)
822 | Expr::Parameter(_, s)
823 | Expr::List(_, s)
824 | Expr::Map(_, s)
825 | Expr::Property { span: s, .. }
826 | Expr::Binary { span: s, .. }
827 | Expr::Unary { span: s, .. }
828 | Expr::FunctionCall { span: s, .. }
829 | Expr::TypeCast { span: s, .. }
830 | Expr::Case { span: s, .. }
831 | Expr::ListPredicate { span: s, .. }
832 | Expr::ListComprehension { span: s, .. }
833 | Expr::Reduce { span: s, .. }
834 | Expr::MapProjection { span: s, .. }
835 | Expr::Index { span: s, .. }
836 | Expr::Slice { span: s, .. }
837 | Expr::ExistsSubquery { span: s, .. }
838 | Expr::PatternComprehension { span: s, .. } => *s,
839 }
840 }
841}
842
843#[derive(Debug, Clone, Copy, PartialEq, Eq)]
844pub enum BinaryOp {
845 Or,
846 Xor,
847 And,
848 Eq,
849 Ne,
850 Lt,
851 Gt,
852 Le,
853 Ge,
854 Add,
855 Sub,
856 Mul,
857 Div,
858 Mod,
859 Pow,
860 In,
861 StartsWith,
862 EndsWith,
863 Contains,
864 IsNull,
865 IsNotNull,
866 RegexMatch,
867}
868
869#[derive(Debug, Clone, Copy, PartialEq, Eq)]
870pub enum UnaryOp {
871 Not,
872 Pos,
873 Neg,
874}