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/11/02 02:02:50 UTC

calcite git commit: [CALCITE-2405] In Babel parser, make 400 reserved keywords including YEAR, SECOND, DESC non-reserved

Repository: calcite
Updated Branches:
  refs/heads/master 9c26a9e74 -> 561c6427e


[CALCITE-2405] In Babel parser, make 400 reserved keywords including YEAR, SECOND, DESC non-reserved

Command words (e.g. SELECT, UPDATE, EXPLAIN, ALTER), SQL clause names
(e.g. WHERE, ORDER, INNER but not BY), and keywords that start literals
(DATE, TIME, TIMESTAMP, INTERVAL) remain reserved.

In Planner, use the parser's conformance.

Avoid javac StackOverflowError by splitting up the NonReservedKeywords()
parser method into several parts.

Compatibility warning: If you have created your own sub-parser you must
copy nonReservedKeywords from core config.fmpp to your config.fmpp.
Previously the core non-reserved keywords were in a parser method
CommonNonReservedKeywords(), but that method has been removed.

Upgrade freemarker to 2.3.28.


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

Branch: refs/heads/master
Commit: 561c6427e3602510d619b45cd7da840773fa0d2c
Parents: 9c26a9e
Author: Julian Hyde <jh...@apache.org>
Authored: Tue Sep 4 16:54:05 2018 -0700
Committer: Julian Hyde <jh...@apache.org>
Committed: Thu Nov 1 16:02:56 2018 -0700

----------------------------------------------------------------------
 babel/src/main/codegen/config.fmpp              | 761 ++++++++++++++++++-
 .../apache/calcite/test/BabelParserTest.java    |  98 +++
 core/src/main/codegen/config.fmpp               | 289 +++++++
 core/src/main/codegen/templates/Parser.jj       | 381 ++--------
 .../org/apache/calcite/prepare/PlannerImpl.java |   3 +-
 core/src/test/codegen/config.fmpp               | 289 +++++++
 .../calcite/sql/parser/SqlParserTest.java       | 160 ++--
 pom.xml                                         |   2 +-
 server/src/main/codegen/config.fmpp             | 291 +++++++
 9 files changed, 1891 insertions(+), 383 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/calcite/blob/561c6427/babel/src/main/codegen/config.fmpp
----------------------------------------------------------------------
diff --git a/babel/src/main/codegen/config.fmpp b/babel/src/main/codegen/config.fmpp
index 57b6419..d17215d 100644
--- a/babel/src/main/codegen/config.fmpp
+++ b/babel/src/main/codegen/config.fmpp
@@ -30,7 +30,766 @@ data: {
 
       # List of keywords from "keywords" section that are not reserved.
       nonReservedKeywords: [
-        "SEMI"
+        "A"
+        "ABSOLUTE"
+        "ACTION"
+        "ADA"
+        "ADD"
+        "ADMIN"
+        "AFTER"
+        "ALWAYS"
+        "APPLY"
+        "ASC"
+        "ASSERTION"
+        "ASSIGNMENT"
+        "ATTRIBUTE"
+        "ATTRIBUTES"
+        "BEFORE"
+        "BERNOULLI"
+        "BREADTH"
+        "C"
+        "CASCADE"
+        "CATALOG"
+        "CATALOG_NAME"
+        "CENTURY"
+        "CHAIN"
+        "CHARACTER_SET_CATALOG"
+        "CHARACTER_SET_NAME"
+        "CHARACTER_SET_SCHEMA"
+        "CHARACTERISTICS"
+        "CHARACTERS"
+        "CLASS_ORIGIN"
+        "COBOL"
+        "COLLATION"
+        "COLLATION_CATALOG"
+        "COLLATION_NAME"
+        "COLLATION_SCHEMA"
+        "COLUMN_NAME"
+        "COMMAND_FUNCTION"
+        "COMMAND_FUNCTION_CODE"
+        "COMMITTED"
+        "CONDITION_NUMBER"
+        "CONNECTION"
+        "CONNECTION_NAME"
+        "CONSTRAINT_CATALOG"
+        "CONSTRAINT_NAME"
+        "CONSTRAINT_SCHEMA"
+        "CONSTRAINTS"
+        "CONSTRUCTOR"
+        "CONTINUE"
+        "CURSOR_NAME"
+        "DATA"
+        "DATABASE"
+        "DATETIME_INTERVAL_CODE"
+        "DATETIME_INTERVAL_PRECISION"
+        "DECADE"
+        "DEFAULTS"
+        "DEFERRABLE"
+        "DEFERRED"
+        "DEFINED"
+        "DEFINER"
+        "DEGREE"
+        "DEPTH"
+        "DERIVED"
+        "DESC"
+        "DESCRIPTION"
+        "DESCRIPTOR"
+        "DIAGNOSTICS"
+        "DISPATCH"
+        "DOMAIN"
+        "DOW"
+        "DOY"
+        "DYNAMIC_FUNCTION"
+        "DYNAMIC_FUNCTION_CODE"
+        "EPOCH"
+        "EXCEPTION"
+        "EXCLUDE"
+        "EXCLUDING"
+        "FINAL"
+        "FIRST"
+        "FOLLOWING"
+        "FORTRAN"
+        "FOUND"
+        "FRAC_SECOND"
+        "G"
+        "GENERAL"
+        "GENERATED"
+        "GEOMETRY"
+        "GO"
+        "GOTO"
+        "GRANTED"
+        "HIERARCHY"
+        "IMMEDIATE"
+        "IMMEDIATELY"
+        "IMPLEMENTATION"
+        "INCLUDING"
+        "INCREMENT"
+        "INITIALLY"
+        "INPUT"
+        "INSTANCE"
+        "INSTANTIABLE"
+        "INVOKER"
+        "ISODOW"
+        "ISOYEAR"
+        "ISOLATION"
+        "JAVA"
+        "JSON"
+        "K"
+        "KEY"
+        "KEY_MEMBER"
+        "KEY_TYPE"
+        "LABEL"
+        "LAST"
+        "LENGTH"
+        "LEVEL"
+        "LIBRARY"
+        "LOCATOR"
+        "M"
+        "MAP"
+        "MATCHED"
+        "MAXVALUE"
+        "MICROSECOND"
+        "MESSAGE_LENGTH"
+        "MESSAGE_OCTET_LENGTH"
+        "MESSAGE_TEXT"
+        "MILLISECOND"
+        "MILLENNIUM"
+        "MINVALUE"
+        "MORE_"
+        "MUMPS"
+        "NAME"
+        "NAMES"
+        "NANOSECOND"
+        "NESTING"
+        "NORMALIZED"
+        "NULLABLE"
+        "NULLS"
+        "NUMBER"
+        "OBJECT"
+        "OCTETS"
+        "OPTION"
+        "OPTIONS"
+        "ORDERING"
+        "ORDINALITY"
+        "OTHERS"
+        "OUTPUT"
+        "OVERRIDING"
+        "PAD"
+        "PARAMETER_MODE"
+        "PARAMETER_NAME"
+        "PARAMETER_ORDINAL_POSITION"
+        "PARAMETER_SPECIFIC_CATALOG"
+        "PARAMETER_SPECIFIC_NAME"
+        "PARAMETER_SPECIFIC_SCHEMA"
+        "PARTIAL"
+        "PASCAL"
+        "PASSTHROUGH"
+        "PAST"
+        "PATH"
+        "PLACING"
+        "PLAN"
+        "PLI"
+        "PRECEDING"
+        "PRESERVE"
+        "PRIOR"
+        "PRIVILEGES"
+        "PUBLIC"
+        "QUARTER"
+        "READ"
+        "RELATIVE"
+        "REPEATABLE"
+        "REPLACE"
+        "RESTART"
+        "RESTRICT"
+        "RETURNED_CARDINALITY"
+        "RETURNED_LENGTH"
+        "RETURNED_OCTET_LENGTH"
+        "RETURNED_SQLSTATE"
+        "ROLE"
+        "ROUTINE"
+        "ROUTINE_CATALOG"
+        "ROUTINE_NAME"
+        "ROUTINE_SCHEMA"
+        "ROW_COUNT"
+        "SCALE"
+        "SCHEMA"
+        "SCHEMA_NAME"
+        "SCOPE_CATALOGS"
+        "SCOPE_NAME"
+        "SCOPE_SCHEMA"
+        "SECTION"
+        "SECURITY"
+        "SELF"
+        "SEQUENCE"
+        "SERIALIZABLE"
+        "SERVER"
+        "SERVER_NAME"
+        "SESSION"
+        "SETS"
+        "SIMPLE"
+        "SIZE"
+        "SOURCE"
+        "SPACE"
+        "SPECIFIC_NAME"
+        "SQL_BIGINT"
+        "SQL_BINARY"
+        "SQL_BIT"
+        "SQL_BLOB"
+        "SQL_BOOLEAN"
+        "SQL_CHAR"
+        "SQL_CLOB"
+        "SQL_DATE"
+        "SQL_DECIMAL"
+        "SQL_DOUBLE"
+        "SQL_FLOAT"
+        "SQL_INTEGER"
+        "SQL_INTERVAL_DAY"
+        "SQL_INTERVAL_DAY_TO_HOUR"
+        "SQL_INTERVAL_DAY_TO_MINUTE"
+        "SQL_INTERVAL_DAY_TO_SECOND"
+        "SQL_INTERVAL_HOUR"
+        "SQL_INTERVAL_HOUR_TO_MINUTE"
+        "SQL_INTERVAL_HOUR_TO_SECOND"
+        "SQL_INTERVAL_MINUTE"
+        "SQL_INTERVAL_MINUTE_TO_SECOND"
+        "SQL_INTERVAL_MONTH"
+        "SQL_INTERVAL_SECOND"
+        "SQL_INTERVAL_YEAR"
+        "SQL_INTERVAL_YEAR_TO_MONTH"
+        "SQL_LONGVARBINARY"
+        "SQL_LONGVARNCHAR"
+        "SQL_LONGVARCHAR"
+        "SQL_NCHAR"
+        "SQL_NCLOB"
+        "SQL_NUMERIC"
+        "SQL_NVARCHAR"
+        "SQL_REAL"
+        "SQL_SMALLINT"
+        "SQL_TIME"
+        "SQL_TIMESTAMP"
+        "SQL_TINYINT"
+        "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"
+        "SQL_VARBINARY"
+        "SQL_VARCHAR"
+        "STATE"
+        "STATEMENT"
+        "STRUCTURE"
+        "STYLE"
+        "SUBCLASS_ORIGIN"
+        "SUBSTITUTE"
+        "TABLE_NAME"
+        "TEMPORARY"
+        "TIES"
+        "TIMESTAMPADD"
+        "TIMESTAMPDIFF"
+        "TOP_LEVEL_COUNT"
+        "TRANSACTION"
+        "TRANSACTIONS_ACTIVE"
+        "TRANSACTIONS_COMMITTED"
+        "TRANSACTIONS_ROLLED_BACK"
+        "TRANSFORM"
+        "TRANSFORMS"
+        "TRIGGER_CATALOG"
+        "TRIGGER_NAME"
+        "TRIGGER_SCHEMA"
+        "TYPE"
+        "UNBOUNDED"
+        "UNCOMMITTED"
+        "UNDER"
+        "UNNAMED"
+        "USAGE"
+        "USER_DEFINED_TYPE_CATALOG"
+        "USER_DEFINED_TYPE_CODE"
+        "USER_DEFINED_TYPE_NAME"
+        "USER_DEFINED_TYPE_SCHEMA"
+        "VERSION"
+        "VIEW"
+        "WEEK"
+        "WRAPPER"
+        "WORK"
+        "WRITE"
+        "XML"
+        "ZONE"
+
+        # not in core, added in babel
+        "SEMI",
+
+        # The following keywords are reserved in core Calcite,
+        # are reserved in some version of SQL,
+        # but are not reserved in Babel.
+        #
+        # Words that are commented out (e.g. "AND") are still reserved.
+        # These are the most important reserved words, and SQL cannot be
+        # unambiguously parsed if they are not reserved. For example, if
+        # "INNER" is not reserved then in the query
+        #
+        #   select * from emp inner join dept using (deptno)"
+        #
+        # "inner" could be a table alias for "emp".
+        #
+        "ABS",
+        "ABSOLUTE",
+        "ACTION",
+        "ADD",
+        "AFTER",
+        "ALL",
+        "ALLOCATE",
+        "ALLOW",
+        "ALTER",
+        "AND",
+#       "ANY",
+        "ARE",
+        "ARRAY",
+#       # "ARRAY_AGG", # not a keyword in Calcite
+        "ARRAY_MAX_CARDINALITY",
+        "AS",
+        "ASC",
+        "ASENSITIVE",
+        "ASSERTION",
+        "ASYMMETRIC",
+        "AT",
+        "ATOMIC",
+        "AUTHORIZATION",
+        "AVG",
+        "BEFORE",
+        "BEGIN",
+        "BEGIN_FRAME",
+        "BEGIN_PARTITION",
+        "BETWEEN",
+        "BIGINT",
+        "BINARY",
+        "BIT",
+#       # "BIT_LENGTH", # not a keyword in Calcite
+        "BLOB",
+        "BOOLEAN",
+        "BOTH",
+        "BREADTH",
+        "BY",
+#       "CALL",
+        "CALLED",
+        "CARDINALITY",
+        "CASCADE",
+        "CASCADED",
+#       "CASE",
+        "CAST",
+        "CATALOG",
+        "CEIL",
+        "CEILING",
+        "CHAR",
+        "CHARACTER",
+        "CHARACTER_LENGTH",
+        "CHAR_LENGTH",
+        "CHECK",
+        "CLASSIFIER",
+        "CLOB",
+        "CLOSE",
+        "COALESCE",
+        "COLLATE",
+        "COLLATION",
+        "COLLECT",
+        "COLUMN",
+        "COMMIT",
+        "CONDITION",
+        "CONNECT",
+        "CONNECTION",
+        "CONSTRAINT",
+        "CONSTRAINTS",
+        "CONSTRUCTOR",
+        "CONTAINS",
+        "CONTINUE",
+        "CONVERT",
+        "CORR",
+        "CORRESPONDING",
+        "COUNT",
+        "COVAR_POP",
+        "COVAR_SAMP",
+#       "CREATE",
+#       "CROSS",
+        "CUBE",
+        "CUME_DIST",
+#       "CURRENT",
+        "CURRENT_CATALOG",
+        "CURRENT_DATE",
+        "CURRENT_DEFAULT_TRANSFORM_GROUP",
+        "CURRENT_PATH",
+        "CURRENT_ROLE",
+        "CURRENT_ROW",
+        "CURRENT_SCHEMA",
+        "CURRENT_TIME",
+        "CURRENT_TIMESTAMP",
+        "CURRENT_TRANSFORM_GROUP_FOR_TYPE",
+        "CURRENT_USER",
+#       "CURSOR",
+        "CYCLE",
+        "DATA",
+#       "DATE",
+        "DAY",
+#       # "DAYS", # not a keyword in Calcite
+        "DEALLOCATE",
+        "DEC",
+        "DECIMAL",
+        "DECLARE",
+#       # "DEFAULT",
+        "DEFERRABLE",
+        "DEFERRED",
+#       "DEFINE",
+#       "DELETE",
+        "DENSE_RANK",
+        "DEPTH",
+        "DEREF",
+        "DESC",
+#       "DESCRIBE", # must be reserved
+       "DESCRIPTOR",
+       "DETERMINISTIC",
+       "DIAGNOSTICS",
+       "DISALLOW",
+       "DISCONNECT",
+#       "DISTINCT",
+#       # "DO",  # not a keyword in Calcite
+       "DOMAIN",
+       "DOUBLE",
+#       "DROP", # probably must be reserved
+       "DYNAMIC",
+       "EACH",
+       "ELEMENT",
+       "ELSE",
+#       # "ELSEIF", # not a keyword in Calcite
+       "EMPTY",
+       "END",
+#       # "END-EXEC", # not a keyword in Calcite, and contains '-'
+       "END_FRAME",
+       "END_PARTITION",
+       "EQUALS",
+       "ESCAPE",
+       "EVERY",
+#       "EXCEPT", # must be reserved
+       "EXCEPTION",
+       "EXEC",
+       "EXECUTE",
+       "EXISTS",
+#       # "EXIT", # not a keyword in Calcite
+       "EXP",
+#       "EXPLAIN", # must be reserved
+       "EXTEND",
+       "EXTERNAL",
+       "EXTRACT",
+       "FALSE",
+#        "FETCH",
+        "FILTER",
+        "FIRST",
+        "FIRST_VALUE",
+        "FLOAT",
+        "FLOOR",
+        "FOR",
+        "FOREIGN",
+#       # "FOREVER", # not a keyword in Calcite
+        "FOUND",
+        "FRAME_ROW",
+        "FREE",
+#       "FROM", # must be reserved
+#       "FULL", # must be reserved
+        "FUNCTION",
+        "FUSION",
+        "GENERAL",
+        "GET",
+        "GLOBAL",
+        "GO",
+        "GOTO",
+#       "GRANT",
+#       "GROUP",
+#       "GROUPING",
+        "GROUPS",
+#       # "HANDLER", # not a keyword in Calcite
+#       "HAVING",
+        "HOLD",
+        "HOUR",
+#       # "HOURS", # not a keyword in Calcite
+        "IDENTITY",
+#       # "IF", # not a keyword in Calcite
+        "IMMEDIATE",
+        "IMMEDIATELY",
+        "IMPORT",
+#       "IN",
+        "INDICATOR",
+        "INITIAL",
+        "INITIALLY",
+#       "INNER",
+        "INOUT",
+        "INPUT",
+        "INSENSITIVE",
+#       "INSERT",
+        "INT",
+        "INTEGER",
+#       "INTERSECT",
+        "INTERSECTION",
+#       "INTERVAL",
+#       "INTO",
+        "IS",
+        "ISOLATION",
+#       # "ITERATE", # not a keyword in Calcite
+#       "JOIN",
+#       # "KEEP", # not a keyword in Calcite
+        "KEY",
+        "LAG",
+        "LANGUAGE",
+        "LARGE",
+        "LAST",
+        "LAST_VALUE",
+#       "LATERAL",
+        "LEAD",
+        "LEADING",
+#       # "LEAVE", # not a keyword in Calcite
+#       "LEFT",
+        "LEVEL",
+        "LIKE",
+        "LIKE_REGEX",
+#       "LIMIT",
+        "LN",
+        "LOCAL",
+        "LOCALTIME",
+        "LOCALTIMESTAMP",
+        "LOCATOR",
+#       # "LOOP", # not a keyword in Calcite
+        "LOWER",
+        "MAP",
+        "MATCH",
+        "MATCHES",
+        "MATCH_NUMBER",
+#       "MATCH_RECOGNIZE",
+        "MAX",
+#       # "MAX_CARDINALITY", # not a keyword in Calcite
+        "MEASURES",
+        "MEMBER",
+#       "MERGE",
+        "METHOD",
+        "MIN",
+#       "MINUS",
+        "MINUTE",
+#       # "MINUTES", # not a keyword in Calcite
+        "MOD",
+        "MODIFIES",
+        "MODULE",
+        "MONTH",
+        "MULTISET",
+        "NAMES",
+        "NATIONAL",
+#       "NATURAL",
+        "NCHAR",
+        "NCLOB",
+#       "NEW",
+#       "NEXT",
+        "NO",
+        "NONE",
+        "NORMALIZE",
+        "NOT",
+        "NTH_VALUE",
+        "NTILE",
+#       "NULL",
+        "NULLIF",
+        "NUMERIC",
+        "OBJECT",
+        "OCCURRENCES_REGEX",
+        "OCTET_LENGTH",
+        "OF",
+#       "OFFSET",
+        "OLD",
+        "OMIT",
+#       "ON",
+        "ONE",
+        "ONLY",
+        "OPEN",
+        "OPTION",
+        "OR",
+#       "ORDER",
+        "ORDINALITY",
+        "OUT",
+#       "OUTER",
+        "OUTPUT",
+#       "OVER",
+        "OVERLAPS",
+        "OVERLAY",
+        "PAD",
+        "PARAMETER",
+        "PARTIAL",
+#       "PARTITION",
+        "PATH",
+#       "PATTERN",
+        "PER",
+        "PERCENT",
+        "PERCENTILE_CONT",
+        "PERCENTILE_DISC",
+        "PERCENT_RANK",
+        "PERIOD",
+        "PERMUTE",
+        "PORTION",
+        "POSITION",
+        "POSITION_REGEX",
+        "POWER",
+        "PRECEDES",
+        "PRECISION",
+        "PREPARE",
+        "PRESERVE",
+        "PREV",
+        "PRIMARY",
+        "PRIOR",
+        "PRIVILEGES",
+        "PROCEDURE",
+        "PUBLIC",
+#       "RANGE",
+        "RANK",
+        "READ",
+        "READS",
+        "REAL",
+        "RECURSIVE",
+        "REF",
+        "REFERENCES",
+        "REFERENCING",
+        "REGR_AVGX",
+        "REGR_AVGY",
+        "REGR_COUNT",
+        "REGR_INTERCEPT",
+        "REGR_R2",
+        "REGR_SLOPE",
+        "REGR_SXX",
+        "REGR_SXY",
+        "REGR_SYY",
+        "RELATIVE",
+        "RELEASE",
+#       # "REPEAT", # not a keyword in Calcite
+        "RESET",
+#       # "RESIGNAL", # not a keyword in Calcite
+        "RESTRICT",
+        "RESULT",
+        "RETURN",
+        "RETURNS",
+        "REVOKE",
+#       "RIGHT",
+        "ROLE",
+        "ROLLBACK",
+#       "ROLLUP",
+        "ROUTINE",
+#       "ROW",
+#       "ROWS",
+        "ROW_NUMBER",
+        "RUNNING",
+        "SAVEPOINT",
+        "SCHEMA",
+        "SCOPE",
+        "SCROLL",
+        "SEARCH",
+        "SECOND",
+#       # "SECONDS", # not a keyword in Calcite
+        "SECTION",
+        "SEEK",
+#       "SELECT",
+        "SENSITIVE",
+        "SESSION",
+        "SESSION_USER",
+#       "SET",
+#       "SETS",
+        "SHOW",
+#       # "SIGNAL", # not a keyword in Calcite
+        "SIMILAR",
+        "SIZE",
+#       # "SKIP", # messes with JavaCC's <SKIP> token
+        "SMALLINT",
+#       "SOME",
+        "SPACE",
+        "SPECIFIC",
+        "SPECIFICTYPE",
+        "SQL",
+#       # "SQLCODE", # not a keyword in Calcite
+#       # "SQLERROR", # not a keyword in Calcite
+        "SQLEXCEPTION",
+        "SQLSTATE",
+        "SQLWARNING",
+        "SQRT",
+        "START",
+        "STATE",
+        "STATIC",
+        "STDDEV_POP",
+        "STDDEV_SAMP",
+#       "STREAM",
+        "SUBMULTISET",
+        "SUBSET",
+        "SUBSTRING",
+        "SUBSTRING_REGEX",
+        "SUCCEEDS",
+        "SUM",
+        "SYMMETRIC",
+        "SYSTEM",
+        "SYSTEM_TIME",
+        "SYSTEM_USER",
+#       "TABLE",
+#       "TABLESAMPLE",
+        "TEMPORARY",
+#       "THEN",
+#       "TIME",
+#       "TIMESTAMP",
+        "TIMEZONE_HOUR",
+        "TIMEZONE_MINUTE",
+        "TINYINT",
+        "TO",
+        "TRAILING",
+        "TRANSACTION",
+        "TRANSLATE",
+        "TRANSLATE_REGEX",
+        "TRANSLATION",
+        "TREAT",
+        "TRIGGER",
+        "TRIM",
+        "TRIM_ARRAY",
+        "TRUE",
+        "TRUNCATE",
+        "UESCAPE",
+        "UNDER",
+#       # "UNDO", # not a keyword in Calcite
+#       "UNION",
+        "UNIQUE",
+        "UNKNOWN",
+#       "UNNEST",
+#       # "UNTIL", # not a keyword in Calcite
+#       "UPDATE",
+        "UPPER",
+        "UPSERT",
+        "USAGE",
+        "USER",
+#       "USING",
+        "VALUE",
+#       "VALUES",
+        "VALUE_OF",
+        "VARBINARY",
+        "VARCHAR",
+        "VARYING",
+        "VAR_POP",
+        "VAR_SAMP",
+        "VERSION",
+        "VERSIONING",
+#       # "VERSIONS", # not a keyword in Calcite
+        "VIEW",
+#       "WHEN",
+        "WHENEVER",
+#       "WHERE",
+#       # "WHILE", # not a keyword in Calcite
+        "WIDTH_BUCKET",
+#       "WINDOW",
+#       "WITH",
+        "WITHIN",
+        "WITHOUT",
+        "WORK",
+        "WRITE",
+        "YEAR",
+        # "YEARS", # not a keyword in Calcite
+        "ZONE",
       ]
 
       # List of additional join types. Each is a method with no arguments.

http://git-wip-us.apache.org/repos/asf/calcite/blob/561c6427/babel/src/test/java/org/apache/calcite/test/BabelParserTest.java
----------------------------------------------------------------------
diff --git a/babel/src/test/java/org/apache/calcite/test/BabelParserTest.java b/babel/src/test/java/org/apache/calcite/test/BabelParserTest.java
index 521266d..896a96e 100644
--- a/babel/src/test/java/org/apache/calcite/test/BabelParserTest.java
+++ b/babel/src/test/java/org/apache/calcite/test/BabelParserTest.java
@@ -16,12 +16,20 @@
  */
 package org.apache.calcite.test;
 
+import org.apache.calcite.sql.parser.SqlAbstractParserImpl;
 import org.apache.calcite.sql.parser.SqlParserImplFactory;
 import org.apache.calcite.sql.parser.SqlParserTest;
 import org.apache.calcite.sql.parser.babel.SqlBabelParserImpl;
 
+import org.junit.Ignore;
 import org.junit.Test;
 
+import java.util.Arrays;
+import java.util.Locale;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.junit.Assert.assertThat;
+
 /**
  * Tests the "Babel" SQL parser, that understands all dialects of SQL.
  */
@@ -35,6 +43,51 @@ public class BabelParserTest extends SqlParserTest {
     // by design, method only works in base class; no-ops in this sub-class
   }
 
+  @Test public void testReservedWords() {
+    assertThat(isReserved("escape"), is(false));
+  }
+
+  /** {@inheritDoc}
+   *
+   * <p>Copy-pasted from base method, but with some key differences.
+   */
+  @Override @Test public void testMetadata() {
+    SqlAbstractParserImpl.Metadata metadata = getSqlParser("").getMetadata();
+    assertThat(metadata.isReservedFunctionName("ABS"), is(true));
+    assertThat(metadata.isReservedFunctionName("FOO"), is(false));
+
+    assertThat(metadata.isContextVariableName("CURRENT_USER"), is(true));
+    assertThat(metadata.isContextVariableName("CURRENT_CATALOG"), is(true));
+    assertThat(metadata.isContextVariableName("CURRENT_SCHEMA"), is(true));
+    assertThat(metadata.isContextVariableName("ABS"), is(false));
+    assertThat(metadata.isContextVariableName("FOO"), is(false));
+
+    assertThat(metadata.isNonReservedKeyword("A"), is(true));
+    assertThat(metadata.isNonReservedKeyword("KEY"), is(true));
+    assertThat(metadata.isNonReservedKeyword("SELECT"), is(false));
+    assertThat(metadata.isNonReservedKeyword("FOO"), is(false));
+    assertThat(metadata.isNonReservedKeyword("ABS"), is(true)); // was false
+
+    assertThat(metadata.isKeyword("ABS"), is(true));
+    assertThat(metadata.isKeyword("CURRENT_USER"), is(true));
+    assertThat(metadata.isKeyword("CURRENT_CATALOG"), is(true));
+    assertThat(metadata.isKeyword("CURRENT_SCHEMA"), is(true));
+    assertThat(metadata.isKeyword("KEY"), is(true));
+    assertThat(metadata.isKeyword("SELECT"), is(true));
+    assertThat(metadata.isKeyword("HAVING"), is(true));
+    assertThat(metadata.isKeyword("A"), is(true));
+    assertThat(metadata.isKeyword("BAR"), is(false));
+
+    assertThat(metadata.isReservedWord("SELECT"), is(true));
+    assertThat(metadata.isReservedWord("CURRENT_CATALOG"), is(false)); // was true
+    assertThat(metadata.isReservedWord("CURRENT_SCHEMA"), is(false)); // was true
+    assertThat(metadata.isReservedWord("KEY"), is(false));
+
+    String jdbcKeywords = metadata.getJdbcKeywords();
+    assertThat(jdbcKeywords.contains(",COLLECT,"), is(false)); // was true
+    assertThat(!jdbcKeywords.contains(",SELECT,"), is(true));
+  }
+
   @Test public void testSelect() {
     final String sql = "select 1 from t";
     final String expected = "SELECT 1\n"
@@ -42,6 +95,51 @@ public class BabelParserTest extends SqlParserTest {
     sql(sql).ok(expected);
   }
 
+  @Test public void testYearIsNotReserved() {
+    final String sql = "select 1 as year from t";
+    final String expected = "SELECT 1 AS `YEAR`\n"
+        + "FROM `T`";
+    sql(sql).ok(expected);
+  }
+
+  /** Tests that there are no reserved keywords. */
+  @Ignore
+  @Test public void testKeywords() {
+    final String[] reserved = {"AND", "ANY", "END-EXEC"};
+    final StringBuilder sql = new StringBuilder("select ");
+    final StringBuilder expected = new StringBuilder("SELECT ");
+    for (String keyword : keywords(null)) {
+      // Skip "END-EXEC"; I don't know how a keyword can contain '-'
+      if (!Arrays.asList(reserved).contains(keyword)) {
+        sql.append("1 as ").append(keyword).append(", ");
+        expected.append("1 as `").append(keyword.toUpperCase(Locale.ROOT))
+            .append("`,\n");
+      }
+    }
+    sql.setLength(sql.length() - 2); // remove ', '
+    expected.setLength(expected.length() - 2); // remove ',\n'
+    sql.append(" from t");
+    expected.append("\nFROM t");
+    sql(sql.toString()).ok(expected.toString());
+  }
+
+  /** In Babel, AS is not reserved. */
+  @Test public void testAs() {
+    final String expected = "SELECT `AS`\n"
+        + "FROM `T`";
+    sql("select as from t").ok(expected);
+  }
+
+  /** In Babel, DESC is not reserved. */
+  @Test public void testDesc() {
+    final String sql = "select desc\n"
+        + "from t\n"
+        + "order by desc asc, desc desc";
+    final String expected = "SELECT `DESC`\n"
+        + "FROM `T`\n"
+        + "ORDER BY `DESC`, `DESC` DESC";
+    sql(sql).ok(expected);
+  }
 }
 
 // End BabelParserTest.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/561c6427/core/src/main/codegen/config.fmpp
----------------------------------------------------------------------
diff --git a/core/src/main/codegen/config.fmpp b/core/src/main/codegen/config.fmpp
index 2cec0c8..4e77ce5 100644
--- a/core/src/main/codegen/config.fmpp
+++ b/core/src/main/codegen/config.fmpp
@@ -50,6 +50,295 @@ data: {
 
     # List of keywords from "keywords" section that are not reserved.
     nonReservedKeywords: [
+        "A"
+        "ABSOLUTE"
+        "ACTION"
+        "ADA"
+        "ADD"
+        "ADMIN"
+        "AFTER"
+        "ALWAYS"
+        "APPLY"
+        "ASC"
+        "ASSERTION"
+        "ASSIGNMENT"
+        "ATTRIBUTE"
+        "ATTRIBUTES"
+        "BEFORE"
+        "BERNOULLI"
+        "BREADTH"
+        "C"
+        "CASCADE"
+        "CATALOG"
+        "CATALOG_NAME"
+        "CENTURY"
+        "CHAIN"
+        "CHARACTER_SET_CATALOG"
+        "CHARACTER_SET_NAME"
+        "CHARACTER_SET_SCHEMA"
+        "CHARACTERISTICS"
+        "CHARACTERS"
+        "CLASS_ORIGIN"
+        "COBOL"
+        "COLLATION"
+        "COLLATION_CATALOG"
+        "COLLATION_NAME"
+        "COLLATION_SCHEMA"
+        "COLUMN_NAME"
+        "COMMAND_FUNCTION"
+        "COMMAND_FUNCTION_CODE"
+        "COMMITTED"
+        "CONDITION_NUMBER"
+        "CONNECTION"
+        "CONNECTION_NAME"
+        "CONSTRAINT_CATALOG"
+        "CONSTRAINT_NAME"
+        "CONSTRAINT_SCHEMA"
+        "CONSTRAINTS"
+        "CONSTRUCTOR"
+        "CONTINUE"
+        "CURSOR_NAME"
+        "DATA"
+        "DATABASE"
+        "DATETIME_INTERVAL_CODE"
+        "DATETIME_INTERVAL_PRECISION"
+        "DECADE"
+        "DEFAULTS"
+        "DEFERRABLE"
+        "DEFERRED"
+        "DEFINED"
+        "DEFINER"
+        "DEGREE"
+        "DEPTH"
+        "DERIVED"
+        "DESC"
+        "DESCRIPTION"
+        "DESCRIPTOR"
+        "DIAGNOSTICS"
+        "DISPATCH"
+        "DOMAIN"
+        "DOW"
+        "DOY"
+        "DYNAMIC_FUNCTION"
+        "DYNAMIC_FUNCTION_CODE"
+        "EPOCH"
+        "EXCEPTION"
+        "EXCLUDE"
+        "EXCLUDING"
+        "FINAL"
+        "FIRST"
+        "FOLLOWING"
+        "FORTRAN"
+        "FOUND"
+        "FRAC_SECOND"
+        "G"
+        "GENERAL"
+        "GENERATED"
+        "GEOMETRY"
+        "GO"
+        "GOTO"
+        "GRANTED"
+        "HIERARCHY"
+        "IMMEDIATE"
+        "IMMEDIATELY"
+        "IMPLEMENTATION"
+        "INCLUDING"
+        "INCREMENT"
+        "INITIALLY"
+        "INPUT"
+        "INSTANCE"
+        "INSTANTIABLE"
+        "INVOKER"
+        "ISODOW"
+        "ISOYEAR"
+        "ISOLATION"
+        "JAVA"
+        "JSON"
+        "K"
+        "KEY"
+        "KEY_MEMBER"
+        "KEY_TYPE"
+        "LABEL"
+        "LAST"
+        "LENGTH"
+        "LEVEL"
+        "LIBRARY"
+        "LOCATOR"
+        "M"
+        "MAP"
+        "MATCHED"
+        "MAXVALUE"
+        "MICROSECOND"
+        "MESSAGE_LENGTH"
+        "MESSAGE_OCTET_LENGTH"
+        "MESSAGE_TEXT"
+        "MILLISECOND"
+        "MILLENNIUM"
+        "MINVALUE"
+        "MORE_"
+        "MUMPS"
+        "NAME"
+        "NAMES"
+        "NANOSECOND"
+        "NESTING"
+        "NORMALIZED"
+        "NULLABLE"
+        "NULLS"
+        "NUMBER"
+        "OBJECT"
+        "OCTETS"
+        "OPTION"
+        "OPTIONS"
+        "ORDERING"
+        "ORDINALITY"
+        "OTHERS"
+        "OUTPUT"
+        "OVERRIDING"
+        "PAD"
+        "PARAMETER_MODE"
+        "PARAMETER_NAME"
+        "PARAMETER_ORDINAL_POSITION"
+        "PARAMETER_SPECIFIC_CATALOG"
+        "PARAMETER_SPECIFIC_NAME"
+        "PARAMETER_SPECIFIC_SCHEMA"
+        "PARTIAL"
+        "PASCAL"
+        "PASSTHROUGH"
+        "PAST"
+        "PATH"
+        "PLACING"
+        "PLAN"
+        "PLI"
+        "PRECEDING"
+        "PRESERVE"
+        "PRIOR"
+        "PRIVILEGES"
+        "PUBLIC"
+        "QUARTER"
+        "READ"
+        "RELATIVE"
+        "REPEATABLE"
+        "REPLACE"
+        "RESTART"
+        "RESTRICT"
+        "RETURNED_CARDINALITY"
+        "RETURNED_LENGTH"
+        "RETURNED_OCTET_LENGTH"
+        "RETURNED_SQLSTATE"
+        "ROLE"
+        "ROUTINE"
+        "ROUTINE_CATALOG"
+        "ROUTINE_NAME"
+        "ROUTINE_SCHEMA"
+        "ROW_COUNT"
+        "SCALE"
+        "SCHEMA"
+        "SCHEMA_NAME"
+        "SCOPE_CATALOGS"
+        "SCOPE_NAME"
+        "SCOPE_SCHEMA"
+        "SECTION"
+        "SECURITY"
+        "SELF"
+        "SEQUENCE"
+        "SERIALIZABLE"
+        "SERVER"
+        "SERVER_NAME"
+        "SESSION"
+        "SETS"
+        "SIMPLE"
+        "SIZE"
+        "SOURCE"
+        "SPACE"
+        "SPECIFIC_NAME"
+        "SQL_BIGINT"
+        "SQL_BINARY"
+        "SQL_BIT"
+        "SQL_BLOB"
+        "SQL_BOOLEAN"
+        "SQL_CHAR"
+        "SQL_CLOB"
+        "SQL_DATE"
+        "SQL_DECIMAL"
+        "SQL_DOUBLE"
+        "SQL_FLOAT"
+        "SQL_INTEGER"
+        "SQL_INTERVAL_DAY"
+        "SQL_INTERVAL_DAY_TO_HOUR"
+        "SQL_INTERVAL_DAY_TO_MINUTE"
+        "SQL_INTERVAL_DAY_TO_SECOND"
+        "SQL_INTERVAL_HOUR"
+        "SQL_INTERVAL_HOUR_TO_MINUTE"
+        "SQL_INTERVAL_HOUR_TO_SECOND"
+        "SQL_INTERVAL_MINUTE"
+        "SQL_INTERVAL_MINUTE_TO_SECOND"
+        "SQL_INTERVAL_MONTH"
+        "SQL_INTERVAL_SECOND"
+        "SQL_INTERVAL_YEAR"
+        "SQL_INTERVAL_YEAR_TO_MONTH"
+        "SQL_LONGVARBINARY"
+        "SQL_LONGVARNCHAR"
+        "SQL_LONGVARCHAR"
+        "SQL_NCHAR"
+        "SQL_NCLOB"
+        "SQL_NUMERIC"
+        "SQL_NVARCHAR"
+        "SQL_REAL"
+        "SQL_SMALLINT"
+        "SQL_TIME"
+        "SQL_TIMESTAMP"
+        "SQL_TINYINT"
+        "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"
+        "SQL_VARBINARY"
+        "SQL_VARCHAR"
+        "STATE"
+        "STATEMENT"
+        "STRUCTURE"
+        "STYLE"
+        "SUBCLASS_ORIGIN"
+        "SUBSTITUTE"
+        "TABLE_NAME"
+        "TEMPORARY"
+        "TIES"
+        "TIMESTAMPADD"
+        "TIMESTAMPDIFF"
+        "TOP_LEVEL_COUNT"
+        "TRANSACTION"
+        "TRANSACTIONS_ACTIVE"
+        "TRANSACTIONS_COMMITTED"
+        "TRANSACTIONS_ROLLED_BACK"
+        "TRANSFORM"
+        "TRANSFORMS"
+        "TRIGGER_CATALOG"
+        "TRIGGER_NAME"
+        "TRIGGER_SCHEMA"
+        "TYPE"
+        "UNBOUNDED"
+        "UNCOMMITTED"
+        "UNDER"
+        "UNNAMED"
+        "USAGE"
+        "USER_DEFINED_TYPE_CATALOG"
+        "USER_DEFINED_TYPE_CODE"
+        "USER_DEFINED_TYPE_NAME"
+        "USER_DEFINED_TYPE_SCHEMA"
+        "VERSION"
+        "VIEW"
+        "WEEK"
+        "WRAPPER"
+        "WORK"
+        "WRITE"
+        "XML"
+        "ZONE"
     ]
 
     # List of additional join types. Each is a method with no arguments.

http://git-wip-us.apache.org/repos/asf/calcite/blob/561c6427/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 0dc23eb..bcc9e56 100644
--- a/core/src/main/codegen/templates/Parser.jj
+++ b/core/src/main/codegen/templates/Parser.jj
@@ -240,17 +240,6 @@ JAVACODE String unquotedIdentifier() {
         unquotedCasing);
 }
 
-String NonReservedKeyWord() :
-{
-    String kw;
-}
-{
-    kw = CommonNonReservedKeyWord()
-    {
-        return kw;
-    }
-}
-
 /**
  * Allows parser to be extended with new types of table references.  The
  * default implementation of this production is empty.
@@ -6109,330 +6098,82 @@ SqlPostfixOperator PostfixRowOperator() :
 </#list>
 }
 
-/*
- * Abstract production:
- *
- *   String NonReservedKeyWord()
- *
- * Parses non-reserved keywords (e.g. keywords that may be used as
- * identifiers).  Should use CommonNonReservedKeyWord as a base, but
- * may add other key words.
- */
-
 /**
- * Parses a non-reserved keyword for use as an identifier.  Specializations
- * of this parser can use this as a base for implementing the
- * NonReservedKeyWord() production.
+ * Parses a non-reserved keyword for use as an identifier.
+ *
+ * <p>The method is broken up into several sub-methods; without this
+ * decomposition, parsers such as Babel with more than ~1,000 non-reserved
+ * keywords would generate such deeply nested 'if' statements that javac would
+ * fail with a {@link StackOverflowError}.
  *
- * <p>When adding keywords to this list, be sure that they are not reserved
- * by the SQL:2003 standard (see productions for "non-reserved word"
- * and "reserved word" in reference below).
+ * <p>The list is generated from the FMPP config data. To add or remove
+ * keywords, modify config.fmpp. For parsers except Babel, make sure that
+ * keywords are not reserved by the SQL standard.
  *
  * @see Glossary#SQL2003 SQL:2003 Part 2 Section 5.2
  */
-String CommonNonReservedKeyWord() :
+String NonReservedKeyWord() :
 {
 }
 {
     (
-        <A>
-    |   <ABSOLUTE>
-    |   <ACTION>
-    |   <ADA>
-    |   <ADD>
-    |   <ADMIN>
-    |   <AFTER>
-    |   <ALWAYS>
-    |   <APPLY>
-    |   <ASC>
-    |   <ASSERTION>
-    |   <ASSIGNMENT>
-    |   <ATTRIBUTE>
-    |   <ATTRIBUTES>
-    |   <BEFORE>
-    |   <BERNOULLI>
-    |   <BREADTH>
-    |   <C>
-    |   <CASCADE>
-    |   <CATALOG>
-    |   <CATALOG_NAME>
-    |   <CENTURY>
-    |   <CHAIN>
-    |   <CHARACTER_SET_CATALOG>
-    |   <CHARACTER_SET_NAME>
-    |   <CHARACTER_SET_SCHEMA>
-    |   <CHARACTERISTICS>
-    |   <CHARACTERS>
-    |   <CLASS_ORIGIN>
-    |   <COBOL>
-    |   <COLLATION>
-    |   <COLLATION_CATALOG>
-    |   <COLLATION_NAME>
-    |   <COLLATION_SCHEMA>
-    |   <COLUMN_NAME>
-    |   <COMMAND_FUNCTION>
-    |   <COMMAND_FUNCTION_CODE>
-    |   <COMMITTED>
-    |   <CONDITION_NUMBER>
-    |   <CONNECTION>
-    |   <CONNECTION_NAME>
-    |   <CONSTRAINT_CATALOG>
-    |   <CONSTRAINT_NAME>
-    |   <CONSTRAINT_SCHEMA>
-    |   <CONSTRAINTS>
-    |   <CONSTRUCTOR>
-    |   <CONTINUE>
-    |   <CURSOR_NAME>
-    |   <DATA>
-    |   <DATABASE>
-    |   <DATETIME_INTERVAL_CODE>
-    |   <DATETIME_INTERVAL_PRECISION>
-    |   <DECADE>
-    |   <DEFAULTS>
-    |   <DEFERRABLE>
-    |   <DEFERRED>
-    |   <DEFINED>
-    |   <DEFINER>
-    |   <DEGREE>
-    |   <DEPTH>
-    |   <DERIVED>
-    |   <DESC>
-    |   <DESCRIPTION>
-    |   <DESCRIPTOR>
-    |   <DIAGNOSTICS>
-    |   <DISPATCH>
-    |   <DOMAIN>
-    |   <DOW>
-    |   <DOY>
-    |   <DYNAMIC_FUNCTION>
-    |   <DYNAMIC_FUNCTION_CODE>
-    |   <EPOCH>
-    |   <EXCEPTION>
-    |   <EXCLUDE>
-    |   <EXCLUDING>
-    |   <FINAL>
-    |   <FIRST>
-    |   <FOLLOWING>
-    |   <FORTRAN>
-    |   <FOUND>
-    |   <FRAC_SECOND>
-    |   <G>
-    |   <GENERAL>
-    |   <GENERATED>
-    |   <GEOMETRY>
-    |   <GO>
-    |   <GOTO>
-    |   <GRANTED>
-    |   <HIERARCHY>
-    |   <IMMEDIATE>
-    |   <IMMEDIATELY>
-    |   <IMPLEMENTATION>
-    |   <INCLUDING>
-    |   <INCREMENT>
-    |   <INITIALLY>
-    |   <INPUT>
-    |   <INSTANCE>
-    |   <INSTANTIABLE>
-    |   <INVOKER>
-    |   <ISODOW>
-    |   <ISOYEAR>
-    |   <ISOLATION>
-    |   <JAVA>
-    |   <JSON>
-    |   <K>
-    |   <KEY>
-    |   <KEY_MEMBER>
-    |   <KEY_TYPE>
-    |   <LABEL>
-    |   <LAST>
-    |   <LENGTH>
-    |   <LEVEL>
-    |   <LIBRARY>
-    |   <LOCATOR>
-    |   <M>
-    |   <MAP>
-    |   <MATCHED>
-    |   <MAXVALUE>
-    |   <MICROSECOND>
-    |   <MESSAGE_LENGTH>
-    |   <MESSAGE_OCTET_LENGTH>
-    |   <MESSAGE_TEXT>
-    |   <MILLISECOND>
-    |   <MILLENNIUM>
-    |   <MINVALUE>
-    |   <MORE_>
-    |   <MUMPS>
-    |   <NAME>
-    |   <NAMES>
-    |   <NANOSECOND>
-    |   <NESTING>
-    |   <NORMALIZED>
-    |   <NULLABLE>
-    |   <NULLS>
-    |   <NUMBER>
-    |   <OBJECT>
-    |   <OCTETS>
-    |   <OPTION>
-    |   <OPTIONS>
-    |   <ORDERING>
-    |   <ORDINALITY>
-    |   <OTHERS>
-    |   <OUTPUT>
-    |   <OVERRIDING>
-    |   <PAD>
-    |   <PARAMETER_MODE>
-    |   <PARAMETER_NAME>
-    |   <PARAMETER_ORDINAL_POSITION>
-    |   <PARAMETER_SPECIFIC_CATALOG>
-    |   <PARAMETER_SPECIFIC_NAME>
-    |   <PARAMETER_SPECIFIC_SCHEMA>
-    |   <PARTIAL>
-    |   <PASCAL>
-    |   <PASSTHROUGH>
-    |   <PAST>
-    |   <PATH>
-    |   <PLACING>
-    |   <PLAN>
-    |   <PLI>
-    |   <PRECEDING>
-    |   <PRESERVE>
-    |   <PRIOR>
-    |   <PRIVILEGES>
-    |   <PUBLIC>
-    |   <QUARTER>
-    |   <READ>
-    |   <RELATIVE>
-    |   <REPEATABLE>
-    |   <REPLACE>
-    |   <RESTART>
-    |   <RESTRICT>
-    |   <RETURNED_CARDINALITY>
-    |   <RETURNED_LENGTH>
-    |   <RETURNED_OCTET_LENGTH>
-    |   <RETURNED_SQLSTATE>
-    |   <ROLE>
-    |   <ROUTINE>
-    |   <ROUTINE_CATALOG>
-    |   <ROUTINE_NAME>
-    |   <ROUTINE_SCHEMA>
-    |   <ROW_COUNT>
-    |   <SCALE>
-    |   <SCHEMA>
-    |   <SCHEMA_NAME>
-    |   <SCOPE_CATALOGS>
-    |   <SCOPE_NAME>
-    |   <SCOPE_SCHEMA>
-    |   <SECTION>
-    |   <SECURITY>
-    |   <SELF>
-    |   <SEQUENCE>
-    |   <SERIALIZABLE>
-    |   <SERVER>
-    |   <SERVER_NAME>
-    |   <SESSION>
-    |   <SETS>
-    |   <SIMPLE>
-    |   <SIZE>
-    |   <SOURCE>
-    |   <SPACE>
-    |   <SPECIFIC_NAME>
-    |   <SQL_BIGINT>
-    |   <SQL_BINARY>
-    |   <SQL_BIT>
-    |   <SQL_BLOB>
-    |   <SQL_BOOLEAN>
-    |   <SQL_CHAR>
-    |   <SQL_CLOB>
-    |   <SQL_DATE>
-    |   <SQL_DECIMAL>
-    |   <SQL_DOUBLE>
-    |   <SQL_FLOAT>
-    |   <SQL_INTEGER>
-    |   <SQL_INTERVAL_DAY>
-    |   <SQL_INTERVAL_DAY_TO_HOUR>
-    |   <SQL_INTERVAL_DAY_TO_MINUTE>
-    |   <SQL_INTERVAL_DAY_TO_SECOND>
-    |   <SQL_INTERVAL_HOUR>
-    |   <SQL_INTERVAL_HOUR_TO_MINUTE>
-    |   <SQL_INTERVAL_HOUR_TO_SECOND>
-    |   <SQL_INTERVAL_MINUTE>
-    |   <SQL_INTERVAL_MINUTE_TO_SECOND>
-    |   <SQL_INTERVAL_MONTH>
-    |   <SQL_INTERVAL_SECOND>
-    |   <SQL_INTERVAL_YEAR>
-    |   <SQL_INTERVAL_YEAR_TO_MONTH>
-    |   <SQL_LONGVARBINARY>
-    |   <SQL_LONGVARNCHAR>
-    |   <SQL_LONGVARCHAR>
-    |   <SQL_NCHAR>
-    |   <SQL_NCLOB>
-    |   <SQL_NUMERIC>
-    |   <SQL_NVARCHAR>
-    |   <SQL_REAL>
-    |   <SQL_SMALLINT>
-    |   <SQL_TIME>
-    |   <SQL_TIMESTAMP>
-    |   <SQL_TINYINT>
-    |   <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>
-    |   <SQL_VARBINARY>
-    |   <SQL_VARCHAR>
-    |   <STATE>
-    |   <STATEMENT>
-    |   <STRUCTURE>
-    |   <STYLE>
-    |   <SUBCLASS_ORIGIN>
-    |   <SUBSTITUTE>
-    |   <TABLE_NAME>
-    |   <TEMPORARY>
-    |   <TIES>
-    |   <TIMESTAMPADD>
-    |   <TIMESTAMPDIFF>
-    |   <TOP_LEVEL_COUNT>
-    |   <TRANSACTION>
-    |   <TRANSACTIONS_ACTIVE>
-    |   <TRANSACTIONS_COMMITTED>
-    |   <TRANSACTIONS_ROLLED_BACK>
-    |   <TRANSFORM>
-    |   <TRANSFORMS>
-    |   <TRIGGER_CATALOG>
-    |   <TRIGGER_NAME>
-    |   <TRIGGER_SCHEMA>
-    |   <TYPE>
-    |   <UNBOUNDED>
-    |   <UNCOMMITTED>
-    |   <UNDER>
-    |   <UNNAMED>
-    |   <USAGE>
-    |   <USER_DEFINED_TYPE_CATALOG>
-    |   <USER_DEFINED_TYPE_CODE>
-    |   <USER_DEFINED_TYPE_NAME>
-    |   <USER_DEFINED_TYPE_SCHEMA>
-    |   <VERSION>
-    |   <VIEW>
-    |   <WEEK>
-    |   <WRAPPER>
-    |   <WORK>
-    |   <WRITE>
-    |   <XML>
-    |   <ZONE>
-<#list parser.nonReservedKeywords as keyword>
-    |   <${keyword}>
-</#list>
+        NonReservedKeyWord0of3()
+    |   NonReservedKeyWord1of3()
+    |   NonReservedKeyWord2of3()
     )
     {
         return unquotedIdentifier();
     }
 }
 
+/** @see #NonReservedKeyWord */
+void NonReservedKeyWord0of3() :
+{
+}
+{
+    (
+<#list parser.nonReservedKeywords as keyword>
+<#if keyword?index == 0>
+        <${keyword}>
+<#elseif keyword?index % 3 == 0>
+    |   <${keyword}>
+</#if>
+</#list>
+    )
+}
+
+/** @see #NonReservedKeyWord */
+void NonReservedKeyWord1of3() :
+{
+}
+{
+    (
+<#list parser.nonReservedKeywords as keyword>
+<#if keyword?index == 1>
+        <${keyword}>
+<#elseif keyword?index % 3 == 1>
+    |   <${keyword}>
+</#if>
+</#list>
+    )
+}
+
+/** @see #NonReservedKeyWord */
+void NonReservedKeyWord2of3() :
+{
+}
+{
+    (
+<#list parser.nonReservedKeywords as keyword>
+<#if keyword?index == 2>
+        <${keyword}>
+<#elseif keyword?index % 3 == 2>
+    |   <${keyword}>
+</#if>
+</#list>
+    )
+}
+
 /* LITERALS */
 
 <DEFAULT, DQID, BTID> TOKEN :

http://git-wip-us.apache.org/repos/asf/calcite/blob/561c6427/core/src/main/java/org/apache/calcite/prepare/PlannerImpl.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/prepare/PlannerImpl.java b/core/src/main/java/org/apache/calcite/prepare/PlannerImpl.java
index 9269155..382b2d7 100644
--- a/core/src/main/java/org/apache/calcite/prepare/PlannerImpl.java
+++ b/core/src/main/java/org/apache/calcite/prepare/PlannerImpl.java
@@ -39,7 +39,6 @@ import org.apache.calcite.sql.SqlOperatorTable;
 import org.apache.calcite.sql.parser.SqlParseException;
 import org.apache.calcite.sql.parser.SqlParser;
 import org.apache.calcite.sql.validate.SqlConformance;
-import org.apache.calcite.sql.validate.SqlConformanceEnum;
 import org.apache.calcite.sql.validate.SqlValidator;
 import org.apache.calcite.sql2rel.RelDecorrelator;
 import org.apache.calcite.sql2rel.SqlRexConvertletTable;
@@ -202,7 +201,7 @@ public class PlannerImpl implements Planner, ViewExpander {
         return connectionConfig.conformance();
       }
     }
-    return SqlConformanceEnum.DEFAULT;
+    return config.getParserConfig().conformance();
   }
 
   public Pair<SqlNode, RelDataType> validateAndGetType(SqlNode sqlNode)

http://git-wip-us.apache.org/repos/asf/calcite/blob/561c6427/core/src/test/codegen/config.fmpp
----------------------------------------------------------------------
diff --git a/core/src/test/codegen/config.fmpp b/core/src/test/codegen/config.fmpp
index 7833ee2..317656f 100644
--- a/core/src/test/codegen/config.fmpp
+++ b/core/src/test/codegen/config.fmpp
@@ -34,6 +34,295 @@ data: {
 
       # List of keywords from "keywords" section that are not reserved.
       nonReservedKeywords: [
+        "A"
+        "ABSOLUTE"
+        "ACTION"
+        "ADA"
+        "ADD"
+        "ADMIN"
+        "AFTER"
+        "ALWAYS"
+        "APPLY"
+        "ASC"
+        "ASSERTION"
+        "ASSIGNMENT"
+        "ATTRIBUTE"
+        "ATTRIBUTES"
+        "BEFORE"
+        "BERNOULLI"
+        "BREADTH"
+        "C"
+        "CASCADE"
+        "CATALOG"
+        "CATALOG_NAME"
+        "CENTURY"
+        "CHAIN"
+        "CHARACTER_SET_CATALOG"
+        "CHARACTER_SET_NAME"
+        "CHARACTER_SET_SCHEMA"
+        "CHARACTERISTICS"
+        "CHARACTERS"
+        "CLASS_ORIGIN"
+        "COBOL"
+        "COLLATION"
+        "COLLATION_CATALOG"
+        "COLLATION_NAME"
+        "COLLATION_SCHEMA"
+        "COLUMN_NAME"
+        "COMMAND_FUNCTION"
+        "COMMAND_FUNCTION_CODE"
+        "COMMITTED"
+        "CONDITION_NUMBER"
+        "CONNECTION"
+        "CONNECTION_NAME"
+        "CONSTRAINT_CATALOG"
+        "CONSTRAINT_NAME"
+        "CONSTRAINT_SCHEMA"
+        "CONSTRAINTS"
+        "CONSTRUCTOR"
+        "CONTINUE"
+        "CURSOR_NAME"
+        "DATA"
+        "DATABASE"
+        "DATETIME_INTERVAL_CODE"
+        "DATETIME_INTERVAL_PRECISION"
+        "DECADE"
+        "DEFAULTS"
+        "DEFERRABLE"
+        "DEFERRED"
+        "DEFINED"
+        "DEFINER"
+        "DEGREE"
+        "DEPTH"
+        "DERIVED"
+        "DESC"
+        "DESCRIPTION"
+        "DESCRIPTOR"
+        "DIAGNOSTICS"
+        "DISPATCH"
+        "DOMAIN"
+        "DOW"
+        "DOY"
+        "DYNAMIC_FUNCTION"
+        "DYNAMIC_FUNCTION_CODE"
+        "EPOCH"
+        "EXCEPTION"
+        "EXCLUDE"
+        "EXCLUDING"
+        "FINAL"
+        "FIRST"
+        "FOLLOWING"
+        "FORTRAN"
+        "FOUND"
+        "FRAC_SECOND"
+        "G"
+        "GENERAL"
+        "GENERATED"
+        "GEOMETRY"
+        "GO"
+        "GOTO"
+        "GRANTED"
+        "HIERARCHY"
+        "IMMEDIATE"
+        "IMMEDIATELY"
+        "IMPLEMENTATION"
+        "INCLUDING"
+        "INCREMENT"
+        "INITIALLY"
+        "INPUT"
+        "INSTANCE"
+        "INSTANTIABLE"
+        "INVOKER"
+        "ISODOW"
+        "ISOYEAR"
+        "ISOLATION"
+        "JAVA"
+        "JSON"
+        "K"
+        "KEY"
+        "KEY_MEMBER"
+        "KEY_TYPE"
+        "LABEL"
+        "LAST"
+        "LENGTH"
+        "LEVEL"
+        "LIBRARY"
+        "LOCATOR"
+        "M"
+        "MAP"
+        "MATCHED"
+        "MAXVALUE"
+        "MICROSECOND"
+        "MESSAGE_LENGTH"
+        "MESSAGE_OCTET_LENGTH"
+        "MESSAGE_TEXT"
+        "MILLISECOND"
+        "MILLENNIUM"
+        "MINVALUE"
+        "MORE_"
+        "MUMPS"
+        "NAME"
+        "NAMES"
+        "NANOSECOND"
+        "NESTING"
+        "NORMALIZED"
+        "NULLABLE"
+        "NULLS"
+        "NUMBER"
+        "OBJECT"
+        "OCTETS"
+        "OPTION"
+        "OPTIONS"
+        "ORDERING"
+        "ORDINALITY"
+        "OTHERS"
+        "OUTPUT"
+        "OVERRIDING"
+        "PAD"
+        "PARAMETER_MODE"
+        "PARAMETER_NAME"
+        "PARAMETER_ORDINAL_POSITION"
+        "PARAMETER_SPECIFIC_CATALOG"
+        "PARAMETER_SPECIFIC_NAME"
+        "PARAMETER_SPECIFIC_SCHEMA"
+        "PARTIAL"
+        "PASCAL"
+        "PASSTHROUGH"
+        "PAST"
+        "PATH"
+        "PLACING"
+        "PLAN"
+        "PLI"
+        "PRECEDING"
+        "PRESERVE"
+        "PRIOR"
+        "PRIVILEGES"
+        "PUBLIC"
+        "QUARTER"
+        "READ"
+        "RELATIVE"
+        "REPEATABLE"
+        "REPLACE"
+        "RESTART"
+        "RESTRICT"
+        "RETURNED_CARDINALITY"
+        "RETURNED_LENGTH"
+        "RETURNED_OCTET_LENGTH"
+        "RETURNED_SQLSTATE"
+        "ROLE"
+        "ROUTINE"
+        "ROUTINE_CATALOG"
+        "ROUTINE_NAME"
+        "ROUTINE_SCHEMA"
+        "ROW_COUNT"
+        "SCALE"
+        "SCHEMA"
+        "SCHEMA_NAME"
+        "SCOPE_CATALOGS"
+        "SCOPE_NAME"
+        "SCOPE_SCHEMA"
+        "SECTION"
+        "SECURITY"
+        "SELF"
+        "SEQUENCE"
+        "SERIALIZABLE"
+        "SERVER"
+        "SERVER_NAME"
+        "SESSION"
+        "SETS"
+        "SIMPLE"
+        "SIZE"
+        "SOURCE"
+        "SPACE"
+        "SPECIFIC_NAME"
+        "SQL_BIGINT"
+        "SQL_BINARY"
+        "SQL_BIT"
+        "SQL_BLOB"
+        "SQL_BOOLEAN"
+        "SQL_CHAR"
+        "SQL_CLOB"
+        "SQL_DATE"
+        "SQL_DECIMAL"
+        "SQL_DOUBLE"
+        "SQL_FLOAT"
+        "SQL_INTEGER"
+        "SQL_INTERVAL_DAY"
+        "SQL_INTERVAL_DAY_TO_HOUR"
+        "SQL_INTERVAL_DAY_TO_MINUTE"
+        "SQL_INTERVAL_DAY_TO_SECOND"
+        "SQL_INTERVAL_HOUR"
+        "SQL_INTERVAL_HOUR_TO_MINUTE"
+        "SQL_INTERVAL_HOUR_TO_SECOND"
+        "SQL_INTERVAL_MINUTE"
+        "SQL_INTERVAL_MINUTE_TO_SECOND"
+        "SQL_INTERVAL_MONTH"
+        "SQL_INTERVAL_SECOND"
+        "SQL_INTERVAL_YEAR"
+        "SQL_INTERVAL_YEAR_TO_MONTH"
+        "SQL_LONGVARBINARY"
+        "SQL_LONGVARNCHAR"
+        "SQL_LONGVARCHAR"
+        "SQL_NCHAR"
+        "SQL_NCLOB"
+        "SQL_NUMERIC"
+        "SQL_NVARCHAR"
+        "SQL_REAL"
+        "SQL_SMALLINT"
+        "SQL_TIME"
+        "SQL_TIMESTAMP"
+        "SQL_TINYINT"
+        "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"
+        "SQL_VARBINARY"
+        "SQL_VARCHAR"
+        "STATE"
+        "STATEMENT"
+        "STRUCTURE"
+        "STYLE"
+        "SUBCLASS_ORIGIN"
+        "SUBSTITUTE"
+        "TABLE_NAME"
+        "TEMPORARY"
+        "TIES"
+        "TIMESTAMPADD"
+        "TIMESTAMPDIFF"
+        "TOP_LEVEL_COUNT"
+        "TRANSACTION"
+        "TRANSACTIONS_ACTIVE"
+        "TRANSACTIONS_COMMITTED"
+        "TRANSACTIONS_ROLLED_BACK"
+        "TRANSFORM"
+        "TRANSFORMS"
+        "TRIGGER_CATALOG"
+        "TRIGGER_NAME"
+        "TRIGGER_SCHEMA"
+        "TYPE"
+        "UNBOUNDED"
+        "UNCOMMITTED"
+        "UNDER"
+        "UNNAMED"
+        "USAGE"
+        "USER_DEFINED_TYPE_CATALOG"
+        "USER_DEFINED_TYPE_CODE"
+        "USER_DEFINED_TYPE_NAME"
+        "USER_DEFINED_TYPE_SCHEMA"
+        "VERSION"
+        "VIEW"
+        "WEEK"
+        "WRAPPER"
+        "WORK"
+        "WRITE"
+        "XML"
+        "ZONE"
       ]
 
       # List of additional join types. Each is a method with no arguments.

http://git-wip-us.apache.org/repos/asf/calcite/blob/561c6427/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 4db60f1..6ad2769 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
@@ -61,9 +61,7 @@ import static org.hamcrest.CoreMatchers.equalTo;
 import static org.hamcrest.CoreMatchers.is;
 import static org.hamcrest.CoreMatchers.not;
 import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertThat;
-import static org.junit.Assert.assertTrue;
 import static org.junit.Assume.assumeTrue;
 
 /**
@@ -644,7 +642,15 @@ public class SqlParserTest {
     return keywords("c");
   }
 
-  private static SortedSet<String> keywords(String dialect) {
+  /** Returns whether a word is reserved in this parser. This method can be
+   * used to disable tests that behave differently with different collections
+   * of reserved words. */
+  protected boolean isReserved(String word) {
+    SqlAbstractParserImpl.Metadata metadata = getSqlParser("").getMetadata();
+    return metadata.isReservedWord(word.toUpperCase(Locale.ROOT));
+  }
+
+  protected static SortedSet<String> keywords(String dialect) {
     final ImmutableSortedSet.Builder<String> builder =
         ImmutableSortedSet.naturalOrder();
     String r = null;
@@ -1330,10 +1336,12 @@ public class SqlParserTest {
         "values a similar to b like c similar to d escape e escape f",
         "VALUES (ROW((`A` SIMILAR TO (`B` LIKE (`C` SIMILAR TO `D` ESCAPE `E`) ESCAPE `F`))))");
 
-    // FIXME should fail at "escape"
-    checkFails(
-        "select * from t ^where^ escape 'e'",
-        "(?s).*Encountered \"where escape\" at .*");
+    if (isReserved("ESCAPE")) {
+      // FIXME should fail at "escape"
+      checkFails(
+          "select * from t ^where^ escape 'e'",
+          "(?s).*Encountered \"where escape\" at .*");
+    }
 
     // LIKE with +
     check(
@@ -1346,15 +1354,19 @@ public class SqlParserTest {
         "VALUES (ROW((`A` LIKE (`B` || `C`) ESCAPE `D`)))");
 
     // ESCAPE with no expression
-    // FIXME should fail at "escape"
-    checkFails(
-        "values a ^like^ escape d",
-        "(?s).*Encountered \"like escape\" at .*");
+    if (isReserved("ESCAPE")) {
+      // FIXME should fail at "escape"
+      checkFails(
+          "values a ^like^ escape d",
+          "(?s).*Encountered \"like escape\" at .*");
+    }
 
     // ESCAPE with no expression
-    checkFails(
-        "values a like b || c ^escape^ and false",
-        "(?s).*Encountered \"escape and\" at line 1, column 22.*");
+    if (isReserved("ESCAPE")) {
+      checkFails(
+          "values a like b || c ^escape^ and false",
+          "(?s).*Encountered \"escape and\" at line 1, column 22.*");
+    }
 
     // basic SIMILAR TO
     check(
@@ -3519,23 +3531,33 @@ public class SqlParserTest {
   @Test public void testUpsertValues() {
     final String expected = "UPSERT INTO `EMPS`\n"
         + "VALUES (ROW(1, 'Fredkin'))";
-    sql("upsert into emps values (1,'Fredkin')")
-        .ok(expected)
-        .node(not(isDdl()));
+    final String sql = "upsert into emps values (1,'Fredkin')";
+    if (isReserved("UPSERT")) {
+      sql(sql)
+          .ok(expected)
+          .node(not(isDdl()));
+    }
   }
 
   @Test public void testUpsertSelect() {
-    sql("upsert into emps select * from emp as e")
-        .ok("UPSERT INTO `EMPS`\n"
-                + "(SELECT *\n"
-                + "FROM `EMP` AS `E`)");
+    final String sql = "upsert into emps select * from emp as e";
+    final String expected = "UPSERT INTO `EMPS`\n"
+        + "(SELECT *\n"
+        + "FROM `EMP` AS `E`)";
+    if (isReserved("UPSERT")) {
+      sql(sql).ok(expected);
+    }
   }
 
   @Test public void testExplainUpsert() {
-    sql("explain plan for upsert into emps1 values (1, 2)")
-        .ok("EXPLAIN PLAN INCLUDING ATTRIBUTES WITH IMPLEMENTATION FOR\n"
-            + "UPSERT INTO `EMPS1`\n"
-            + "VALUES (ROW(1, 2))");
+    final String sql = "explain plan for upsert into emps1 values (1, 2)";
+    final String expected = "EXPLAIN PLAN INCLUDING ATTRIBUTES"
+        + " WITH IMPLEMENTATION FOR\n"
+        + "UPSERT INTO `EMPS1`\n"
+        + "VALUES (ROW(1, 2))";
+    if (isReserved("UPSERT")) {
+      sql(sql).ok(expected);
+    }
   }
 
   @Test public void testDelete() {
@@ -3781,9 +3803,11 @@ public class SqlParserTest {
     checkExp(
         "nullif(v1,v2)",
         "(NULLIF(`V1`, `V2`))");
-    checkExpFails(
-        "1 + ^nullif^ + 3",
-        "(?s)Encountered \"nullif \\+\" at line 1, column 5.*");
+    if (isReserved("NULLIF")) {
+      checkExpFails(
+          "1 + ^nullif^ + 3",
+          "(?s)Encountered \"nullif \\+\" at line 1, column 5.*");
+    }
   }
 
   @Test public void testCoalesce() {
@@ -3841,6 +3865,24 @@ public class SqlParserTest {
     checkExp("replace('x', 'y', 'z')", "REPLACE('x', 'y', 'z')");
   }
 
+  @Test public void testDateLiteral() {
+    final String expected = "SELECT DATE '1980-01-01'\n"
+        + "FROM `T`";
+    sql("select date '1980-01-01' from t").ok(expected);
+    final String expected1 = "SELECT TIME '00:00:00'\n"
+        + "FROM `T`";
+    sql("select time '00:00:00' from t").ok(expected1);
+    final String expected2 = "SELECT TIMESTAMP '1980-01-01 00:00:00'\n"
+        + "FROM `T`";
+    sql("select timestamp '1980-01-01 00:00:00' from t").ok(expected2);
+    final String expected3 = "SELECT INTERVAL '3' DAY\n"
+        + "FROM `T`";
+    sql("select interval '3' day from t").ok(expected3);
+    final String expected4 = "SELECT INTERVAL '5:6' HOUR TO MINUTE\n"
+        + "FROM `T`";
+    sql("select interval '5:6' hour to minute from t").ok(expected4);
+  }
+
   // check date/time functions.
   @Test public void testTimeDate() {
     // CURRENT_TIME - returns time w/ timezone
@@ -7076,39 +7118,39 @@ public class SqlParserTest {
 
   @Test public void testMetadata() {
     SqlAbstractParserImpl.Metadata metadata = getSqlParser("").getMetadata();
-    assertTrue(metadata.isReservedFunctionName("ABS"));
-    assertFalse(metadata.isReservedFunctionName("FOO"));
-
-    assertTrue(metadata.isContextVariableName("CURRENT_USER"));
-    assertTrue(metadata.isContextVariableName("CURRENT_CATALOG"));
-    assertTrue(metadata.isContextVariableName("CURRENT_SCHEMA"));
-    assertFalse(metadata.isContextVariableName("ABS"));
-    assertFalse(metadata.isContextVariableName("FOO"));
-
-    assertTrue(metadata.isNonReservedKeyword("A"));
-    assertTrue(metadata.isNonReservedKeyword("KEY"));
-    assertFalse(metadata.isNonReservedKeyword("SELECT"));
-    assertFalse(metadata.isNonReservedKeyword("FOO"));
-    assertFalse(metadata.isNonReservedKeyword("ABS"));
-
-    assertTrue(metadata.isKeyword("ABS"));
-    assertTrue(metadata.isKeyword("CURRENT_USER"));
-    assertTrue(metadata.isKeyword("CURRENT_CATALOG"));
-    assertTrue(metadata.isKeyword("CURRENT_SCHEMA"));
-    assertTrue(metadata.isKeyword("KEY"));
-    assertTrue(metadata.isKeyword("SELECT"));
-    assertTrue(metadata.isKeyword("HAVING"));
-    assertTrue(metadata.isKeyword("A"));
-    assertFalse(metadata.isKeyword("BAR"));
-
-    assertTrue(metadata.isReservedWord("SELECT"));
-    assertTrue(metadata.isReservedWord("CURRENT_CATALOG"));
-    assertTrue(metadata.isReservedWord("CURRENT_SCHEMA"));
-    assertFalse(metadata.isReservedWord("KEY"));
+    assertThat(metadata.isReservedFunctionName("ABS"), is(true));
+    assertThat(metadata.isReservedFunctionName("FOO"), is(false));
+
+    assertThat(metadata.isContextVariableName("CURRENT_USER"), is(true));
+    assertThat(metadata.isContextVariableName("CURRENT_CATALOG"), is(true));
+    assertThat(metadata.isContextVariableName("CURRENT_SCHEMA"), is(true));
+    assertThat(metadata.isContextVariableName("ABS"), is(false));
+    assertThat(metadata.isContextVariableName("FOO"), is(false));
+
+    assertThat(metadata.isNonReservedKeyword("A"), is(true));
+    assertThat(metadata.isNonReservedKeyword("KEY"), is(true));
+    assertThat(metadata.isNonReservedKeyword("SELECT"), is(false));
+    assertThat(metadata.isNonReservedKeyword("FOO"), is(false));
+    assertThat(metadata.isNonReservedKeyword("ABS"), is(false));
+
+    assertThat(metadata.isKeyword("ABS"), is(true));
+    assertThat(metadata.isKeyword("CURRENT_USER"), is(true));
+    assertThat(metadata.isKeyword("CURRENT_CATALOG"), is(true));
+    assertThat(metadata.isKeyword("CURRENT_SCHEMA"), is(true));
+    assertThat(metadata.isKeyword("KEY"), is(true));
+    assertThat(metadata.isKeyword("SELECT"), is(true));
+    assertThat(metadata.isKeyword("HAVING"), is(true));
+    assertThat(metadata.isKeyword("A"), is(true));
+    assertThat(metadata.isKeyword("BAR"), is(false));
+
+    assertThat(metadata.isReservedWord("SELECT"), is(true));
+    assertThat(metadata.isReservedWord("CURRENT_CATALOG"), is(true));
+    assertThat(metadata.isReservedWord("CURRENT_SCHEMA"), is(true));
+    assertThat(metadata.isReservedWord("KEY"), is(false));
 
     String jdbcKeywords = metadata.getJdbcKeywords();
-    assertTrue(jdbcKeywords.contains(",COLLECT,"));
-    assertTrue(!jdbcKeywords.contains(",SELECT,"));
+    assertThat(jdbcKeywords.contains(",COLLECT,"), is(true));
+    assertThat(!jdbcKeywords.contains(",SELECT,"), is(true));
   }
 
   /**

http://git-wip-us.apache.org/repos/asf/calcite/blob/561c6427/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index 60f6099..d2ad4e3 100644
--- a/pom.xml
+++ b/pom.xml
@@ -82,7 +82,7 @@ limitations under the License.
     <foodmart-data-hsqldb.version>0.3</foodmart-data-hsqldb.version>
     <foodmart-queries.version>0.4.1</foodmart-queries.version>
     <forbiddenapis.version>2.6</forbiddenapis.version>
-    <freemarker.version>2.3.25-incubating</freemarker.version>
+    <freemarker.version>2.3.28</freemarker.version>
     <git-commit-id-plugin.version>2.1.9</git-commit-id-plugin.version>
     <geode.version>1.6.0</geode.version>
     <fongo.version>2.1.1</fongo.version>

http://git-wip-us.apache.org/repos/asf/calcite/blob/561c6427/server/src/main/codegen/config.fmpp
----------------------------------------------------------------------
diff --git a/server/src/main/codegen/config.fmpp b/server/src/main/codegen/config.fmpp
index 00a32ca..f0d8e48 100644
--- a/server/src/main/codegen/config.fmpp
+++ b/server/src/main/codegen/config.fmpp
@@ -37,6 +37,297 @@ data: {
 
       # List of keywords from "keywords" section that are not reserved.
       nonReservedKeywords: [
+        "A"
+        "ABSOLUTE"
+        "ACTION"
+        "ADA"
+        "ADD"
+        "ADMIN"
+        "AFTER"
+        "ALWAYS"
+        "APPLY"
+        "ASC"
+        "ASSERTION"
+        "ASSIGNMENT"
+        "ATTRIBUTE"
+        "ATTRIBUTES"
+        "BEFORE"
+        "BERNOULLI"
+        "BREADTH"
+        "C"
+        "CASCADE"
+        "CATALOG"
+        "CATALOG_NAME"
+        "CENTURY"
+        "CHAIN"
+        "CHARACTER_SET_CATALOG"
+        "CHARACTER_SET_NAME"
+        "CHARACTER_SET_SCHEMA"
+        "CHARACTERISTICS"
+        "CHARACTERS"
+        "CLASS_ORIGIN"
+        "COBOL"
+        "COLLATION"
+        "COLLATION_CATALOG"
+        "COLLATION_NAME"
+        "COLLATION_SCHEMA"
+        "COLUMN_NAME"
+        "COMMAND_FUNCTION"
+        "COMMAND_FUNCTION_CODE"
+        "COMMITTED"
+        "CONDITION_NUMBER"
+        "CONNECTION"
+        "CONNECTION_NAME"
+        "CONSTRAINT_CATALOG"
+        "CONSTRAINT_NAME"
+        "CONSTRAINT_SCHEMA"
+        "CONSTRAINTS"
+        "CONSTRUCTOR"
+        "CONTINUE"
+        "CURSOR_NAME"
+        "DATA"
+        "DATABASE"
+        "DATETIME_INTERVAL_CODE"
+        "DATETIME_INTERVAL_PRECISION"
+        "DECADE"
+        "DEFAULTS"
+        "DEFERRABLE"
+        "DEFERRED"
+        "DEFINED"
+        "DEFINER"
+        "DEGREE"
+        "DEPTH"
+        "DERIVED"
+        "DESC"
+        "DESCRIPTION"
+        "DESCRIPTOR"
+        "DIAGNOSTICS"
+        "DISPATCH"
+        "DOMAIN"
+        "DOW"
+        "DOY"
+        "DYNAMIC_FUNCTION"
+        "DYNAMIC_FUNCTION_CODE"
+        "EPOCH"
+        "EXCEPTION"
+        "EXCLUDE"
+        "EXCLUDING"
+        "FINAL"
+        "FIRST"
+        "FOLLOWING"
+        "FORTRAN"
+        "FOUND"
+        "FRAC_SECOND"
+        "G"
+        "GENERAL"
+        "GENERATED"
+        "GEOMETRY"
+        "GO"
+        "GOTO"
+        "GRANTED"
+        "HIERARCHY"
+        "IMMEDIATE"
+        "IMMEDIATELY"
+        "IMPLEMENTATION"
+        "INCLUDING"
+        "INCREMENT"
+        "INITIALLY"
+        "INPUT"
+        "INSTANCE"
+        "INSTANTIABLE"
+        "INVOKER"
+        "ISODOW"
+        "ISOYEAR"
+        "ISOLATION"
+        "JAVA"
+        "JSON"
+        "K"
+        "KEY"
+        "KEY_MEMBER"
+        "KEY_TYPE"
+        "LABEL"
+        "LAST"
+        "LENGTH"
+        "LEVEL"
+        "LIBRARY"
+        "LOCATOR"
+        "M"
+        "MAP"
+        "MATCHED"
+        "MAXVALUE"
+        "MICROSECOND"
+        "MESSAGE_LENGTH"
+        "MESSAGE_OCTET_LENGTH"
+        "MESSAGE_TEXT"
+        "MILLISECOND"
+        "MILLENNIUM"
+        "MINVALUE"
+        "MORE_"
+        "MUMPS"
+        "NAME"
+        "NAMES"
+        "NANOSECOND"
+        "NESTING"
+        "NORMALIZED"
+        "NULLABLE"
+        "NULLS"
+        "NUMBER"
+        "OBJECT"
+        "OCTETS"
+        "OPTION"
+        "OPTIONS"
+        "ORDERING"
+        "ORDINALITY"
+        "OTHERS"
+        "OUTPUT"
+        "OVERRIDING"
+        "PAD"
+        "PARAMETER_MODE"
+        "PARAMETER_NAME"
+        "PARAMETER_ORDINAL_POSITION"
+        "PARAMETER_SPECIFIC_CATALOG"
+        "PARAMETER_SPECIFIC_NAME"
+        "PARAMETER_SPECIFIC_SCHEMA"
+        "PARTIAL"
+        "PASCAL"
+        "PASSTHROUGH"
+        "PAST"
+        "PATH"
+        "PLACING"
+        "PLAN"
+        "PLI"
+        "PRECEDING"
+        "PRESERVE"
+        "PRIOR"
+        "PRIVILEGES"
+        "PUBLIC"
+        "QUARTER"
+        "READ"
+        "RELATIVE"
+        "REPEATABLE"
+        "REPLACE"
+        "RESTART"
+        "RESTRICT"
+        "RETURNED_CARDINALITY"
+        "RETURNED_LENGTH"
+        "RETURNED_OCTET_LENGTH"
+        "RETURNED_SQLSTATE"
+        "ROLE"
+        "ROUTINE"
+        "ROUTINE_CATALOG"
+        "ROUTINE_NAME"
+        "ROUTINE_SCHEMA"
+        "ROW_COUNT"
+        "SCALE"
+        "SCHEMA"
+        "SCHEMA_NAME"
+        "SCOPE_CATALOGS"
+        "SCOPE_NAME"
+        "SCOPE_SCHEMA"
+        "SECTION"
+        "SECURITY"
+        "SELF"
+        "SEQUENCE"
+        "SERIALIZABLE"
+        "SERVER"
+        "SERVER_NAME"
+        "SESSION"
+        "SETS"
+        "SIMPLE"
+        "SIZE"
+        "SOURCE"
+        "SPACE"
+        "SPECIFIC_NAME"
+        "SQL_BIGINT"
+        "SQL_BINARY"
+        "SQL_BIT"
+        "SQL_BLOB"
+        "SQL_BOOLEAN"
+        "SQL_CHAR"
+        "SQL_CLOB"
+        "SQL_DATE"
+        "SQL_DECIMAL"
+        "SQL_DOUBLE"
+        "SQL_FLOAT"
+        "SQL_INTEGER"
+        "SQL_INTERVAL_DAY"
+        "SQL_INTERVAL_DAY_TO_HOUR"
+        "SQL_INTERVAL_DAY_TO_MINUTE"
+        "SQL_INTERVAL_DAY_TO_SECOND"
+        "SQL_INTERVAL_HOUR"
+        "SQL_INTERVAL_HOUR_TO_MINUTE"
+        "SQL_INTERVAL_HOUR_TO_SECOND"
+        "SQL_INTERVAL_MINUTE"
+        "SQL_INTERVAL_MINUTE_TO_SECOND"
+        "SQL_INTERVAL_MONTH"
+        "SQL_INTERVAL_SECOND"
+        "SQL_INTERVAL_YEAR"
+        "SQL_INTERVAL_YEAR_TO_MONTH"
+        "SQL_LONGVARBINARY"
+        "SQL_LONGVARNCHAR"
+        "SQL_LONGVARCHAR"
+        "SQL_NCHAR"
+        "SQL_NCLOB"
+        "SQL_NUMERIC"
+        "SQL_NVARCHAR"
+        "SQL_REAL"
+        "SQL_SMALLINT"
+        "SQL_TIME"
+        "SQL_TIMESTAMP"
+        "SQL_TINYINT"
+        "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"
+        "SQL_VARBINARY"
+        "SQL_VARCHAR"
+        "STATE"
+        "STATEMENT"
+        "STRUCTURE"
+        "STYLE"
+        "SUBCLASS_ORIGIN"
+        "SUBSTITUTE"
+        "TABLE_NAME"
+        "TEMPORARY"
+        "TIES"
+        "TIMESTAMPADD"
+        "TIMESTAMPDIFF"
+        "TOP_LEVEL_COUNT"
+        "TRANSACTION"
+        "TRANSACTIONS_ACTIVE"
+        "TRANSACTIONS_COMMITTED"
+        "TRANSACTIONS_ROLLED_BACK"
+        "TRANSFORM"
+        "TRANSFORMS"
+        "TRIGGER_CATALOG"
+        "TRIGGER_NAME"
+        "TRIGGER_SCHEMA"
+        "TYPE"
+        "UNBOUNDED"
+        "UNCOMMITTED"
+        "UNDER"
+        "UNNAMED"
+        "USAGE"
+        "USER_DEFINED_TYPE_CATALOG"
+        "USER_DEFINED_TYPE_CODE"
+        "USER_DEFINED_TYPE_NAME"
+        "USER_DEFINED_TYPE_SCHEMA"
+        "VERSION"
+        "VIEW"
+        "WEEK"
+        "WRAPPER"
+        "WORK"
+        "WRITE"
+        "XML"
+        "ZONE"
+
+        # not in core, added in server
         "IF"
         "MATERIALIZED"
         "STORED"