[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 <[email protected]> Authored: Thu Mar 3 17:07:10 2016 +0200 Committer: Julian Hyde <[email protected]> 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**,
