@@ -52,7 +52,7 @@ use datafusion_expr_common::sort_properties::ExprProperties;
5252/// [`Expr`]: https://docs.rs/datafusion/latest/datafusion/logical_expr/enum.Expr.html
5353/// [`create_physical_expr`]: https://docs.rs/datafusion/latest/datafusion/physical_expr/fn.create_physical_expr.html
5454/// [`Column`]: https://docs.rs/datafusion/latest/datafusion/physical_expr/expressions/struct.Column.html
55- pub trait PhysicalExpr : Send + Sync + Display + Debug + PartialEq < dyn Any > {
55+ pub trait PhysicalExpr : Send + Sync + Display + Debug + DynEq + DynHash {
5656 /// Returns the physical expression as [`Any`] so that it can be
5757 /// downcast to a specific implementation.
5858 fn as_any ( & self ) -> & dyn Any ;
@@ -141,38 +141,6 @@ pub trait PhysicalExpr: Send + Sync + Display + Debug + PartialEq<dyn Any> {
141141 Ok ( Some ( vec ! [ ] ) )
142142 }
143143
144- /// Update the hash `state` with this expression requirements from
145- /// [`Hash`].
146- ///
147- /// This method is required to support hashing [`PhysicalExpr`]s. To
148- /// implement it, typically the type implementing
149- /// [`PhysicalExpr`] implements [`Hash`] and
150- /// then the following boiler plate is used:
151- ///
152- /// # Example:
153- /// ```
154- /// // User defined expression that derives Hash
155- /// #[derive(Hash, Debug, PartialEq, Eq)]
156- /// struct MyExpr {
157- /// val: u64
158- /// }
159- ///
160- /// // impl PhysicalExpr {
161- /// // ...
162- /// # impl MyExpr {
163- /// // Boiler plate to call the derived Hash impl
164- /// fn dyn_hash(&self, state: &mut dyn std::hash::Hasher) {
165- /// use std::hash::Hash;
166- /// let mut s = state;
167- /// self.hash(&mut s);
168- /// }
169- /// // }
170- /// # }
171- /// ```
172- /// Note: [`PhysicalExpr`] is not constrained by [`Hash`]
173- /// directly because it must remain object safe.
174- fn dyn_hash ( & self , _state : & mut dyn Hasher ) ;
175-
176144 /// Calculates the properties of this [`PhysicalExpr`] based on its
177145 /// children's properties (i.e. order and range), recursively aggregating
178146 /// the information from its children. In cases where the [`PhysicalExpr`]
@@ -183,6 +151,42 @@ pub trait PhysicalExpr: Send + Sync + Display + Debug + PartialEq<dyn Any> {
183151 }
184152}
185153
154+ /// [`PhysicalExpr`] can't be constrained by [`Eq`] directly because it must remain object
155+ /// safe. To ease implementation blanket implementation is provided for [`Eq`] types.
156+ pub trait DynEq {
157+ fn dyn_eq ( & self , other : & dyn Any ) -> bool ;
158+ }
159+
160+ impl < T : Eq + Any > DynEq for T {
161+ fn dyn_eq ( & self , other : & dyn Any ) -> bool {
162+ other
163+ . downcast_ref :: < Self > ( )
164+ . map_or ( false , |other| other == self )
165+ }
166+ }
167+
168+ impl PartialEq for dyn PhysicalExpr {
169+ fn eq ( & self , other : & Self ) -> bool {
170+ self . dyn_eq ( other. as_any ( ) )
171+ }
172+ }
173+
174+ impl Eq for dyn PhysicalExpr { }
175+
176+ /// [`PhysicalExpr`] can't be constrained by [`Hash`] directly because it must remain
177+ /// object safe. To ease implementation blanket implementation is provided for [`Hash`]
178+ /// types.
179+ pub trait DynHash {
180+ fn dyn_hash ( & self , _state : & mut dyn Hasher ) ;
181+ }
182+
183+ impl < T : Hash + Any > DynHash for T {
184+ fn dyn_hash ( & self , mut state : & mut dyn Hasher ) {
185+ self . type_id ( ) . hash ( & mut state) ;
186+ self . hash ( & mut state)
187+ }
188+ }
189+
186190impl Hash for dyn PhysicalExpr {
187191 fn hash < H : Hasher > ( & self , state : & mut H ) {
188192 self . dyn_hash ( state) ;
@@ -210,20 +214,6 @@ pub fn with_new_children_if_necessary(
210214 }
211215}
212216
213- pub fn down_cast_any_ref ( any : & dyn Any ) -> & dyn Any {
214- if any. is :: < Arc < dyn PhysicalExpr > > ( ) {
215- any. downcast_ref :: < Arc < dyn PhysicalExpr > > ( )
216- . unwrap ( )
217- . as_any ( )
218- } else if any. is :: < Box < dyn PhysicalExpr > > ( ) {
219- any. downcast_ref :: < Box < dyn PhysicalExpr > > ( )
220- . unwrap ( )
221- . as_any ( )
222- } else {
223- any
224- }
225- }
226-
227217/// Returns [`Display`] able a list of [`PhysicalExpr`]
228218///
229219/// Example output: `[a + 1, b]`
0 commit comments