def castStringToDTInterval()

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)
    }
  }