@@ -12,6 +12,7 @@ use rust_decimal::Decimal as RustDecimal;
12
12
use serde:: { Deserialize , Serialize } ;
13
13
use std:: fmt;
14
14
use std:: fmt:: Display ;
15
+ use std:: num:: NonZeroU32 ;
15
16
use std:: ops:: Range ;
16
17
17
18
/// Provides the required methods for AstNode conversations.
@@ -235,6 +236,13 @@ pub type CallAst = AstBytePos<Call>;
235
236
pub type CaseAst = AstBytePos < Case > ;
236
237
pub type FromClauseAst = AstBytePos < FromClause > ;
237
238
pub type FromLetAst = AstBytePos < FromLet > ;
239
+ pub type GraphMatchAst = AstBytePos < GraphMatch > ;
240
+ pub type GraphMatchExprAst = AstBytePos < GraphMatchExpr > ;
241
+ pub type GraphMatchEdgeAst = AstBytePos < GraphMatchEdge > ;
242
+ pub type GraphMatchNodeAst = AstBytePos < GraphMatchNode > ;
243
+ pub type GraphMatchPatternAst = AstBytePos < GraphMatchPattern > ;
244
+ pub type GraphMatchPatternPartAst = AstBytePos < GraphMatchPatternPart > ;
245
+ pub type GraphMatchQuantifierAst = AstBytePos < GraphMatchQuantifier > ;
238
246
pub type GroupByExprAst = AstBytePos < GroupByExpr > ;
239
247
pub type GroupKeyAst = AstBytePos < GroupKey > ;
240
248
pub type InAst = AstBytePos < In > ;
@@ -655,6 +663,9 @@ pub enum FromClause {
655
663
FromLet ( FromLetAst ) ,
656
664
/// <from_source> JOIN \[INNER | LEFT | RIGHT | FULL\] <from_source> ON <expr>
657
665
Join ( JoinAst ) ,
666
+
667
+ /// <expr> MATCH <graph_pattern>
668
+ GraphMatch ( GraphMatchAst ) ,
658
669
}
659
670
660
671
#[ derive( Clone , Debug , PartialEq , Deserialize , Serialize ) ]
@@ -699,6 +710,142 @@ pub enum JoinKind {
699
710
Cross ,
700
711
}
701
712
713
+ #[ derive( Clone , Debug , PartialEq , Deserialize , Serialize ) ]
714
+ pub struct GraphMatch {
715
+ pub expr : Box < Expr > ,
716
+ pub graph_expr : Box < GraphMatchExprAst > ,
717
+ }
718
+
719
+ /// The direction of an edge
720
+ /// | Orientation | Edge pattern | Abbreviation |
721
+ /// |---------------------------+--------------+--------------|
722
+ /// | Pointing left | <−[ spec ]− | <− |
723
+ /// | Undirected | ~[ spec ]~ | ~ |
724
+ /// | Pointing right | −[ spec ]−> | −> |
725
+ /// | Left or undirected | <~[ spec ]~ | <~ |
726
+ /// | Undirected or right | ~[ spec ]~> | ~> |
727
+ /// | Left or right | <−[ spec ]−> | <−> |
728
+ /// | Left, undirected or right | −[ spec ]− | − |
729
+ ///
730
+ /// Fig. 5. Table of edge patterns:
731
+ /// https://arxiv.org/abs/2112.06217
732
+ #[ derive( Clone , Debug , PartialEq , Deserialize , Serialize ) ]
733
+ pub enum GraphMatchDirection {
734
+ Left ,
735
+ Undirected ,
736
+ Right ,
737
+ LeftOrUndirected ,
738
+ UndirectedOrRight ,
739
+ LeftOrRight ,
740
+ LeftOrUndirectedOrRight ,
741
+ }
742
+
743
+ /// A part of a graph pattern
744
+ #[ derive( Clone , Debug , PartialEq , Deserialize , Serialize ) ]
745
+ pub enum GraphMatchPatternPart {
746
+ /// A single node in a graph pattern.
747
+ Node ( GraphMatchNodeAst ) ,
748
+
749
+ /// A single edge in a graph pattern.
750
+ Edge ( GraphMatchEdgeAst ) ,
751
+
752
+ /// A sub-pattern.
753
+ Pattern ( GraphMatchPatternAst ) ,
754
+ }
755
+
756
+ /// A quantifier for graph edges or patterns. (e.g., the `{2,5}` in `MATCH (x)->{2,5}(y)`)
757
+ #[ derive( Clone , Debug , PartialEq , Deserialize , Serialize ) ]
758
+ pub struct GraphMatchQuantifier {
759
+ pub lower : u32 ,
760
+ pub upper : Option < NonZeroU32 > ,
761
+ }
762
+
763
+ /// A path restrictor
764
+ /// | Keyword | Description
765
+ /// |----------------+--------------
766
+ /// | TRAIL | No repeated edges.
767
+ /// | ACYCLIC | No repeated nodes.
768
+ /// | SIMPLE | No repeated nodes, except that the first and last nodes may be the same.
769
+ ///
770
+ /// Fig. 7. Table of restrictors:
771
+ /// https://arxiv.org/abs/2112.06217
772
+ #[ derive( Clone , Debug , PartialEq , Deserialize , Serialize ) ]
773
+ pub enum GraphMatchRestrictor {
774
+ Trail ,
775
+ Acyclic ,
776
+ Simple ,
777
+ }
778
+
779
+ /// A single node in a graph pattern.
780
+ #[ derive( Clone , Debug , PartialEq , Deserialize , Serialize ) ]
781
+ pub struct GraphMatchNode {
782
+ /// an optional node pre-filter, e.g.: `WHERE c.name='Alarm'` in `MATCH (c WHERE c.name='Alarm')`
783
+ pub prefilter : Option < Box < Expr > > ,
784
+ /// the optional element variable of the node match, e.g.: `x` in `MATCH (x)`
785
+ pub variable : Option < SymbolPrimitive > ,
786
+ /// the optional label(s) to match for the node, e.g.: `Entity` in `MATCH (x:Entity)`
787
+ pub label : Option < Vec < SymbolPrimitive > > ,
788
+ }
789
+
790
+ /// A single edge in a graph pattern.
791
+ #[ derive( Clone , Debug , PartialEq , Deserialize , Serialize ) ]
792
+ pub struct GraphMatchEdge {
793
+ /// edge direction
794
+ pub direction : GraphMatchDirection ,
795
+ /// an optional quantifier for the edge match
796
+ pub quantifier : Option < GraphMatchQuantifierAst > ,
797
+ /// an optional edge pre-filter, e.g.: `WHERE t.capacity>100` in `MATCH −[t:hasSupply WHERE t.capacity>100]−>`
798
+ pub prefilter : Option < Box < Expr > > ,
799
+ /// the optional element variable of the edge match, e.g.: `t` in `MATCH −[t]−>`
800
+ pub variable : Option < SymbolPrimitive > ,
801
+ /// the optional label(s) to match for the edge. e.g.: `Target` in `MATCH −[t:Target]−>`
802
+ pub label : Option < Vec < SymbolPrimitive > > ,
803
+ }
804
+
805
+ /// A single graph match pattern.
806
+ #[ derive( Clone , Debug , PartialEq , Deserialize , Serialize ) ]
807
+ pub struct GraphMatchPattern {
808
+ pub restrictor : Option < GraphMatchRestrictor > ,
809
+ /// an optional quantifier for the entire pattern match
810
+ pub quantifier : Option < GraphMatchQuantifierAst > ,
811
+ /// an optional pattern pre-filter, e.g.: `WHERE a.name=b.name` in `MATCH [(a)->(b) WHERE a.name=b.name]`
812
+ pub prefilter : Option < Box < Expr > > ,
813
+ /// the optional element variable of the pattern, e.g.: `p` in `MATCH p = (a) −[t]−> (b)`
814
+ pub variable : Option < SymbolPrimitive > ,
815
+ /// the ordered pattern parts
816
+ pub parts : Vec < GraphMatchPatternPart > ,
817
+ }
818
+
819
+ /// A path selector
820
+ /// | Keyword
821
+ /// |------------------
822
+ /// | ANY SHORTEST
823
+ /// | ALL SHORTEST
824
+ /// | ANY
825
+ /// | ANY k
826
+ /// | SHORTEST k
827
+ /// | SHORTEST k GROUP
828
+ ///
829
+ /// Fig. 8. Table of restrictors:
830
+ /// https://arxiv.org/abs/2112.06217
831
+ #[ derive( Clone , Debug , PartialEq , Deserialize , Serialize ) ]
832
+ pub enum GraphMatchSelector {
833
+ AnyShortest ,
834
+ AllShortest ,
835
+ Any ,
836
+ AnyK ( NonZeroU32 ) ,
837
+ ShortestK ( NonZeroU32 ) ,
838
+ ShortestKGroup ( NonZeroU32 ) ,
839
+ }
840
+
841
+ /// A graph match clause as defined in GPML
842
+ /// See https://arxiv.org/abs/2112.06217
843
+ #[ derive( Clone , Debug , PartialEq , Deserialize , Serialize ) ]
844
+ pub struct GraphMatchExpr {
845
+ pub selector : Option < GraphMatchSelector > ,
846
+ pub patterns : Vec < GraphMatchPatternAst > ,
847
+ }
848
+
702
849
/// A generic pair of expressions. Used in the `pub struct`, `searched_case`
703
850
/// and `simple_case` expr variants above.
704
851
#[ derive( Clone , Debug , PartialEq , Deserialize , Serialize ) ]
0 commit comments