@@ -140,6 +140,8 @@ pub trait Memo<T: NodeType>: 'static + Send + Sync {
140
140
fn get_all_exprs_in_group ( & self , group_id : GroupId ) -> Vec < ExprId > {
141
141
let group = self . get_group ( group_id) ;
142
142
let mut exprs = group. group_exprs . iter ( ) . copied ( ) . collect_vec ( ) ;
143
+ // Sort so that we can get a stable processing order for the expressions, therefore making regression test
144
+ // yield a stable result across different platforms.
143
145
exprs. sort ( ) ;
144
146
exprs
145
147
}
@@ -163,6 +165,9 @@ pub trait Memo<T: NodeType>: 'static + Send + Sync {
163
165
/// separate entity. If the representation stores predicates in the rel node children, the
164
166
/// repr should use this function to get the predicate binding. Otherwise, use `ger_pred`
165
167
/// for those predicates stored within the `predicates` field.
168
+ ///
169
+ /// TODO: this can be removed after the predicate refactor, unless someone comes up with a
170
+ /// plan representation that embeds predicates in the plan node.
166
171
fn get_predicate_binding ( & self , group_id : GroupId ) -> Option < ArcPlanNode < T > > {
167
172
get_predicate_binding_group_inner ( self , group_id, true )
168
173
}
@@ -676,7 +681,10 @@ impl<T: NodeType> NaiveMemo<T> {
676
681
mod tests {
677
682
678
683
use super :: * ;
679
- use crate :: nodes:: { PredNode , Value } ;
684
+ use crate :: {
685
+ nodes:: { PredNode , Value } ,
686
+ property:: PropertyBuilder ,
687
+ } ;
680
688
681
689
#[ derive( Debug , Clone , PartialEq , Eq , Hash ) ]
682
690
enum MemoTestRelTyp {
@@ -873,4 +881,64 @@ mod tests {
873
881
) ; // these two expressions are merged
874
882
assert_eq ! ( memo. get_expr_info( expr1) , memo. get_expr_info( expr2) ) ;
875
883
}
884
+
885
+ struct TestPropertyBuilder ;
886
+
887
+ #[ derive( Clone , Debug ) ]
888
+ struct TestProp ( Vec < String > ) ;
889
+ impl std:: fmt:: Display for TestProp {
890
+ fn fmt ( & self , f : & mut std:: fmt:: Formatter < ' _ > ) -> std:: fmt:: Result {
891
+ write ! ( f, "{:?}" , self . 0 )
892
+ }
893
+ }
894
+ impl PropertyBuilder < MemoTestRelTyp > for TestPropertyBuilder {
895
+ type Prop = TestProp ;
896
+ fn derive (
897
+ & self ,
898
+ typ : MemoTestRelTyp ,
899
+ pred : & [ ArcPredNode < MemoTestRelTyp > ] ,
900
+ children : & [ & Self :: Prop ] ,
901
+ ) -> Self :: Prop {
902
+ match typ {
903
+ MemoTestRelTyp :: Join => {
904
+ let mut a = children[ 0 ] . 0 . clone ( ) ;
905
+ let b = children[ 1 ] . 0 . clone ( ) ;
906
+ a. extend ( b) ;
907
+ TestProp ( a)
908
+ }
909
+ MemoTestRelTyp :: Project => {
910
+ let preds = & pred[ 0 ] . children ;
911
+ TestProp (
912
+ preds
913
+ . iter ( )
914
+ . map ( |x| x. data . as_ref ( ) . unwrap ( ) . as_i64 ( ) . to_string ( ) )
915
+ . collect ( ) ,
916
+ )
917
+ }
918
+ MemoTestRelTyp :: Scan => TestProp ( vec ! [ "scan_col" . to_string( ) ] ) ,
919
+ }
920
+ }
921
+ fn property_name ( & self ) -> & ' static str {
922
+ "test"
923
+ }
924
+ }
925
+
926
+ #[ test]
927
+ fn logical_property ( ) {
928
+ let mut memo = NaiveMemo :: new ( Arc :: new ( [ Box :: new ( TestPropertyBuilder ) ] ) ) ;
929
+ let ( group_id, _) = memo. add_new_expr ( join (
930
+ scan ( "t1" ) ,
931
+ project (
932
+ scan ( "t2" ) ,
933
+ list ( vec ! [ expr( Value :: Int64 ( 1 ) ) , expr( Value :: Int64 ( 2 ) ) ] ) ,
934
+ ) ,
935
+ expr ( Value :: Bool ( true ) ) ,
936
+ ) ) ;
937
+ let group = memo. get_group ( group_id) ;
938
+ assert_eq ! ( group. properties. len( ) , 1 ) ;
939
+ assert_eq ! (
940
+ group. properties[ 0 ] . downcast_ref:: <TestProp >( ) . unwrap( ) . 0 ,
941
+ vec![ "scan_col" , "1" , "2" ]
942
+ ) ;
943
+ }
876
944
}
0 commit comments