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