diff --git a/datafusion/src/physical_plan/expressions/average.rs b/datafusion/src/physical_plan/expressions/average.rs index f09298998a2a4..a57c525394171 100644 --- a/datafusion/src/physical_plan/expressions/average.rs +++ b/datafusion/src/physical_plan/expressions/average.rs @@ -171,13 +171,8 @@ impl Accumulator for AvgAccumulator { Ok(vec![ScalarValue::from(self.count), self.sum.clone()]) } - fn update(&mut self, values: &[ScalarValue]) -> Result<()> { - let values = &values[0]; - - self.count += (!values.is_null()) as u64; - self.sum = sum::sum(&self.sum, values)?; - - Ok(()) + fn update(&mut self, _values: &[ScalarValue]) -> Result<()> { + unimplemented!("update_batch is implemented instead"); } fn update_batch(&mut self, values: &[ArrayRef]) -> Result<()> { @@ -188,18 +183,8 @@ impl Accumulator for AvgAccumulator { Ok(()) } - fn merge(&mut self, states: &[ScalarValue]) -> Result<()> { - let count = &states[0]; - // counts are summed - if let ScalarValue::UInt64(Some(c)) = count { - self.count += c - } else { - unreachable!() - }; - - // sums are summed - self.sum = sum::sum(&self.sum, &states[1])?; - Ok(()) + fn merge(&mut self, _states: &[ScalarValue]) -> Result<()> { + unimplemented!("merge_batch is implemented instead"); } fn merge_batch(&mut self, states: &[ArrayRef]) -> Result<()> { diff --git a/datafusion/src/physical_plan/expressions/count.rs b/datafusion/src/physical_plan/expressions/count.rs index 30c44f1c03b45..edd9aea0219ac 100644 --- a/datafusion/src/physical_plan/expressions/count.rs +++ b/datafusion/src/physical_plan/expressions/count.rs @@ -112,22 +112,12 @@ impl Accumulator for CountAccumulator { Ok(()) } - fn update(&mut self, values: &[ScalarValue]) -> Result<()> { - let value = &values[0]; - if !value.is_null() { - self.count += 1; - } - Ok(()) + fn update(&mut self, _values: &[ScalarValue]) -> Result<()> { + unimplemented!("update_batch is implemented instead"); } - fn merge(&mut self, states: &[ScalarValue]) -> Result<()> { - let count = &states[0]; - if let ScalarValue::UInt64(Some(delta)) = count { - self.count += *delta; - } else { - unreachable!() - } - Ok(()) + fn merge(&mut self, _states: &[ScalarValue]) -> Result<()> { + unimplemented!("merge_batch is implemented instead"); } fn merge_batch(&mut self, states: &[ArrayRef]) -> Result<()> { diff --git a/datafusion/src/physical_plan/expressions/sum.rs b/datafusion/src/physical_plan/expressions/sum.rs index 027736dbc478c..61691c4933ee3 100644 --- a/datafusion/src/physical_plan/expressions/sum.rs +++ b/datafusion/src/physical_plan/expressions/sum.rs @@ -353,10 +353,8 @@ impl Accumulator for SumAccumulator { Ok(vec![self.sum.clone()]) } - fn update(&mut self, values: &[ScalarValue]) -> Result<()> { - // sum(v1, v2, v3) = v1 + v2 + v3 - self.sum = sum(&self.sum, &values[0])?; - Ok(()) + fn update(&mut self, _values: &[ScalarValue]) -> Result<()> { + unimplemented!("update_batch is implemented instead"); } fn update_batch(&mut self, values: &[ArrayRef]) -> Result<()> { @@ -365,9 +363,8 @@ impl Accumulator for SumAccumulator { Ok(()) } - fn merge(&mut self, states: &[ScalarValue]) -> Result<()> { - // sum(sum1, sum2) = sum1 + sum2 - self.update(states) + fn merge(&mut self, _states: &[ScalarValue]) -> Result<()> { + unimplemented!("merge_batch is implemented instead"); } fn merge_batch(&mut self, states: &[ArrayRef]) -> Result<()> { diff --git a/datafusion/src/physical_plan/expressions/variance.rs b/datafusion/src/physical_plan/expressions/variance.rs index 75164405e537f..05d8e4154d729 100644 --- a/datafusion/src/physical_plan/expressions/variance.rs +++ b/datafusion/src/physical_plan/expressions/variance.rs @@ -302,122 +302,12 @@ impl Accumulator for VarianceAccumulator { Ok(()) } - fn update(&mut self, values: &[ScalarValue]) -> Result<()> { - let values = &values[0]; - let is_empty = values.is_null(); - let mean = ScalarValue::from(self.mean); - let m2 = ScalarValue::from(self.m2); - - if !is_empty { - let new_count = self.count + 1; - let delta1 = ScalarValue::add(values, &mean.arithmetic_negate())?; - let new_mean = ScalarValue::add( - &ScalarValue::div(&delta1, &ScalarValue::from(new_count as f64))?, - &mean, - )?; - let delta2 = ScalarValue::add(values, &new_mean.arithmetic_negate())?; - let tmp = ScalarValue::mul(&delta1, &delta2)?; - - let new_m2 = ScalarValue::add(&m2, &tmp)?; - self.count += 1; - - if let ScalarValue::Float64(Some(c)) = new_mean { - self.mean = c; - } else { - unreachable!() - }; - if let ScalarValue::Float64(Some(m)) = new_m2 { - self.m2 = m; - } else { - unreachable!() - }; - } - - Ok(()) + fn update(&mut self, _values: &[ScalarValue]) -> Result<()> { + unimplemented!("update_batch is implemented instead"); } - fn merge(&mut self, states: &[ScalarValue]) -> Result<()> { - let count; - let mean; - let m2; - let mut new_count: u64 = self.count; - - if let ScalarValue::UInt64(Some(c)) = states[0] { - count = c; - } else { - unreachable!() - }; - - if count == 0_u64 { - return Ok(()); - } - - if let ScalarValue::Float64(Some(m)) = states[1] { - mean = m; - } else { - unreachable!() - }; - if let ScalarValue::Float64(Some(n)) = states[2] { - m2 = n; - } else { - unreachable!() - }; - - if self.count == 0 { - self.count = count; - self.mean = mean; - self.m2 = m2; - return Ok(()); - } - - new_count += count; - - let mean1 = ScalarValue::from(self.mean); - let mean2 = ScalarValue::from(mean); - - let new_mean = ScalarValue::add( - &ScalarValue::div( - &ScalarValue::mul(&mean1, &ScalarValue::from(self.count))?, - &ScalarValue::from(new_count as f64), - )?, - &ScalarValue::div( - &ScalarValue::mul(&mean2, &ScalarValue::from(count))?, - &ScalarValue::from(new_count as f64), - )?, - )?; - - let delta = ScalarValue::add(&mean2.arithmetic_negate(), &mean1)?; - let delta_sqrt = ScalarValue::mul(&delta, &delta)?; - let new_m2 = ScalarValue::add( - &ScalarValue::add( - &ScalarValue::mul( - &delta_sqrt, - &ScalarValue::div( - &ScalarValue::mul( - &ScalarValue::from(self.count), - &ScalarValue::from(count), - )?, - &ScalarValue::from(new_count as f64), - )?, - )?, - &ScalarValue::from(self.m2), - )?, - &ScalarValue::from(m2), - )?; - - self.count = new_count; - if let ScalarValue::Float64(Some(c)) = new_mean { - self.mean = c; - } else { - unreachable!() - }; - if let ScalarValue::Float64(Some(m)) = new_m2 { - self.m2 = m; - } else { - unreachable!() - }; - - Ok(()) + fn merge(&mut self, _states: &[ScalarValue]) -> Result<()> { + unimplemented!("merge_batch is implemented instead"); } fn evaluate(&self) -> Result { diff --git a/datafusion/src/scalar.rs b/datafusion/src/scalar.rs index cf6e8a1ac1c2f..cdcf11eccea27 100644 --- a/datafusion/src/scalar.rs +++ b/datafusion/src/scalar.rs @@ -526,301 +526,6 @@ macro_rules! eq_array_primitive { } impl ScalarValue { - /// Return true if the value is numeric - pub fn is_numeric(&self) -> bool { - matches!( - self, - ScalarValue::Float32(_) - | ScalarValue::Float64(_) - | ScalarValue::Decimal128(_, _, _) - | ScalarValue::Int8(_) - | ScalarValue::Int16(_) - | ScalarValue::Int32(_) - | ScalarValue::Int64(_) - | ScalarValue::UInt8(_) - | ScalarValue::UInt16(_) - | ScalarValue::UInt32(_) - | ScalarValue::UInt64(_) - ) - } - - /// Add two numeric ScalarValues - pub fn add(lhs: &ScalarValue, rhs: &ScalarValue) -> Result { - if !lhs.is_numeric() || !rhs.is_numeric() { - return Err(DataFusionError::Internal(format!( - "Addition only supports numeric types, \ - here has {:?} and {:?}", - lhs.get_datatype(), - rhs.get_datatype() - ))); - } - - if lhs.is_null() || rhs.is_null() { - return Err(DataFusionError::Internal( - "Addition does not support empty values".to_string(), - )); - } - - // TODO: Finding a good way to support operation between different types without - // writing a hige match block. - // TODO: Add support for decimal types - match (lhs, rhs) { - (ScalarValue::Decimal128(_, _, _), _) | - (_, ScalarValue::Decimal128(_, _, _)) => { - Err(DataFusionError::Internal( - "Addition with Decimals are not supported for now".to_string() - )) - }, - // f64 / _ - (ScalarValue::Float64(f1), ScalarValue::Float64(f2)) => { - Ok(ScalarValue::Float64(Some(f1.unwrap() + f2.unwrap()))) - }, - // f32 / _ - (ScalarValue::Float32(f1), ScalarValue::Float64(f2)) => { - Ok(ScalarValue::Float64(Some(f1.unwrap() as f64 + f2.unwrap()))) - }, - (ScalarValue::Float32(f1), ScalarValue::Float32(f2)) => { - Ok(ScalarValue::Float64(Some(f1.unwrap() as f64 + f2.unwrap() as f64))) - }, - // i64 / _ - (ScalarValue::Int64(f1), ScalarValue::Float64(f2)) => { - Ok(ScalarValue::Float64(Some(f1.unwrap() as f64 + f2.unwrap()))) - }, - (ScalarValue::Int64(f1), ScalarValue::Int64(f2)) => { - Ok(ScalarValue::Int64(Some(f1.unwrap() + f2.unwrap()))) - }, - // i32 / _ - (ScalarValue::Int32(f1), ScalarValue::Float64(f2)) => { - Ok(ScalarValue::Float64(Some(f1.unwrap() as f64 + f2.unwrap()))) - }, - (ScalarValue::Int32(f1), ScalarValue::Int32(f2)) => { - Ok(ScalarValue::Int64(Some(f1.unwrap() as i64 + f2.unwrap() as i64))) - }, - // i16 / _ - (ScalarValue::Int16(f1), ScalarValue::Float64(f2)) => { - Ok(ScalarValue::Float64(Some(f1.unwrap() as f64 + f2.unwrap()))) - }, - (ScalarValue::Int16(f1), ScalarValue::Int16(f2)) => { - Ok(ScalarValue::Int32(Some(f1.unwrap() as i32 + f2.unwrap() as i32))) - }, - // i8 / _ - (ScalarValue::Int8(f1), ScalarValue::Float64(f2)) => { - Ok(ScalarValue::Float64(Some(f1.unwrap() as f64 + f2.unwrap()))) - }, - (ScalarValue::Int8(f1), ScalarValue::Int8(f2)) => { - Ok(ScalarValue::Int16(Some(f1.unwrap() as i16 + f2.unwrap() as i16))) - }, - // u64 / _ - (ScalarValue::UInt64(f1), ScalarValue::Float64(f2)) => { - Ok(ScalarValue::Float64(Some(f1.unwrap() as f64 + f2.unwrap()))) - }, - (ScalarValue::UInt64(f1), ScalarValue::UInt64(f2)) => { - Ok(ScalarValue::UInt64(Some(f1.unwrap() as u64 + f2.unwrap() as u64))) - }, - // u32 / _ - (ScalarValue::UInt32(f1), ScalarValue::Float64(f2)) => { - Ok(ScalarValue::Float64(Some(f1.unwrap() as f64 + f2.unwrap()))) - }, - (ScalarValue::UInt32(f1), ScalarValue::UInt32(f2)) => { - Ok(ScalarValue::UInt64(Some(f1.unwrap() as u64 + f2.unwrap() as u64))) - }, - // u16 / _ - (ScalarValue::UInt16(f1), ScalarValue::Float64(f2)) => { - Ok(ScalarValue::Float64(Some(f1.unwrap() as f64 + f2.unwrap()))) - }, - (ScalarValue::UInt16(f1), ScalarValue::UInt16(f2)) => { - Ok(ScalarValue::UInt32(Some(f1.unwrap() as u32 + f2.unwrap() as u32))) - }, - // u8 / _ - (ScalarValue::UInt8(f1), ScalarValue::Float64(f2)) => { - Ok(ScalarValue::Float64(Some(f1.unwrap() as f64 + f2.unwrap()))) - }, - (ScalarValue::UInt8(f1), ScalarValue::UInt8(f2)) => { - Ok(ScalarValue::UInt16(Some(f1.unwrap() as u16 + f2.unwrap() as u16))) - }, - _ => Err(DataFusionError::Internal( - format!( - "Addition only support calculation with the same type or f64 as one of the numbers for now, here has {:?} and {:?}", - lhs.get_datatype(), rhs.get_datatype() - ))), - } - } - - /// Multiply two numeric ScalarValues - pub fn mul(lhs: &ScalarValue, rhs: &ScalarValue) -> Result { - if !lhs.is_numeric() || !rhs.is_numeric() { - return Err(DataFusionError::Internal(format!( - "Multiplication is only supported on numeric types, \ - here has {:?} and {:?}", - lhs.get_datatype(), - rhs.get_datatype() - ))); - } - - if lhs.is_null() || rhs.is_null() { - return Err(DataFusionError::Internal( - "Multiplication does not support empty values".to_string(), - )); - } - - // TODO: Finding a good way to support operation between different types without - // writing a hige match block. - // TODO: Add support for decimal type - match (lhs, rhs) { - (ScalarValue::Decimal128(_, _, _), _) - | (_, ScalarValue::Decimal128(_, _, _)) => Err(DataFusionError::Internal( - "Multiplication with Decimals are not supported for now".to_string(), - )), - // f64 / _ - (ScalarValue::Float64(f1), ScalarValue::Float64(f2)) => { - Ok(ScalarValue::Float64(Some(f1.unwrap() * f2.unwrap()))) - } - // f32 / _ - (ScalarValue::Float32(f1), ScalarValue::Float32(f2)) => Ok( - ScalarValue::Float64(Some(f1.unwrap() as f64 * f2.unwrap() as f64)), - ), - // i64 / _ - (ScalarValue::Int64(f1), ScalarValue::Int64(f2)) => { - Ok(ScalarValue::Int64(Some(f1.unwrap() * f2.unwrap()))) - } - // i32 / _ - (ScalarValue::Int32(f1), ScalarValue::Int32(f2)) => Ok(ScalarValue::Int64( - Some(f1.unwrap() as i64 * f2.unwrap() as i64), - )), - // i16 / _ - (ScalarValue::Int16(f1), ScalarValue::Int16(f2)) => Ok(ScalarValue::Int32( - Some(f1.unwrap() as i32 * f2.unwrap() as i32), - )), - // i8 / _ - (ScalarValue::Int8(f1), ScalarValue::Int8(f2)) => Ok(ScalarValue::Int16( - Some(f1.unwrap() as i16 * f2.unwrap() as i16), - )), - // u64 / _ - (ScalarValue::UInt64(f1), ScalarValue::UInt64(f2)) => Ok( - ScalarValue::UInt64(Some(f1.unwrap() as u64 * f2.unwrap() as u64)), - ), - // u32 / _ - (ScalarValue::UInt32(f1), ScalarValue::UInt32(f2)) => Ok( - ScalarValue::UInt64(Some(f1.unwrap() as u64 * f2.unwrap() as u64)), - ), - // u16 / _ - (ScalarValue::UInt16(f1), ScalarValue::UInt16(f2)) => Ok( - ScalarValue::UInt32(Some(f1.unwrap() as u32 * f2.unwrap() as u32)), - ), - // u8 / _ - (ScalarValue::UInt8(f1), ScalarValue::UInt8(f2)) => Ok(ScalarValue::UInt16( - Some(f1.unwrap() as u16 * f2.unwrap() as u16), - )), - _ => Err(DataFusionError::Internal(format!( - "Multiplication only support f64 for now, here has {:?} and {:?}", - lhs.get_datatype(), - rhs.get_datatype() - ))), - } - } - - /// Division between two numeric ScalarValues - pub fn div(lhs: &ScalarValue, rhs: &ScalarValue) -> Result { - if !lhs.is_numeric() || !rhs.is_numeric() { - return Err(DataFusionError::Internal(format!( - "Division is only supported on numeric types, \ - here has {:?} and {:?}", - lhs.get_datatype(), - rhs.get_datatype() - ))); - } - - if lhs.is_null() || rhs.is_null() { - return Err(DataFusionError::Internal( - "Division does not support empty values".to_string(), - )); - } - - // TODO: Finding a good way to support operation between different types without - // writing a hige match block. - // TODO: Add support for decimal types - match (lhs, rhs) { - (ScalarValue::Decimal128(_, _, _), _) | - (_, ScalarValue::Decimal128(_, _, _)) => { - Err(DataFusionError::Internal( - "Division with Decimals are not supported for now".to_string() - )) - }, - // f64 / _ - (ScalarValue::Float64(f1), ScalarValue::Float64(f2)) => { - Ok(ScalarValue::Float64(Some(f1.unwrap() / f2.unwrap()))) - }, - // f32 / _ - (ScalarValue::Float32(f1), ScalarValue::Float64(f2)) => { - Ok(ScalarValue::Float64(Some(f1.unwrap() as f64/ f2.unwrap()))) - }, - (ScalarValue::Float32(f1), ScalarValue::Float32(f2)) => { - Ok(ScalarValue::Float64(Some(f1.unwrap() as f64/ f2.unwrap() as f64))) - }, - // i64 / _ - (ScalarValue::Int64(f1), ScalarValue::Float64(f2)) => { - Ok(ScalarValue::Float64(Some(f1.unwrap() as f64 / f2.unwrap()))) - }, - (ScalarValue::Int64(f1), ScalarValue::Int64(f2)) => { - Ok(ScalarValue::Float64(Some(f1.unwrap() as f64 / f2.unwrap() as f64))) - }, - // i32 / _ - (ScalarValue::Int32(f1), ScalarValue::Float64(f2)) => { - Ok(ScalarValue::Float64(Some(f1.unwrap() as f64 / f2.unwrap()))) - }, - (ScalarValue::Int32(f1), ScalarValue::Int32(f2)) => { - Ok(ScalarValue::Float64(Some(f1.unwrap() as f64 / f2.unwrap() as f64))) - }, - // i16 / _ - (ScalarValue::Int16(f1), ScalarValue::Float64(f2)) => { - Ok(ScalarValue::Float64(Some(f1.unwrap() as f64 / f2.unwrap()))) - }, - (ScalarValue::Int16(f1), ScalarValue::Int16(f2)) => { - Ok(ScalarValue::Float64(Some(f1.unwrap() as f64 / f2.unwrap() as f64))) - }, - // i8 / _ - (ScalarValue::Int8(f1), ScalarValue::Float64(f2)) => { - Ok(ScalarValue::Float64(Some(f1.unwrap() as f64 / f2.unwrap()))) - }, - (ScalarValue::Int8(f1), ScalarValue::Int8(f2)) => { - Ok(ScalarValue::Float64(Some(f1.unwrap() as f64 / f2.unwrap() as f64))) - }, - // u64 / _ - (ScalarValue::UInt64(f1), ScalarValue::Float64(f2)) => { - Ok(ScalarValue::Float64(Some(f1.unwrap() as f64 / f2.unwrap()))) - }, - (ScalarValue::UInt64(f1), ScalarValue::UInt64(f2)) => { - Ok(ScalarValue::Float64(Some(f1.unwrap() as f64 / f2.unwrap() as f64))) - }, - // u32 / _ - (ScalarValue::UInt32(f1), ScalarValue::Float64(f2)) => { - Ok(ScalarValue::Float64(Some(f1.unwrap() as f64 / f2.unwrap()))) - }, - (ScalarValue::UInt32(f1), ScalarValue::UInt32(f2)) => { - Ok(ScalarValue::Float64(Some(f1.unwrap() as f64 / f2.unwrap() as f64))) - }, - // u16 / _ - (ScalarValue::UInt16(f1), ScalarValue::Float64(f2)) => { - Ok(ScalarValue::Float64(Some(f1.unwrap() as f64 / f2.unwrap()))) - }, - (ScalarValue::UInt16(f1), ScalarValue::UInt16(f2)) => { - Ok(ScalarValue::Float64(Some(f1.unwrap() as f64 / f2.unwrap() as f64))) - }, - // u8 / _ - (ScalarValue::UInt8(f1), ScalarValue::Float64(f2)) => { - Ok(ScalarValue::Float64(Some(f1.unwrap() as f64 / f2.unwrap()))) - }, - (ScalarValue::UInt8(f1), ScalarValue::UInt8(f2)) => { - Ok(ScalarValue::Float64(Some(f1.unwrap() as f64 / f2.unwrap() as f64))) - }, - _ => Err(DataFusionError::Internal( - format!( - "Division only support calculation with the same type or f64 as denominator for now, here has {:?} and {:?}", - lhs.get_datatype(), rhs.get_datatype() - ))), - } - } - /// Create a decimal Scalar from value/precision and scale. pub fn try_new_decimal128( value: i128, @@ -3376,245 +3081,4 @@ mod tests { DataType::Timestamp(TimeUnit::Nanosecond, Some("UTC".to_owned())) ); } - - macro_rules! test_scalar_op { - ($OP:ident, $LHS:expr, $LHS_TYPE:ident, $RHS:expr, $RHS_TYPE:ident, $RESULT:expr, $RESULT_TYPE:ident) => {{ - let v1 = &ScalarValue::from($LHS as $LHS_TYPE); - let v2 = &ScalarValue::from($RHS as $RHS_TYPE); - assert_eq!( - ScalarValue::$OP(v1, v2).unwrap(), - ScalarValue::from($RESULT as $RESULT_TYPE) - ); - }}; - } - - macro_rules! test_scalar_op_err { - ($OP:ident, $LHS:expr, $LHS_TYPE:ident, $RHS:expr, $RHS_TYPE:ident) => {{ - let v1 = &ScalarValue::from($LHS as $LHS_TYPE); - let v2 = &ScalarValue::from($RHS as $RHS_TYPE); - let actual = ScalarValue::$OP(v1, v2).is_err(); - assert!(actual); - }}; - } - - #[test] - fn scalar_addition() { - test_scalar_op!(add, 1, f64, 2, f64, 3, f64); - test_scalar_op!(add, 1, f32, 2, f32, 3, f64); - test_scalar_op!(add, 1, i64, 2, i64, 3, i64); - test_scalar_op!(add, 100, i64, -32, i64, 68, i64); - test_scalar_op!(add, -102, i64, 32, i64, -70, i64); - test_scalar_op!(add, 1, i32, 2, i32, 3, i64); - test_scalar_op!( - add, - std::i32::MAX, - i32, - std::i32::MAX, - i32, - std::i32::MAX as i64 * 2, - i64 - ); - test_scalar_op!(add, 1, i16, 2, i16, 3, i32); - test_scalar_op!( - add, - std::i16::MAX, - i16, - std::i16::MAX, - i16, - std::i16::MAX as i32 * 2, - i32 - ); - test_scalar_op!(add, 1, i8, 2, i8, 3, i16); - test_scalar_op!( - add, - std::i8::MAX, - i8, - std::i8::MAX, - i8, - std::i8::MAX as i16 * 2, - i16 - ); - test_scalar_op!(add, 1, u64, 2, u64, 3, u64); - test_scalar_op!(add, 1, u32, 2, u32, 3, u64); - test_scalar_op!( - add, - std::u32::MAX, - u32, - std::u32::MAX, - u32, - std::u32::MAX as u64 * 2, - u64 - ); - test_scalar_op!(add, 1, u16, 2, u16, 3, u32); - test_scalar_op!( - add, - std::u16::MAX, - u16, - std::u16::MAX, - u16, - std::u16::MAX as u32 * 2, - u32 - ); - test_scalar_op!(add, 1, u8, 2, u8, 3, u16); - test_scalar_op!( - add, - std::u8::MAX, - u8, - std::u8::MAX, - u8, - std::u8::MAX as u16 * 2, - u16 - ); - test_scalar_op_err!(add, 1, i32, 2, u16); - test_scalar_op_err!(add, 1, i32, 2, u16); - - let v1 = &ScalarValue::from(1); - let v2 = &ScalarValue::Decimal128(Some(2), 0, 0); - assert!(ScalarValue::add(v1, v2).is_err()); - - let v1 = &ScalarValue::Decimal128(Some(1), 0, 0); - let v2 = &ScalarValue::from(2); - assert!(ScalarValue::add(v1, v2).is_err()); - - let v1 = &ScalarValue::Float32(None); - let v2 = &ScalarValue::from(2); - assert!(ScalarValue::add(v1, v2).is_err()); - - let v2 = &ScalarValue::Float32(None); - let v1 = &ScalarValue::from(2); - assert!(ScalarValue::add(v1, v2).is_err()); - - let v1 = &ScalarValue::Float32(None); - let v2 = &ScalarValue::Float32(None); - assert!(ScalarValue::add(v1, v2).is_err()); - } - - #[test] - fn scalar_multiplication() { - test_scalar_op!(mul, 1, f64, 2, f64, 2, f64); - test_scalar_op!(mul, 1, f32, 2, f32, 2, f64); - test_scalar_op!(mul, 15, i64, 2, i64, 30, i64); - test_scalar_op!(mul, 100, i64, -32, i64, -3200, i64); - test_scalar_op!(mul, -1.1, f64, 2, f64, -2.2, f64); - test_scalar_op!(mul, 1, i32, 2, i32, 2, i64); - test_scalar_op!( - mul, - std::i32::MAX, - i32, - std::i32::MAX, - i32, - std::i32::MAX as i64 * std::i32::MAX as i64, - i64 - ); - test_scalar_op!(mul, 1, i16, 2, i16, 2, i32); - test_scalar_op!( - mul, - std::i16::MAX, - i16, - std::i16::MAX, - i16, - std::i16::MAX as i32 * std::i16::MAX as i32, - i32 - ); - test_scalar_op!(mul, 1, i8, 2, i8, 2, i16); - test_scalar_op!( - mul, - std::i8::MAX, - i8, - std::i8::MAX, - i8, - std::i8::MAX as i16 * std::i8::MAX as i16, - i16 - ); - test_scalar_op!(mul, 1, u64, 2, u64, 2, u64); - test_scalar_op!(mul, 1, u32, 2, u32, 2, u64); - test_scalar_op!( - mul, - std::u32::MAX, - u32, - std::u32::MAX, - u32, - std::u32::MAX as u64 * std::u32::MAX as u64, - u64 - ); - test_scalar_op!(mul, 1, u16, 2, u16, 2, u32); - test_scalar_op!( - mul, - std::u16::MAX, - u16, - std::u16::MAX, - u16, - std::u16::MAX as u32 * std::u16::MAX as u32, - u32 - ); - test_scalar_op!(mul, 1, u8, 2, u8, 2, u16); - test_scalar_op!( - mul, - std::u8::MAX, - u8, - std::u8::MAX, - u8, - std::u8::MAX as u16 * std::u8::MAX as u16, - u16 - ); - test_scalar_op_err!(mul, 1, i32, 2, u16); - test_scalar_op_err!(mul, 1, i32, 2, u16); - - let v1 = &ScalarValue::from(1); - let v2 = &ScalarValue::Decimal128(Some(2), 0, 0); - assert!(ScalarValue::mul(v1, v2).is_err()); - - let v1 = &ScalarValue::Decimal128(Some(1), 0, 0); - let v2 = &ScalarValue::from(2); - assert!(ScalarValue::mul(v1, v2).is_err()); - - let v1 = &ScalarValue::Float32(None); - let v2 = &ScalarValue::from(2); - assert!(ScalarValue::mul(v1, v2).is_err()); - - let v2 = &ScalarValue::Float32(None); - let v1 = &ScalarValue::from(2); - assert!(ScalarValue::mul(v1, v2).is_err()); - - let v1 = &ScalarValue::Float32(None); - let v2 = &ScalarValue::Float32(None); - assert!(ScalarValue::mul(v1, v2).is_err()); - } - - #[test] - fn scalar_division() { - test_scalar_op!(div, 1, f64, 2, f64, 0.5, f64); - test_scalar_op!(div, 1, f32, 2, f32, 0.5, f64); - test_scalar_op!(div, 15, i64, 2, i64, 7.5, f64); - test_scalar_op!(div, 100, i64, -2, i64, -50, f64); - test_scalar_op!(div, 1, i32, 2, i32, 0.5, f64); - test_scalar_op!(div, 1, i16, 2, i16, 0.5, f64); - test_scalar_op!(div, 1, i8, 2, i8, 0.5, f64); - test_scalar_op!(div, 1, u64, 2, u64, 0.5, f64); - test_scalar_op!(div, 1, u32, 2, u32, 0.5, f64); - test_scalar_op!(div, 1, u16, 2, u16, 0.5, f64); - test_scalar_op!(div, 1, u8, 2, u8, 0.5, f64); - test_scalar_op_err!(div, 1, i32, 2, u16); - test_scalar_op_err!(div, 1, i32, 2, u16); - - let v1 = &ScalarValue::from(1); - let v2 = &ScalarValue::Decimal128(Some(2), 0, 0); - assert!(ScalarValue::div(v1, v2).is_err()); - - let v1 = &ScalarValue::Decimal128(Some(1), 0, 0); - let v2 = &ScalarValue::from(2); - assert!(ScalarValue::div(v1, v2).is_err()); - - let v1 = &ScalarValue::Float32(None); - let v2 = &ScalarValue::from(2); - assert!(ScalarValue::div(v1, v2).is_err()); - - let v2 = &ScalarValue::Float32(None); - let v1 = &ScalarValue::from(2); - assert!(ScalarValue::div(v1, v2).is_err()); - - let v1 = &ScalarValue::Float32(None); - let v2 = &ScalarValue::Float32(None); - assert!(ScalarValue::div(v1, v2).is_err()); - } }