You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@arrow.apache.org by tu...@apache.org on 2022/07/15 15:16:51 UTC

[arrow-rs] branch master updated: Add support of converting `FixedSizeBinaryArray` to `DecimalArray` (#2041)

This is an automated email from the ASF dual-hosted git repository.

tustvold pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/arrow-rs.git


The following commit(s) were added to refs/heads/master by this push:
     new 9d8f0c934 Add support of converting `FixedSizeBinaryArray` to `DecimalArray` (#2041)
9d8f0c934 is described below

commit 9d8f0c934a27cd57d36ab4224f232ddf6addf03d
Author: Remzi Yang <59...@users.noreply.github.com>
AuthorDate: Fri Jul 15 23:16:46 2022 +0800

    Add support of converting `FixedSizeBinaryArray` to `DecimalArray` (#2041)
    
    * Add support of converting FixedSizeBinaryArray to Decimal
    
    Signed-off-by: remzi <13...@gmail.com>
    
    * Update arrow/src/array/array_decimal.rs
    
    Co-authored-by: Raphael Taylor-Davies <17...@users.noreply.github.com>
    
    * use better builder API
    
    Signed-off-by: remzi <13...@gmail.com>
    
    * trigger CI
    
    Signed-off-by: remzi <13...@gmail.com>
    
    Co-authored-by: Raphael Taylor-Davies <17...@users.noreply.github.com>
---
 arrow/src/array/array_decimal.rs | 62 +++++++++++++++++++++++++++++++++++++++-
 1 file changed, 61 insertions(+), 1 deletion(-)

diff --git a/arrow/src/array/array_decimal.rs b/arrow/src/array/array_decimal.rs
index 15863cfff..ccb1fe052 100644
--- a/arrow/src/array/array_decimal.rs
+++ b/arrow/src/array/array_decimal.rs
@@ -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;
@@ -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,
@@ -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)