Skip to content

Dividing decimal type gives wrong error: "170141183460469231731687303715884105727 is too large to store in a Decimal128 #3498

@alamb

Description

@alamb

Describe the bug
Dividing by Decimal value by zero results in

cd datafusion-cli
cargo run
DataFusion CLI v12.0.0
❯ select cast(1 as int) / cast (0 as int);

ArrowError(DivideByZero)
❯ select cast(1 as double) / cast (0 as double);

ArrowError(DivideByZero)
❯ select cast(1 as decimal(10, 1)) / cast (0 as decimal(10, 1));

ArrowError(InvalidArgumentError("170141183460469231731687303715884105727 is too large to store in a Decimal128 of precision 10. Max is 9999999999"))
❯ 

To Reproduce
See above (divide a decimal number by zero)

Expected behavior
I expect an DivideByZero error:

select cast(1 as decimal(10, 1)) / cast (0 as decimal(10, 1));

ArrowError(DivideByZero)

Additional context
Found while working on #3483

I am pretty sure the problem is in

pub(crate) fn divide_decimal(
    left: &Decimal128Array,
    right: &Decimal128Array,
) -> Result<Decimal128Array> {
    let mul = 10_f64.powi(left.scale() as i32);
    let array = arith_decimal(left, right, |left, right| {
        let l_value = left as f64;
        let r_value = right as f64;
        let result = ((l_value / r_value) * mul) as i128;
        Ok(result)
    })?

Specifically, using floating point math to divide two floats and then casting to an int128 is where the 170141183460469231731687303715884105727 value comes from

https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=b5949eb324d9828a802aa11b4fa9d029

FYI @liukun4515

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions