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

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


The following commit(s) were added to refs/heads/main by this push:
     new 5d087d0d62 fix: Correctly decode zero-valued Decimal256s in 
integration tests (#10873)
5d087d0d62 is described below

commit 5d087d0d627eef30eb89eec8866bdfb0267467b8
Author: Neil Conway <[email protected]>
AuthorDate: Wed Aug 26 22:14:34 2026 -0400

    fix: Correctly decode zero-valued Decimal256s in integration tests (#10873)
    
    # Which issue does this PR close?
    
    - Closes #10872.
    
    # Rationale for this change
    
    The Decimal256 branch of `array_from_json` didn't handle zeros
    correctly. It builds a little-endian two's-complement buffer as part of
    converting string-valued decimals into native Decimal256 values, but for
    `0` inputs exactly, it used the wrong fill bytes (it used `0xFF` instead
    of `0`). This lead to `0` being decoded as `-256`.
    
    # What changes are included in this PR?
    
    * Fix decoding bug (use `0` fill bytes for `0` input values)
    * Add unit test
    
    # Are these changes tested?
    
    Yes, new test added.
    
    # Are there any user-facing changes?
    
    No.
---
 arrow-integration-test/src/lib.rs | 37 ++++++++++++++++++++++++++++++++++---
 1 file changed, 34 insertions(+), 3 deletions(-)

diff --git a/arrow-integration-test/src/lib.rs 
b/arrow-integration-test/src/lib.rs
index 64860a7ff4..4636aafd59 100644
--- a/arrow-integration-test/src/lib.rs
+++ b/arrow-integration-test/src/lib.rs
@@ -962,10 +962,13 @@ pub fn array_from_json(
                         let str = value.as_str().unwrap();
                         let integer = BigInt::parse_bytes(str.as_bytes(), 
10).unwrap();
                         let integer_bytes = integer.to_signed_bytes_le();
-                        let mut bytes = if integer.is_positive() {
-                            [0_u8; 32]
-                        } else {
+                        // Sign-extend the minimal-length two's-complement
+                        // encoding to the full 32 bytes: 0x00 fill for
+                        // non-negative values, 0xFF for negative ones.
+                        let mut bytes = if integer.is_negative() {
                             [255_u8; 32]
+                        } else {
+                            [0_u8; 32]
                         };
                         
bytes[0..integer_bytes.len()].copy_from_slice(integer_bytes.as_slice());
                         b.append_value(i256::from_le_bytes(bytes));
@@ -1269,6 +1272,34 @@ impl ArrowJsonBatch {
 mod tests {
     use super::*;
 
+    #[test]
+    fn test_decimal256_from_json() {
+        let field = Field::new("c", DataType::Decimal256(76, 0), false);
+        let col: ArrowJsonColumn = serde_json::from_str(
+            r#"{
+                "name": "c",
+                "count": 5,
+                "VALIDITY": [1, 1, 1, 1, 1],
+                "DATA": [
+                    "0",
+                    "1",
+                    "-1",
+                    "123456789012345678901234567890",
+                    "-123456789012345678901234567890"
+                ]
+            }"#,
+        )
+        .unwrap();
+        let arr = array_from_json(&field, col, None).unwrap();
+        let arr = arr.as_any().downcast_ref::<Decimal256Array>().unwrap();
+        assert_eq!(arr.value(0), i256::ZERO);
+        assert_eq!(arr.value(1), i256::from_i128(1));
+        assert_eq!(arr.value(2), i256::from_i128(-1));
+        let big = i256::from_string("123456789012345678901234567890").unwrap();
+        assert_eq!(arr.value(3), big);
+        assert_eq!(arr.value(4), i256::ZERO - big);
+    }
+
     #[test]
     fn test_schema_equality() {
         let json = r#"

Reply via email to