You are viewing a plain text version of this content. The canonical link for it is here.
Posted to github@arrow.apache.org by "snoopuppy582 (via GitHub)" <gi...@apache.org> on 2026/09/05 10:25:58 UTC

[PR] Avoid overflow in decimal precision and scale arithmetic [arrow-rs]

snoopuppy582 opened a new pull request, #10996:
URL: https://github.com/apache/arrow-rs/pull/10996

   # Which issue does this PR close?
   
   Closes #10978.
   
   # Rationale for this change
   
   Valid negative decimal scales can overflow `i8` precision/scale calculations, causing debug panics or incorrect metadata and cast fast-path selection when overflow checks are disabled.
   
   # What changes are included in this PR?
   
   - Compute add/subtract/remainder precision and scale differences in `i16`, clamping precision before narrowing.
   - Reject unrepresentable multiplication scales and overflowing remainder alignment factors.
   - Widen decimal cast scale differences and precision checks while preserving existing rounding, nulls, and safe/unsafe cast behavior.
   
   # Are these changes tested?
   
   The six new regression tests fail on current `main` before the fix.
   
   - `cargo +stable test -p arrow-arith -p arrow-cast --lib`: 623 passed.
   - `cargo +stable --config 'profile.test.package.arrow-arith.overflow-checks=false' --config 'profile.test.package.arrow-cast.overflow-checks=false' test -p arrow-arith -p arrow-cast --lib decimal256 --verbose`: 31 passed. This is an unchecked test profile, not an optimized release build.
   - `cargo +stable fmt --all -- --check` and `git diff --check`: passed.
   - `cargo +stable clippy -p arrow-arith -p arrow-cast --lib --tests --no-deps -- -D warnings -A clippy::chunks_exact_to_as_chunks`: passed.
   
   Local checks used Rust 1.98.0 on Windows because the installed repository-pinned 1.97.1 toolchain was incomplete. Strict Clippy first reported the new `chunks_exact_to_as_chunks` lint in unchanged `arrow-buffer` and `arrow-arith/src/aggregate.rs` code. The scoped run allows only that lint; the repository's existing removed-lint configuration also emits a compatibility warning. No source or lint configuration was changed for these diagnostics.
   
   # Are there any user-facing changes?
   
   Affected addition, subtraction, multiplication, remainder, and decimal casts now return correctly calculated results or checked errors for extreme negative scales instead of panicking or wrapping metadata. Public API signatures are unchanged.
   
   AI assistance: OpenAI Codex (GPT-6) generated the implementation, regression tests, and this description. Codex agents reviewed the diff and ran the checks listed above.
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: github-unsubscribe@arrow.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] Avoid overflow in decimal precision and scale arithmetic [arrow-rs]

Posted by "Jefffrey (via GitHub)" <gi...@apache.org>.
Jefffrey merged PR #10996:
URL: https://github.com/apache/arrow-rs/pull/10996


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: github-unsubscribe@arrow.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] Avoid overflow in decimal precision and scale arithmetic [arrow-rs]

Posted by "Jefffrey (via GitHub)" <gi...@apache.org>.
Jefffrey commented on PR #10996:
URL: https://github.com/apache/arrow-rs/pull/10996#issuecomment-5563376450

   @ryux1 this reads as an LLM apology... please refrain from spamming LLM comments unless you feel it has something to add, and when you do please clearly indicate it is from an LLM


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: github-unsubscribe@arrow.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] Avoid overflow in decimal precision and scale arithmetic [arrow-rs]

Posted by "Jefffrey (via GitHub)" <gi...@apache.org>.
Jefffrey commented on PR #10996:
URL: https://github.com/apache/arrow-rs/pull/10996#issuecomment-5560250832

   @ryux1 are you an LLM agent? i cant help notice youve been mass commenting across discussions and pull requests and these messages read very much like a LLM


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: github-unsubscribe@arrow.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] Avoid overflow in decimal precision and scale arithmetic [arrow-rs]

Posted by "snoopuppy582 (via GitHub)" <gi...@apache.org>.
snoopuppy582 commented on PR #10996:
URL: https://github.com/apache/arrow-rs/pull/10996#issuecomment-5864236472

   Updated in 6265e35f4. The arithmetic branches now widen their locals once and narrow the result scale at `with_precision_and_scale`.
   
   I split the tests by expected precision and failure path, removed redundant wrapping/extreme-scale cases, and added exact error assertions. The cast tests now separate successful rescaling, precision overflow, and native overflow.
   
   All 628 arithmetic/cast unit tests and 36 decimal256 tests with overflow checks disabled pass, along with formatting and the scoped Clippy check described in the PR. Codex assisted with these revisions and this reply.


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: github-unsubscribe@arrow.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] Avoid overflow in decimal precision and scale arithmetic [arrow-rs]

Posted by "ryux1 (via GitHub)" <gi...@apache.org>.
ryux1 commented on PR #10996:
URL: https://github.com/apache/arrow-rs/pull/10996#issuecomment-5560816754

   Yes — I have been using an AI coding assistant for some of these reviews. You are right that the recent volume and wording came across as automated. I am going to stop the drive-by reviews and only comment when I have a concrete, independently checked issue to add. Sorry for the noise.


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: github-unsubscribe@arrow.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] Avoid overflow in decimal precision and scale arithmetic [arrow-rs]

Posted by "Jefffrey (via GitHub)" <gi...@apache.org>.
Jefffrey commented on code in PR #10996:
URL: https://github.com/apache/arrow-rs/pull/10996#discussion_r4043054410


##########
arrow-arith/src/numeric.rs:
##########
@@ -1140,12 +1149,14 @@ fn decimal_op<T: DecimalType>(
             // max(s1, s2)
             let result_scale = *s1.max(s2);
             // min(p1-s1, p2 -s2) + max( s1,s2 )
-            let result_precision =
-                (result_scale.saturating_add((*p1 as i8 - s1).min(*p2 as i8 - s2)) as u8)
-                    .min(T::MAX_PRECISION);
+            let result_precision = (result_scale as i16
+                + (*p1 as i16 - *s1 as i16).min(*p2 as i16 - *s2 as i16))
+            .min(T::MAX_PRECISION as i16) as u8;
 
-            let l_mul = T::Native::usize_as(10).pow_wrapping((result_scale - s1) as _);
-            let r_mul = T::Native::usize_as(10).pow_wrapping((result_scale - s2) as _);
+            let l_mul =
+                T::Native::usize_as(10).pow_checked((result_scale as i16 - *s1 as i16) as _)?;
+            let r_mul =
+                T::Native::usize_as(10).pow_checked((result_scale as i16 - *s2 as i16) as _)?;

Review Comment:
   similarly here



##########
arrow-arith/src/numeric.rs:
##########
@@ -1534,6 +1545,82 @@ mod tests {
         assert_eq!(err, "Divide by zero error");
     }
 
+    #[test]
+    fn test_decimal256_negative_scale_metadata() {
+        for (precision, scale, expected_precision) in
+            [(76, -51, 76), (76, -52, 76), (76, -76, 76), (20, -128, 21)]
+        {
+            let a = Decimal256Array::from(vec![Some(i256::ONE), Some(i256::MINUS_ONE), None])
+                .with_precision_and_scale(precision, scale)
+                .unwrap();
+            let b = Decimal256Array::from(vec![i256::from_i128(2), i256::ONE, i256::ONE])
+                .with_precision_and_scale(precision, scale)
+                .unwrap();
+            for (operation, values, precision) in [
+                (
+                    add as fn(_, _) -> _,
+                    [Some(3), Some(0), None],
+                    expected_precision,
+                ),
+                (add_wrapping, [Some(3), Some(0), None], expected_precision),
+                (sub, [Some(-1), Some(-2), None], expected_precision),
+                (sub_wrapping, [Some(-1), Some(-2), None], expected_precision),
+                (rem, [Some(1), Some(0), None], precision),
+            ] {
+                let expected =
+                    Decimal256Array::from(values.map(|x| x.map(i256::from_i128)).to_vec())
+                        .with_precision_and_scale(precision, scale)

Review Comment:
   theres too many parameters going on here; cant we split the tests up. for example, grouping in `rem` is confusing since its expected precision is differen from the others, and the add/sub wrapping variations will have same result anyway



##########
arrow-arith/src/numeric.rs:
##########
@@ -1047,12 +1047,13 @@ fn decimal_op<T: DecimalType>(
 
             // max(s1, s2) + max(p1-s1, p2-s2) + 1
             let result_precision =
-                (result_scale.saturating_add((*p1 as i8 - s1).max(*p2 as i8 - s2)) as u8)
-                    .saturating_add(1)
-                    .min(T::MAX_PRECISION);
+                (result_scale as i16 + (*p1 as i16 - *s1 as i16).max(*p2 as i16 - *s2 as i16) + 1)

Review Comment:
   can we refactor these to not have the `as i16` everywhere? its a bit hard to read
   
   for example we could make `result_scale` an `i16` above, then we dont need to constantly cast it and its only used once more down below in `with_precision_and_scale` so thats just a single `as i8`



##########
arrow-arith/src/numeric.rs:
##########
@@ -1534,6 +1545,82 @@ mod tests {
         assert_eq!(err, "Divide by zero error");
     }
 
+    #[test]
+    fn test_decimal256_negative_scale_metadata() {
+        for (precision, scale, expected_precision) in
+            [(76, -51, 76), (76, -52, 76), (76, -76, 76), (20, -128, 21)]
+        {
+            let a = Decimal256Array::from(vec![Some(i256::ONE), Some(i256::MINUS_ONE), None])
+                .with_precision_and_scale(precision, scale)
+                .unwrap();
+            let b = Decimal256Array::from(vec![i256::from_i128(2), i256::ONE, i256::ONE])
+                .with_precision_and_scale(precision, scale)
+                .unwrap();
+            for (operation, values, precision) in [
+                (
+                    add as fn(_, _) -> _,
+                    [Some(3), Some(0), None],
+                    expected_precision,
+                ),
+                (add_wrapping, [Some(3), Some(0), None], expected_precision),
+                (sub, [Some(-1), Some(-2), None], expected_precision),
+                (sub_wrapping, [Some(-1), Some(-2), None], expected_precision),
+                (rem, [Some(1), Some(0), None], precision),
+            ] {
+                let expected =
+                    Decimal256Array::from(values.map(|x| x.map(i256::from_i128)).to_vec())
+                        .with_precision_and_scale(precision, scale)
+                        .unwrap();
+                let result = operation(&a, &b).unwrap();
+                assert_eq!(result.as_primitive::<Decimal256Type>(), &expected);
+            }
+        }
+    }
+
+    #[test]
+    fn test_decimal256_extreme_scale_difference() {
+        let a = Decimal256Array::from(vec![i256::ONE])
+            .with_precision_and_scale(20, i8::MIN)
+            .unwrap();
+        let b = Decimal256Array::from(vec![i256::from_i128(2)])
+            .with_precision_and_scale(20, i8::MIN + 1)
+            .unwrap();
+        for (operation, value, precision) in
+            [(add as fn(_, _) -> _, 12, 22), (sub, 8, 22), (rem, 0, 20)]
+        {
+            let result = operation(&a, &b).unwrap();
+            assert_eq!(result.data_type(), &DataType::Decimal256(precision, -127));
+            assert_eq!(
+                result.as_primitive::<Decimal256Type>().value(0),
+                i256::from_i128(value)
+            );
+        }
+        let b = b.with_precision_and_scale(76, 76).unwrap();
+        for operation in [add, sub, rem] {
+            assert!(matches!(
+                operation(&a, &b),
+                Err(ArrowError::ArithmeticOverflow(_))
+            ));
+        }
+    }
+
+    #[test]
+    fn test_decimal256_multiply_minimum_scale() {
+        let a = Decimal256Array::from(vec![i256::ONE])
+            .with_precision_and_scale(76, -64)
+            .unwrap();
+        for operation in [mul, mul_wrapping] {
+            let result = operation(&a, &a).unwrap();
+            assert_eq!(result.data_type(), &DataType::Decimal256(76, i8::MIN));
+            assert_eq!(result.as_primitive::<Decimal256Type>().value(0), i256::ONE);
+            let b = a.clone().with_precision_and_scale(76, -65).unwrap();
+            assert!(matches!(
+                operation(&a, &b),
+                Err(ArrowError::InvalidArgumentError(_))

Review Comment:
   same here



##########
arrow-cast/src/cast/mod.rs:
##########
@@ -11023,6 +11023,82 @@ mod tests {
         assert!(result.value(0) < 0.0); // Negative result
     }
 
+    #[test]
+    fn test_cast_decimal256_negative_scale_metadata() {
+        for scale in [-51, -52, -75, -76] {
+            let input = Decimal256Array::from(vec![
+                Some(i256::ZERO),
+                Some(i256::ONE),
+                Some(i256::MINUS_ONE),
+                Some(i256::from_i128(6)),
+                None,
+            ])
+            .with_precision_and_scale(76, scale)
+            .unwrap();
+            let value = i256::from_i128(10).pow_wrapping((-scale) as u32);
+            let values = if scale == -76 {
+                vec![Some(i256::ZERO), None, None, None, None]
+            } else {
+                vec![
+                    Some(i256::ZERO),
+                    Some(value),
+                    Some(-value),
+                    Some(value * i256::from_i128(6)),
+                    None,
+                ]
+            };
+            let expected = Decimal256Array::from(values)
+                .with_precision_and_scale(76, 0)
+                .unwrap();
+            let result = cast(&input, &DataType::Decimal256(76, 0)).unwrap();
+            assert_eq!(result.as_primitive::<Decimal256Type>(), &expected);
+            let result = cast_with_options(
+                &input,
+                &DataType::Decimal256(76, 0),
+                &CastOptions {
+                    safe: false,
+                    ..Default::default()
+                },
+            );
+            if scale == -76 {
+                assert!(result.is_err());
+            } else {
+                assert_eq!(result.unwrap().as_primitive::<Decimal256Type>(), &expected);

Review Comment:
   i dont like having this if condition just because its an exceptional case being lumped in with the others; can we unroll the loop instead, and separate exceptional cases from others



##########
arrow-arith/src/numeric.rs:
##########
@@ -1534,6 +1545,82 @@ mod tests {
         assert_eq!(err, "Divide by zero error");
     }
 
+    #[test]
+    fn test_decimal256_negative_scale_metadata() {
+        for (precision, scale, expected_precision) in
+            [(76, -51, 76), (76, -52, 76), (76, -76, 76), (20, -128, 21)]
+        {
+            let a = Decimal256Array::from(vec![Some(i256::ONE), Some(i256::MINUS_ONE), None])
+                .with_precision_and_scale(precision, scale)
+                .unwrap();
+            let b = Decimal256Array::from(vec![i256::from_i128(2), i256::ONE, i256::ONE])
+                .with_precision_and_scale(precision, scale)
+                .unwrap();
+            for (operation, values, precision) in [
+                (
+                    add as fn(_, _) -> _,
+                    [Some(3), Some(0), None],
+                    expected_precision,
+                ),
+                (add_wrapping, [Some(3), Some(0), None], expected_precision),
+                (sub, [Some(-1), Some(-2), None], expected_precision),
+                (sub_wrapping, [Some(-1), Some(-2), None], expected_precision),
+                (rem, [Some(1), Some(0), None], precision),
+            ] {
+                let expected =
+                    Decimal256Array::from(values.map(|x| x.map(i256::from_i128)).to_vec())
+                        .with_precision_and_scale(precision, scale)
+                        .unwrap();
+                let result = operation(&a, &b).unwrap();
+                assert_eq!(result.as_primitive::<Decimal256Type>(), &expected);
+            }
+        }
+    }
+
+    #[test]
+    fn test_decimal256_extreme_scale_difference() {
+        let a = Decimal256Array::from(vec![i256::ONE])
+            .with_precision_and_scale(20, i8::MIN)
+            .unwrap();
+        let b = Decimal256Array::from(vec![i256::from_i128(2)])
+            .with_precision_and_scale(20, i8::MIN + 1)
+            .unwrap();
+        for (operation, value, precision) in
+            [(add as fn(_, _) -> _, 12, 22), (sub, 8, 22), (rem, 0, 20)]
+        {
+            let result = operation(&a, &b).unwrap();
+            assert_eq!(result.data_type(), &DataType::Decimal256(precision, -127));
+            assert_eq!(
+                result.as_primitive::<Decimal256Type>().value(0),
+                i256::from_i128(value)
+            );
+        }
+        let b = b.with_precision_and_scale(76, 76).unwrap();
+        for operation in [add, sub, rem] {
+            assert!(matches!(
+                operation(&a, &b),
+                Err(ArrowError::ArithmeticOverflow(_))

Review Comment:
   can we assert the error message to ensure we're hitting the expected one



##########
arrow-arith/src/numeric.rs:
##########
@@ -1534,6 +1545,82 @@ mod tests {
         assert_eq!(err, "Divide by zero error");
     }
 
+    #[test]
+    fn test_decimal256_negative_scale_metadata() {
+        for (precision, scale, expected_precision) in
+            [(76, -51, 76), (76, -52, 76), (76, -76, 76), (20, -128, 21)]
+        {
+            let a = Decimal256Array::from(vec![Some(i256::ONE), Some(i256::MINUS_ONE), None])
+                .with_precision_and_scale(precision, scale)
+                .unwrap();
+            let b = Decimal256Array::from(vec![i256::from_i128(2), i256::ONE, i256::ONE])
+                .with_precision_and_scale(precision, scale)
+                .unwrap();
+            for (operation, values, precision) in [
+                (
+                    add as fn(_, _) -> _,
+                    [Some(3), Some(0), None],
+                    expected_precision,
+                ),
+                (add_wrapping, [Some(3), Some(0), None], expected_precision),
+                (sub, [Some(-1), Some(-2), None], expected_precision),
+                (sub_wrapping, [Some(-1), Some(-2), None], expected_precision),
+                (rem, [Some(1), Some(0), None], precision),
+            ] {
+                let expected =
+                    Decimal256Array::from(values.map(|x| x.map(i256::from_i128)).to_vec())
+                        .with_precision_and_scale(precision, scale)
+                        .unwrap();
+                let result = operation(&a, &b).unwrap();
+                assert_eq!(result.as_primitive::<Decimal256Type>(), &expected);
+            }
+        }
+    }
+
+    #[test]
+    fn test_decimal256_extreme_scale_difference() {
+        let a = Decimal256Array::from(vec![i256::ONE])
+            .with_precision_and_scale(20, i8::MIN)
+            .unwrap();
+        let b = Decimal256Array::from(vec![i256::from_i128(2)])
+            .with_precision_and_scale(20, i8::MIN + 1)
+            .unwrap();
+        for (operation, value, precision) in
+            [(add as fn(_, _) -> _, 12, 22), (sub, 8, 22), (rem, 0, 20)]
+        {
+            let result = operation(&a, &b).unwrap();
+            assert_eq!(result.data_type(), &DataType::Decimal256(precision, -127));

Review Comment:
   similarly i feel its better to unwrap the loop as it feels like adding complexity with tracking these parameters, not to mention the closure for the operation



##########
arrow-cast/src/cast/mod.rs:
##########
@@ -11023,6 +11023,82 @@ mod tests {
         assert!(result.value(0) < 0.0); // Negative result
     }
 
+    #[test]
+    fn test_cast_decimal256_negative_scale_metadata() {
+        for scale in [-51, -52, -75, -76] {
+            let input = Decimal256Array::from(vec![
+                Some(i256::ZERO),
+                Some(i256::ONE),
+                Some(i256::MINUS_ONE),
+                Some(i256::from_i128(6)),
+                None,
+            ])
+            .with_precision_and_scale(76, scale)
+            .unwrap();
+            let value = i256::from_i128(10).pow_wrapping((-scale) as u32);
+            let values = if scale == -76 {
+                vec![Some(i256::ZERO), None, None, None, None]
+            } else {
+                vec![
+                    Some(i256::ZERO),
+                    Some(value),
+                    Some(-value),
+                    Some(value * i256::from_i128(6)),
+                    None,
+                ]
+            };
+            let expected = Decimal256Array::from(values)
+                .with_precision_and_scale(76, 0)
+                .unwrap();
+            let result = cast(&input, &DataType::Decimal256(76, 0)).unwrap();
+            assert_eq!(result.as_primitive::<Decimal256Type>(), &expected);
+            let result = cast_with_options(
+                &input,
+                &DataType::Decimal256(76, 0),
+                &CastOptions {
+                    safe: false,
+                    ..Default::default()
+                },
+            );
+            if scale == -76 {
+                assert!(result.is_err());
+            } else {
+                assert_eq!(result.unwrap().as_primitive::<Decimal256Type>(), &expected);
+            }
+        }
+    }
+
+    #[test]
+    fn test_cast_decimal256_extreme_scale_difference() {
+        for (low_scale, high_scale) in [(-76, 76), (i8::MIN, 76)] {
+            let input = Decimal256Array::from(vec![Some(i256::ONE), Some(i256::MINUS_ONE), None])
+                .with_precision_and_scale(76, low_scale)
+                .unwrap();
+            for safe in [true, false] {
+                let options = CastOptions {
+                    safe,
+                    ..Default::default()
+                };
+                assert!(
+                    cast_with_options(&input, &DataType::Decimal256(76, high_scale), &options)
+                        .is_err()

Review Comment:
   can we assert the error message to ensure its the expected one?



##########
arrow-cast/src/cast/mod.rs:
##########
@@ -11023,6 +11023,82 @@ mod tests {
         assert!(result.value(0) < 0.0); // Negative result
     }
 
+    #[test]
+    fn test_cast_decimal256_negative_scale_metadata() {
+        for scale in [-51, -52, -75, -76] {
+            let input = Decimal256Array::from(vec![
+                Some(i256::ZERO),
+                Some(i256::ONE),
+                Some(i256::MINUS_ONE),
+                Some(i256::from_i128(6)),
+                None,
+            ])
+            .with_precision_and_scale(76, scale)
+            .unwrap();
+            let value = i256::from_i128(10).pow_wrapping((-scale) as u32);
+            let values = if scale == -76 {
+                vec![Some(i256::ZERO), None, None, None, None]
+            } else {
+                vec![
+                    Some(i256::ZERO),
+                    Some(value),
+                    Some(-value),
+                    Some(value * i256::from_i128(6)),
+                    None,
+                ]
+            };
+            let expected = Decimal256Array::from(values)
+                .with_precision_and_scale(76, 0)
+                .unwrap();
+            let result = cast(&input, &DataType::Decimal256(76, 0)).unwrap();
+            assert_eq!(result.as_primitive::<Decimal256Type>(), &expected);
+            let result = cast_with_options(
+                &input,
+                &DataType::Decimal256(76, 0),
+                &CastOptions {
+                    safe: false,
+                    ..Default::default()
+                },
+            );
+            if scale == -76 {
+                assert!(result.is_err());
+            } else {
+                assert_eq!(result.unwrap().as_primitive::<Decimal256Type>(), &expected);
+            }
+        }
+    }
+
+    #[test]
+    fn test_cast_decimal256_extreme_scale_difference() {
+        for (low_scale, high_scale) in [(-76, 76), (i8::MIN, 76)] {

Review Comment:
   is there really a need to have both these test cases? wouldnt `i8::MIN` cover them both?



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: github-unsubscribe@arrow.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] Avoid overflow in decimal precision and scale arithmetic [arrow-rs]

Posted by "Jefffrey (via GitHub)" <gi...@apache.org>.
Jefffrey commented on PR #10996:
URL: https://github.com/apache/arrow-rs/pull/10996#issuecomment-5907548325

   thanks @snoopuppy582 


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: github-unsubscribe@arrow.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org