Skip to content

Commit

Permalink
[SPARK-32840][SQL] nvalid interval value can happen to be just adhesi…
Browse files Browse the repository at this point in the history
…ve with the unit
  • Loading branch information
yaooqinn committed Sep 10, 2020
1 parent 0c7616b commit d3dc77c
Show file tree
Hide file tree
Showing 4 changed files with 88 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2107,7 +2107,16 @@ class AstBuilder(conf: SQLConf) extends SqlBaseBaseVisitor[AnyRef] with Logging
val kvs = units.indices.map { i =>
val u = units(i).getText
val v = if (values(i).STRING() != null) {
string(values(i).STRING())
val value = string(values(i).STRING())
// SPARK-32840: For invalid cases, e.g. INTERVAL '1 day 2' hour,
// INTERVAL 'interval 1' day, we need to check ahead before they are concatenated with
// units and become valid ones, e.g. '1 day 2 hour'.
// Ideally, we only ensure the value parts don't contain any units here.
if (value.exists(Character.isLetter)) {
throw new ParseException("Can only use numbers in the interval value part for" +
s" multiple unit value pairs interval form, but got invalid value: $value", ctx)
}
value
} else {
values(i).getText
}
Expand Down
4 changes: 4 additions & 0 deletions sql/core/src/test/resources/sql-tests/inputs/interval.sql
Original file line number Diff line number Diff line change
Expand Up @@ -180,3 +180,7 @@ SELECT
to_json(from_json('{"a":"1 days"}', 'a interval')),
to_json(map('a', interval 25 month 100 day 130 minute)),
from_json(to_json(map('a', interval 25 month 100 day 130 minute)), 'a interval');

select interval '1 day 2' day;
select interval 'interval 1' day;
select interval '-\t 1' day;
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
-- Automatically generated by SQLQueryTestSuite
-- Number of queries: 93
-- Number of queries: 96


-- !query
Expand Down Expand Up @@ -956,3 +956,39 @@ SELECT
struct<from_json({"a":"1 days"}):struct<a:interval>,to_json(from_json({"a":"1 days"})):string,to_json(map(a, INTERVAL '2 years 1 months 100 days 2 hours 10 minutes')):string,from_json(to_json(map(a, INTERVAL '2 years 1 months 100 days 2 hours 10 minutes'))):struct<a:interval>>
-- !query output
{"a":1 days} {"a":"1 days"} {"a":"2 years 1 months 100 days 2 hours 10 minutes"} {"a":2 years 1 months 100 days 2 hours 10 minutes}


-- !query
select interval '1 day 2' day
-- !query schema
struct<>
-- !query output
org.apache.spark.sql.catalyst.parser.ParseException

Can only use numbers in the interval value part for multiple unit value pairs interval form, but got invalid value: 1 day 2(line 1, pos 16)

== SQL ==
select interval '1 day 2' day
----------------^^^


-- !query
select interval 'interval 1' day
-- !query schema
struct<>
-- !query output
org.apache.spark.sql.catalyst.parser.ParseException

Can only use numbers in the interval value part for multiple unit value pairs interval form, but got invalid value: interval 1(line 1, pos 16)

== SQL ==
select interval 'interval 1' day
----------------^^^


-- !query
select interval '-\t 1' day
-- !query schema
struct<INTERVAL '-1 days':interval>
-- !query output
-1 days
38 changes: 37 additions & 1 deletion sql/core/src/test/resources/sql-tests/results/interval.sql.out
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
-- Automatically generated by SQLQueryTestSuite
-- Number of queries: 93
-- Number of queries: 96


-- !query
Expand Down Expand Up @@ -928,3 +928,39 @@ SELECT
struct<from_json({"a":"1 days"}):struct<a:interval>,to_json(from_json({"a":"1 days"})):string,to_json(map(a, INTERVAL '2 years 1 months 100 days 2 hours 10 minutes')):string,from_json(to_json(map(a, INTERVAL '2 years 1 months 100 days 2 hours 10 minutes'))):struct<a:interval>>
-- !query output
{"a":1 days} {"a":"1 days"} {"a":"2 years 1 months 100 days 2 hours 10 minutes"} {"a":2 years 1 months 100 days 2 hours 10 minutes}


-- !query
select interval '1 day 2' day
-- !query schema
struct<>
-- !query output
org.apache.spark.sql.catalyst.parser.ParseException

Can only use numbers in the interval value part for multiple unit value pairs interval form, but got invalid value: 1 day 2(line 1, pos 16)

== SQL ==
select interval '1 day 2' day
----------------^^^


-- !query
select interval 'interval 1' day
-- !query schema
struct<>
-- !query output
org.apache.spark.sql.catalyst.parser.ParseException

Can only use numbers in the interval value part for multiple unit value pairs interval form, but got invalid value: interval 1(line 1, pos 16)

== SQL ==
select interval 'interval 1' day
----------------^^^


-- !query
select interval '-\t 1' day
-- !query schema
struct<INTERVAL '-1 days':interval>
-- !query output
-1 days

0 comments on commit d3dc77c

Please sign in to comment.