This is an automated email from the ASF dual-hosted git repository.
dheres pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/arrow-datafusion.git
The following commit(s) were added to refs/heads/master by this push:
new 794b92b Remove unused `update` and `merge` implementations from
Aggregates and supporting `ScalarValue` arithmetic (#1550)
794b92b is described below
commit 794b92b4e03ee3b470c0506019bca4659cee5e34
Author: Andrew Lamb <[email protected]>
AuthorDate: Thu Jan 13 02:41:42 2022 -0500
Remove unused `update` and `merge` implementations from Aggregates and
supporting `ScalarValue` arithmetic (#1550)
* Remove Scalar::{add,mul,div}
* fixups
---
.../src/physical_plan/expressions/average.rs | 23 +-
datafusion/src/physical_plan/expressions/count.rs | 18 +-
datafusion/src/physical_plan/expressions/sum.rs | 11 +-
.../src/physical_plan/expressions/variance.rs | 118 +----
datafusion/src/scalar.rs | 536 ---------------------
5 files changed, 16 insertions(+), 690 deletions(-)
diff --git a/datafusion/src/physical_plan/expressions/average.rs
b/datafusion/src/physical_plan/expressions/average.rs
index f092989..a57c525 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 30c44f1..edd9aea 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 027736d..61691c4 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 7516440..05d8e41 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<ScalarValue> {
diff --git a/datafusion/src/scalar.rs b/datafusion/src/scalar.rs
index cf6e8a1..cdcf11e 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<ScalarValue> {
- 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<ScalarValue> {
- 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<ScalarValue> {
- 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());
- }
}