Skip to content

Commit 5af4333

Browse files
authored
Update to bigdecimal 0.4.7 (#13747)
* 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
1 parent c030bfe commit 5af4333

File tree

3 files changed

+34
-33
lines changed

3 files changed

+34
-33
lines changed

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ arrow-ipc = { version = "53.3.0", default-features = false, features = [
9393
arrow-ord = { version = "53.3.0", default-features = false }
9494
arrow-schema = { version = "53.3.0", default-features = false }
9595
async-trait = "0.1.73"
96-
bigdecimal = "0.4.6"
96+
bigdecimal = "0.4.7"
9797
bytes = "1.4"
9898
chrono = { version = "0.4.38", default-features = false }
9999
ctor = "0.2.0"

datafusion/sqllogictest/src/engines/conversion.rs

Lines changed: 29 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -81,16 +81,18 @@ pub(crate) fn f64_to_str(value: f64) -> String {
8181
}
8282
}
8383

84-
pub(crate) fn i128_to_str(value: i128, precision: &u8, scale: &i8) -> String {
84+
pub(crate) fn decimal_128_to_str(value: i128, scale: i8) -> String {
85+
let precision = u8::MAX; // does not matter
8586
big_decimal_to_str(
86-
BigDecimal::from_str(&Decimal128Type::format_decimal(value, *precision, *scale))
87+
BigDecimal::from_str(&Decimal128Type::format_decimal(value, precision, scale))
8788
.unwrap(),
8889
)
8990
}
9091

91-
pub(crate) fn i256_to_str(value: i256, precision: &u8, scale: &i8) -> String {
92+
pub(crate) fn decimal_256_to_str(value: i256, scale: i8) -> String {
93+
let precision = u8::MAX; // does not matter
9294
big_decimal_to_str(
93-
BigDecimal::from_str(&Decimal256Type::format_decimal(value, *precision, *scale))
95+
BigDecimal::from_str(&Decimal256Type::format_decimal(value, precision, scale))
9496
.unwrap(),
9597
)
9698
}
@@ -104,30 +106,7 @@ pub(crate) fn big_decimal_to_str(value: BigDecimal) -> String {
104106
// Round the value to limit the number of decimal places
105107
let value = value.round(12).normalized();
106108
// Format the value to a string
107-
format_big_decimal(value)
108-
}
109-
110-
fn format_big_decimal(value: BigDecimal) -> String {
111-
let (integer, scale) = value.into_bigint_and_exponent();
112-
let mut str = integer.to_str_radix(10);
113-
if scale <= 0 {
114-
// Append zeros to the right of the integer part
115-
str.extend(std::iter::repeat('0').take(scale.unsigned_abs() as usize));
116-
str
117-
} else {
118-
let (sign, unsigned_len, unsigned_str) = if integer.is_negative() {
119-
("-", str.len() - 1, &str[1..])
120-
} else {
121-
("", str.len(), &str[..])
122-
};
123-
let scale = scale as usize;
124-
if unsigned_len <= scale {
125-
format!("{}0.{:0>scale$}", sign, unsigned_str)
126-
} else {
127-
str.insert(str.len() - scale, '.');
128-
str
129-
}
130-
}
109+
value.to_plain_string()
131110
}
132111

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

150129
#[test]
151130
fn test_big_decimal_to_str() {
131+
assert_decimal_str_eq!(110, 3, "0.11");
152132
assert_decimal_str_eq!(11, 3, "0.011");
153133
assert_decimal_str_eq!(11, 2, "0.11");
154134
assert_decimal_str_eq!(11, 1, "1.1");
155135
assert_decimal_str_eq!(11, 0, "11");
156136
assert_decimal_str_eq!(11, -1, "110");
157137
assert_decimal_str_eq!(0, 0, "0");
138+
assert_decimal_str_eq!(
139+
12345678901234567890123456789012345678_i128,
140+
0,
141+
"12345678901234567890123456789012345678"
142+
);
143+
assert_decimal_str_eq!(
144+
12345678901234567890123456789012345678_i128,
145+
38,
146+
"0.123456789012"
147+
);
158148

159149
// Negative cases
150+
assert_decimal_str_eq!(-110, 3, "-0.11");
160151
assert_decimal_str_eq!(-11, 3, "-0.011");
161152
assert_decimal_str_eq!(-11, 2, "-0.11");
162153
assert_decimal_str_eq!(-11, 1, "-1.1");
163154
assert_decimal_str_eq!(-11, 0, "-11");
164155
assert_decimal_str_eq!(-11, -1, "-110");
156+
assert_decimal_str_eq!(
157+
-12345678901234567890123456789012345678_i128,
158+
0,
159+
"-12345678901234567890123456789012345678"
160+
);
161+
assert_decimal_str_eq!(
162+
-12345678901234567890123456789012345678_i128,
163+
38,
164+
"-0.123456789012"
165+
);
165166

166167
// Round to 12 decimal places
167168
// 1.0000000000011 -> 1.000000000001

datafusion/sqllogictest/src/engines/datafusion_engine/normalize.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -213,13 +213,13 @@ pub fn cell_to_string(col: &ArrayRef, row: usize) -> Result<String> {
213213
DataType::Float64 => {
214214
Ok(f64_to_str(get_row_value!(array::Float64Array, col, row)))
215215
}
216-
DataType::Decimal128(precision, scale) => {
216+
DataType::Decimal128(_, scale) => {
217217
let value = get_row_value!(array::Decimal128Array, col, row);
218-
Ok(i128_to_str(value, precision, scale))
218+
Ok(decimal_128_to_str(value, *scale))
219219
}
220-
DataType::Decimal256(precision, scale) => {
220+
DataType::Decimal256(_, scale) => {
221221
let value = get_row_value!(array::Decimal256Array, col, row);
222-
Ok(i256_to_str(value, precision, scale))
222+
Ok(decimal_256_to_str(value, *scale))
223223
}
224224
DataType::LargeUtf8 => Ok(varchar_to_str(get_row_value!(
225225
array::LargeStringArray,

0 commit comments

Comments
 (0)