Skip to content

Commit

Permalink
Add ArrowError::ArithmeticOverflow
Browse files Browse the repository at this point in the history
  • Loading branch information
alamb committed Jul 17, 2024
1 parent effccc1 commit 6fd1628
Show file tree
Hide file tree
Showing 5 changed files with 38 additions and 24 deletions.
4 changes: 2 additions & 2 deletions arrow-arith/src/arithmetic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ pub fn multiply_fixed_point_checked(
let mut mul = a.wrapping_mul(b);
mul = divide_and_round::<Decimal256Type>(mul, divisor);
mul.to_i128().ok_or_else(|| {
ArrowError::ComputeError(format!("Overflow happened on: {:?} * {:?}", a, b))
ArrowError::ArithmeticOverflow(format!("Overflow happened on: {:?} * {:?}", a, b))
})
})
.and_then(|a| a.with_precision_and_scale(precision, required_scale))
Expand Down Expand Up @@ -323,7 +323,7 @@ mod tests {

// `multiply` overflows on this case.
let err = mul(&a, &b).unwrap_err();
assert_eq!(err.to_string(), "Compute error: Overflow happened on: 123456789000000000000000000 * 10000000000000000000");
assert_eq!(err.to_string(), "Arithmetic overflow: Overflow happened on: 123456789000000000000000000 * 10000000000000000000");

// Avoid overflow by reducing the scale.
let result = multiply_fixed_point(&a, &b, 28).unwrap();
Expand Down
32 changes: 19 additions & 13 deletions arrow-arith/src/numeric.rs
Original file line number Diff line number Diff line change
Expand Up @@ -888,15 +888,15 @@ mod tests {

test_neg_primitive::<Int32Type>(
&[i32::MIN],
Err("Compute error: Overflow happened on: - -2147483648"),
Err("Arithmetic overflow: Overflow happened on: - -2147483648"),
);
test_neg_primitive::<Int64Type>(
&[i64::MIN],
Err("Compute error: Overflow happened on: - -9223372036854775808"),
Err("Arithmetic overflow: Overflow happened on: - -9223372036854775808"),
);
test_neg_primitive::<DurationSecondType>(
&[i64::MIN],
Err("Compute error: Overflow happened on: - -9223372036854775808"),
Err("Arithmetic overflow: Overflow happened on: - -9223372036854775808"),
);

let r = neg_wrapping(&Int32Array::from(vec![i32::MIN])).unwrap();
Expand All @@ -911,7 +911,7 @@ mod tests {

assert_eq!(
err,
"Compute error: Overflow happened on: - -9223372036854775808"
"Arithmetic overflow: Overflow happened on: - -9223372036854775808"
);

let a = Decimal128Array::from(vec![1, 3, -44, 2, 4])
Expand Down Expand Up @@ -1016,28 +1016,31 @@ mod tests {
let a = UInt8Array::from(vec![56, 5, 3]);
let b = UInt8Array::from(vec![200, 2, 5]);
let err = add(&a, &b).unwrap_err().to_string();
assert_eq!(err, "Compute error: Overflow happened on: 56 + 200");
assert_eq!(err, "Arithmetic overflow: Overflow happened on: 56 + 200");
let result = add_wrapping(&a, &b).unwrap();
assert_eq!(result.as_ref(), &UInt8Array::from(vec![0, 7, 8]));

let a = UInt8Array::from(vec![34, 5, 3]);
let b = UInt8Array::from(vec![200, 2, 5]);
let err = sub(&a, &b).unwrap_err().to_string();
assert_eq!(err, "Compute error: Overflow happened on: 34 - 200");
assert_eq!(err, "Arithmetic overflow: Overflow happened on: 34 - 200");
let result = sub_wrapping(&a, &b).unwrap();
assert_eq!(result.as_ref(), &UInt8Array::from(vec![90, 3, 254]));

let a = UInt8Array::from(vec![34, 5, 3]);
let b = UInt8Array::from(vec![200, 2, 5]);
let err = mul(&a, &b).unwrap_err().to_string();
assert_eq!(err, "Compute error: Overflow happened on: 34 * 200");
assert_eq!(err, "Arithmetic overflow: Overflow happened on: 34 * 200");
let result = mul_wrapping(&a, &b).unwrap();
assert_eq!(result.as_ref(), &UInt8Array::from(vec![144, 10, 15]));

let a = Int16Array::from(vec![i16::MIN]);
let b = Int16Array::from(vec![-1]);
let err = div(&a, &b).unwrap_err().to_string();
assert_eq!(err, "Compute error: Overflow happened on: -32768 / -1");
assert_eq!(
err,
"Arithmetic overflow: Overflow happened on: -32768 / -1"
);

let a = Int16Array::from(vec![21]);
let b = Int16Array::from(vec![0]);
Expand Down Expand Up @@ -1146,15 +1149,15 @@ mod tests {
.with_precision_and_scale(3, -2)
.unwrap();
let err = add(&a, &b).unwrap_err().to_string();
assert_eq!(err, "Compute error: Overflow happened on: 10 ^ 39");
assert_eq!(err, "Arithmetic overflow: Overflow happened on: 10 ^ 39");

let a = Decimal128Array::from(vec![10])
.with_precision_and_scale(3, -1)
.unwrap();
let err = add(&a, &b).unwrap_err().to_string();
assert_eq!(
err,
"Compute error: Overflow happened on: 10 * 100000000000000000000000000000000000000"
"Arithmetic overflow: Overflow happened on: 10 * 100000000000000000000000000000000000000"
);

let b = Decimal128Array::from(vec![0])
Expand Down Expand Up @@ -1349,7 +1352,10 @@ mod tests {
let a = IntervalMonthDayNanoArray::from(vec![IntervalMonthDayNano::MAX]);
let b = IntervalMonthDayNanoArray::from(vec![IntervalMonthDayNano::ONE]);
let err = add(&a, &b).unwrap_err().to_string();
assert_eq!(err, "Compute error: Overflow happened on: 2147483647 + 1");
assert_eq!(
err,
"Arithmetic overflow: Overflow happened on: 2147483647 + 1"
);
}

fn test_duration_impl<T: ArrowPrimitiveType<Native = i64>>() {
Expand Down Expand Up @@ -1384,7 +1390,7 @@ mod tests {
let err = add(&a, &b).unwrap_err().to_string();
assert_eq!(
err,
"Compute error: Overflow happened on: 9223372036854775807 + 1"
"Arithmetic overflow: Overflow happened on: 9223372036854775807 + 1"
);
}

Expand Down Expand Up @@ -1511,7 +1517,7 @@ mod tests {
let err = sub(&a, &b).unwrap_err().to_string();
assert_eq!(
err,
"Compute error: Overflow happened on: 9223372036854775807 - -1"
"Arithmetic overflow: Overflow happened on: 9223372036854775807 - -1"
);
}
}
17 changes: 10 additions & 7 deletions arrow-array/src/arithmetic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@ macro_rules! native_type_op {
#[inline]
fn add_checked(self, rhs: Self) -> Result<Self, ArrowError> {
self.checked_add(rhs).ok_or_else(|| {
ArrowError::ComputeError(format!(
ArrowError::ArithmeticOverflow(format!(
"Overflow happened on: {:?} + {:?}",
self, rhs
))
Expand All @@ -169,7 +169,7 @@ macro_rules! native_type_op {
#[inline]
fn sub_checked(self, rhs: Self) -> Result<Self, ArrowError> {
self.checked_sub(rhs).ok_or_else(|| {
ArrowError::ComputeError(format!(
ArrowError::ArithmeticOverflow(format!(
"Overflow happened on: {:?} - {:?}",
self, rhs
))
Expand All @@ -184,7 +184,7 @@ macro_rules! native_type_op {
#[inline]
fn mul_checked(self, rhs: Self) -> Result<Self, ArrowError> {
self.checked_mul(rhs).ok_or_else(|| {
ArrowError::ComputeError(format!(
ArrowError::ArithmeticOverflow(format!(
"Overflow happened on: {:?} * {:?}",
self, rhs
))
Expand All @@ -202,7 +202,7 @@ macro_rules! native_type_op {
Err(ArrowError::DivideByZero)
} else {
self.checked_div(rhs).ok_or_else(|| {
ArrowError::ComputeError(format!(
ArrowError::ArithmeticOverflow(format!(
"Overflow happened on: {:?} / {:?}",
self, rhs
))
Expand All @@ -221,7 +221,7 @@ macro_rules! native_type_op {
Err(ArrowError::DivideByZero)
} else {
self.checked_rem(rhs).ok_or_else(|| {
ArrowError::ComputeError(format!(
ArrowError::ArithmeticOverflow(format!(
"Overflow happened on: {:?} % {:?}",
self, rhs
))
Expand All @@ -237,14 +237,17 @@ macro_rules! native_type_op {
#[inline]
fn neg_checked(self) -> Result<Self, ArrowError> {
self.checked_neg().ok_or_else(|| {
ArrowError::ComputeError(format!("Overflow happened on: - {:?}", self))
ArrowError::ArithmeticOverflow(format!("Overflow happened on: - {:?}", self))
})
}

#[inline]
fn pow_checked(self, exp: u32) -> Result<Self, ArrowError> {
self.checked_pow(exp).ok_or_else(|| {
ArrowError::ComputeError(format!("Overflow happened on: {:?} ^ {exp:?}", self))
ArrowError::ArithmeticOverflow(format!(
"Overflow happened on: {:?} ^ {exp:?}",
self
))
})
}

Expand Down
7 changes: 5 additions & 2 deletions arrow-cast/src/cast/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4436,7 +4436,7 @@ mod tests {
))],
IntervalUnit::DayTime,
format!(
"Compute error: Overflow happened on: {} * 100",
"Arithmetic overflow: Overflow happened on: {} * 100",
i64::MAX - 2
)
);
Expand All @@ -4448,7 +4448,10 @@ mod tests {
i64::MAX - 2
))],
IntervalUnit::MonthDayNano,
format!("Compute error: Overflow happened on: {} * 12", i64::MAX - 2)
format!(
"Arithmetic overflow: Overflow happened on: {} * 12",
i64::MAX - 2
)
);
}

Expand Down
2 changes: 2 additions & 0 deletions arrow-schema/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ pub enum ArrowError {
SchemaError(String),
ComputeError(String),
DivideByZero,
ArithmeticOverflow(String),
CsvError(String),
JsonError(String),
IoError(String, std::io::Error),
Expand Down Expand Up @@ -88,6 +89,7 @@ impl Display for ArrowError {
ArrowError::ParseError(desc) => write!(f, "Parser error: {desc}"),
ArrowError::SchemaError(desc) => write!(f, "Schema error: {desc}"),
ArrowError::ComputeError(desc) => write!(f, "Compute error: {desc}"),
ArrowError::ArithmeticOverflow(desc) => write!(f, "Arithmetic overflow: {desc}"),
ArrowError::DivideByZero => write!(f, "Divide by zero error"),
ArrowError::CsvError(desc) => write!(f, "Csv error: {desc}"),
ArrowError::JsonError(desc) => write!(f, "Json error: {desc}"),
Expand Down

0 comments on commit 6fd1628

Please sign in to comment.