You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@arrow.apache.org by al...@apache.org on 2021/11/10 11:40:34 UTC
[arrow-rs] branch master updated: add checker for appending i128 to
decimal builder (#928)
This is an automated email from the ASF dual-hosted git repository.
alamb 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 1945f6f add checker for appending i128 to decimal builder (#928)
1945f6f is described below
commit 1945f6f96551e501010a4578295456a1f9f335e9
Author: Kun Liu <li...@apache.org>
AuthorDate: Wed Nov 10 19:40:29 2021 +0800
add checker for appending i128 to decimal builder (#928)
* add check for appending i128 to decimal builder
* remove the ArrowError(DecimalError)
---
arrow/src/array/array_binary.rs | 35 +++++++++++++++-
arrow/src/array/builder.rs | 89 +++++++++++++++++++++++++++++++++++++++++
2 files changed, 123 insertions(+), 1 deletion(-)
diff --git a/arrow/src/array/array_binary.rs b/arrow/src/array/array_binary.rs
index 0592c04..ecf1850 100644
--- a/arrow/src/array/array_binary.rs
+++ b/arrow/src/array/array_binary.rs
@@ -1287,8 +1287,41 @@ mod tests {
}
#[test]
+ fn test_decimal_append_error_value() {
+ let mut decimal_builder = DecimalBuilder::new(10, 5, 3);
+ let mut result = decimal_builder.append_value(123456);
+ let mut error = result.unwrap_err();
+ assert_eq!(
+ "Invalid argument error: The value of 123456 i128 is not compatible with Decimal(5,3)",
+ error.to_string()
+ );
+ decimal_builder.append_value(12345).unwrap();
+ let arr = decimal_builder.finish();
+ assert_eq!("12.345", arr.value_as_string(0));
+
+ decimal_builder = DecimalBuilder::new(10, 2, 1);
+ result = decimal_builder.append_value(100);
+ error = result.unwrap_err();
+ assert_eq!(
+ "Invalid argument error: The value of 100 i128 is not compatible with Decimal(2,1)",
+ error.to_string()
+ );
+ decimal_builder.append_value(99).unwrap();
+ result = decimal_builder.append_value(-100);
+ error = result.unwrap_err();
+ assert_eq!(
+ "Invalid argument error: The value of -100 i128 is not compatible with Decimal(2,1)",
+ error.to_string()
+ );
+ decimal_builder.append_value(-99).unwrap();
+ let arr = decimal_builder.finish();
+ assert_eq!("9.9", arr.value_as_string(0));
+ assert_eq!("-9.9", arr.value_as_string(1));
+ }
+
+ #[test]
fn test_decimal_array_value_as_string() {
- let mut decimal_builder = DecimalBuilder::new(7, 5, 3);
+ let mut decimal_builder = DecimalBuilder::new(7, 6, 3);
for value in [123450, -123450, 100, -100, 10, -10, 0] {
decimal_builder.append_value(value).unwrap();
}
diff --git a/arrow/src/array/builder.rs b/arrow/src/array/builder.rs
index 60f76d9..d08816c 100644
--- a/arrow/src/array/builder.rs
+++ b/arrow/src/array/builder.rs
@@ -1118,6 +1118,87 @@ pub struct FixedSizeBinaryBuilder {
builder: FixedSizeListBuilder<UInt8Builder>,
}
+const MAX_DECIMAL_FOR_EACH_PRECISION: [i128; 38] = [
+ 9,
+ 99,
+ 999,
+ 9999,
+ 99999,
+ 999999,
+ 9999999,
+ 99999999,
+ 999999999,
+ 9999999999,
+ 99999999999,
+ 999999999999,
+ 9999999999999,
+ 99999999999999,
+ 999999999999999,
+ 9999999999999999,
+ 99999999999999999,
+ 999999999999999999,
+ 9999999999999999999,
+ 99999999999999999999,
+ 999999999999999999999,
+ 9999999999999999999999,
+ 99999999999999999999999,
+ 999999999999999999999999,
+ 9999999999999999999999999,
+ 99999999999999999999999999,
+ 999999999999999999999999999,
+ 9999999999999999999999999999,
+ 99999999999999999999999999999,
+ 999999999999999999999999999999,
+ 9999999999999999999999999999999,
+ 99999999999999999999999999999999,
+ 999999999999999999999999999999999,
+ 9999999999999999999999999999999999,
+ 99999999999999999999999999999999999,
+ 999999999999999999999999999999999999,
+ 9999999999999999999999999999999999999,
+ 170141183460469231731687303715884105727,
+];
+const MIN_DECIMAL_FOR_EACH_PRECISION: [i128; 38] = [
+ -9,
+ -99,
+ -999,
+ -9999,
+ -99999,
+ -999999,
+ -9999999,
+ -99999999,
+ -999999999,
+ -9999999999,
+ -99999999999,
+ -999999999999,
+ -9999999999999,
+ -99999999999999,
+ -999999999999999,
+ -9999999999999999,
+ -99999999999999999,
+ -999999999999999999,
+ -9999999999999999999,
+ -99999999999999999999,
+ -999999999999999999999,
+ -9999999999999999999999,
+ -99999999999999999999999,
+ -999999999999999999999999,
+ -9999999999999999999999999,
+ -99999999999999999999999999,
+ -999999999999999999999999999,
+ -9999999999999999999999999999,
+ -99999999999999999999999999999,
+ -999999999999999999999999999999,
+ -9999999999999999999999999999999,
+ -99999999999999999999999999999999,
+ -999999999999999999999999999999999,
+ -9999999999999999999999999999999999,
+ -99999999999999999999999999999999999,
+ -999999999999999999999999999999999999,
+ -9999999999999999999999999999999999999,
+ -170141183460469231731687303715884105728,
+];
+
///
/// Array Builder for [`DecimalArray`]
///
@@ -1431,6 +1512,14 @@ impl DecimalBuilder {
/// distinct array element.
#[inline]
pub fn append_value(&mut self, value: i128) -> Result<()> {
+ if value > MAX_DECIMAL_FOR_EACH_PRECISION[self.precision - 1]
+ || value < MIN_DECIMAL_FOR_EACH_PRECISION[self.precision - 1]
+ {
+ return Err(ArrowError::InvalidArgumentError(format!(
+ "The value of {} i128 is not compatible with Decimal({},{})",
+ value, self.precision, self.scale
+ )));
+ }
let value_as_bytes = Self::from_i128_to_fixed_size_bytes(
value,
self.builder.value_length() as usize,