apache / arrow-rs

Official Rust implementation of Apache Arrow
https://arrow.apache.org/
Apache License 2.0
2.62k stars 802 forks source link

Signed decimal e-notation parsing bug #6728

Closed gruuya closed 1 week ago

gruuya commented 1 week ago

Describe the bug Parsing signed decimal numbers in e-notation has a bug, whereby the parsed values is magnified by an order of magnitude (leading to potential false overflows).

To Reproduce Run the following test (e.g. in arrow-cast/src/parse.rs)

    #[test]
    fn test_negative_decimal_e_notation() {
        assert_eq!(
            parse_decimal::<Decimal128Type>("-1e3", 38, 6).unwrap(),
            -1000000000i128,
        );

        assert_eq!(
            parse_decimal::<Decimal128Type>("-1e31", 38, 6).unwrap(),
            -10000000000000000000000000000000000000i128,
        );
    }

The first assertion will fail, as the parsed value is erroneously -11000000000, while the second example will panic with parse decimal overflow (-1e31), even though the value fits in the specified precision/scale range.

Expected behavior The first test case above should return -1000000000i128 (i.e. 3 zeros from e3 + additional 6 zeros from the scale).

The seconds case shouldn't overflow and should instead return -10000000000000000000000000000000000000i128 (i.e. 31 zeros from e31 + additional 6 zeros from the scale).

Additional context

alamb commented 5 days ago

label_issue.py automatically added labels {'arrow'} from #6729