1
- use itertools:: { Either , Itertools } ;
2
- use partiql_logical as logical;
3
- use partiql_logical:: {
4
- AggFunc , BagOperator , BinaryOp , BindingsOp , CallName , GraphMatchExpr , GroupingStrategy ,
5
- IsTypeExpr , JoinKind , Lit , LogicalPlan , OpId , PathComponent , Pattern , PatternMatchExpr ,
6
- SearchedCase , SetQuantifier , SortSpecNullOrder , SortSpecOrder , Type , UnaryOp , ValueExpr ,
7
- VarRefType ,
8
- } ;
9
- use petgraph:: prelude:: StableGraph ;
10
- use std:: collections:: HashMap ;
11
-
12
1
use crate :: error:: { ErrorNode , PlanErr , PlanningError } ;
13
2
use crate :: eval;
14
3
use crate :: eval:: evaluable:: {
@@ -23,11 +12,22 @@ use crate::eval::expr::{
23
12
EvalLikeNonStringNonLiteralMatch , EvalListExpr , EvalLitExpr , EvalOpBinary , EvalOpUnary ,
24
13
EvalPath , EvalSearchedCaseExpr , EvalStringFn , EvalTrimFn , EvalTupleExpr , EvalVarRef ,
25
14
} ;
15
+ use crate :: eval:: graph:: string_graph:: StringGraphTypes ;
26
16
use crate :: eval:: EvalPlan ;
17
+ use itertools:: { Either , Itertools } ;
27
18
use partiql_catalog:: catalog:: { Catalog , FunctionEntryFunction } ;
28
19
use partiql_extension_ion:: boxed_ion:: BoxedIonType ;
20
+ use partiql_logical as logical;
21
+ use partiql_logical:: {
22
+ AggFunc , BagOperator , BinaryOp , BindingsOp , CallName , GraphMatchExpr , GroupingStrategy ,
23
+ IsTypeExpr , JoinKind , Lit , LogicalPlan , OpId , PathComponent , Pattern , PatternMatchExpr ,
24
+ SearchedCase , SetQuantifier , SortSpecNullOrder , SortSpecOrder , Type , UnaryOp , ValueExpr ,
25
+ VarRefType ,
26
+ } ;
29
27
use partiql_value:: boxed_variant:: DynBoxedVariantTypeFactory ;
30
28
use partiql_value:: { Bag , List , Tuple , Value , Variant } ;
29
+ use petgraph:: prelude:: StableGraph ;
30
+ use std:: collections:: HashMap ;
31
31
32
32
#[ macro_export]
33
33
macro_rules! correct_num_args_or_err {
@@ -494,13 +494,15 @@ impl<'c> EvaluatorPlanner<'c> {
494
494
495
495
( "pattern expr" , expr)
496
496
}
497
- ValueExpr :: GraphMatch ( GraphMatchExpr { value, pattern } ) => {
498
- //let pattern = plan_graph_match(pattern);
499
- let pattern = todo ! ( ) ;
500
-
501
- let expr = EvalGraphMatch :: new ( pattern) . bind :: < { STRICT } > ( plan_args ( & [ value] ) ) ;
502
- ( "graphmatch expr" , expr)
503
- }
497
+ ValueExpr :: GraphMatch ( GraphMatchExpr { value, pattern } ) => (
498
+ "graphmatch expr" ,
499
+ match plan_graph_plan ( pattern) {
500
+ Ok ( pattern) => {
501
+ EvalGraphMatch :: new ( pattern) . bind :: < { STRICT } > ( plan_args ( & [ value] ) )
502
+ }
503
+ Err ( e) => Ok ( self . err ( e) as Box < dyn EvalExpr > ) ,
504
+ } ,
505
+ ) ,
504
506
ValueExpr :: SubQueryExpr ( expr) => (
505
507
"subquery" ,
506
508
Ok ( Box :: new ( EvalSubQueryExpr :: new (
@@ -791,6 +793,122 @@ impl<'c> EvaluatorPlanner<'c> {
791
793
}
792
794
}
793
795
796
+ fn plan_graph_plan (
797
+ pattern : & partiql_logical:: PathPatternMatch ,
798
+ ) -> Result < eval:: graph:: plan:: PathPatternMatch < StringGraphTypes > , PlanningError > {
799
+ use eval:: graph:: plan as physical;
800
+ use partiql_logical as logical;
801
+
802
+ fn plan_bind_spec (
803
+ pattern : & logical:: BindSpec ,
804
+ ) -> Result < physical:: BindSpec < StringGraphTypes > , PlanningError > {
805
+ Ok ( physical:: BindSpec ( pattern. 0 . clone ( ) ) )
806
+ }
807
+
808
+ fn plan_label_filter (
809
+ pattern : & logical:: LabelFilter ,
810
+ ) -> Result < physical:: LabelFilter < StringGraphTypes > , PlanningError > {
811
+ Ok ( match pattern {
812
+ logical:: LabelFilter :: Always => physical:: LabelFilter :: Always ,
813
+ logical:: LabelFilter :: Never => physical:: LabelFilter :: Never ,
814
+ logical:: LabelFilter :: Named ( n) => physical:: LabelFilter :: Named ( n. clone ( ) ) ,
815
+ } )
816
+ }
817
+
818
+ fn plan_value_filter (
819
+ pattern : & logical:: ValueFilter ,
820
+ ) -> Result < physical:: ValueFilter , PlanningError > {
821
+ Ok ( match pattern {
822
+ logical:: ValueFilter :: Always => physical:: ValueFilter :: Always ,
823
+ } )
824
+ }
825
+
826
+ fn plan_node_filter (
827
+ pattern : & logical:: NodeFilter ,
828
+ ) -> Result < physical:: NodeFilter < StringGraphTypes > , PlanningError > {
829
+ Ok ( physical:: NodeFilter {
830
+ label : plan_label_filter ( & pattern. label ) ?,
831
+ filter : plan_value_filter ( & pattern. filter ) ?,
832
+ } )
833
+ }
834
+
835
+ fn plan_edge_filter (
836
+ pattern : & logical:: EdgeFilter ,
837
+ ) -> Result < physical:: EdgeFilter < StringGraphTypes > , PlanningError > {
838
+ Ok ( physical:: EdgeFilter {
839
+ label : plan_label_filter ( & pattern. label ) ?,
840
+ filter : plan_value_filter ( & pattern. filter ) ?,
841
+ } )
842
+ }
843
+
844
+ fn plan_step_filter (
845
+ pattern : & logical:: StepFilter ,
846
+ ) -> Result < physical:: StepFilter < StringGraphTypes > , PlanningError > {
847
+ let dir = match pattern. dir {
848
+ logical:: DirectionFilter :: L => physical:: DirectionFilter :: L ,
849
+ logical:: DirectionFilter :: R => physical:: DirectionFilter :: R ,
850
+ logical:: DirectionFilter :: U => physical:: DirectionFilter :: U ,
851
+ logical:: DirectionFilter :: LU => physical:: DirectionFilter :: LU ,
852
+ logical:: DirectionFilter :: UR => physical:: DirectionFilter :: UR ,
853
+ logical:: DirectionFilter :: LR => physical:: DirectionFilter :: LR ,
854
+ logical:: DirectionFilter :: LUR => physical:: DirectionFilter :: LUR ,
855
+ } ;
856
+ Ok ( physical:: StepFilter {
857
+ dir,
858
+ triple : plan_triple_filter ( & pattern. triple ) ?,
859
+ } )
860
+ }
861
+
862
+ fn plan_triple_filter (
863
+ pattern : & logical:: TripleFilter ,
864
+ ) -> Result < physical:: TripleFilter < StringGraphTypes > , PlanningError > {
865
+ Ok ( physical:: TripleFilter {
866
+ lhs : plan_node_filter ( & pattern. lhs ) ?,
867
+ e : plan_edge_filter ( & pattern. e ) ?,
868
+ rhs : plan_node_filter ( & pattern. rhs ) ?,
869
+ } )
870
+ }
871
+
872
+ fn plan_node_match (
873
+ pattern : & logical:: NodeMatch ,
874
+ ) -> Result < physical:: NodeMatch < StringGraphTypes > , PlanningError > {
875
+ Ok ( physical:: NodeMatch {
876
+ binder : plan_bind_spec ( & pattern. binder ) ?,
877
+ spec : plan_node_filter ( & pattern. spec ) ?,
878
+ } )
879
+ }
880
+
881
+ fn plan_path_match (
882
+ pattern : & logical:: PathMatch ,
883
+ ) -> Result < physical:: PathMatch < StringGraphTypes > , PlanningError > {
884
+ let ( l, m, r) = & pattern. binders ;
885
+ let binders = ( plan_bind_spec ( l) ?, plan_bind_spec ( m) ?, plan_bind_spec ( r) ?) ;
886
+ Ok ( physical:: PathMatch {
887
+ binders,
888
+ spec : plan_step_filter ( & pattern. spec ) ?,
889
+ } )
890
+ }
891
+
892
+ fn plan_path_pattern_match (
893
+ pattern : & logical:: PathPatternMatch ,
894
+ ) -> Result < physical:: PathPatternMatch < StringGraphTypes > , PlanningError > {
895
+ Ok ( match pattern {
896
+ logical:: PathPatternMatch :: Node ( n) => {
897
+ physical:: PathPatternMatch :: Node ( plan_node_match ( n) ?)
898
+ }
899
+ logical:: PathPatternMatch :: Match ( m) => {
900
+ physical:: PathPatternMatch :: Match ( plan_path_match ( m) ?)
901
+ }
902
+ logical:: PathPatternMatch :: Concat ( ms) => {
903
+ let ms: Result < Vec < _ > , _ > = ms. iter ( ) . map ( plan_path_pattern_match) . collect ( ) ;
904
+ physical:: PathPatternMatch :: Concat ( ms?)
905
+ }
906
+ } )
907
+ }
908
+
909
+ plan_path_pattern_match ( pattern)
910
+ }
911
+
794
912
fn plan_lit ( lit : & Lit ) -> Result < Value , PlanningError > {
795
913
let lit_to_val = |lit| plan_lit ( lit) ;
796
914
Ok ( match lit {
0 commit comments