[SPARK-29502][SQL] typed interval expression should fail for invalid format

### What changes were proposed in this pull request?

This is a followup of https://github.com/apache/spark/pull/25241 .

The typed interval expression should fail for invalid format.

### Why are the changes needed?

Te be consistent with the typed timestamp/date expression

### Does this PR introduce any user-facing change?

Yes. But this feature is not released yet.

### How was this patch tested?

updated test

Closes #26151 from cloud-fan/bug.

Authored-by: Wenchen Fan <wenchen@databricks.com>
Signed-off-by: Yuming Wang <wgyumg@gmail.com>
This commit is contained in:
Wenchen Fan 2019-10-18 16:12:03 -07:00 committed by Yuming Wang
parent e4b4a35de2
commit 2437878299
2 changed files with 12 additions and 5 deletions

View file

@ -1769,7 +1769,15 @@ class AstBuilder(conf: SQLConf) extends SqlBaseBaseVisitor[AnyRef] with Logging
val zoneId = getZoneId(SQLConf.get.sessionLocalTimeZone)
toLiteral(stringToTimestamp(_, zoneId), TimestampType)
case "INTERVAL" =>
Literal(CalendarInterval.fromString(value), CalendarIntervalType)
val interval = try {
CalendarInterval.fromCaseInsensitiveString(value)
} catch {
case e: IllegalArgumentException =>
val ex = new ParseException("Cannot parse the INTERVAL value: " + value, ctx)
ex.setStackTrace(e.getStackTrace)
throw ex
}
Literal(interval, CalendarIntervalType)
case "X" =>
val padding = if (value.length % 2 != 0) "0" else ""
Literal(DatatypeConverter.parseHexBinary(padding + value))

View file

@ -424,19 +424,18 @@ class ExpressionParserSuite extends AnalysisTest {
test("type constructors") {
// Dates.
assertEqual("dAte '2016-03-11'", Literal(Date.valueOf("2016-03-11")))
intercept("DAtE 'mar 11 2016'")
intercept("DAtE 'mar 11 2016'", "Cannot parse the DATE value")
// Timestamps.
assertEqual("tImEstAmp '2016-03-11 20:54:00.000'",
Literal(Timestamp.valueOf("2016-03-11 20:54:00.000")))
intercept("timestamP '2016-33-11 20:54:00.000'")
intercept("timestamP '2016-33-11 20:54:00.000'", "Cannot parse the TIMESTAMP value")
// Interval.
val intervalLiteral = Literal(CalendarInterval.fromString("interval 3 month 1 hour"))
assertEqual("InterVal 'interval 3 month 1 hour'", intervalLiteral)
assertEqual("INTERVAL '3 month 1 hour'", intervalLiteral)
assertEqual("Interval 'interval 3 monthsss 1 hoursss'",
Literal(null, CalendarIntervalType))
intercept("Interval 'interval 3 monthsss 1 hoursss'", "Cannot parse the INTERVAL value")
// Binary.
assertEqual("X'A'", Literal(Array(0x0a).map(_.toByte)))