diff --git a/datafusion/physical-expr/src/expressions/binary.rs b/datafusion/physical-expr/src/expressions/binary.rs index 7cdac6cbb1f9..649861f92602 100644 --- a/datafusion/physical-expr/src/expressions/binary.rs +++ b/datafusion/physical-expr/src/expressions/binary.rs @@ -47,15 +47,43 @@ use kernels::{ }; /// Binary expression -#[derive(Debug, Hash, Clone, Eq, PartialEq)] -pub struct BinaryExpr { - left: Arc, +#[derive(Debug, Clone, Eq)] +pub struct BinaryExpr { + left: Arc, op: Operator, - right: Arc, + right: Arc, /// Specifies whether an error is returned on overflow or not fail_on_overflow: bool, } +// Manaully derive PartialEq and Hash to work around https://github.com/rust-lang/rust/issues/78808 +// +// Without this workaround the derive macro generates code with the following issue: +// error[E0507]: cannot move out of `other.left` which is behind a shared reference +// --> datafusion/physical-expr/src/expressions/binary.rs:53:5 +// | +// 51 | #[derive(Debug, Hash, Clone, Eq, PartialEq)] +// | --------- in this derive macro expansion +// 52 | pub struct BinaryExpr { +// 53 | left: Arc, +// | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ move occurs because `other.left` has type `Arc`, which does not implement the `Copy` trait +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(&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(