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 2016/03/08 07:13:24 UTC
[4/5] calcite git commit: [CALCITE-1124] Add TIMESTAMPADD,
TIMESTAMPDIFF functions (Arina Ielchiieva)
[CALCITE-1124] Add TIMESTAMPADD, TIMESTAMPDIFF functions (Arina Ielchiieva)
Close apache/calcite#204
Project: http://git-wip-us.apache.org/repos/asf/calcite/repo
Commit: http://git-wip-us.apache.org/repos/asf/calcite/commit/0b9ea986
Tree: http://git-wip-us.apache.org/repos/asf/calcite/tree/0b9ea986
Diff: http://git-wip-us.apache.org/repos/asf/calcite/diff/0b9ea986
Branch: refs/heads/master
Commit: 0b9ea986b847c325da009376d3b9031c9303090e
Parents: cf5d07b
Author: Arina Ielchiieva <ar...@gmail.com>
Authored: Thu Mar 3 17:07:10 2016 +0200
Committer: Julian Hyde <jh...@apache.org>
Committed: Mon Mar 7 21:26:48 2016 -0800
----------------------------------------------------------------------
core/src/main/codegen/templates/Parser.jj | 135 +++++++++++++++++++
.../apache/calcite/sql/TimestampInterval.java | 47 +++++++
.../calcite/sql/fun/SqlStdOperatorTable.java | 63 +++++++++
.../calcite/sql/parser/SqlParserTest.java | 41 ++++++
.../calcite/sql/test/SqlOperatorBaseTest.java | 15 +++
.../apache/calcite/test/SqlValidatorTest.java | 48 +++++++
site/_docs/reference.md | 16 +++
7 files changed, 365 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/calcite/blob/0b9ea986/core/src/main/codegen/templates/Parser.jj
----------------------------------------------------------------------
diff --git a/core/src/main/codegen/templates/Parser.jj b/core/src/main/codegen/templates/Parser.jj
index ce4920b..01c35bb 100644
--- a/core/src/main/codegen/templates/Parser.jj
+++ b/core/src/main/codegen/templates/Parser.jj
@@ -82,6 +82,7 @@ import org.apache.calcite.sql.SqlUtil;
import org.apache.calcite.sql.SqlWindow;
import org.apache.calcite.sql.SqlWith;
import org.apache.calcite.sql.SqlWithItem;
+import org.apache.calcite.sql.TimestampInterval;
import org.apache.calcite.sql.fun.SqlCase;
import org.apache.calcite.sql.fun.SqlStdOperatorTable;
import org.apache.calcite.sql.fun.SqlTrimFunction;
@@ -3438,6 +3439,64 @@ TimeUnit TimeUnit() :
}
}
+SqlLiteral TimestampInterval() :
+{
+SqlLiteral.SqlSymbol symbol = null;
+}
+{
+ (
+ ( <FRAC_SECOND> | <MICROSECOND> | <SQL_TSI_FRAC_SECOND> | <SQL_TSI_MICROSECOND> )
+ {
+ symbol = TimestampInterval.MICROSECOND;
+ }
+ |
+ ( <SECOND> | <SQL_TSI_SECOND> )
+ {
+ symbol = TimestampInterval.SECOND;
+ }
+ |
+ ( <MINUTE> | <SQL_TSI_MINUTE> )
+ {
+ symbol = TimestampInterval.MINUTE;
+ }
+ |
+ ( <HOUR> | <SQL_TSI_HOUR> )
+ {
+ symbol = TimestampInterval.HOUR;
+ }
+ |
+ ( <DAY> | <SQL_TSI_DAY> )
+ {
+ symbol = TimestampInterval.DAY;
+ }
+ |
+ (<WEEK> | <SQL_TSI_WEEK> )
+ {
+ symbol = TimestampInterval.WEEK;
+ }
+ |
+ ( <MONTH> | <SQL_TSI_MONTH> )
+ {
+ symbol = TimestampInterval.MONTH;
+ }
+ |
+ ( <QUARTER> | <SQL_TSI_QUARTER> )
+ {
+ symbol = TimestampInterval.QUARTER;
+ }
+ |
+ ( <YEAR> | <SQL_TSI_YEAR> )
+ {
+ symbol = TimestampInterval.YEAR;
+ }
+ )
+ {
+ return SqlLiteral.createSymbol(symbol, getPos());
+ }
+}
+
+
+
/**
* Parses a dynamic parameter marker.
*/
@@ -4143,6 +4202,50 @@ SqlNode BuiltinFunctionCall() :
}
)
|
+ (
+ <TIMESTAMPADD>
+ {
+ pos = getPos();
+ SqlLiteral interval;
+ }
+ <LPAREN>
+ interval = TimestampInterval()
+ { args = startList(interval); }
+ <COMMA>
+ e = Expression(ExprContext.ACCEPT_SUBQUERY)
+ { args.add(e); }
+ <COMMA>
+ e = Expression(ExprContext.ACCEPT_SUBQUERY)
+ { args.add(e); }
+ <RPAREN>
+ {
+ return SqlStdOperatorTable.TIMESTAMP_ADD.createCall(
+ pos, SqlParserUtil.toNodeArray(args));
+ }
+ )
+ |
+ (
+ <TIMESTAMPDIFF>
+ {
+ pos = getPos();
+ SqlLiteral interval;
+ }
+ <LPAREN>
+ interval = TimestampInterval()
+ { args = startList(interval); }
+ <COMMA>
+ e = Expression(ExprContext.ACCEPT_SUBQUERY)
+ { args.add(e); }
+ <COMMA>
+ e = Expression(ExprContext.ACCEPT_SUBQUERY)
+ { args.add(e); }
+ <RPAREN>
+ {
+ return SqlStdOperatorTable.TIMESTAMP_DIFF.createCall(
+ pos, SqlParserUtil.toNodeArray(args));
+ }
+ )
+ |
{
SqlNode node;
}
@@ -4810,6 +4913,7 @@ SqlPostfixOperator PostfixRowOperator() :
| < FOREIGN: "FOREIGN" >
| < FORTRAN: "FORTRAN" >
| < FOUND: "FOUND" >
+ | < FRAC_SECOND: "FRAC_SECOND" >
| < FREE: "FREE" >
| < FROM: "FROM" >
| < FULL: "FULL" >
@@ -4892,6 +4996,7 @@ SqlPostfixOperator PostfixRowOperator() :
| < MESSAGE_OCTET_LENGTH: "MESSAGE_OCTET_LENGTH" >
| < MESSAGE_TEXT: "MESSAGE_TEXT" >
| < METHOD: "METHOD" >
+ | < MICROSECOND: "MICROSECOND" >
| < MIN: "MIN" >
| < MINUTE: "MINUTE" >
| < MINVALUE: "MINVALUE" >
@@ -4975,6 +5080,7 @@ SqlPostfixOperator PostfixRowOperator() :
| < PRIVILEGES: "PRIVILEGES" >
| < PROCEDURE: "PROCEDURE" >
| < PUBLIC: "PUBLIC" >
+ | < QUARTER: "QUARTER" >
| < RANGE: "RANGE" >
| < RANK: "RANK" >
| < READ: "READ" >
@@ -5057,6 +5163,16 @@ SqlPostfixOperator PostfixRowOperator() :
| < SQLEXCEPTION: "SQLEXCEPTION" >
| < SQLSTATE: "SQLSTATE" >
| < SQLWARNING: "SQLWARNING" >
+ | < SQL_TSI_DAY: "SQL_TSI_DAY" >
+ | < SQL_TSI_FRAC_SECOND: "SQL_TSI_FRAC_SECOND" >
+ | < SQL_TSI_HOUR: "SQL_TSI_HOUR" >
+ | < SQL_TSI_MICROSECOND: "SQL_TSI_MICROSECOND" >
+ | < SQL_TSI_MINUTE: "SQL_TSI_MINUTE" >
+ | < SQL_TSI_MONTH: "SQL_TSI_MONTH" >
+ | < SQL_TSI_QUARTER: "SQL_TSI_QUARTER" >
+ | < SQL_TSI_SECOND: "SQL_TSI_SECOND" >
+ | < SQL_TSI_WEEK: "SQL_TSI_WEEK" >
+ | < SQL_TSI_YEAR: "SQL_TSI_YEAR" >
| < SQRT: "SQRT" >
| < START: "START" >
| < STATE: "STATE" >
@@ -5083,6 +5199,8 @@ SqlPostfixOperator PostfixRowOperator() :
| < TIES: "TIES" >
| < TIME: "TIME" >
| < TIMESTAMP: "TIMESTAMP" >
+ | < TIMESTAMPADD: "TIMESTAMPADD" >
+ | < TIMESTAMPDIFF: "TIMESTAMPDIFF" >
| < TIMEZONE_HOUR: "TIMEZONE_HOUR" >
| < TIMEZONE_MINUTE: "TIMEZONE_MINUTE" >
| < TINYINT: "TINYINT" >
@@ -5133,6 +5251,7 @@ SqlPostfixOperator PostfixRowOperator() :
| < VARYING: "VARYING" >
| < VERSION: "VERSION" >
| < VIEW: "VIEW" >
+ | < WEEK: "WEEK" >
| < WHEN: "WHEN" >
| < WHENEVER: "WHENEVER" >
| < WHERE: "WHERE" >
@@ -5254,6 +5373,7 @@ String CommonNonReservedKeyWord() :
| <FOLLOWING>
| <FORTRAN>
| <FOUND>
+ | <FRAC_SECOND>
| <G>
| <GENERAL>
| <GENERATED>
@@ -5286,6 +5406,7 @@ String CommonNonReservedKeyWord() :
| <MAP>
| <MATCHED>
| <MAXVALUE>
+ | <MICROSECOND>
| <MESSAGE_LENGTH>
| <MESSAGE_OCTET_LENGTH>
| <MESSAGE_TEXT>
@@ -5327,6 +5448,7 @@ String CommonNonReservedKeyWord() :
| <PRIOR>
| <PRIVILEGES>
| <PUBLIC>
+ | <QUARTER>
| <READ>
| <RELATIVE>
| <REPEATABLE>
@@ -5362,6 +5484,16 @@ String CommonNonReservedKeyWord() :
| <SOURCE>
| <SPACE>
| <SPECIFIC_NAME>
+ | <SQL_TSI_DAY>
+ | <SQL_TSI_FRAC_SECOND>
+ | <SQL_TSI_HOUR>
+ | <SQL_TSI_MICROSECOND>
+ | <SQL_TSI_MINUTE>
+ | <SQL_TSI_MONTH>
+ | <SQL_TSI_QUARTER>
+ | <SQL_TSI_SECOND>
+ | <SQL_TSI_WEEK>
+ | <SQL_TSI_YEAR>
| <STATE>
| <STATEMENT>
| <STRUCTURE>
@@ -5371,6 +5503,8 @@ String CommonNonReservedKeyWord() :
| <TABLE_NAME>
| <TEMPORARY>
| <TIES>
+ | <TIMESTAMPADD>
+ | <TIMESTAMPDIFF>
| <TOP_LEVEL_COUNT>
| <TRANSACTION>
| <TRANSACTIONS_ACTIVE>
@@ -5393,6 +5527,7 @@ String CommonNonReservedKeyWord() :
| <USER_DEFINED_TYPE_SCHEMA>
| <VERSION>
| <VIEW>
+ | <WEEK>
| <WRAPPER>
| <WORK>
| <WRITE>
http://git-wip-us.apache.org/repos/asf/calcite/blob/0b9ea986/core/src/main/java/org/apache/calcite/sql/TimestampInterval.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/sql/TimestampInterval.java b/core/src/main/java/org/apache/calcite/sql/TimestampInterval.java
new file mode 100644
index 0000000..d586d4a
--- /dev/null
+++ b/core/src/main/java/org/apache/calcite/sql/TimestampInterval.java
@@ -0,0 +1,47 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to you under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.calcite.sql;
+
+import org.apache.calcite.sql.parser.SqlParserPos;
+
+/**
+ * Enumerates the timestamp intervals.
+ */
+public enum TimestampInterval implements SqlLiteral.SqlSymbol {
+
+ MICROSECOND,
+ SECOND,
+ MINUTE,
+ HOUR,
+ DAY,
+ WEEK,
+ MONTH,
+ QUARTER,
+ YEAR;
+
+ /**
+ * Creates a parse-tree node representing an occurrence of this
+ * condition type keyword at a particular position in the parsed
+ * text.
+ */
+ public SqlLiteral symbol(SqlParserPos pos) {
+ return SqlLiteral.createSymbol(this, pos);
+ }
+
+}
+
+// End TimestampInterval.java
http://git-wip-us.apache.org/repos/asf/calcite/blob/0b9ea986/core/src/main/java/org/apache/calcite/sql/fun/SqlStdOperatorTable.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/sql/fun/SqlStdOperatorTable.java b/core/src/main/java/org/apache/calcite/sql/fun/SqlStdOperatorTable.java
index ece34a5..98d2e85 100644
--- a/core/src/main/java/org/apache/calcite/sql/fun/SqlStdOperatorTable.java
+++ b/core/src/main/java/org/apache/calcite/sql/fun/SqlStdOperatorTable.java
@@ -46,6 +46,7 @@ import org.apache.calcite.sql.type.InferTypes;
import org.apache.calcite.sql.type.OperandTypes;
import org.apache.calcite.sql.type.ReturnTypes;
import org.apache.calcite.sql.type.SqlOperandCountRanges;
+import org.apache.calcite.sql.type.SqlTypeFamily;
import org.apache.calcite.sql.type.SqlTypeName;
import org.apache.calcite.sql.util.ReflectiveSqlOperatorTable;
import org.apache.calcite.sql.validate.SqlModality;
@@ -1315,6 +1316,68 @@ public class SqlStdOperatorTable extends ReflectiveSqlOperatorTable {
new SqlCurrentDateFunction();
/**
+ * <p>Timestamp modifying or calculating difference functions.
+ * As first parameter take timestamp interval.
+ * </p>
+ *
+ * <p>Interval can one of the following literals:<br>
+ * <i>FRAC_SECOND, MICROSECOND, SQL_TSI_FRAC_SECOND, SQL_TSI_MICROSECOND</i><br>
+ * <i>SECOND, SQL_TSI_SECOND</i><br>
+ * <i>MINUTE, SQL_TSI_MINUTE</i><br>
+ * <i>HOUR, SQL_TSI_HOUR</i><br>
+ * <i>DAY, SQL_TSI_DAY</i><br>
+ * <i>WEEK, SQL_TSI_WEEK</i><br>
+ * <i>MONTH, SQL_TSI_MONTH</i><br>
+ * <i>QUARTER, SQL_TSI_QUARTER</i><br>
+ * <i>YEAR, SQL_TSI_YEAR</i><br>
+ * </p>
+ */
+
+ /**
+ * <p>The SQL <code>TIMESTAMP_ADD</code> function.
+ * Adds interval to timestamp.</p>
+ *
+ * <p>The SQL syntax is
+ *
+ * <blockquote>
+ * <code>TIMESTAMP_ADD(<i>timestamp interval</i>,<i>quantity</i>,<i>timestamp</i>)</code>
+ * </blockquote><br>
+ *
+ * Returns modified timestamp.</p>
+ */
+ public static final SqlFunction TIMESTAMP_ADD =
+ new SqlFunction(
+ "TIMESTAMPADD",
+ SqlKind.OTHER_FUNCTION,
+ ReturnTypes.ARG2,
+ null,
+ OperandTypes.family(
+ SqlTypeFamily.ANY, SqlTypeFamily.INTEGER, SqlTypeFamily.DATETIME),
+ SqlFunctionCategory.TIMEDATE);
+
+ /**
+ * <p>The SQL <code>TIMESTAMP_DIFF</code> function.
+ * Calculates difference between two timestamps.</p>
+ *
+ * <p>The SQL syntax is
+ *
+ * <blockquote>
+ * <code>TIMESTAMP_DIFF(<i>timestamp interval</i>,<i>timestamp</i>,<i>timestamp</i>)</code>
+ * </blockquote><br>
+ *
+ * Returns difference between two timestamps in indicated timestamp interval.</p>
+ */
+ public static final SqlFunction TIMESTAMP_DIFF = new SqlFunction(
+ "TIMESTAMPDIFF",
+ SqlKind.OTHER_FUNCTION,
+ ReturnTypes.INTEGER_NULLABLE,
+ null,
+ OperandTypes.family(
+ SqlTypeFamily.ANY, SqlTypeFamily.DATETIME, SqlTypeFamily.DATETIME),
+ SqlFunctionCategory.TIMEDATE);
+
+
+ /**
* Use of the <code>IN_FENNEL</code> operator forces the argument to be
* evaluated in Fennel. Otherwise acts as identity function.
*/
http://git-wip-us.apache.org/repos/asf/calcite/blob/0b9ea986/core/src/test/java/org/apache/calcite/sql/parser/SqlParserTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/calcite/sql/parser/SqlParserTest.java b/core/src/test/java/org/apache/calcite/sql/parser/SqlParserTest.java
index 31dbd58..858e8a0 100644
--- a/core/src/test/java/org/apache/calcite/sql/parser/SqlParserTest.java
+++ b/core/src/test/java/org/apache/calcite/sql/parser/SqlParserTest.java
@@ -29,6 +29,9 @@ import org.apache.calcite.util.ConversionUtil;
import org.apache.calcite.util.TestUtil;
import org.apache.calcite.util.Util;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+
import org.junit.Ignore;
import org.junit.Test;
@@ -39,7 +42,10 @@ import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.net.URL;
+import java.util.Arrays;
+import java.util.List;
import java.util.Locale;
+import java.util.Map;
import static org.hamcrest.CoreMatchers.equalTo;
import static org.junit.Assert.assertEquals;
@@ -5525,6 +5531,41 @@ public class SqlParserTest {
"CAST(INTERVAL '3-2' YEAR TO MONTH AS CHAR(5))");
}
+ @Test public void testTimestampAddAndDiff() {
+ Map<String, List<String>> tsi = ImmutableMap.<String, List<String>>builder()
+ .put("MICROSECOND",
+ Arrays.asList("FRAC_SECOND", "MICROSECOND",
+ "SQL_TSI_FRAC_SECOND", "SQL_TSI_MICROSECOND"))
+ .put("SECOND", Arrays.asList("SECOND", "SQL_TSI_SECOND"))
+ .put("MINUTE", Arrays.asList("MINUTE", "SQL_TSI_MINUTE"))
+ .put("HOUR", Arrays.asList("HOUR", "SQL_TSI_HOUR"))
+ .put("DAY", Arrays.asList("DAY", "SQL_TSI_DAY"))
+ .put("WEEK", Arrays.asList("WEEK", "SQL_TSI_WEEK"))
+ .put("MONTH", Arrays.asList("MONTH", "SQL_TSI_MONTH"))
+ .put("QUARTER", Arrays.asList("QUARTER", "SQL_TSI_QUARTER"))
+ .put("YEAR", Arrays.asList("YEAR", "SQL_TSI_YEAR"))
+ .build();
+
+ List<String> functions = ImmutableList.<String>builder()
+ .add("timestampadd(%1$s, 12, %2$scurrent_timestamp%2$s)")
+ .add("timestampdiff(%1$s, %2$scurrent_timestamp%2$s, %2$scurrent_timestamp%2$s)")
+ .build();
+
+ for (Map.Entry<String, List<String>> intervalGroup : tsi.entrySet()) {
+ for (String function : functions) {
+ for (String interval : intervalGroup.getValue()) {
+ checkExp(String.format(function, interval, ""),
+ String.format(function, intervalGroup.getKey(), "`").toUpperCase());
+ }
+ }
+ }
+
+ checkExpFails("timestampadd(^incorrect^, 1, current_timestamp)",
+ "(?s).*Was expecting one of.*");
+ checkExpFails("timestampdiff(^incorrect^, current_timestamp, current_timestamp)",
+ "(?s).*Was expecting one of.*");
+ }
+
@Test public void testUnnest() {
check(
"select*from unnest(x)",
http://git-wip-us.apache.org/repos/asf/calcite/blob/0b9ea986/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 81bfeed..48311dd 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
@@ -4599,6 +4599,21 @@ public abstract class SqlOperatorBaseTest {
"floor(cast(null as interval year))");
}
+ @Test public void testTimestampAddAdnDiff() {
+ if (!enable) {
+ return;
+ }
+ tester.checkScalar(
+ "timestampadd(MINUTE, 2, timestamp '2016-02-24 12:42:25')",
+ "2016-02-24 12:42:27",
+ "TIMESTAMP(0) NOT NULL");
+ tester.checkScalar(
+ "timestampdiff(YEAR, "
+ + "timestamp '2014-02-24 12:42:25', "
+ + "timestamp '2016-02-24 12:42:25')",
+ "2", "INTEGER NOT NULL");
+ }
+
@Test public void testDenseRankFunc() {
tester.setFor(
SqlStdOperatorTable.DENSE_RANK, VM_FENNEL, VM_JAVA);
http://git-wip-us.apache.org/repos/asf/calcite/blob/0b9ea986/core/src/test/java/org/apache/calcite/test/SqlValidatorTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/calcite/test/SqlValidatorTest.java b/core/src/test/java/org/apache/calcite/test/SqlValidatorTest.java
index b3a8699..c8ba8e9 100644
--- a/core/src/test/java/org/apache/calcite/test/SqlValidatorTest.java
+++ b/core/src/test/java/org/apache/calcite/test/SqlValidatorTest.java
@@ -3589,6 +3589,54 @@ public class SqlValidatorTest extends SqlValidatorTestCase {
"(?s).*Cannot apply '/' to arguments of type '<DECIMAL.4, 3.> / <INTERVAL DAY TO SECOND>'.*");
}
+ @Test public void testTimestampAddAndDiff() {
+ List<String> tsi = ImmutableList.<String>builder()
+ .add("FRAC_SECOND")
+ .add("MICROSECOND")
+ .add("MINUTE")
+ .add("HOUR")
+ .add("DAY")
+ .add("WEEK")
+ .add("MONTH")
+ .add("QUARTER")
+ .add("YEAR")
+ .add("SQL_TSI_FRAC_SECOND")
+ .add("SQL_TSI_MICROSECOND")
+ .add("SQL_TSI_MINUTE")
+ .add("SQL_TSI_HOUR")
+ .add("SQL_TSI_DAY")
+ .add("SQL_TSI_WEEK")
+ .add("SQL_TSI_MONTH")
+ .add("SQL_TSI_QUARTER")
+ .add("SQL_TSI_YEAR")
+ .build();
+
+ List<String> functions = ImmutableList.<String>builder()
+ .add("timestampadd(%s, 12, current_timestamp)")
+ .add("timestampdiff(%s, current_timestamp, current_timestamp)")
+ .build();
+
+ for (String interval : tsi) {
+ for (String function : functions) {
+ checkExp(String.format(function, interval));
+ }
+ }
+
+ checkExpType(
+ "timestampadd(SQL_TSI_WEEK, 2, current_timestamp)", "TIMESTAMP(0) NOT NULL");
+ checkExpType(
+ "timestampadd(SQL_TSI_WEEK, 2, cast(null as timestamp))", "TIMESTAMP(0)");
+ checkExpType(
+ "timestampdiff(SQL_TSI_WEEK, current_timestamp, current_timestamp)", "INTEGER NOT NULL");
+ checkExpType(
+ "timestampdiff(SQL_TSI_WEEK, cast(null as timestamp), current_timestamp)", "INTEGER");
+
+ checkWholeExpFails("timestampadd(incorrect, 1, current_timestamp)",
+ "(?s).*Was expecting one of.*");
+ checkWholeExpFails("timestampdiff(incorrect, current_timestamp, current_timestamp)",
+ "(?s).*Was expecting one of.*");
+ }
+
@Test public void testNumericOperators() {
// unary operator
checkExpType("- cast(1 as TINYINT)", "TINYINT NOT NULL");
http://git-wip-us.apache.org/repos/asf/calcite/blob/0b9ea986/site/_docs/reference.md
----------------------------------------------------------------------
diff --git a/site/_docs/reference.md b/site/_docs/reference.md
index 7bc9bc3..8785bd5 100644
--- a/site/_docs/reference.md
+++ b/site/_docs/reference.md
@@ -379,6 +379,7 @@ FOLLOWING,
**FOREIGN**,
FORTRAN,
FOUND,
+FRAC_SECOND,
**FREE**,
**FROM**,
**FULL**,
@@ -461,6 +462,7 @@ MESSAGE_LENGTH,
MESSAGE_OCTET_LENGTH,
MESSAGE_TEXT,
**METHOD**,
+MICROSECOND,
**MIN**,
**MINUTE**,
MINVALUE,
@@ -544,6 +546,7 @@ PRIOR,
PRIVILEGES,
**PROCEDURE**,
PUBLIC,
+QUARTER,
**RANGE**,
**RANK**,
READ,
@@ -626,6 +629,16 @@ SPECIFIC_NAME,
**SQLEXCEPTION**,
**SQLSTATE**,
**SQLWARNING**,
+SQL_TSI_DAY,
+SQL_TSI_FRAC_SECOND,
+SQL_TSI_HOUR,
+SQL_TSI_MICROSECOND,
+SQL_TSI_MINUTE,
+SQL_TSI_MONTH,
+SQL_TSI_QUARTER,
+SQL_TSI_SECOND,
+SQL_TSI_WEEK,
+SQL_TSI_YEAR,
**SQRT**,
**START**,
STATE,
@@ -652,6 +665,8 @@ TEMPORARY,
TIES,
**TIME**,
**TIMESTAMP**,
+TIMESTAMPADD,
+TIMESTAMPDIFF,
**TIMEZONE_HOUR**,
**TIMEZONE_MINUTE**,
**TINYINT**,
@@ -702,6 +717,7 @@ USER_DEFINED_TYPE_SCHEMA,
**VAR_SAMP**,
VERSION,
VIEW,
+WEEK,
**WHEN**,
**WHENEVER**,
**WHERE**,