From 45c951c1b7beb594260330b683af8b3947078ded Mon Sep 17 00:00:00 2001 From: Jark Wu Date: Mon, 24 Oct 2016 17:48:53 +0800 Subject: [PATCH] [FLINK-4762] [table] Use plural in time interval units --- docs/dev/table_api.md | 6 +- .../flink/api/scala/table/expressionDsl.scala | 49 ++++++++++++++ .../table/expressions/ExpressionParser.scala | 24 ++++--- .../api/table/ExpressionReductionTest.scala | 8 +-- .../expressions/ScalarFunctionsTest.scala | 12 ++-- .../table/expressions/TemporalTypesTest.scala | 64 +++++++++---------- 6 files changed, 110 insertions(+), 53 deletions(-) diff --git a/docs/dev/table_api.md b/docs/dev/table_api.md index d464cb93c40a3..57a2b5cc937a1 100644 --- a/docs/dev/table_api.md +++ b/docs/dev/table_api.md @@ -965,7 +965,7 @@ composite = suffixed | atom ; suffixed = interval | cast | as | aggregation | if | functionCall ; -interval = composite , "." , ("year" | "month" | "day" | "hour" | "minute" | "second" | "milli") ; +interval = composite , "." , ("year" | "years" | "month" | "months" | "day" | "days" | "hour" | "hours" | "minute" | "minutes" | "second" | "seconds" | "milli" | "millis") ; cast = composite , ".cast(" , dataType , ")" ; @@ -998,7 +998,7 @@ If working with exact numeric values or large decimals is required, the Table AP In order to work with temporal values the Table API supports Java SQL's Date, Time, and Timestamp types. In the Scala Table API literals can be defined by using `java.sql.Date.valueOf("2016-06-27")`, `java.sql.Time.valueOf("10:10:42")`, or `java.sql.Timestamp.valueOf("2016-06-27 10:10:42.123")`. The Java and Scala Table API also support calling `"2016-06-27".toDate()`, `"10:10:42".toTime()`, and `"2016-06-27 10:10:42.123".toTimestamp()` for converting Strings into temporal types. *Note:* Since Java's temporal SQL types are time zone dependent, please make sure that the Flink Client and all TaskManagers use the same time zone. -Temporal intervals can be represented as number of months (`Types.INTERVAL_MONTHS`) or number of milliseconds (`Types.INTERVAL_MILLIS`). Intervals of same type can be added or subtracted (e.g. `2.hour + 10.minutes`). Intervals of milliseconds can be added to time points (e.g. `"2016-08-10".toDate + 5.day`). +Temporal intervals can be represented as number of months (`Types.INTERVAL_MONTHS`) or number of milliseconds (`Types.INTERVAL_MILLIS`). Intervals of same type can be added or subtracted (e.g. `1.hour + 10.minutes`). Intervals of milliseconds can be added to time points (e.g. `"2016-08-10".toDate + 5.days`). {% top %} @@ -2092,7 +2092,7 @@ temporalOverlaps(TIMEPOINT, TEMPORAL, TIMEPOINT, TEMPORAL) {% endhighlight %} -

Determines whether two anchored time intervals overlap. Time point and temporal are transformed into a range defined by two time points (start, end). The function evaluates leftEnd >= rightStart && rightEnd >= leftStart. E.g. temporalOverlaps('2:55:00'.toTime, 1.hour, '3:30:00'.toTime, 2.hour) leads to true.

+

Determines whether two anchored time intervals overlap. Time point and temporal are transformed into a range defined by two time points (start, end). The function evaluates leftEnd >= rightStart && rightEnd >= leftStart. E.g. temporalOverlaps('2:55:00'.toTime, 1.hour, '3:30:00'.toTime, 2.hours) leads to true.

diff --git a/flink-libraries/flink-table/src/main/scala/org/apache/flink/api/scala/table/expressionDsl.scala b/flink-libraries/flink-table/src/main/scala/org/apache/flink/api/scala/table/expressionDsl.scala index 77e5b44b6ea1e..5df91750fb32a 100644 --- a/flink-libraries/flink-table/src/main/scala/org/apache/flink/api/scala/table/expressionDsl.scala +++ b/flink-libraries/flink-table/src/main/scala/org/apache/flink/api/scala/table/expressionDsl.scala @@ -321,6 +321,13 @@ trait ImplicitExpressionOperations { */ def year = toMonthInterval(expr, 12) + /** + * Creates an interval of the given number of years. + * + * @return interval of months + */ + def years = year + /** * Creates an interval of the given number of months. * @@ -328,6 +335,13 @@ trait ImplicitExpressionOperations { */ def month = toMonthInterval(expr, 1) + /** + * Creates an interval of the given number of months. + * + * @return interval of months + */ + def months = month + /** * Creates an interval of the given number of days. * @@ -335,6 +349,13 @@ trait ImplicitExpressionOperations { */ def day = toMilliInterval(expr, MILLIS_PER_DAY) + /** + * Creates an interval of the given number of days. + * + * @return interval of milliseconds + */ + def days = day + /** * Creates an interval of the given number of hours. * @@ -342,6 +363,13 @@ trait ImplicitExpressionOperations { */ def hour = toMilliInterval(expr, MILLIS_PER_HOUR) + /** + * Creates an interval of the given number of hours. + * + * @return interval of milliseconds + */ + def hours = hour + /** * Creates an interval of the given number of minutes. * @@ -349,6 +377,13 @@ trait ImplicitExpressionOperations { */ def minute = toMilliInterval(expr, MILLIS_PER_MINUTE) + /** + * Creates an interval of the given number of minutes. + * + * @return interval of milliseconds + */ + def minutes = minute + /** * Creates an interval of the given number of seconds. * @@ -356,12 +391,26 @@ trait ImplicitExpressionOperations { */ def second = toMilliInterval(expr, MILLIS_PER_SECOND) + /** + * Creates an interval of the given number of seconds. + * + * @return interval of milliseconds + */ + def seconds = second + /** * Creates an interval of the given number of milliseconds. * * @return interval of milliseconds */ def milli = toMilliInterval(expr, 1) + + /** + * Creates an interval of the given number of milliseconds. + * + * @return interval of milliseconds + */ + def millis = milli } /** diff --git a/flink-libraries/flink-table/src/main/scala/org/apache/flink/api/table/expressions/ExpressionParser.scala b/flink-libraries/flink-table/src/main/scala/org/apache/flink/api/table/expressions/ExpressionParser.scala index c5e50402b90eb..424d86c00da14 100644 --- a/flink-libraries/flink-table/src/main/scala/org/apache/flink/api/table/expressions/ExpressionParser.scala +++ b/flink-libraries/flink-table/src/main/scala/org/apache/flink/api/table/expressions/ExpressionParser.scala @@ -66,12 +66,19 @@ object ExpressionParser extends JavaTokenParsers with PackratParsers { lazy val EXTRACT: Keyword = Keyword("extract") lazy val FLOOR: Keyword = Keyword("floor") lazy val CEIL: Keyword = Keyword("ceil") + lazy val YEARS: Keyword = Keyword("years") lazy val YEAR: Keyword = Keyword("year") + lazy val MONTHS: Keyword = Keyword("months") lazy val MONTH: Keyword = Keyword("month") + lazy val DAYS: Keyword = Keyword("days") lazy val DAY: Keyword = Keyword("day") + lazy val HOURS: Keyword = Keyword("hours") lazy val HOUR: Keyword = Keyword("hour") + lazy val MINUTES: Keyword = Keyword("minutes") lazy val MINUTE: Keyword = Keyword("minute") + lazy val SECONDS: Keyword = Keyword("seconds") lazy val SECOND: Keyword = Keyword("second") + lazy val MILLIS: Keyword = Keyword("millis") lazy val MILLI: Keyword = Keyword("milli") lazy val STAR: Keyword = Keyword("*") @@ -240,21 +247,22 @@ object ExpressionParser extends JavaTokenParsers with PackratParsers { composite <~ "." ~ TO_TIME ~ opt("()") ^^ { e => Cast(e, SqlTimeTypeInfo.TIME) } lazy val suffixTimeInterval : PackratParser[Expression] = - composite ~ "." ~ (YEAR | MONTH | DAY | HOUR | MINUTE | SECOND | MILLI) ^^ { + composite ~ "." ~ (YEARS | MONTHS | DAYS | HOURS | MINUTES | SECONDS | MILLIS | + YEAR | MONTH | DAY | HOUR | MINUTE | SECOND | MILLI) ^^ { - case expr ~ _ ~ YEAR.key => toMonthInterval(expr, 12) + case expr ~ _ ~ (YEARS.key | YEAR.key) => toMonthInterval(expr, 12) - case expr ~ _ ~ MONTH.key => toMonthInterval(expr, 1) + case expr ~ _ ~ (MONTHS.key | MONTH.key) => toMonthInterval(expr, 1) - case expr ~ _ ~ DAY.key => toMilliInterval(expr, MILLIS_PER_DAY) + case expr ~ _ ~ (DAYS.key | DAY.key) => toMilliInterval(expr, MILLIS_PER_DAY) - case expr ~ _ ~ HOUR.key => toMilliInterval(expr, MILLIS_PER_HOUR) + case expr ~ _ ~ (HOURS.key | HOUR.key) => toMilliInterval(expr, MILLIS_PER_HOUR) - case expr ~ _ ~ MINUTE.key => toMilliInterval(expr, MILLIS_PER_MINUTE) + case expr ~ _ ~ (MINUTES.key | MINUTE.key) => toMilliInterval(expr, MILLIS_PER_MINUTE) - case expr ~ _ ~ SECOND.key => toMilliInterval(expr, MILLIS_PER_SECOND) + case expr ~ _ ~ (SECONDS.key | SECOND.key) => toMilliInterval(expr, MILLIS_PER_SECOND) - case expr ~ _ ~ MILLI.key => toMilliInterval(expr, 1) + case expr ~ _ ~ (MILLIS.key | MILLI.key)=> toMilliInterval(expr, 1) } lazy val suffixed: PackratParser[Expression] = diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/api/table/ExpressionReductionTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/api/table/ExpressionReductionTest.scala index 2f98b801bcfcb..9694687199edd 100644 --- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/api/table/ExpressionReductionTest.scala +++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/api/table/ExpressionReductionTest.scala @@ -146,7 +146,7 @@ class ExpressionReductionTest extends TableTestBase { (11 === 1) ? ("a", "b"), " STRING ".trim, "test" + "string", - "1990-10-14 23:00:00.123".toTimestamp + 10.day + 1.second, + "1990-10-14 23:00:00.123".toTimestamp + 10.days + 1.second, 1.isNull, "TEST".like("%EST"), 2.5.toExpr.floor(), @@ -182,7 +182,7 @@ class ExpressionReductionTest extends TableTestBase { (11 === 1) ? ("a", "b"), " STRING ".trim, "test" + "string", - "1990-10-14 23:00:00.123".toTimestamp + 10.day + 1.second, + "1990-10-14 23:00:00.123".toTimestamp + 10.days + 1.second, 1.isNull, "TEST".like("%EST"), 2.5.toExpr.floor(), @@ -344,7 +344,7 @@ class ExpressionReductionTest extends TableTestBase { (11 === 1) ? ("a", "b"), " STRING ".trim, "test" + "string", - "1990-10-14 23:00:00.123".toTimestamp + 10.day + 1.second, + "1990-10-14 23:00:00.123".toTimestamp + 10.days + 1.second, 1.isNull, "TEST".like("%EST"), 2.5.toExpr.floor(), @@ -380,7 +380,7 @@ class ExpressionReductionTest extends TableTestBase { (11 === 1) ? ("a", "b"), " STRING ".trim, "test" + "string", - "1990-10-14 23:00:00.123".toTimestamp + 10.day + 1.second, + "1990-10-14 23:00:00.123".toTimestamp + 10.days + 1.second, 1.isNull, "TEST".like("%EST"), 2.5.toExpr.floor(), diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/api/table/expressions/ScalarFunctionsTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/api/table/expressions/ScalarFunctionsTest.scala index c930454717be3..46aff01dae7a7 100644 --- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/api/table/expressions/ScalarFunctionsTest.scala +++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/api/table/expressions/ScalarFunctionsTest.scala @@ -821,8 +821,8 @@ class ScalarFunctionsTest extends ExpressionTestBase { @Test def testOverlaps(): Unit = { testAllApis( - temporalOverlaps("2:55:00".toTime, 1.hour, "3:30:00".toTime, 2.hour), - "temporalOverlaps('2:55:00'.toTime, 1.hour, '3:30:00'.toTime, 2.hour)", + temporalOverlaps("2:55:00".toTime, 1.hour, "3:30:00".toTime, 2.hours), + "temporalOverlaps('2:55:00'.toTime, 1.hour, '3:30:00'.toTime, 2.hours)", "(TIME '2:55:00', INTERVAL '1' HOUR) OVERLAPS (TIME '3:30:00', INTERVAL '2' HOUR)", "true") @@ -833,14 +833,14 @@ class ScalarFunctionsTest extends ExpressionTestBase { "true") testAllApis( - temporalOverlaps("9:00:00".toTime, "10:00:00".toTime, "10:15:00".toTime, 3.hour), - "temporalOverlaps('9:00:00'.toTime, '10:00:00'.toTime, '10:15:00'.toTime, 3.hour)", + temporalOverlaps("9:00:00".toTime, "10:00:00".toTime, "10:15:00".toTime, 3.hours), + "temporalOverlaps('9:00:00'.toTime, '10:00:00'.toTime, '10:15:00'.toTime, 3.hours)", "(TIME '9:00:00', TIME '10:00:00') OVERLAPS (TIME '10:15:00', INTERVAL '3' HOUR)", "false") testAllApis( - temporalOverlaps("2011-03-10".toDate, 10.day, "2011-03-19".toDate, 10.day), - "temporalOverlaps('2011-03-10'.toDate, 10.day, '2011-03-19'.toDate, 10.day)", + temporalOverlaps("2011-03-10".toDate, 10.days, "2011-03-19".toDate, 10.days), + "temporalOverlaps('2011-03-10'.toDate, 10.days, '2011-03-19'.toDate, 10.days)", "(DATE '2011-03-10', INTERVAL '10' DAY) OVERLAPS (DATE '2011-03-19', INTERVAL '10' DAY)", "true") diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/api/table/expressions/TemporalTypesTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/api/table/expressions/TemporalTypesTest.scala index 24ff51ccbaf9e..9a34260b70edb 100644 --- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/api/table/expressions/TemporalTypesTest.scala +++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/api/table/expressions/TemporalTypesTest.scala @@ -98,8 +98,8 @@ class TemporalTypesTest extends ExpressionTestBase { "+0-01") testAllApis( - 12.day, - "12.day", + 12.days, + "12.days", "INTERVAL '12' DAY", "+12 00:00:00.000") @@ -110,20 +110,20 @@ class TemporalTypesTest extends ExpressionTestBase { "+0 01:00:00.000") testAllApis( - 3.minute, - "3.minute", + 3.minutes, + "3.minutes", "INTERVAL '3' MINUTE", "+0 00:03:00.000") testAllApis( - 3.second, - "3.second", + 3.seconds, + "3.seconds", "INTERVAL '3' SECOND", "+0 00:00:03.000") testAllApis( - 3.milli, - "3.milli", + 3.millis, + "3.millis", "INTERVAL '0.003' SECOND", "+0 00:00:00.003") } @@ -276,44 +276,44 @@ class TemporalTypesTest extends ExpressionTestBase { @Test def testTimeIntervalArithmetic(): Unit = { testAllApis( - 12.month < 24.month, - "12.month < 24.month", + 12.months < 24.months, + "12.months < 24.months", "INTERVAL '12' MONTH < INTERVAL '24' MONTH", "true") testAllApis( - 8.milli > 10.milli, - "8.milli > 10.milli", + 8.millis > 10.millis, + "8.millis > 10.millis", "INTERVAL '0.008' SECOND > INTERVAL '0.010' SECOND", "false") testAllApis( - 8.year === 8.year, - "8.year === 8.year", + 8.years === 8.years, + "8.years === 8.years", "INTERVAL '8' YEAR = INTERVAL '8' YEAR", "true") testAllApis( - 8.year + 10.month, - "8.year + 10.month", + 8.years + 10.months, + "8.years + 10.months", "INTERVAL '8' YEAR + INTERVAL '10' MONTH", "+8-10") testAllApis( - 8.hour + 10.minute + 12.second + 5.milli, - "8.hour + 10.minute + 12.second + 5.milli", + 8.hours + 10.minutes + 12.seconds + 5.millis, + "8.hours + 10.minutes + 12.seconds + 5.millis", "INTERVAL '8' HOUR + INTERVAL '10' MINUTE + INTERVAL '12.005' SECOND", "+0 08:10:12.005") testAllApis( - 1.minute - 10.second, - "1.minute - 10.second", + 1.minute - 10.seconds, + "1.minute - 10.seconds", "INTERVAL '1' MINUTE - INTERVAL '10' SECOND", "+0 00:00:50.000") testAllApis( - 2.year - 12.month, - "2.year - 12.month", + 2.years - 12.months, + "2.years - 12.months", "INTERVAL '2' YEAR - INTERVAL '12' MONTH", "+1-00") @@ -324,32 +324,32 @@ class TemporalTypesTest extends ExpressionTestBase { "-2-00") testAllApis( - 'f0 + 2.day, - "f0 + 2.day", + 'f0 + 2.days, + "f0 + 2.days", "f0 + INTERVAL '2' DAY", "1990-10-16") testAllApis( - 30.day + 'f0, - "30.day + f0", + 30.days + 'f0, + "30.days + f0", "INTERVAL '30' DAY + f0", "1990-11-13") testAllApis( - 'f1 + 12.hour, - "f1 + 12.hour", + 'f1 + 12.hours, + "f1 + 12.hours", "f1 + INTERVAL '12' HOUR", "22:20:45") testAllApis( - 24.hour + 'f1, - "24.hour + f1", + 24.hours + 'f1, + "24.hours + f1", "INTERVAL '24' HOUR + f1", "10:20:45") testAllApis( - 'f2 + 10.day + 4.milli, - "f2 + 10.day + 4.milli", + 'f2 + 10.days + 4.millis, + "f2 + 10.days + 4.millis", "f2 + INTERVAL '10 00:00:00.004' DAY TO SECOND", "1990-10-24 10:20:45.127") }