Skip to content

Commit

Permalink
Add support of converting FixedSizeBinaryArray to DecimalArray (#…
Browse files Browse the repository at this point in the history
…2041)

* Add support of converting FixedSizeBinaryArray to Decimal

Signed-off-by: remzi <[email protected]>

* Update arrow/src/array/array_decimal.rs

Co-authored-by: Raphael Taylor-Davies <[email protected]>

* use better builder API

Signed-off-by: remzi <[email protected]>

* trigger CI

Signed-off-by: remzi <[email protected]>

Co-authored-by: Raphael Taylor-Davies <[email protected]>
  • Loading branch information
HaoYang670 and tustvold authored Jul 15, 2022
1 parent 7fff23f commit 9d8f0c9
Showing 1 changed file with 61 additions and 1 deletion.
62 changes: 61 additions & 1 deletion arrow/src/array/array_decimal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,10 @@ use std::convert::From;
use std::fmt;
use std::{any::Any, iter::FromIterator};

use super::BooleanBufferBuilder;
use super::{
array::print_long_array, raw_pointer::RawPtrBox, Array, ArrayData, FixedSizeListArray,
};
use super::{BooleanBufferBuilder, FixedSizeBinaryArray};
pub use crate::array::DecimalIter;
use crate::buffer::Buffer;
use crate::datatypes::DataType;
Expand Down Expand Up @@ -148,6 +148,30 @@ pub trait BasicDecimalArray<T: BasicDecimal, U: From<ArrayData>>:
self.value(row).to_string()
}

/// Build a decimal array from [`FixedSizeBinaryArray`].
///
/// NB: This function does not validate that each value is in the permissible
/// range for a decimal
fn from_fixed_size_binary_array(
v: FixedSizeBinaryArray,
precision: usize,
scale: usize,
) -> U {
assert!(
v.value_length() == Self::VALUE_LENGTH,
"Value length of the array ({}) must equal to the byte width of the decimal ({})",
v.value_length(),
Self::VALUE_LENGTH,
);
let builder = v
.into_data()
.into_builder()
.data_type(DataType::Decimal(precision, scale));

let array_data = unsafe { builder.build_unchecked() };
U::from(array_data)
}

fn from_fixed_size_list_array(
v: FixedSizeListArray,
precision: usize,
Expand Down Expand Up @@ -646,6 +670,42 @@ mod tests {
);
}

#[test]
fn test_decimal_array_from_fixed_size_binary() {
let value_data = ArrayData::builder(DataType::FixedSizeBinary(16))
.offset(1)
.len(3)
.add_buffer(Buffer::from_slice_ref(&[99999_i128, 2, 34, 560]))
.null_bit_buffer(Some(Buffer::from_slice_ref(&[0b1010])))
.build()
.unwrap();

let binary_array = FixedSizeBinaryArray::from(value_data);
let decimal = DecimalArray::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());
assert!(decimal.is_null(1));
assert_eq!(decimal.value_as_string(2), "56.0".to_string());
}

#[test]
#[should_panic(
expected = "Value length of the array (8) must equal to the byte width of the decimal (16)"
)]
fn test_decimal_array_from_fixed_size_binary_wrong_length() {
let value_data = ArrayData::builder(DataType::FixedSizeBinary(8))
.offset(1)
.len(3)
.add_buffer(Buffer::from_slice_ref(&[99999_i64, 2, 34, 560]))
.null_bit_buffer(Some(Buffer::from_slice_ref(&[0b1010])))
.build()
.unwrap();

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

#[test]
fn test_decimal_array_from_fixed_size_list() {
let value_data = ArrayData::builder(DataType::UInt8)
Expand Down

0 comments on commit 9d8f0c9

Please sign in to comment.