Skip to content

Commit 7bdb20e

Browse files
committed
fix: grouping separator for float and decimal
1 parent 48d20ad commit 7bdb20e

1 file changed

Lines changed: 27 additions & 1 deletion

File tree

datafusion/spark/src/function/string/format_string.rs

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1775,6 +1775,9 @@ impl ConversionSpecifier {
17751775
if strip_trailing_0s {
17761776
number = trim_trailing_0s(&number).to_owned();
17771777
}
1778+
if self.grouping_separator {
1779+
number = insert_thousands_separator(&number);
1780+
}
17781781
}
17791782
if self.alt_form && !number.contains('.') {
17801783
number += ".";
@@ -2035,7 +2038,7 @@ impl ConversionSpecifier {
20352038
_ => 6,
20362039
};
20372040

2038-
let number = match self.conversion_type {
2041+
let mut number = match self.conversion_type {
20392042
ConversionType::DecFloatLower => {
20402043
// Format as fixed-point decimal
20412044
self.format_decimal_fixed(&abs_decimal, precision, strip_trailing_0s)?
@@ -2082,6 +2085,10 @@ impl ConversionSpecifier {
20822085
}
20832086
};
20842087

2088+
if self.grouping_separator {
2089+
number = insert_thousands_separator(&number);
2090+
}
2091+
20852092
// Handle padding
20862093
let NumericParam::Literal(width) = self.width else {
20872094
writer.push_str(&prefix);
@@ -2337,6 +2344,25 @@ impl FloatBits for f64 {
23372344
}
23382345
}
23392346

2347+
/// Inserts thousands separators (`,`) into the integer part of a numeric string.
2348+
/// For example, `"1234567.89"` becomes `"1,234,567.89"`.
2349+
fn insert_thousands_separator(number: &str) -> String {
2350+
let (int_part, frac_part) = match number.find('.') {
2351+
Some(pos) => (&number[..pos], &number[pos..]),
2352+
None => (number, ""),
2353+
};
2354+
let mut result = String::new();
2355+
let chars: Vec<char> = int_part.chars().collect();
2356+
for (i, c) in chars.iter().enumerate() {
2357+
if i > 0 && (chars.len() - i).is_multiple_of(3) {
2358+
result.push(',');
2359+
}
2360+
result.push(*c);
2361+
}
2362+
result.push_str(frac_part);
2363+
result
2364+
}
2365+
23402366
fn trim_trailing_0s(number: &str) -> &str {
23412367
if number.contains('.') {
23422368
for (i, c) in number.chars().rev().enumerate() {

0 commit comments

Comments
 (0)