From 5189d667fba4312972d081b75d868accb85df4ec Mon Sep 17 00:00:00 2001 From: Liang-Chi Hsieh Date: Mon, 3 Jul 2023 11:19:08 -0700 Subject: [PATCH] Return error when internal multiplication overflowing in decimal division kernel --- .../core/tests/sqllogictests/test_files/decimal.slt | 9 +++++++++ .../src/expressions/binary/kernels_arrow.rs | 8 ++++---- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/datafusion/core/tests/sqllogictests/test_files/decimal.slt b/datafusion/core/tests/sqllogictests/test_files/decimal.slt index fd4e80e1afe4..f41351774172 100644 --- a/datafusion/core/tests/sqllogictests/test_files/decimal.slt +++ b/datafusion/core/tests/sqllogictests/test_files/decimal.slt @@ -603,3 +603,12 @@ query R select try_cast(1234567 as decimal(7,3)); ---- NULL + +statement ok +create table foo (a DECIMAL(38, 20), b DECIMAL(38, 0)); + +statement ok +insert into foo VALUES (1, 5); + +query error DataFusion error: Arrow error: Compute error: Overflow happened on: 100000000000000000000 \* 100000000000000000000000000000000000000 +select a / b from foo; diff --git a/datafusion/physical-expr/src/expressions/binary/kernels_arrow.rs b/datafusion/physical-expr/src/expressions/binary/kernels_arrow.rs index e7d7f62c86d2..9c6645c30371 100644 --- a/datafusion/physical-expr/src/expressions/binary/kernels_arrow.rs +++ b/datafusion/physical-expr/src/expressions/binary/kernels_arrow.rs @@ -20,8 +20,8 @@ use arrow::compute::{ add_dyn, add_scalar_dyn, divide_dyn_checked, divide_scalar_dyn, modulus_dyn, - modulus_scalar_dyn, multiply_fixed_point, multiply_scalar_dyn, subtract_dyn, - subtract_scalar_dyn, try_unary, + modulus_scalar_dyn, multiply_fixed_point, multiply_scalar_checked_dyn, + multiply_scalar_dyn, subtract_dyn, subtract_scalar_dyn, try_unary, }; use arrow::datatypes::{Date32Type, Date64Type, Decimal128Type}; use arrow::{array::*, datatypes::ArrowNumericType}; @@ -662,7 +662,7 @@ pub(crate) fn divide_decimal_dyn_scalar( let (precision, scale) = get_precision_scale(result_type)?; let mul = 10_i128.pow(scale as u32); - let array = multiply_scalar_dyn::(left, mul)?; + let array = multiply_scalar_checked_dyn::(left, mul)?; let array = divide_scalar_dyn::(&array, right)?; decimal_array_with_precision_scale(array, precision, scale) @@ -719,7 +719,7 @@ pub(crate) fn divide_dyn_checked_decimal( let (precision, scale) = get_precision_scale(result_type)?; let mul = 10_i128.pow(scale as u32); - let array = multiply_scalar_dyn::(left, mul)?; + let array = multiply_scalar_checked_dyn::(left, mul)?; // Restore to original precision and scale (metadata only) let (org_precision, org_scale) = get_precision_scale(right.data_type())?;