[SPARK-35771][SQL] Format year-month intervals using type fields
### What changes were proposed in this pull request? This PR proposes to format year-month interval to strings using the start and end fields of `YearMonthIntervalType`. ### Why are the changes needed? Currently, they are ignored, and any `YearMonthIntervalType` is formatted as `INTERVAL YEAR TO MONTH`. ### Does this PR introduce _any_ user-facing change? No. ### How was this patch tested? New test. Closes #32924 from sarutak/year-month-interval-format. Authored-by: Kousuke Saruta <sarutak@oss.nttdata.com> Signed-off-by: Max Gekk <max.gekk@gmail.com>
This commit is contained in:
parent
4530760c40
commit
184f65e7c7
|
@ -29,7 +29,7 @@ import org.apache.spark.sql.catalyst.util.DateTimeUtils.millisToMicros
|
|||
import org.apache.spark.sql.catalyst.util.IntervalStringStyles.{ANSI_STYLE, HIVE_STYLE, IntervalStyle}
|
||||
import org.apache.spark.sql.errors.QueryExecutionErrors
|
||||
import org.apache.spark.sql.internal.SQLConf
|
||||
import org.apache.spark.sql.types.{DayTimeIntervalType, Decimal}
|
||||
import org.apache.spark.sql.types.{DayTimeIntervalType, Decimal, YearMonthIntervalType}
|
||||
import org.apache.spark.unsafe.types.{CalendarInterval, UTF8String}
|
||||
|
||||
// The style of textual representation of intervals
|
||||
|
@ -945,7 +945,6 @@ object IntervalUtils {
|
|||
def toYearMonthIntervalString(
|
||||
months: Int,
|
||||
style: IntervalStyle,
|
||||
// TODO(SPARK-35771): Format year-month intervals using type fields
|
||||
startField: Byte,
|
||||
endField: Byte): String = {
|
||||
var sign = ""
|
||||
|
@ -954,10 +953,22 @@ object IntervalUtils {
|
|||
sign = "-"
|
||||
absMonths = -absMonths
|
||||
}
|
||||
val payload = s"$sign${absMonths / MONTHS_PER_YEAR}-${absMonths % MONTHS_PER_YEAR}"
|
||||
val year = s"$sign${absMonths / MONTHS_PER_YEAR}"
|
||||
val month = s"${absMonths % MONTHS_PER_YEAR}"
|
||||
val yearAndMonth = s"$year-$month"
|
||||
style match {
|
||||
case ANSI_STYLE => s"INTERVAL '$payload' YEAR TO MONTH"
|
||||
case HIVE_STYLE => payload
|
||||
case ANSI_STYLE =>
|
||||
val formatBuilder = new StringBuilder("INTERVAL '")
|
||||
if (startField == endField) {
|
||||
startField match {
|
||||
case YearMonthIntervalType.YEAR => formatBuilder.append(s"$year' YEAR")
|
||||
case YearMonthIntervalType.MONTH => formatBuilder.append(s"$month' MONTH")
|
||||
}
|
||||
} else {
|
||||
formatBuilder.append(s"$yearAndMonth' YEAR TO MONTH")
|
||||
}
|
||||
formatBuilder.toString
|
||||
case HIVE_STYLE => s"$yearAndMonth"
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -619,4 +619,30 @@ class IntervalUtilsSuite extends SparkFunSuite with SQLHelper {
|
|||
assert(toDayTimeIntervalString(micros, ANSI_STYLE, SECOND, SECOND) === sec)
|
||||
}
|
||||
}
|
||||
|
||||
test("SPARK-35771: Format year-month intervals using type fields") {
|
||||
import org.apache.spark.sql.types.YearMonthIntervalType._
|
||||
Seq(
|
||||
0 ->
|
||||
("INTERVAL '0-0' YEAR TO MONTH", "INTERVAL '0' YEAR", "INTERVAL '0' MONTH"),
|
||||
-11 -> ("INTERVAL '-0-11' YEAR TO MONTH", "INTERVAL '-0' YEAR", "INTERVAL '11' MONTH"),
|
||||
11 -> ("INTERVAL '0-11' YEAR TO MONTH", "INTERVAL '0' YEAR", "INTERVAL '11' MONTH"),
|
||||
-13 -> ("INTERVAL '-1-1' YEAR TO MONTH", "INTERVAL '-1' YEAR", "INTERVAL '1' MONTH"),
|
||||
13 -> ("INTERVAL '1-1' YEAR TO MONTH", "INTERVAL '1' YEAR", "INTERVAL '1' MONTH"),
|
||||
-24 -> ("INTERVAL '-2-0' YEAR TO MONTH", "INTERVAL '-2' YEAR", "INTERVAL '0' MONTH"),
|
||||
24 -> ("INTERVAL '2-0' YEAR TO MONTH", "INTERVAL '2' YEAR", "INTERVAL '0' MONTH"),
|
||||
Int.MinValue ->
|
||||
("INTERVAL '-178956970-8' YEAR TO MONTH",
|
||||
"INTERVAL '-178956970' YEAR",
|
||||
"INTERVAL '8' MONTH"),
|
||||
Int.MaxValue ->
|
||||
("INTERVAL '178956970-7' YEAR TO MONTH",
|
||||
"INTERVAL '178956970' YEAR",
|
||||
"INTERVAL '7' MONTH")
|
||||
).foreach { case (months, (yearToMonth, year, month)) =>
|
||||
assert(toYearMonthIntervalString(months, ANSI_STYLE, YEAR, MONTH) === yearToMonth)
|
||||
assert(toYearMonthIntervalString(months, ANSI_STYLE, YEAR, YEAR) === year)
|
||||
assert(toYearMonthIntervalString(months, ANSI_STYLE, MONTH, MONTH) === month)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue