@@ -12,6 +12,7 @@ use rust_decimal::Decimal as RustDecimal;
12
12
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
#[ cfg( feature = "serde" ) ]
@@ -258,6 +259,13 @@ pub type CallAst = AstBytePos<Call>;
258
259
pub type CaseAst = AstBytePos < Case > ;
259
260
pub type FromClauseAst = AstBytePos < FromClause > ;
260
261
pub type FromLetAst = AstBytePos < FromLet > ;
262
+ pub type GraphMatchAst = AstBytePos < GraphMatch > ;
263
+ pub type GraphMatchExprAst = AstBytePos < GraphMatchExpr > ;
264
+ pub type GraphMatchEdgeAst = AstBytePos < GraphMatchEdge > ;
265
+ pub type GraphMatchNodeAst = AstBytePos < GraphMatchNode > ;
266
+ pub type GraphMatchPatternAst = AstBytePos < GraphMatchPattern > ;
267
+ pub type GraphMatchPatternPartAst = AstBytePos < GraphMatchPatternPart > ;
268
+ pub type GraphMatchQuantifierAst = AstBytePos < GraphMatchQuantifier > ;
261
269
pub type GroupByExprAst = AstBytePos < GroupByExpr > ;
262
270
pub type GroupKeyAst = AstBytePos < GroupKey > ;
263
271
pub type InAst = AstBytePos < In > ;
@@ -675,6 +683,9 @@ pub enum FromClause {
675
683
FromLet ( FromLetAst ) ,
676
684
/// <from_source> JOIN \[INNER | LEFT | RIGHT | FULL\] <from_source> ON <expr>
677
685
Join ( JoinAst ) ,
686
+
687
+ /// <expr> MATCH <graph_pattern>
688
+ GraphMatch ( GraphMatchAst ) ,
678
689
}
679
690
680
691
#[ derive( Clone , Debug , PartialEq ) ]
@@ -724,6 +735,152 @@ pub enum JoinKind {
724
735
Cross ,
725
736
}
726
737
738
+ #[ derive( Clone , Debug , PartialEq ) ]
739
+ #[ cfg_attr( feature = "serde" , derive( Serialize , Deserialize ) ) ]
740
+ pub struct GraphMatch {
741
+ pub expr : Box < Expr > ,
742
+ pub graph_expr : Box < GraphMatchExprAst > ,
743
+ }
744
+
745
+ /// The direction of an edge
746
+ /// | Orientation | Edge pattern | Abbreviation |
747
+ /// |---------------------------+--------------+--------------|
748
+ /// | Pointing left | <−[ spec ]− | <− |
749
+ /// | Undirected | ~[ spec ]~ | ~ |
750
+ /// | Pointing right | −[ spec ]−> | −> |
751
+ /// | Left or undirected | <~[ spec ]~ | <~ |
752
+ /// | Undirected or right | ~[ spec ]~> | ~> |
753
+ /// | Left or right | <−[ spec ]−> | <−> |
754
+ /// | Left, undirected or right | −[ spec ]− | − |
755
+ ///
756
+ /// Fig. 5. Table of edge patterns:
757
+ /// https://arxiv.org/abs/2112.06217
758
+ #[ derive( Clone , Debug , PartialEq ) ]
759
+ #[ cfg_attr( feature = "serde" , derive( Serialize , Deserialize ) ) ]
760
+ pub enum GraphMatchDirection {
761
+ Left ,
762
+ Undirected ,
763
+ Right ,
764
+ LeftOrUndirected ,
765
+ UndirectedOrRight ,
766
+ LeftOrRight ,
767
+ LeftOrUndirectedOrRight ,
768
+ }
769
+
770
+ /// A part of a graph pattern
771
+ #[ derive( Clone , Debug , PartialEq ) ]
772
+ #[ cfg_attr( feature = "serde" , derive( Serialize , Deserialize ) ) ]
773
+ pub enum GraphMatchPatternPart {
774
+ /// A single node in a graph pattern.
775
+ Node ( GraphMatchNodeAst ) ,
776
+
777
+ /// A single edge in a graph pattern.
778
+ Edge ( GraphMatchEdgeAst ) ,
779
+
780
+ /// A sub-pattern.
781
+ Pattern ( GraphMatchPatternAst ) ,
782
+ }
783
+
784
+ /// A quantifier for graph edges or patterns. (e.g., the `{2,5}` in `MATCH (x)->{2,5}(y)`)
785
+ #[ derive( Clone , Debug , PartialEq ) ]
786
+ #[ cfg_attr( feature = "serde" , derive( Serialize , Deserialize ) ) ]
787
+ pub struct GraphMatchQuantifier {
788
+ pub lower : u32 ,
789
+ pub upper : Option < NonZeroU32 > ,
790
+ }
791
+
792
+ /// A path restrictor
793
+ /// | Keyword | Description
794
+ /// |----------------+--------------
795
+ /// | TRAIL | No repeated edges.
796
+ /// | ACYCLIC | No repeated nodes.
797
+ /// | SIMPLE | No repeated nodes, except that the first and last nodes may be the same.
798
+ ///
799
+ /// Fig. 7. Table of restrictors:
800
+ /// https://arxiv.org/abs/2112.06217
801
+ #[ derive( Clone , Debug , PartialEq ) ]
802
+ #[ cfg_attr( feature = "serde" , derive( Serialize , Deserialize ) ) ]
803
+ pub enum GraphMatchRestrictor {
804
+ Trail ,
805
+ Acyclic ,
806
+ Simple ,
807
+ }
808
+
809
+ /// A single node in a graph pattern.
810
+ #[ derive( Clone , Debug , PartialEq ) ]
811
+ #[ cfg_attr( feature = "serde" , derive( Serialize , Deserialize ) ) ]
812
+ pub struct GraphMatchNode {
813
+ /// an optional node pre-filter, e.g.: `WHERE c.name='Alarm'` in `MATCH (c WHERE c.name='Alarm')`
814
+ pub prefilter : Option < Box < Expr > > ,
815
+ /// the optional element variable of the node match, e.g.: `x` in `MATCH (x)`
816
+ pub variable : Option < SymbolPrimitive > ,
817
+ /// the optional label(s) to match for the node, e.g.: `Entity` in `MATCH (x:Entity)`
818
+ pub label : Option < Vec < SymbolPrimitive > > ,
819
+ }
820
+
821
+ /// A single edge in a graph pattern.
822
+ #[ derive( Clone , Debug , PartialEq ) ]
823
+ #[ cfg_attr( feature = "serde" , derive( Serialize , Deserialize ) ) ]
824
+ pub struct GraphMatchEdge {
825
+ /// edge direction
826
+ pub direction : GraphMatchDirection ,
827
+ /// an optional quantifier for the edge match
828
+ pub quantifier : Option < GraphMatchQuantifierAst > ,
829
+ /// an optional edge pre-filter, e.g.: `WHERE t.capacity>100` in `MATCH −[t:hasSupply WHERE t.capacity>100]−>`
830
+ pub prefilter : Option < Box < Expr > > ,
831
+ /// the optional element variable of the edge match, e.g.: `t` in `MATCH −[t]−>`
832
+ pub variable : Option < SymbolPrimitive > ,
833
+ /// the optional label(s) to match for the edge. e.g.: `Target` in `MATCH −[t:Target]−>`
834
+ pub label : Option < Vec < SymbolPrimitive > > ,
835
+ }
836
+
837
+ /// A single graph match pattern.
838
+ #[ derive( Clone , Debug , PartialEq ) ]
839
+ #[ cfg_attr( feature = "serde" , derive( Serialize , Deserialize ) ) ]
840
+ pub struct GraphMatchPattern {
841
+ pub restrictor : Option < GraphMatchRestrictor > ,
842
+ /// an optional quantifier for the entire pattern match
843
+ pub quantifier : Option < GraphMatchQuantifierAst > ,
844
+ /// an optional pattern pre-filter, e.g.: `WHERE a.name=b.name` in `MATCH [(a)->(b) WHERE a.name=b.name]`
845
+ pub prefilter : Option < Box < Expr > > ,
846
+ /// the optional element variable of the pattern, e.g.: `p` in `MATCH p = (a) −[t]−> (b)`
847
+ pub variable : Option < SymbolPrimitive > ,
848
+ /// the ordered pattern parts
849
+ pub parts : Vec < GraphMatchPatternPart > ,
850
+ }
851
+
852
+ /// A path selector
853
+ /// | Keyword
854
+ /// |------------------
855
+ /// | ANY SHORTEST
856
+ /// | ALL SHORTEST
857
+ /// | ANY
858
+ /// | ANY k
859
+ /// | SHORTEST k
860
+ /// | SHORTEST k GROUP
861
+ ///
862
+ /// Fig. 8. Table of restrictors:
863
+ /// https://arxiv.org/abs/2112.06217
864
+ #[ derive( Clone , Debug , PartialEq ) ]
865
+ #[ cfg_attr( feature = "serde" , derive( Serialize , Deserialize ) ) ]
866
+ pub enum GraphMatchSelector {
867
+ AnyShortest ,
868
+ AllShortest ,
869
+ Any ,
870
+ AnyK ( NonZeroU32 ) ,
871
+ ShortestK ( NonZeroU32 ) ,
872
+ ShortestKGroup ( NonZeroU32 ) ,
873
+ }
874
+
875
+ /// A graph match clause as defined in GPML
876
+ /// See https://arxiv.org/abs/2112.06217
877
+ #[ derive( Clone , Debug , PartialEq ) ]
878
+ #[ cfg_attr( feature = "serde" , derive( Serialize , Deserialize ) ) ]
879
+ pub struct GraphMatchExpr {
880
+ pub selector : Option < GraphMatchSelector > ,
881
+ pub patterns : Vec < GraphMatchPatternAst > ,
882
+ }
883
+
727
884
/// A generic pair of expressions. Used in the `pub struct`, `searched_case`
728
885
/// and `simple_case` expr variants above.
729
886
#[ derive( Clone , Debug , PartialEq ) ]
0 commit comments