|
10 | 10 | use rust_decimal::Decimal as RustDecimal;
|
11 | 11 |
|
12 | 12 | use std::fmt;
|
| 13 | +use std::num::NonZeroU32; |
13 | 14 |
|
14 | 15 | #[cfg(feature = "serde")]
|
15 | 16 | use serde::{Deserialize, Serialize};
|
@@ -534,6 +535,8 @@ pub enum FromClause {
|
534 | 535 | FromLet(AstNode<FromLet>),
|
535 | 536 | /// <from_source> JOIN \[INNER | LEFT | RIGHT | FULL\] <from_source> ON <expr>
|
536 | 537 | Join(AstNode<Join>),
|
| 538 | + /// <expr> MATCH <graph_pattern> |
| 539 | + GraphMatch(AstNode<GraphMatch>), |
537 | 540 | }
|
538 | 541 |
|
539 | 542 | #[derive(Clone, Debug, PartialEq)]
|
@@ -583,7 +586,153 @@ pub enum JoinSpec {
|
583 | 586 | Natural,
|
584 | 587 | }
|
585 | 588 |
|
586 |
| -/// GROUP BY <grouping_strategy> <group_key>[, <group_key>]... \[AS <symbol>\] |
| 589 | +#[derive(Clone, Debug, PartialEq)] |
| 590 | +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] |
| 591 | +pub struct GraphMatch { |
| 592 | + pub expr: Box<Expr>, |
| 593 | + pub graph_expr: Box<AstNode<GraphMatchExpr>>, |
| 594 | +} |
| 595 | + |
| 596 | +/// The direction of an edge |
| 597 | +/// | Orientation | Edge pattern | Abbreviation | |
| 598 | +/// |---------------------------+--------------+--------------| |
| 599 | +/// | Pointing left | <−[ spec ]− | <− | |
| 600 | +/// | Undirected | ~[ spec ]~ | ~ | |
| 601 | +/// | Pointing right | −[ spec ]−> | −> | |
| 602 | +/// | Left or undirected | <~[ spec ]~ | <~ | |
| 603 | +/// | Undirected or right | ~[ spec ]~> | ~> | |
| 604 | +/// | Left or right | <−[ spec ]−> | <−> | |
| 605 | +/// | Left, undirected or right | −[ spec ]− | − | |
| 606 | +/// |
| 607 | +/// Fig. 5. Table of edge patterns: |
| 608 | +/// https://arxiv.org/abs/2112.06217 |
| 609 | +#[derive(Clone, Debug, PartialEq)] |
| 610 | +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] |
| 611 | +pub enum GraphMatchDirection { |
| 612 | + Left, |
| 613 | + Undirected, |
| 614 | + Right, |
| 615 | + LeftOrUndirected, |
| 616 | + UndirectedOrRight, |
| 617 | + LeftOrRight, |
| 618 | + LeftOrUndirectedOrRight, |
| 619 | +} |
| 620 | + |
| 621 | +/// A part of a graph pattern |
| 622 | +#[derive(Clone, Debug, PartialEq)] |
| 623 | +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] |
| 624 | +pub enum GraphMatchPatternPart { |
| 625 | + /// A single node in a graph pattern. |
| 626 | + Node(AstNode<GraphMatchNode>), |
| 627 | + |
| 628 | + /// A single edge in a graph pattern. |
| 629 | + Edge(AstNode<GraphMatchEdge>), |
| 630 | + |
| 631 | + /// A sub-pattern. |
| 632 | + Pattern(AstNode<GraphMatchPattern>), |
| 633 | +} |
| 634 | + |
| 635 | +/// A quantifier for graph edges or patterns. (e.g., the `{2,5}` in `MATCH (x)->{2,5}(y)`) |
| 636 | +#[derive(Clone, Debug, PartialEq)] |
| 637 | +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] |
| 638 | +pub struct GraphMatchQuantifier { |
| 639 | + pub lower: u32, |
| 640 | + pub upper: Option<NonZeroU32>, |
| 641 | +} |
| 642 | + |
| 643 | +/// A path restrictor |
| 644 | +/// | Keyword | Description |
| 645 | +/// |----------------+-------------- |
| 646 | +/// | TRAIL | No repeated edges. |
| 647 | +/// | ACYCLIC | No repeated nodes. |
| 648 | +/// | SIMPLE | No repeated nodes, except that the first and last nodes may be the same. |
| 649 | +/// |
| 650 | +/// Fig. 7. Table of restrictors: |
| 651 | +/// https://arxiv.org/abs/2112.06217 |
| 652 | +#[derive(Clone, Debug, PartialEq)] |
| 653 | +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] |
| 654 | +pub enum GraphMatchRestrictor { |
| 655 | + Trail, |
| 656 | + Acyclic, |
| 657 | + Simple, |
| 658 | +} |
| 659 | + |
| 660 | +/// A single node in a graph pattern. |
| 661 | +#[derive(Clone, Debug, PartialEq)] |
| 662 | +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] |
| 663 | +pub struct GraphMatchNode { |
| 664 | + /// an optional node pre-filter, e.g.: `WHERE c.name='Alarm'` in `MATCH (c WHERE c.name='Alarm')` |
| 665 | + pub prefilter: Option<Box<Expr>>, |
| 666 | + /// the optional element variable of the node match, e.g.: `x` in `MATCH (x)` |
| 667 | + pub variable: Option<SymbolPrimitive>, |
| 668 | + /// the optional label(s) to match for the node, e.g.: `Entity` in `MATCH (x:Entity)` |
| 669 | + pub label: Option<Vec<SymbolPrimitive>>, |
| 670 | +} |
| 671 | + |
| 672 | +/// A single edge in a graph pattern. |
| 673 | +#[derive(Clone, Debug, PartialEq)] |
| 674 | +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] |
| 675 | +pub struct GraphMatchEdge { |
| 676 | + /// edge direction |
| 677 | + pub direction: GraphMatchDirection, |
| 678 | + /// an optional quantifier for the edge match |
| 679 | + pub quantifier: Option<AstNode<GraphMatchQuantifier>>, |
| 680 | + /// an optional edge pre-filter, e.g.: `WHERE t.capacity>100` in `MATCH −[t:hasSupply WHERE t.capacity>100]−>` |
| 681 | + pub prefilter: Option<Box<Expr>>, |
| 682 | + /// the optional element variable of the edge match, e.g.: `t` in `MATCH −[t]−>` |
| 683 | + pub variable: Option<SymbolPrimitive>, |
| 684 | + /// the optional label(s) to match for the edge. e.g.: `Target` in `MATCH −[t:Target]−>` |
| 685 | + pub label: Option<Vec<SymbolPrimitive>>, |
| 686 | +} |
| 687 | + |
| 688 | +/// A single graph match pattern. |
| 689 | +#[derive(Clone, Debug, PartialEq)] |
| 690 | +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] |
| 691 | +pub struct GraphMatchPattern { |
| 692 | + pub restrictor: Option<GraphMatchRestrictor>, |
| 693 | + /// an optional quantifier for the entire pattern match |
| 694 | + pub quantifier: Option<AstNode<GraphMatchQuantifier>>, |
| 695 | + /// an optional pattern pre-filter, e.g.: `WHERE a.name=b.name` in `MATCH [(a)->(b) WHERE a.name=b.name]` |
| 696 | + pub prefilter: Option<Box<Expr>>, |
| 697 | + /// the optional element variable of the pattern, e.g.: `p` in `MATCH p = (a) −[t]−> (b)` |
| 698 | + pub variable: Option<SymbolPrimitive>, |
| 699 | + /// the ordered pattern parts |
| 700 | + pub parts: Vec<GraphMatchPatternPart>, |
| 701 | +} |
| 702 | + |
| 703 | +/// A path selector |
| 704 | +/// | Keyword |
| 705 | +/// |------------------ |
| 706 | +/// | ANY SHORTEST |
| 707 | +/// | ALL SHORTEST |
| 708 | +/// | ANY |
| 709 | +/// | ANY k |
| 710 | +/// | SHORTEST k |
| 711 | +/// | SHORTEST k GROUP |
| 712 | +/// |
| 713 | +/// Fig. 8. Table of restrictors: |
| 714 | +/// https://arxiv.org/abs/2112.06217 |
| 715 | +#[derive(Clone, Debug, PartialEq)] |
| 716 | +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] |
| 717 | +pub enum GraphMatchSelector { |
| 718 | + AnyShortest, |
| 719 | + AllShortest, |
| 720 | + Any, |
| 721 | + AnyK(NonZeroU32), |
| 722 | + ShortestK(NonZeroU32), |
| 723 | + ShortestKGroup(NonZeroU32), |
| 724 | +} |
| 725 | + |
| 726 | +/// A graph match clause as defined in GPML |
| 727 | +/// See https://arxiv.org/abs/2112.06217 |
| 728 | +#[derive(Clone, Debug, PartialEq)] |
| 729 | +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] |
| 730 | +pub struct GraphMatchExpr { |
| 731 | + pub selector: Option<GraphMatchSelector>, |
| 732 | + pub patterns: Vec<AstNode<GraphMatchPattern>>, |
| 733 | +} |
| 734 | + |
| 735 | +/// GROUP BY <grouping_strategy> <group_key_list>... \[AS <symbol>\] |
587 | 736 | #[derive(Clone, Debug, PartialEq)]
|
588 | 737 | #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
589 | 738 | pub struct GroupByExpr {
|
|
0 commit comments