apache / apache/arrow-rs

Casting decimal -> decimal with large scale is buggy

Open
#10,946 1 comment 0 reactions 1 assignee Claimed by @neilconway View on GitHub
bug
Dominant language
Rust
Stars
3.6k
Forks
1.3k
Avg merge
2d 14h
Merged PRs (30d)
167

Description

### Describe the bug

Casting decimal -> decimal with a much larger scale can produce incorrect values, including panics in debug mode.

### To Reproduce

```rust
use arrow_array::{Array, Decimal256Array};
use arrow_buffer::i256;
use arrow_cast::{cast_with_options, CastOptions};
use arrow_schema::DataType;

let array = Decimal256Array::from(vec![
i256::from_i128(1),
i256::from_i128(10_i128.pow(16)),
i256::from_i128(10_i128.pow(17)),
])
.with_precision_and_scale(76, 0)
.unwrap();

// Strict mode; safe mode returns the same values (no nulls, no error)
let options = CastOptions { safe: false, ..Default::default() };
let result = cast_with_options(&array, &DataType::Decimal256(76, 60), &options).unwrap();
```

Results:

```
1 -> 1000000000000000000000000000000000000000000000000000000000000
10000000000000000 -> 10000000000000000000000000000000000000000000000000000000000000000000000000000
100000000000000000 -> -15792089237316195423570985008687907853269984665640564039457584007913129639936
```

The first result is correct.

The second result exceeds the maximum value representable at precision 76 but is returned without error.

The third result is just wrong.

### Expected behavior

_No response_

### Additional context

_No response_

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.