Skip to content

Commit

Permalink
Update to bigdecimal 0.4.7 (#13747)
Browse files Browse the repository at this point in the history
* Add big decimal formatting test cases with potential trailing zeros

* Rename and simplify decimal rendering functions

- add `decimal` to function name
- drop `precision` parameter as it is not supposed to affect the result

* Update to bigdecimal 0.4.7

Utilize new `to_plain_string` function
  • Loading branch information
findepi authored Dec 13, 2024
1 parent c030bfe commit 5af4333
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 33 deletions.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ arrow-ipc = { version = "53.3.0", default-features = false, features = [
arrow-ord = { version = "53.3.0", default-features = false }
arrow-schema = { version = "53.3.0", default-features = false }
async-trait = "0.1.73"
bigdecimal = "0.4.6"
bigdecimal = "0.4.7"
bytes = "1.4"
chrono = { version = "0.4.38", default-features = false }
ctor = "0.2.0"
Expand Down
57 changes: 29 additions & 28 deletions datafusion/sqllogictest/src/engines/conversion.rs
Original file line number Diff line number Diff line change
Expand Up @@ -81,16 +81,18 @@ pub(crate) fn f64_to_str(value: f64) -> String {
}
}

pub(crate) fn i128_to_str(value: i128, precision: &u8, scale: &i8) -> String {
pub(crate) fn decimal_128_to_str(value: i128, scale: i8) -> String {
let precision = u8::MAX; // does not matter
big_decimal_to_str(
BigDecimal::from_str(&Decimal128Type::format_decimal(value, *precision, *scale))
BigDecimal::from_str(&Decimal128Type::format_decimal(value, precision, scale))
.unwrap(),
)
}

pub(crate) fn i256_to_str(value: i256, precision: &u8, scale: &i8) -> String {
pub(crate) fn decimal_256_to_str(value: i256, scale: i8) -> String {
let precision = u8::MAX; // does not matter
big_decimal_to_str(
BigDecimal::from_str(&Decimal256Type::format_decimal(value, *precision, *scale))
BigDecimal::from_str(&Decimal256Type::format_decimal(value, precision, scale))
.unwrap(),
)
}
Expand All @@ -104,30 +106,7 @@ pub(crate) fn big_decimal_to_str(value: BigDecimal) -> String {
// Round the value to limit the number of decimal places
let value = value.round(12).normalized();
// Format the value to a string
format_big_decimal(value)
}

fn format_big_decimal(value: BigDecimal) -> String {
let (integer, scale) = value.into_bigint_and_exponent();
let mut str = integer.to_str_radix(10);
if scale <= 0 {
// Append zeros to the right of the integer part
str.extend(std::iter::repeat('0').take(scale.unsigned_abs() as usize));
str
} else {
let (sign, unsigned_len, unsigned_str) = if integer.is_negative() {
("-", str.len() - 1, &str[1..])
} else {
("", str.len(), &str[..])
};
let scale = scale as usize;
if unsigned_len <= scale {
format!("{}0.{:0>scale$}", sign, unsigned_str)
} else {
str.insert(str.len() - scale, '.');
str
}
}
value.to_plain_string()
}

#[cfg(test)]
Expand All @@ -149,19 +128,41 @@ mod tests {

#[test]
fn test_big_decimal_to_str() {
assert_decimal_str_eq!(110, 3, "0.11");
assert_decimal_str_eq!(11, 3, "0.011");
assert_decimal_str_eq!(11, 2, "0.11");
assert_decimal_str_eq!(11, 1, "1.1");
assert_decimal_str_eq!(11, 0, "11");
assert_decimal_str_eq!(11, -1, "110");
assert_decimal_str_eq!(0, 0, "0");
assert_decimal_str_eq!(
12345678901234567890123456789012345678_i128,
0,
"12345678901234567890123456789012345678"
);
assert_decimal_str_eq!(
12345678901234567890123456789012345678_i128,
38,
"0.123456789012"
);

// Negative cases
assert_decimal_str_eq!(-110, 3, "-0.11");
assert_decimal_str_eq!(-11, 3, "-0.011");
assert_decimal_str_eq!(-11, 2, "-0.11");
assert_decimal_str_eq!(-11, 1, "-1.1");
assert_decimal_str_eq!(-11, 0, "-11");
assert_decimal_str_eq!(-11, -1, "-110");
assert_decimal_str_eq!(
-12345678901234567890123456789012345678_i128,
0,
"-12345678901234567890123456789012345678"
);
assert_decimal_str_eq!(
-12345678901234567890123456789012345678_i128,
38,
"-0.123456789012"
);

// Round to 12 decimal places
// 1.0000000000011 -> 1.000000000001
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -213,13 +213,13 @@ pub fn cell_to_string(col: &ArrayRef, row: usize) -> Result<String> {
DataType::Float64 => {
Ok(f64_to_str(get_row_value!(array::Float64Array, col, row)))
}
DataType::Decimal128(precision, scale) => {
DataType::Decimal128(_, scale) => {
let value = get_row_value!(array::Decimal128Array, col, row);
Ok(i128_to_str(value, precision, scale))
Ok(decimal_128_to_str(value, *scale))
}
DataType::Decimal256(precision, scale) => {
DataType::Decimal256(_, scale) => {
let value = get_row_value!(array::Decimal256Array, col, row);
Ok(i256_to_str(value, precision, scale))
Ok(decimal_256_to_str(value, *scale))
}
DataType::LargeUtf8 => Ok(varchar_to_str(get_row_value!(
array::LargeStringArray,
Expand Down

0 comments on commit 5af4333

Please sign in to comment.