Uh oh!
There was an error while loading. Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork 2.3k
Implement Eq, PartialEq, Hash for dyn PhysicalExpr#13005
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
Uh oh!
There was an error while loading. Please reload this page.
Changes from all commits
4181cb25e9257c1aa787d8b4ef5666fdd18f1917fa4a69b2cFile filter
Filter by extension
Conversations
Uh oh!
There was an error while loading. Please reload this page.
Jump to
Uh oh!
There was an error while loading. Please reload this page.
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,7 +47,7 @@ use kernels::{ | ||
| }; | ||
| /// Binary expression | ||
| #[derive(Debug, Hash, Clone)] | ||
| #[derive(Debug, Clone, Eq)] | ||
| pub struct BinaryExpr { | ||
| left: Arc<dyn PhysicalExpr>, | ||
| op: Operator, | ||
| @@ -57,6 +56,24 @@ pub struct BinaryExpr { | ||
| fail_on_overflow: bool, | ||
| } | ||
| // Manually derive PartialEq and Hash to work around https://github.com/rust-lang/rust/issues/78808 | ||
| impl PartialEq for BinaryExpr { | ||
| fn eq(&self, other: &Self) -> bool { | ||
| self.left.eq(&other.left) | ||
| && self.op.eq(&other.op) | ||
| && self.right.eq(&other.right) | ||
| && self.fail_on_overflow.eq(&other.fail_on_overflow) | ||
| } | ||
| } | ||
| impl Hash for BinaryExpr { | ||
| fn hash<H: std::hash::Hasher>(&self, state: &mut H) { | ||
| self.left.hash(state); | ||
| self.op.hash(state); | ||
| self.right.hash(state); | ||
| self.fail_on_overflow.hash(state); | ||
| } | ||
| } | ||
| impl BinaryExpr { | ||
| /// Create new binary expression | ||
| pub fn new( | ||
| @@ -477,11 +494,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 +537,6 @@ impl PhysicalExpr for BinaryExpr { | ||
| } | ||
| } | ||
| impl PartialEq<dyn Any> for BinaryExpr { | ||
Contributor 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)] | ||
Contributor 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 ContributorAuthor 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 Contributor 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? ContributorAuthor 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 | ||
Uh oh!
There was an error while loading. Please reload this page.
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.