17
17
18
18
use std:: sync:: Arc ;
19
19
20
+ use datafusion_common:: HashMap ;
20
21
pub ( crate ) use datafusion_physical_expr_common:: physical_expr:: PhysicalExpr ;
22
+ pub use datafusion_physical_expr_common:: physical_expr:: PhysicalExprRef ;
21
23
use itertools:: izip;
22
24
23
- /// Shared [`PhysicalExpr`].
24
- pub type PhysicalExprRef = Arc < dyn PhysicalExpr > ;
25
-
26
25
/// This function is similar to the `contains` method of `Vec`. It finds
27
26
/// whether `expr` is among `physical_exprs`.
28
27
pub fn physical_exprs_contains (
@@ -48,31 +47,24 @@ pub fn physical_exprs_bag_equal(
48
47
lhs : & [ Arc < dyn PhysicalExpr > ] ,
49
48
rhs : & [ Arc < dyn PhysicalExpr > ] ,
50
49
) -> bool {
51
- // TODO: Once we can use `HashMap`s with `Arc<dyn PhysicalExpr>`, this
52
- // function should use a `HashMap` to reduce computational complexity.
53
- if lhs. len ( ) == rhs. len ( ) {
54
- let mut rhs_vec = rhs. to_vec ( ) ;
55
- for expr in lhs {
56
- if let Some ( idx) = rhs_vec. iter ( ) . position ( |e| expr. eq ( e) ) {
57
- rhs_vec. swap_remove ( idx) ;
58
- } else {
59
- return false ;
60
- }
61
- }
62
- true
63
- } else {
64
- false
50
+ let mut multi_set_lhs: HashMap < _ , usize > = HashMap :: new ( ) ;
51
+ let mut multi_set_rhs: HashMap < _ , usize > = HashMap :: new ( ) ;
52
+ for expr in lhs {
53
+ * multi_set_lhs. entry ( expr) . or_insert ( 0 ) += 1 ;
54
+ }
55
+ for expr in rhs {
56
+ * multi_set_rhs. entry ( expr) . or_insert ( 0 ) += 1 ;
65
57
}
58
+ multi_set_lhs == multi_set_rhs
66
59
}
67
60
68
61
#[ cfg( test) ]
69
62
mod tests {
70
- use std :: sync :: Arc ;
63
+ use super :: * ;
71
64
72
65
use crate :: expressions:: { Column , Literal } ;
73
66
use crate :: physical_expr:: {
74
67
physical_exprs_bag_equal, physical_exprs_contains, physical_exprs_equal,
75
- PhysicalExpr ,
76
68
} ;
77
69
78
70
use datafusion_common:: ScalarValue ;
0 commit comments