From 2e19615dd5735694f1920bf551fe83cb425d0f4e Mon Sep 17 00:00:00 2001 From: Vasanthakumar Vijayasekaran Date: Sun, 19 Sep 2021 13:37:51 +0530 Subject: [PATCH] Move tests from `src/compute/` to `tests/` (#423) --- src/compute/aggregate/memory.rs | 23 -- src/compute/aggregate/min_max.rs | 189 ------------ src/compute/aggregate/sum.rs | 56 ---- src/compute/arithmetics/basic/add.rs | 162 ---------- src/compute/arithmetics/basic/div.rs | 105 ------- src/compute/arithmetics/basic/mul.rs | 161 ---------- src/compute/arithmetics/basic/pow.rs | 22 -- src/compute/arithmetics/basic/rem.rs | 105 ------- src/compute/arithmetics/basic/sub.rs | 162 ---------- src/compute/arithmetics/decimal/add.rs | 189 ------------ src/compute/arithmetics/decimal/div.rs | 236 -------------- src/compute/arithmetics/decimal/mul.rs | 237 -------------- src/compute/arithmetics/decimal/sub.rs | 185 ----------- src/compute/arithmetics/mod.rs | 68 ----- src/compute/arithmetics/time.rs | 322 -------------------- src/compute/comparison/mod.rs | 70 ----- src/compute/contains.rs | 64 ---- src/compute/sort/lex_sort.rs | 215 ------------- src/compute/take/mod.rs | 180 ----------- tests/it/compute/aggregate/memory.rs | 19 ++ tests/it/compute/aggregate/min_max.rs | 188 ++++++++++++ tests/it/compute/aggregate/mod.rs | 3 + tests/it/compute/aggregate/sum.rs | 54 ++++ tests/it/compute/arithmetics/basic/add.rs | 162 ++++++++++ tests/it/compute/arithmetics/basic/div.rs | 102 +++++++ tests/it/compute/arithmetics/basic/mod.rs | 6 + tests/it/compute/arithmetics/basic/mul.rs | 162 ++++++++++ tests/it/compute/arithmetics/basic/pow.rs | 18 ++ tests/it/compute/arithmetics/basic/rem.rs | 102 +++++++ tests/it/compute/arithmetics/basic/sub.rs | 162 ++++++++++ tests/it/compute/arithmetics/decimal/add.rs | 184 +++++++++++ tests/it/compute/arithmetics/decimal/div.rs | 233 ++++++++++++++ tests/it/compute/arithmetics/decimal/mod.rs | 4 + tests/it/compute/arithmetics/decimal/mul.rs | 235 ++++++++++++++ tests/it/compute/arithmetics/decimal/sub.rs | 180 +++++++++++ tests/it/compute/arithmetics/mod.rs | 68 +++++ tests/it/compute/arithmetics/time.rs | 309 +++++++++++++++++++ tests/it/compute/comparison.rs | 64 ++++ tests/it/compute/contains.rs | 61 ++++ tests/it/compute/mod.rs | 5 + tests/it/compute/sort/lex_sort.rs | 210 +++++++++++++ tests/it/compute/{sort.rs => sort/mod.rs} | 2 + tests/it/compute/take.rs | 176 +++++++++++ 43 files changed, 2709 insertions(+), 2751 deletions(-) create mode 100644 tests/it/compute/aggregate/memory.rs create mode 100644 tests/it/compute/aggregate/min_max.rs create mode 100644 tests/it/compute/aggregate/mod.rs create mode 100644 tests/it/compute/aggregate/sum.rs create mode 100644 tests/it/compute/arithmetics/basic/add.rs create mode 100644 tests/it/compute/arithmetics/basic/div.rs create mode 100644 tests/it/compute/arithmetics/basic/mod.rs create mode 100644 tests/it/compute/arithmetics/basic/mul.rs create mode 100644 tests/it/compute/arithmetics/basic/pow.rs create mode 100644 tests/it/compute/arithmetics/basic/rem.rs create mode 100644 tests/it/compute/arithmetics/basic/sub.rs create mode 100644 tests/it/compute/arithmetics/decimal/add.rs create mode 100644 tests/it/compute/arithmetics/decimal/div.rs create mode 100644 tests/it/compute/arithmetics/decimal/mod.rs create mode 100644 tests/it/compute/arithmetics/decimal/mul.rs create mode 100644 tests/it/compute/arithmetics/decimal/sub.rs create mode 100644 tests/it/compute/arithmetics/mod.rs create mode 100644 tests/it/compute/arithmetics/time.rs create mode 100644 tests/it/compute/comparison.rs create mode 100644 tests/it/compute/contains.rs create mode 100644 tests/it/compute/sort/lex_sort.rs rename tests/it/compute/{sort.rs => sort/mod.rs} (99%) create mode 100644 tests/it/compute/take.rs diff --git a/src/compute/aggregate/memory.rs b/src/compute/aggregate/memory.rs index 9f60f37752c..ec05be51da2 100644 --- a/src/compute/aggregate/memory.rs +++ b/src/compute/aggregate/memory.rs @@ -111,26 +111,3 @@ pub fn estimated_bytes_size(array: &dyn Array) -> usize { }), } } - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn primitive() { - let a = Int32Array::from_slice(&[1, 2, 3, 4, 5]); - assert_eq!(5 * std::mem::size_of::(), estimated_bytes_size(&a)); - } - - #[test] - fn boolean() { - let a = BooleanArray::from_slice(&[true]); - assert_eq!(1, estimated_bytes_size(&a)); - } - - #[test] - fn utf8() { - let a = Utf8Array::::from_slice(&["aaa"]); - assert_eq!(3 + 2 * std::mem::size_of::(), estimated_bytes_size(&a)); - } -} diff --git a/src/compute/aggregate/min_max.rs b/src/compute/aggregate/min_max.rs index 77f7be6c32b..a8eac2dc8e5 100644 --- a/src/compute/aggregate/min_max.rs +++ b/src/compute/aggregate/min_max.rs @@ -425,192 +425,3 @@ pub fn min(array: &dyn Array) -> Result> { } }) } - -#[cfg(test)] -mod tests { - use super::*; - use crate::array::*; - - #[test] - fn test_primitive_array_min_max() { - let a = Int32Array::from_slice(&[5, 6, 7, 8, 9]); - assert_eq!(5, min_primitive(&a).unwrap()); - assert_eq!(9, max_primitive(&a).unwrap()); - } - - #[test] - fn test_primitive_array_min_max_with_nulls() { - let a = Int32Array::from(&[Some(5), None, None, Some(8), Some(9)]); - assert_eq!(5, min_primitive(&a).unwrap()); - assert_eq!(9, max_primitive(&a).unwrap()); - } - - #[test] - fn test_primitive_min_max_1() { - let a = Int32Array::from(&[None, None, Some(5), Some(2)]); - assert_eq!(Some(2), min_primitive(&a)); - assert_eq!(Some(5), max_primitive(&a)); - } - - #[test] - fn min_max_f32() { - let a = Float32Array::from(&[None, None, Some(5.0), Some(2.0)]); - assert_eq!(Some(2.0), min_primitive(&a)); - assert_eq!(Some(5.0), max_primitive(&a)); - } - - #[test] - fn min_max_f64() { - let a = Float64Array::from(&[None, None, Some(5.0), Some(2.0)]); - assert_eq!(Some(2.0), min_primitive(&a)); - assert_eq!(Some(5.0), max_primitive(&a)); - } - - #[test] - fn min_max_f64_large() { - // in simd, f64 has 8 lanes, thus > 8 covers the branch with lanes - let a = Float64Array::from(&[ - None, - None, - Some(8.0), - Some(2.0), - None, - None, - Some(5.0), - Some(2.0), - ]); - assert_eq!(Some(2.0), min_primitive(&a)); - assert_eq!(Some(8.0), max_primitive(&a)); - } - - #[test] - fn min_max_f64_nan_only() { - let a = Float64Array::from(&[None, Some(f64::NAN)]); - assert!(min_primitive(&a).unwrap().is_nan()); - assert!(max_primitive(&a).unwrap().is_nan()); - } - - #[test] - fn min_max_f64_nan() { - let a = Float64Array::from(&[None, Some(1.0), Some(f64::NAN)]); - assert_eq!(Some(1.0), min_primitive(&a)); - assert_eq!(Some(1.0), max_primitive(&a)); - } - - #[test] - fn min_max_f64_edge_cases() { - let a: Float64Array = (0..100).map(|_| Some(f64::NEG_INFINITY)).collect(); - assert_eq!(Some(f64::NEG_INFINITY), min_primitive(&a)); - assert_eq!(Some(f64::NEG_INFINITY), max_primitive(&a)); - - let a: Float64Array = (0..100).map(|_| Some(f64::MIN)).collect(); - assert_eq!(Some(f64::MIN), min_primitive(&a)); - assert_eq!(Some(f64::MIN), max_primitive(&a)); - - let a: Float64Array = (0..100).map(|_| Some(f64::MAX)).collect(); - assert_eq!(Some(f64::MAX), min_primitive(&a)); - assert_eq!(Some(f64::MAX), max_primitive(&a)); - - let a: Float64Array = (0..100).map(|_| Some(f64::INFINITY)).collect(); - assert_eq!(Some(f64::INFINITY), min_primitive(&a)); - assert_eq!(Some(f64::INFINITY), max_primitive(&a)); - } - - // todo: convert me - #[test] - fn test_string_min_max_with_nulls() { - let a = Utf8Array::::from(&[Some("b"), None, None, Some("a"), Some("c")]); - assert_eq!("a", min_string(&a).unwrap()); - assert_eq!("c", max_string(&a).unwrap()); - } - - #[test] - fn test_string_min_max_all_nulls() { - let a = Utf8Array::::from(&[None::<&str>, None]); - assert_eq!(None, min_string(&a)); - assert_eq!(None, max_string(&a)); - } - - #[test] - fn test_string_min_max_1() { - let a = Utf8Array::::from(&[None, None, Some("b"), Some("a")]); - assert_eq!(Some("a"), min_string(&a)); - assert_eq!(Some("b"), max_string(&a)); - } - - #[test] - fn test_boolean_min_max_empty() { - let a = BooleanArray::new_empty(DataType::Boolean); - assert_eq!(None, min_boolean(&a)); - assert_eq!(None, max_boolean(&a)); - } - - #[test] - fn test_boolean_min_max_all_null() { - let a = BooleanArray::from(&[None, None]); - assert_eq!(None, min_boolean(&a)); - assert_eq!(None, max_boolean(&a)); - } - - #[test] - fn test_boolean_min_max_no_null() { - let a = BooleanArray::from(&[Some(true), Some(false), Some(true)]); - assert_eq!(Some(false), min_boolean(&a)); - assert_eq!(Some(true), max_boolean(&a)); - } - - #[test] - fn test_boolean_min_max() { - let a = BooleanArray::from(&[Some(true), Some(true), None, Some(false), None]); - assert_eq!(Some(false), min_boolean(&a)); - assert_eq!(Some(true), max_boolean(&a)); - - let a = BooleanArray::from(&[None, Some(true), None, Some(false), None]); - assert_eq!(Some(false), min_boolean(&a)); - assert_eq!(Some(true), max_boolean(&a)); - - let a = BooleanArray::from(&[Some(false), Some(true), None, Some(false), None]); - assert_eq!(Some(false), min_boolean(&a)); - assert_eq!(Some(true), max_boolean(&a)); - } - - #[test] - fn test_boolean_min_max_smaller() { - let a = BooleanArray::from(&[Some(false)]); - assert_eq!(Some(false), min_boolean(&a)); - assert_eq!(Some(false), max_boolean(&a)); - - let a = BooleanArray::from(&[None, Some(false)]); - assert_eq!(Some(false), min_boolean(&a)); - assert_eq!(Some(false), max_boolean(&a)); - - let a = BooleanArray::from(&[None, Some(true)]); - assert_eq!(Some(true), min_boolean(&a)); - assert_eq!(Some(true), max_boolean(&a)); - - let a = BooleanArray::from(&[Some(true)]); - assert_eq!(Some(true), min_boolean(&a)); - assert_eq!(Some(true), max_boolean(&a)); - } - - #[test] - fn test_binary_min_max_with_nulls() { - let a = BinaryArray::::from(&[Some(b"b"), None, None, Some(b"a"), Some(b"c")]); - assert_eq!("a".as_bytes(), min_binary(&a).unwrap()); - assert_eq!("c".as_bytes(), max_binary(&a).unwrap()); - } - - #[test] - fn test_binary_min_max_all_nulls() { - let a = BinaryArray::::from(&[None::<&[u8]>, None]); - assert_eq!(None, min_binary(&a)); - assert_eq!(None, max_binary(&a)); - } - - #[test] - fn test_binary_min_max_1() { - let a = BinaryArray::::from(&[None, None, Some(b"b"), Some(b"a")]); - assert_eq!(Some("a".as_bytes()), min_binary(&a)); - assert_eq!(Some("b".as_bytes()), max_binary(&a)); - } -} diff --git a/src/compute/aggregate/sum.rs b/src/compute/aggregate/sum.rs index 9179756d909..d0609d1e69a 100644 --- a/src/compute/aggregate/sum.rs +++ b/src/compute/aggregate/sum.rs @@ -174,59 +174,3 @@ pub fn sum(array: &dyn Array) -> Result> { } }) } - -#[cfg(test)] -mod tests { - use super::super::super::arithmetics; - use super::*; - use crate::array::*; - - #[test] - fn test_primitive_array_sum() { - let a = Int32Array::from_slice(&[1, 2, 3, 4, 5]); - assert_eq!( - &PrimitiveScalar::::from(Some(15)) as &dyn Scalar, - sum(&a).unwrap().as_ref() - ); - - let a = a.to(DataType::Date32); - assert_eq!( - &PrimitiveScalar::::from(Some(15)).to(DataType::Date32) as &dyn Scalar, - sum(&a).unwrap().as_ref() - ); - } - - #[test] - fn test_primitive_array_float_sum() { - let a = Float64Array::from_slice(&[1.1f64, 2.2, 3.3, 4.4, 5.5]); - assert!((16.5 - sum_primitive(&a).unwrap()).abs() < f64::EPSILON); - } - - #[test] - fn test_primitive_array_sum_with_nulls() { - let a = Int32Array::from(&[None, Some(2), Some(3), None, Some(5)]); - assert_eq!(10, sum_primitive(&a).unwrap()); - } - - #[test] - fn test_primitive_array_sum_all_nulls() { - let a = Int32Array::from(&[None, None, None]); - assert_eq!(None, sum_primitive(&a)); - } - - #[test] - fn test_primitive_array_sum_large_64() { - let a: Int64Array = (1..=100) - .map(|i| if i % 3 == 0 { Some(i) } else { None }) - .collect(); - let b: Int64Array = (1..=100) - .map(|i| if i % 3 == 0 { Some(0) } else { Some(i) }) - .collect(); - // create an array that actually has non-zero values at the invalid indices - let c = arithmetics::basic::add::add(&a, &b).unwrap(); - assert_eq!( - Some((1..=100).filter(|i| i % 3 == 0).sum()), - sum_primitive(&c) - ); - } -} diff --git a/src/compute/arithmetics/basic/add.rs b/src/compute/arithmetics/basic/add.rs index e2e0d8ebb54..d43113e3d06 100644 --- a/src/compute/arithmetics/basic/add.rs +++ b/src/compute/arithmetics/basic/add.rs @@ -330,165 +330,3 @@ where Ok(overflowing_add_scalar(self, rhs)) } } - -#[cfg(test)] -mod tests { - use super::*; - use crate::array::*; - - #[test] - fn test_add_mismatched_length() { - let a = Int32Array::from_slice(&[5, 6]); - let b = Int32Array::from_slice(&[5]); - add(&a, &b) - .err() - .expect("should have failed due to different lengths"); - } - - #[test] - fn test_add() { - let a = Int32Array::from(&[None, Some(6), None, Some(6)]); - let b = Int32Array::from(&[Some(5), None, None, Some(6)]); - let result = add(&a, &b).unwrap(); - let expected = Int32Array::from(&[None, None, None, Some(12)]); - assert_eq!(result, expected); - - // Trait testing - let result = a.add(&b).unwrap(); - assert_eq!(result, expected); - } - - #[test] - #[should_panic] - fn test_add_panic() { - let a = Int8Array::from(&[Some(100i8)]); - let b = Int8Array::from(&[Some(100i8)]); - let _ = add(&a, &b); - } - - #[test] - fn test_add_checked() { - let a = Int32Array::from(&[None, Some(6), None, Some(6)]); - let b = Int32Array::from(&[Some(5), None, None, Some(6)]); - let result = checked_add(&a, &b).unwrap(); - let expected = Int32Array::from(&[None, None, None, Some(12)]); - assert_eq!(result, expected); - - let a = Int8Array::from(&[Some(100i8), Some(100i8), Some(100i8)]); - let b = Int8Array::from(&[Some(0i8), Some(100i8), Some(0i8)]); - let result = checked_add(&a, &b).unwrap(); - let expected = Int8Array::from(&[Some(100i8), None, Some(100i8)]); - assert_eq!(result, expected); - - // Trait testing - let result = a.checked_add(&b).unwrap(); - assert_eq!(result, expected); - } - - #[test] - fn test_add_saturating() { - let a = Int32Array::from(&[None, Some(6), None, Some(6)]); - let b = Int32Array::from(&[Some(5), None, None, Some(6)]); - let result = saturating_add(&a, &b).unwrap(); - let expected = Int32Array::from(&[None, None, None, Some(12)]); - assert_eq!(result, expected); - - let a = Int8Array::from(&[Some(100i8)]); - let b = Int8Array::from(&[Some(100i8)]); - let result = saturating_add(&a, &b).unwrap(); - let expected = Int8Array::from(&[Some(127)]); - assert_eq!(result, expected); - - // Trait testing - let result = a.saturating_add(&b).unwrap(); - assert_eq!(result, expected); - } - - #[test] - fn test_add_overflowing() { - let a = Int32Array::from(&[None, Some(6), None, Some(6)]); - let b = Int32Array::from(&[Some(5), None, None, Some(6)]); - let (result, overflow) = overflowing_add(&a, &b).unwrap(); - let expected = Int32Array::from(&[None, None, None, Some(12)]); - assert_eq!(result, expected); - assert_eq!(overflow, Bitmap::from([false, false, false, false])); - - let a = Int8Array::from(&[Some(1i8), Some(100i8)]); - let b = Int8Array::from(&[Some(1i8), Some(100i8)]); - let (result, overflow) = overflowing_add(&a, &b).unwrap(); - let expected = Int8Array::from(&[Some(2i8), Some(-56i8)]); - assert_eq!(result, expected); - assert_eq!(overflow, Bitmap::from([false, true])); - - // Trait testing - let (result, overflow) = a.overflowing_add(&b).unwrap(); - assert_eq!(result, expected); - assert_eq!(overflow, Bitmap::from([false, true])); - } - - #[test] - fn test_add_scalar() { - let a = Int32Array::from(&[None, Some(6), None, Some(6)]); - let result = add_scalar(&a, &1i32); - let expected = Int32Array::from(&[None, Some(7), None, Some(7)]); - assert_eq!(result, expected); - - // Trait testing - let result = a.add(&1i32).unwrap(); - assert_eq!(result, expected); - } - - #[test] - fn test_add_scalar_checked() { - let a = Int32Array::from(&[None, Some(6), None, Some(6)]); - let result = checked_add_scalar(&a, &1i32); - let expected = Int32Array::from(&[None, Some(7), None, Some(7)]); - assert_eq!(result, expected); - - let a = Int8Array::from(&[None, Some(100), None, Some(100)]); - let result = checked_add_scalar(&a, &100i8); - let expected = Int8Array::from(&[None, None, None, None]); - assert_eq!(result, expected); - - // Trait testing - let result = a.checked_add(&100i8).unwrap(); - assert_eq!(result, expected); - } - - #[test] - fn test_add_scalar_saturating() { - let a = Int32Array::from(&[None, Some(6), None, Some(6)]); - let result = saturating_add_scalar(&a, &1i32); - let expected = Int32Array::from(&[None, Some(7), None, Some(7)]); - assert_eq!(result, expected); - - let a = Int8Array::from(&[Some(100i8)]); - let result = saturating_add_scalar(&a, &100i8); - let expected = Int8Array::from(&[Some(127)]); - assert_eq!(result, expected); - - // Trait testing - let result = a.saturating_add(&100i8).unwrap(); - assert_eq!(result, expected); - } - - #[test] - fn test_add_scalar_overflowing() { - let a = Int32Array::from(&vec![None, Some(6), None, Some(6)]); - let (result, overflow) = overflowing_add_scalar(&a, &1i32); - let expected = Int32Array::from(&vec![None, Some(7), None, Some(7)]); - assert_eq!(result, expected); - assert_eq!(overflow, Bitmap::from([false, false, false, false])); - - let a = Int8Array::from(&vec![Some(1i8), Some(100i8)]); - let (result, overflow) = overflowing_add_scalar(&a, &100i8); - let expected = Int8Array::from(&vec![Some(101i8), Some(-56i8)]); - assert_eq!(result, expected); - assert_eq!(overflow, Bitmap::from([false, true])); - - // Trait testing - let (result, overflow) = a.overflowing_add(&100i8).unwrap(); - assert_eq!(result, expected); - assert_eq!(overflow, Bitmap::from([false, true])); - } -} diff --git a/src/compute/arithmetics/basic/div.rs b/src/compute/arithmetics/basic/div.rs index e39fd650111..c776292c544 100644 --- a/src/compute/arithmetics/basic/div.rs +++ b/src/compute/arithmetics/basic/div.rs @@ -227,108 +227,3 @@ where Ok(checked_div_scalar(self, rhs)) } } - -#[cfg(test)] -mod tests { - use super::*; - use crate::array::*; - - #[test] - fn test_div_mismatched_length() { - let a = Int32Array::from_slice(&[5, 6]); - let b = Int32Array::from_slice(&[5]); - div(&a, &b) - .err() - .expect("should have failed due to different lengths"); - } - - #[test] - fn test_div() { - let a = Int32Array::from(&[Some(5), Some(6)]); - let b = Int32Array::from(&[Some(5), Some(6)]); - let result = div(&a, &b).unwrap(); - let expected = Int32Array::from(&[Some(1), Some(1)]); - assert_eq!(result, expected); - - // Trait testing - let result = a.div(&b).unwrap(); - assert_eq!(result, expected); - } - - #[test] - #[should_panic] - fn test_div_panic() { - let a = Int8Array::from(&[Some(10i8)]); - let b = Int8Array::from(&[Some(0i8)]); - let _ = div(&a, &b); - } - - #[test] - fn test_div_checked() { - let a = Int32Array::from(&[Some(5), None, Some(3), Some(6)]); - let b = Int32Array::from(&[Some(5), Some(3), None, Some(6)]); - let result = checked_div(&a, &b).unwrap(); - let expected = Int32Array::from(&[Some(1), None, None, Some(1)]); - assert_eq!(result, expected); - - let a = Int32Array::from(&[Some(5), None, Some(3), Some(6)]); - let b = Int32Array::from(&[Some(5), Some(0), Some(0), Some(6)]); - let result = checked_div(&a, &b).unwrap(); - let expected = Int32Array::from(&[Some(1), None, None, Some(1)]); - assert_eq!(result, expected); - - // Trait testing - let result = a.checked_div(&b).unwrap(); - assert_eq!(result, expected); - } - - #[test] - fn test_div_scalar() { - let a = Int32Array::from(&[None, Some(6), None, Some(6)]); - let result = div_scalar(&a, &1i32); - let expected = Int32Array::from(&[None, Some(6), None, Some(6)]); - assert_eq!(result, expected); - - // Trait testing - let result = a.div(&1i32).unwrap(); - assert_eq!(result, expected); - - // check the strength reduced branches - let a = UInt64Array::from(&[None, Some(6), None, Some(6)]); - let result = div_scalar(&a, &1u64); - let expected = UInt64Array::from(&[None, Some(6), None, Some(6)]); - assert_eq!(result, expected); - - let a = UInt32Array::from(&[None, Some(6), None, Some(6)]); - let result = div_scalar(&a, &1u32); - let expected = UInt32Array::from(&[None, Some(6), None, Some(6)]); - assert_eq!(result, expected); - - let a = UInt16Array::from(&[None, Some(6), None, Some(6)]); - let result = div_scalar(&a, &1u16); - let expected = UInt16Array::from(&[None, Some(6), None, Some(6)]); - assert_eq!(result, expected); - - let a = UInt8Array::from(&[None, Some(6), None, Some(6)]); - let result = div_scalar(&a, &1u8); - let expected = UInt8Array::from(&[None, Some(6), None, Some(6)]); - assert_eq!(result, expected); - } - - #[test] - fn test_div_scalar_checked() { - let a = Int32Array::from(&[None, Some(6), None, Some(6)]); - let result = checked_div_scalar(&a, &1i32); - let expected = Int32Array::from(&[None, Some(6), None, Some(6)]); - assert_eq!(result, expected); - - let a = Int32Array::from(&[None, Some(6), None, Some(6)]); - let result = checked_div_scalar(&a, &0); - let expected = Int32Array::from(&[None, None, None, None]); - assert_eq!(result, expected); - - // Trait testing - let result = a.checked_div(&0).unwrap(); - assert_eq!(result, expected); - } -} diff --git a/src/compute/arithmetics/basic/mul.rs b/src/compute/arithmetics/basic/mul.rs index f804345c841..bbe8c3ee4b2 100644 --- a/src/compute/arithmetics/basic/mul.rs +++ b/src/compute/arithmetics/basic/mul.rs @@ -330,164 +330,3 @@ where Ok(overflowing_mul_scalar(self, rhs)) } } -#[cfg(test)] -mod tests { - use super::*; - use crate::array::*; - - #[test] - fn test_mul_mismatched_length() { - let a = Int32Array::from_slice(&[5, 6]); - let b = Int32Array::from_slice(&[5]); - mul(&a, &b) - .err() - .expect("should have failed due to different lengths"); - } - - #[test] - fn test_mul() { - let a = Int32Array::from(&[None, Some(6), None, Some(6)]); - let b = Int32Array::from(&[Some(5), None, None, Some(6)]); - let result = mul(&a, &b).unwrap(); - let expected = Int32Array::from(&[None, None, None, Some(36)]); - assert_eq!(result, expected); - - // Trait testing - let result = a.mul(&b).unwrap(); - assert_eq!(result, expected); - } - - #[test] - #[should_panic] - fn test_mul_panic() { - let a = Int8Array::from(&[Some(-100i8)]); - let b = Int8Array::from(&[Some(100i8)]); - let _ = mul(&a, &b); - } - - #[test] - fn test_mul_checked() { - let a = Int32Array::from(&[None, Some(6), None, Some(6)]); - let b = Int32Array::from(&[Some(5), None, None, Some(6)]); - let result = checked_mul(&a, &b).unwrap(); - let expected = Int32Array::from(&[None, None, None, Some(36)]); - assert_eq!(result, expected); - - let a = Int8Array::from(&[Some(100i8), Some(100i8), Some(100i8)]); - let b = Int8Array::from(&[Some(1i8), Some(100i8), Some(1i8)]); - let result = checked_mul(&a, &b).unwrap(); - let expected = Int8Array::from(&[Some(100i8), None, Some(100i8)]); - assert_eq!(result, expected); - - // Trait testing - let result = a.checked_mul(&b).unwrap(); - assert_eq!(result, expected); - } - - #[test] - fn test_mul_saturating() { - let a = Int32Array::from(&[None, Some(6), None, Some(6)]); - let b = Int32Array::from(&[Some(5), None, None, Some(6)]); - let result = saturating_mul(&a, &b).unwrap(); - let expected = Int32Array::from(&[None, None, None, Some(36)]); - assert_eq!(result, expected); - - let a = Int8Array::from(&[Some(-100i8)]); - let b = Int8Array::from(&[Some(100i8)]); - let result = saturating_mul(&a, &b).unwrap(); - let expected = Int8Array::from(&[Some(-128)]); - assert_eq!(result, expected); - - // Trait testing - let result = a.saturating_mul(&b).unwrap(); - assert_eq!(result, expected); - } - - #[test] - fn test_mul_overflowing() { - let a = Int32Array::from(&[None, Some(6), None, Some(6)]); - let b = Int32Array::from(&[Some(5), None, None, Some(6)]); - let (result, overflow) = overflowing_mul(&a, &b).unwrap(); - let expected = Int32Array::from(&[None, None, None, Some(36)]); - assert_eq!(result, expected); - assert_eq!(overflow, Bitmap::from([false, false, false, false])); - - let a = Int8Array::from(&[Some(1i8), Some(-100i8)]); - let b = Int8Array::from(&[Some(1i8), Some(100i8)]); - let (result, overflow) = overflowing_mul(&a, &b).unwrap(); - let expected = Int8Array::from(&[Some(1i8), Some(-16i8)]); - assert_eq!(result, expected); - assert_eq!(overflow, Bitmap::from([false, true])); - - // Trait testing - let (result, overflow) = a.overflowing_mul(&b).unwrap(); - assert_eq!(result, expected); - assert_eq!(overflow, Bitmap::from([false, true])); - } - - #[test] - fn test_mul_scalar() { - let a = Int32Array::from(&[None, Some(6), None, Some(6)]); - let result = mul_scalar(&a, &1i32); - let expected = Int32Array::from(&[None, Some(6), None, Some(6)]); - assert_eq!(result, expected); - - // Trait testing - let result = a.mul(&1i32).unwrap(); - assert_eq!(result, expected); - } - - #[test] - fn test_mul_scalar_checked() { - let a = Int32Array::from(&[None, Some(6), None, Some(6)]); - let result = checked_mul_scalar(&a, &1i32); - let expected = Int32Array::from(&[None, Some(6), None, Some(6)]); - assert_eq!(result, expected); - - let a = Int8Array::from(&[None, Some(100), None, Some(100)]); - let result = checked_mul_scalar(&a, &100i8); - let expected = Int8Array::from(&[None, None, None, None]); - assert_eq!(result, expected); - - // Trait testing - let result = a.checked_mul(&100i8).unwrap(); - assert_eq!(result, expected); - } - - #[test] - fn test_mul_scalar_saturating() { - let a = Int32Array::from(&[None, Some(6), None, Some(6)]); - let result = saturating_mul_scalar(&a, &1i32); - let expected = Int32Array::from(&[None, Some(6), None, Some(6)]); - assert_eq!(result, expected); - - let a = Int8Array::from(&[Some(-100i8)]); - let result = saturating_mul_scalar(&a, &100i8); - let expected = Int8Array::from(&[Some(-128)]); - assert_eq!(result, expected); - - // Trait testing - let result = a.saturating_mul(&100i8).unwrap(); - assert_eq!(result, expected); - } - - #[test] - fn test_mul_scalar_overflowing() { - let a = Int32Array::from(&[None, Some(6), None, Some(6)]); - let (result, overflow) = overflowing_mul_scalar(&a, &1i32); - let expected = Int32Array::from(&[None, Some(6), None, Some(6)]); - assert_eq!(result, expected); - assert_eq!(overflow, Bitmap::from([false, false, false, false])); - - let a = Int8Array::from(&[Some(1i8), Some(-100i8)]); - let (result, overflow) = overflowing_mul_scalar(&a, &100i8); - let expected = Int8Array::from(&[Some(100i8), Some(-16i8)]); - assert_eq!(result, expected); - assert_eq!(overflow, Bitmap::from([false, true])); - - // Trait testing - let (result, overflow) = a.overflowing_mul(&100i8).unwrap(); - assert_eq!(result, expected); - assert_eq!(overflow, Bitmap::from([false, true])); - } -} diff --git a/src/compute/arithmetics/basic/pow.rs b/src/compute/arithmetics/basic/pow.rs index 78157ef81e5..f1e2efbf9ca 100644 --- a/src/compute/arithmetics/basic/pow.rs +++ b/src/compute/arithmetics/basic/pow.rs @@ -49,25 +49,3 @@ where unary_checked(array, op, array.data_type().clone()) } - -#[cfg(test)] -mod tests { - use super::*; - use crate::array::{Float32Array, Int8Array}; - - #[test] - fn test_raise_power_scalar() { - let a = Float32Array::from(&[Some(2f32), None]); - let actual = powf_scalar(&a, 2.0); - let expected = Float32Array::from(&[Some(4f32), None]); - assert_eq!(expected, actual); - } - - #[test] - fn test_raise_power_scalar_checked() { - let a = Int8Array::from(&[Some(1i8), None, Some(7i8)]); - let actual = checked_powf_scalar(&a, 8usize); - let expected = Int8Array::from(&[Some(1i8), None, None]); - assert_eq!(expected, actual); - } -} diff --git a/src/compute/arithmetics/basic/rem.rs b/src/compute/arithmetics/basic/rem.rs index af696de4968..a087f1fd8da 100644 --- a/src/compute/arithmetics/basic/rem.rs +++ b/src/compute/arithmetics/basic/rem.rs @@ -223,108 +223,3 @@ where Ok(checked_rem_scalar(self, rhs)) } } - -#[cfg(test)] -mod tests { - use super::*; - use crate::array::*; - - #[test] - fn test_rem_mismatched_length() { - let a = Int32Array::from_slice(&[5, 6]); - let b = Int32Array::from_slice(&[5]); - rem(&a, &b) - .err() - .expect("should have failed due to different lengths"); - } - - #[test] - fn test_rem() { - let a = Int32Array::from(&[Some(5), Some(6)]); - let b = Int32Array::from(&[Some(4), Some(4)]); - let result = rem(&a, &b).unwrap(); - let expected = Int32Array::from(&[Some(1), Some(2)]); - assert_eq!(result, expected); - - // Trait testing - let result = a.rem(&b).unwrap(); - assert_eq!(result, expected); - } - - #[test] - #[should_panic] - fn test_rem_panic() { - let a = Int8Array::from(&[Some(10i8)]); - let b = Int8Array::from(&[Some(0i8)]); - let _ = rem(&a, &b); - } - - #[test] - fn test_rem_checked() { - let a = Int32Array::from(&[Some(5), None, Some(3), Some(6)]); - let b = Int32Array::from(&[Some(5), Some(3), None, Some(5)]); - let result = checked_rem(&a, &b).unwrap(); - let expected = Int32Array::from(&[Some(0), None, None, Some(1)]); - assert_eq!(result, expected); - - let a = Int32Array::from(&[Some(5), None, Some(3), Some(6)]); - let b = Int32Array::from(&[Some(5), Some(0), Some(0), Some(5)]); - let result = checked_rem(&a, &b).unwrap(); - let expected = Int32Array::from(&[Some(0), None, None, Some(1)]); - assert_eq!(result, expected); - - // Trait testing - let result = a.checked_rem(&b).unwrap(); - assert_eq!(result, expected); - } - - #[test] - fn test_rem_scalar() { - let a = Int32Array::from(&[None, Some(6), None, Some(5)]); - let result = rem_scalar(&a, &2i32); - let expected = Int32Array::from(&[None, Some(0), None, Some(1)]); - assert_eq!(result, expected); - - // Trait testing - let result = a.rem(&2i32).unwrap(); - assert_eq!(result, expected); - - // check the strength reduced branches - let a = UInt64Array::from(&[None, Some(6), None, Some(5)]); - let result = rem_scalar(&a, &2u64); - let expected = UInt64Array::from(&[None, Some(0), None, Some(1)]); - assert_eq!(result, expected); - - let a = UInt32Array::from(&[None, Some(6), None, Some(5)]); - let result = rem_scalar(&a, &2u32); - let expected = UInt32Array::from(&[None, Some(0), None, Some(1)]); - assert_eq!(result, expected); - - let a = UInt16Array::from(&[None, Some(6), None, Some(5)]); - let result = rem_scalar(&a, &2u16); - let expected = UInt16Array::from(&[None, Some(0), None, Some(1)]); - assert_eq!(result, expected); - - let a = UInt8Array::from(&[None, Some(6), None, Some(5)]); - let result = rem_scalar(&a, &2u8); - let expected = UInt8Array::from(&[None, Some(0), None, Some(1)]); - assert_eq!(result, expected); - } - - #[test] - fn test_rem_scalar_checked() { - let a = Int32Array::from(&[None, Some(6), None, Some(7)]); - let result = checked_rem_scalar(&a, &2i32); - let expected = Int32Array::from(&[None, Some(0), None, Some(1)]); - assert_eq!(result, expected); - - let a = Int32Array::from(&[None, Some(6), None, Some(6)]); - let result = checked_rem_scalar(&a, &0); - let expected = Int32Array::from(&[None, None, None, None]); - assert_eq!(result, expected); - - // Trait testing - let result = a.checked_rem(&0).unwrap(); - assert_eq!(result, expected); - } -} diff --git a/src/compute/arithmetics/basic/sub.rs b/src/compute/arithmetics/basic/sub.rs index ffd0b79015d..7fae4258b6a 100644 --- a/src/compute/arithmetics/basic/sub.rs +++ b/src/compute/arithmetics/basic/sub.rs @@ -330,165 +330,3 @@ where Ok(overflowing_sub_scalar(self, rhs)) } } - -#[cfg(test)] -mod tests { - use super::*; - use crate::array::*; - - #[test] - fn test_sub_mismatched_length() { - let a = Int32Array::from_slice(&[5, 6]); - let b = Int32Array::from_slice(&[5]); - sub(&a, &b) - .err() - .expect("should have failed due to different lengths"); - } - - #[test] - fn test_sub() { - let a = Int32Array::from(&[None, Some(6), None, Some(6)]); - let b = Int32Array::from(&[Some(5), None, None, Some(6)]); - let result = sub(&a, &b).unwrap(); - let expected = Int32Array::from(&[None, None, None, Some(0)]); - assert_eq!(result, expected); - - // Trait testing - let result = a.sub(&b).unwrap(); - assert_eq!(result, expected); - } - - #[test] - #[should_panic] - fn test_sub_panic() { - let a = Int8Array::from(&[Some(-100i8)]); - let b = Int8Array::from(&[Some(100i8)]); - let _ = sub(&a, &b); - } - - #[test] - fn test_sub_checked() { - let a = Int32Array::from(&[None, Some(6), None, Some(6)]); - let b = Int32Array::from(&[Some(5), None, None, Some(6)]); - let result = checked_sub(&a, &b).unwrap(); - let expected = Int32Array::from(&[None, None, None, Some(0)]); - assert_eq!(result, expected); - - let a = Int8Array::from(&[Some(100i8), Some(-100i8), Some(100i8)]); - let b = Int8Array::from(&[Some(1i8), Some(100i8), Some(0i8)]); - let result = checked_sub(&a, &b).unwrap(); - let expected = Int8Array::from(&[Some(99i8), None, Some(100i8)]); - assert_eq!(result, expected); - - // Trait testing - let result = a.checked_sub(&b).unwrap(); - assert_eq!(result, expected); - } - - #[test] - fn test_sub_saturating() { - let a = Int32Array::from(&[None, Some(6), None, Some(6)]); - let b = Int32Array::from(&[Some(5), None, None, Some(6)]); - let result = saturating_sub(&a, &b).unwrap(); - let expected = Int32Array::from(&[None, None, None, Some(0)]); - assert_eq!(result, expected); - - let a = Int8Array::from(&[Some(-100i8)]); - let b = Int8Array::from(&[Some(100i8)]); - let result = saturating_sub(&a, &b).unwrap(); - let expected = Int8Array::from(&[Some(-128)]); - assert_eq!(result, expected); - - // Trait testing - let result = a.saturating_sub(&b).unwrap(); - assert_eq!(result, expected); - } - - #[test] - fn test_sub_overflowing() { - let a = Int32Array::from(&[None, Some(6), None, Some(6)]); - let b = Int32Array::from(&[Some(5), None, None, Some(6)]); - let (result, overflow) = overflowing_sub(&a, &b).unwrap(); - let expected = Int32Array::from(&[None, None, None, Some(0)]); - assert_eq!(result, expected); - assert_eq!(overflow, Bitmap::from([false, false, false, false])); - - let a = Int8Array::from(&[Some(1i8), Some(-100i8)]); - let b = Int8Array::from(&[Some(1i8), Some(100i8)]); - let (result, overflow) = overflowing_sub(&a, &b).unwrap(); - let expected = Int8Array::from(&[Some(0i8), Some(56i8)]); - assert_eq!(result, expected); - assert_eq!(overflow, Bitmap::from([false, true])); - - // Trait testing - let (result, overflow) = a.overflowing_sub(&b).unwrap(); - assert_eq!(result, expected); - assert_eq!(overflow, Bitmap::from([false, true])); - } - - #[test] - fn test_sub_scalar() { - let a = Int32Array::from(&[None, Some(6), None, Some(6)]); - let result = sub_scalar(&a, &1i32); - let expected = Int32Array::from(&[None, Some(5), None, Some(5)]); - assert_eq!(result, expected); - - // Trait testing - let result = a.sub(&1i32).unwrap(); - assert_eq!(result, expected); - } - - #[test] - fn test_sub_scalar_checked() { - let a = Int32Array::from(&[None, Some(6), None, Some(6)]); - let result = checked_sub_scalar(&a, &1i32); - let expected = Int32Array::from(&[None, Some(5), None, Some(5)]); - assert_eq!(result, expected); - - let a = Int8Array::from(&[None, Some(-100), None, Some(-100)]); - let result = checked_sub_scalar(&a, &100i8); - let expected = Int8Array::from(&[None, None, None, None]); - assert_eq!(result, expected); - - // Trait testing - let result = a.checked_sub(&100i8).unwrap(); - assert_eq!(result, expected); - } - - #[test] - fn test_sub_scalar_saturating() { - let a = Int32Array::from(&[None, Some(6), None, Some(6)]); - let result = saturating_sub_scalar(&a, &1i32); - let expected = Int32Array::from(&[None, Some(5), None, Some(5)]); - assert_eq!(result, expected); - - let a = Int8Array::from(&[Some(-100i8)]); - let result = saturating_sub_scalar(&a, &100i8); - let expected = Int8Array::from(&[Some(-128)]); - assert_eq!(result, expected); - - // Trait testing - let result = a.saturating_sub(&100i8).unwrap(); - assert_eq!(result, expected); - } - - #[test] - fn test_sub_scalar_overflowing() { - let a = Int32Array::from(&[None, Some(6), None, Some(6)]); - let (result, overflow) = overflowing_sub_scalar(&a, &1i32); - let expected = Int32Array::from(&[None, Some(5), None, Some(5)]); - assert_eq!(result, expected); - assert_eq!(overflow, Bitmap::from([false, false, false, false])); - - let a = Int8Array::from(&[Some(1i8), Some(-100i8)]); - let (result, overflow) = overflowing_sub_scalar(&a, &100i8); - let expected = Int8Array::from(&[Some(-99i8), Some(56i8)]); - assert_eq!(result, expected); - assert_eq!(overflow, Bitmap::from([false, true])); - - // Trait testing - let (result, overflow) = a.overflowing_sub(&100i8).unwrap(); - assert_eq!(result, expected); - assert_eq!(overflow, Bitmap::from([false, true])); - } -} diff --git a/src/compute/arithmetics/decimal/add.rs b/src/compute/arithmetics/decimal/add.rs index 792b89e74ea..6d8d2e6e429 100644 --- a/src/compute/arithmetics/decimal/add.rs +++ b/src/compute/arithmetics/decimal/add.rs @@ -306,192 +306,3 @@ pub fn adaptive_add( )) } } - -#[allow(clippy::zero_prefixed_literal, clippy::inconsistent_digit_grouping)] -#[cfg(test)] -mod tests { - use super::*; - use crate::array::PrimitiveArray; - use crate::datatypes::DataType; - - #[test] - fn test_add_normal() { - let a = PrimitiveArray::from([Some(11111i128), Some(11100i128), None, Some(22200i128)]) - .to(DataType::Decimal(5, 2)); - - let b = PrimitiveArray::from([Some(22222i128), Some(22200i128), None, Some(11100i128)]) - .to(DataType::Decimal(5, 2)); - - let result = add(&a, &b).unwrap(); - let expected = - PrimitiveArray::from([Some(33333i128), Some(33300i128), None, Some(33300i128)]) - .to(DataType::Decimal(5, 2)); - - assert_eq!(result, expected); - - // Testing trait - let result = a.add(&b).unwrap(); - assert_eq!(result, expected); - } - - #[test] - fn test_add_decimal_wrong_precision() { - let a = PrimitiveArray::from([None]).to(DataType::Decimal(5, 2)); - let b = PrimitiveArray::from([None]).to(DataType::Decimal(6, 2)); - let result = add(&a, &b); - - if result.is_ok() { - panic!("Should panic for different precision"); - } - } - - #[test] - #[should_panic(expected = "Overflow in addition presented for precision 5")] - fn test_add_panic() { - let a = PrimitiveArray::from([Some(99999i128)]).to(DataType::Decimal(5, 2)); - let b = PrimitiveArray::from([Some(1i128)]).to(DataType::Decimal(5, 2)); - let _ = add(&a, &b); - } - - #[test] - fn test_add_saturating() { - let a = PrimitiveArray::from([Some(11111i128), Some(11100i128), None, Some(22200i128)]) - .to(DataType::Decimal(5, 2)); - - let b = PrimitiveArray::from([Some(22222i128), Some(22200i128), None, Some(11100i128)]) - .to(DataType::Decimal(5, 2)); - - let result = saturating_add(&a, &b).unwrap(); - let expected = - PrimitiveArray::from([Some(33333i128), Some(33300i128), None, Some(33300i128)]) - .to(DataType::Decimal(5, 2)); - - assert_eq!(result, expected); - - // Testing trait - let result = a.saturating_add(&b).unwrap(); - assert_eq!(result, expected); - } - - #[test] - fn test_add_saturating_overflow() { - let a = PrimitiveArray::from([ - Some(99999i128), - Some(99999i128), - Some(99999i128), - Some(-99999i128), - ]) - .to(DataType::Decimal(5, 2)); - let b = PrimitiveArray::from([ - Some(00001i128), - Some(00100i128), - Some(10000i128), - Some(-99999i128), - ]) - .to(DataType::Decimal(5, 2)); - - let result = saturating_add(&a, &b).unwrap(); - - let expected = PrimitiveArray::from([ - Some(99999i128), - Some(99999i128), - Some(99999i128), - Some(-99999i128), - ]) - .to(DataType::Decimal(5, 2)); - - assert_eq!(result, expected); - - // Testing trait - let result = a.saturating_add(&b).unwrap(); - assert_eq!(result, expected); - } - - #[test] - fn test_add_checked() { - let a = PrimitiveArray::from([Some(11111i128), Some(11100i128), None, Some(22200i128)]) - .to(DataType::Decimal(5, 2)); - - let b = PrimitiveArray::from([Some(22222i128), Some(22200i128), None, Some(11100i128)]) - .to(DataType::Decimal(5, 2)); - - let result = checked_add(&a, &b).unwrap(); - let expected = - PrimitiveArray::from([Some(33333i128), Some(33300i128), None, Some(33300i128)]) - .to(DataType::Decimal(5, 2)); - - assert_eq!(result, expected); - - // Testing trait - let result = a.checked_add(&b).unwrap(); - assert_eq!(result, expected); - } - - #[test] - fn test_add_checked_overflow() { - let a = PrimitiveArray::from([Some(1i128), Some(99999i128)]).to(DataType::Decimal(5, 2)); - let b = PrimitiveArray::from([Some(1i128), Some(1i128)]).to(DataType::Decimal(5, 2)); - let result = checked_add(&a, &b).unwrap(); - let expected = PrimitiveArray::from([Some(2i128), None]).to(DataType::Decimal(5, 2)); - assert_eq!(result, expected); - - // Testing trait - let result = a.checked_add(&b).unwrap(); - assert_eq!(result, expected); - } - - #[test] - fn test_add_adaptive() { - // 11.1111 -> 6, 4 - // 11111.11 -> 7, 2 - // ----------------- - // 11122.2211 -> 9, 4 - let a = PrimitiveArray::from([Some(11_1111i128)]).to(DataType::Decimal(6, 4)); - let b = PrimitiveArray::from([Some(11111_11i128)]).to(DataType::Decimal(7, 2)); - let result = adaptive_add(&a, &b).unwrap(); - - let expected = PrimitiveArray::from([Some(11122_2211i128)]).to(DataType::Decimal(9, 4)); - - assert_eq!(result, expected); - assert_eq!(result.data_type(), &DataType::Decimal(9, 4)); - - // 0.1111 -> 5, 4 - // 11111.0 -> 6, 1 - // ----------------- - // 11111.1111 -> 9, 4 - let a = PrimitiveArray::from([Some(1111i128)]).to(DataType::Decimal(5, 4)); - let b = PrimitiveArray::from([Some(11111_0i128)]).to(DataType::Decimal(6, 1)); - let result = adaptive_add(&a, &b).unwrap(); - - let expected = PrimitiveArray::from([Some(11111_1111i128)]).to(DataType::Decimal(9, 4)); - - assert_eq!(result, expected); - assert_eq!(result.data_type(), &DataType::Decimal(9, 4)); - - // 11111.11 -> 7, 2 - // 11111.111 -> 8, 3 - // ----------------- - // 22222.221 -> 8, 3 - let a = PrimitiveArray::from([Some(11111_11i128)]).to(DataType::Decimal(7, 2)); - let b = PrimitiveArray::from([Some(11111_111i128)]).to(DataType::Decimal(8, 3)); - let result = adaptive_add(&a, &b).unwrap(); - - let expected = PrimitiveArray::from([Some(22222_221i128)]).to(DataType::Decimal(8, 3)); - - assert_eq!(result, expected); - assert_eq!(result.data_type(), &DataType::Decimal(8, 3)); - - // 99.9999 -> 6, 4 - // 00.0001 -> 6, 4 - // ----------------- - // 100.0000 -> 7, 4 - let a = PrimitiveArray::from([Some(99_9999i128)]).to(DataType::Decimal(6, 4)); - let b = PrimitiveArray::from([Some(00_0001i128)]).to(DataType::Decimal(6, 4)); - let result = adaptive_add(&a, &b).unwrap(); - - let expected = PrimitiveArray::from([Some(100_0000i128)]).to(DataType::Decimal(7, 4)); - - assert_eq!(result, expected); - assert_eq!(result.data_type(), &DataType::Decimal(7, 4)); - } -} diff --git a/src/compute/arithmetics/decimal/div.rs b/src/compute/arithmetics/decimal/div.rs index 65e9b2863a9..b83fba11cfa 100644 --- a/src/compute/arithmetics/decimal/div.rs +++ b/src/compute/arithmetics/decimal/div.rs @@ -331,239 +331,3 @@ pub fn adaptive_div( )) } } - -#[allow(clippy::zero_prefixed_literal, clippy::inconsistent_digit_grouping)] -#[cfg(test)] -mod tests { - use super::*; - use crate::array::PrimitiveArray; - use crate::datatypes::DataType; - - #[test] - fn test_divide_normal() { - // 222.222 --> 222222000 - // 123.456 --> 123456 - // -------- --------- - // 1.800 <-- 1800 - let a = PrimitiveArray::from([ - Some(222_222i128), - Some(10_000i128), - Some(20_000i128), - None, - Some(30_000i128), - Some(123_456i128), - ]) - .to(DataType::Decimal(7, 3)); - - let b = PrimitiveArray::from([ - Some(123_456i128), - Some(2_000i128), - Some(3_000i128), - Some(4_000i128), - Some(4_000i128), - Some(654_321i128), - ]) - .to(DataType::Decimal(7, 3)); - - let result = div(&a, &b).unwrap(); - let expected = PrimitiveArray::from([ - Some(1_800i128), - Some(5_000i128), - Some(6_666i128), - None, - Some(7_500i128), - Some(0_188i128), - ]) - .to(DataType::Decimal(7, 3)); - - assert_eq!(result, expected); - - // Testing trait - let result = a.div(&b).unwrap(); - assert_eq!(result, expected); - } - - #[test] - fn test_divide_decimal_wrong_precision() { - let a = PrimitiveArray::from([None]).to(DataType::Decimal(5, 2)); - let b = PrimitiveArray::from([None]).to(DataType::Decimal(6, 2)); - let result = div(&a, &b); - - if result.is_ok() { - panic!("Should panic for different precision"); - } - } - - #[test] - #[should_panic(expected = "Overflow in multiplication presented for precision 5")] - fn test_divide_panic() { - let a = PrimitiveArray::from([Some(99999i128)]).to(DataType::Decimal(5, 2)); - let b = PrimitiveArray::from([Some(000_01i128)]).to(DataType::Decimal(5, 2)); - let _ = div(&a, &b); - } - - #[test] - fn test_divide_saturating() { - let a = PrimitiveArray::from([ - Some(222_222i128), - Some(10_000i128), - Some(20_000i128), - None, - Some(30_000i128), - Some(123_456i128), - ]) - .to(DataType::Decimal(7, 3)); - - let b = PrimitiveArray::from([ - Some(123_456i128), - Some(2_000i128), - Some(3_000i128), - Some(4_000i128), - Some(4_000i128), - Some(654_321i128), - ]) - .to(DataType::Decimal(7, 3)); - - let result = saturating_div(&a, &b).unwrap(); - let expected = PrimitiveArray::from([ - Some(1_800i128), - Some(5_000i128), - Some(6_666i128), - None, - Some(7_500i128), - Some(0_188i128), - ]) - .to(DataType::Decimal(7, 3)); - - assert_eq!(result, expected); - } - - #[test] - fn test_divide_saturating_overflow() { - let a = PrimitiveArray::from([ - Some(99999i128), - Some(99999i128), - Some(99999i128), - Some(99999i128), - Some(99999i128), - ]) - .to(DataType::Decimal(5, 2)); - let b = PrimitiveArray::from([ - Some(-00001i128), - Some(00001i128), - Some(00010i128), - Some(-00020i128), - Some(00000i128), - ]) - .to(DataType::Decimal(5, 2)); - - let result = saturating_div(&a, &b).unwrap(); - - let expected = PrimitiveArray::from([ - Some(-99999i128), - Some(99999i128), - Some(99999i128), - Some(-99999i128), - Some(00000i128), - ]) - .to(DataType::Decimal(5, 2)); - - assert_eq!(result, expected); - } - - #[test] - fn test_divide_checked() { - let a = PrimitiveArray::from([ - Some(222_222i128), - Some(10_000i128), - Some(20_000i128), - None, - Some(30_000i128), - Some(123_456i128), - ]) - .to(DataType::Decimal(7, 3)); - - let b = PrimitiveArray::from([ - Some(123_456i128), - Some(2_000i128), - Some(3_000i128), - Some(4_000i128), - Some(4_000i128), - Some(654_321i128), - ]) - .to(DataType::Decimal(7, 3)); - - let result = div(&a, &b).unwrap(); - let expected = PrimitiveArray::from([ - Some(1_800i128), - Some(5_000i128), - Some(6_666i128), - None, - Some(7_500i128), - Some(0_188i128), - ]) - .to(DataType::Decimal(7, 3)); - - assert_eq!(result, expected); - } - - #[test] - fn test_divide_checked_overflow() { - let a = PrimitiveArray::from([Some(1_00i128), Some(4_00i128), Some(6_00i128)]) - .to(DataType::Decimal(5, 2)); - let b = PrimitiveArray::from([Some(000_00i128), None, Some(2_00i128)]) - .to(DataType::Decimal(5, 2)); - - let result = checked_div(&a, &b).unwrap(); - let expected = - PrimitiveArray::from([None, None, Some(3_00i128)]).to(DataType::Decimal(5, 2)); - - assert_eq!(result, expected); - - // Testing trait - let result = a.checked_div(&b).unwrap(); - assert_eq!(result, expected); - } - - #[test] - fn test_divide_adaptive() { - // 1000.00 -> 7, 2 - // 10.0000 -> 6, 4 - // ----------------- - // 100.0000 -> 9, 4 - let a = PrimitiveArray::from([Some(1000_00i128)]).to(DataType::Decimal(7, 2)); - let b = PrimitiveArray::from([Some(10_0000i128)]).to(DataType::Decimal(6, 4)); - let result = adaptive_div(&a, &b).unwrap(); - - let expected = PrimitiveArray::from([Some(100_0000i128)]).to(DataType::Decimal(9, 4)); - - assert_eq!(result, expected); - assert_eq!(result.data_type(), &DataType::Decimal(9, 4)); - - // 11111.0 -> 6, 1 - // 10.002 -> 5, 3 - // ----------------- - // 1110.877 -> 8, 3 - let a = PrimitiveArray::from([Some(11111_0i128)]).to(DataType::Decimal(6, 1)); - let b = PrimitiveArray::from([Some(10_002i128)]).to(DataType::Decimal(5, 3)); - let result = adaptive_div(&a, &b).unwrap(); - - let expected = PrimitiveArray::from([Some(1110_877i128)]).to(DataType::Decimal(8, 3)); - - assert_eq!(result, expected); - assert_eq!(result.data_type(), &DataType::Decimal(8, 3)); - - // 12345.67 -> 7, 2 - // 12345.678 -> 8, 3 - // ----------------- - // 0.999 -> 8, 3 - let a = PrimitiveArray::from([Some(12345_67i128)]).to(DataType::Decimal(7, 2)); - let b = PrimitiveArray::from([Some(12345_678i128)]).to(DataType::Decimal(8, 3)); - let result = adaptive_div(&a, &b).unwrap(); - - let expected = PrimitiveArray::from([Some(0_999i128)]).to(DataType::Decimal(8, 3)); - - assert_eq!(result, expected); - assert_eq!(result.data_type(), &DataType::Decimal(8, 3)); - } -} diff --git a/src/compute/arithmetics/decimal/mul.rs b/src/compute/arithmetics/decimal/mul.rs index 0447e6e96a9..008f608db02 100644 --- a/src/compute/arithmetics/decimal/mul.rs +++ b/src/compute/arithmetics/decimal/mul.rs @@ -335,240 +335,3 @@ pub fn adaptive_mul( )) } } - -#[allow(clippy::zero_prefixed_literal, clippy::inconsistent_digit_grouping)] -#[cfg(test)] -mod tests { - use super::*; - use crate::array::PrimitiveArray; - use crate::datatypes::DataType; - - #[test] - fn test_multiply_normal() { - // 111.11 --> 11111 - // 222.22 --> 22222 - // -------- ------- - // 24690.86 <-- 246908642 - let a = PrimitiveArray::from([ - Some(111_11i128), - Some(10_00i128), - Some(20_00i128), - None, - Some(30_00i128), - Some(123_45i128), - ]) - .to(DataType::Decimal(7, 2)); - - let b = PrimitiveArray::from([ - Some(222_22i128), - Some(2_00i128), - Some(3_00i128), - None, - Some(4_00i128), - Some(543_21i128), - ]) - .to(DataType::Decimal(7, 2)); - - let result = mul(&a, &b).unwrap(); - let expected = PrimitiveArray::from([ - Some(24690_86i128), - Some(20_00i128), - Some(60_00i128), - None, - Some(120_00i128), - Some(67059_27i128), - ]) - .to(DataType::Decimal(7, 2)); - - assert_eq!(result, expected); - - // Testing trait - let result = a.mul(&b).unwrap(); - assert_eq!(result, expected); - } - - #[test] - fn test_multiply_decimal_wrong_precision() { - let a = PrimitiveArray::from([None]).to(DataType::Decimal(5, 2)); - let b = PrimitiveArray::from([None]).to(DataType::Decimal(6, 2)); - let result = mul(&a, &b); - - if result.is_ok() { - panic!("Should panic for different precision"); - } - } - - #[test] - #[should_panic(expected = "Overflow in multiplication presented for precision 5")] - fn test_multiply_panic() { - let a = PrimitiveArray::from([Some(99999i128)]).to(DataType::Decimal(5, 2)); - let b = PrimitiveArray::from([Some(100_00i128)]).to(DataType::Decimal(5, 2)); - let _ = mul(&a, &b); - } - - #[test] - fn test_multiply_saturating() { - let a = PrimitiveArray::from([ - Some(111_11i128), - Some(10_00i128), - Some(20_00i128), - None, - Some(30_00i128), - Some(123_45i128), - ]) - .to(DataType::Decimal(7, 2)); - - let b = PrimitiveArray::from([ - Some(222_22i128), - Some(2_00i128), - Some(3_00i128), - None, - Some(4_00i128), - Some(543_21i128), - ]) - .to(DataType::Decimal(7, 2)); - - let result = saturating_mul(&a, &b).unwrap(); - let expected = PrimitiveArray::from([ - Some(24690_86i128), - Some(20_00i128), - Some(60_00i128), - None, - Some(120_00i128), - Some(67059_27i128), - ]) - .to(DataType::Decimal(7, 2)); - - assert_eq!(result, expected); - - // Testing trait - let result = a.saturating_mul(&b).unwrap(); - assert_eq!(result, expected); - } - - #[test] - fn test_multiply_saturating_overflow() { - let a = PrimitiveArray::from([ - Some(99999i128), - Some(99999i128), - Some(99999i128), - Some(99999i128), - ]) - .to(DataType::Decimal(5, 2)); - let b = PrimitiveArray::from([ - Some(-00100i128), - Some(01000i128), - Some(10000i128), - Some(-99999i128), - ]) - .to(DataType::Decimal(5, 2)); - - let result = saturating_mul(&a, &b).unwrap(); - - let expected = PrimitiveArray::from([ - Some(-99999i128), - Some(99999i128), - Some(99999i128), - Some(-99999i128), - ]) - .to(DataType::Decimal(5, 2)); - - assert_eq!(result, expected); - - // Testing trait - let result = a.saturating_mul(&b).unwrap(); - assert_eq!(result, expected); - } - - #[test] - fn test_multiply_checked() { - let a = PrimitiveArray::from([ - Some(111_11i128), - Some(10_00i128), - Some(20_00i128), - None, - Some(30_00i128), - Some(123_45i128), - ]) - .to(DataType::Decimal(7, 2)); - - let b = PrimitiveArray::from([ - Some(222_22i128), - Some(2_00i128), - Some(3_00i128), - None, - Some(4_00i128), - Some(543_21i128), - ]) - .to(DataType::Decimal(7, 2)); - - let result = checked_mul(&a, &b).unwrap(); - let expected = PrimitiveArray::from([ - Some(24690_86i128), - Some(20_00i128), - Some(60_00i128), - None, - Some(120_00i128), - Some(67059_27i128), - ]) - .to(DataType::Decimal(7, 2)); - - assert_eq!(result, expected); - - // Testing trait - let result = a.checked_mul(&b).unwrap(); - assert_eq!(result, expected); - } - - #[test] - fn test_multiply_checked_overflow() { - let a = PrimitiveArray::from([Some(99999i128), Some(1_00i128)]).to(DataType::Decimal(5, 2)); - let b = PrimitiveArray::from([Some(10000i128), Some(2_00i128)]).to(DataType::Decimal(5, 2)); - let result = checked_mul(&a, &b).unwrap(); - let expected = PrimitiveArray::from([None, Some(2_00i128)]).to(DataType::Decimal(5, 2)); - - assert_eq!(result, expected); - } - - #[test] - fn test_multiply_adaptive() { - // 1000.00 -> 7, 2 - // 10.0000 -> 6, 4 - // ----------------- - // 10000.0000 -> 9, 4 - let a = PrimitiveArray::from([Some(1000_00i128)]).to(DataType::Decimal(7, 2)); - let b = PrimitiveArray::from([Some(10_0000i128)]).to(DataType::Decimal(6, 4)); - let result = adaptive_mul(&a, &b).unwrap(); - - let expected = PrimitiveArray::from([Some(10000_0000i128)]).to(DataType::Decimal(9, 4)); - - assert_eq!(result, expected); - assert_eq!(result.data_type(), &DataType::Decimal(9, 4)); - - // 11111.0 -> 6, 1 - // 10.002 -> 5, 3 - // ----------------- - // 111132.222 -> 9, 3 - let a = PrimitiveArray::from([Some(11111_0i128)]).to(DataType::Decimal(6, 1)); - let b = PrimitiveArray::from([Some(10_002i128)]).to(DataType::Decimal(5, 3)); - let result = adaptive_mul(&a, &b).unwrap(); - - let expected = PrimitiveArray::from([Some(111132_222i128)]).to(DataType::Decimal(9, 3)); - - assert_eq!(result, expected); - assert_eq!(result.data_type(), &DataType::Decimal(9, 3)); - - // 12345.67 -> 7, 2 - // 12345.678 -> 8, 3 - // ----------------- - // 152415666.514 -> 11, 3 - let a = PrimitiveArray::from([Some(12345_67i128)]).to(DataType::Decimal(7, 2)); - let b = PrimitiveArray::from([Some(12345_678i128)]).to(DataType::Decimal(8, 3)); - let result = adaptive_mul(&a, &b).unwrap(); - - let expected = PrimitiveArray::from([Some(152415666_514i128)]).to(DataType::Decimal(12, 3)); - - assert_eq!(result, expected); - assert_eq!(result.data_type(), &DataType::Decimal(12, 3)); - } -} diff --git a/src/compute/arithmetics/decimal/sub.rs b/src/compute/arithmetics/decimal/sub.rs index 17d7668dae4..130193bbb36 100644 --- a/src/compute/arithmetics/decimal/sub.rs +++ b/src/compute/arithmetics/decimal/sub.rs @@ -304,188 +304,3 @@ pub fn adaptive_sub( )) } } - -#[allow(clippy::zero_prefixed_literal, clippy::inconsistent_digit_grouping)] -#[cfg(test)] -mod tests { - use super::*; - use crate::array::PrimitiveArray; - use crate::datatypes::DataType; - - #[test] - fn test_subtract_normal() { - let a = PrimitiveArray::from([Some(11111i128), Some(22200i128), None, Some(40000i128)]) - .to(DataType::Decimal(5, 2)); - - let b = PrimitiveArray::from([Some(22222i128), Some(11100i128), None, Some(11100i128)]) - .to(DataType::Decimal(5, 2)); - - let result = sub(&a, &b).unwrap(); - let expected = - PrimitiveArray::from([Some(-11111i128), Some(11100i128), None, Some(28900i128)]) - .to(DataType::Decimal(5, 2)); - - assert_eq!(result, expected); - - // Testing trait - let result = a.sub(&b).unwrap(); - assert_eq!(result, expected); - } - - #[test] - fn test_subtract_decimal_wrong_precision() { - let a = PrimitiveArray::from([None]).to(DataType::Decimal(5, 2)); - let b = PrimitiveArray::from([None]).to(DataType::Decimal(6, 2)); - let result = sub(&a, &b); - - if result.is_ok() { - panic!("Should panic for different precision"); - } - } - - #[test] - #[should_panic(expected = "Overflow in subtract presented for precision 5")] - fn test_subtract_panic() { - let a = PrimitiveArray::from([Some(-99999i128)]).to(DataType::Decimal(5, 2)); - let b = PrimitiveArray::from([Some(1i128)]).to(DataType::Decimal(5, 2)); - let _ = sub(&a, &b); - } - - #[test] - fn test_subtract_saturating() { - let a = PrimitiveArray::from([Some(11111i128), Some(22200i128), None, Some(40000i128)]) - .to(DataType::Decimal(5, 2)); - - let b = PrimitiveArray::from([Some(22222i128), Some(11100i128), None, Some(11100i128)]) - .to(DataType::Decimal(5, 2)); - - let result = saturating_sub(&a, &b).unwrap(); - let expected = - PrimitiveArray::from([Some(-11111i128), Some(11100i128), None, Some(28900i128)]) - .to(DataType::Decimal(5, 2)); - - assert_eq!(result, expected); - - // Testing trait - let result = a.saturating_sub(&b).unwrap(); - assert_eq!(result, expected); - } - - #[test] - fn test_subtract_saturating_overflow() { - let a = PrimitiveArray::from([ - Some(-99999i128), - Some(-99999i128), - Some(-99999i128), - Some(99999i128), - ]) - .to(DataType::Decimal(5, 2)); - let b = PrimitiveArray::from([ - Some(00001i128), - Some(00100i128), - Some(10000i128), - Some(-99999i128), - ]) - .to(DataType::Decimal(5, 2)); - - let result = saturating_sub(&a, &b).unwrap(); - - let expected = PrimitiveArray::from([ - Some(-99999i128), - Some(-99999i128), - Some(-99999i128), - Some(99999i128), - ]) - .to(DataType::Decimal(5, 2)); - - assert_eq!(result, expected); - - // Testing trait - let result = a.saturating_sub(&b).unwrap(); - assert_eq!(result, expected); - } - - #[test] - fn test_subtract_checked() { - let a = PrimitiveArray::from([Some(11111i128), Some(22200i128), None, Some(40000i128)]) - .to(DataType::Decimal(5, 2)); - - let b = PrimitiveArray::from([Some(22222i128), Some(11100i128), None, Some(11100i128)]) - .to(DataType::Decimal(5, 2)); - - let result = checked_sub(&a, &b).unwrap(); - let expected = - PrimitiveArray::from([Some(-11111i128), Some(11100i128), None, Some(28900i128)]) - .to(DataType::Decimal(5, 2)); - - assert_eq!(result, expected); - - // Testing trait - let result = a.checked_sub(&b).unwrap(); - assert_eq!(result, expected); - } - - #[test] - fn test_subtract_checked_overflow() { - let a = PrimitiveArray::from([Some(4i128), Some(-99999i128)]).to(DataType::Decimal(5, 2)); - let b = PrimitiveArray::from([Some(2i128), Some(1i128)]).to(DataType::Decimal(5, 2)); - let result = checked_sub(&a, &b).unwrap(); - let expected = PrimitiveArray::from([Some(2i128), None]).to(DataType::Decimal(5, 2)); - assert_eq!(result, expected); - } - - #[test] - fn test_subtract_adaptive() { - // 11.1111 -> 6, 4 - // 11111.11 -> 7, 2 - // ------------------ - // -11099.9989 -> 9, 4 - let a = PrimitiveArray::from([Some(11_1111i128)]).to(DataType::Decimal(6, 4)); - let b = PrimitiveArray::from([Some(11111_11i128)]).to(DataType::Decimal(7, 2)); - let result = adaptive_sub(&a, &b).unwrap(); - - let expected = PrimitiveArray::from([Some(-11099_9989i128)]).to(DataType::Decimal(9, 4)); - - assert_eq!(result, expected); - assert_eq!(result.data_type(), &DataType::Decimal(9, 4)); - - // 11111.0 -> 6, 1 - // 0.1111 -> 5, 4 - // ----------------- - // 11110.8889 -> 9, 4 - let a = PrimitiveArray::from([Some(11111_0i128)]).to(DataType::Decimal(6, 1)); - let b = PrimitiveArray::from([Some(1111i128)]).to(DataType::Decimal(5, 4)); - let result = adaptive_sub(&a, &b).unwrap(); - - let expected = PrimitiveArray::from([Some(11110_8889i128)]).to(DataType::Decimal(9, 4)); - - assert_eq!(result, expected); - assert_eq!(result.data_type(), &DataType::Decimal(9, 4)); - - // 11111.11 -> 7, 2 - // 11111.111 -> 8, 3 - // ----------------- - // -00000.001 -> 8, 3 - let a = PrimitiveArray::from([Some(11111_11i128)]).to(DataType::Decimal(7, 2)); - let b = PrimitiveArray::from([Some(11111_111i128)]).to(DataType::Decimal(8, 3)); - let result = adaptive_sub(&a, &b).unwrap(); - - let expected = PrimitiveArray::from([Some(-00000_001i128)]).to(DataType::Decimal(8, 3)); - - assert_eq!(result, expected); - assert_eq!(result.data_type(), &DataType::Decimal(8, 3)); - - // 99.9999 -> 6, 4 - // -00.0001 -> 6, 4 - // ----------------- - // 100.0000 -> 7, 4 - let a = PrimitiveArray::from([Some(99_9999i128)]).to(DataType::Decimal(6, 4)); - let b = PrimitiveArray::from([Some(-00_0001i128)]).to(DataType::Decimal(6, 4)); - let result = adaptive_sub(&a, &b).unwrap(); - - let expected = PrimitiveArray::from([Some(100_0000i128)]).to(DataType::Decimal(7, 4)); - - assert_eq!(result, expected); - assert_eq!(result.data_type(), &DataType::Decimal(7, 4)); - } -} diff --git a/src/compute/arithmetics/mod.rs b/src/compute/arithmetics/mod.rs index 3ca6c51b17c..8475055b771 100644 --- a/src/compute/arithmetics/mod.rs +++ b/src/compute/arithmetics/mod.rs @@ -427,71 +427,3 @@ unsafe impl NotI128 for i32 {} unsafe impl NotI128 for i64 {} unsafe impl NotI128 for f32 {} unsafe impl NotI128 for f64 {} - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn consistency() { - use crate::datatypes::DataType::*; - use crate::datatypes::TimeUnit; - - let datatypes = vec![ - Null, - Boolean, - UInt8, - UInt16, - UInt32, - UInt64, - Int8, - Int16, - Int32, - Int64, - Float32, - Float64, - Timestamp(TimeUnit::Second, None), - Timestamp(TimeUnit::Millisecond, None), - Timestamp(TimeUnit::Microsecond, None), - Timestamp(TimeUnit::Nanosecond, None), - Time64(TimeUnit::Microsecond), - Time64(TimeUnit::Nanosecond), - Date32, - Time32(TimeUnit::Second), - Time32(TimeUnit::Millisecond), - Date64, - Utf8, - LargeUtf8, - Binary, - LargeBinary, - Duration(TimeUnit::Second), - Duration(TimeUnit::Millisecond), - Duration(TimeUnit::Microsecond), - Duration(TimeUnit::Nanosecond), - Interval(IntervalUnit::MonthDayNano), - ]; - let operators = vec![ - Operator::Add, - Operator::Divide, - Operator::Subtract, - Operator::Multiply, - Operator::Remainder, - ]; - - let cases = datatypes - .clone() - .into_iter() - .zip(operators.into_iter()) - .zip(datatypes.into_iter()); - - cases.for_each(|((lhs, op), rhs)| { - let lhs_a = new_empty_array(lhs.clone()); - let rhs_a = new_empty_array(rhs.clone()); - if can_arithmetic(&lhs, op, &rhs) { - assert!(arithmetic(lhs_a.as_ref(), op, rhs_a.as_ref()).is_ok()); - } else { - assert!(arithmetic(lhs_a.as_ref(), op, rhs_a.as_ref()).is_err()); - } - }); - } -} diff --git a/src/compute/arithmetics/time.rs b/src/compute/arithmetics/time.rs index 601457f6e12..1b64c4e0038 100644 --- a/src/compute/arithmetics/time.rs +++ b/src/compute/arithmetics/time.rs @@ -285,325 +285,3 @@ pub fn add_interval( )), } } - -#[cfg(test)] -mod tests { - use super::*; - use crate::array::PrimitiveArray; - use crate::datatypes::{DataType, TimeUnit}; - - #[test] - fn test_adding_timestamp() { - let timestamp = - PrimitiveArray::from([Some(100000i64), Some(200000i64), None, Some(300000i64)]).to( - DataType::Timestamp(TimeUnit::Second, Some("America/New_York".to_string())), - ); - - let duration = PrimitiveArray::from([Some(10i64), Some(20i64), None, Some(30i64)]) - .to(DataType::Duration(TimeUnit::Second)); - - let result = add_duration(×tamp, &duration).unwrap(); - let expected = - PrimitiveArray::from([Some(100010i64), Some(200020i64), None, Some(300030i64)]).to( - DataType::Timestamp(TimeUnit::Second, Some("America/New_York".to_string())), - ); - - assert_eq!(result, expected); - } - - #[test] - fn test_adding_duration_different_scale() { - let timestamp = - PrimitiveArray::from([Some(100000i64), Some(200000i64), None, Some(300000i64)]).to( - DataType::Timestamp(TimeUnit::Second, Some("America/New_York".to_string())), - ); - let expected = - PrimitiveArray::from([Some(100010i64), Some(200020i64), None, Some(300030i64)]).to( - DataType::Timestamp(TimeUnit::Second, Some("America/New_York".to_string())), - ); - - // Testing duration in milliseconds - let duration = - PrimitiveArray::from([Some(10_000i64), Some(20_000i64), None, Some(30_000i64)]) - .to(DataType::Duration(TimeUnit::Millisecond)); - - let result = add_duration(×tamp, &duration).unwrap(); - assert_eq!(result, expected); - - // Testing duration in nanoseconds. - // The last digits in the nanosecond are not significant enough to - // be added to the timestamp which is in seconds and doesn't have a - // fractional value - let duration = PrimitiveArray::from([ - Some(10_000_000_999i64), - Some(20_000_000_000i64), - None, - Some(30_000_000_000i64), - ]) - .to(DataType::Duration(TimeUnit::Nanosecond)); - - let result = add_duration(×tamp, &duration).unwrap(); - assert_eq!(result, expected); - } - - #[test] - fn test_adding_subtract_timestamps_scale() { - let timestamp = PrimitiveArray::from([Some(10i64), Some(20i64), None, Some(30i64)]).to( - DataType::Timestamp(TimeUnit::Millisecond, Some("America/New_York".to_string())), - ); - let duration = PrimitiveArray::from([Some(1i64), Some(2i64), None, Some(3i64)]) - .to(DataType::Duration(TimeUnit::Second)); - - let expected = - PrimitiveArray::from([Some(1_010i64), Some(2_020i64), None, Some(3_030i64)]).to( - DataType::Timestamp(TimeUnit::Millisecond, Some("America/New_York".to_string())), - ); - - let result = add_duration(×tamp, &duration).unwrap(); - assert_eq!(result, expected); - - let timestamp = PrimitiveArray::from([Some(10i64), Some(20i64), None, Some(30i64)]).to( - DataType::Timestamp(TimeUnit::Nanosecond, Some("America/New_York".to_string())), - ); - let duration = PrimitiveArray::from([Some(1i64), Some(2i64), None, Some(3i64)]) - .to(DataType::Duration(TimeUnit::Second)); - - let expected = PrimitiveArray::from([ - Some(1_000_000_010i64), - Some(2_000_000_020i64), - None, - Some(3_000_000_030i64), - ]) - .to(DataType::Timestamp( - TimeUnit::Nanosecond, - Some("America/New_York".to_string()), - )); - - let result = add_duration(×tamp, &duration).unwrap(); - assert_eq!(result, expected); - } - - #[test] - fn test_subtract_timestamp() { - let timestamp = - PrimitiveArray::from([Some(100000i64), Some(200000i64), None, Some(300000i64)]).to( - DataType::Timestamp(TimeUnit::Second, Some("America/New_York".to_string())), - ); - - let duration = PrimitiveArray::from([Some(10i64), Some(20i64), None, Some(30i64)]) - .to(DataType::Duration(TimeUnit::Second)); - - let result = subtract_duration(×tamp, &duration).unwrap(); - let expected = - PrimitiveArray::from([Some(99990i64), Some(199980i64), None, Some(299970i64)]).to( - DataType::Timestamp(TimeUnit::Second, Some("America/New_York".to_string())), - ); - - assert_eq!(result, expected); - } - - #[test] - fn test_subtracting_duration_different_scale() { - let timestamp = - PrimitiveArray::from([Some(100000i64), Some(200000i64), None, Some(300000i64)]).to( - DataType::Timestamp(TimeUnit::Second, Some("America/New_York".to_string())), - ); - let expected = - PrimitiveArray::from([Some(99990i64), Some(199980i64), None, Some(299970i64)]).to( - DataType::Timestamp(TimeUnit::Second, Some("America/New_York".to_string())), - ); - - // Testing duration in milliseconds - let duration = - PrimitiveArray::from([Some(10_000i64), Some(20_000i64), None, Some(30_000i64)]) - .to(DataType::Duration(TimeUnit::Millisecond)); - - let result = subtract_duration(×tamp, &duration).unwrap(); - assert_eq!(result, expected); - - // Testing duration in nanoseconds. - // The last digits in the nanosecond are not significant enough to - // be added to the timestamp which is in seconds and doesn't have a - // fractional value - let duration = PrimitiveArray::from([ - Some(10_000_000_999i64), - Some(20_000_000_000i64), - None, - Some(30_000_000_000i64), - ]) - .to(DataType::Duration(TimeUnit::Nanosecond)); - - let result = subtract_duration(×tamp, &duration).unwrap(); - assert_eq!(result, expected); - } - - #[test] - fn test_subtracting_subtract_timestamps_scale() { - let timestamp = PrimitiveArray::from([Some(10i64), Some(20i64), None, Some(30i64)]).to( - DataType::Timestamp(TimeUnit::Millisecond, Some("America/New_York".to_string())), - ); - let duration = PrimitiveArray::from([Some(1i64), Some(2i64), None, Some(3i64)]) - .to(DataType::Duration(TimeUnit::Second)); - - let expected = - PrimitiveArray::from([Some(-990i64), Some(-1_980i64), None, Some(-2_970i64)]).to( - DataType::Timestamp(TimeUnit::Millisecond, Some("America/New_York".to_string())), - ); - - let result = subtract_duration(×tamp, &duration).unwrap(); - assert_eq!(result, expected); - - let timestamp = PrimitiveArray::from([Some(10i64), Some(20i64), None, Some(30i64)]).to( - DataType::Timestamp(TimeUnit::Nanosecond, Some("America/New_York".to_string())), - ); - let duration = PrimitiveArray::from([Some(1i64), Some(2i64), None, Some(3i64)]) - .to(DataType::Duration(TimeUnit::Second)); - - let expected = PrimitiveArray::from([ - Some(-999_999_990i64), - Some(-1_999_999_980i64), - None, - Some(-2_999_999_970i64), - ]) - .to(DataType::Timestamp( - TimeUnit::Nanosecond, - Some("America/New_York".to_string()), - )); - - let result = subtract_duration(×tamp, &duration).unwrap(); - assert_eq!(result, expected); - } - - #[test] - fn test_subtract_timestamps() { - let timestamp_a = - PrimitiveArray::from([Some(100_010i64), Some(200_020i64), None, Some(300_030i64)]) - .to(DataType::Timestamp(TimeUnit::Second, None)); - - let timestamp_b = - PrimitiveArray::from([Some(100_000i64), Some(200_000i64), None, Some(300_000i64)]) - .to(DataType::Timestamp(TimeUnit::Second, None)); - - let expected = PrimitiveArray::from([Some(10i64), Some(20i64), None, Some(30i64)]) - .to(DataType::Duration(TimeUnit::Second)); - - let result = subtract_timestamps(×tamp_a, ×tamp_b).unwrap(); - assert_eq!(result, expected); - } - - #[test] - fn test_subtract_timestamps_scale() { - let timestamp_a = PrimitiveArray::from([ - Some(100_000_000i64), - Some(200_000_000i64), - None, - Some(300_000_000i64), - ]) - .to(DataType::Timestamp(TimeUnit::Millisecond, None)); - - let timestamp_b = - PrimitiveArray::from([Some(100_010i64), Some(200_020i64), None, Some(300_030i64)]) - .to(DataType::Timestamp(TimeUnit::Second, None)); - - let expected = - PrimitiveArray::from([Some(-10_000i64), Some(-20_000i64), None, Some(-30_000i64)]) - .to(DataType::Duration(TimeUnit::Millisecond)); - - let result = subtract_timestamps(×tamp_a, ×tamp_b).unwrap(); - assert_eq!(result, expected); - } - - #[test] - fn test_adding_to_time() { - let duration = PrimitiveArray::from([Some(10i64), Some(20i64), None, Some(30i64)]) - .to(DataType::Duration(TimeUnit::Second)); - - // Testing Time32 - let time_32 = - PrimitiveArray::from([Some(100000i32), Some(200000i32), None, Some(300000i32)]) - .to(DataType::Time32(TimeUnit::Second)); - - let result = add_duration(&time_32, &duration).unwrap(); - let expected = - PrimitiveArray::from([Some(100010i32), Some(200020i32), None, Some(300030i32)]) - .to(DataType::Time32(TimeUnit::Second)); - - assert_eq!(result, expected); - } - - #[test] - fn test_subtract_to_time() { - let duration = PrimitiveArray::from([Some(10i64), Some(20i64), None, Some(30i64)]) - .to(DataType::Duration(TimeUnit::Second)); - - // Testing Time32 - let time_32 = - PrimitiveArray::from([Some(100000i32), Some(200000i32), None, Some(300000i32)]) - .to(DataType::Time32(TimeUnit::Second)); - - let result = subtract_duration(&time_32, &duration).unwrap(); - let expected = - PrimitiveArray::from([Some(99990i32), Some(199980i32), None, Some(299970i32)]) - .to(DataType::Time32(TimeUnit::Second)); - - assert_eq!(result, expected); - } - - #[test] - fn test_date32() { - let duration = PrimitiveArray::from([ - Some(86_400), // 1 day - Some(864_000i64), // 10 days - None, - Some(8_640_000i64), // 100 days - ]) - .to(DataType::Duration(TimeUnit::Second)); - - let date_32 = - PrimitiveArray::from([Some(100_000i32), Some(100_000i32), None, Some(100_000i32)]) - .to(DataType::Date32); - - let result = add_duration(&date_32, &duration).unwrap(); - let expected = - PrimitiveArray::from([Some(100_001i32), Some(100_010i32), None, Some(100_100i32)]) - .to(DataType::Date32); - - assert_eq!(result, expected); - - let result = subtract_duration(&date_32, &duration).unwrap(); - let expected = - PrimitiveArray::from([Some(99_999i32), Some(99_990i32), None, Some(99_900i32)]) - .to(DataType::Date32); - - assert_eq!(result, expected); - } - - #[test] - fn test_date64() { - let duration = PrimitiveArray::from([ - Some(10i64), // 10 milliseconds - Some(100i64), // 100 milliseconds - None, - Some(1_000i64), // 1000 milliseconds - ]) - .to(DataType::Duration(TimeUnit::Millisecond)); - - let date_64 = - PrimitiveArray::from([Some(100_000i64), Some(100_000i64), None, Some(100_000i64)]) - .to(DataType::Date64); - - let result = add_duration(&date_64, &duration).unwrap(); - let expected = - PrimitiveArray::from([Some(100_010i64), Some(100_100i64), None, Some(101_000i64)]) - .to(DataType::Date64); - - assert_eq!(result, expected); - - let result = subtract_duration(&date_64, &duration).unwrap(); - let expected = - PrimitiveArray::from([Some(99_990i64), Some(99_900i64), None, Some(99_000i64)]) - .to(DataType::Date64); - - assert_eq!(result, expected); - } -} diff --git a/src/compute/comparison/mod.rs b/src/compute/comparison/mod.rs index 54d12991274..35e3d324f15 100644 --- a/src/compute/comparison/mod.rs +++ b/src/compute/comparison/mod.rs @@ -375,73 +375,3 @@ pub fn can_compare(data_type: &DataType) -> bool { | DataType::LargeBinary ) } - -#[cfg(test)] -mod tests { - use crate::scalar::new_scalar; - - use super::*; - - #[test] - fn consistency() { - use crate::array::new_null_array; - use crate::datatypes::DataType::*; - use crate::datatypes::TimeUnit; - - let datatypes = vec![ - Null, - Boolean, - UInt8, - UInt16, - UInt32, - UInt64, - Int8, - Int16, - Int32, - Int64, - Float32, - Float64, - Timestamp(TimeUnit::Second, None), - Timestamp(TimeUnit::Millisecond, None), - Timestamp(TimeUnit::Microsecond, None), - Timestamp(TimeUnit::Nanosecond, None), - Time64(TimeUnit::Microsecond), - Time64(TimeUnit::Nanosecond), - Date32, - Time32(TimeUnit::Second), - Time32(TimeUnit::Millisecond), - Date64, - Utf8, - LargeUtf8, - Binary, - LargeBinary, - Duration(TimeUnit::Second), - Duration(TimeUnit::Millisecond), - Duration(TimeUnit::Microsecond), - Duration(TimeUnit::Nanosecond), - ]; - - // array <> array - datatypes.clone().into_iter().for_each(|d1| { - let array = new_null_array(d1.clone(), 10); - let op = Operator::Eq; - if can_compare(&d1) { - assert!(compare(array.as_ref(), array.as_ref(), op).is_ok()); - } else { - assert!(compare(array.as_ref(), array.as_ref(), op).is_err()); - } - }); - - // array <> scalar - datatypes.into_iter().for_each(|d1| { - let array = new_null_array(d1.clone(), 10); - let scalar = new_scalar(array.as_ref(), 0); - let op = Operator::Eq; - if can_compare(&d1) { - assert!(compare_scalar(array.as_ref(), scalar.as_ref(), op).is_ok()); - } else { - assert!(compare_scalar(array.as_ref(), scalar.as_ref(), op).is_err()); - } - }); - } -} diff --git a/src/compute/contains.rs b/src/compute/contains.rs index 402cb03ba62..8afec9e2a36 100644 --- a/src/compute/contains.rs +++ b/src/compute/contains.rs @@ -212,67 +212,3 @@ pub fn contains(list: &dyn Array, values: &dyn Array) -> Result { ))), } } - -// disable wrapping inside literal vectors used for test data and assertions -#[rustfmt::skip::macros(vec)] -#[cfg(test)] -mod tests { - use super::*; - - use crate::array::*; - - // Expected behaviour: - // contains([1, 2, null], 1) = true - // contains([1, 2, null], 3) = false - // contains([1, 2, null], null) = null - // contains(null, 1) = null - #[test] - fn test_contains() { - let data = vec![ - Some(vec![Some(1), Some(2), None]), - Some(vec![Some(1), Some(2), None]), - Some(vec![Some(1), Some(2), None]), - None, - ]; - let values = Int32Array::from(&[Some(1), Some(3), None, Some(1)]); - let expected = BooleanArray::from(vec![ - Some(true), - Some(false), - None, - None - ]); - - let mut a = MutableListArray::>::new(); - a.try_extend(data).unwrap(); - let a: ListArray = a.into(); - - let result = contains(&a, &values).unwrap(); - - assert_eq!(result, expected); - } - - #[test] - fn test_contains_binary() { - let data = vec![ - Some(vec![Some(b"a"), Some(b"b"), None]), - Some(vec![Some(b"a"), Some(b"b"), None]), - Some(vec![Some(b"a"), Some(b"b"), None]), - None, - ]; - let values = BinaryArray::::from(&[Some(b"a"), Some(b"c"), None, Some(b"a")]); - let expected = BooleanArray::from(vec![ - Some(true), - Some(false), - None, - None - ]); - - let mut a = MutableListArray::>::new(); - a.try_extend(data).unwrap(); - let a: ListArray = a.into(); - - let result = contains(&a, &values).unwrap(); - - assert_eq!(result, expected); - } -} diff --git a/src/compute/sort/lex_sort.rs b/src/compute/sort/lex_sort.rs index 4e8797eba4f..7fe0c2bc864 100644 --- a/src/compute/sort/lex_sort.rs +++ b/src/compute/sort/lex_sort.rs @@ -189,218 +189,3 @@ pub fn lexsort_to_indices( None, )) } - -#[cfg(test)] -mod tests { - use crate::array::*; - - use super::*; - - fn test_lex_sort_arrays(input: Vec, expected: Vec>) { - let sorted = lexsort::(&input, None).unwrap(); - assert_eq!(sorted, expected); - - let sorted = lexsort::(&input, Some(2)).unwrap(); - let expected = expected - .into_iter() - .map(|x| x.slice(0, 2)) - .collect::>(); - assert_eq!(sorted, expected); - } - - #[test] - fn test_lex_sort_mixed_types() { - let c1 = Int64Array::from(&[Some(0), Some(2), Some(-1), Some(0)]); - let c2 = UInt32Array::from(&[Some(101), Some(8), Some(7), Some(102)]); - let c3 = Int64Array::from(&[Some(-1), Some(-2), Some(-3), Some(-4)]); - - let input = vec![ - SortColumn { - values: &c1, - options: None, - }, - SortColumn { - values: &c2, - options: None, - }, - SortColumn { - values: &c3, - options: None, - }, - ]; - let c1 = Int64Array::from(&[Some(-1), Some(0), Some(0), Some(2)]); - let c2 = UInt32Array::from(&[Some(7), Some(101), Some(102), Some(8)]); - let c3 = Int64Array::from(&[Some(-3), Some(-1), Some(-4), Some(-2)]); - let expected = vec![Box::new(c1) as Box, Box::new(c2), Box::new(c3)]; - test_lex_sort_arrays(input, expected); - } - - #[test] - fn test_lex_sort_mixed_types2() { - // test mix of string and in64 with option - let c1 = Int64Array::from(&[Some(0), Some(2), Some(-1), Some(0)]); - let c2 = Utf8Array::::from(&vec![Some("foo"), Some("9"), Some("7"), Some("bar")]); - let input = vec![ - SortColumn { - values: &c1, - options: Some(SortOptions { - descending: true, - nulls_first: true, - }), - }, - SortColumn { - values: &c2, - options: Some(SortOptions { - descending: true, - nulls_first: true, - }), - }, - ]; - let expected = vec![ - Box::new(Int64Array::from(&[Some(2), Some(0), Some(0), Some(-1)])) as Box, - Box::new(Utf8Array::::from(&vec![ - Some("9"), - Some("foo"), - Some("bar"), - Some("7"), - ])) as Box, - ]; - test_lex_sort_arrays(input, expected); - } - - /* - // test sort with nulls first - let input = vec![ - SortColumn { - values: Arc::new(PrimitiveArray::::from(vec![ - None, - Some(-1), - Some(2), - None, - ])) as ArrayRef, - options: Some(SortOptions { - descending: true, - nulls_first: true, - }), - }, - SortColumn { - values: Arc::new(StringArray::from(vec![ - Some("foo"), - Some("world"), - Some("hello"), - None, - ])) as ArrayRef, - options: Some(SortOptions { - descending: true, - nulls_first: true, - }), - }, - ]; - let expected = vec![ - Arc::new(PrimitiveArray::::from(vec![ - None, - None, - Some(2), - Some(-1), - ])) as ArrayRef, - Arc::new(StringArray::from(vec![ - None, - Some("foo"), - Some("hello"), - Some("world"), - ])) as ArrayRef, - ]; - test_lex_sort_arrays(input, expected); - - // test sort with nulls last - let input = vec![ - SortColumn { - values: Arc::new(PrimitiveArray::::from(vec![ - None, - Some(-1), - Some(2), - None, - ])) as ArrayRef, - options: Some(SortOptions { - descending: true, - nulls_first: false, - }), - }, - SortColumn { - values: Arc::new(StringArray::from(vec![ - Some("foo"), - Some("world"), - Some("hello"), - None, - ])) as ArrayRef, - options: Some(SortOptions { - descending: true, - nulls_first: false, - }), - }, - ]; - let expected = vec![ - Arc::new(PrimitiveArray::::from(vec![ - Some(2), - Some(-1), - None, - None, - ])) as ArrayRef, - Arc::new(StringArray::from(vec![ - Some("hello"), - Some("world"), - Some("foo"), - None, - ])) as ArrayRef, - ]; - test_lex_sort_arrays(input, expected); - - // test sort with opposite options - let input = vec![ - SortColumn { - values: Arc::new(PrimitiveArray::::from(vec![ - None, - Some(-1), - Some(2), - Some(-1), - None, - ])) as ArrayRef, - options: Some(SortOptions { - descending: false, - nulls_first: false, - }), - }, - SortColumn { - values: Arc::new(StringArray::from(vec![ - Some("foo"), - Some("bar"), - Some("world"), - Some("hello"), - None, - ])) as ArrayRef, - options: Some(SortOptions { - descending: true, - nulls_first: true, - }), - }, - ]; - let expected = vec![ - Arc::new(PrimitiveArray::::from(vec![ - Some(-1), - Some(-1), - Some(2), - None, - None, - ])) as ArrayRef, - Arc::new(StringArray::from(vec![ - Some("hello"), - Some("bar"), - Some("world"), - None, - Some("foo"), - ])) as ArrayRef, - ]; - test_lex_sort_arrays(input, expected); - } - */ -} diff --git a/src/compute/take/mod.rs b/src/compute/take/mod.rs index 65ce13cf815..46075ef7aa0 100644 --- a/src/compute/take/mod.rs +++ b/src/compute/take/mod.rs @@ -144,183 +144,3 @@ pub fn can_take(data_type: &DataType) -> bool { _ => false, } } - -#[cfg(test)] -mod tests { - use std::sync::Arc; - - use crate::datatypes::{Field, IntervalUnit}; - use crate::{array::*, bitmap::MutableBitmap, types::NativeType}; - - use super::*; - - fn test_take_primitive( - data: &[Option], - indices: &Int32Array, - expected_data: &[Option], - data_type: DataType, - ) -> Result<()> - where - T: NativeType, - { - let output = PrimitiveArray::::from(data).to(data_type.clone()); - let expected = PrimitiveArray::::from(expected_data).to(data_type); - let output = take(&output, indices)?; - assert_eq!(expected, output.as_ref()); - Ok(()) - } - - #[test] - fn test_take_primitive_non_null_indices() { - let indices = Int32Array::from_slice(&[0, 5, 3, 1, 4, 2]); - test_take_primitive::( - &[None, Some(2), Some(4), Some(6), Some(8), None], - &indices, - &[None, None, Some(6), Some(2), Some(8), Some(4)], - DataType::Int8, - ) - .unwrap(); - - test_take_primitive::( - &[Some(0), Some(2), Some(4), Some(6), Some(8), Some(10)], - &indices, - &[Some(0), Some(10), Some(6), Some(2), Some(8), Some(4)], - DataType::Int8, - ) - .unwrap(); - } - - #[test] - fn test_take_primitive_null_values() { - let indices = Int32Array::from(&[Some(0), None, Some(3), Some(1), Some(4), Some(2)]); - test_take_primitive::( - &[Some(0), Some(2), Some(4), Some(6), Some(8), Some(10)], - &indices, - &[Some(0), None, Some(6), Some(2), Some(8), Some(4)], - DataType::Int8, - ) - .unwrap(); - - test_take_primitive::( - &[None, Some(2), Some(4), Some(6), Some(8), Some(10)], - &indices, - &[None, None, Some(6), Some(2), Some(8), Some(4)], - DataType::Int8, - ) - .unwrap(); - } - - fn create_test_struct() -> StructArray { - let boolean = BooleanArray::from_slice(&[true, false, false, true]); - let int = Int32Array::from_slice(&[42, 28, 19, 31]); - let validity = vec![true, true, false, true] - .into_iter() - .collect::() - .into(); - let fields = vec![ - Field::new("a", DataType::Boolean, true), - Field::new("b", DataType::Int32, true), - ]; - StructArray::from_data( - DataType::Struct(fields), - vec![ - Arc::new(boolean) as Arc, - Arc::new(int) as Arc, - ], - validity, - ) - } - - #[test] - fn test_struct_with_nulls() { - let array = create_test_struct(); - - let indices = Int32Array::from(&[None, Some(3), Some(1), None, Some(0)]); - - let output = take(&array, &indices).unwrap(); - - let boolean = BooleanArray::from(&[None, Some(true), Some(false), None, Some(true)]); - let int = Int32Array::from(&[None, Some(31), Some(28), None, Some(42)]); - let validity = vec![false, true, true, false, true] - .into_iter() - .collect::() - .into(); - let expected = StructArray::from_data( - array.data_type().clone(), - vec![ - Arc::new(boolean) as Arc, - Arc::new(int) as Arc, - ], - validity, - ); - assert_eq!(expected, output.as_ref()); - } - - #[test] - fn consistency() { - use crate::array::new_null_array; - use crate::datatypes::DataType::*; - use crate::datatypes::TimeUnit; - - let datatypes = vec![ - Null, - Boolean, - UInt8, - UInt16, - UInt32, - UInt64, - Int8, - Int16, - Int32, - Int64, - Float32, - Float64, - Timestamp(TimeUnit::Second, None), - Timestamp(TimeUnit::Millisecond, None), - Timestamp(TimeUnit::Microsecond, None), - Timestamp(TimeUnit::Nanosecond, None), - Time64(TimeUnit::Microsecond), - Time64(TimeUnit::Nanosecond), - Interval(IntervalUnit::DayTime), - Interval(IntervalUnit::YearMonth), - Date32, - Time32(TimeUnit::Second), - Time32(TimeUnit::Millisecond), - Date64, - Utf8, - LargeUtf8, - Binary, - LargeBinary, - Duration(TimeUnit::Second), - Duration(TimeUnit::Millisecond), - Duration(TimeUnit::Microsecond), - Duration(TimeUnit::Nanosecond), - ]; - - datatypes.into_iter().for_each(|d1| { - let array = new_null_array(d1.clone(), 10); - let indices = Int32Array::from(&[Some(1), Some(2), None, Some(3)]); - if can_take(&d1) { - assert!(take(array.as_ref(), &indices).is_ok()); - } else { - assert!(take(array.as_ref(), &indices).is_err()); - } - }); - } - - #[test] - fn empty() { - let indices = Int32Array::from_slice(&[]); - let values = BooleanArray::from(vec![Some(true), Some(false)]); - let a = take(&values, &indices).unwrap(); - assert_eq!(a.len(), 0) - } - - #[test] - fn unsigned_take() { - let indices = UInt32Array::from_slice(&[]); - let values = BooleanArray::from(vec![Some(true), Some(false)]); - let a = take(&values, &indices).unwrap(); - assert_eq!(a.len(), 0) - } -} diff --git a/tests/it/compute/aggregate/memory.rs b/tests/it/compute/aggregate/memory.rs new file mode 100644 index 00000000000..d38967571cc --- /dev/null +++ b/tests/it/compute/aggregate/memory.rs @@ -0,0 +1,19 @@ +use arrow2::{array::*, compute::aggregate::estimated_bytes_size}; + +#[test] +fn primitive() { + let a = Int32Array::from_slice(&[1, 2, 3, 4, 5]); + assert_eq!(5 * std::mem::size_of::(), estimated_bytes_size(&a)); +} + +#[test] +fn boolean() { + let a = BooleanArray::from_slice(&[true]); + assert_eq!(1, estimated_bytes_size(&a)); +} + +#[test] +fn utf8() { + let a = Utf8Array::::from_slice(&["aaa"]); + assert_eq!(3 + 2 * std::mem::size_of::(), estimated_bytes_size(&a)); +} diff --git a/tests/it/compute/aggregate/min_max.rs b/tests/it/compute/aggregate/min_max.rs new file mode 100644 index 00000000000..abeaf304596 --- /dev/null +++ b/tests/it/compute/aggregate/min_max.rs @@ -0,0 +1,188 @@ +use arrow2::compute::aggregate::{ + max_binary, max_boolean, max_primitive, max_string, min_binary, min_boolean, min_primitive, + min_string, +}; +use arrow2::{array::*, datatypes::DataType}; + +#[test] +fn test_primitive_array_min_max() { + let a = Int32Array::from_slice(&[5, 6, 7, 8, 9]); + assert_eq!(5, min_primitive(&a).unwrap()); + assert_eq!(9, max_primitive(&a).unwrap()); +} + +#[test] +fn test_primitive_array_min_max_with_nulls() { + let a = Int32Array::from(&[Some(5), None, None, Some(8), Some(9)]); + assert_eq!(5, min_primitive(&a).unwrap()); + assert_eq!(9, max_primitive(&a).unwrap()); +} + +#[test] +fn test_primitive_min_max_1() { + let a = Int32Array::from(&[None, None, Some(5), Some(2)]); + assert_eq!(Some(2), min_primitive(&a)); + assert_eq!(Some(5), max_primitive(&a)); +} + +#[test] +fn min_max_f32() { + let a = Float32Array::from(&[None, None, Some(5.0), Some(2.0)]); + assert_eq!(Some(2.0), min_primitive(&a)); + assert_eq!(Some(5.0), max_primitive(&a)); +} + +#[test] +fn min_max_f64() { + let a = Float64Array::from(&[None, None, Some(5.0), Some(2.0)]); + assert_eq!(Some(2.0), min_primitive(&a)); + assert_eq!(Some(5.0), max_primitive(&a)); +} + +#[test] +fn min_max_f64_large() { + // in simd, f64 has 8 lanes, thus > 8 covers the branch with lanes + let a = Float64Array::from(&[ + None, + None, + Some(8.0), + Some(2.0), + None, + None, + Some(5.0), + Some(2.0), + ]); + assert_eq!(Some(2.0), min_primitive(&a)); + assert_eq!(Some(8.0), max_primitive(&a)); +} + +#[test] +fn min_max_f64_nan_only() { + let a = Float64Array::from(&[None, Some(f64::NAN)]); + assert!(min_primitive(&a).unwrap().is_nan()); + assert!(max_primitive(&a).unwrap().is_nan()); +} + +#[test] +fn min_max_f64_nan() { + let a = Float64Array::from(&[None, Some(1.0), Some(f64::NAN)]); + assert_eq!(Some(1.0), min_primitive(&a)); + assert_eq!(Some(1.0), max_primitive(&a)); +} + +#[test] +fn min_max_f64_edge_cases() { + let a: Float64Array = (0..100).map(|_| Some(f64::NEG_INFINITY)).collect(); + assert_eq!(Some(f64::NEG_INFINITY), min_primitive(&a)); + assert_eq!(Some(f64::NEG_INFINITY), max_primitive(&a)); + + let a: Float64Array = (0..100).map(|_| Some(f64::MIN)).collect(); + assert_eq!(Some(f64::MIN), min_primitive(&a)); + assert_eq!(Some(f64::MIN), max_primitive(&a)); + + let a: Float64Array = (0..100).map(|_| Some(f64::MAX)).collect(); + assert_eq!(Some(f64::MAX), min_primitive(&a)); + assert_eq!(Some(f64::MAX), max_primitive(&a)); + + let a: Float64Array = (0..100).map(|_| Some(f64::INFINITY)).collect(); + assert_eq!(Some(f64::INFINITY), min_primitive(&a)); + assert_eq!(Some(f64::INFINITY), max_primitive(&a)); +} + +// todo: convert me +#[test] +fn test_string_min_max_with_nulls() { + let a = Utf8Array::::from(&[Some("b"), None, None, Some("a"), Some("c")]); + assert_eq!("a", min_string(&a).unwrap()); + assert_eq!("c", max_string(&a).unwrap()); +} + +#[test] +fn test_string_min_max_all_nulls() { + let a = Utf8Array::::from(&[None::<&str>, None]); + assert_eq!(None, min_string(&a)); + assert_eq!(None, max_string(&a)); +} + +#[test] +fn test_string_min_max_1() { + let a = Utf8Array::::from(&[None, None, Some("b"), Some("a")]); + assert_eq!(Some("a"), min_string(&a)); + assert_eq!(Some("b"), max_string(&a)); +} + +#[test] +fn test_boolean_min_max_empty() { + let a = BooleanArray::new_empty(DataType::Boolean); + assert_eq!(None, min_boolean(&a)); + assert_eq!(None, max_boolean(&a)); +} + +#[test] +fn test_boolean_min_max_all_null() { + let a = BooleanArray::from(&[None, None]); + assert_eq!(None, min_boolean(&a)); + assert_eq!(None, max_boolean(&a)); +} + +#[test] +fn test_boolean_min_max_no_null() { + let a = BooleanArray::from(&[Some(true), Some(false), Some(true)]); + assert_eq!(Some(false), min_boolean(&a)); + assert_eq!(Some(true), max_boolean(&a)); +} + +#[test] +fn test_boolean_min_max() { + let a = BooleanArray::from(&[Some(true), Some(true), None, Some(false), None]); + assert_eq!(Some(false), min_boolean(&a)); + assert_eq!(Some(true), max_boolean(&a)); + + let a = BooleanArray::from(&[None, Some(true), None, Some(false), None]); + assert_eq!(Some(false), min_boolean(&a)); + assert_eq!(Some(true), max_boolean(&a)); + + let a = BooleanArray::from(&[Some(false), Some(true), None, Some(false), None]); + assert_eq!(Some(false), min_boolean(&a)); + assert_eq!(Some(true), max_boolean(&a)); +} + +#[test] +fn test_boolean_min_max_smaller() { + let a = BooleanArray::from(&[Some(false)]); + assert_eq!(Some(false), min_boolean(&a)); + assert_eq!(Some(false), max_boolean(&a)); + + let a = BooleanArray::from(&[None, Some(false)]); + assert_eq!(Some(false), min_boolean(&a)); + assert_eq!(Some(false), max_boolean(&a)); + + let a = BooleanArray::from(&[None, Some(true)]); + assert_eq!(Some(true), min_boolean(&a)); + assert_eq!(Some(true), max_boolean(&a)); + + let a = BooleanArray::from(&[Some(true)]); + assert_eq!(Some(true), min_boolean(&a)); + assert_eq!(Some(true), max_boolean(&a)); +} + +#[test] +fn test_binary_min_max_with_nulls() { + let a = BinaryArray::::from(&[Some(b"b"), None, None, Some(b"a"), Some(b"c")]); + assert_eq!("a".as_bytes(), min_binary(&a).unwrap()); + assert_eq!("c".as_bytes(), max_binary(&a).unwrap()); +} + +#[test] +fn test_binary_min_max_all_nulls() { + let a = BinaryArray::::from(&[None::<&[u8]>, None]); + assert_eq!(None, min_binary(&a)); + assert_eq!(None, max_binary(&a)); +} + +#[test] +fn test_binary_min_max_1() { + let a = BinaryArray::::from(&[None, None, Some(b"b"), Some(b"a")]); + assert_eq!(Some("a".as_bytes()), min_binary(&a)); + assert_eq!(Some("b".as_bytes()), max_binary(&a)); +} diff --git a/tests/it/compute/aggregate/mod.rs b/tests/it/compute/aggregate/mod.rs new file mode 100644 index 00000000000..c907e2e563f --- /dev/null +++ b/tests/it/compute/aggregate/mod.rs @@ -0,0 +1,3 @@ +mod memory; +mod min_max; +mod sum; diff --git a/tests/it/compute/aggregate/sum.rs b/tests/it/compute/aggregate/sum.rs new file mode 100644 index 00000000000..1ad77afc086 --- /dev/null +++ b/tests/it/compute/aggregate/sum.rs @@ -0,0 +1,54 @@ +use arrow2::array::*; +use arrow2::compute::aggregate::{sum, sum_primitive}; +use arrow2::compute::arithmetics; +use arrow2::datatypes::DataType; +use arrow2::scalar::{PrimitiveScalar, Scalar}; + +#[test] +fn test_primitive_array_sum() { + let a = Int32Array::from_slice(&[1, 2, 3, 4, 5]); + assert_eq!( + &PrimitiveScalar::::from(Some(15)) as &dyn Scalar, + sum(&a).unwrap().as_ref() + ); + + let a = a.to(DataType::Date32); + assert_eq!( + &PrimitiveScalar::::from(Some(15)).to(DataType::Date32) as &dyn Scalar, + sum(&a).unwrap().as_ref() + ); +} + +#[test] +fn test_primitive_array_float_sum() { + let a = Float64Array::from_slice(&[1.1f64, 2.2, 3.3, 4.4, 5.5]); + assert!((16.5 - sum_primitive(&a).unwrap()).abs() < f64::EPSILON); +} + +#[test] +fn test_primitive_array_sum_with_nulls() { + let a = Int32Array::from(&[None, Some(2), Some(3), None, Some(5)]); + assert_eq!(10, sum_primitive(&a).unwrap()); +} + +#[test] +fn test_primitive_array_sum_all_nulls() { + let a = Int32Array::from(&[None, None, None]); + assert_eq!(None, sum_primitive(&a)); +} + +#[test] +fn test_primitive_array_sum_large_64() { + let a: Int64Array = (1..=100) + .map(|i| if i % 3 == 0 { Some(i) } else { None }) + .collect(); + let b: Int64Array = (1..=100) + .map(|i| if i % 3 == 0 { Some(0) } else { Some(i) }) + .collect(); + // create an array that actually has non-zero values at the invalid indices + let c = arithmetics::basic::add::add(&a, &b).unwrap(); + assert_eq!( + Some((1..=100).filter(|i| i % 3 == 0).sum()), + sum_primitive(&c) + ); +} diff --git a/tests/it/compute/arithmetics/basic/add.rs b/tests/it/compute/arithmetics/basic/add.rs new file mode 100644 index 00000000000..aa563cbbe47 --- /dev/null +++ b/tests/it/compute/arithmetics/basic/add.rs @@ -0,0 +1,162 @@ +use arrow2::array::*; +use arrow2::bitmap::Bitmap; +use arrow2::compute::arithmetics::basic::add::*; +use arrow2::compute::arithmetics::{ + ArrayAdd, ArrayCheckedAdd, ArrayOverflowingAdd, ArraySaturatingAdd, +}; + +#[test] +fn test_add_mismatched_length() { + let a = Int32Array::from_slice(&[5, 6]); + let b = Int32Array::from_slice(&[5]); + add(&a, &b) + .err() + .expect("should have failed due to different lengths"); +} + +#[test] +fn test_add() { + let a = Int32Array::from(&[None, Some(6), None, Some(6)]); + let b = Int32Array::from(&[Some(5), None, None, Some(6)]); + let result = add(&a, &b).unwrap(); + let expected = Int32Array::from(&[None, None, None, Some(12)]); + assert_eq!(result, expected); + + // Trait testing + let result = a.add(&b).unwrap(); + assert_eq!(result, expected); +} + +#[test] +#[should_panic] +fn test_add_panic() { + let a = Int8Array::from(&[Some(100i8)]); + let b = Int8Array::from(&[Some(100i8)]); + let _ = add(&a, &b); +} + +#[test] +fn test_add_checked() { + let a = Int32Array::from(&[None, Some(6), None, Some(6)]); + let b = Int32Array::from(&[Some(5), None, None, Some(6)]); + let result = checked_add(&a, &b).unwrap(); + let expected = Int32Array::from(&[None, None, None, Some(12)]); + assert_eq!(result, expected); + + let a = Int8Array::from(&[Some(100i8), Some(100i8), Some(100i8)]); + let b = Int8Array::from(&[Some(0i8), Some(100i8), Some(0i8)]); + let result = checked_add(&a, &b).unwrap(); + let expected = Int8Array::from(&[Some(100i8), None, Some(100i8)]); + assert_eq!(result, expected); + + // Trait testing + let result = a.checked_add(&b).unwrap(); + assert_eq!(result, expected); +} + +#[test] +fn test_add_saturating() { + let a = Int32Array::from(&[None, Some(6), None, Some(6)]); + let b = Int32Array::from(&[Some(5), None, None, Some(6)]); + let result = saturating_add(&a, &b).unwrap(); + let expected = Int32Array::from(&[None, None, None, Some(12)]); + assert_eq!(result, expected); + + let a = Int8Array::from(&[Some(100i8)]); + let b = Int8Array::from(&[Some(100i8)]); + let result = saturating_add(&a, &b).unwrap(); + let expected = Int8Array::from(&[Some(127)]); + assert_eq!(result, expected); + + // Trait testing + let result = a.saturating_add(&b).unwrap(); + assert_eq!(result, expected); +} + +#[test] +fn test_add_overflowing() { + let a = Int32Array::from(&[None, Some(6), None, Some(6)]); + let b = Int32Array::from(&[Some(5), None, None, Some(6)]); + let (result, overflow) = overflowing_add(&a, &b).unwrap(); + let expected = Int32Array::from(&[None, None, None, Some(12)]); + assert_eq!(result, expected); + assert_eq!(overflow, Bitmap::from([false, false, false, false])); + + let a = Int8Array::from(&[Some(1i8), Some(100i8)]); + let b = Int8Array::from(&[Some(1i8), Some(100i8)]); + let (result, overflow) = overflowing_add(&a, &b).unwrap(); + let expected = Int8Array::from(&[Some(2i8), Some(-56i8)]); + assert_eq!(result, expected); + assert_eq!(overflow, Bitmap::from([false, true])); + + // Trait testing + let (result, overflow) = a.overflowing_add(&b).unwrap(); + assert_eq!(result, expected); + assert_eq!(overflow, Bitmap::from([false, true])); +} + +#[test] +fn test_add_scalar() { + let a = Int32Array::from(&[None, Some(6), None, Some(6)]); + let result = add_scalar(&a, &1i32); + let expected = Int32Array::from(&[None, Some(7), None, Some(7)]); + assert_eq!(result, expected); + + // Trait testing + let result = a.add(&1i32).unwrap(); + assert_eq!(result, expected); +} + +#[test] +fn test_add_scalar_checked() { + let a = Int32Array::from(&[None, Some(6), None, Some(6)]); + let result = checked_add_scalar(&a, &1i32); + let expected = Int32Array::from(&[None, Some(7), None, Some(7)]); + assert_eq!(result, expected); + + let a = Int8Array::from(&[None, Some(100), None, Some(100)]); + let result = checked_add_scalar(&a, &100i8); + let expected = Int8Array::from(&[None, None, None, None]); + assert_eq!(result, expected); + + // Trait testing + let result = a.checked_add(&100i8).unwrap(); + assert_eq!(result, expected); +} + +#[test] +fn test_add_scalar_saturating() { + let a = Int32Array::from(&[None, Some(6), None, Some(6)]); + let result = saturating_add_scalar(&a, &1i32); + let expected = Int32Array::from(&[None, Some(7), None, Some(7)]); + assert_eq!(result, expected); + + let a = Int8Array::from(&[Some(100i8)]); + let result = saturating_add_scalar(&a, &100i8); + let expected = Int8Array::from(&[Some(127)]); + assert_eq!(result, expected); + + // Trait testing + let result = a.saturating_add(&100i8).unwrap(); + assert_eq!(result, expected); +} + +#[test] +fn test_add_scalar_overflowing() { + let a = Int32Array::from(&vec![None, Some(6), None, Some(6)]); + let (result, overflow) = overflowing_add_scalar(&a, &1i32); + let expected = Int32Array::from(&vec![None, Some(7), None, Some(7)]); + assert_eq!(result, expected); + assert_eq!(overflow, Bitmap::from([false, false, false, false])); + + let a = Int8Array::from(&vec![Some(1i8), Some(100i8)]); + let (result, overflow) = overflowing_add_scalar(&a, &100i8); + let expected = Int8Array::from(&vec![Some(101i8), Some(-56i8)]); + assert_eq!(result, expected); + assert_eq!(overflow, Bitmap::from([false, true])); + + // Trait testing + let (result, overflow) = a.overflowing_add(&100i8).unwrap(); + assert_eq!(result, expected); + assert_eq!(overflow, Bitmap::from([false, true])); +} diff --git a/tests/it/compute/arithmetics/basic/div.rs b/tests/it/compute/arithmetics/basic/div.rs new file mode 100644 index 00000000000..98500dfbc05 --- /dev/null +++ b/tests/it/compute/arithmetics/basic/div.rs @@ -0,0 +1,102 @@ +use arrow2::array::*; +use arrow2::compute::arithmetics::basic::div::*; +use arrow2::compute::arithmetics::{ArrayCheckedDiv, ArrayDiv}; + +#[test] +fn test_div_mismatched_length() { + let a = Int32Array::from_slice(&[5, 6]); + let b = Int32Array::from_slice(&[5]); + div(&a, &b) + .err() + .expect("should have failed due to different lengths"); +} + +#[test] +fn test_div() { + let a = Int32Array::from(&[Some(5), Some(6)]); + let b = Int32Array::from(&[Some(5), Some(6)]); + let result = div(&a, &b).unwrap(); + let expected = Int32Array::from(&[Some(1), Some(1)]); + assert_eq!(result, expected); + + // Trait testing + let result = a.div(&b).unwrap(); + assert_eq!(result, expected); +} + +#[test] +#[should_panic] +fn test_div_panic() { + let a = Int8Array::from(&[Some(10i8)]); + let b = Int8Array::from(&[Some(0i8)]); + let _ = div(&a, &b); +} + +#[test] +fn test_div_checked() { + let a = Int32Array::from(&[Some(5), None, Some(3), Some(6)]); + let b = Int32Array::from(&[Some(5), Some(3), None, Some(6)]); + let result = checked_div(&a, &b).unwrap(); + let expected = Int32Array::from(&[Some(1), None, None, Some(1)]); + assert_eq!(result, expected); + + let a = Int32Array::from(&[Some(5), None, Some(3), Some(6)]); + let b = Int32Array::from(&[Some(5), Some(0), Some(0), Some(6)]); + let result = checked_div(&a, &b).unwrap(); + let expected = Int32Array::from(&[Some(1), None, None, Some(1)]); + assert_eq!(result, expected); + + // Trait testing + let result = a.checked_div(&b).unwrap(); + assert_eq!(result, expected); +} + +#[test] +fn test_div_scalar() { + let a = Int32Array::from(&[None, Some(6), None, Some(6)]); + let result = div_scalar(&a, &1i32); + let expected = Int32Array::from(&[None, Some(6), None, Some(6)]); + assert_eq!(result, expected); + + // Trait testing + let result = a.div(&1i32).unwrap(); + assert_eq!(result, expected); + + // check the strength reduced branches + let a = UInt64Array::from(&[None, Some(6), None, Some(6)]); + let result = div_scalar(&a, &1u64); + let expected = UInt64Array::from(&[None, Some(6), None, Some(6)]); + assert_eq!(result, expected); + + let a = UInt32Array::from(&[None, Some(6), None, Some(6)]); + let result = div_scalar(&a, &1u32); + let expected = UInt32Array::from(&[None, Some(6), None, Some(6)]); + assert_eq!(result, expected); + + let a = UInt16Array::from(&[None, Some(6), None, Some(6)]); + let result = div_scalar(&a, &1u16); + let expected = UInt16Array::from(&[None, Some(6), None, Some(6)]); + assert_eq!(result, expected); + + let a = UInt8Array::from(&[None, Some(6), None, Some(6)]); + let result = div_scalar(&a, &1u8); + let expected = UInt8Array::from(&[None, Some(6), None, Some(6)]); + assert_eq!(result, expected); +} + +#[test] +fn test_div_scalar_checked() { + let a = Int32Array::from(&[None, Some(6), None, Some(6)]); + let result = checked_div_scalar(&a, &1i32); + let expected = Int32Array::from(&[None, Some(6), None, Some(6)]); + assert_eq!(result, expected); + + let a = Int32Array::from(&[None, Some(6), None, Some(6)]); + let result = checked_div_scalar(&a, &0); + let expected = Int32Array::from(&[None, None, None, None]); + assert_eq!(result, expected); + + // Trait testing + let result = a.checked_div(&0).unwrap(); + assert_eq!(result, expected); +} diff --git a/tests/it/compute/arithmetics/basic/mod.rs b/tests/it/compute/arithmetics/basic/mod.rs new file mode 100644 index 00000000000..f38e93823e6 --- /dev/null +++ b/tests/it/compute/arithmetics/basic/mod.rs @@ -0,0 +1,6 @@ +mod add; +mod div; +mod mul; +mod pow; +mod rem; +mod sub; diff --git a/tests/it/compute/arithmetics/basic/mul.rs b/tests/it/compute/arithmetics/basic/mul.rs new file mode 100644 index 00000000000..fa3ba7e8e73 --- /dev/null +++ b/tests/it/compute/arithmetics/basic/mul.rs @@ -0,0 +1,162 @@ +use arrow2::array::*; +use arrow2::bitmap::Bitmap; +use arrow2::compute::arithmetics::basic::mul::*; +use arrow2::compute::arithmetics::{ + ArrayCheckedMul, ArrayMul, ArrayOverflowingMul, ArraySaturatingMul, +}; + +#[test] +fn test_mul_mismatched_length() { + let a = Int32Array::from_slice(&[5, 6]); + let b = Int32Array::from_slice(&[5]); + mul(&a, &b) + .err() + .expect("should have failed due to different lengths"); +} + +#[test] +fn test_mul() { + let a = Int32Array::from(&[None, Some(6), None, Some(6)]); + let b = Int32Array::from(&[Some(5), None, None, Some(6)]); + let result = mul(&a, &b).unwrap(); + let expected = Int32Array::from(&[None, None, None, Some(36)]); + assert_eq!(result, expected); + + // Trait testing + let result = a.mul(&b).unwrap(); + assert_eq!(result, expected); +} + +#[test] +#[should_panic] +fn test_mul_panic() { + let a = Int8Array::from(&[Some(-100i8)]); + let b = Int8Array::from(&[Some(100i8)]); + let _ = mul(&a, &b); +} + +#[test] +fn test_mul_checked() { + let a = Int32Array::from(&[None, Some(6), None, Some(6)]); + let b = Int32Array::from(&[Some(5), None, None, Some(6)]); + let result = checked_mul(&a, &b).unwrap(); + let expected = Int32Array::from(&[None, None, None, Some(36)]); + assert_eq!(result, expected); + + let a = Int8Array::from(&[Some(100i8), Some(100i8), Some(100i8)]); + let b = Int8Array::from(&[Some(1i8), Some(100i8), Some(1i8)]); + let result = checked_mul(&a, &b).unwrap(); + let expected = Int8Array::from(&[Some(100i8), None, Some(100i8)]); + assert_eq!(result, expected); + + // Trait testing + let result = a.checked_mul(&b).unwrap(); + assert_eq!(result, expected); +} + +#[test] +fn test_mul_saturating() { + let a = Int32Array::from(&[None, Some(6), None, Some(6)]); + let b = Int32Array::from(&[Some(5), None, None, Some(6)]); + let result = saturating_mul(&a, &b).unwrap(); + let expected = Int32Array::from(&[None, None, None, Some(36)]); + assert_eq!(result, expected); + + let a = Int8Array::from(&[Some(-100i8)]); + let b = Int8Array::from(&[Some(100i8)]); + let result = saturating_mul(&a, &b).unwrap(); + let expected = Int8Array::from(&[Some(-128)]); + assert_eq!(result, expected); + + // Trait testing + let result = a.saturating_mul(&b).unwrap(); + assert_eq!(result, expected); +} + +#[test] +fn test_mul_overflowing() { + let a = Int32Array::from(&[None, Some(6), None, Some(6)]); + let b = Int32Array::from(&[Some(5), None, None, Some(6)]); + let (result, overflow) = overflowing_mul(&a, &b).unwrap(); + let expected = Int32Array::from(&[None, None, None, Some(36)]); + assert_eq!(result, expected); + assert_eq!(overflow, Bitmap::from([false, false, false, false])); + + let a = Int8Array::from(&[Some(1i8), Some(-100i8)]); + let b = Int8Array::from(&[Some(1i8), Some(100i8)]); + let (result, overflow) = overflowing_mul(&a, &b).unwrap(); + let expected = Int8Array::from(&[Some(1i8), Some(-16i8)]); + assert_eq!(result, expected); + assert_eq!(overflow, Bitmap::from([false, true])); + + // Trait testing + let (result, overflow) = a.overflowing_mul(&b).unwrap(); + assert_eq!(result, expected); + assert_eq!(overflow, Bitmap::from([false, true])); +} + +#[test] +fn test_mul_scalar() { + let a = Int32Array::from(&[None, Some(6), None, Some(6)]); + let result = mul_scalar(&a, &1i32); + let expected = Int32Array::from(&[None, Some(6), None, Some(6)]); + assert_eq!(result, expected); + + // Trait testing + let result = a.mul(&1i32).unwrap(); + assert_eq!(result, expected); +} + +#[test] +fn test_mul_scalar_checked() { + let a = Int32Array::from(&[None, Some(6), None, Some(6)]); + let result = checked_mul_scalar(&a, &1i32); + let expected = Int32Array::from(&[None, Some(6), None, Some(6)]); + assert_eq!(result, expected); + + let a = Int8Array::from(&[None, Some(100), None, Some(100)]); + let result = checked_mul_scalar(&a, &100i8); + let expected = Int8Array::from(&[None, None, None, None]); + assert_eq!(result, expected); + + // Trait testing + let result = a.checked_mul(&100i8).unwrap(); + assert_eq!(result, expected); +} + +#[test] +fn test_mul_scalar_saturating() { + let a = Int32Array::from(&[None, Some(6), None, Some(6)]); + let result = saturating_mul_scalar(&a, &1i32); + let expected = Int32Array::from(&[None, Some(6), None, Some(6)]); + assert_eq!(result, expected); + + let a = Int8Array::from(&[Some(-100i8)]); + let result = saturating_mul_scalar(&a, &100i8); + let expected = Int8Array::from(&[Some(-128)]); + assert_eq!(result, expected); + + // Trait testing + let result = a.saturating_mul(&100i8).unwrap(); + assert_eq!(result, expected); +} + +#[test] +fn test_mul_scalar_overflowing() { + let a = Int32Array::from(&[None, Some(6), None, Some(6)]); + let (result, overflow) = overflowing_mul_scalar(&a, &1i32); + let expected = Int32Array::from(&[None, Some(6), None, Some(6)]); + assert_eq!(result, expected); + assert_eq!(overflow, Bitmap::from([false, false, false, false])); + + let a = Int8Array::from(&[Some(1i8), Some(-100i8)]); + let (result, overflow) = overflowing_mul_scalar(&a, &100i8); + let expected = Int8Array::from(&[Some(100i8), Some(-16i8)]); + assert_eq!(result, expected); + assert_eq!(overflow, Bitmap::from([false, true])); + + // Trait testing + let (result, overflow) = a.overflowing_mul(&100i8).unwrap(); + assert_eq!(result, expected); + assert_eq!(overflow, Bitmap::from([false, true])); +} diff --git a/tests/it/compute/arithmetics/basic/pow.rs b/tests/it/compute/arithmetics/basic/pow.rs new file mode 100644 index 00000000000..f73d0db5fee --- /dev/null +++ b/tests/it/compute/arithmetics/basic/pow.rs @@ -0,0 +1,18 @@ +use arrow2::array::*; +use arrow2::compute::arithmetics::basic::pow::*; + +#[test] +fn test_raise_power_scalar() { + let a = Float32Array::from(&[Some(2f32), None]); + let actual = powf_scalar(&a, 2.0); + let expected = Float32Array::from(&[Some(4f32), None]); + assert_eq!(expected, actual); +} + +#[test] +fn test_raise_power_scalar_checked() { + let a = Int8Array::from(&[Some(1i8), None, Some(7i8)]); + let actual = checked_powf_scalar(&a, 8usize); + let expected = Int8Array::from(&[Some(1i8), None, None]); + assert_eq!(expected, actual); +} diff --git a/tests/it/compute/arithmetics/basic/rem.rs b/tests/it/compute/arithmetics/basic/rem.rs new file mode 100644 index 00000000000..1001d9fe8c6 --- /dev/null +++ b/tests/it/compute/arithmetics/basic/rem.rs @@ -0,0 +1,102 @@ +use arrow2::array::*; +use arrow2::compute::arithmetics::basic::rem::*; +use arrow2::compute::arithmetics::{ArrayCheckedRem, ArrayRem}; + +#[test] +fn test_rem_mismatched_length() { + let a = Int32Array::from_slice(&[5, 6]); + let b = Int32Array::from_slice(&[5]); + rem(&a, &b) + .err() + .expect("should have failed due to different lengths"); +} + +#[test] +fn test_rem() { + let a = Int32Array::from(&[Some(5), Some(6)]); + let b = Int32Array::from(&[Some(4), Some(4)]); + let result = rem(&a, &b).unwrap(); + let expected = Int32Array::from(&[Some(1), Some(2)]); + assert_eq!(result, expected); + + // Trait testing + let result = a.rem(&b).unwrap(); + assert_eq!(result, expected); +} + +#[test] +#[should_panic] +fn test_rem_panic() { + let a = Int8Array::from(&[Some(10i8)]); + let b = Int8Array::from(&[Some(0i8)]); + let _ = rem(&a, &b); +} + +#[test] +fn test_rem_checked() { + let a = Int32Array::from(&[Some(5), None, Some(3), Some(6)]); + let b = Int32Array::from(&[Some(5), Some(3), None, Some(5)]); + let result = checked_rem(&a, &b).unwrap(); + let expected = Int32Array::from(&[Some(0), None, None, Some(1)]); + assert_eq!(result, expected); + + let a = Int32Array::from(&[Some(5), None, Some(3), Some(6)]); + let b = Int32Array::from(&[Some(5), Some(0), Some(0), Some(5)]); + let result = checked_rem(&a, &b).unwrap(); + let expected = Int32Array::from(&[Some(0), None, None, Some(1)]); + assert_eq!(result, expected); + + // Trait testing + let result = a.checked_rem(&b).unwrap(); + assert_eq!(result, expected); +} + +#[test] +fn test_rem_scalar() { + let a = Int32Array::from(&[None, Some(6), None, Some(5)]); + let result = rem_scalar(&a, &2i32); + let expected = Int32Array::from(&[None, Some(0), None, Some(1)]); + assert_eq!(result, expected); + + // Trait testing + let result = a.rem(&2i32).unwrap(); + assert_eq!(result, expected); + + // check the strength reduced branches + let a = UInt64Array::from(&[None, Some(6), None, Some(5)]); + let result = rem_scalar(&a, &2u64); + let expected = UInt64Array::from(&[None, Some(0), None, Some(1)]); + assert_eq!(result, expected); + + let a = UInt32Array::from(&[None, Some(6), None, Some(5)]); + let result = rem_scalar(&a, &2u32); + let expected = UInt32Array::from(&[None, Some(0), None, Some(1)]); + assert_eq!(result, expected); + + let a = UInt16Array::from(&[None, Some(6), None, Some(5)]); + let result = rem_scalar(&a, &2u16); + let expected = UInt16Array::from(&[None, Some(0), None, Some(1)]); + assert_eq!(result, expected); + + let a = UInt8Array::from(&[None, Some(6), None, Some(5)]); + let result = rem_scalar(&a, &2u8); + let expected = UInt8Array::from(&[None, Some(0), None, Some(1)]); + assert_eq!(result, expected); +} + +#[test] +fn test_rem_scalar_checked() { + let a = Int32Array::from(&[None, Some(6), None, Some(7)]); + let result = checked_rem_scalar(&a, &2i32); + let expected = Int32Array::from(&[None, Some(0), None, Some(1)]); + assert_eq!(result, expected); + + let a = Int32Array::from(&[None, Some(6), None, Some(6)]); + let result = checked_rem_scalar(&a, &0); + let expected = Int32Array::from(&[None, None, None, None]); + assert_eq!(result, expected); + + // Trait testing + let result = a.checked_rem(&0).unwrap(); + assert_eq!(result, expected); +} diff --git a/tests/it/compute/arithmetics/basic/sub.rs b/tests/it/compute/arithmetics/basic/sub.rs new file mode 100644 index 00000000000..53e15dad932 --- /dev/null +++ b/tests/it/compute/arithmetics/basic/sub.rs @@ -0,0 +1,162 @@ +use arrow2::array::*; +use arrow2::bitmap::Bitmap; +use arrow2::compute::arithmetics::basic::sub::*; +use arrow2::compute::arithmetics::{ + ArrayCheckedSub, ArrayOverflowingSub, ArraySaturatingSub, ArraySub, +}; + +#[test] +fn test_sub_mismatched_length() { + let a = Int32Array::from_slice(&[5, 6]); + let b = Int32Array::from_slice(&[5]); + sub(&a, &b) + .err() + .expect("should have failed due to different lengths"); +} + +#[test] +fn test_sub() { + let a = Int32Array::from(&[None, Some(6), None, Some(6)]); + let b = Int32Array::from(&[Some(5), None, None, Some(6)]); + let result = sub(&a, &b).unwrap(); + let expected = Int32Array::from(&[None, None, None, Some(0)]); + assert_eq!(result, expected); + + // Trait testing + let result = a.sub(&b).unwrap(); + assert_eq!(result, expected); +} + +#[test] +#[should_panic] +fn test_sub_panic() { + let a = Int8Array::from(&[Some(-100i8)]); + let b = Int8Array::from(&[Some(100i8)]); + let _ = sub(&a, &b); +} + +#[test] +fn test_sub_checked() { + let a = Int32Array::from(&[None, Some(6), None, Some(6)]); + let b = Int32Array::from(&[Some(5), None, None, Some(6)]); + let result = checked_sub(&a, &b).unwrap(); + let expected = Int32Array::from(&[None, None, None, Some(0)]); + assert_eq!(result, expected); + + let a = Int8Array::from(&[Some(100i8), Some(-100i8), Some(100i8)]); + let b = Int8Array::from(&[Some(1i8), Some(100i8), Some(0i8)]); + let result = checked_sub(&a, &b).unwrap(); + let expected = Int8Array::from(&[Some(99i8), None, Some(100i8)]); + assert_eq!(result, expected); + + // Trait testing + let result = a.checked_sub(&b).unwrap(); + assert_eq!(result, expected); +} + +#[test] +fn test_sub_saturating() { + let a = Int32Array::from(&[None, Some(6), None, Some(6)]); + let b = Int32Array::from(&[Some(5), None, None, Some(6)]); + let result = saturating_sub(&a, &b).unwrap(); + let expected = Int32Array::from(&[None, None, None, Some(0)]); + assert_eq!(result, expected); + + let a = Int8Array::from(&[Some(-100i8)]); + let b = Int8Array::from(&[Some(100i8)]); + let result = saturating_sub(&a, &b).unwrap(); + let expected = Int8Array::from(&[Some(-128)]); + assert_eq!(result, expected); + + // Trait testing + let result = a.saturating_sub(&b).unwrap(); + assert_eq!(result, expected); +} + +#[test] +fn test_sub_overflowing() { + let a = Int32Array::from(&[None, Some(6), None, Some(6)]); + let b = Int32Array::from(&[Some(5), None, None, Some(6)]); + let (result, overflow) = overflowing_sub(&a, &b).unwrap(); + let expected = Int32Array::from(&[None, None, None, Some(0)]); + assert_eq!(result, expected); + assert_eq!(overflow, Bitmap::from([false, false, false, false])); + + let a = Int8Array::from(&[Some(1i8), Some(-100i8)]); + let b = Int8Array::from(&[Some(1i8), Some(100i8)]); + let (result, overflow) = overflowing_sub(&a, &b).unwrap(); + let expected = Int8Array::from(&[Some(0i8), Some(56i8)]); + assert_eq!(result, expected); + assert_eq!(overflow, Bitmap::from([false, true])); + + // Trait testing + let (result, overflow) = a.overflowing_sub(&b).unwrap(); + assert_eq!(result, expected); + assert_eq!(overflow, Bitmap::from([false, true])); +} + +#[test] +fn test_sub_scalar() { + let a = Int32Array::from(&[None, Some(6), None, Some(6)]); + let result = sub_scalar(&a, &1i32); + let expected = Int32Array::from(&[None, Some(5), None, Some(5)]); + assert_eq!(result, expected); + + // Trait testing + let result = a.sub(&1i32).unwrap(); + assert_eq!(result, expected); +} + +#[test] +fn test_sub_scalar_checked() { + let a = Int32Array::from(&[None, Some(6), None, Some(6)]); + let result = checked_sub_scalar(&a, &1i32); + let expected = Int32Array::from(&[None, Some(5), None, Some(5)]); + assert_eq!(result, expected); + + let a = Int8Array::from(&[None, Some(-100), None, Some(-100)]); + let result = checked_sub_scalar(&a, &100i8); + let expected = Int8Array::from(&[None, None, None, None]); + assert_eq!(result, expected); + + // Trait testing + let result = a.checked_sub(&100i8).unwrap(); + assert_eq!(result, expected); +} + +#[test] +fn test_sub_scalar_saturating() { + let a = Int32Array::from(&[None, Some(6), None, Some(6)]); + let result = saturating_sub_scalar(&a, &1i32); + let expected = Int32Array::from(&[None, Some(5), None, Some(5)]); + assert_eq!(result, expected); + + let a = Int8Array::from(&[Some(-100i8)]); + let result = saturating_sub_scalar(&a, &100i8); + let expected = Int8Array::from(&[Some(-128)]); + assert_eq!(result, expected); + + // Trait testing + let result = a.saturating_sub(&100i8).unwrap(); + assert_eq!(result, expected); +} + +#[test] +fn test_sub_scalar_overflowing() { + let a = Int32Array::from(&[None, Some(6), None, Some(6)]); + let (result, overflow) = overflowing_sub_scalar(&a, &1i32); + let expected = Int32Array::from(&[None, Some(5), None, Some(5)]); + assert_eq!(result, expected); + assert_eq!(overflow, Bitmap::from([false, false, false, false])); + + let a = Int8Array::from(&[Some(1i8), Some(-100i8)]); + let (result, overflow) = overflowing_sub_scalar(&a, &100i8); + let expected = Int8Array::from(&[Some(-99i8), Some(56i8)]); + assert_eq!(result, expected); + assert_eq!(overflow, Bitmap::from([false, true])); + + // Trait testing + let (result, overflow) = a.overflowing_sub(&100i8).unwrap(); + assert_eq!(result, expected); + assert_eq!(overflow, Bitmap::from([false, true])); +} diff --git a/tests/it/compute/arithmetics/decimal/add.rs b/tests/it/compute/arithmetics/decimal/add.rs new file mode 100644 index 00000000000..7f772a5b933 --- /dev/null +++ b/tests/it/compute/arithmetics/decimal/add.rs @@ -0,0 +1,184 @@ +#![allow(clippy::zero_prefixed_literal, clippy::inconsistent_digit_grouping)] + +use arrow2::array::*; +use arrow2::compute::arithmetics::decimal::add::*; +use arrow2::compute::arithmetics::{ArrayAdd, ArrayCheckedAdd, ArraySaturatingAdd}; +use arrow2::datatypes::DataType; + +#[test] +fn test_add_normal() { + let a = PrimitiveArray::from([Some(11111i128), Some(11100i128), None, Some(22200i128)]) + .to(DataType::Decimal(5, 2)); + + let b = PrimitiveArray::from([Some(22222i128), Some(22200i128), None, Some(11100i128)]) + .to(DataType::Decimal(5, 2)); + + let result = add(&a, &b).unwrap(); + let expected = PrimitiveArray::from([Some(33333i128), Some(33300i128), None, Some(33300i128)]) + .to(DataType::Decimal(5, 2)); + + assert_eq!(result, expected); + + // Testing trait + let result = a.add(&b).unwrap(); + assert_eq!(result, expected); +} + +#[test] +fn test_add_decimal_wrong_precision() { + let a = PrimitiveArray::from([None]).to(DataType::Decimal(5, 2)); + let b = PrimitiveArray::from([None]).to(DataType::Decimal(6, 2)); + let result = add(&a, &b); + + if result.is_ok() { + panic!("Should panic for different precision"); + } +} + +#[test] +#[should_panic(expected = "Overflow in addition presented for precision 5")] +fn test_add_panic() { + let a = PrimitiveArray::from([Some(99999i128)]).to(DataType::Decimal(5, 2)); + let b = PrimitiveArray::from([Some(1i128)]).to(DataType::Decimal(5, 2)); + let _ = add(&a, &b); +} + +#[test] +fn test_add_saturating() { + let a = PrimitiveArray::from([Some(11111i128), Some(11100i128), None, Some(22200i128)]) + .to(DataType::Decimal(5, 2)); + + let b = PrimitiveArray::from([Some(22222i128), Some(22200i128), None, Some(11100i128)]) + .to(DataType::Decimal(5, 2)); + + let result = saturating_add(&a, &b).unwrap(); + let expected = PrimitiveArray::from([Some(33333i128), Some(33300i128), None, Some(33300i128)]) + .to(DataType::Decimal(5, 2)); + + assert_eq!(result, expected); + + // Testing trait + let result = a.saturating_add(&b).unwrap(); + assert_eq!(result, expected); +} + +#[test] +fn test_add_saturating_overflow() { + let a = PrimitiveArray::from([ + Some(99999i128), + Some(99999i128), + Some(99999i128), + Some(-99999i128), + ]) + .to(DataType::Decimal(5, 2)); + let b = PrimitiveArray::from([ + Some(00001i128), + Some(00100i128), + Some(10000i128), + Some(-99999i128), + ]) + .to(DataType::Decimal(5, 2)); + + let result = saturating_add(&a, &b).unwrap(); + + let expected = PrimitiveArray::from([ + Some(99999i128), + Some(99999i128), + Some(99999i128), + Some(-99999i128), + ]) + .to(DataType::Decimal(5, 2)); + + assert_eq!(result, expected); + + // Testing trait + let result = a.saturating_add(&b).unwrap(); + assert_eq!(result, expected); +} + +#[test] +fn test_add_checked() { + let a = PrimitiveArray::from([Some(11111i128), Some(11100i128), None, Some(22200i128)]) + .to(DataType::Decimal(5, 2)); + + let b = PrimitiveArray::from([Some(22222i128), Some(22200i128), None, Some(11100i128)]) + .to(DataType::Decimal(5, 2)); + + let result = checked_add(&a, &b).unwrap(); + let expected = PrimitiveArray::from([Some(33333i128), Some(33300i128), None, Some(33300i128)]) + .to(DataType::Decimal(5, 2)); + + assert_eq!(result, expected); + + // Testing trait + let result = a.checked_add(&b).unwrap(); + assert_eq!(result, expected); +} + +#[test] +fn test_add_checked_overflow() { + let a = PrimitiveArray::from([Some(1i128), Some(99999i128)]).to(DataType::Decimal(5, 2)); + let b = PrimitiveArray::from([Some(1i128), Some(1i128)]).to(DataType::Decimal(5, 2)); + let result = checked_add(&a, &b).unwrap(); + let expected = PrimitiveArray::from([Some(2i128), None]).to(DataType::Decimal(5, 2)); + assert_eq!(result, expected); + + // Testing trait + let result = a.checked_add(&b).unwrap(); + assert_eq!(result, expected); +} + +#[test] +fn test_add_adaptive() { + // 11.1111 -> 6, 4 + // 11111.11 -> 7, 2 + // ----------------- + // 11122.2211 -> 9, 4 + let a = PrimitiveArray::from([Some(11_1111i128)]).to(DataType::Decimal(6, 4)); + let b = PrimitiveArray::from([Some(11111_11i128)]).to(DataType::Decimal(7, 2)); + let result = adaptive_add(&a, &b).unwrap(); + + let expected = PrimitiveArray::from([Some(11122_2211i128)]).to(DataType::Decimal(9, 4)); + + assert_eq!(result, expected); + assert_eq!(result.data_type(), &DataType::Decimal(9, 4)); + + // 0.1111 -> 5, 4 + // 11111.0 -> 6, 1 + // ----------------- + // 11111.1111 -> 9, 4 + let a = PrimitiveArray::from([Some(1111i128)]).to(DataType::Decimal(5, 4)); + let b = PrimitiveArray::from([Some(11111_0i128)]).to(DataType::Decimal(6, 1)); + let result = adaptive_add(&a, &b).unwrap(); + + let expected = PrimitiveArray::from([Some(11111_1111i128)]).to(DataType::Decimal(9, 4)); + + assert_eq!(result, expected); + assert_eq!(result.data_type(), &DataType::Decimal(9, 4)); + + // 11111.11 -> 7, 2 + // 11111.111 -> 8, 3 + // ----------------- + // 22222.221 -> 8, 3 + let a = PrimitiveArray::from([Some(11111_11i128)]).to(DataType::Decimal(7, 2)); + let b = PrimitiveArray::from([Some(11111_111i128)]).to(DataType::Decimal(8, 3)); + let result = adaptive_add(&a, &b).unwrap(); + + let expected = PrimitiveArray::from([Some(22222_221i128)]).to(DataType::Decimal(8, 3)); + + assert_eq!(result, expected); + assert_eq!(result.data_type(), &DataType::Decimal(8, 3)); + + // 99.9999 -> 6, 4 + // 00.0001 -> 6, 4 + // ----------------- + // 100.0000 -> 7, 4 + let a = PrimitiveArray::from([Some(99_9999i128)]).to(DataType::Decimal(6, 4)); + let b = PrimitiveArray::from([Some(00_0001i128)]).to(DataType::Decimal(6, 4)); + let result = adaptive_add(&a, &b).unwrap(); + + let expected = PrimitiveArray::from([Some(100_0000i128)]).to(DataType::Decimal(7, 4)); + + assert_eq!(result, expected); + assert_eq!(result.data_type(), &DataType::Decimal(7, 4)); +} diff --git a/tests/it/compute/arithmetics/decimal/div.rs b/tests/it/compute/arithmetics/decimal/div.rs new file mode 100644 index 00000000000..15b8c6b83a8 --- /dev/null +++ b/tests/it/compute/arithmetics/decimal/div.rs @@ -0,0 +1,233 @@ +#![allow(clippy::zero_prefixed_literal, clippy::inconsistent_digit_grouping)] + +use arrow2::array::*; +use arrow2::compute::arithmetics::decimal::div::*; +use arrow2::compute::arithmetics::{ArrayCheckedDiv, ArrayDiv}; +use arrow2::datatypes::DataType; + +#[test] +fn test_divide_normal() { + // 222.222 --> 222222000 + // 123.456 --> 123456 + // -------- --------- + // 1.800 <-- 1800 + let a = PrimitiveArray::from([ + Some(222_222i128), + Some(10_000i128), + Some(20_000i128), + None, + Some(30_000i128), + Some(123_456i128), + ]) + .to(DataType::Decimal(7, 3)); + + let b = PrimitiveArray::from([ + Some(123_456i128), + Some(2_000i128), + Some(3_000i128), + Some(4_000i128), + Some(4_000i128), + Some(654_321i128), + ]) + .to(DataType::Decimal(7, 3)); + + let result = div(&a, &b).unwrap(); + let expected = PrimitiveArray::from([ + Some(1_800i128), + Some(5_000i128), + Some(6_666i128), + None, + Some(7_500i128), + Some(0_188i128), + ]) + .to(DataType::Decimal(7, 3)); + + assert_eq!(result, expected); + + // Testing trait + let result = a.div(&b).unwrap(); + assert_eq!(result, expected); +} + +#[test] +fn test_divide_decimal_wrong_precision() { + let a = PrimitiveArray::from([None]).to(DataType::Decimal(5, 2)); + let b = PrimitiveArray::from([None]).to(DataType::Decimal(6, 2)); + let result = div(&a, &b); + + if result.is_ok() { + panic!("Should panic for different precision"); + } +} + +#[test] +#[should_panic(expected = "Overflow in multiplication presented for precision 5")] +fn test_divide_panic() { + let a = PrimitiveArray::from([Some(99999i128)]).to(DataType::Decimal(5, 2)); + let b = PrimitiveArray::from([Some(000_01i128)]).to(DataType::Decimal(5, 2)); + let _ = div(&a, &b); +} + +#[test] +fn test_divide_saturating() { + let a = PrimitiveArray::from([ + Some(222_222i128), + Some(10_000i128), + Some(20_000i128), + None, + Some(30_000i128), + Some(123_456i128), + ]) + .to(DataType::Decimal(7, 3)); + + let b = PrimitiveArray::from([ + Some(123_456i128), + Some(2_000i128), + Some(3_000i128), + Some(4_000i128), + Some(4_000i128), + Some(654_321i128), + ]) + .to(DataType::Decimal(7, 3)); + + let result = saturating_div(&a, &b).unwrap(); + let expected = PrimitiveArray::from([ + Some(1_800i128), + Some(5_000i128), + Some(6_666i128), + None, + Some(7_500i128), + Some(0_188i128), + ]) + .to(DataType::Decimal(7, 3)); + + assert_eq!(result, expected); +} + +#[test] +fn test_divide_saturating_overflow() { + let a = PrimitiveArray::from([ + Some(99999i128), + Some(99999i128), + Some(99999i128), + Some(99999i128), + Some(99999i128), + ]) + .to(DataType::Decimal(5, 2)); + let b = PrimitiveArray::from([ + Some(-00001i128), + Some(00001i128), + Some(00010i128), + Some(-00020i128), + Some(00000i128), + ]) + .to(DataType::Decimal(5, 2)); + + let result = saturating_div(&a, &b).unwrap(); + + let expected = PrimitiveArray::from([ + Some(-99999i128), + Some(99999i128), + Some(99999i128), + Some(-99999i128), + Some(00000i128), + ]) + .to(DataType::Decimal(5, 2)); + + assert_eq!(result, expected); +} + +#[test] +fn test_divide_checked() { + let a = PrimitiveArray::from([ + Some(222_222i128), + Some(10_000i128), + Some(20_000i128), + None, + Some(30_000i128), + Some(123_456i128), + ]) + .to(DataType::Decimal(7, 3)); + + let b = PrimitiveArray::from([ + Some(123_456i128), + Some(2_000i128), + Some(3_000i128), + Some(4_000i128), + Some(4_000i128), + Some(654_321i128), + ]) + .to(DataType::Decimal(7, 3)); + + let result = div(&a, &b).unwrap(); + let expected = PrimitiveArray::from([ + Some(1_800i128), + Some(5_000i128), + Some(6_666i128), + None, + Some(7_500i128), + Some(0_188i128), + ]) + .to(DataType::Decimal(7, 3)); + + assert_eq!(result, expected); +} + +#[test] +fn test_divide_checked_overflow() { + let a = PrimitiveArray::from([Some(1_00i128), Some(4_00i128), Some(6_00i128)]) + .to(DataType::Decimal(5, 2)); + let b = + PrimitiveArray::from([Some(000_00i128), None, Some(2_00i128)]).to(DataType::Decimal(5, 2)); + + let result = checked_div(&a, &b).unwrap(); + let expected = PrimitiveArray::from([None, None, Some(3_00i128)]).to(DataType::Decimal(5, 2)); + + assert_eq!(result, expected); + + // Testing trait + let result = a.checked_div(&b).unwrap(); + assert_eq!(result, expected); +} + +#[test] +fn test_divide_adaptive() { + // 1000.00 -> 7, 2 + // 10.0000 -> 6, 4 + // ----------------- + // 100.0000 -> 9, 4 + let a = PrimitiveArray::from([Some(1000_00i128)]).to(DataType::Decimal(7, 2)); + let b = PrimitiveArray::from([Some(10_0000i128)]).to(DataType::Decimal(6, 4)); + let result = adaptive_div(&a, &b).unwrap(); + + let expected = PrimitiveArray::from([Some(100_0000i128)]).to(DataType::Decimal(9, 4)); + + assert_eq!(result, expected); + assert_eq!(result.data_type(), &DataType::Decimal(9, 4)); + + // 11111.0 -> 6, 1 + // 10.002 -> 5, 3 + // ----------------- + // 1110.877 -> 8, 3 + let a = PrimitiveArray::from([Some(11111_0i128)]).to(DataType::Decimal(6, 1)); + let b = PrimitiveArray::from([Some(10_002i128)]).to(DataType::Decimal(5, 3)); + let result = adaptive_div(&a, &b).unwrap(); + + let expected = PrimitiveArray::from([Some(1110_877i128)]).to(DataType::Decimal(8, 3)); + + assert_eq!(result, expected); + assert_eq!(result.data_type(), &DataType::Decimal(8, 3)); + + // 12345.67 -> 7, 2 + // 12345.678 -> 8, 3 + // ----------------- + // 0.999 -> 8, 3 + let a = PrimitiveArray::from([Some(12345_67i128)]).to(DataType::Decimal(7, 2)); + let b = PrimitiveArray::from([Some(12345_678i128)]).to(DataType::Decimal(8, 3)); + let result = adaptive_div(&a, &b).unwrap(); + + let expected = PrimitiveArray::from([Some(0_999i128)]).to(DataType::Decimal(8, 3)); + + assert_eq!(result, expected); + assert_eq!(result.data_type(), &DataType::Decimal(8, 3)); +} diff --git a/tests/it/compute/arithmetics/decimal/mod.rs b/tests/it/compute/arithmetics/decimal/mod.rs new file mode 100644 index 00000000000..190e8dcf9a7 --- /dev/null +++ b/tests/it/compute/arithmetics/decimal/mod.rs @@ -0,0 +1,4 @@ +mod add; +mod div; +mod mul; +mod sub; diff --git a/tests/it/compute/arithmetics/decimal/mul.rs b/tests/it/compute/arithmetics/decimal/mul.rs new file mode 100644 index 00000000000..6c26d290059 --- /dev/null +++ b/tests/it/compute/arithmetics/decimal/mul.rs @@ -0,0 +1,235 @@ +#![allow(clippy::zero_prefixed_literal, clippy::inconsistent_digit_grouping)] + +use arrow2::array::*; +use arrow2::compute::arithmetics::decimal::mul::*; +use arrow2::compute::arithmetics::{ArrayCheckedMul, ArrayMul, ArraySaturatingMul}; +use arrow2::datatypes::DataType; + +#[test] +fn test_multiply_normal() { + // 111.11 --> 11111 + // 222.22 --> 22222 + // -------- ------- + // 24690.86 <-- 246908642 + let a = PrimitiveArray::from([ + Some(111_11i128), + Some(10_00i128), + Some(20_00i128), + None, + Some(30_00i128), + Some(123_45i128), + ]) + .to(DataType::Decimal(7, 2)); + + let b = PrimitiveArray::from([ + Some(222_22i128), + Some(2_00i128), + Some(3_00i128), + None, + Some(4_00i128), + Some(543_21i128), + ]) + .to(DataType::Decimal(7, 2)); + + let result = mul(&a, &b).unwrap(); + let expected = PrimitiveArray::from([ + Some(24690_86i128), + Some(20_00i128), + Some(60_00i128), + None, + Some(120_00i128), + Some(67059_27i128), + ]) + .to(DataType::Decimal(7, 2)); + + assert_eq!(result, expected); + + // Testing trait + let result = a.mul(&b).unwrap(); + assert_eq!(result, expected); +} + +#[test] +fn test_multiply_decimal_wrong_precision() { + let a = PrimitiveArray::from([None]).to(DataType::Decimal(5, 2)); + let b = PrimitiveArray::from([None]).to(DataType::Decimal(6, 2)); + let result = mul(&a, &b); + + if result.is_ok() { + panic!("Should panic for different precision"); + } +} + +#[test] +#[should_panic(expected = "Overflow in multiplication presented for precision 5")] +fn test_multiply_panic() { + let a = PrimitiveArray::from([Some(99999i128)]).to(DataType::Decimal(5, 2)); + let b = PrimitiveArray::from([Some(100_00i128)]).to(DataType::Decimal(5, 2)); + let _ = mul(&a, &b); +} + +#[test] +fn test_multiply_saturating() { + let a = PrimitiveArray::from([ + Some(111_11i128), + Some(10_00i128), + Some(20_00i128), + None, + Some(30_00i128), + Some(123_45i128), + ]) + .to(DataType::Decimal(7, 2)); + + let b = PrimitiveArray::from([ + Some(222_22i128), + Some(2_00i128), + Some(3_00i128), + None, + Some(4_00i128), + Some(543_21i128), + ]) + .to(DataType::Decimal(7, 2)); + + let result = saturating_mul(&a, &b).unwrap(); + let expected = PrimitiveArray::from([ + Some(24690_86i128), + Some(20_00i128), + Some(60_00i128), + None, + Some(120_00i128), + Some(67059_27i128), + ]) + .to(DataType::Decimal(7, 2)); + + assert_eq!(result, expected); + + // Testing trait + let result = a.saturating_mul(&b).unwrap(); + assert_eq!(result, expected); +} + +#[test] +fn test_multiply_saturating_overflow() { + let a = PrimitiveArray::from([ + Some(99999i128), + Some(99999i128), + Some(99999i128), + Some(99999i128), + ]) + .to(DataType::Decimal(5, 2)); + let b = PrimitiveArray::from([ + Some(-00100i128), + Some(01000i128), + Some(10000i128), + Some(-99999i128), + ]) + .to(DataType::Decimal(5, 2)); + + let result = saturating_mul(&a, &b).unwrap(); + + let expected = PrimitiveArray::from([ + Some(-99999i128), + Some(99999i128), + Some(99999i128), + Some(-99999i128), + ]) + .to(DataType::Decimal(5, 2)); + + assert_eq!(result, expected); + + // Testing trait + let result = a.saturating_mul(&b).unwrap(); + assert_eq!(result, expected); +} + +#[test] +fn test_multiply_checked() { + let a = PrimitiveArray::from([ + Some(111_11i128), + Some(10_00i128), + Some(20_00i128), + None, + Some(30_00i128), + Some(123_45i128), + ]) + .to(DataType::Decimal(7, 2)); + + let b = PrimitiveArray::from([ + Some(222_22i128), + Some(2_00i128), + Some(3_00i128), + None, + Some(4_00i128), + Some(543_21i128), + ]) + .to(DataType::Decimal(7, 2)); + + let result = checked_mul(&a, &b).unwrap(); + let expected = PrimitiveArray::from([ + Some(24690_86i128), + Some(20_00i128), + Some(60_00i128), + None, + Some(120_00i128), + Some(67059_27i128), + ]) + .to(DataType::Decimal(7, 2)); + + assert_eq!(result, expected); + + // Testing trait + let result = a.checked_mul(&b).unwrap(); + assert_eq!(result, expected); +} + +#[test] +fn test_multiply_checked_overflow() { + let a = PrimitiveArray::from([Some(99999i128), Some(1_00i128)]).to(DataType::Decimal(5, 2)); + let b = PrimitiveArray::from([Some(10000i128), Some(2_00i128)]).to(DataType::Decimal(5, 2)); + let result = checked_mul(&a, &b).unwrap(); + let expected = PrimitiveArray::from([None, Some(2_00i128)]).to(DataType::Decimal(5, 2)); + + assert_eq!(result, expected); +} + +#[test] +fn test_multiply_adaptive() { + // 1000.00 -> 7, 2 + // 10.0000 -> 6, 4 + // ----------------- + // 10000.0000 -> 9, 4 + let a = PrimitiveArray::from([Some(1000_00i128)]).to(DataType::Decimal(7, 2)); + let b = PrimitiveArray::from([Some(10_0000i128)]).to(DataType::Decimal(6, 4)); + let result = adaptive_mul(&a, &b).unwrap(); + + let expected = PrimitiveArray::from([Some(10000_0000i128)]).to(DataType::Decimal(9, 4)); + + assert_eq!(result, expected); + assert_eq!(result.data_type(), &DataType::Decimal(9, 4)); + + // 11111.0 -> 6, 1 + // 10.002 -> 5, 3 + // ----------------- + // 111132.222 -> 9, 3 + let a = PrimitiveArray::from([Some(11111_0i128)]).to(DataType::Decimal(6, 1)); + let b = PrimitiveArray::from([Some(10_002i128)]).to(DataType::Decimal(5, 3)); + let result = adaptive_mul(&a, &b).unwrap(); + + let expected = PrimitiveArray::from([Some(111132_222i128)]).to(DataType::Decimal(9, 3)); + + assert_eq!(result, expected); + assert_eq!(result.data_type(), &DataType::Decimal(9, 3)); + + // 12345.67 -> 7, 2 + // 12345.678 -> 8, 3 + // ----------------- + // 152415666.514 -> 11, 3 + let a = PrimitiveArray::from([Some(12345_67i128)]).to(DataType::Decimal(7, 2)); + let b = PrimitiveArray::from([Some(12345_678i128)]).to(DataType::Decimal(8, 3)); + let result = adaptive_mul(&a, &b).unwrap(); + + let expected = PrimitiveArray::from([Some(152415666_514i128)]).to(DataType::Decimal(12, 3)); + + assert_eq!(result, expected); + assert_eq!(result.data_type(), &DataType::Decimal(12, 3)); +} diff --git a/tests/it/compute/arithmetics/decimal/sub.rs b/tests/it/compute/arithmetics/decimal/sub.rs new file mode 100644 index 00000000000..467b1d220c6 --- /dev/null +++ b/tests/it/compute/arithmetics/decimal/sub.rs @@ -0,0 +1,180 @@ +#![allow(clippy::zero_prefixed_literal, clippy::inconsistent_digit_grouping)] + +use arrow2::array::*; +use arrow2::compute::arithmetics::decimal::sub::*; +use arrow2::compute::arithmetics::{ArrayCheckedSub, ArraySaturatingSub, ArraySub}; +use arrow2::datatypes::DataType; + +#[test] +fn test_subtract_normal() { + let a = PrimitiveArray::from([Some(11111i128), Some(22200i128), None, Some(40000i128)]) + .to(DataType::Decimal(5, 2)); + + let b = PrimitiveArray::from([Some(22222i128), Some(11100i128), None, Some(11100i128)]) + .to(DataType::Decimal(5, 2)); + + let result = sub(&a, &b).unwrap(); + let expected = PrimitiveArray::from([Some(-11111i128), Some(11100i128), None, Some(28900i128)]) + .to(DataType::Decimal(5, 2)); + + assert_eq!(result, expected); + + // Testing trait + let result = a.sub(&b).unwrap(); + assert_eq!(result, expected); +} + +#[test] +fn test_subtract_decimal_wrong_precision() { + let a = PrimitiveArray::from([None]).to(DataType::Decimal(5, 2)); + let b = PrimitiveArray::from([None]).to(DataType::Decimal(6, 2)); + let result = sub(&a, &b); + + if result.is_ok() { + panic!("Should panic for different precision"); + } +} + +#[test] +#[should_panic(expected = "Overflow in subtract presented for precision 5")] +fn test_subtract_panic() { + let a = PrimitiveArray::from([Some(-99999i128)]).to(DataType::Decimal(5, 2)); + let b = PrimitiveArray::from([Some(1i128)]).to(DataType::Decimal(5, 2)); + let _ = sub(&a, &b); +} + +#[test] +fn test_subtract_saturating() { + let a = PrimitiveArray::from([Some(11111i128), Some(22200i128), None, Some(40000i128)]) + .to(DataType::Decimal(5, 2)); + + let b = PrimitiveArray::from([Some(22222i128), Some(11100i128), None, Some(11100i128)]) + .to(DataType::Decimal(5, 2)); + + let result = saturating_sub(&a, &b).unwrap(); + let expected = PrimitiveArray::from([Some(-11111i128), Some(11100i128), None, Some(28900i128)]) + .to(DataType::Decimal(5, 2)); + + assert_eq!(result, expected); + + // Testing trait + let result = a.saturating_sub(&b).unwrap(); + assert_eq!(result, expected); +} + +#[test] +fn test_subtract_saturating_overflow() { + let a = PrimitiveArray::from([ + Some(-99999i128), + Some(-99999i128), + Some(-99999i128), + Some(99999i128), + ]) + .to(DataType::Decimal(5, 2)); + let b = PrimitiveArray::from([ + Some(00001i128), + Some(00100i128), + Some(10000i128), + Some(-99999i128), + ]) + .to(DataType::Decimal(5, 2)); + + let result = saturating_sub(&a, &b).unwrap(); + + let expected = PrimitiveArray::from([ + Some(-99999i128), + Some(-99999i128), + Some(-99999i128), + Some(99999i128), + ]) + .to(DataType::Decimal(5, 2)); + + assert_eq!(result, expected); + + // Testing trait + let result = a.saturating_sub(&b).unwrap(); + assert_eq!(result, expected); +} + +#[test] +fn test_subtract_checked() { + let a = PrimitiveArray::from([Some(11111i128), Some(22200i128), None, Some(40000i128)]) + .to(DataType::Decimal(5, 2)); + + let b = PrimitiveArray::from([Some(22222i128), Some(11100i128), None, Some(11100i128)]) + .to(DataType::Decimal(5, 2)); + + let result = checked_sub(&a, &b).unwrap(); + let expected = PrimitiveArray::from([Some(-11111i128), Some(11100i128), None, Some(28900i128)]) + .to(DataType::Decimal(5, 2)); + + assert_eq!(result, expected); + + // Testing trait + let result = a.checked_sub(&b).unwrap(); + assert_eq!(result, expected); +} + +#[test] +fn test_subtract_checked_overflow() { + let a = PrimitiveArray::from([Some(4i128), Some(-99999i128)]).to(DataType::Decimal(5, 2)); + let b = PrimitiveArray::from([Some(2i128), Some(1i128)]).to(DataType::Decimal(5, 2)); + let result = checked_sub(&a, &b).unwrap(); + let expected = PrimitiveArray::from([Some(2i128), None]).to(DataType::Decimal(5, 2)); + assert_eq!(result, expected); +} + +#[test] +fn test_subtract_adaptive() { + // 11.1111 -> 6, 4 + // 11111.11 -> 7, 2 + // ------------------ + // -11099.9989 -> 9, 4 + let a = PrimitiveArray::from([Some(11_1111i128)]).to(DataType::Decimal(6, 4)); + let b = PrimitiveArray::from([Some(11111_11i128)]).to(DataType::Decimal(7, 2)); + let result = adaptive_sub(&a, &b).unwrap(); + + let expected = PrimitiveArray::from([Some(-11099_9989i128)]).to(DataType::Decimal(9, 4)); + + assert_eq!(result, expected); + assert_eq!(result.data_type(), &DataType::Decimal(9, 4)); + + // 11111.0 -> 6, 1 + // 0.1111 -> 5, 4 + // ----------------- + // 11110.8889 -> 9, 4 + let a = PrimitiveArray::from([Some(11111_0i128)]).to(DataType::Decimal(6, 1)); + let b = PrimitiveArray::from([Some(1111i128)]).to(DataType::Decimal(5, 4)); + let result = adaptive_sub(&a, &b).unwrap(); + + let expected = PrimitiveArray::from([Some(11110_8889i128)]).to(DataType::Decimal(9, 4)); + + assert_eq!(result, expected); + assert_eq!(result.data_type(), &DataType::Decimal(9, 4)); + + // 11111.11 -> 7, 2 + // 11111.111 -> 8, 3 + // ----------------- + // -00000.001 -> 8, 3 + let a = PrimitiveArray::from([Some(11111_11i128)]).to(DataType::Decimal(7, 2)); + let b = PrimitiveArray::from([Some(11111_111i128)]).to(DataType::Decimal(8, 3)); + let result = adaptive_sub(&a, &b).unwrap(); + + let expected = PrimitiveArray::from([Some(-00000_001i128)]).to(DataType::Decimal(8, 3)); + + assert_eq!(result, expected); + assert_eq!(result.data_type(), &DataType::Decimal(8, 3)); + + // 99.9999 -> 6, 4 + // -00.0001 -> 6, 4 + // ----------------- + // 100.0000 -> 7, 4 + let a = PrimitiveArray::from([Some(99_9999i128)]).to(DataType::Decimal(6, 4)); + let b = PrimitiveArray::from([Some(-00_0001i128)]).to(DataType::Decimal(6, 4)); + let result = adaptive_sub(&a, &b).unwrap(); + + let expected = PrimitiveArray::from([Some(100_0000i128)]).to(DataType::Decimal(7, 4)); + + assert_eq!(result, expected); + assert_eq!(result.data_type(), &DataType::Decimal(7, 4)); +} diff --git a/tests/it/compute/arithmetics/mod.rs b/tests/it/compute/arithmetics/mod.rs new file mode 100644 index 00000000000..00b90bc0dd1 --- /dev/null +++ b/tests/it/compute/arithmetics/mod.rs @@ -0,0 +1,68 @@ +mod basic; +mod decimal; +mod time; + +use arrow2::array::new_empty_array; +use arrow2::compute::arithmetics::{arithmetic, can_arithmetic, Operator}; +use arrow2::datatypes::DataType::*; +use arrow2::datatypes::{IntervalUnit, TimeUnit}; + +#[test] +fn consistency() { + let datatypes = vec![ + Null, + Boolean, + UInt8, + UInt16, + UInt32, + UInt64, + Int8, + Int16, + Int32, + Int64, + Float32, + Float64, + Timestamp(TimeUnit::Second, None), + Timestamp(TimeUnit::Millisecond, None), + Timestamp(TimeUnit::Microsecond, None), + Timestamp(TimeUnit::Nanosecond, None), + Time64(TimeUnit::Microsecond), + Time64(TimeUnit::Nanosecond), + Date32, + Time32(TimeUnit::Second), + Time32(TimeUnit::Millisecond), + Date64, + Utf8, + LargeUtf8, + Binary, + LargeBinary, + Duration(TimeUnit::Second), + Duration(TimeUnit::Millisecond), + Duration(TimeUnit::Microsecond), + Duration(TimeUnit::Nanosecond), + Interval(IntervalUnit::MonthDayNano), + ]; + let operators = vec![ + Operator::Add, + Operator::Divide, + Operator::Subtract, + Operator::Multiply, + Operator::Remainder, + ]; + + let cases = datatypes + .clone() + .into_iter() + .zip(operators.into_iter()) + .zip(datatypes.into_iter()); + + cases.for_each(|((lhs, op), rhs)| { + let lhs_a = new_empty_array(lhs.clone()); + let rhs_a = new_empty_array(rhs.clone()); + if can_arithmetic(&lhs, op, &rhs) { + assert!(arithmetic(lhs_a.as_ref(), op, rhs_a.as_ref()).is_ok()); + } else { + assert!(arithmetic(lhs_a.as_ref(), op, rhs_a.as_ref()).is_err()); + } + }); +} diff --git a/tests/it/compute/arithmetics/time.rs b/tests/it/compute/arithmetics/time.rs new file mode 100644 index 00000000000..e4462198f3c --- /dev/null +++ b/tests/it/compute/arithmetics/time.rs @@ -0,0 +1,309 @@ +use arrow2::array::*; +use arrow2::compute::arithmetics::time::{add_duration, subtract_duration, subtract_timestamps}; +use arrow2::datatypes::{DataType, TimeUnit}; + +#[test] +fn test_adding_timestamp() { + let timestamp = + PrimitiveArray::from([Some(100000i64), Some(200000i64), None, Some(300000i64)]).to( + DataType::Timestamp(TimeUnit::Second, Some("America/New_York".to_string())), + ); + + let duration = PrimitiveArray::from([Some(10i64), Some(20i64), None, Some(30i64)]) + .to(DataType::Duration(TimeUnit::Second)); + + let result = add_duration(×tamp, &duration).unwrap(); + let expected = + PrimitiveArray::from([Some(100010i64), Some(200020i64), None, Some(300030i64)]).to( + DataType::Timestamp(TimeUnit::Second, Some("America/New_York".to_string())), + ); + + assert_eq!(result, expected); +} + +#[test] +fn test_adding_duration_different_scale() { + let timestamp = + PrimitiveArray::from([Some(100000i64), Some(200000i64), None, Some(300000i64)]).to( + DataType::Timestamp(TimeUnit::Second, Some("America/New_York".to_string())), + ); + let expected = + PrimitiveArray::from([Some(100010i64), Some(200020i64), None, Some(300030i64)]).to( + DataType::Timestamp(TimeUnit::Second, Some("America/New_York".to_string())), + ); + + // Testing duration in milliseconds + let duration = PrimitiveArray::from([Some(10_000i64), Some(20_000i64), None, Some(30_000i64)]) + .to(DataType::Duration(TimeUnit::Millisecond)); + + let result = add_duration(×tamp, &duration).unwrap(); + assert_eq!(result, expected); + + // Testing duration in nanoseconds. + // The last digits in the nanosecond are not significant enough to + // be added to the timestamp which is in seconds and doesn't have a + // fractional value + let duration = PrimitiveArray::from([ + Some(10_000_000_999i64), + Some(20_000_000_000i64), + None, + Some(30_000_000_000i64), + ]) + .to(DataType::Duration(TimeUnit::Nanosecond)); + + let result = add_duration(×tamp, &duration).unwrap(); + assert_eq!(result, expected); +} + +#[test] +fn test_adding_subtract_timestamps_scale() { + let timestamp = PrimitiveArray::from([Some(10i64), Some(20i64), None, Some(30i64)]).to( + DataType::Timestamp(TimeUnit::Millisecond, Some("America/New_York".to_string())), + ); + let duration = PrimitiveArray::from([Some(1i64), Some(2i64), None, Some(3i64)]) + .to(DataType::Duration(TimeUnit::Second)); + + let expected = PrimitiveArray::from([Some(1_010i64), Some(2_020i64), None, Some(3_030i64)]).to( + DataType::Timestamp(TimeUnit::Millisecond, Some("America/New_York".to_string())), + ); + + let result = add_duration(×tamp, &duration).unwrap(); + assert_eq!(result, expected); + + let timestamp = PrimitiveArray::from([Some(10i64), Some(20i64), None, Some(30i64)]).to( + DataType::Timestamp(TimeUnit::Nanosecond, Some("America/New_York".to_string())), + ); + let duration = PrimitiveArray::from([Some(1i64), Some(2i64), None, Some(3i64)]) + .to(DataType::Duration(TimeUnit::Second)); + + let expected = PrimitiveArray::from([ + Some(1_000_000_010i64), + Some(2_000_000_020i64), + None, + Some(3_000_000_030i64), + ]) + .to(DataType::Timestamp( + TimeUnit::Nanosecond, + Some("America/New_York".to_string()), + )); + + let result = add_duration(×tamp, &duration).unwrap(); + assert_eq!(result, expected); +} + +#[test] +fn test_subtract_timestamp() { + let timestamp = + PrimitiveArray::from([Some(100000i64), Some(200000i64), None, Some(300000i64)]).to( + DataType::Timestamp(TimeUnit::Second, Some("America/New_York".to_string())), + ); + + let duration = PrimitiveArray::from([Some(10i64), Some(20i64), None, Some(30i64)]) + .to(DataType::Duration(TimeUnit::Second)); + + let result = subtract_duration(×tamp, &duration).unwrap(); + let expected = + PrimitiveArray::from([Some(99990i64), Some(199980i64), None, Some(299970i64)]).to( + DataType::Timestamp(TimeUnit::Second, Some("America/New_York".to_string())), + ); + + assert_eq!(result, expected); +} + +#[test] +fn test_subtracting_duration_different_scale() { + let timestamp = + PrimitiveArray::from([Some(100000i64), Some(200000i64), None, Some(300000i64)]).to( + DataType::Timestamp(TimeUnit::Second, Some("America/New_York".to_string())), + ); + let expected = + PrimitiveArray::from([Some(99990i64), Some(199980i64), None, Some(299970i64)]).to( + DataType::Timestamp(TimeUnit::Second, Some("America/New_York".to_string())), + ); + + // Testing duration in milliseconds + let duration = PrimitiveArray::from([Some(10_000i64), Some(20_000i64), None, Some(30_000i64)]) + .to(DataType::Duration(TimeUnit::Millisecond)); + + let result = subtract_duration(×tamp, &duration).unwrap(); + assert_eq!(result, expected); + + // Testing duration in nanoseconds. + // The last digits in the nanosecond are not significant enough to + // be added to the timestamp which is in seconds and doesn't have a + // fractional value + let duration = PrimitiveArray::from([ + Some(10_000_000_999i64), + Some(20_000_000_000i64), + None, + Some(30_000_000_000i64), + ]) + .to(DataType::Duration(TimeUnit::Nanosecond)); + + let result = subtract_duration(×tamp, &duration).unwrap(); + assert_eq!(result, expected); +} + +#[test] +fn test_subtracting_subtract_timestamps_scale() { + let timestamp = PrimitiveArray::from([Some(10i64), Some(20i64), None, Some(30i64)]).to( + DataType::Timestamp(TimeUnit::Millisecond, Some("America/New_York".to_string())), + ); + let duration = PrimitiveArray::from([Some(1i64), Some(2i64), None, Some(3i64)]) + .to(DataType::Duration(TimeUnit::Second)); + + let expected = + PrimitiveArray::from([Some(-990i64), Some(-1_980i64), None, Some(-2_970i64)]).to( + DataType::Timestamp(TimeUnit::Millisecond, Some("America/New_York".to_string())), + ); + + let result = subtract_duration(×tamp, &duration).unwrap(); + assert_eq!(result, expected); + + let timestamp = PrimitiveArray::from([Some(10i64), Some(20i64), None, Some(30i64)]).to( + DataType::Timestamp(TimeUnit::Nanosecond, Some("America/New_York".to_string())), + ); + let duration = PrimitiveArray::from([Some(1i64), Some(2i64), None, Some(3i64)]) + .to(DataType::Duration(TimeUnit::Second)); + + let expected = PrimitiveArray::from([ + Some(-999_999_990i64), + Some(-1_999_999_980i64), + None, + Some(-2_999_999_970i64), + ]) + .to(DataType::Timestamp( + TimeUnit::Nanosecond, + Some("America/New_York".to_string()), + )); + + let result = subtract_duration(×tamp, &duration).unwrap(); + assert_eq!(result, expected); +} + +#[test] +fn test_subtract_timestamps() { + let timestamp_a = + PrimitiveArray::from([Some(100_010i64), Some(200_020i64), None, Some(300_030i64)]) + .to(DataType::Timestamp(TimeUnit::Second, None)); + + let timestamp_b = + PrimitiveArray::from([Some(100_000i64), Some(200_000i64), None, Some(300_000i64)]) + .to(DataType::Timestamp(TimeUnit::Second, None)); + + let expected = PrimitiveArray::from([Some(10i64), Some(20i64), None, Some(30i64)]) + .to(DataType::Duration(TimeUnit::Second)); + + let result = subtract_timestamps(×tamp_a, ×tamp_b).unwrap(); + assert_eq!(result, expected); +} + +#[test] +fn test_subtract_timestamps_scale() { + let timestamp_a = PrimitiveArray::from([ + Some(100_000_000i64), + Some(200_000_000i64), + None, + Some(300_000_000i64), + ]) + .to(DataType::Timestamp(TimeUnit::Millisecond, None)); + + let timestamp_b = + PrimitiveArray::from([Some(100_010i64), Some(200_020i64), None, Some(300_030i64)]) + .to(DataType::Timestamp(TimeUnit::Second, None)); + + let expected = + PrimitiveArray::from([Some(-10_000i64), Some(-20_000i64), None, Some(-30_000i64)]) + .to(DataType::Duration(TimeUnit::Millisecond)); + + let result = subtract_timestamps(×tamp_a, ×tamp_b).unwrap(); + assert_eq!(result, expected); +} + +#[test] +fn test_adding_to_time() { + let duration = PrimitiveArray::from([Some(10i64), Some(20i64), None, Some(30i64)]) + .to(DataType::Duration(TimeUnit::Second)); + + // Testing Time32 + let time_32 = PrimitiveArray::from([Some(100000i32), Some(200000i32), None, Some(300000i32)]) + .to(DataType::Time32(TimeUnit::Second)); + + let result = add_duration(&time_32, &duration).unwrap(); + let expected = PrimitiveArray::from([Some(100010i32), Some(200020i32), None, Some(300030i32)]) + .to(DataType::Time32(TimeUnit::Second)); + + assert_eq!(result, expected); +} + +#[test] +fn test_subtract_to_time() { + let duration = PrimitiveArray::from([Some(10i64), Some(20i64), None, Some(30i64)]) + .to(DataType::Duration(TimeUnit::Second)); + + // Testing Time32 + let time_32 = PrimitiveArray::from([Some(100000i32), Some(200000i32), None, Some(300000i32)]) + .to(DataType::Time32(TimeUnit::Second)); + + let result = subtract_duration(&time_32, &duration).unwrap(); + let expected = PrimitiveArray::from([Some(99990i32), Some(199980i32), None, Some(299970i32)]) + .to(DataType::Time32(TimeUnit::Second)); + + assert_eq!(result, expected); +} + +#[test] +fn test_date32() { + let duration = PrimitiveArray::from([ + Some(86_400), // 1 day + Some(864_000i64), // 10 days + None, + Some(8_640_000i64), // 100 days + ]) + .to(DataType::Duration(TimeUnit::Second)); + + let date_32 = + PrimitiveArray::from([Some(100_000i32), Some(100_000i32), None, Some(100_000i32)]) + .to(DataType::Date32); + + let result = add_duration(&date_32, &duration).unwrap(); + let expected = + PrimitiveArray::from([Some(100_001i32), Some(100_010i32), None, Some(100_100i32)]) + .to(DataType::Date32); + + assert_eq!(result, expected); + + let result = subtract_duration(&date_32, &duration).unwrap(); + let expected = PrimitiveArray::from([Some(99_999i32), Some(99_990i32), None, Some(99_900i32)]) + .to(DataType::Date32); + + assert_eq!(result, expected); +} + +#[test] +fn test_date64() { + let duration = PrimitiveArray::from([ + Some(10i64), // 10 milliseconds + Some(100i64), // 100 milliseconds + None, + Some(1_000i64), // 1000 milliseconds + ]) + .to(DataType::Duration(TimeUnit::Millisecond)); + + let date_64 = + PrimitiveArray::from([Some(100_000i64), Some(100_000i64), None, Some(100_000i64)]) + .to(DataType::Date64); + + let result = add_duration(&date_64, &duration).unwrap(); + let expected = + PrimitiveArray::from([Some(100_010i64), Some(100_100i64), None, Some(101_000i64)]) + .to(DataType::Date64); + + assert_eq!(result, expected); + + let result = subtract_duration(&date_64, &duration).unwrap(); + let expected = PrimitiveArray::from([Some(99_990i64), Some(99_900i64), None, Some(99_000i64)]) + .to(DataType::Date64); + + assert_eq!(result, expected); +} diff --git a/tests/it/compute/comparison.rs b/tests/it/compute/comparison.rs new file mode 100644 index 00000000000..02943ce6e25 --- /dev/null +++ b/tests/it/compute/comparison.rs @@ -0,0 +1,64 @@ +use arrow2::array::new_null_array; +use arrow2::compute::comparison::{can_compare, compare, compare_scalar, Operator}; +use arrow2::datatypes::DataType::*; +use arrow2::datatypes::TimeUnit; +use arrow2::scalar::new_scalar; + +#[test] +fn consistency() { + let datatypes = vec![ + Null, + Boolean, + UInt8, + UInt16, + UInt32, + UInt64, + Int8, + Int16, + Int32, + Int64, + Float32, + Float64, + Timestamp(TimeUnit::Second, None), + Timestamp(TimeUnit::Millisecond, None), + Timestamp(TimeUnit::Microsecond, None), + Timestamp(TimeUnit::Nanosecond, None), + Time64(TimeUnit::Microsecond), + Time64(TimeUnit::Nanosecond), + Date32, + Time32(TimeUnit::Second), + Time32(TimeUnit::Millisecond), + Date64, + Utf8, + LargeUtf8, + Binary, + LargeBinary, + Duration(TimeUnit::Second), + Duration(TimeUnit::Millisecond), + Duration(TimeUnit::Microsecond), + Duration(TimeUnit::Nanosecond), + ]; + + // array <> array + datatypes.clone().into_iter().for_each(|d1| { + let array = new_null_array(d1.clone(), 10); + let op = Operator::Eq; + if can_compare(&d1) { + assert!(compare(array.as_ref(), array.as_ref(), op).is_ok()); + } else { + assert!(compare(array.as_ref(), array.as_ref(), op).is_err()); + } + }); + + // array <> scalar + datatypes.into_iter().for_each(|d1| { + let array = new_null_array(d1.clone(), 10); + let scalar = new_scalar(array.as_ref(), 0); + let op = Operator::Eq; + if can_compare(&d1) { + assert!(compare_scalar(array.as_ref(), scalar.as_ref(), op).is_ok()); + } else { + assert!(compare_scalar(array.as_ref(), scalar.as_ref(), op).is_err()); + } + }); +} diff --git a/tests/it/compute/contains.rs b/tests/it/compute/contains.rs new file mode 100644 index 00000000000..ac789628b1d --- /dev/null +++ b/tests/it/compute/contains.rs @@ -0,0 +1,61 @@ +use arrow2::array::*; +use arrow2::compute::contains::contains; + +// disable wrapping inside literal vectors used for test data and assertions +#[rustfmt::skip::macros(vec)] +// Expected behaviour: +// contains([1, 2, null], 1) = true +// contains([1, 2, null], 3) = false +// contains([1, 2, null], null) = null +// contains(null, 1) = null +#[test] +fn test_contains() { + let data = vec![ + Some(vec![Some(1), Some(2), None]), + Some(vec![Some(1), Some(2), None]), + Some(vec![Some(1), Some(2), None]), + None, + ]; + let values = Int32Array::from(&[Some(1), Some(3), None, Some(1)]); + let expected = BooleanArray::from(vec![ + Some(true), + Some(false), + None, + None + ]); + + let mut a = MutableListArray::>::new(); + a.try_extend(data).unwrap(); + let a: ListArray = a.into(); + + let result = contains(&a, &values).unwrap(); + + assert_eq!(result, expected); +} + +// disable wrapping inside literal vectors used for test data and assertions +#[rustfmt::skip::macros(vec)] +#[test] +fn test_contains_binary() { + let data = vec![ + Some(vec![Some(b"a"), Some(b"b"), None]), + Some(vec![Some(b"a"), Some(b"b"), None]), + Some(vec![Some(b"a"), Some(b"b"), None]), + None, + ]; + let values = BinaryArray::::from(&[Some(b"a"), Some(b"c"), None, Some(b"a")]); + let expected = BooleanArray::from(vec![ + Some(true), + Some(false), + None, + None + ]); + + let mut a = MutableListArray::>::new(); + a.try_extend(data).unwrap(); + let a: ListArray = a.into(); + + let result = contains(&a, &values).unwrap(); + + assert_eq!(result, expected); +} diff --git a/tests/it/compute/mod.rs b/tests/it/compute/mod.rs index 0f2ed2c12a3..78eced0b882 100644 --- a/tests/it/compute/mod.rs +++ b/tests/it/compute/mod.rs @@ -1,7 +1,11 @@ +mod aggregate; +mod arithmetics; mod boolean; mod boolean_kleene; mod cast; +mod comparison; mod concat; +mod contains; mod filter; mod hash; mod if_then_else; @@ -16,5 +20,6 @@ mod partition; mod regex_match; mod sort; mod substring; +mod take; mod temporal; mod window; diff --git a/tests/it/compute/sort/lex_sort.rs b/tests/it/compute/sort/lex_sort.rs new file mode 100644 index 00000000000..bf0b146a8fe --- /dev/null +++ b/tests/it/compute/sort/lex_sort.rs @@ -0,0 +1,210 @@ +use arrow2::array::*; +use arrow2::compute::sort::{lexsort, SortColumn, SortOptions}; + +fn test_lex_sort_arrays(input: Vec, expected: Vec>) { + let sorted = lexsort::(&input, None).unwrap(); + assert_eq!(sorted, expected); + + let sorted = lexsort::(&input, Some(2)).unwrap(); + let expected = expected + .into_iter() + .map(|x| x.slice(0, 2)) + .collect::>(); + assert_eq!(sorted, expected); +} + +#[test] +fn test_lex_sort_mixed_types() { + let c1 = Int64Array::from(&[Some(0), Some(2), Some(-1), Some(0)]); + let c2 = UInt32Array::from(&[Some(101), Some(8), Some(7), Some(102)]); + let c3 = Int64Array::from(&[Some(-1), Some(-2), Some(-3), Some(-4)]); + + let input = vec![ + SortColumn { + values: &c1, + options: None, + }, + SortColumn { + values: &c2, + options: None, + }, + SortColumn { + values: &c3, + options: None, + }, + ]; + let c1 = Int64Array::from(&[Some(-1), Some(0), Some(0), Some(2)]); + let c2 = UInt32Array::from(&[Some(7), Some(101), Some(102), Some(8)]); + let c3 = Int64Array::from(&[Some(-3), Some(-1), Some(-4), Some(-2)]); + let expected = vec![Box::new(c1) as Box, Box::new(c2), Box::new(c3)]; + test_lex_sort_arrays(input, expected); +} + +#[test] +fn test_lex_sort_mixed_types2() { + // test mix of string and in64 with option + let c1 = Int64Array::from(&[Some(0), Some(2), Some(-1), Some(0)]); + let c2 = Utf8Array::::from(&vec![Some("foo"), Some("9"), Some("7"), Some("bar")]); + let input = vec![ + SortColumn { + values: &c1, + options: Some(SortOptions { + descending: true, + nulls_first: true, + }), + }, + SortColumn { + values: &c2, + options: Some(SortOptions { + descending: true, + nulls_first: true, + }), + }, + ]; + let expected = vec![ + Box::new(Int64Array::from(&[Some(2), Some(0), Some(0), Some(-1)])) as Box, + Box::new(Utf8Array::::from(&vec![ + Some("9"), + Some("foo"), + Some("bar"), + Some("7"), + ])) as Box, + ]; + test_lex_sort_arrays(input, expected); +} + +/* + // test sort with nulls first + let input = vec![ + SortColumn { + values: Arc::new(PrimitiveArray::::from(vec![ + None, + Some(-1), + Some(2), + None, + ])) as ArrayRef, + options: Some(SortOptions { + descending: true, + nulls_first: true, + }), + }, + SortColumn { + values: Arc::new(StringArray::from(vec![ + Some("foo"), + Some("world"), + Some("hello"), + None, + ])) as ArrayRef, + options: Some(SortOptions { + descending: true, + nulls_first: true, + }), + }, + ]; + let expected = vec![ + Arc::new(PrimitiveArray::::from(vec![ + None, + None, + Some(2), + Some(-1), + ])) as ArrayRef, + Arc::new(StringArray::from(vec![ + None, + Some("foo"), + Some("hello"), + Some("world"), + ])) as ArrayRef, + ]; + test_lex_sort_arrays(input, expected); + + // test sort with nulls last + let input = vec![ + SortColumn { + values: Arc::new(PrimitiveArray::::from(vec![ + None, + Some(-1), + Some(2), + None, + ])) as ArrayRef, + options: Some(SortOptions { + descending: true, + nulls_first: false, + }), + }, + SortColumn { + values: Arc::new(StringArray::from(vec![ + Some("foo"), + Some("world"), + Some("hello"), + None, + ])) as ArrayRef, + options: Some(SortOptions { + descending: true, + nulls_first: false, + }), + }, + ]; + let expected = vec![ + Arc::new(PrimitiveArray::::from(vec![ + Some(2), + Some(-1), + None, + None, + ])) as ArrayRef, + Arc::new(StringArray::from(vec![ + Some("hello"), + Some("world"), + Some("foo"), + None, + ])) as ArrayRef, + ]; + test_lex_sort_arrays(input, expected); + + // test sort with opposite options + let input = vec![ + SortColumn { + values: Arc::new(PrimitiveArray::::from(vec![ + None, + Some(-1), + Some(2), + Some(-1), + None, + ])) as ArrayRef, + options: Some(SortOptions { + descending: false, + nulls_first: false, + }), + }, + SortColumn { + values: Arc::new(StringArray::from(vec![ + Some("foo"), + Some("bar"), + Some("world"), + Some("hello"), + None, + ])) as ArrayRef, + options: Some(SortOptions { + descending: true, + nulls_first: true, + }), + }, + ]; + let expected = vec![ + Arc::new(PrimitiveArray::::from(vec![ + Some(-1), + Some(-1), + Some(2), + None, + None, + ])) as ArrayRef, + Arc::new(StringArray::from(vec![ + Some("hello"), + Some("bar"), + Some("world"), + None, + Some("foo"), + ])) as ArrayRef, + ]; + test_lex_sort_arrays(input, expected); +} +*/ diff --git a/tests/it/compute/sort.rs b/tests/it/compute/sort/mod.rs similarity index 99% rename from tests/it/compute/sort.rs rename to tests/it/compute/sort/mod.rs index 1f2df489150..a29d99e2986 100644 --- a/tests/it/compute/sort.rs +++ b/tests/it/compute/sort/mod.rs @@ -1,3 +1,5 @@ +mod lex_sort; + use arrow2::array::*; use arrow2::compute::sort::*; use arrow2::datatypes::*; diff --git a/tests/it/compute/take.rs b/tests/it/compute/take.rs new file mode 100644 index 00000000000..c5dfbc88493 --- /dev/null +++ b/tests/it/compute/take.rs @@ -0,0 +1,176 @@ +use std::sync::Arc; + +use arrow2::compute::take::{can_take, take}; +use arrow2::datatypes::{DataType, Field, IntervalUnit}; +use arrow2::error::Result; +use arrow2::{array::*, bitmap::MutableBitmap, types::NativeType}; + +fn test_take_primitive( + data: &[Option], + indices: &Int32Array, + expected_data: &[Option], + data_type: DataType, +) -> Result<()> +where + T: NativeType, +{ + let output = PrimitiveArray::::from(data).to(data_type.clone()); + let expected = PrimitiveArray::::from(expected_data).to(data_type); + let output = take(&output, indices)?; + assert_eq!(expected, output.as_ref()); + Ok(()) +} + +#[test] +fn test_take_primitive_non_null_indices() { + let indices = Int32Array::from_slice(&[0, 5, 3, 1, 4, 2]); + test_take_primitive::( + &[None, Some(2), Some(4), Some(6), Some(8), None], + &indices, + &[None, None, Some(6), Some(2), Some(8), Some(4)], + DataType::Int8, + ) + .unwrap(); + + test_take_primitive::( + &[Some(0), Some(2), Some(4), Some(6), Some(8), Some(10)], + &indices, + &[Some(0), Some(10), Some(6), Some(2), Some(8), Some(4)], + DataType::Int8, + ) + .unwrap(); +} + +#[test] +fn test_take_primitive_null_values() { + let indices = Int32Array::from(&[Some(0), None, Some(3), Some(1), Some(4), Some(2)]); + test_take_primitive::( + &[Some(0), Some(2), Some(4), Some(6), Some(8), Some(10)], + &indices, + &[Some(0), None, Some(6), Some(2), Some(8), Some(4)], + DataType::Int8, + ) + .unwrap(); + + test_take_primitive::( + &[None, Some(2), Some(4), Some(6), Some(8), Some(10)], + &indices, + &[None, None, Some(6), Some(2), Some(8), Some(4)], + DataType::Int8, + ) + .unwrap(); +} + +fn create_test_struct() -> StructArray { + let boolean = BooleanArray::from_slice(&[true, false, false, true]); + let int = Int32Array::from_slice(&[42, 28, 19, 31]); + let validity = vec![true, true, false, true] + .into_iter() + .collect::() + .into(); + let fields = vec![ + Field::new("a", DataType::Boolean, true), + Field::new("b", DataType::Int32, true), + ]; + StructArray::from_data( + DataType::Struct(fields), + vec![ + Arc::new(boolean) as Arc, + Arc::new(int) as Arc, + ], + validity, + ) +} + +#[test] +fn test_struct_with_nulls() { + let array = create_test_struct(); + + let indices = Int32Array::from(&[None, Some(3), Some(1), None, Some(0)]); + + let output = take(&array, &indices).unwrap(); + + let boolean = BooleanArray::from(&[None, Some(true), Some(false), None, Some(true)]); + let int = Int32Array::from(&[None, Some(31), Some(28), None, Some(42)]); + let validity = vec![false, true, true, false, true] + .into_iter() + .collect::() + .into(); + let expected = StructArray::from_data( + array.data_type().clone(), + vec![ + Arc::new(boolean) as Arc, + Arc::new(int) as Arc, + ], + validity, + ); + assert_eq!(expected, output.as_ref()); +} + +#[test] +fn consistency() { + use arrow2::array::new_null_array; + use arrow2::datatypes::DataType::*; + use arrow2::datatypes::TimeUnit; + + let datatypes = vec![ + Null, + Boolean, + UInt8, + UInt16, + UInt32, + UInt64, + Int8, + Int16, + Int32, + Int64, + Float32, + Float64, + Timestamp(TimeUnit::Second, None), + Timestamp(TimeUnit::Millisecond, None), + Timestamp(TimeUnit::Microsecond, None), + Timestamp(TimeUnit::Nanosecond, None), + Time64(TimeUnit::Microsecond), + Time64(TimeUnit::Nanosecond), + Interval(IntervalUnit::DayTime), + Interval(IntervalUnit::YearMonth), + Date32, + Time32(TimeUnit::Second), + Time32(TimeUnit::Millisecond), + Date64, + Utf8, + LargeUtf8, + Binary, + LargeBinary, + Duration(TimeUnit::Second), + Duration(TimeUnit::Millisecond), + Duration(TimeUnit::Microsecond), + Duration(TimeUnit::Nanosecond), + ]; + + datatypes.into_iter().for_each(|d1| { + let array = new_null_array(d1.clone(), 10); + let indices = Int32Array::from(&[Some(1), Some(2), None, Some(3)]); + if can_take(&d1) { + assert!(take(array.as_ref(), &indices).is_ok()); + } else { + assert!(take(array.as_ref(), &indices).is_err()); + } + }); +} + +#[test] +fn empty() { + let indices = Int32Array::from_slice(&[]); + let values = BooleanArray::from(vec![Some(true), Some(false)]); + let a = take(&values, &indices).unwrap(); + assert_eq!(a.len(), 0) +} + +#[test] +fn unsigned_take() { + let indices = UInt32Array::from_slice(&[]); + let values = BooleanArray::from(vec![Some(true), Some(false)]); + let a = take(&values, &indices).unwrap(); + assert_eq!(a.len(), 0) +}