This is an automated email from the ASF dual-hosted git repository. alamb pushed a commit to branch cherry_pick_deb31a0e in repository https://gitbox.apache.org/repos/asf/arrow-rs.git
commit 69f36ccf37670ba106ab0a94066bad95a20f1130 Author: Sergii Mikhtoniuk <[email protected]> AuthorDate: Sun Aug 29 03:22:16 2021 -0700 Fix decimal value_as_string (#722) Fixes #710 --- arrow/src/array/array_binary.rs | 35 +++++++++++++++++++++++++++++++---- 1 file changed, 31 insertions(+), 4 deletions(-) diff --git a/arrow/src/array/array_binary.rs b/arrow/src/array/array_binary.rs index a88fb2c..b477fc6 100644 --- a/arrow/src/array/array_binary.rs +++ b/arrow/src/array/array_binary.rs @@ -744,12 +744,22 @@ impl DecimalArray { #[inline] pub fn value_as_string(&self, row: usize) -> String { - let decimal_string = self.value(row).to_string(); + let value = self.value(row); + let value_str = value.to_string(); + if self.scale == 0 { - decimal_string + value_str } else { - let splits = decimal_string.split_at(decimal_string.len() - self.scale); - format!("{}.{}", splits.0, splits.1) + let (sign, rest) = value_str.split_at(if value >= 0 { 0 } else { 1 }); + + if rest.len() > self.scale { + // Decimal separator is in the middle of the string + let (whole, decimal) = value_str.split_at(value_str.len() - self.scale); + format!("{}.{}", whole, decimal) + } else { + // String has to be padded + format!("{}0.{:0>width$}", sign, rest, width = self.scale) + } } } @@ -1241,6 +1251,23 @@ mod tests { } #[test] + fn test_decimal_array_value_as_string() { + let mut decimal_builder = DecimalBuilder::new(7, 5, 3); + for value in [123450, -123450, 100, -100, 10, -10, 0] { + decimal_builder.append_value(value).unwrap(); + } + let arr = decimal_builder.finish(); + + assert_eq!("123.450", arr.value_as_string(0)); + assert_eq!("-123.450", arr.value_as_string(1)); + assert_eq!("0.100", arr.value_as_string(2)); + assert_eq!("-0.100", arr.value_as_string(3)); + assert_eq!("0.010", arr.value_as_string(4)); + assert_eq!("-0.010", arr.value_as_string(5)); + assert_eq!("0.000", arr.value_as_string(6)); + } + + #[test] fn test_decimal_array_fmt_debug() { let values: Vec<i128> = vec![8887000000, -8887000000]; let mut decimal_builder = DecimalBuilder::new(3, 23, 6);
