From 586ef495d57095bbcbc0c4f666017c6843c4b0cd Mon Sep 17 00:00:00 2001 From: Yuming Wang Date: Wed, 24 Jul 2019 15:19:41 +0800 Subject: [PATCH] Support typed interval expression --- .../spark/sql/catalyst/parser/AstBuilder.scala | 4 +++- .../parser/ExpressionParserSuite.scala | 6 ++++++ .../resources/sql-tests/inputs/literals.sql | 4 ++++ .../sql-tests/results/literals.sql.out | 18 +++++++++++++++++- 4 files changed, 30 insertions(+), 2 deletions(-) diff --git a/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/parser/AstBuilder.scala b/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/parser/AstBuilder.scala index a7a3b96ba726d..5c7859041409e 100644 --- a/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/parser/AstBuilder.scala +++ b/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/parser/AstBuilder.scala @@ -1688,7 +1688,7 @@ class AstBuilder(conf: SQLConf) extends SqlBaseBaseVisitor[AnyRef] with Logging * {{{ * [TYPE] '[VALUE]' * }}} - * Currently Date, Timestamp and Binary typed literals are supported. + * Currently Date, Timestamp, Interval and Binary typed literals are supported. */ override def visitTypeConstructor(ctx: TypeConstructorContext): Literal = withOrigin(ctx) { val value = string(ctx.STRING) @@ -1704,6 +1704,8 @@ class AstBuilder(conf: SQLConf) extends SqlBaseBaseVisitor[AnyRef] with Logging case "TIMESTAMP" => val zoneId = getZoneId(SQLConf.get.sessionLocalTimeZone) toLiteral(stringToTimestamp(_, zoneId), TimestampType) + case "INTERVAL" => + Literal(CalendarInterval.fromString(value), CalendarIntervalType) case "X" => val padding = if (value.length % 2 != 0) "0" else "" Literal(DatatypeConverter.parseHexBinary(padding + value)) diff --git a/sql/catalyst/src/test/scala/org/apache/spark/sql/catalyst/parser/ExpressionParserSuite.scala b/sql/catalyst/src/test/scala/org/apache/spark/sql/catalyst/parser/ExpressionParserSuite.scala index 6248e5724f063..ee89980d3eedd 100644 --- a/sql/catalyst/src/test/scala/org/apache/spark/sql/catalyst/parser/ExpressionParserSuite.scala +++ b/sql/catalyst/src/test/scala/org/apache/spark/sql/catalyst/parser/ExpressionParserSuite.scala @@ -431,6 +431,12 @@ class ExpressionParserSuite extends AnalysisTest { Literal(Timestamp.valueOf("2016-03-11 20:54:00.000"))) intercept("timestamP '2016-33-11 20:54:00.000'") + // Interval. + assertEqual("InterVal 'interval 3 month 1 hour'", + Literal(CalendarInterval.fromString("interval 3 month 1 hour"))) + assertEqual("Interval 'interval 3 monthsss 1 hoursss'", + Literal(null, CalendarIntervalType)) + // Binary. assertEqual("X'A'", Literal(Array(0x0a).map(_.toByte))) assertEqual("x'A10C'", Literal(Array(0xa1, 0x0c).map(_.toByte))) diff --git a/sql/core/src/test/resources/sql-tests/inputs/literals.sql b/sql/core/src/test/resources/sql-tests/inputs/literals.sql index a743cf1ec2cde..816386c483209 100644 --- a/sql/core/src/test/resources/sql-tests/inputs/literals.sql +++ b/sql/core/src/test/resources/sql-tests/inputs/literals.sql @@ -108,3 +108,7 @@ SELECT 3.14, -3.14, 3.14e8, 3.14e-8, -3.14e8, -3.14e-8, 3.14e+8, 3.14E8, 3.14E-8 -- map + interval test select map(1, interval 1 day, 2, interval 3 week); + +-- typed interval expression +select interval 'interval 3 year 1 hour'; +select interval '3 year 1 hour'; diff --git a/sql/core/src/test/resources/sql-tests/results/literals.sql.out b/sql/core/src/test/resources/sql-tests/results/literals.sql.out index cacc44d2b1e38..e1e8d685e8787 100644 --- a/sql/core/src/test/resources/sql-tests/results/literals.sql.out +++ b/sql/core/src/test/resources/sql-tests/results/literals.sql.out @@ -1,5 +1,5 @@ -- Automatically generated by SQLQueryTestSuite --- Number of queries: 44 +-- Number of queries: 46 -- !query 0 @@ -422,3 +422,19 @@ select map(1, interval 1 day, 2, interval 3 week) struct> -- !query 43 output {1:interval 1 days,2:interval 3 weeks} + + +-- !query 44 +select interval 'interval 3 year 1 hour' +-- !query 44 schema +struct +-- !query 44 output +interval 3 years 1 hours + + +-- !query 45 +select interval '3 year 1 hour' +-- !query 45 schema +struct +-- !query 45 output +NULL