cloud-fan commented on a change in pull request #32949:
URL: https://github.com/apache/spark/pull/32949#discussion_r664723089
##########
File path:
sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/parser/AstBuilder.scala
##########
@@ -2386,20 +2386,42 @@ class AstBuilder extends SqlBaseBaseVisitor[AnyRef]
with SQLConfHelper with Logg
// `CalendarInterval` doesn't have enough info. For instance, new
CalendarInterval(0, 0, 0)
// can be derived from INTERVAL '0-0' YEAR TO MONTH as well as from
// INTERVAL '0 00:00:00' DAY TO SECOND.
+ val fromUnit =
+
ctx.errorCapturingUnitToUnitInterval.body.from.getText.toLowerCase(Locale.ROOT)
val toUnit =
ctx.errorCapturingUnitToUnitInterval.body.to.getText.toLowerCase(Locale.ROOT)
if (toUnit == "month") {
assert(calendarInterval.days == 0 && calendarInterval.microseconds ==
0)
- // TODO(SPARK-35773): Parse year-month interval literals to tightest
types
- Literal(calendarInterval.months, YearMonthIntervalType())
+ val start = YearMonthIntervalType.stringToField(fromUnit)
+ val end = YearMonthIntervalType.stringToField(toUnit)
+ Literal(calendarInterval.months, YearMonthIntervalType(start,
YearMonthIntervalType.MONTH))
} else {
assert(calendarInterval.months == 0)
- val fromUnit =
-
ctx.errorCapturingUnitToUnitInterval.body.from.getText.toLowerCase(Locale.ROOT)
val micros = IntervalUtils.getDuration(calendarInterval,
TimeUnit.MICROSECONDS)
val start = DayTimeIntervalType.stringToField(fromUnit)
val end = DayTimeIntervalType.stringToField(toUnit)
Literal(micros, DayTimeIntervalType(start, end))
}
+ } else if (ctx.errorCapturingMultiUnitsInterval != null &&
!conf.legacyIntervalEnabled) {
+ val units =
+ ctx.errorCapturingMultiUnitsInterval.body.unit.asScala.map(
+ _.getText.toLowerCase(Locale.ROOT).stripSuffix("s"))
+ if (units.forall(YearMonthIntervalType.stringToField.contains)) {
+ val fields = units.map(YearMonthIntervalType.stringToField)
+ Literal(calendarInterval.months, YearMonthIntervalType(fields.min,
fields.max))
+ } else if (units.forall(DayTimeIntervalType.stringToField.contains)) {
+ val micros = IntervalUtils.getDuration(calendarInterval,
TimeUnit.MICROSECONDS)
+ val fields = units.map(DayTimeIntervalType.stringToField)
+ Literal(micros, DayTimeIntervalType(fields.min, fields.max))
+ } else if (units.forall(IntervalUtils.nonAnsiIntervalUnits.contains)) {
+ // Weeks, milliseconds and nanoseconds
Review comment:
these are all day-time fields. How about
```
val yearMonthFields = ArrayBuffer.empty[String]
val dayTimeFields = ArrayBuffer.empty[String]
for (unit <- units) {
if (YearMonthIntervalType.stringToField.contains(unit)) {
yearMonthFields += unit
} else if (DayTimeIntervalType.stringToField.contains(unit)) {
dayTimeFields += unit
} else if (unit == "week") {
dayTimeFields += "day"
} else if (unit == "milliseconds" || unit == ...) {
dayTimeFields += "second"
} else {
throw QueryParsingErrors.unsupportedIntervalUnitError(ctx)
}
}
if (yearMonthFields.nonEmpty) {
if (dayTimeFields.nonEmpty) throw
QueryParsingErrors.mixedIntervalUnitsError(ctx)
Literal...YearMonthIntervalType
} else {
Literal... DayTimeIntervalType
}
```
--
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]