(&self, writer: &mut String, value: &str, scale: i64)
| 2050 | } |
| 2051 | |
| 2052 | fn format_decimal(&self, writer: &mut String, value: &str, scale: i64) -> Result<()> { |
| 2053 | self.validate_grouping_separator()?; |
| 2054 | |
| 2055 | let mut prefix = String::new(); |
| 2056 | let upper = self.conversion_type.is_upper(); |
| 2057 | |
| 2058 | // Parse as BigDecimal |
| 2059 | let decimal = value |
| 2060 | .parse::<BigInt>() |
| 2061 | .map_err(|e| exec_datafusion_err!("Failed to parse decimal: {}", e))?; |
| 2062 | let decimal = BigDecimal::from_bigint(decimal, scale); |
| 2063 | |
| 2064 | // Handle sign |
| 2065 | // TODO: `negative_in_parentheses` (the `(` flag) is not implemented here. |
| 2066 | // Java/Spark wrap negative values in parentheses when this flag is set |
| 2067 | // (e.g. `%(,.2f` with -1234.5 → "(1,234.50)"), but this path always |
| 2068 | // uses a minus sign. See `format_float` for the correct implementation. |
| 2069 | let is_negative = decimal.sign() == Sign::Minus; |
| 2070 | let abs_decimal = decimal.abs(); |
| 2071 | |
| 2072 | if is_negative { |
| 2073 | prefix.push('-'); |
| 2074 | } else if self.space_sign { |
| 2075 | prefix.push(' '); |
| 2076 | } else if self.force_sign { |
| 2077 | prefix.push('+'); |
| 2078 | } |
| 2079 | |
| 2080 | let exp_symb = if upper { 'E' } else { 'e' }; |
| 2081 | let mut strip_trailing_0s = false; |
| 2082 | |
| 2083 | // Get precision setting |
| 2084 | let mut precision = match self.precision { |
| 2085 | NumericParam::Literal(p) => p, |
| 2086 | _ => 6, |
| 2087 | }; |
| 2088 | |
| 2089 | let number = match self.conversion_type { |
| 2090 | ConversionType::DecFloatLower => { |
| 2091 | // Format as fixed-point decimal |
| 2092 | let mut n = self.format_decimal_fixed( |
| 2093 | &abs_decimal, |
| 2094 | precision, |
| 2095 | strip_trailing_0s, |
| 2096 | )?; |
| 2097 | if self.grouping_separator { |
| 2098 | n = insert_thousands_separator(&n); |
| 2099 | } |
| 2100 | n |
| 2101 | } |
| 2102 | ConversionType::SciFloatLower => self.format_decimal_scientific( |
| 2103 | &abs_decimal, |
| 2104 | precision, |
| 2105 | 'e', |
| 2106 | strip_trailing_0s, |
| 2107 | )?, |
| 2108 | ConversionType::SciFloatUpper => self.format_decimal_scientific( |
| 2109 | &abs_decimal, |
no test coverage detected