-
Notifications
You must be signed in to change notification settings - Fork 1.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Implement Eq
, PartialEq
, Hash
for dyn PhysicalExpr
#13005
Changes from 1 commit
4181cb2
5e9257c
1aa787d
8b4ef56
66fdd18
f1917fa
4a69b2c
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -17,11 +17,10 @@ | |
|
||
mod kernels; | ||
|
||
use std::hash::{Hash, Hasher}; | ||
use std::hash::Hash; | ||
use std::{any::Any, sync::Arc}; | ||
|
||
use crate::intervals::cp_solver::{propagate_arithmetic, propagate_comparison}; | ||
use crate::physical_expr::down_cast_any_ref; | ||
use crate::PhysicalExpr; | ||
|
||
use arrow::array::*; | ||
|
@@ -48,11 +47,11 @@ use kernels::{ | |
}; | ||
|
||
/// Binary expression | ||
#[derive(Debug, Hash, Clone)] | ||
pub struct BinaryExpr { | ||
left: Arc<dyn PhysicalExpr>, | ||
#[derive(Debug, Hash, Clone, Eq, PartialEq)] | ||
pub struct BinaryExpr<DynPhysicalExpr: ?Sized = dyn PhysicalExpr> { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The removal of the boiler plate in this PR is great ❤️ I feel like this additional trait / workaround is non ideal as it makes understanding the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I am playing around with it to see if I can avoid it somehow There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Here is one way that seems to work: peter-toth#5 More verbose, but I think it keeps the structs simpler to understand There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Sure, we don't need to keep the generic parameter workaround. I agree that those params look a bit weird. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Github copilot and I banged out the code. However, I think I accidentally push the commits to your branch 😬 -- hopefully that is ok There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. No problem. 😁 I've just updated the PR description. |
||
left: Arc<DynPhysicalExpr>, | ||
op: Operator, | ||
right: Arc<dyn PhysicalExpr>, | ||
right: Arc<DynPhysicalExpr>, | ||
/// Specifies whether an error is returned on overflow or not | ||
fail_on_overflow: bool, | ||
} | ||
|
@@ -477,11 +476,6 @@ impl PhysicalExpr for BinaryExpr { | |
} | ||
} | ||
|
||
fn dyn_hash(&self, state: &mut dyn Hasher) { | ||
let mut s = state; | ||
self.hash(&mut s); | ||
} | ||
|
||
/// For each operator, [`BinaryExpr`] has distinct rules. | ||
/// TODO: There may be rules specific to some data types and expression ranges. | ||
fn get_properties(&self, children: &[ExprProperties]) -> Result<ExprProperties> { | ||
|
@@ -525,20 +519,6 @@ impl PhysicalExpr for BinaryExpr { | |
} | ||
} | ||
|
||
impl PartialEq<dyn Any> for BinaryExpr { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. removing this is great |
||
fn eq(&self, other: &dyn Any) -> bool { | ||
down_cast_any_ref(other) | ||
.downcast_ref::<Self>() | ||
.map(|x| { | ||
self.left.eq(&x.left) | ||
&& self.op == x.op | ||
&& self.right.eq(&x.right) | ||
&& self.fail_on_overflow.eq(&x.fail_on_overflow) | ||
}) | ||
.unwrap_or(false) | ||
} | ||
} | ||
|
||
/// Casts dictionary array to result type for binary numerical operators. Such operators | ||
/// between array and scalar produce a dictionary array other than primitive array of the | ||
/// same operators between array and array. This leads to inconsistent result types causing | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -16,11 +16,10 @@ | |
// under the License. | ||
|
||
use std::borrow::Cow; | ||
use std::hash::{Hash, Hasher}; | ||
use std::hash::Hash; | ||
use std::{any::Any, sync::Arc}; | ||
|
||
use crate::expressions::try_cast; | ||
use crate::physical_expr::down_cast_any_ref; | ||
use crate::PhysicalExpr; | ||
|
||
use arrow::array::*; | ||
|
@@ -37,7 +36,7 @@ use itertools::Itertools; | |
|
||
type WhenThen = (Arc<dyn PhysicalExpr>, Arc<dyn PhysicalExpr>); | ||
|
||
#[derive(Debug, Hash)] | ||
#[derive(Debug, Hash, PartialEq, Eq)] | ||
enum EvalMethod { | ||
/// CASE WHEN condition THEN result | ||
/// [WHEN ...] | ||
|
@@ -80,7 +79,7 @@ enum EvalMethod { | |
/// [WHEN ...] | ||
/// [ELSE result] | ||
/// END | ||
#[derive(Debug, Hash)] | ||
#[derive(Debug, Hash, PartialEq, Eq)] | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. How can it permit auto derivation of There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah, this is probably the strangest part of the bug. If you have double wrappers around There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should we create a ticket to remove those impl's once the bug is resolved? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. How about #13196? |
||
pub struct CaseExpr { | ||
/// Optional base expression that can be compared to literal values in the "when" expressions | ||
expr: Option<Arc<dyn PhysicalExpr>>, | ||
|
@@ -506,39 +505,6 @@ impl PhysicalExpr for CaseExpr { | |
)?)) | ||
} | ||
} | ||
|
||
fn dyn_hash(&self, state: &mut dyn Hasher) { | ||
let mut s = state; | ||
self.hash(&mut s); | ||
} | ||
} | ||
|
||
impl PartialEq<dyn Any> for CaseExpr { | ||
fn eq(&self, other: &dyn Any) -> bool { | ||
down_cast_any_ref(other) | ||
.downcast_ref::<Self>() | ||
.map(|x| { | ||
let expr_eq = match (&self.expr, &x.expr) { | ||
(Some(expr1), Some(expr2)) => expr1.eq(expr2), | ||
(None, None) => true, | ||
_ => false, | ||
}; | ||
let else_expr_eq = match (&self.else_expr, &x.else_expr) { | ||
(Some(expr1), Some(expr2)) => expr1.eq(expr2), | ||
(None, None) => true, | ||
_ => false, | ||
}; | ||
expr_eq | ||
&& else_expr_eq | ||
&& self.when_then_expr.len() == x.when_then_expr.len() | ||
&& self.when_then_expr.iter().zip(x.when_then_expr.iter()).all( | ||
|((when1, then1), (when2, then2))| { | ||
when1.eq(when2) && then1.eq(then2) | ||
}, | ||
) | ||
}) | ||
.unwrap_or(false) | ||
} | ||
} | ||
|
||
/// Create a CASE expression | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe we can add some documentation here explaining why this is needed and what it is used for
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added in f1917fa.