mbutrovich opened a new issue, #12095:
URL: https://github.com/apache/arrow-rs/issues/12095
**Describe the bug**
`PrimitiveArray::validate_decimal_precision` returns `Decimal precision
{precision} is less than scale {scale}` for any array whose scale is negative,
whatever its precision and values. Its guard compares `precision < self.scale()
as u8`, and a negative scale cast to `u8` wraps, so `-2` becomes `254`.
https://github.com/apache/arrow-rs/blob/cc58320c2da359b757814db5a9651397d829b601/arrow-array/src/array/primitive_array.rs#L1708-L1714
The type-level check `validate_decimal_precision_and_scale` guards the same
comparison with `scale > 0`:
https://github.com/apache/arrow-rs/blob/cc58320c2da359b757814db5a9651397d829b601/arrow-array/src/types.rs#L1465-L1469
The guard came in with #8396, first released in 57.0.0.
**To Reproduce**
On `main` at cc58320c2d:
```rust
use arrow_array::Decimal128Array;
fn main() {
// 1 at scale -2 is 100, which fits in precision 5
let a = Decimal128Array::from(vec![1])
.with_precision_and_scale(5, -2)
.unwrap();
println!("{:?}", a.validate_decimal_precision(5));
// Err(InvalidArgumentError("Decimal precision 5 is less than scale -2"))
// The same value at scale 2 passes
let b = Decimal128Array::from(vec![1])
.with_precision_and_scale(5, 2)
.unwrap();
println!("{:?}", b.validate_decimal_precision(5));
// Ok(())
}
```
**Expected behavior**
`Ok(())` for the first array, since its value fits precision 5. A guard of
`self.scale() > 0 && precision < self.scale() as u8` would match
`validate_decimal_precision_and_scale`.
**Additional context**
Property-based tests found it on a generated `Decimal128(5, -2)` array.
Checking each value with `DecimalType::validate_decimal_precision` works around
it.
--
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: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]