cloud-fan commented on code in PR #36365:
URL: https://github.com/apache/spark/pull/36365#discussion_r869007019
##########
sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/util/ToNumberParser.scala:
##########
@@ -599,4 +614,254 @@ class ToNumberParser(numberFormat: String, errorOnFail:
Boolean) extends Seriali
Decimal(javaDecimal, precision, scale)
}
}
+
+ /**
+ * Converts a decimal value to a string based on the given number format.
+ *
+ * Iterates through the [[formatTokens]] obtained from processing the format
string, while also
+ * inspecting the input decimal value.
+ *
+ * @param input the decimal value that needs to be converted
+ * @return the result String value obtained from string formatting
+ */
+ def format(input: Decimal): UTF8String = {
+ val result = new StringBuilder()
+ // These are string representations of the input Decimal value.
+ val (inputBeforeDecimalPoint: String,
+ inputAfterDecimalPoint: String) =
+ formatSplitInputBeforeAndAfterDecimalPoint(input)
+ // These are indexes into the characters of the input string before and
after the decimal point.
+ formattingBeforeDecimalPointIndex = 0
+ formattingAfterDecimalPointIndex = 0
+ var reachedDecimalPoint = false
+
+ // Iterate through the tokens representing the provided format string, in
order.
+ for (formatToken: InputToken <- formatTokens) {
+ formatToken match {
+ case groups: DigitGroups =>
+ formatDigitGroups(
+ groups, inputBeforeDecimalPoint, inputAfterDecimalPoint,
reachedDecimalPoint, result)
+ case DecimalPoint() =>
+ // If the last character so far is a space, change it to a zero.
This means the input
+ // decimal does not have an integer part.
+ if (result.nonEmpty && result.last == SPACE) {
+ result(result.length - 1) = ZERO_DIGIT
+ }
+ result.append(POINT_SIGN)
+ reachedDecimalPoint = true
+ case DollarSign() =>
+ result.append(DOLLAR_SIGN)
+ case _: OptionalPlusOrMinusSign =>
+ stripTrailingLoneDecimalPoint(result)
+ if (input < Decimal.ZERO) {
+ addCharacterCheckingTrailingSpaces(result, MINUS_SIGN)
+ } else {
+ addCharacterCheckingTrailingSpaces(result, PLUS_SIGN)
+ }
+ case _: OptionalMinusSign =>
+ if (input < Decimal.ZERO) {
+ stripTrailingLoneDecimalPoint(result)
+ addCharacterCheckingTrailingSpaces(result, MINUS_SIGN)
+ // Add a second space to account for the "MI" sequence comprising
two characters in the
+ // format string.
+ result.append(SPACE)
+ } else {
+ result.append(SPACE)
+ result.append(SPACE)
+ }
+ case OpeningAngleBracket() =>
+ if (input < Decimal.ZERO) {
+ result.append(ANGLE_BRACKET_OPEN)
+ }
+ case ClosingAngleBracket() =>
+ stripTrailingLoneDecimalPoint(result)
+ if (input < Decimal.ZERO) {
+ addCharacterCheckingTrailingSpaces(result, ANGLE_BRACKET_CLOSE)
+ } else {
+ result.append(SPACE)
+ result.append(SPACE)
+ }
+ }
+ }
+
+ if (formattingBeforeDecimalPointIndex < inputBeforeDecimalPoint.length ||
+ formattingAfterDecimalPointIndex < inputAfterDecimalPoint.length) {
+ // Remaining digits before or after the decimal point exist in the
decimal value but not in
+ // the format string.
+ formatMatchFailure(input, numberFormat)
+ } else {
+ stripTrailingLoneDecimalPoint(result)
+ if (result.isEmpty || result.toString == "+" || result.toString == "-") {
Review Comment:
shall we cache the result of `result.toString`?
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]