You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@flink.apache.org by tw...@apache.org on 2016/11/23 09:06:59 UTC
flink git commit: [FLINK-5124] [table] Support more temporal
arithmetic
Repository: flink
Updated Branches:
refs/heads/master 4c23879a5 -> 4653ad388
[FLINK-5124] [table] Support more temporal arithmetic
This closes #2851.
Project: http://git-wip-us.apache.org/repos/asf/flink/repo
Commit: http://git-wip-us.apache.org/repos/asf/flink/commit/4653ad38
Tree: http://git-wip-us.apache.org/repos/asf/flink/tree/4653ad38
Diff: http://git-wip-us.apache.org/repos/asf/flink/diff/4653ad38
Branch: refs/heads/master
Commit: 4653ad388b05b3ba7e37982bb8af09e7fcbed6be
Parents: 4c23879
Author: twalthr <tw...@apache.org>
Authored: Tue Nov 22 18:30:38 2016 +0100
Committer: twalthr <tw...@apache.org>
Committed: Wed Nov 23 10:05:55 2016 +0100
----------------------------------------------------------------------
.../flink/api/table/codegen/CodeGenerator.scala | 2 +-
.../table/codegen/calls/ScalarOperators.scala | 34 ++-
.../api/table/expressions/arithmetic.scala | 4 +
.../table/expressions/TemporalTypesTest.scala | 215 +++++++++++++++++--
4 files changed, 220 insertions(+), 35 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/flink/blob/4653ad38/flink-libraries/flink-table/src/main/scala/org/apache/flink/api/table/codegen/CodeGenerator.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/main/scala/org/apache/flink/api/table/codegen/CodeGenerator.scala b/flink-libraries/flink-table/src/main/scala/org/apache/flink/api/table/codegen/CodeGenerator.scala
index d40e0e3..2a8ef44 100644
--- a/flink-libraries/flink-table/src/main/scala/org/apache/flink/api/table/codegen/CodeGenerator.scala
+++ b/flink-libraries/flink-table/src/main/scala/org/apache/flink/api/table/codegen/CodeGenerator.scala
@@ -792,7 +792,7 @@ class CodeGenerator(
requireNumeric(right)
generateArithmeticOperator("-", nullCheck, resultType, left, right)
- case MINUS if isTemporal(resultType) =>
+ case MINUS | MINUS_DATE if isTemporal(resultType) =>
val left = operands.head
val right = operands(1)
requireTemporal(left)
http://git-wip-us.apache.org/repos/asf/flink/blob/4653ad38/flink-libraries/flink-table/src/main/scala/org/apache/flink/api/table/codegen/calls/ScalarOperators.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/main/scala/org/apache/flink/api/table/codegen/calls/ScalarOperators.scala b/flink-libraries/flink-table/src/main/scala/org/apache/flink/api/table/codegen/calls/ScalarOperators.scala
index bf76015..75c0149 100644
--- a/flink-libraries/flink-table/src/main/scala/org/apache/flink/api/table/codegen/calls/ScalarOperators.scala
+++ b/flink-libraries/flink-table/src/main/scala/org/apache/flink/api/table/codegen/calls/ScalarOperators.scala
@@ -656,38 +656,36 @@ object ScalarOperators {
right: GeneratedExpression)
: GeneratedExpression = {
- val operator = if (plus) "+" else "-"
+ val op = if (plus) "+" else "-"
(left.resultType, right.resultType) match {
case (l: TimeIntervalTypeInfo[_], r: TimeIntervalTypeInfo[_]) if l == r =>
- generateArithmeticOperator(operator, nullCheck, l, left, right)
+ generateArithmeticOperator(op, nullCheck, l, left, right)
+
+ case (SqlTimeTypeInfo.DATE, TimeIntervalTypeInfo.INTERVAL_MILLIS) =>
+ generateOperatorIfNotNull(nullCheck, SqlTimeTypeInfo.DATE, left, right) {
+ (l, r) => s"$l $op ((int) ($r / ${MILLIS_PER_DAY}L))"
+ }
- case (SqlTimeTypeInfo.DATE, TimeIntervalTypeInfo.INTERVAL_MILLIS) |
- (TimeIntervalTypeInfo.INTERVAL_MILLIS, SqlTimeTypeInfo.DATE) =>
+ case (SqlTimeTypeInfo.DATE, TimeIntervalTypeInfo.INTERVAL_MONTHS) =>
generateOperatorIfNotNull(nullCheck, SqlTimeTypeInfo.DATE, left, right) {
- if (isTimePoint(left.resultType)) {
- (leftTerm, rightTerm) => s"$leftTerm + ((int) ($rightTerm / ${MILLIS_PER_DAY}L))"
- } else {
- (leftTerm, rightTerm) => s"((int) ($leftTerm / ${MILLIS_PER_DAY}L)) + $rightTerm"
- }
+ (l, r) => s"${qualifyMethod(BuiltInMethod.ADD_MONTHS.method)}($l, $op($r))"
}
- case (SqlTimeTypeInfo.TIME, TimeIntervalTypeInfo.INTERVAL_MILLIS) |
- (TimeIntervalTypeInfo.INTERVAL_MILLIS, SqlTimeTypeInfo.TIME) =>
+ case (SqlTimeTypeInfo.TIME, TimeIntervalTypeInfo.INTERVAL_MILLIS) =>
generateOperatorIfNotNull(nullCheck, SqlTimeTypeInfo.TIME, left, right) {
- if (isTimePoint(left.resultType)) {
- (leftTerm, rightTerm) => s"$leftTerm + ((int) ($rightTerm))"
- } else {
- (leftTerm, rightTerm) => s"((int) ($leftTerm)) + $rightTerm"
- }
+ (l, r) => s"$l $op ((int) ($r))"
}
case (SqlTimeTypeInfo.TIMESTAMP, TimeIntervalTypeInfo.INTERVAL_MILLIS) =>
generateOperatorIfNotNull(nullCheck, SqlTimeTypeInfo.TIMESTAMP, left, right) {
- (leftTerm, rightTerm) => s"$leftTerm + $rightTerm"
+ (l, r) => s"$l $op $r"
}
- // TODO more operations when CALCITE-308 is fixed
+ case (SqlTimeTypeInfo.TIMESTAMP, TimeIntervalTypeInfo.INTERVAL_MONTHS) =>
+ generateOperatorIfNotNull(nullCheck, SqlTimeTypeInfo.TIMESTAMP, left, right) {
+ (l, r) => s"${qualifyMethod(BuiltInMethod.ADD_MONTHS.method)}($l, $op($r))"
+ }
case _ =>
throw new CodeGenException("Unsupported temporal arithmetic.")
http://git-wip-us.apache.org/repos/asf/flink/blob/4653ad38/flink-libraries/flink-table/src/main/scala/org/apache/flink/api/table/expressions/arithmetic.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/main/scala/org/apache/flink/api/table/expressions/arithmetic.scala b/flink-libraries/flink-table/src/main/scala/org/apache/flink/api/table/expressions/arithmetic.scala
index cf4f82a..8702886 100644
--- a/flink-libraries/flink-table/src/main/scala/org/apache/flink/api/table/expressions/arithmetic.scala
+++ b/flink-libraries/flink-table/src/main/scala/org/apache/flink/api/table/expressions/arithmetic.scala
@@ -129,6 +129,10 @@ case class Minus(left: Expression, right: Expression) extends BinaryArithmetic {
override private[flink] def validateInput(): ValidationResult = {
if (isTimeInterval(left.resultType) && left.resultType == right.resultType) {
ValidationSuccess
+ } else if (isTimePoint(left.resultType) && isTimeInterval(right.resultType)) {
+ ValidationSuccess
+ } else if (isTimeInterval(left.resultType) && isTimePoint(right.resultType)) {
+ ValidationSuccess
} else {
super.validateInput()
}
http://git-wip-us.apache.org/repos/asf/flink/blob/4653ad38/flink-libraries/flink-table/src/test/scala/org/apache/flink/api/table/expressions/TemporalTypesTest.scala
----------------------------------------------------------------------
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 9a34260..0547552 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
@@ -275,6 +275,9 @@ class TemporalTypesTest extends ExpressionTestBase {
@Test
def testTimeIntervalArithmetic(): Unit = {
+
+ // interval months comparison
+
testAllApis(
12.months < 24.months,
"12.months < 24.months",
@@ -282,17 +285,27 @@ class TemporalTypesTest extends ExpressionTestBase {
"true")
testAllApis(
+ 8.years === 8.years,
+ "8.years === 8.years",
+ "INTERVAL '8' YEAR = INTERVAL '8' YEAR",
+ "true")
+
+ // interval millis comparison
+
+ testAllApis(
8.millis > 10.millis,
"8.millis > 10.millis",
"INTERVAL '0.008' SECOND > INTERVAL '0.010' SECOND",
"false")
testAllApis(
- 8.years === 8.years,
- "8.years === 8.years",
- "INTERVAL '8' YEAR = INTERVAL '8' YEAR",
+ 8.millis === 8.millis,
+ "8.millis === 8.millis",
+ "INTERVAL '0.008' SECOND = INTERVAL '0.008' SECOND",
"true")
+ // interval months addition/subtraction
+
testAllApis(
8.years + 10.months,
"8.years + 10.months",
@@ -300,6 +313,20 @@ class TemporalTypesTest extends ExpressionTestBase {
"+8-10")
testAllApis(
+ 2.years - 12.months,
+ "2.years - 12.months",
+ "INTERVAL '2' YEAR - INTERVAL '12' MONTH",
+ "+1-00")
+
+ testAllApis(
+ -2.years,
+ "-2.years",
+ "-INTERVAL '2' YEAR",
+ "-2-00")
+
+ // interval millis addition/subtraction
+
+ testAllApis(
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",
@@ -312,46 +339,202 @@ class TemporalTypesTest extends ExpressionTestBase {
"+0 00:00:50.000")
testAllApis(
- 2.years - 12.months,
- "2.years - 12.months",
- "INTERVAL '2' YEAR - INTERVAL '12' MONTH",
- "+1-00")
+ -10.seconds,
+ "-10.seconds",
+ "-INTERVAL '10' SECOND",
+ "-0 00:00:10.000")
- testAllApis(
- -'f9.cast(Types.INTERVAL_MONTHS),
- "-f9.cast(INTERVAL_MONTHS)",
- "-CAST(f9 AS INTERVAL YEAR)",
- "-2-00")
+ // addition to date
+ // interval millis
testAllApis(
'f0 + 2.days,
"f0 + 2.days",
"f0 + INTERVAL '2' DAY",
"1990-10-16")
+ // interval millis
testAllApis(
30.days + 'f0,
"30.days + f0",
"INTERVAL '30' DAY + f0",
"1990-11-13")
+ // interval months
+ testAllApis(
+ 'f0 + 2.months,
+ "f0 + 2.months",
+ "f0 + INTERVAL '2' MONTH",
+ "1990-12-14")
+
+ // interval months
+ testAllApis(
+ 2.months + 'f0,
+ "2.months + f0",
+ "INTERVAL '2' MONTH + f0",
+ "1990-12-14")
+
+ // addition to time
+
+ // interval millis
testAllApis(
'f1 + 12.hours,
"f1 + 12.hours",
"f1 + INTERVAL '12' HOUR",
"22:20:45")
+ // interval millis
testAllApis(
- 24.hours + 'f1,
- "24.hours + f1",
- "INTERVAL '24' HOUR + f1",
- "10:20:45")
+ 12.hours + 'f1,
+ "12.hours + f1",
+ "INTERVAL '12' HOUR + f1",
+ "22:20:45")
+
+ // addition to timestamp
+ // interval millis
testAllApis(
'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")
+
+ // interval millis
+ testAllApis(
+ 10.days + 'f2 + 4.millis,
+ "10.days + f2 + 4.millis",
+ "INTERVAL '10 00:00:00.004' DAY TO SECOND + f2",
+ "1990-10-24 10:20:45.127")
+
+ // interval months
+ testAllApis(
+ 'f2 + 10.years,
+ "f2 + 10.years",
+ "f2 + INTERVAL '10' YEAR",
+ "2000-10-14 10:20:45.123")
+
+ // interval months
+ testAllApis(
+ 10.years + 'f2,
+ "10.years + f2",
+ "INTERVAL '10' YEAR + f2",
+ "2000-10-14 10:20:45.123")
+
+ // subtraction from date
+
+ // interval millis
+ testAllApis(
+ 'f0 - 2.days,
+ "f0 - 2.days",
+ "f0 - INTERVAL '2' DAY",
+ "1990-10-12")
+
+ // interval millis
+ testAllApis(
+ -30.days + 'f0,
+ "-30.days + f0",
+ "INTERVAL '-30' DAY + f0",
+ "1990-09-14")
+
+ // interval months
+ testAllApis(
+ 'f0 - 2.months,
+ "f0 - 2.months",
+ "f0 - INTERVAL '2' MONTH",
+ "1990-08-14")
+
+ // interval months
+ testAllApis(
+ -2.months + 'f0,
+ "-2.months + f0",
+ "-INTERVAL '2' MONTH + f0",
+ "1990-08-14")
+
+ // subtraction from time
+
+ // interval millis
+ testAllApis(
+ 'f1 - 12.hours,
+ "f1 - 12.hours",
+ "f1 - INTERVAL '12' HOUR",
+ "22:20:45")
+
+ // interval millis
+ testAllApis(
+ -12.hours + 'f1,
+ "-12.hours + f1",
+ "INTERVAL '-12' HOUR + f1",
+ "22:20:45")
+
+ // subtraction from timestamp
+
+ // interval millis
+ testAllApis(
+ 'f2 - 10.days - 4.millis,
+ "f2 - 10.days - 4.millis",
+ "f2 - INTERVAL '10 00:00:00.004' DAY TO SECOND",
+ "1990-10-04 10:20:45.119")
+
+ // interval millis
+ testAllApis(
+ -10.days + 'f2 - 4.millis,
+ "-10.days + f2 - 4.millis",
+ "INTERVAL '-10 00:00:00.004' DAY TO SECOND + f2",
+ "1990-10-04 10:20:45.119")
+
+ // interval months
+ testAllApis(
+ 'f2 - 10.years,
+ "f2 - 10.years",
+ "f2 - INTERVAL '10' YEAR",
+ "1980-10-14 10:20:45.123")
+
+ // interval months
+ testAllApis(
+ -10.years + 'f2,
+ "-10.years + f2",
+ "INTERVAL '-10' YEAR + f2",
+ "1980-10-14 10:20:45.123")
+
+ // casting
+
+ testAllApis(
+ -'f9.cast(Types.INTERVAL_MONTHS),
+ "-f9.cast(INTERVAL_MONTHS)",
+ "-CAST(f9 AS INTERVAL YEAR)",
+ "-2-00")
+
+ testAllApis(
+ -'f10.cast(Types.INTERVAL_MILLIS),
+ "-f10.cast(INTERVAL_MILLIS)",
+ "-CAST(f10 AS INTERVAL SECOND)",
+ "-0 00:00:12.000")
+
+ // addition/subtraction of interval millis and interval months
+
+ testAllApis(
+ 'f0 + 2.days + 1.month,
+ "f0 + 2.days + 1.month",
+ "f0 + INTERVAL '2' DAY + INTERVAL '1' MONTH",
+ "1990-11-16")
+
+ testAllApis(
+ 'f0 - 2.days - 1.month,
+ "f0 - 2.days - 1.month",
+ "f0 - INTERVAL '2' DAY - INTERVAL '1' MONTH",
+ "1990-09-12")
+
+ testAllApis(
+ 'f2 + 2.days + 1.month,
+ "f2 + 2.days + 1.month",
+ "f2 + INTERVAL '2' DAY + INTERVAL '1' MONTH",
+ "1990-11-16 10:20:45.123")
+
+ testAllApis(
+ 'f2 - 2.days - 1.month,
+ "f2 - 2.days - 1.month",
+ "f2 - INTERVAL '2' DAY - INTERVAL '1' MONTH",
+ "1990-09-12 10:20:45.123")
}
// ----------------------------------------------------------------------------------------------