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

github-merge-queue[bot] pushed a commit to branch 
gh-readonly-queue/main/pr-11544-497bd538e8886246a7002b941ed305b9b870f10c
in repository https://gitbox.apache.org/repos/asf/arrow-rs.git

commit 7d04f36df412ac6177fa2fc768e8215089899581
Author: Shawn Chang <[email protected]>
AuthorDate: Thu Oct 15 03:55:07 2026 +0000

    fix(parquet): Fix physical type for precision-one decimals (#11544)
    
    # Which issue does this PR close?
    
    No linked issue.
    
    # Rationale for this change
    
    Decimal precision 1 was incorrectly mapped to Parquet INT64 because the
    INT32 physical-type range used an exclusive lower bound, even though
    precisions 1 through 9 fit in INT32. This corrects the generated Parquet
    physical schema so a precision-one decimal is written as INT32.
    
    # What changes are included in this PR?
    
    A one-line boundary correction in the Arrow-to-Parquet decimal mapping
    (exclusive `> 1` lower bound changed to inclusive `>= 1`), plus a
    regression test generalized into a table-driven test.
    
    # Are these changes tested?
    
    Yes. The table-driven regression test covers all three decimal
    physical-type branches and their boundaries: INT32 for precisions 1–9,
    INT64 for precisions 10–18, and FIXED_LEN_BYTE_ARRAY for precisions
    greater than 18.
    
    # Are there any significant user-facing changes?
    
    No significant API or compatibility changes. This corrects the generated
    Parquet physical schema for precision-one decimals.
---
 parquet/src/arrow/schema/mod.rs | 37 ++++++++++++++++++++++++++++++++++++-
 1 file changed, 36 insertions(+), 1 deletion(-)

diff --git a/parquet/src/arrow/schema/mod.rs b/parquet/src/arrow/schema/mod.rs
index 4189c3ab0f..968571cbb6 100644
--- a/parquet/src/arrow/schema/mod.rs
+++ b/parquet/src/arrow/schema/mod.rs
@@ -744,7 +744,7 @@ fn arrow_to_parquet_type(field: &Field, coerce_types: bool) 
-> Result<Type> {
         | DataType::Decimal256(precision, scale) => {
             // Decimal precision determines the Parquet physical type to use.
             // Following the: 
https://github.com/apache/parquet-format/blob/master/LogicalTypes.md#decimal
-            let (physical_type, length) = if *precision > 1 && *precision <= 9 
{
+            let (physical_type, length) = if *precision >= 1 && *precision <= 
9 {
                 (PhysicalType::INT32, -1)
             } else if *precision <= 18 {
                 (PhysicalType::INT64, -1)
@@ -977,6 +977,41 @@ mod tests {
         assert_eq!(&arrow_fields, converted_arrow_schema.fields());
     }
 
+    #[test]
+    fn test_decimal_precision_physical_types() {
+        let cases = [
+            (1, PhysicalType::INT32, None),
+            (9, PhysicalType::INT32, None),
+            (10, PhysicalType::INT64, None),
+            (18, PhysicalType::INT64, None),
+            (19, PhysicalType::FIXED_LEN_BYTE_ARRAY, Some(9)),
+            (38, PhysicalType::FIXED_LEN_BYTE_ARRAY, Some(16)),
+        ];
+
+        for (precision, expected_type, expected_length) in cases {
+            let arrow_schema = Schema::new(vec![Field::new(
+                "decimal",
+                DataType::Decimal128(precision, 0),
+                false,
+            )]);
+            let parquet_schema = 
ArrowSchemaConverter::new().convert(&arrow_schema).unwrap();
+            let column = parquet_schema.column(0);
+
+            assert_eq!(
+                column.physical_type(),
+                expected_type,
+                "precision {precision}"
+            );
+            if let Some(expected_length) = expected_length {
+                assert_eq!(
+                    column.type_length(),
+                    expected_length,
+                    "precision {precision}"
+                );
+            }
+        }
+    }
+
     #[test]
     fn test_byte_array_fields() {
         let message_type = "

Reply via email to