You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@calcite.apache.org by jh...@apache.org on 2018/12/02 00:55:07 UTC

[15/15] calcite git commit: [CALCITE-2699] TIMESTAMPADD function now applies to DATE and TIME as well as TIMESTAMP (xuqianjin)

[CALCITE-2699] TIMESTAMPADD function now applies to DATE and TIME as well as TIMESTAMP (xuqianjin)

Close apache/calcite#936


Project: http://git-wip-us.apache.org/repos/asf/calcite/repo
Commit: http://git-wip-us.apache.org/repos/asf/calcite/commit/18caf38f
Tree: http://git-wip-us.apache.org/repos/asf/calcite/tree/18caf38f
Diff: http://git-wip-us.apache.org/repos/asf/calcite/diff/18caf38f

Branch: refs/heads/master
Commit: 18caf38f83802015043eb06ad8aa49d1efe7ff68
Parents: fbf193b
Author: xuqianjin <x1...@163.com>
Authored: Fri Nov 23 22:15:20 2018 +0800
Committer: Julian Hyde <jh...@apache.org>
Committed: Sat Dec 1 14:43:59 2018 -0800

----------------------------------------------------------------------
 .../calcite/adapter/enumerable/RexImpTable.java | 15 +++++---
 .../sql/fun/SqlTimestampAddFunction.java        | 12 ++++---
 .../calcite/sql/test/SqlOperatorBaseTest.java   | 37 ++++++++++++++++++++
 site/_docs/reference.md                         |  2 +-
 4 files changed, 56 insertions(+), 10 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/calcite/blob/18caf38f/core/src/main/java/org/apache/calcite/adapter/enumerable/RexImpTable.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/adapter/enumerable/RexImpTable.java b/core/src/main/java/org/apache/calcite/adapter/enumerable/RexImpTable.java
index ada4333..7776ac9 100644
--- a/core/src/main/java/org/apache/calcite/adapter/enumerable/RexImpTable.java
+++ b/core/src/main/java/org/apache/calcite/adapter/enumerable/RexImpTable.java
@@ -2617,11 +2617,16 @@ public class RexImpTable {
         case MINUS:
           trop1 = Expressions.negate(trop1);
         }
-        final BuiltInMethod method =
-            operand0.getType().getSqlTypeName() == SqlTypeName.TIMESTAMP
-                ? BuiltInMethod.ADD_MONTHS
-                : BuiltInMethod.ADD_MONTHS_INT;
-        return Expressions.call(method.method, trop0, trop1);
+        switch (typeName) {
+        case TIME:
+          return Expressions.convert_(trop0, long.class);
+        default:
+          final BuiltInMethod method =
+              operand0.getType().getSqlTypeName() == SqlTypeName.TIMESTAMP
+                  ? BuiltInMethod.ADD_MONTHS
+                  : BuiltInMethod.ADD_MONTHS_INT;
+          return Expressions.call(method.method, trop0, trop1);
+        }
 
       case INTERVAL_DAY:
       case INTERVAL_DAY_HOUR:

http://git-wip-us.apache.org/repos/asf/calcite/blob/18caf38f/core/src/main/java/org/apache/calcite/sql/fun/SqlTimestampAddFunction.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/sql/fun/SqlTimestampAddFunction.java b/core/src/main/java/org/apache/calcite/sql/fun/SqlTimestampAddFunction.java
index bc459d0..72b00f0 100644
--- a/core/src/main/java/org/apache/calcite/sql/fun/SqlTimestampAddFunction.java
+++ b/core/src/main/java/org/apache/calcite/sql/fun/SqlTimestampAddFunction.java
@@ -29,13 +29,13 @@ import org.apache.calcite.sql.type.SqlTypeName;
 
 /**
  * The <code>TIMESTAMPADD</code> function, which adds an interval to a
- * timestamp.
+ * datetime (TIMESTAMP, TIME or DATE).
  *
  * <p>The SQL syntax is
  *
  * <blockquote>
  * <code>TIMESTAMPADD(<i>timestamp interval</i>, <i>quantity</i>,
- * <i>timestamp</i>)</code>
+ * <i>datetime</i>)</code>
  * </blockquote>
  *
  * <p>The interval time unit can one of the following literals:<ul>
@@ -51,7 +51,7 @@ import org.apache.calcite.sql.type.SqlTypeName;
  * <li>YEAR (and synonym  SQL_TSI_YEAR)
  * </ul>
  *
- * <p>Returns modified timestamp.
+ * <p>Returns modified datetime.
  */
 public class SqlTimestampAddFunction extends SqlFunction {
 
@@ -85,7 +85,11 @@ public class SqlTimestampAddFunction extends SqlFunction {
             MICROSECOND_PRECISION);
         break;
       default:
-        type = typeFactory.createSqlType(SqlTypeName.TIMESTAMP);
+        if (operandType2.getSqlTypeName() == SqlTypeName.TIME) {
+          type = typeFactory.createSqlType(SqlTypeName.TIME);
+        } else {
+          type = typeFactory.createSqlType(SqlTypeName.TIMESTAMP);
+        }
       }
       break;
     default:

http://git-wip-us.apache.org/repos/asf/calcite/blob/18caf38f/core/src/test/java/org/apache/calcite/sql/test/SqlOperatorBaseTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/calcite/sql/test/SqlOperatorBaseTest.java b/core/src/test/java/org/apache/calcite/sql/test/SqlOperatorBaseTest.java
index 78a2fb7..1a1b750 100644
--- a/core/src/test/java/org/apache/calcite/sql/test/SqlOperatorBaseTest.java
+++ b/core/src/test/java/org/apache/calcite/sql/test/SqlOperatorBaseTest.java
@@ -6957,6 +6957,43 @@ public abstract class SqlOperatorBaseTest {
         "2016-06-30", "DATE NOT NULL");
     tester.checkScalar("timestampadd(MONTH, -1, date '2016-03-31')",
         "2016-02-29", "DATE NOT NULL");
+
+    // TIMESTAMPADD with time; returns a time value.The interval is positive.
+    tester.checkScalar("timestampadd(SECOND, 1, time '23:59:59')",
+        "00:00:00", "TIME(0) NOT NULL");
+    tester.checkScalar("timestampadd(MINUTE, 1, time '00:00:00')",
+        "00:01:00", "TIME(0) NOT NULL");
+    tester.checkScalar("timestampadd(MINUTE, 1, time '23:59:59')",
+        "00:00:59", "TIME(0) NOT NULL");
+    tester.checkScalar("timestampadd(HOUR, 1, time '23:59:59')",
+        "00:59:59", "TIME(0) NOT NULL");
+    tester.checkScalar("timestampadd(DAY, 15, time '23:59:59')",
+        "23:59:59", "TIME(0) NOT NULL");
+    tester.checkScalar("timestampadd(WEEK, 3, time '23:59:59')",
+        "23:59:59", "TIME(0) NOT NULL");
+    tester.checkScalar("timestampadd(MONTH, 6, time '23:59:59')",
+        "23:59:59", "TIME(0) NOT NULL");
+    tester.checkScalar("timestampadd(QUARTER, 1, time '23:59:59')",
+        "23:59:59", "TIME(0) NOT NULL");
+    tester.checkScalar("timestampadd(YEAR, 10, time '23:59:59')",
+        "23:59:59", "TIME(0) NOT NULL");
+    // TIMESTAMPADD with time; returns a time value .The interval is negative.
+    tester.checkScalar("timestampadd(SECOND, -1, time '00:00:00')",
+        "23:59:59", "TIME(0) NOT NULL");
+    tester.checkScalar("timestampadd(MINUTE, -1, time '00:00:00')",
+        "23:59:00", "TIME(0) NOT NULL");
+    tester.checkScalar("timestampadd(HOUR, -1, time '00:00:00')",
+        "23:00:00", "TIME(0) NOT NULL");
+    tester.checkScalar("timestampadd(DAY, -1, time '23:59:59')",
+        "23:59:59", "TIME(0) NOT NULL");
+    tester.checkScalar("timestampadd(WEEK, -1, time '23:59:59')",
+        "23:59:59", "TIME(0) NOT NULL");
+    tester.checkScalar("timestampadd(MONTH, -1, time '23:59:59')",
+        "23:59:59", "TIME(0) NOT NULL");
+    tester.checkScalar("timestampadd(QUARTER, -1, time '23:59:59')",
+        "23:59:59", "TIME(0) NOT NULL");
+    tester.checkScalar("timestampadd(YEAR, -1, time '23:59:59')",
+        "23:59:59", "TIME(0) NOT NULL");
   }
 
   @Test public void testTimestampAddFractionalSeconds() {

http://git-wip-us.apache.org/repos/asf/calcite/blob/18caf38f/site/_docs/reference.md
----------------------------------------------------------------------
diff --git a/site/_docs/reference.md b/site/_docs/reference.md
index e43e255..ab2f4f3 100644
--- a/site/_docs/reference.md
+++ b/site/_docs/reference.md
@@ -1473,7 +1473,7 @@ Not implemented:
 | {fn HOUR(date)} | Equivalent to `EXTRACT(HOUR FROM date)`. Returns an integer between 0 and 23.
 | {fn MINUTE(date)} | Equivalent to `EXTRACT(MINUTE FROM date)`. Returns an integer between 0 and 59.
 | {fn SECOND(date)} | Equivalent to `EXTRACT(SECOND FROM date)`. Returns an integer between 0 and 59.
-| {fn TIMESTAMPADD(timeUnit, count, timestamp)} | Adds an interval of *count* *timeUnit*s to a timestamp
+| {fn TIMESTAMPADD(timeUnit, count, datetime)} | Adds an interval of *count* *timeUnit*s to a datetime
 | {fn TIMESTAMPDIFF(timeUnit, timestamp1, timestamp2)} | Subtracts *timestamp1* from *timestamp2* and returns the result in *timeUnit*s
 
 Not implemented: