Skip to content

Commit

Permalink
Add decimal array tests back
Browse files Browse the repository at this point in the history
  • Loading branch information
viirya committed Oct 12, 2022
1 parent fdf1022 commit 89889be
Showing 1 changed file with 246 additions and 0 deletions.
246 changes: 246 additions & 0 deletions arrow-array/src/array/primitive_array.rs
Expand Up @@ -1007,6 +1007,7 @@ impl<T: DecimalType + ArrowPrimitiveType> PrimitiveArray<T> {
#[cfg(test)]
mod tests {
use super::*;
use crate::builder::{Decimal128Builder, Decimal256Builder};
use crate::BooleanArray;

#[test]
Expand Down Expand Up @@ -1561,4 +1562,249 @@ mod tests {
let array = PrimitiveArray::<Decimal256Type>::from(array.data().clone());
assert_eq!(array.values(), &values);
}

#[test]
fn test_decimal_array() {
// let val_8887: [u8; 16] = [192, 219, 180, 17, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
// let val_neg_8887: [u8; 16] = [64, 36, 75, 238, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255];
let values: [u8; 32] = [
192, 219, 180, 17, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64, 36, 75, 238, 253,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
];
let array_data = ArrayData::builder(DataType::Decimal128(38, 6))
.len(2)
.add_buffer(Buffer::from(&values[..]))
.build()
.unwrap();
let decimal_array = Decimal128Array::from(array_data);
assert_eq!(8_887_000_000_i128, decimal_array.value(0).into());
assert_eq!(-8_887_000_000_i128, decimal_array.value(1).into());
}

#[test]
#[cfg(not(feature = "force_validate"))]
fn test_decimal_append_error_value() {
let mut decimal_builder = Decimal128Builder::with_capacity(10);
decimal_builder.append_value(123456);
let result = decimal_builder.finish().with_precision_and_scale(5, 3);
let mut error = result.unwrap_err();
assert_eq!(
"Invalid argument error: 123456 is too large to store in a Decimal128 of precision 5. Max is 99999",
error.to_string()
);

decimal_builder = Decimal128Builder::with_capacity(10);
decimal_builder.append_value(123456);
decimal_builder.append_value(12345);
let result = unsafe {
decimal_builder
.finish()
.unchecked_with_precision_and_scale(5, 3)
};
assert!(result.is_ok());
let arr = result.unwrap();
assert_eq!("12.345", arr.value_as_string(1).unwrap());

decimal_builder = Decimal128Builder::new();
decimal_builder.append_value(100);
let result = decimal_builder.finish().with_precision_and_scale(2, 1);
error = result.unwrap_err();
assert_eq!(
"Invalid argument error: 100 is too large to store in a Decimal128 of precision 2. Max is 99",
error.to_string()
);

decimal_builder = Decimal128Builder::new();
decimal_builder.append_value(100);
decimal_builder.append_value(99);
decimal_builder.append_value(-100);
decimal_builder.append_value(-99);
let result = unsafe {
decimal_builder
.finish()
.unchecked_with_precision_and_scale(2, 1)
};
assert!(result.is_ok());
let arr = result.unwrap();
assert_eq!("9.9", arr.value_as_string(1).unwrap());
assert_eq!("-9.9", arr.value_as_string(3).unwrap());
}

#[test]
fn test_decimal_from_iter_values() {
let array = Decimal128Array::from_iter_values(vec![-100, 0, 101].into_iter());
assert_eq!(array.len(), 3);
assert_eq!(array.data_type(), &DataType::Decimal128(38, 10));
assert_eq!(-100_i128, array.value(0).into());
assert!(!array.is_null(0));
assert_eq!(0_i128, array.value(1).into());
assert!(!array.is_null(1));
assert_eq!(101_i128, array.value(2).into());
assert!(!array.is_null(2));
}

#[test]
fn test_decimal_from_iter() {
let array: Decimal128Array =
vec![Some(-100), None, Some(101)].into_iter().collect();
assert_eq!(array.len(), 3);
assert_eq!(array.data_type(), &DataType::Decimal128(38, 10));
assert_eq!(-100_i128, array.value(0).into());
assert!(!array.is_null(0));
assert!(array.is_null(1));
assert_eq!(101_i128, array.value(2).into());
assert!(!array.is_null(2));
}

#[test]
fn test_decimal_iter_sized() {
let data = vec![Some(-100), None, Some(101)];
let array: Decimal128Array = data.into_iter().collect();
let mut iter = array.into_iter();

// is exact sized
assert_eq!(array.len(), 3);

// size_hint is reported correctly
assert_eq!(iter.size_hint(), (3, Some(3)));
iter.next().unwrap();
assert_eq!(iter.size_hint(), (2, Some(2)));
iter.next().unwrap();
iter.next().unwrap();
assert_eq!(iter.size_hint(), (0, Some(0)));
assert!(iter.next().is_none());
assert_eq!(iter.size_hint(), (0, Some(0)));
}

#[test]
fn test_decimal_array_value_as_string() {
let arr = [123450, -123450, 100, -100, 10, -10, 0]
.into_iter()
.map(Some)
.collect::<Decimal128Array>()
.with_precision_and_scale(6, 3)
.unwrap();

assert_eq!("123.450", arr.value_as_string(0).unwrap());
assert_eq!("-123.450", arr.value_as_string(1).unwrap());
assert_eq!("0.100", arr.value_as_string(2).unwrap());
assert_eq!("-0.100", arr.value_as_string(3).unwrap());
assert_eq!("0.010", arr.value_as_string(4).unwrap());
assert_eq!("-0.010", arr.value_as_string(5).unwrap());
assert_eq!("0.000", arr.value_as_string(6).unwrap());
}

#[test]
fn test_decimal_array_with_precision_and_scale() {
let arr = Decimal128Array::from_iter_values([12345, 456, 7890, -123223423432432])
.with_precision_and_scale(20, 2)
.unwrap();

assert_eq!(arr.data_type(), &DataType::Decimal128(20, 2));
assert_eq!(arr.precision().unwrap(), 20);
assert_eq!(arr.scale().unwrap(), 2);

let actual: Vec<_> = (0..arr.len())
.map(|i| arr.value_as_string(i).unwrap())
.collect();
let expected = vec!["123.45", "4.56", "78.90", "-1232234234324.32"];

assert_eq!(actual, expected);
}

#[test]
#[should_panic(
expected = "-123223423432432 is too small to store in a Decimal128 of precision 5. Min is -99999"
)]
fn test_decimal_array_with_precision_and_scale_out_of_range() {
Decimal128Array::from_iter_values([12345, 456, 7890, -123223423432432])
// precision is too small to hold value
.with_precision_and_scale(5, 2)
.unwrap();
}

#[test]
#[should_panic(expected = "precision 40 is greater than max 38")]
fn test_decimal_array_with_precision_and_scale_invalid_precision() {
Decimal128Array::from_iter_values([12345, 456])
.with_precision_and_scale(40, 2)
.unwrap();
}

#[test]
#[should_panic(expected = "scale 40 is greater than max 38")]
fn test_decimal_array_with_precision_and_scale_invalid_scale() {
Decimal128Array::from_iter_values([12345, 456])
.with_precision_and_scale(20, 40)
.unwrap();
}

#[test]
#[should_panic(expected = "scale 10 is greater than precision 4")]
fn test_decimal_array_with_precision_and_scale_invalid_precision_and_scale() {
Decimal128Array::from_iter_values([12345, 456])
.with_precision_and_scale(4, 10)
.unwrap();
}

#[test]
fn test_decimal256_iter() {
let mut builder = Decimal256Builder::with_capacity(30);
let decimal1 = i256::from_i128(12345);
builder.append_value(decimal1);

builder.append_null();

let decimal2 = i256::from_i128(56789);
builder.append_value(decimal2);

let array: Decimal256Array =
builder.finish().with_precision_and_scale(76, 6).unwrap();

let collected: Vec<_> = array.iter().collect();
assert_eq!(vec![Some(decimal1), None, Some(decimal2)], collected);
}

#[test]
fn test_from_iter_decimal256array() {
let value1 = i256::from_i128(12345);
let value2 = i256::from_i128(56789);

let mut array: Decimal256Array =
vec![Some(value1.clone()), None, Some(value2.clone())]
.into_iter()
.collect();
array = array.with_precision_and_scale(76, 10).unwrap();
assert_eq!(array.len(), 3);
assert_eq!(array.data_type(), &DataType::Decimal256(76, 10));
assert_eq!(value1, array.value(0));
assert!(!array.is_null(0));
assert!(array.is_null(1));
assert_eq!(value2, array.value(2));
assert!(!array.is_null(2));
}

#[test]
fn test_from_iter_decimal128array() {
let mut array: Decimal128Array =
vec![Some(-100), None, Some(101)].into_iter().collect();
array = array.with_precision_and_scale(38, 10).unwrap();
assert_eq!(array.len(), 3);
assert_eq!(array.data_type(), &DataType::Decimal128(38, 10));
assert_eq!(-100_i128, array.value(0).into());
assert!(!array.is_null(0));
assert!(array.is_null(1));
assert_eq!(101_i128, array.value(2).into());
assert!(!array.is_null(2));
}

#[test]
#[should_panic(
expected = "Trying to access an element at index 4 from a PrimitiveArray of length 3"
)]
fn test_fixed_size_binary_array_get_value_index_out_of_bound() {
let array = Decimal128Array::from_iter_values(vec![-100, 0, 101].into_iter());

array.value(4);
}
}

0 comments on commit 89889be

Please sign in to comment.