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/08/29 10:22:21 UTC

[arrow-rs] branch master updated: Fix decimal value_as_string (#722)

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 deb31a0  Fix decimal value_as_string (#722)
deb31a0 is described below

commit deb31a0e9df45e0aa4f8e12e57ced9d0ce8c579c
Author: Sergii Mikhtoniuk <mi...@gmail.com>
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);