Skip to content

Incorrect results when casting large strings to Decimal256 #10665

Description

@neilconway

Describe the bug

When casting strings to Decimal256, an input whose unscaled value exceeds the i256 range is handled incorrectly; it is converted to an incorrect result value (due to wrapping of the internal i256 representation), rather than being rejected.

To Reproduce

```rust
use arrow_array::{cast::AsArray, types::Decimal256Type, StringArray};
use arrow_cast::{cast_with_options, CastOptions};
use arrow_schema::DataType;
use std::sync::Arc;

fn main() {
    // ~7.2 x 10^64: 65 integer digits and 33 fractional digits
    let input = "72167486952390333280550343777716101824043691957654319462507011489.831702916080743443465428641160496";
    let array = Arc::new(StringArray::from(vec![input])) as arrow_array::ArrayRef;
    let options = CastOptions { safe: false, ..Default::default() };
    let result = cast_with_options(&array, &DataType::Decimal256(76, 17), &options).unwrap();
    println!("{}", result.as_primitive::<Decimal256Type>().value_as_string(0));
}

Results

67335233014482809727371051363254493174014793837924915072256.89984486799063144

(which is incorrect.)

Expected behavior

A cast error, because the input is not representable as Decimal256 (it requires 82 decimal digits, but Decimal256 tops out at ~77 decimal digits).

Additional context

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions