Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Define Decimal128Builder and Decimal128Array #2102

Merged
merged 1 commit into from Jul 19, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion arrow/src/array/array.rs
Expand Up @@ -403,7 +403,7 @@ pub fn make_array(data: ArrayData) -> ArrayRef {
dt => panic!("Unexpected dictionary key type {:?}", dt),
},
DataType::Null => Arc::new(NullArray::from(data)) as ArrayRef,
DataType::Decimal(_, _) => Arc::new(DecimalArray::from(data)) as ArrayRef,
DataType::Decimal(_, _) => Arc::new(Decimal128Array::from(data)) as ArrayRef,
dt => panic!("Unexpected data type {:?}", dt),
}
}
Expand Down
79 changes: 40 additions & 39 deletions arrow/src/array/array_decimal.rs
Expand Up @@ -34,17 +34,17 @@ use crate::datatypes::{
use crate::error::{ArrowError, Result};
use crate::util::decimal::{BasicDecimal, Decimal128, Decimal256};

/// `DecimalArray` stores fixed width decimal numbers,
/// `Decimal128Array` stores fixed width decimal numbers,
/// with a fixed precision and scale.
///
/// # Examples
///
/// ```
/// use arrow::array::{Array, BasicDecimalArray, DecimalArray};
/// use arrow::array::{Array, BasicDecimalArray, Decimal128Array};
/// use arrow::datatypes::DataType;
///
/// // Create a DecimalArray with the default precision and scale
/// let decimal_array: DecimalArray = vec![
/// let decimal_array: Decimal128Array = vec![
/// Some(8_887_000_000),
/// None,
/// Some(-8_887_000_000),
Expand All @@ -68,7 +68,7 @@ use crate::util::decimal::{BasicDecimal, Decimal128, Decimal256};
/// assert_eq!(6, decimal_array.scale());
/// ```
///
pub struct DecimalArray {
pub struct Decimal128Array {
data: ArrayData,
value_data: RawPtrBox<u8>,
precision: usize,
Expand Down Expand Up @@ -186,13 +186,13 @@ pub trait BasicDecimalArray<T: BasicDecimal, U: From<ArrayData>>:
assert_eq!(
child_data.child_data().len(),
0,
"DecimalArray can only be created from list array of u8 values \
"Decimal128Array can only be created from list array of u8 values \
(i.e. FixedSizeList<PrimitiveArray<u8>>)."
);
assert_eq!(
child_data.data_type(),
&DataType::UInt8,
"DecimalArray can only be created from FixedSizeList<u8> arrays, mismatched data types."
"Decimal128Array can only be created from FixedSizeList<u8> arrays, mismatched data types."
);

let list_offset = v.offset();
Expand All @@ -208,7 +208,7 @@ pub trait BasicDecimalArray<T: BasicDecimal, U: From<ArrayData>>:
}
}

impl BasicDecimalArray<Decimal128, DecimalArray> for DecimalArray {
impl BasicDecimalArray<Decimal128, Decimal128Array> for Decimal128Array {
const VALUE_LENGTH: i32 = 16;

fn data(&self) -> &ArrayData {
Expand Down Expand Up @@ -240,8 +240,8 @@ impl BasicDecimalArray<Decimal256, Decimal256Array> for Decimal256Array {
}
}

impl DecimalArray {
/// Creates a [DecimalArray] with default precision and scale,
impl Decimal128Array {
/// Creates a [Decimal128Array] with default precision and scale,
/// based on an iterator of `i128` values without nulls
pub fn from_iter_values<I: IntoIterator<Item = i128>>(iter: I) -> Self {
let val_buf: Buffer = iter.into_iter().collect();
Expand All @@ -256,10 +256,10 @@ impl DecimalArray {
vec![],
)
};
DecimalArray::from(data)
Decimal128Array::from(data)
}

/// Returns a DecimalArray with the same data as self, with the
/// Returns a Decimal128Array with the same data as self, with the
/// specified precision.
///
/// Returns an Error if:
Expand Down Expand Up @@ -319,12 +319,12 @@ impl DecimalArray {
}
}

impl From<ArrayData> for DecimalArray {
impl From<ArrayData> for Decimal128Array {
fn from(data: ArrayData) -> Self {
assert_eq!(
data.buffers().len(),
1,
"DecimalArray data should contain 1 buffer only (values)"
"Decimal128Array data should contain 1 buffer only (values)"
);
let values = data.buffers()[0].as_ptr();
let (precision, scale) = match data.data_type() {
Expand All @@ -345,7 +345,7 @@ impl From<ArrayData> for Decimal256Array {
assert_eq!(
data.buffers().len(),
1,
"DecimalArray data should contain 1 buffer only (values)"
"Decimal128Array data should contain 1 buffer only (values)"
);
let values = data.buffers()[0].as_ptr();
let (precision, scale) = match data.data_type() {
Expand All @@ -361,7 +361,7 @@ impl From<ArrayData> for Decimal256Array {
}
}

impl<'a> IntoIterator for &'a DecimalArray {
impl<'a> IntoIterator for &'a Decimal128Array {
type Item = Option<i128>;
type IntoIter = DecimalIter<'a>;

Expand All @@ -370,14 +370,14 @@ impl<'a> IntoIterator for &'a DecimalArray {
}
}

impl<'a> DecimalArray {
impl<'a> Decimal128Array {
/// constructs a new iterator
pub fn iter(&'a self) -> DecimalIter<'a> {
DecimalIter::new(self)
}
}

impl<Ptr: Borrow<Option<i128>>> FromIterator<Ptr> for DecimalArray {
impl<Ptr: Borrow<Option<i128>>> FromIterator<Ptr> for Decimal128Array {
fn from_iter<I: IntoIterator<Item = Ptr>>(iter: I) -> Self {
let iter = iter.into_iter();
let (lower, upper) = iter.size_hint();
Expand Down Expand Up @@ -409,7 +409,7 @@ impl<Ptr: Borrow<Option<i128>>> FromIterator<Ptr> for DecimalArray {
vec![],
)
};
DecimalArray::from(data)
Decimal128Array::from(data)
}
}

Expand Down Expand Up @@ -459,12 +459,12 @@ macro_rules! def_decimal_array {
};
}

def_decimal_array!(DecimalArray, "DecimalArray");
def_decimal_array!(Decimal128Array, "Decimal128Array");
def_decimal_array!(Decimal256Array, "Decimal256Array");

#[cfg(test)]
mod tests {
use crate::{array::DecimalBuilder, datatypes::Field};
use crate::{array::Decimal128Builder, datatypes::Field};

use super::*;

Expand All @@ -481,7 +481,7 @@ mod tests {
.add_buffer(Buffer::from(&values[..]))
.build()
.unwrap();
let decimal_array = DecimalArray::from(array_data);
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());
assert_eq!(16, decimal_array.value_length());
Expand All @@ -490,7 +490,7 @@ mod tests {
#[test]
#[cfg(not(feature = "force_validate"))]
fn test_decimal_append_error_value() {
let mut decimal_builder = DecimalBuilder::new(10, 5, 3);
let mut decimal_builder = Decimal128Builder::new(10, 5, 3);
let mut result = decimal_builder.append_value(123456);
let mut error = result.unwrap_err();
assert_eq!(
Expand All @@ -507,7 +507,7 @@ mod tests {
let arr = decimal_builder.finish();
assert_eq!("12.345", arr.value_as_string(1));

decimal_builder = DecimalBuilder::new(10, 2, 1);
decimal_builder = Decimal128Builder::new(10, 2, 1);
result = decimal_builder.append_value(100);
error = result.unwrap_err();
assert_eq!(
Expand All @@ -531,7 +531,7 @@ mod tests {

#[test]
fn test_decimal_from_iter_values() {
let array = DecimalArray::from_iter_values(vec![-100, 0, 101].into_iter());
let array = Decimal128Array::from_iter_values(vec![-100, 0, 101].into_iter());
assert_eq!(array.len(), 3);
assert_eq!(array.data_type(), &DataType::Decimal(38, 10));
assert_eq!(-100_i128, array.value(0).into());
Expand All @@ -544,7 +544,8 @@ mod tests {

#[test]
fn test_decimal_from_iter() {
let array: DecimalArray = vec![Some(-100), None, Some(101)].into_iter().collect();
let array: Decimal128Array =
vec![Some(-100), None, Some(101)].into_iter().collect();
assert_eq!(array.len(), 3);
assert_eq!(array.data_type(), &DataType::Decimal(38, 10));
assert_eq!(-100_i128, array.value(0).into());
Expand All @@ -557,7 +558,7 @@ mod tests {
#[test]
fn test_decimal_iter() {
let data = vec![Some(-100), None, Some(101)];
let array: DecimalArray = data.clone().into_iter().collect();
let array: Decimal128Array = data.clone().into_iter().collect();

let collected: Vec<_> = array.iter().collect();
assert_eq!(data, collected);
Expand All @@ -566,7 +567,7 @@ mod tests {
#[test]
fn test_decimal_into_iter() {
let data = vec![Some(-100), None, Some(101)];
let array: DecimalArray = data.clone().into_iter().collect();
let array: Decimal128Array = data.clone().into_iter().collect();

let collected: Vec<_> = array.into_iter().collect();
assert_eq!(data, collected);
Expand All @@ -575,7 +576,7 @@ mod tests {
#[test]
fn test_decimal_iter_sized() {
let data = vec![Some(-100), None, Some(101)];
let array: DecimalArray = data.into_iter().collect();
let array: Decimal128Array = data.into_iter().collect();
let mut iter = array.into_iter();

// is exact sized
Expand All @@ -597,7 +598,7 @@ mod tests {
let arr = [123450, -123450, 100, -100, 10, -10, 0]
.into_iter()
.map(Some)
.collect::<DecimalArray>()
.collect::<Decimal128Array>()
.with_precision_and_scale(6, 3)
.unwrap();

Expand All @@ -612,7 +613,7 @@ mod tests {

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

Expand All @@ -631,7 +632,7 @@ mod tests {
expected = "-123223423432432 is too small to store in a Decimal of precision 5. Min is -99999"
)]
fn test_decimal_array_with_precision_and_scale_out_of_range() {
DecimalArray::from_iter_values([12345, 456, 7890, -123223423432432])
Decimal128Array::from_iter_values([12345, 456, 7890, -123223423432432])
// precision is too small to hold value
.with_precision_and_scale(5, 2)
.unwrap();
Expand All @@ -640,23 +641,23 @@ mod tests {
#[test]
#[should_panic(expected = "precision 40 is greater than max 38")]
fn test_decimal_array_with_precision_and_scale_invalid_precision() {
DecimalArray::from_iter_values([12345, 456])
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() {
DecimalArray::from_iter_values([12345, 456])
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() {
DecimalArray::from_iter_values([12345, 456])
Decimal128Array::from_iter_values([12345, 456])
.with_precision_and_scale(4, 10)
.unwrap();
}
Expand All @@ -665,12 +666,12 @@ mod tests {
fn test_decimal_array_fmt_debug() {
let arr = [Some(8887000000), Some(-8887000000), None]
.iter()
.collect::<DecimalArray>()
.collect::<Decimal128Array>()
.with_precision_and_scale(23, 6)
.unwrap();

assert_eq!(
"DecimalArray<23, 6>\n[\n 8887.000000,\n -8887.000000,\n null,\n]",
"Decimal128Array<23, 6>\n[\n 8887.000000,\n -8887.000000,\n null,\n]",
format!("{:?}", arr)
);
}
Expand All @@ -686,7 +687,7 @@ mod tests {
.unwrap();

let binary_array = FixedSizeBinaryArray::from(value_data);
let decimal = DecimalArray::from_fixed_size_binary_array(binary_array, 38, 1);
let decimal = Decimal128Array::from_fixed_size_binary_array(binary_array, 38, 1);

assert_eq!(decimal.len(), 3);
assert_eq!(decimal.value_as_string(0), "0.2".to_string());
Expand All @@ -708,7 +709,7 @@ mod tests {
.unwrap();

let binary_array = FixedSizeBinaryArray::from(value_data);
let _ = DecimalArray::from_fixed_size_binary_array(binary_array, 38, 1);
let _ = Decimal128Array::from_fixed_size_binary_array(binary_array, 38, 1);
}

#[test]
Expand Down Expand Up @@ -736,7 +737,7 @@ mod tests {
.build()
.unwrap();
let list_array = FixedSizeListArray::from(list_data);
let decimal = DecimalArray::from_fixed_size_list_array(list_array, 38, 0);
let decimal = Decimal128Array::from_fixed_size_list_array(list_array, 38, 0);

assert_eq!(decimal.len(), 2);
assert!(decimal.is_null(0));
Expand Down