in sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/util/IntervalUtils.scala [275:373]
def castStringToDTInterval(
input: UTF8String,
startField: Byte,
endField: Byte): Long = {
def secondAndMicro(second: String, micro: String): String = {
if (micro != null) {
s"$second$micro"
} else {
second
}
}
def checkTargetType(targetStartField: Byte, targetEndField: Byte): Boolean =
startField == targetStartField && endField == targetEndField
val trimmedInput = input.trimAll().toString
trimmedInput match {
case dayHourRegex(sign, day, hour) if checkTargetType(DT.DAY, DT.HOUR) =>
toDTInterval(day, hour, "0", "0", finalSign(sign))
case dayHourLiteralRegex(firstSign, secondSign, day, hour)
if checkTargetType(DT.DAY, DT.HOUR) =>
toDTInterval(day, hour, "0", "0", finalSign(firstSign, secondSign))
case dayMinuteRegex(sign, day, hour, minute) if checkTargetType(DT.DAY, DT.MINUTE) =>
toDTInterval(day, hour, minute, "0", finalSign(sign))
case dayMinuteLiteralRegex(firstSign, secondSign, day, hour, minute)
if checkTargetType(DT.DAY, DT.MINUTE) =>
toDTInterval(day, hour, minute, "0", finalSign(firstSign, secondSign))
case daySecondRegex(sign, day, hour, minute, second, micro)
if checkTargetType(DT.DAY, DT.SECOND) =>
toDTInterval(day, hour, minute, secondAndMicro(second, micro), finalSign(sign))
case daySecondLiteralRegex(firstSign, secondSign, day, hour, minute, second, micro)
if checkTargetType(DT.DAY, DT.SECOND) =>
toDTInterval(day, hour, minute, secondAndMicro(second, micro),
finalSign(firstSign, secondSign))
case hourMinuteRegex(sign, hour, minute) if checkTargetType(DT.HOUR, DT.MINUTE) =>
toDTInterval(hour, minute, "0", finalSign(sign))
case hourMinuteLiteralRegex(firstSign, secondSign, hour, minute)
if checkTargetType(DT.HOUR, DT.MINUTE) =>
toDTInterval(hour, minute, "0", finalSign(firstSign, secondSign))
case hourSecondRegex(sign, hour, minute, second, micro)
if checkTargetType(DT.HOUR, DT.SECOND) =>
toDTInterval(hour, minute, secondAndMicro(second, micro), finalSign(sign))
case hourSecondLiteralRegex(firstSign, secondSign, hour, minute, second, micro)
if checkTargetType(DT.HOUR, DT.SECOND) =>
toDTInterval(hour, minute, secondAndMicro(second, micro), finalSign(firstSign, secondSign))
case minuteSecondRegex(sign, minute, second, micro)
if checkTargetType(DT.MINUTE, DT.SECOND) =>
toDTInterval(minute, secondAndMicro(second, micro), finalSign(sign))
case minuteSecondLiteralRegex(firstSign, secondSign, minute, second, micro)
if checkTargetType(DT.MINUTE, DT.SECOND) =>
toDTInterval(minute, secondAndMicro(second, micro), finalSign(firstSign, secondSign))
case dayTimeIndividualRegex(firstSign, value, suffix) =>
safeToInterval("day-time", trimmedInput) {
val sign = finalSign(firstSign)
(startField, endField) match {
case (DT.DAY, DT.DAY) if suffix == null && value.length <= 9 =>
sign * value.toLong * MICROS_PER_DAY
case (DT.HOUR, DT.HOUR) if suffix == null && value.length <= 10 =>
sign * value.toLong * MICROS_PER_HOUR
case (DT.MINUTE, DT.MINUTE) if suffix == null && value.length <= 12 =>
sign * value.toLong * MICROS_PER_MINUTE
case (DT.SECOND, DT.SECOND) if value.length <= 13 =>
sign match {
case 1 => parseSecondNano(secondAndMicro(value, suffix))
case -1 => parseSecondNano(s"-${secondAndMicro(value, suffix)}")
}
case (_, _) => throwIllegalIntervalFormatException(input, startField, endField,
"day-time", DT(startField, endField).typeName, true)
}
}
case dayTimeIndividualLiteralRegex(firstSign, secondSign, value, suffix, unit) =>
safeToInterval("day-time", trimmedInput) {
val sign = finalSign(firstSign, secondSign)
unit.toUpperCase(Locale.ROOT) match {
case "DAY" if suffix == null && value.length <= 9 && checkTargetType(DT.DAY, DT.DAY) =>
sign * value.toLong * MICROS_PER_DAY
case "HOUR" if suffix == null && value.length <= 10
&& checkTargetType(DT.HOUR, DT.HOUR) =>
sign * value.toLong * MICROS_PER_HOUR
case "MINUTE" if suffix == null && value.length <= 12
&& checkTargetType(DT.MINUTE, DT.MINUTE) =>
sign * value.toLong * MICROS_PER_MINUTE
case "SECOND" if value.length <= 13 && checkTargetType(DT.SECOND, DT.SECOND) =>
sign match {
case 1 => parseSecondNano(secondAndMicro(value, suffix))
case -1 => parseSecondNano(s"-${secondAndMicro(value, suffix)}")
}
case _ => throwIllegalIntervalFormatException(input, startField, endField,
"day-time", DT(startField, endField).typeName, true)
}
}
case _ => throwIllegalIntervalFormatException(input, startField, endField,
"day-time", DT(startField, endField).typeName, true)
}
}