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/09/09 18:52:08 UTC

[arrow-rs] branch cherry_pick_deb31a0e created (now 69f36cc)

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

alamb pushed a change to branch cherry_pick_deb31a0e
in repository https://gitbox.apache.org/repos/asf/arrow-rs.git.


      at 69f36cc  Fix decimal value_as_string (#722)

This branch includes the following new commits:

     new 69f36cc  Fix decimal value_as_string (#722)

The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


[arrow-rs] 01/01: Fix decimal value_as_string (#722)

Posted by al...@apache.org.
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 <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);