[SPARK-23264][SQL] Make INTERVAL keyword optional in INTERVAL clauses when ANSI mode enabled

## What changes were proposed in this pull request?
This pr updated parsing rules in `SqlBase.g4` to support a SQL query below when ANSI mode enabled;
```
SELECT CAST('2017-08-04' AS DATE) + 1 days;
```
The current master cannot parse it though, other dbms-like systems support the syntax (e.g., hive and mysql). Also, the syntax is frequently used in the official TPC-DS queries.

This pr added new tokens as follows;
```
YEAR | YEARS | MONTH | MONTHS | WEEK | WEEKS | DAY | DAYS | HOUR | HOURS | MINUTE
MINUTES | SECOND | SECONDS | MILLISECOND | MILLISECONDS | MICROSECOND | MICROSECONDS
```
Then, it registered the keywords below as the ANSI reserved (this follows SQL-2011);
```
 DAY | HOUR | MINUTE | MONTH | SECOND | YEAR
```

## How was this patch tested?
Added tests in `SQLQuerySuite`, `ExpressionParserSuite`, and `TableIdentifierParserSuite`.

Closes #20433 from maropu/SPARK-23264.

Authored-by: Takeshi Yamamuro <yamamuro@apache.org>
Signed-off-by: Takeshi Yamamuro <yamamuro@apache.org>
This commit is contained in:
Takeshi Yamamuro 2019-03-14 10:45:29 +09:00
parent 2d0b7cfe44
commit bacffb8810
8 changed files with 827 additions and 48 deletions

View file

@ -137,7 +137,8 @@ The list of reserved and non-reserved keywords can change according to the confi
<tr><td>DATABASE</td><td>non-reserved</td><td>non-reserved</td><td>non-reserved</td></tr>
<tr><td>DATABASES</td><td>non-reserved</td><td>non-reserved</td><td>non-reserved</td></tr>
<tr><td>DATE</td><td>non-reserved</td><td>non-reserved</td><td>reserved</td></tr>
<tr><td>DAY</td><td>non-reserved</td><td>non-reserved</td><td>reserved</td></tr>
<tr><td>DAY</td><td>reserved</td><td>non-reserved</td><td>reserved</td></tr>
<tr><td>DAYS</td><td>non-reserved</td><td>non-reserved</td><td>non-reserved</td></tr>
<tr><td>DBPROPERTIES</td><td>non-reserved</td><td>non-reserved</td><td>non-reserved</td></tr>
<tr><td>DEALLOCATE</td><td>non-reserved</td><td>non-reserved</td><td>reserved</td></tr>
<tr><td>DEC</td><td>non-reserved</td><td>non-reserved</td><td>reserved</td></tr>
@ -230,7 +231,8 @@ The list of reserved and non-reserved keywords can change according to the confi
<tr><td>HANDLER</td><td>non-reserved</td><td>non-reserved</td><td>reserved</td></tr>
<tr><td>HAVING</td><td>reserved</td><td>non-reserved</td><td>reserved</td></tr>
<tr><td>HOLD</td><td>non-reserved</td><td>non-reserved</td><td>reserved</td></tr>
<tr><td>HOUR</td><td>non-reserved</td><td>non-reserved</td><td>reserved</td></tr>
<tr><td>HOUR</td><td>reserved</td><td>non-reserved</td><td>reserved</td></tr>
<tr><td>HOURS</td><td>non-reserved</td><td>non-reserved</td><td>non-reserved</td></tr>
<tr><td>IDENTITY</td><td>non-reserved</td><td>non-reserved</td><td>reserved</td></tr>
<tr><td>IF</td><td>non-reserved</td><td>non-reserved</td><td>reserved</td></tr>
<tr><td>IGNORE</td><td>non-reserved</td><td>non-reserved</td><td>non-reserved</td></tr>
@ -313,13 +315,19 @@ The list of reserved and non-reserved keywords can change according to the confi
<tr><td>MEMBER</td><td>non-reserved</td><td>non-reserved</td><td>reserved</td></tr>
<tr><td>MERGE</td><td>non-reserved</td><td>non-reserved</td><td>reserved</td></tr>
<tr><td>METHOD</td><td>non-reserved</td><td>non-reserved</td><td>reserved</td></tr>
<tr><td>MICROSECOND</td><td>non-reserved</td><td>non-reserved</td><td>non-reserved</td></tr>
<tr><td>MICROSECONDS</td><td>non-reserved</td><td>non-reserved</td><td>non-reserved</td></tr>
<tr><td>MILLISECOND</td><td>non-reserved</td><td>non-reserved</td><td>non-reserved</td></tr>
<tr><td>MILLISECONDS</td><td>non-reserved</td><td>non-reserved</td><td>non-reserved</td></tr>
<tr><td>MIN</td><td>non-reserved</td><td>non-reserved</td><td>reserved</td></tr>
<tr><td>MINUS</td><td>reserved</td><td>reserved</td><td>non-reserved</td></tr>
<tr><td>MINUTE</td><td>non-reserved</td><td>non-reserved</td><td>reserved</td></tr>
<tr><td>MINUTE</td><td>reserved</td><td>non-reserved</td><td>reserved</td></tr>
<tr><td>MINUTES</td><td>non-reserved</td><td>non-reserved</td><td>non-reserved</td></tr>
<tr><td>MOD</td><td>non-reserved</td><td>non-reserved</td><td>reserved</td></tr>
<tr><td>MODIFIES</td><td>non-reserved</td><td>non-reserved</td><td>reserved</td></tr>
<tr><td>MODULE</td><td>non-reserved</td><td>non-reserved</td><td>reserved</td></tr>
<tr><td>MONTH</td><td>non-reserved</td><td>non-reserved</td><td>reserved</td></tr>
<tr><td>MONTH</td><td>reserved</td><td>non-reserved</td><td>reserved</td></tr>
<tr><td>MONTHS</td><td>non-reserved</td><td>non-reserved</td><td>non-reserved</td></tr>
<tr><td>MSCK</td><td>non-reserved</td><td>non-reserved</td><td>non-reserved</td></tr>
<tr><td>MULTISET</td><td>non-reserved</td><td>non-reserved</td><td>reserved</td></tr>
<tr><td>NAMES</td><td>non-reserved</td><td>non-reserved</td><td>non-reserved</td></tr>
@ -448,7 +456,8 @@ The list of reserved and non-reserved keywords can change according to the confi
<tr><td>SCOPE</td><td>non-reserved</td><td>non-reserved</td><td>reserved</td></tr>
<tr><td>SCROLL</td><td>non-reserved</td><td>non-reserved</td><td>reserved</td></tr>
<tr><td>SEARCH</td><td>non-reserved</td><td>non-reserved</td><td>reserved</td></tr>
<tr><td>SECOND</td><td>non-reserved</td><td>non-reserved</td><td>reserved</td></tr>
<tr><td>SECOND</td><td>reserved</td><td>non-reserved</td><td>reserved</td></tr>
<tr><td>SECONDS</td><td>non-reserved</td><td>non-reserved</td><td>non-reserved</td></tr>
<tr><td>SECTION</td><td>non-reserved</td><td>non-reserved</td><td>non-reserved</td></tr>
<tr><td>SEEK</td><td>non-reserved</td><td>non-reserved</td><td>non-reserved</td></tr>
<tr><td>SELECT</td><td>reserved</td><td>non-reserved</td><td>reserved</td></tr>
@ -568,8 +577,11 @@ The list of reserved and non-reserved keywords can change according to the confi
<tr><td>WITH</td><td>reserved</td><td>non-reserved</td><td>reserved</td></tr>
<tr><td>WITHIN</td><td>non-reserved</td><td>non-reserved</td><td>reserved</td></tr>
<tr><td>WITHOUT</td><td>non-reserved</td><td>non-reserved</td><td>reserved</td></tr>
<tr><td>WEEK</td><td>non-reserved</td><td>non-reserved</td><td>non-reserved</td></tr>
<tr><td>WEEKS</td><td>non-reserved</td><td>non-reserved</td><td>non-reserved</td></tr>
<tr><td>WORK</td><td>non-reserved</td><td>non-reserved</td><td>non-reserved</td></tr>
<tr><td>WRITE</td><td>non-reserved</td><td>non-reserved</td><td>non-reserved</td></tr>
<tr><td>YEAR</td><td>non-reserved</td><td>non-reserved</td><td>reserved</td></tr>
<tr><td>YEAR</td><td>reserved</td><td>non-reserved</td><td>reserved</td></tr>
<tr><td>YEARS</td><td>non-reserved</td><td>non-reserved</td><td>non-reserved</td></tr>
<tr><td>ZONE</td><td>non-reserved</td><td>non-reserved</td><td>non-reserved</td></tr>
</table>

View file

@ -655,11 +655,12 @@ booleanValue
;
interval
: INTERVAL intervalField*
: {ansi}? INTERVAL? intervalField+
| {!ansi}? INTERVAL intervalField*
;
intervalField
: value=intervalValue unit=identifier (TO to=identifier)?
: value=intervalValue unit=intervalUnit (TO to=intervalUnit)?
;
intervalValue
@ -667,6 +668,27 @@ intervalValue
| STRING
;
intervalUnit
: DAY
| DAYS
| HOUR
| HOURS
| MICROSECOND
| MICROSECONDS
| MILLISECOND
| MILLISECONDS
| MINUTE
| MINUTES
| MONTH
| MONTHS
| SECOND
| SECONDS
| WEEK
| WEEKS
| YEAR
| YEARS
;
colPosition
: FIRST | AFTER identifier
;
@ -795,6 +817,7 @@ ansiNonReserved
| DATA
| DATABASE
| DATABASES
| DAYS
| DBPROPERTIES
| DEFINED
| DELETE
@ -825,6 +848,7 @@ ansiNonReserved
| FUNCTIONS
| GLOBAL
| GROUPING
| HOURS
| IF
| IGNORE
| IMPORT
@ -851,6 +875,12 @@ ansiNonReserved
| LOGICAL
| MACRO
| MAP
| MICROSECOND
| MICROSECONDS
| MILLISECOND
| MILLISECONDS
| MINUTES
| MONTHS
| MSCK
| NO
| NULLS
@ -891,6 +921,7 @@ ansiNonReserved
| ROW
| ROWS
| SCHEMA
| SECONDS
| SEPARATED
| SERDE
| SERDEPROPERTIES
@ -924,7 +955,10 @@ ansiNonReserved
| USE
| VALUES
| VIEW
| WEEK
| WEEKS
| WINDOW
| YEARS
;
defaultReserved
@ -996,6 +1030,8 @@ nonReserved
| DATA
| DATABASE
| DATABASES
| DAY
| DAYS
| DBPROPERTIES
| DEFINED
| DELETE
@ -1037,6 +1073,8 @@ nonReserved
| GROUP
| GROUPING
| HAVING
| HOUR
| HOURS
| IF
| IGNORE
| IMPORT
@ -1067,6 +1105,14 @@ nonReserved
| LOGICAL
| MACRO
| MAP
| MICROSECOND
| MICROSECONDS
| MILLISECOND
| MILLISECONDS
| MINUTE
| MINUTES
| MONTH
| MONTHS
| MSCK
| NO
| NOT
@ -1115,6 +1161,8 @@ nonReserved
| ROLLUP
| ROW
| ROWS
| SECOND
| SECONDS
| SELECT
| SEPARATED
| SERDE
@ -1157,10 +1205,14 @@ nonReserved
| USER
| VALUES
| VIEW
| WEEK
| WEEKS
| WHEN
| WHERE
| WINDOW
| WITH
| YEAR
| YEARS
;
SELECT: 'SELECT';
@ -1199,6 +1251,24 @@ ASC: 'ASC';
DESC: 'DESC';
FOR: 'FOR';
INTERVAL: 'INTERVAL';
YEAR: 'YEAR';
YEARS: 'YEARS';
MONTH: 'MONTH';
MONTHS: 'MONTHS';
WEEK: 'WEEK';
WEEKS: 'WEEKS';
DAY: 'DAY';
DAYS: 'DAYS';
HOUR: 'HOUR';
HOURS: 'HOURS';
MINUTE: 'MINUTE';
MINUTES: 'MINUTES';
SECOND: 'SECOND';
SECONDS: 'SECONDS';
MILLISECOND: 'MILLISECOND';
MILLISECONDS: 'MILLISECONDS';
MICROSECOND: 'MICROSECOND';
MICROSECONDS: 'MICROSECONDS';
CASE: 'CASE';
WHEN: 'WHEN';
THEN: 'THEN';

View file

@ -39,7 +39,6 @@ import org.apache.spark.unsafe.types.CalendarInterval
* CheckAnalysis classes.
*/
class ExpressionParserSuite extends PlanTest {
import CatalystSqlParser._
import org.apache.spark.sql.catalyst.dsl.expressions._
import org.apache.spark.sql.catalyst.dsl.plans._
@ -585,16 +584,7 @@ class ExpressionParserSuite extends PlanTest {
}
}
test("intervals") {
def intervalLiteral(u: String, s: String): Literal = {
Literal(CalendarInterval.fromSingleUnitString(u, s))
}
// Empty interval statement
intercept("interval", "at least one time unit should be given for interval literal")
// Single Intervals.
val units = Seq(
val intervalUnits = Seq(
"year",
"month",
"week",
@ -604,30 +594,50 @@ class ExpressionParserSuite extends PlanTest {
"second",
"millisecond",
"microsecond")
def intervalLiteral(u: String, s: String): Literal = {
Literal(CalendarInterval.fromSingleUnitString(u, s))
}
test("intervals") {
def checkIntervals(intervalValue: String, expected: Literal): Unit = {
assertEqual(s"interval $intervalValue", expected)
// SPARK-23264 Support interval values without INTERVAL clauses if ANSI SQL enabled
withSQLConf(SQLConf.ANSI_SQL_PARSER.key -> "true") {
assertEqual(intervalValue, expected)
}
}
// Empty interval statement
intercept("interval", "at least one time unit should be given for interval literal")
// Single Intervals.
val forms = Seq("", "s")
val values = Seq("0", "10", "-7", "21")
units.foreach { unit =>
intervalUnits.foreach { unit =>
forms.foreach { form =>
values.foreach { value =>
val expected = intervalLiteral(unit, value)
assertEqual(s"interval $value $unit$form", expected)
assertEqual(s"interval '$value' $unit$form", expected)
checkIntervals(s"$value $unit$form", expected)
checkIntervals(s"'$value' $unit$form", expected)
}
}
}
// Hive nanosecond notation.
assertEqual("interval 13.123456789 seconds", intervalLiteral("second", "13.123456789"))
assertEqual("interval -13.123456789 second", intervalLiteral("second", "-13.123456789"))
checkIntervals("13.123456789 seconds", intervalLiteral("second", "13.123456789"))
checkIntervals("-13.123456789 second", intervalLiteral("second", "-13.123456789"))
// Non Existing unit
intercept("interval 10 nanoseconds", "No interval can be constructed")
intercept("interval 10 nanoseconds",
"no viable alternative at input 'interval 10 nanoseconds'")
// Year-Month intervals.
val yearMonthValues = Seq("123-10", "496-0", "-2-3", "-123-0")
yearMonthValues.foreach { value =>
val result = Literal(CalendarInterval.fromYearMonthString(value))
assertEqual(s"interval '$value' year to month", result)
checkIntervals(s"'$value' year to month", result)
}
// Day-Time intervals.
@ -640,22 +650,51 @@ class ExpressionParserSuite extends PlanTest {
"1 0:0:1")
datTimeValues.foreach { value =>
val result = Literal(CalendarInterval.fromDayTimeString(value))
assertEqual(s"interval '$value' day to second", result)
checkIntervals(s"'$value' day to second", result)
}
// Unknown FROM TO intervals
intercept("interval 10 month to second", "Intervals FROM month TO second are not supported.")
intercept("interval 10 month to second",
"Intervals FROM month TO second are not supported.")
// Composed intervals.
assertEqual(
"interval 3 months 22 seconds 1 millisecond",
checkIntervals(
"3 months 22 seconds 1 millisecond",
Literal(new CalendarInterval(3, 22001000L)))
assertEqual(
"interval 3 years '-1-10' year to month 3 weeks '1 0:0:2' day to second",
checkIntervals(
"3 years '-1-10' year to month 3 weeks '1 0:0:2' day to second",
Literal(new CalendarInterval(14,
22 * CalendarInterval.MICROS_PER_DAY + 2 * CalendarInterval.MICROS_PER_SECOND)))
}
test("SPARK-23264 Interval Compatibility tests") {
def checkIntervals(intervalValue: String, expected: Literal): Unit = {
withSQLConf(SQLConf.ANSI_SQL_PARSER.key -> "true") {
assertEqual(intervalValue, expected)
}
// Compatibility tests: If ANSI SQL disabled, `intervalValue` should be parsed as an alias
withSQLConf(SQLConf.ANSI_SQL_PARSER.key -> "false") {
val aliases = defaultParser.parseExpression(intervalValue).collect {
case a @ Alias(_: Literal, name)
if intervalUnits.exists { unit => name.startsWith(unit) } => a
}
assert(aliases.size === 1)
}
}
val forms = Seq("", "s")
val values = Seq("5", "1", "-11", "8")
intervalUnits.foreach { unit =>
forms.foreach { form =>
values.foreach { value =>
val expected = intervalLiteral(unit, value)
checkIntervals(s"$value $unit$form", expected)
checkIntervals(s"'$value' $unit$form", expected)
}
}
}
}
test("composed expressions") {
assertEqual("1 + r.r As q", (Literal(1) + UnresolvedAttribute("r.r")).as("q"))
assertEqual("1 - f('o', o(bar))", Literal(1) - 'f.function("o", 'o.function('bar)))

View file

@ -74,6 +74,7 @@ class TableIdentifierParserSuite extends SparkFunSuite with SQLHelper {
"date",
"datetime",
"day",
"days",
"dbproperties",
"decimal",
"deferred",
@ -113,6 +114,7 @@ class TableIdentifierParserSuite extends SparkFunSuite with SQLHelper {
"grouping",
"hold_ddltime",
"hour",
"hours",
"idxproperties",
"ignore",
"import",
@ -148,9 +150,15 @@ class TableIdentifierParserSuite extends SparkFunSuite with SQLHelper {
"mapjoin",
"materialized",
"metadata",
"microsecond",
"microseconds",
"millisecond",
"milliseconds",
"minus",
"minute",
"minutes",
"month",
"months",
"msck",
"no_drop",
"none",
@ -205,6 +213,7 @@ class TableIdentifierParserSuite extends SparkFunSuite with SQLHelper {
"rows",
"schemas",
"second",
"seconds",
"serde",
"serdeproperties",
"server",
@ -253,11 +262,14 @@ class TableIdentifierParserSuite extends SparkFunSuite with SQLHelper {
"utctimestamp",
"values",
"view",
"week",
"weeks",
"while",
"with",
"work",
"write",
"year")
"year",
"years")
val hiveStrictNonReservedKeyword = Seq(
"anti",
@ -408,6 +420,7 @@ class TableIdentifierParserSuite extends SparkFunSuite with SQLHelper {
"databases",
"date",
"day",
"days",
"dbproperties",
"deallocate",
"dec",
@ -500,6 +513,7 @@ class TableIdentifierParserSuite extends SparkFunSuite with SQLHelper {
"having",
"hold",
"hour",
"hours",
"identity",
"if",
"ignore",
@ -582,13 +596,19 @@ class TableIdentifierParserSuite extends SparkFunSuite with SQLHelper {
"member",
"merge",
"method",
"microsecond",
"microseconds",
"millisecond",
"milliseconds",
"min",
"minus",
"minute",
"minutes",
"mod",
"modifies",
"module",
"month",
"months",
"msck",
"multiset",
"names",
@ -716,6 +736,7 @@ class TableIdentifierParserSuite extends SparkFunSuite with SQLHelper {
"scroll",
"search",
"second",
"seconds",
"section",
"seek",
"select",
@ -826,6 +847,8 @@ class TableIdentifierParserSuite extends SparkFunSuite with SQLHelper {
"varying",
"versioning",
"view",
"week",
"weeks",
"when",
"whenever",
"where",
@ -838,6 +861,7 @@ class TableIdentifierParserSuite extends SparkFunSuite with SQLHelper {
"work",
"write",
"year",
"years",
"zone")
val reservedKeywordsInAnsiMode = Set(
@ -860,6 +884,7 @@ class TableIdentifierParserSuite extends SparkFunSuite with SQLHelper {
"current_time",
"current_timestamp",
"current_user",
"day",
"distinct",
"else",
"end",
@ -873,6 +898,7 @@ class TableIdentifierParserSuite extends SparkFunSuite with SQLHelper {
"grant",
"group",
"having",
"hour",
"in",
"inner",
"intersect",
@ -881,6 +907,8 @@ class TableIdentifierParserSuite extends SparkFunSuite with SQLHelper {
"is",
"leading",
"left",
"minute",
"month",
"natural",
"not",
"null",
@ -897,6 +925,7 @@ class TableIdentifierParserSuite extends SparkFunSuite with SQLHelper {
"semi",
"session_user",
"minus",
"second",
"some",
"table",
"then",
@ -908,7 +937,8 @@ class TableIdentifierParserSuite extends SparkFunSuite with SQLHelper {
"using",
"when",
"where",
"with")
"with",
"year")
val nonReservedKeywordsInAnsiMode = allCandidateKeywords -- reservedKeywordsInAnsiMode

View file

@ -0,0 +1,188 @@
-- Turns on ANSI mode
SET spark.sql.parser.ansi.enabled=true;
select
'1' second,
2 seconds,
'1' minute,
2 minutes,
'1' hour,
2 hours,
'1' day,
2 days,
'1' month,
2 months,
'1' year,
2 years;
select
interval '10-11' year to month,
interval '10' year,
interval '11' month;
select
'10-11' year to month,
'10' year,
'11' month;
select
interval '10 9:8:7.987654321' day to second,
interval '10' day,
interval '11' hour,
interval '12' minute,
interval '13' second,
interval '13.123456789' second;
select
'10 9:8:7.987654321' day to second,
'10' day,
'11' hour,
'12' minute,
'13' second,
'13.123456789' second;
select map(1, interval 1 day, 2, interval 3 week);
select map(1, 1 day, 2, 3 week);
-- Interval year-month arithmetic
create temporary view interval_arithmetic as
select CAST(dateval AS date), CAST(tsval AS timestamp) from values
('2012-01-01', '2012-01-01')
as interval_arithmetic(dateval, tsval);
select
dateval,
dateval - interval '2-2' year to month,
dateval - interval '-2-2' year to month,
dateval + interval '2-2' year to month,
dateval + interval '-2-2' year to month,
- interval '2-2' year to month + dateval,
interval '2-2' year to month + dateval
from interval_arithmetic;
select
dateval,
dateval - '2-2' year to month,
dateval - '-2-2' year to month,
dateval + '2-2' year to month,
dateval + '-2-2' year to month,
- '2-2' year to month + dateval,
'2-2' year to month + dateval
from interval_arithmetic;
select
tsval,
tsval - interval '2-2' year to month,
tsval - interval '-2-2' year to month,
tsval + interval '2-2' year to month,
tsval + interval '-2-2' year to month,
- interval '2-2' year to month + tsval,
interval '2-2' year to month + tsval
from interval_arithmetic;
select
tsval,
tsval - '2-2' year to month,
tsval - '-2-2' year to month,
tsval + '2-2' year to month,
tsval + '-2-2' year to month,
- '2-2' year to month + tsval,
'2-2' year to month + tsval
from interval_arithmetic;
select
interval '2-2' year to month + interval '3-3' year to month,
interval '2-2' year to month - interval '3-3' year to month
from interval_arithmetic;
select
'2-2' year to month + '3-3' year to month,
'2-2' year to month - '3-3' year to month
from interval_arithmetic;
-- Interval day-time arithmetic
select
dateval,
dateval - interval '99 11:22:33.123456789' day to second,
dateval - interval '-99 11:22:33.123456789' day to second,
dateval + interval '99 11:22:33.123456789' day to second,
dateval + interval '-99 11:22:33.123456789' day to second,
-interval '99 11:22:33.123456789' day to second + dateval,
interval '99 11:22:33.123456789' day to second + dateval
from interval_arithmetic;
select
dateval,
dateval - '99 11:22:33.123456789' day to second,
dateval - '-99 11:22:33.123456789' day to second,
dateval + '99 11:22:33.123456789' day to second,
dateval + '-99 11:22:33.123456789' day to second,
- '99 11:22:33.123456789' day to second + dateval,
'99 11:22:33.123456789' day to second + dateval
from interval_arithmetic;
select
tsval,
tsval - interval '99 11:22:33.123456789' day to second,
tsval - interval '-99 11:22:33.123456789' day to second,
tsval + interval '99 11:22:33.123456789' day to second,
tsval + interval '-99 11:22:33.123456789' day to second,
-interval '99 11:22:33.123456789' day to second + tsval,
interval '99 11:22:33.123456789' day to second + tsval
from interval_arithmetic;
select
tsval,
tsval - '99 11:22:33.123456789' day to second,
tsval - '-99 11:22:33.123456789' day to second,
tsval + '99 11:22:33.123456789' day to second,
tsval + '-99 11:22:33.123456789' day to second,
- '99 11:22:33.123456789' day to second + tsval,
'99 11:22:33.123456789' day to second + tsval
from interval_arithmetic;
select
interval '99 11:22:33.123456789' day to second + interval '10 9:8:7.123456789' day to second,
interval '99 11:22:33.123456789' day to second - interval '10 9:8:7.123456789' day to second
from interval_arithmetic;
select
'99 11:22:33.123456789' day to second + '10 9:8:7.123456789' day to second,
'99 11:22:33.123456789' day to second - '10 9:8:7.123456789' day to second
from interval_arithmetic;
-- More tests for interval syntax alternatives
select 30 day;
select 30 day day;
select 30 day day day;
select date '2012-01-01' - 30 day;
select date '2012-01-01' - 30 day day;
select date '2012-01-01' - 30 day day day;
select date '2012-01-01' + '-30' day;
select date '2012-01-01' + interval '-30' day;
-- Unsupported syntax for intervals
select date '2012-01-01' + interval (-30) day;
select date '2012-01-01' + (-30) day;
create temporary view t as select * from values (1), (2) as t(a);
select date '2012-01-01' + interval (a + 1) day from t;
select date '2012-01-01' + (a + 1) day from t;
-- Turns off ANSI mode
SET spark.sql.parser.ansi.enabled=false;

View file

@ -0,0 +1,439 @@
-- Automatically generated by SQLQueryTestSuite
-- Number of queries: 35
-- !query 0
SET spark.sql.parser.ansi.enabled=true
-- !query 0 schema
struct<key:string,value:string>
-- !query 0 output
spark.sql.parser.ansi.enabled true
-- !query 1
select
'1' second,
2 seconds,
'1' minute,
2 minutes,
'1' hour,
2 hours,
'1' day,
2 days,
'1' month,
2 months,
'1' year,
2 years
-- !query 1 schema
struct<interval 1 seconds:calendarinterval,interval 2 seconds:calendarinterval,interval 1 minutes:calendarinterval,interval 2 minutes:calendarinterval,interval 1 hours:calendarinterval,interval 2 hours:calendarinterval,interval 1 days:calendarinterval,interval 2 days:calendarinterval,interval 1 months:calendarinterval,interval 2 months:calendarinterval,interval 1 years:calendarinterval,interval 2 years:calendarinterval>
-- !query 1 output
interval 1 seconds interval 2 seconds interval 1 minutes interval 2 minutes interval 1 hours interval 2 hours interval 1 days interval 2 days interval 1 months interval 2 months interval 1 years interval 2 years
-- !query 2
select
interval '10-11' year to month,
interval '10' year,
interval '11' month
-- !query 2 schema
struct<interval 10 years 11 months:calendarinterval,interval 10 years:calendarinterval,interval 11 months:calendarinterval>
-- !query 2 output
interval 10 years 11 months interval 10 years interval 11 months
-- !query 3
select
'10-11' year to month,
'10' year,
'11' month
-- !query 3 schema
struct<interval 10 years 11 months:calendarinterval,interval 10 years:calendarinterval,interval 11 months:calendarinterval>
-- !query 3 output
interval 10 years 11 months interval 10 years interval 11 months
-- !query 4
select
interval '10 9:8:7.987654321' day to second,
interval '10' day,
interval '11' hour,
interval '12' minute,
interval '13' second,
interval '13.123456789' second
-- !query 4 schema
struct<interval 1 weeks 3 days 9 hours 8 minutes 7 seconds 987 milliseconds 654 microseconds:calendarinterval,interval 1 weeks 3 days:calendarinterval,interval 11 hours:calendarinterval,interval 12 minutes:calendarinterval,interval 13 seconds:calendarinterval,interval 13 seconds 123 milliseconds 456 microseconds:calendarinterval>
-- !query 4 output
interval 1 weeks 3 days 9 hours 8 minutes 7 seconds 987 milliseconds 654 microseconds interval 1 weeks 3 days interval 11 hours interval 12 minutes interval 13 seconds interval 13 seconds 123 milliseconds 456 microseconds
-- !query 5
select
'10 9:8:7.987654321' day to second,
'10' day,
'11' hour,
'12' minute,
'13' second,
'13.123456789' second
-- !query 5 schema
struct<interval 1 weeks 3 days 9 hours 8 minutes 7 seconds 987 milliseconds 654 microseconds:calendarinterval,interval 1 weeks 3 days:calendarinterval,interval 11 hours:calendarinterval,interval 12 minutes:calendarinterval,interval 13 seconds:calendarinterval,interval 13 seconds 123 milliseconds 456 microseconds:calendarinterval>
-- !query 5 output
interval 1 weeks 3 days 9 hours 8 minutes 7 seconds 987 milliseconds 654 microseconds interval 1 weeks 3 days interval 11 hours interval 12 minutes interval 13 seconds interval 13 seconds 123 milliseconds 456 microseconds
-- !query 6
select map(1, interval 1 day, 2, interval 3 week)
-- !query 6 schema
struct<map(1, interval 1 days, 2, interval 3 weeks):map<int,calendarinterval>>
-- !query 6 output
{1:interval 1 days,2:interval 3 weeks}
-- !query 7
select map(1, 1 day, 2, 3 week)
-- !query 7 schema
struct<map(1, interval 1 days, 2, interval 3 weeks):map<int,calendarinterval>>
-- !query 7 output
{1:interval 1 days,2:interval 3 weeks}
-- !query 8
create temporary view interval_arithmetic as
select CAST(dateval AS date), CAST(tsval AS timestamp) from values
('2012-01-01', '2012-01-01')
as interval_arithmetic(dateval, tsval)
-- !query 8 schema
struct<>
-- !query 8 output
-- !query 9
select
dateval,
dateval - interval '2-2' year to month,
dateval - interval '-2-2' year to month,
dateval + interval '2-2' year to month,
dateval + interval '-2-2' year to month,
- interval '2-2' year to month + dateval,
interval '2-2' year to month + dateval
from interval_arithmetic
-- !query 9 schema
struct<dateval:date,CAST(CAST(dateval AS TIMESTAMP) - interval 2 years 2 months AS DATE):date,CAST(CAST(dateval AS TIMESTAMP) - interval -2 years -2 months AS DATE):date,CAST(CAST(dateval AS TIMESTAMP) + interval 2 years 2 months AS DATE):date,CAST(CAST(dateval AS TIMESTAMP) + interval -2 years -2 months AS DATE):date,CAST(CAST(dateval AS TIMESTAMP) + (- interval 2 years 2 months) AS DATE):date,CAST(CAST(dateval AS TIMESTAMP) + interval 2 years 2 months AS DATE):date>
-- !query 9 output
2012-01-01 2009-11-01 2014-03-01 2014-03-01 2009-11-01 2009-11-01 2014-03-01
-- !query 10
select
dateval,
dateval - '2-2' year to month,
dateval - '-2-2' year to month,
dateval + '2-2' year to month,
dateval + '-2-2' year to month,
- '2-2' year to month + dateval,
'2-2' year to month + dateval
from interval_arithmetic
-- !query 10 schema
struct<dateval:date,CAST(CAST(dateval AS TIMESTAMP) - interval 2 years 2 months AS DATE):date,CAST(CAST(dateval AS TIMESTAMP) - interval -2 years -2 months AS DATE):date,CAST(CAST(dateval AS TIMESTAMP) + interval 2 years 2 months AS DATE):date,CAST(CAST(dateval AS TIMESTAMP) + interval -2 years -2 months AS DATE):date,CAST(CAST(dateval AS TIMESTAMP) + (- interval 2 years 2 months) AS DATE):date,CAST(CAST(dateval AS TIMESTAMP) + interval 2 years 2 months AS DATE):date>
-- !query 10 output
2012-01-01 2009-11-01 2014-03-01 2014-03-01 2009-11-01 2009-11-01 2014-03-01
-- !query 11
select
tsval,
tsval - interval '2-2' year to month,
tsval - interval '-2-2' year to month,
tsval + interval '2-2' year to month,
tsval + interval '-2-2' year to month,
- interval '2-2' year to month + tsval,
interval '2-2' year to month + tsval
from interval_arithmetic
-- !query 11 schema
struct<tsval:timestamp,CAST(tsval - interval 2 years 2 months AS TIMESTAMP):timestamp,CAST(tsval - interval -2 years -2 months AS TIMESTAMP):timestamp,CAST(tsval + interval 2 years 2 months AS TIMESTAMP):timestamp,CAST(tsval + interval -2 years -2 months AS TIMESTAMP):timestamp,CAST(tsval + (- interval 2 years 2 months) AS TIMESTAMP):timestamp,CAST(tsval + interval 2 years 2 months AS TIMESTAMP):timestamp>
-- !query 11 output
2012-01-01 00:00:00 2009-11-01 00:00:00 2014-03-01 00:00:00 2014-03-01 00:00:00 2009-11-01 00:00:00 2009-11-01 00:00:00 2014-03-01 00:00:00
-- !query 12
select
tsval,
tsval - '2-2' year to month,
tsval - '-2-2' year to month,
tsval + '2-2' year to month,
tsval + '-2-2' year to month,
- '2-2' year to month + tsval,
'2-2' year to month + tsval
from interval_arithmetic
-- !query 12 schema
struct<tsval:timestamp,CAST(tsval - interval 2 years 2 months AS TIMESTAMP):timestamp,CAST(tsval - interval -2 years -2 months AS TIMESTAMP):timestamp,CAST(tsval + interval 2 years 2 months AS TIMESTAMP):timestamp,CAST(tsval + interval -2 years -2 months AS TIMESTAMP):timestamp,CAST(tsval + (- interval 2 years 2 months) AS TIMESTAMP):timestamp,CAST(tsval + interval 2 years 2 months AS TIMESTAMP):timestamp>
-- !query 12 output
2012-01-01 00:00:00 2009-11-01 00:00:00 2014-03-01 00:00:00 2014-03-01 00:00:00 2009-11-01 00:00:00 2009-11-01 00:00:00 2014-03-01 00:00:00
-- !query 13
select
interval '2-2' year to month + interval '3-3' year to month,
interval '2-2' year to month - interval '3-3' year to month
from interval_arithmetic
-- !query 13 schema
struct<(interval 2 years 2 months + interval 3 years 3 months):calendarinterval,(interval 2 years 2 months - interval 3 years 3 months):calendarinterval>
-- !query 13 output
interval 5 years 5 months interval -1 years -1 months
-- !query 14
select
'2-2' year to month + '3-3' year to month,
'2-2' year to month - '3-3' year to month
from interval_arithmetic
-- !query 14 schema
struct<(interval 2 years 2 months + interval 3 years 3 months):calendarinterval,(interval 2 years 2 months - interval 3 years 3 months):calendarinterval>
-- !query 14 output
interval 5 years 5 months interval -1 years -1 months
-- !query 15
select
dateval,
dateval - interval '99 11:22:33.123456789' day to second,
dateval - interval '-99 11:22:33.123456789' day to second,
dateval + interval '99 11:22:33.123456789' day to second,
dateval + interval '-99 11:22:33.123456789' day to second,
-interval '99 11:22:33.123456789' day to second + dateval,
interval '99 11:22:33.123456789' day to second + dateval
from interval_arithmetic
-- !query 15 schema
struct<dateval:date,CAST(CAST(dateval AS TIMESTAMP) - interval 14 weeks 1 days 11 hours 22 minutes 33 seconds 123 milliseconds 456 microseconds AS DATE):date,CAST(CAST(dateval AS TIMESTAMP) - interval -14 weeks -1 days -11 hours -22 minutes -33 seconds -123 milliseconds -456 microseconds AS DATE):date,CAST(CAST(dateval AS TIMESTAMP) + interval 14 weeks 1 days 11 hours 22 minutes 33 seconds 123 milliseconds 456 microseconds AS DATE):date,CAST(CAST(dateval AS TIMESTAMP) + interval -14 weeks -1 days -11 hours -22 minutes -33 seconds -123 milliseconds -456 microseconds AS DATE):date,CAST(CAST(dateval AS TIMESTAMP) + (- interval 14 weeks 1 days 11 hours 22 minutes 33 seconds 123 milliseconds 456 microseconds) AS DATE):date,CAST(CAST(dateval AS TIMESTAMP) + interval 14 weeks 1 days 11 hours 22 minutes 33 seconds 123 milliseconds 456 microseconds AS DATE):date>
-- !query 15 output
2012-01-01 2011-09-23 2012-04-09 2012-04-09 2011-09-23 2011-09-23 2012-04-09
-- !query 16
select
dateval,
dateval - '99 11:22:33.123456789' day to second,
dateval - '-99 11:22:33.123456789' day to second,
dateval + '99 11:22:33.123456789' day to second,
dateval + '-99 11:22:33.123456789' day to second,
- '99 11:22:33.123456789' day to second + dateval,
'99 11:22:33.123456789' day to second + dateval
from interval_arithmetic
-- !query 16 schema
struct<dateval:date,CAST(CAST(dateval AS TIMESTAMP) - interval 14 weeks 1 days 11 hours 22 minutes 33 seconds 123 milliseconds 456 microseconds AS DATE):date,CAST(CAST(dateval AS TIMESTAMP) - interval -14 weeks -1 days -11 hours -22 minutes -33 seconds -123 milliseconds -456 microseconds AS DATE):date,CAST(CAST(dateval AS TIMESTAMP) + interval 14 weeks 1 days 11 hours 22 minutes 33 seconds 123 milliseconds 456 microseconds AS DATE):date,CAST(CAST(dateval AS TIMESTAMP) + interval -14 weeks -1 days -11 hours -22 minutes -33 seconds -123 milliseconds -456 microseconds AS DATE):date,CAST(CAST(dateval AS TIMESTAMP) + (- interval 14 weeks 1 days 11 hours 22 minutes 33 seconds 123 milliseconds 456 microseconds) AS DATE):date,CAST(CAST(dateval AS TIMESTAMP) + interval 14 weeks 1 days 11 hours 22 minutes 33 seconds 123 milliseconds 456 microseconds AS DATE):date>
-- !query 16 output
2012-01-01 2011-09-23 2012-04-09 2012-04-09 2011-09-23 2011-09-23 2012-04-09
-- !query 17
select
tsval,
tsval - interval '99 11:22:33.123456789' day to second,
tsval - interval '-99 11:22:33.123456789' day to second,
tsval + interval '99 11:22:33.123456789' day to second,
tsval + interval '-99 11:22:33.123456789' day to second,
-interval '99 11:22:33.123456789' day to second + tsval,
interval '99 11:22:33.123456789' day to second + tsval
from interval_arithmetic
-- !query 17 schema
struct<tsval:timestamp,CAST(tsval - interval 14 weeks 1 days 11 hours 22 minutes 33 seconds 123 milliseconds 456 microseconds AS TIMESTAMP):timestamp,CAST(tsval - interval -14 weeks -1 days -11 hours -22 minutes -33 seconds -123 milliseconds -456 microseconds AS TIMESTAMP):timestamp,CAST(tsval + interval 14 weeks 1 days 11 hours 22 minutes 33 seconds 123 milliseconds 456 microseconds AS TIMESTAMP):timestamp,CAST(tsval + interval -14 weeks -1 days -11 hours -22 minutes -33 seconds -123 milliseconds -456 microseconds AS TIMESTAMP):timestamp,CAST(tsval + (- interval 14 weeks 1 days 11 hours 22 minutes 33 seconds 123 milliseconds 456 microseconds) AS TIMESTAMP):timestamp,CAST(tsval + interval 14 weeks 1 days 11 hours 22 minutes 33 seconds 123 milliseconds 456 microseconds AS TIMESTAMP):timestamp>
-- !query 17 output
2012-01-01 00:00:00 2011-09-23 13:37:26.876544 2012-04-09 12:22:33.123456 2012-04-09 12:22:33.123456 2011-09-23 13:37:26.876544 2011-09-23 13:37:26.876544 2012-04-09 12:22:33.123456
-- !query 18
select
tsval,
tsval - '99 11:22:33.123456789' day to second,
tsval - '-99 11:22:33.123456789' day to second,
tsval + '99 11:22:33.123456789' day to second,
tsval + '-99 11:22:33.123456789' day to second,
- '99 11:22:33.123456789' day to second + tsval,
'99 11:22:33.123456789' day to second + tsval
from interval_arithmetic
-- !query 18 schema
struct<tsval:timestamp,CAST(tsval - interval 14 weeks 1 days 11 hours 22 minutes 33 seconds 123 milliseconds 456 microseconds AS TIMESTAMP):timestamp,CAST(tsval - interval -14 weeks -1 days -11 hours -22 minutes -33 seconds -123 milliseconds -456 microseconds AS TIMESTAMP):timestamp,CAST(tsval + interval 14 weeks 1 days 11 hours 22 minutes 33 seconds 123 milliseconds 456 microseconds AS TIMESTAMP):timestamp,CAST(tsval + interval -14 weeks -1 days -11 hours -22 minutes -33 seconds -123 milliseconds -456 microseconds AS TIMESTAMP):timestamp,CAST(tsval + (- interval 14 weeks 1 days 11 hours 22 minutes 33 seconds 123 milliseconds 456 microseconds) AS TIMESTAMP):timestamp,CAST(tsval + interval 14 weeks 1 days 11 hours 22 minutes 33 seconds 123 milliseconds 456 microseconds AS TIMESTAMP):timestamp>
-- !query 18 output
2012-01-01 00:00:00 2011-09-23 13:37:26.876544 2012-04-09 12:22:33.123456 2012-04-09 12:22:33.123456 2011-09-23 13:37:26.876544 2011-09-23 13:37:26.876544 2012-04-09 12:22:33.123456
-- !query 19
select
interval '99 11:22:33.123456789' day to second + interval '10 9:8:7.123456789' day to second,
interval '99 11:22:33.123456789' day to second - interval '10 9:8:7.123456789' day to second
from interval_arithmetic
-- !query 19 schema
struct<(interval 14 weeks 1 days 11 hours 22 minutes 33 seconds 123 milliseconds 456 microseconds + interval 1 weeks 3 days 9 hours 8 minutes 7 seconds 123 milliseconds 456 microseconds):calendarinterval,(interval 14 weeks 1 days 11 hours 22 minutes 33 seconds 123 milliseconds 456 microseconds - interval 1 weeks 3 days 9 hours 8 minutes 7 seconds 123 milliseconds 456 microseconds):calendarinterval>
-- !query 19 output
interval 15 weeks 4 days 20 hours 30 minutes 40 seconds 246 milliseconds 912 microseconds interval 12 weeks 5 days 2 hours 14 minutes 26 seconds
-- !query 20
select
'99 11:22:33.123456789' day to second + '10 9:8:7.123456789' day to second,
'99 11:22:33.123456789' day to second - '10 9:8:7.123456789' day to second
from interval_arithmetic
-- !query 20 schema
struct<(interval 14 weeks 1 days 11 hours 22 minutes 33 seconds 123 milliseconds 456 microseconds + interval 1 weeks 3 days 9 hours 8 minutes 7 seconds 123 milliseconds 456 microseconds):calendarinterval,(interval 14 weeks 1 days 11 hours 22 minutes 33 seconds 123 milliseconds 456 microseconds - interval 1 weeks 3 days 9 hours 8 minutes 7 seconds 123 milliseconds 456 microseconds):calendarinterval>
-- !query 20 output
interval 15 weeks 4 days 20 hours 30 minutes 40 seconds 246 milliseconds 912 microseconds interval 12 weeks 5 days 2 hours 14 minutes 26 seconds
-- !query 21
select 30 day
-- !query 21 schema
struct<interval 4 weeks 2 days:calendarinterval>
-- !query 21 output
interval 4 weeks 2 days
-- !query 22
select 30 day day
-- !query 22 schema
struct<>
-- !query 22 output
org.apache.spark.sql.catalyst.parser.ParseException
no viable alternative at input 'day'(line 1, pos 14)
== SQL ==
select 30 day day
--------------^^^
-- !query 23
select 30 day day day
-- !query 23 schema
struct<>
-- !query 23 output
org.apache.spark.sql.catalyst.parser.ParseException
no viable alternative at input 'day'(line 1, pos 14)
== SQL ==
select 30 day day day
--------------^^^
-- !query 24
select date '2012-01-01' - 30 day
-- !query 24 schema
struct<CAST(CAST(DATE '2012-01-01' AS TIMESTAMP) - interval 4 weeks 2 days AS DATE):date>
-- !query 24 output
2011-12-02
-- !query 25
select date '2012-01-01' - 30 day day
-- !query 25 schema
struct<>
-- !query 25 output
org.apache.spark.sql.catalyst.parser.ParseException
no viable alternative at input 'day'(line 1, pos 34)
== SQL ==
select date '2012-01-01' - 30 day day
----------------------------------^^^
-- !query 26
select date '2012-01-01' - 30 day day day
-- !query 26 schema
struct<>
-- !query 26 output
org.apache.spark.sql.catalyst.parser.ParseException
no viable alternative at input 'day'(line 1, pos 34)
== SQL ==
select date '2012-01-01' - 30 day day day
----------------------------------^^^
-- !query 27
select date '2012-01-01' + '-30' day
-- !query 27 schema
struct<CAST(CAST(DATE '2012-01-01' AS TIMESTAMP) + interval -4 weeks -2 days AS DATE):date>
-- !query 27 output
2011-12-02
-- !query 28
select date '2012-01-01' + interval '-30' day
-- !query 28 schema
struct<CAST(CAST(DATE '2012-01-01' AS TIMESTAMP) + interval -4 weeks -2 days AS DATE):date>
-- !query 28 output
2011-12-02
-- !query 29
select date '2012-01-01' + interval (-30) day
-- !query 29 schema
struct<>
-- !query 29 output
org.apache.spark.sql.catalyst.parser.ParseException
no viable alternative at input 'day'(line 1, pos 42)
== SQL ==
select date '2012-01-01' + interval (-30) day
------------------------------------------^^^
-- !query 30
select date '2012-01-01' + (-30) day
-- !query 30 schema
struct<>
-- !query 30 output
org.apache.spark.sql.catalyst.parser.ParseException
no viable alternative at input 'day'(line 1, pos 33)
== SQL ==
select date '2012-01-01' + (-30) day
---------------------------------^^^
-- !query 31
create temporary view t as select * from values (1), (2) as t(a)
-- !query 31 schema
struct<>
-- !query 31 output
-- !query 32
select date '2012-01-01' + interval (a + 1) day from t
-- !query 32 schema
struct<>
-- !query 32 output
org.apache.spark.sql.catalyst.parser.ParseException
no viable alternative at input 'day'(line 1, pos 44)
== SQL ==
select date '2012-01-01' + interval (a + 1) day from t
--------------------------------------------^^^
-- !query 33
select date '2012-01-01' + (a + 1) day from t
-- !query 33 schema
struct<>
-- !query 33 output
org.apache.spark.sql.catalyst.parser.ParseException
no viable alternative at input 'day'(line 1, pos 35)
== SQL ==
select date '2012-01-01' + (a + 1) day from t
-----------------------------------^^^
-- !query 34
SET spark.sql.parser.ansi.enabled=false
-- !query 34 schema
struct<key:string,value:string>
-- !query 34 output
spark.sql.parser.ansi.enabled false

View file

@ -343,11 +343,11 @@ struct<>
-- !query 36 output
org.apache.spark.sql.catalyst.parser.ParseException
No interval can be constructed(line 1, pos 16)
no viable alternative at input 'interval 10 nanoseconds'(line 1, pos 19)
== SQL ==
select interval 10 nanoseconds
----------------^^^
-------------------^^^
-- !query 37

View file

@ -19,7 +19,7 @@ package org.apache.spark.sql
import java.io.File
import java.net.{MalformedURLException, URL}
import java.sql.Timestamp
import java.sql.{Date, Timestamp}
import java.util.concurrent.atomic.AtomicBoolean
import org.apache.spark.{AccumulatorSuite, SparkException}
@ -413,32 +413,32 @@ class SQLQuerySuite extends QueryTest with SharedSQLContext {
checkAnswer(sql(
"SELECT time FROM timestamps WHERE time='1969-12-31 16:00:00.0'"),
Row(java.sql.Timestamp.valueOf("1969-12-31 16:00:00")))
Row(Timestamp.valueOf("1969-12-31 16:00:00")))
checkAnswer(sql(
"SELECT time FROM timestamps WHERE time=CAST('1969-12-31 16:00:00.001' AS TIMESTAMP)"),
Row(java.sql.Timestamp.valueOf("1969-12-31 16:00:00.001")))
Row(Timestamp.valueOf("1969-12-31 16:00:00.001")))
checkAnswer(sql(
"SELECT time FROM timestamps WHERE time='1969-12-31 16:00:00.001'"),
Row(java.sql.Timestamp.valueOf("1969-12-31 16:00:00.001")))
Row(Timestamp.valueOf("1969-12-31 16:00:00.001")))
checkAnswer(sql(
"SELECT time FROM timestamps WHERE '1969-12-31 16:00:00.001'=time"),
Row(java.sql.Timestamp.valueOf("1969-12-31 16:00:00.001")))
Row(Timestamp.valueOf("1969-12-31 16:00:00.001")))
checkAnswer(sql(
"""SELECT time FROM timestamps WHERE time<'1969-12-31 16:00:00.003'
AND time>'1969-12-31 16:00:00.001'"""),
Row(java.sql.Timestamp.valueOf("1969-12-31 16:00:00.002")))
Row(Timestamp.valueOf("1969-12-31 16:00:00.002")))
checkAnswer(sql(
"""
|SELECT time FROM timestamps
|WHERE time IN ('1969-12-31 16:00:00.001','1969-12-31 16:00:00.002')
""".stripMargin),
Seq(Row(java.sql.Timestamp.valueOf("1969-12-31 16:00:00.001")),
Row(java.sql.Timestamp.valueOf("1969-12-31 16:00:00.002"))))
Seq(Row(Timestamp.valueOf("1969-12-31 16:00:00.001")),
Row(Timestamp.valueOf("1969-12-31 16:00:00.002"))))
checkAnswer(sql(
"SELECT time FROM timestamps WHERE time='123'"),
@ -548,7 +548,7 @@ class SQLQuerySuite extends QueryTest with SharedSQLContext {
test("date row") {
checkAnswer(sql(
"""select cast("2015-01-28" as date) from testData limit 1"""),
Row(java.sql.Date.valueOf("2015-01-28"))
Row(Date.valueOf("2015-01-28"))
)
}
@ -1484,11 +1484,12 @@ class SQLQuerySuite extends QueryTest with SharedSQLContext {
sql("select interval")
}
assert(e1.message.contains("at least one time unit should be given for interval literal"))
// Currently we don't yet support nanosecond
val e2 = intercept[AnalysisException] {
sql("select interval 23 nanosecond")
}
assert(e2.message.contains("No interval can be constructed"))
assert(e2.message.contains("no viable alternative at input 'interval 23 nanosecond'"))
}
test("SPARK-8945: add and subtract expressions for interval type") {