Skip to content

Commit

Permalink
for simple case of equal scale and bigger precision, no conversion ne…
Browse files Browse the repository at this point in the history
…eded.

revert whitespace changes

formatting check
  • Loading branch information
himadripal committed Dec 5, 2024
1 parent 264c29b commit 6c50fe3
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 13 deletions.
11 changes: 7 additions & 4 deletions arrow-cast/src/cast/decimal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,7 @@ where
// Only support one type of decimal cast operations
pub(crate) fn cast_decimal_to_decimal_same_type<T>(
array: &PrimitiveArray<T>,
input_precision: u8,
input_scale: i8,
output_precision: u8,
output_scale: i8,
Expand All @@ -163,8 +164,10 @@ where
T: DecimalType,
T::Native: DecimalCast + ArrowNativeTypeOp,
{
let array: PrimitiveArray<T> = if input_scale <= output_scale {
// input_scale <= output_scale
let array: PrimitiveArray<T> =
if input_scale == output_scale && input_precision <= output_precision {
array.clone()
} else if input_scale < output_scale {
// the scale doesn't change, but precision may change and cause overflow
convert_to_bigger_or_equal_scale_decimal::<T, T>(
array,
Expand All @@ -174,14 +177,14 @@ where
cast_options,
)?
} else {
convert_to_smaller_scale_decimal::<T, T>(
convert_to_smaller_scale_decimal::<T, T>(
array,
input_scale,
output_precision,
output_scale,
cast_options,
)?
};
};

Ok(Arc::new(array.with_precision_and_scale(
output_precision,
Expand Down
35 changes: 26 additions & 9 deletions arrow-cast/src/cast/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -824,18 +824,20 @@ pub fn cast_with_options(
(Map(_, ordered1), Map(_, ordered2)) if ordered1 == ordered2 => {
cast_map_values(array.as_map(), to_type, cast_options, ordered1.to_owned())
}
(Decimal128(_, s1), Decimal128(p2, s2)) => {
(Decimal128(p1, s1), Decimal128(p2, s2)) => {
cast_decimal_to_decimal_same_type::<Decimal128Type>(
array.as_primitive(),
*p1,
*s1,
*p2,
*s2,
cast_options,
)
}
(Decimal256(_, s1), Decimal256(p2, s2)) => {
(Decimal256(p1, s1), Decimal256(p2, s2)) => {
cast_decimal_to_decimal_same_type::<Decimal256Type>(
array.as_primitive(),
*p1,
*s1,
*p2,
*s2,
Expand Down Expand Up @@ -2683,7 +2685,10 @@ mod tests {
let array = create_decimal_array(array, 10, 0).unwrap();
let result_safe = cast(&array, &DataType::Decimal128(2, 2));
assert!(result_safe.is_ok());
let options = CastOptions { safe: false, ..Default::default() };
let options = CastOptions {
safe: false,
..Default::default()
};

let result_unsafe = cast_with_options(&array, &DataType::Decimal128(2, 2), &options);
assert_eq!("Invalid argument error: 12345600 is too large to store in a Decimal128 of precision 2. Max is 99",
Expand Down Expand Up @@ -9837,10 +9842,13 @@ mod tests {
let output_type = DataType::Decimal128(6, 2);
assert!(can_cast_types(&input_type, &output_type));

let options = CastOptions { safe: false, ..Default::default() };
let options = CastOptions {
safe: false,
..Default::default()
};
let result = cast_with_options(&array, &output_type, &options);
assert_eq!(result.unwrap_err().to_string(),
"Invalid argument error: 123456789 is too large to store in a Decimal128 of precision 6. Max is 999999");
"Invalid argument error: 123456790 is too large to store in a Decimal128 of precision 6. Max is 999999");
}

#[test]
Expand All @@ -9852,10 +9860,13 @@ mod tests {
let output_type = DataType::Decimal128(6, 2);
assert!(can_cast_types(&input_type, &output_type));

let options = CastOptions { safe: false, ..Default::default() };
let options = CastOptions {
safe: false,
..Default::default()
};
let result = cast_with_options(&array, &output_type, &options);
assert_eq!(result.unwrap_err().to_string(),
"Invalid argument error: 123456789 is too large to store in a Decimal128 of precision 6. Max is 999999");
"Invalid argument error: 123456790 is too large to store in a Decimal128 of precision 6. Max is 999999");
}

#[test]
Expand All @@ -9867,7 +9878,10 @@ mod tests {
let output_type = DataType::Decimal128(6, 3);
assert!(can_cast_types(&input_type, &output_type));

let options = CastOptions { safe: false, ..Default::default() };
let options = CastOptions {
safe: false,
..Default::default()
};
let result = cast_with_options(&array, &output_type, &options);
assert_eq!(result.unwrap_err().to_string(),
"Invalid argument error: 1234567890 is too large to store in a Decimal128 of precision 6. Max is 999999");
Expand All @@ -9882,7 +9896,10 @@ mod tests {
let output_type = DataType::Decimal256(6, 2);
assert!(can_cast_types(&input_type, &output_type));

let options = CastOptions { safe: false, ..Default::default() };
let options = CastOptions {
safe: false,
..Default::default()
};
let result = cast_with_options(&array, &output_type, &options);
assert_eq!(result.unwrap_err().to_string(),
"Invalid argument error: 123456789 is too large to store in a Decimal256 of precision 6. Max is 999999");
Expand Down

0 comments on commit 6c50fe3

Please sign in to comment.