You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by al...@apache.org on 2022/03/22 08:57:56 UTC

[ignite] branch sql-calcite updated: IGNITE-16710 Add generated parser sources to git - Fixes #9900.

This is an automated email from the ASF dual-hosted git repository.

alexpl pushed a commit to branch sql-calcite
in repository https://gitbox.apache.org/repos/asf/ignite.git


The following commit(s) were added to refs/heads/sql-calcite by this push:
     new 724b0bf  IGNITE-16710 Add generated parser sources to git - Fixes #9900.
724b0bf is described below

commit 724b0bfdca9a8866fcb69c06f8a4a1c348070239
Author: Aleksey Plekhanov <pl...@gmail.com>
AuthorDate: Tue Mar 22 11:38:37 2022 +0300

    IGNITE-16710 Add generated parser sources to git - Fixes #9900.
    
    Signed-off-by: Aleksey Plekhanov <pl...@gmail.com>
---
 modules/calcite/pom.xml                            |     2 +-
 modules/calcite/src/main/codegen/config.fmpp       |     3 +-
 .../query/calcite/CalciteQueryProcessor.java       |     2 +-
 .../query/calcite/sql/IgniteSqlAlterTable.java     |     2 +-
 .../calcite/sql/IgniteSqlAlterTableAddColumn.java  |     2 +-
 .../calcite/sql/IgniteSqlAlterTableDropColumn.java |     2 +-
 .../query/calcite/sql/IgniteSqlAlterUser.java      |     2 +-
 .../query/calcite/sql/IgniteSqlCreateIndex.java    |     2 +-
 .../query/calcite/sql/IgniteSqlCreateTable.java    |     2 +-
 .../query/calcite/sql/IgniteSqlCreateUser.java     |     2 +-
 .../query/calcite/sql/IgniteSqlDropIndex.java      |     2 +-
 .../query/calcite/sql/IgniteSqlDropUser.java       |     2 +-
 .../calcite/sql/generated/IgniteSqlParserImpl.java | 33498 +++++++++++++++++++
 .../generated/IgniteSqlParserImplConstants.java    |  1584 +
 .../generated/IgniteSqlParserImplTokenManager.java | 26455 +++++++++++++++
 .../calcite/sql/generated/ParseException.java      |   192 +
 .../calcite/sql/generated/SimpleCharStream.java    |   439 +
 .../query/calcite/sql/generated/Token.java         |    81 +
 .../query/calcite/sql/generated/TokenMgrError.java |   133 +
 .../query/calcite/sql/generated/package-info.java  |    28 +
 .../query/calcite/sql/SqlCustomParserTest.java     |     1 +
 parent/pom.xml                                     |     1 +
 22 files changed, 62425 insertions(+), 12 deletions(-)

diff --git a/modules/calcite/pom.xml b/modules/calcite/pom.xml
index 600be82..dcb39b0 100644
--- a/modules/calcite/pom.xml
+++ b/modules/calcite/pom.xml
@@ -297,7 +297,7 @@
                         </goals>
                         <configuration>
                             <sourceDirectory>${project.build.directory}/generated-sources/fmpp</sourceDirectory>
-                            <outputDirectory>${project.build.directory}/generated-sources/javacc</outputDirectory>
+                            <outputDirectory>${project.build.sourceDirectory}</outputDirectory>
                             <includes>
                                 <include>**/Parser.jj</include>
                             </includes>
diff --git a/modules/calcite/src/main/codegen/config.fmpp b/modules/calcite/src/main/codegen/config.fmpp
index aeaa0b6..f692ad7 100644
--- a/modules/calcite/src/main/codegen/config.fmpp
+++ b/modules/calcite/src/main/codegen/config.fmpp
@@ -21,7 +21,7 @@ data: {
   # FMPP will use the declaration from default_config.fmpp.
   parser: {
     # Generated parser implementation class package and name
-    package: "org.apache.ignite.internal.processors.query.calcite.sql",
+    package: "org.apache.ignite.internal.processors.query.calcite.sql.generated",
     class: "IgniteSqlParserImpl",
 
     # List of additional classes and packages to import.
@@ -35,6 +35,7 @@ data: {
       "org.apache.ignite.internal.processors.query.calcite.util.IgniteResource",
       "org.apache.ignite.lang.IgniteUuid",
       "org.apache.calcite.sql.ddl.SqlDdlNodes",
+      "org.apache.ignite.internal.processors.query.calcite.sql.*",
     ]
 
     # List of new keywords. Example: "DATABASES", "TABLES". If the keyword is
diff --git a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/CalciteQueryProcessor.java b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/CalciteQueryProcessor.java
index 347bfd2..beb3836 100644
--- a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/CalciteQueryProcessor.java
+++ b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/CalciteQueryProcessor.java
@@ -77,9 +77,9 @@ import org.apache.ignite.internal.processors.query.calcite.prepare.QueryPlanCach
 import org.apache.ignite.internal.processors.query.calcite.schema.SchemaHolder;
 import org.apache.ignite.internal.processors.query.calcite.schema.SchemaHolderImpl;
 import org.apache.ignite.internal.processors.query.calcite.sql.IgniteSqlConformance;
-import org.apache.ignite.internal.processors.query.calcite.sql.IgniteSqlParserImpl;
 import org.apache.ignite.internal.processors.query.calcite.sql.fun.IgniteOwnSqlOperatorTable;
 import org.apache.ignite.internal.processors.query.calcite.sql.fun.IgniteStdSqlOperatorTable;
+import org.apache.ignite.internal.processors.query.calcite.sql.generated.IgniteSqlParserImpl;
 import org.apache.ignite.internal.processors.query.calcite.trait.CorrelationTraitDef;
 import org.apache.ignite.internal.processors.query.calcite.trait.DistributionTraitDef;
 import org.apache.ignite.internal.processors.query.calcite.trait.RewindabilityTraitDef;
diff --git a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/sql/IgniteSqlAlterTable.java b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/sql/IgniteSqlAlterTable.java
index 67e7031..d7f0453 100644
--- a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/sql/IgniteSqlAlterTable.java
+++ b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/sql/IgniteSqlAlterTable.java
@@ -31,7 +31,7 @@ public class IgniteSqlAlterTable extends IgniteAbstractSqlAlterTable {
     private final boolean logging;
 
     /** */
-    protected IgniteSqlAlterTable(SqlParserPos pos, boolean ifExists, SqlIdentifier tblName, boolean logging) {
+    public IgniteSqlAlterTable(SqlParserPos pos, boolean ifExists, SqlIdentifier tblName, boolean logging) {
         super(pos, ifExists, tblName);
         this.logging = logging;
     }
diff --git a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/sql/IgniteSqlAlterTableAddColumn.java b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/sql/IgniteSqlAlterTableAddColumn.java
index 0687bbb..5f78ef1 100644
--- a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/sql/IgniteSqlAlterTableAddColumn.java
+++ b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/sql/IgniteSqlAlterTableAddColumn.java
@@ -36,7 +36,7 @@ public class IgniteSqlAlterTableAddColumn extends IgniteAbstractSqlAlterTable {
     private final SqlNodeList columns;
 
     /** */
-    protected IgniteSqlAlterTableAddColumn(SqlParserPos pos, boolean ifExists, SqlIdentifier tblName,
+    public IgniteSqlAlterTableAddColumn(SqlParserPos pos, boolean ifExists, SqlIdentifier tblName,
         boolean ifNotExistsColumn, SqlNodeList columns) {
         super(pos, ifExists, tblName);
         this.ifNotExistsColumn = ifNotExistsColumn;
diff --git a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/sql/IgniteSqlAlterTableDropColumn.java b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/sql/IgniteSqlAlterTableDropColumn.java
index e7a1b7e..dedb5fe 100644
--- a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/sql/IgniteSqlAlterTableDropColumn.java
+++ b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/sql/IgniteSqlAlterTableDropColumn.java
@@ -36,7 +36,7 @@ public class IgniteSqlAlterTableDropColumn extends IgniteAbstractSqlAlterTable {
     private final SqlNodeList columns;
 
     /** */
-    protected IgniteSqlAlterTableDropColumn(SqlParserPos pos, boolean ifExists, SqlIdentifier tblName,
+    public IgniteSqlAlterTableDropColumn(SqlParserPos pos, boolean ifExists, SqlIdentifier tblName,
         boolean ifExistsColumn, SqlNodeList columns) {
         super(pos, ifExists, tblName);
         this.ifExistsColumn = ifExistsColumn;
diff --git a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/sql/IgniteSqlAlterUser.java b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/sql/IgniteSqlAlterUser.java
index 4772085..4dbcc28 100644
--- a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/sql/IgniteSqlAlterUser.java
+++ b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/sql/IgniteSqlAlterUser.java
@@ -44,7 +44,7 @@ public class IgniteSqlAlterUser extends SqlDdl {
         new SqlSpecialOperator("ALTER USER", SqlKind.OTHER_DDL);
 
     /** */
-    protected IgniteSqlAlterUser(SqlParserPos pos, SqlIdentifier user, SqlLiteral pwd) {
+    public IgniteSqlAlterUser(SqlParserPos pos, SqlIdentifier user, SqlLiteral pwd) {
         super(OPERATOR, pos);
         this.user = Objects.requireNonNull(user, "user");
         this.pwd = Objects.requireNonNull(pwd, "password");
diff --git a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/sql/IgniteSqlCreateIndex.java b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/sql/IgniteSqlCreateIndex.java
index ca472d0..45a8473 100644
--- a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/sql/IgniteSqlCreateIndex.java
+++ b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/sql/IgniteSqlCreateIndex.java
@@ -55,7 +55,7 @@ public class IgniteSqlCreateIndex extends SqlCreate {
         new SqlSpecialOperator("CREATE INDEX", SqlKind.CREATE_INDEX);
 
     /** Creates a SqlCreateIndex. */
-    protected IgniteSqlCreateIndex(SqlParserPos pos, boolean ifNotExists, SqlIdentifier idxName, SqlIdentifier tblName,
+    public IgniteSqlCreateIndex(SqlParserPos pos, boolean ifNotExists, SqlIdentifier idxName, SqlIdentifier tblName,
         SqlNodeList columnList, SqlNumericLiteral parallel, SqlNumericLiteral inlineSize) {
         super(OPERATOR, pos, false, ifNotExists);
         this.idxName = Objects.requireNonNull(idxName, "index name");
diff --git a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/sql/IgniteSqlCreateTable.java b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/sql/IgniteSqlCreateTable.java
index bda05e6..f00b1ca 100644
--- a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/sql/IgniteSqlCreateTable.java
+++ b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/sql/IgniteSqlCreateTable.java
@@ -51,7 +51,7 @@ public class IgniteSqlCreateTable extends SqlCreate {
         new SqlSpecialOperator("CREATE TABLE", SqlKind.CREATE_TABLE);
 
     /** Creates a SqlCreateTable. */
-    protected IgniteSqlCreateTable(SqlParserPos pos, boolean ifNotExists, SqlIdentifier name,
+    public IgniteSqlCreateTable(SqlParserPos pos, boolean ifNotExists, SqlIdentifier name,
         @Nullable SqlNodeList columnList, @Nullable SqlNode qry, @Nullable SqlNodeList createOptionList) {
         super(OPERATOR, pos, false, ifNotExists);
         this.name = Objects.requireNonNull(name, "name");
diff --git a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/sql/IgniteSqlCreateUser.java b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/sql/IgniteSqlCreateUser.java
index 5074080..c93add2 100644
--- a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/sql/IgniteSqlCreateUser.java
+++ b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/sql/IgniteSqlCreateUser.java
@@ -44,7 +44,7 @@ public class IgniteSqlCreateUser extends SqlCreate {
         new SqlSpecialOperator("CREATE USER", SqlKind.OTHER_DDL);
 
     /** */
-    protected IgniteSqlCreateUser(SqlParserPos pos, SqlIdentifier user, SqlLiteral pwd) {
+    public IgniteSqlCreateUser(SqlParserPos pos, SqlIdentifier user, SqlLiteral pwd) {
         super(OPERATOR, pos, false, false);
         this.user = Objects.requireNonNull(user, "user");
         this.pwd = Objects.requireNonNull(pwd, "password");
diff --git a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/sql/IgniteSqlDropIndex.java b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/sql/IgniteSqlDropIndex.java
index 57afc9c..793f3a6 100644
--- a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/sql/IgniteSqlDropIndex.java
+++ b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/sql/IgniteSqlDropIndex.java
@@ -40,7 +40,7 @@ public class IgniteSqlDropIndex extends SqlDrop {
         new SqlSpecialOperator("DROP INDEX", SqlKind.DROP_INDEX);
 
     /** */
-    protected IgniteSqlDropIndex(SqlParserPos pos, boolean ifExists, SqlIdentifier idxName) {
+    public IgniteSqlDropIndex(SqlParserPos pos, boolean ifExists, SqlIdentifier idxName) {
         super(OPERATOR, pos, ifExists);
         name = Objects.requireNonNull(idxName, "index name");
     }
diff --git a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/sql/IgniteSqlDropUser.java b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/sql/IgniteSqlDropUser.java
index bd067f0..081737f 100644
--- a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/sql/IgniteSqlDropUser.java
+++ b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/sql/IgniteSqlDropUser.java
@@ -40,7 +40,7 @@ public class IgniteSqlDropUser extends SqlDrop {
         new SqlSpecialOperator("DROP USER", SqlKind.OTHER_DDL);
 
     /** */
-    protected IgniteSqlDropUser(SqlParserPos pos, SqlIdentifier user) {
+    public IgniteSqlDropUser(SqlParserPos pos, SqlIdentifier user) {
         super(OPERATOR, pos, false);
         this.user = Objects.requireNonNull(user, "user");
     }
diff --git a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/sql/generated/IgniteSqlParserImpl.java b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/sql/generated/IgniteSqlParserImpl.java
new file mode 100644
index 0000000..505da8f8
--- /dev/null
+++ b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/sql/generated/IgniteSqlParserImpl.java
@@ -0,0 +1,33498 @@
+/* Generated By:JavaCC: Do not edit this line. IgniteSqlParserImpl.java */
+package org.apache.ignite.internal.processors.query.calcite.sql.generated;
+
+import java.util.UUID;
+import org.apache.calcite.sql.SqlCreate;
+import org.apache.calcite.sql.SqlDrop;
+import org.apache.calcite.sql.SqlLiteral;
+import org.apache.calcite.schema.ColumnStrategy;
+import org.apache.ignite.internal.processors.query.calcite.util.IgniteResource;
+import org.apache.ignite.lang.IgniteUuid;
+import org.apache.calcite.sql.ddl.SqlDdlNodes;
+import org.apache.ignite.internal.processors.query.calcite.sql.*;
+
+import org.apache.calcite.avatica.util.Casing;
+import org.apache.calcite.avatica.util.DateTimeUtils;
+import org.apache.calcite.avatica.util.TimeUnit;
+import org.apache.calcite.rel.type.RelDataType;
+import org.apache.calcite.runtime.CalciteContextException;
+import org.apache.calcite.sql.JoinConditionType;
+import org.apache.calcite.sql.JoinType;
+import org.apache.calcite.sql.SqlAlter;
+import org.apache.calcite.sql.SqlBasicTypeNameSpec;
+import org.apache.calcite.sql.SqlBinaryOperator;
+import org.apache.calcite.sql.SqlCall;
+import org.apache.calcite.sql.SqlCharStringLiteral;
+import org.apache.calcite.sql.SqlCollation;
+import org.apache.calcite.sql.SqlCollectionTypeNameSpec;
+import org.apache.calcite.sql.SqlDataTypeSpec;
+import org.apache.calcite.sql.SqlDateLiteral;
+import org.apache.calcite.sql.SqlDelete;
+import org.apache.calcite.sql.SqlDescribeSchema;
+import org.apache.calcite.sql.SqlDescribeTable;
+import org.apache.calcite.sql.SqlDynamicParam;
+import org.apache.calcite.sql.SqlExplain;
+import org.apache.calcite.sql.SqlExplainFormat;
+import org.apache.calcite.sql.SqlExplainLevel;
+import org.apache.calcite.sql.SqlFunction;
+import org.apache.calcite.sql.SqlFunctionCategory;
+import org.apache.calcite.sql.SqlHint;
+import org.apache.calcite.sql.SqlIdentifier;
+import org.apache.calcite.sql.SqlInsert;
+import org.apache.calcite.sql.SqlInsertKeyword;
+import org.apache.calcite.sql.SqlIntervalLiteral;
+import org.apache.calcite.sql.SqlIntervalQualifier;
+import org.apache.calcite.sql.SqlJdbcDataTypeName;
+import org.apache.calcite.sql.SqlJdbcFunctionCall;
+import org.apache.calcite.sql.SqlJoin;
+import org.apache.calcite.sql.SqlJsonConstructorNullClause;
+import org.apache.calcite.sql.SqlJsonEncoding;
+import org.apache.calcite.sql.SqlJsonExistsErrorBehavior;
+import org.apache.calcite.sql.SqlJsonEmptyOrError;
+import org.apache.calcite.sql.SqlJsonQueryEmptyOrErrorBehavior;
+import org.apache.calcite.sql.SqlJsonQueryWrapperBehavior;
+import org.apache.calcite.sql.SqlJsonValueEmptyOrErrorBehavior;
+import org.apache.calcite.sql.SqlJsonValueReturning;
+import org.apache.calcite.sql.SqlKind;
+import org.apache.calcite.sql.SqlLiteral;
+import org.apache.calcite.sql.SqlMatchRecognize;
+import org.apache.calcite.sql.SqlMerge;
+import org.apache.calcite.sql.SqlNode;
+import org.apache.calcite.sql.SqlNodeList;
+import org.apache.calcite.sql.SqlNumericLiteral;
+import org.apache.calcite.sql.SqlOperator;
+import org.apache.calcite.sql.SqlOrderBy;
+import org.apache.calcite.sql.SqlPivot;
+import org.apache.calcite.sql.SqlPostfixOperator;
+import org.apache.calcite.sql.SqlPrefixOperator;
+import org.apache.calcite.sql.SqlRowTypeNameSpec;
+import org.apache.calcite.sql.SqlSampleSpec;
+import org.apache.calcite.sql.SqlSelect;
+import org.apache.calcite.sql.SqlSelectKeyword;
+import org.apache.calcite.sql.SqlSetOption;
+import org.apache.calcite.sql.SqlSnapshot;
+import org.apache.calcite.sql.SqlTableRef;
+import org.apache.calcite.sql.SqlTimeLiteral;
+import org.apache.calcite.sql.SqlTimestampLiteral;
+import org.apache.calcite.sql.SqlTypeNameSpec;
+import org.apache.calcite.sql.SqlUnnestOperator;
+import org.apache.calcite.sql.SqlUnpivot;
+import org.apache.calcite.sql.SqlUpdate;
+import org.apache.calcite.sql.SqlUserDefinedTypeNameSpec;
+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.fun.SqlCase;
+import org.apache.calcite.sql.fun.SqlInternalOperators;
+import org.apache.calcite.sql.fun.SqlLibraryOperators;
+import org.apache.calcite.sql.fun.SqlStdOperatorTable;
+import org.apache.calcite.sql.fun.SqlTrimFunction;
+import org.apache.calcite.sql.parser.Span;
+import org.apache.calcite.sql.parser.SqlAbstractParserImpl;
+import org.apache.calcite.sql.parser.SqlParseException;
+import org.apache.calcite.sql.parser.SqlParser;
+import org.apache.calcite.sql.parser.SqlParserImplFactory;
+import org.apache.calcite.sql.parser.SqlParserPos;
+import org.apache.calcite.sql.parser.SqlParserUtil;
+import org.apache.calcite.sql.type.SqlTypeName;
+import org.apache.calcite.sql.validate.SqlConformance;
+import org.apache.calcite.util.Glossary;
+import org.apache.calcite.util.NlsString;
+import org.apache.calcite.util.Pair;
+import org.apache.calcite.util.SourceStringReader;
+import org.apache.calcite.util.Util;
+import org.apache.calcite.util.trace.CalciteTrace;
+
+import org.slf4j.Logger;
+
+import java.io.Reader;
+import java.math.BigDecimal;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Calendar;
+import java.util.Collections;
+import java.util.List;
+import java.util.Locale;
+
+import static org.apache.calcite.util.Static.RESOURCE;
+
+/**
+ * SQL parser, generated from Parser.jj by JavaCC.
+ *
+ * <p>The public wrapper for this parser is {@link SqlParser}.
+ */
+public class IgniteSqlParserImpl extends SqlAbstractParserImpl implements IgniteSqlParserImplConstants {
+    private static final Logger LOGGER = CalciteTrace.getParserTracer();
+
+    // Can't use quoted literal because of a bug in how JavaCC translates
+    // backslash-backslash.
+    private static final char BACKSLASH = 0x5c;
+    private static final char DOUBLE_QUOTE = 0x22;
+    private static final String DQ = DOUBLE_QUOTE + "";
+    private static final String DQDQ = DQ + DQ;
+
+    private static Metadata metadata;
+
+    private Casing unquotedCasing;
+    private Casing quotedCasing;
+    private int identifierMaxLength;
+    private SqlConformance conformance;
+
+    /**
+     * {@link SqlParserImplFactory} implementation for creating parser.
+     */
+    public static final SqlParserImplFactory FACTORY = new SqlParserImplFactory() {
+        public SqlAbstractParserImpl getParser(Reader reader) {
+            final IgniteSqlParserImpl parser = new IgniteSqlParserImpl(reader);
+            if (reader instanceof SourceStringReader) {
+                final String sql =
+                    ((SourceStringReader) reader).getSourceString();
+                parser.setOriginalSql(sql);
+            }
+          return parser;
+        }
+    };
+
+    public SqlParseException normalizeException(Throwable ex) {
+        try {
+            if (ex instanceof ParseException) {
+                ex = cleanupParseException((ParseException) ex);
+            }
+            return convertException(ex);
+        } catch (ParseException e) {
+            throw new AssertionError(e);
+        }
+    }
+
+    public Metadata getMetadata() {
+        synchronized (IgniteSqlParserImpl.class) {
+            if (metadata == null) {
+                metadata = new MetadataImpl(
+                    new IgniteSqlParserImpl(new java.io.StringReader("")));
+            }
+            return metadata;
+        }
+    }
+
+    public void setTabSize(int tabSize) {
+        jj_input_stream.setTabSize(tabSize);
+    }
+
+    public void switchTo(SqlAbstractParserImpl.LexicalState state) {
+        final int stateOrdinal =
+            Arrays.asList(IgniteSqlParserImplTokenManager.lexStateNames)
+                .indexOf(state.name());
+        token_source.SwitchTo(stateOrdinal);
+    }
+
+    public void setQuotedCasing(Casing quotedCasing) {
+        this.quotedCasing = quotedCasing;
+    }
+
+    public void setUnquotedCasing(Casing unquotedCasing) {
+        this.unquotedCasing = unquotedCasing;
+    }
+
+    public void setIdentifierMaxLength(int identifierMaxLength) {
+        this.identifierMaxLength = identifierMaxLength;
+    }
+
+    public void setConformance(SqlConformance conformance) {
+        this.conformance = conformance;
+    }
+
+    public SqlNode parseSqlExpressionEof() throws Exception {
+        return SqlExpressionEof();
+    }
+
+    public SqlNode parseSqlStmtEof() throws Exception {
+        return SqlStmtEof();
+    }
+
+    public SqlNodeList parseSqlStmtList() throws Exception {
+        return SqlStmtList();
+    }
+
+    private SqlNode extend(SqlNode table, SqlNodeList extendList) {
+        return SqlStdOperatorTable.EXTEND.createCall(
+            Span.of(table, extendList).pos(), table, extendList);
+    }
+
+    /** Adds a warning that a token such as "HOURS" was used,
+    * whereas the SQL standard only allows "HOUR".
+    *
+    * <p>Currently, we silently add an exception to a list of warnings. In
+    * future, we may have better compliance checking, for example a strict
+    * compliance mode that throws if any non-standard features are used. */
+    private TimeUnit warn(TimeUnit timeUnit) throws ParseException {
+        final String token = getToken(0).image.toUpperCase(Locale.ROOT);
+        warnings.add(
+            SqlUtil.newContextException(getPos(),
+                RESOURCE.nonStandardFeatureUsed(token)));
+        return timeUnit;
+    }
+
+  void debug_message1() throws ParseException {
+    LOGGER.info("{} , {}", getToken(0).image, getToken(1).image);
+  }
+
+  String unquotedIdentifier() throws ParseException {
+    return SqlParserUtil.toCase(getToken(0).image, unquotedCasing);
+  }
+
+/**
+ * Allows parser to be extended with new types of table references.  The
+ * default implementation of this production is empty.
+ */
+  final public SqlNode ExtendedTableRef() throws ParseException {
+    UnusedExtension();
+        {if (true) return null;}
+    throw new Error("Missing return statement in function");
+  }
+
+/**
+ * Allows an OVER clause following a table expression as an extension to
+ * standard SQL syntax. The default implementation of this production is empty.
+ */
+  final public SqlNode TableOverOpt() throws ParseException {
+        {if (true) return null;}
+    throw new Error("Missing return statement in function");
+  }
+
+/*
+ * Parses dialect-specific keywords immediately following the SELECT keyword.
+ */
+  final public void SqlSelectKeywords(List<SqlLiteral> keywords) throws ParseException {
+    E();
+  }
+
+/*
+ * Parses dialect-specific keywords immediately following the INSERT keyword.
+ */
+  final public void SqlInsertKeywords(List<SqlLiteral> keywords) throws ParseException {
+    E();
+  }
+
+/*
+* Parse Floor/Ceil function parameters
+*/
+  final public SqlNode FloorCeilOptions(Span s, boolean floorFlag) throws ParseException {
+    SqlNode node;
+    node = StandardFloorCeilOptions(s, floorFlag);
+        {if (true) return node;}
+    throw new Error("Missing return statement in function");
+  }
+
+  void E() throws ParseException {
+  }
+
+  List startList(Object o) throws ParseException {
+    List list = new ArrayList();
+    list.add(o);
+    return list;
+  }
+
+  protected SqlParserPos getPos() throws ParseException {
+    return new SqlParserPos(
+        token.beginLine,
+        token.beginColumn,
+        token.endLine,
+        token.endColumn);
+  }
+
+  Span span() throws ParseException {
+    return Span.of(getPos());
+  }
+
+  void checkQueryExpression(ExprContext exprContext) throws ParseException {
+    switch (exprContext) {
+    case ACCEPT_NON_QUERY:
+    case ACCEPT_SUB_QUERY:
+    case ACCEPT_CURSOR:
+        throw SqlUtil.newContextException(getPos(),
+            RESOURCE.illegalQueryExpression());
+    }
+  }
+
+  void checkNonQueryExpression(ExprContext exprContext) throws ParseException {
+    switch (exprContext) {
+    case ACCEPT_QUERY:
+        throw SqlUtil.newContextException(getPos(),
+            RESOURCE.illegalNonQueryExpression());
+    }
+  }
+
+  SqlParseException convertException(Throwable ex) throws ParseException {
+    if (ex instanceof SqlParseException) {
+        return (SqlParseException) ex;
+    }
+    SqlParserPos pos = null;
+    int[][] expectedTokenSequences = null;
+    String[] tokenImage = null;
+    if (ex instanceof ParseException) {
+        ParseException pex = (ParseException) ex;
+        expectedTokenSequences = pex.expectedTokenSequences;
+        tokenImage = pex.tokenImage;
+        if (pex.currentToken != null) {
+            final Token token = pex.currentToken.next;
+            // Checks token.image.equals("1") to avoid recursive call.
+            // The SqlAbstractParserImpl#MetadataImpl constructor uses constant "1" to
+            // throw intentionally to collect the expected tokens.
+            if (!token.image.equals("1")
+                && getMetadata().isKeyword(token.image)
+                && SqlParserUtil.allowsIdentifier(tokenImage, expectedTokenSequences)) {
+                // If the next token is a keyword, reformat the error message as:
+
+                // Incorrect syntax near the keyword '{keyword}' at line {line_number},
+                // column {column_number}.
+                final String expecting = ex.getMessage()
+                    .substring(ex.getMessage().indexOf("Was expecting"));
+                final String errorMsg = String.format("Incorrect syntax near the keyword '%s' "
+                        + "at line %d, column %d.\n%s",
+                    token.image,
+                    token.beginLine,
+                    token.beginColumn,
+                    expecting);
+                // Replace the ParseException with explicit error message.
+                ex = new ParseException(errorMsg);
+            }
+            pos = new SqlParserPos(
+                token.beginLine,
+                token.beginColumn,
+                token.endLine,
+                token.endColumn);
+        }
+    } else if (ex instanceof TokenMgrError) {
+        TokenMgrError tme = (TokenMgrError) ex;
+        expectedTokenSequences = null;
+        tokenImage = null;
+        // Example:
+        //    Lexical error at line 3, column 24.  Encountered "#" after "a".
+        final java.util.regex.Pattern pattern = java.util.regex.Pattern.compile(
+            "(?s)Lexical error at line ([0-9]+), column ([0-9]+).*");
+        java.util.regex.Matcher matcher = pattern.matcher(ex.getMessage());
+        if (matcher.matches()) {
+            int line = Integer.parseInt(matcher.group(1));
+            int column = Integer.parseInt(matcher.group(2));
+            pos = new SqlParserPos(line, column, line, column);
+        }
+    } else if (ex instanceof CalciteContextException) {
+        // CalciteContextException is the standard wrapper for exceptions
+        // produced by the validator, but in the parser, the standard is
+        // SqlParseException; so, strip it away. In case you were wondering,
+        // the CalciteContextException appears because the parser
+        // occasionally calls into validator-style code such as
+        // SqlSpecialOperator.reduceExpr.
+        CalciteContextException ece =
+            (CalciteContextException) ex;
+        pos = new SqlParserPos(
+            ece.getPosLine(),
+            ece.getPosColumn(),
+            ece.getEndPosLine(),
+            ece.getEndPosColumn());
+        ex = ece.getCause();
+    }
+
+    return new SqlParseException(
+        ex.getMessage(), pos, expectedTokenSequences, tokenImage, ex);
+  }
+
+  ParseException cleanupParseException(ParseException ex) throws ParseException {
+    if (ex.expectedTokenSequences == null) {
+        return ex;
+    }
+    int iIdentifier = Arrays.asList(ex.tokenImage).indexOf("<IDENTIFIER>");
+
+    // Find all sequences in the error which contain identifier. For
+    // example,
+    //       {<IDENTIFIER>}
+    //       {A}
+    //       {B, C}
+    //       {D, <IDENTIFIER>}
+    //       {D, A}
+    //       {D, B}
+    //
+    // would yield
+    //       {}
+    //       {D}
+    boolean id = false;
+    final List<int[]> prefixList = new ArrayList<int[]>();
+    for (int i = 0; i < ex.expectedTokenSequences.length; ++i) {
+        int[] seq = ex.expectedTokenSequences[i];
+        int j = seq.length - 1;
+        int i1 = seq[j];
+        if (i1 == iIdentifier) {
+            int[] prefix = new int[j];
+            System.arraycopy(seq, 0, prefix, 0, j);
+            prefixList.add(prefix);
+        }
+    }
+
+    if (prefixList.isEmpty()) {
+        return ex;
+    }
+
+    int[][] prefixes = (int[][])
+        prefixList.toArray(new int[prefixList.size()][]);
+
+    // Since <IDENTIFIER> was one of the possible productions,
+    // we know that the parser will also have included all
+    // of the non-reserved keywords (which are treated as
+    // identifiers in non-keyword contexts).  So, now we need
+    // to clean those out, since they're totally irrelevant.
+
+    final List<int[]> list = new ArrayList<int[]>();
+    Metadata metadata = getMetadata();
+    for (int i = 0; i < ex.expectedTokenSequences.length; ++i) {
+        int [] seq = ex.expectedTokenSequences[i];
+        String tokenImage = ex.tokenImage[seq[seq.length - 1]];
+        String token = SqlParserUtil.getTokenVal(tokenImage);
+        if (token == null  || !metadata.isNonReservedKeyword(token)) {
+            list.add(seq);
+            continue;
+        }
+        boolean match = matchesPrefix(seq, prefixes);
+        if (!match) {
+            list.add(seq);
+        }
+    }
+
+    ex.expectedTokenSequences =
+        (int [][]) list.toArray(new int [list.size()][]);
+    return ex;
+  }
+
+  boolean matchesPrefix(int[] seq, int[][] prefixes) throws ParseException {
+    nextPrefix:
+    for (int[] prefix : prefixes) {
+        if (seq.length == prefix.length + 1) {
+            for (int k = 0; k < prefix.length; k++) {
+                if (prefix[k] != seq[k]) {
+                    continue nextPrefix;
+                }
+            }
+            return true;
+        }
+    }
+    return false;
+  }
+
+/*****************************************
+ * Syntactical Descriptions              *
+ *****************************************/
+
+/**
+ * Parses either a row expression or a query expression with an optional
+ * ORDER BY.
+ *
+ * <p>Postgres syntax for limit:
+ *
+ * <blockquote><pre>
+ *    [ LIMIT { count | ALL } ]
+ *    [ OFFSET start ]</pre>
+ * </blockquote>
+ *
+ * <p>MySQL syntax for limit:
+ *
+ * <blockquote><pre>
+ *    [ LIMIT { count | start, count } ]</pre>
+ * </blockquote>
+ *
+ * <p>SQL:2008 syntax for limit:
+ *
+ * <blockquote><pre>
+ *    [ OFFSET start { ROW | ROWS } ]
+ *    [ FETCH { FIRST | NEXT } [ count ] { ROW | ROWS } ONLY ]</pre>
+ * </blockquote>
+ */
+  final public SqlNode OrderedQueryOrExpr(ExprContext exprContext) throws ParseException {
+    SqlNode e;
+    SqlNodeList orderBy = null;
+    SqlNode start = null;
+    SqlNode count = null;
+    e = QueryOrExpr(exprContext);
+    if (jj_2_1(2)) {
+      // use the syntactic type of the expression we just parsed
+              // to decide whether ORDER BY makes sense
+              orderBy = OrderBy(e.isA(SqlKind.QUERY));
+    } else {
+      ;
+    }
+    if (jj_2_5(2)) {
+      jj_consume_token(LIMIT);
+      if (jj_2_2(2)) {
+        start = UnsignedNumericLiteralOrParam();
+        jj_consume_token(COMMA);
+        count = UnsignedNumericLiteralOrParam();
+                if (!this.conformance.isLimitStartCountAllowed()) {
+                    {if (true) throw SqlUtil.newContextException(getPos(), RESOURCE.limitStartCountNotAllowed());}
+                }
+      } else if (jj_2_3(2)) {
+        count = UnsignedNumericLiteralOrParam();
+      } else if (jj_2_4(2)) {
+        jj_consume_token(ALL);
+      } else {
+        jj_consume_token(-1);
+        throw new ParseException();
+      }
+    } else {
+      ;
+    }
+    if (jj_2_9(2)) {
+      jj_consume_token(OFFSET);
+      start = UnsignedNumericLiteralOrParam();
+      if (jj_2_8(2)) {
+        if (jj_2_6(2)) {
+          jj_consume_token(ROW);
+        } else if (jj_2_7(2)) {
+          jj_consume_token(ROWS);
+        } else {
+          jj_consume_token(-1);
+          throw new ParseException();
+        }
+      } else {
+        ;
+      }
+    } else {
+      ;
+    }
+    if (jj_2_14(2)) {
+      jj_consume_token(FETCH);
+      if (jj_2_10(2)) {
+        jj_consume_token(FIRST);
+      } else if (jj_2_11(2)) {
+        jj_consume_token(NEXT);
+      } else {
+        jj_consume_token(-1);
+        throw new ParseException();
+      }
+      count = UnsignedNumericLiteralOrParam();
+      if (jj_2_12(2)) {
+        jj_consume_token(ROW);
+      } else if (jj_2_13(2)) {
+        jj_consume_token(ROWS);
+      } else {
+        jj_consume_token(-1);
+        throw new ParseException();
+      }
+      jj_consume_token(ONLY);
+    } else {
+      ;
+    }
+        if (orderBy != null || start != null || count != null) {
+            if (orderBy == null) {
+                orderBy = SqlNodeList.EMPTY;
+            }
+            e = new SqlOrderBy(getPos(), e, orderBy, start, count);
+
+        }
+        {if (true) return e;}
+    throw new Error("Missing return statement in function");
+  }
+
+/**
+ * Parses a leaf in a query expression (SELECT, VALUES or TABLE).
+ */
+  final public SqlNode LeafQuery(ExprContext exprContext) throws ParseException {
+    SqlNode e;
+    if (jj_2_15(2)) {
+        // ensure a query is legal in this context
+        checkQueryExpression(exprContext);
+      e = SqlSelect();
+                      {if (true) return e;}
+    } else if (jj_2_16(2)) {
+      e = TableConstructor();
+                             {if (true) return e;}
+    } else if (jj_2_17(2)) {
+      e = ExplicitTable(getPos());
+                                  {if (true) return e;}
+    } else {
+      jj_consume_token(-1);
+      throw new ParseException();
+    }
+    throw new Error("Missing return statement in function");
+  }
+
+/**
+ * Parses a parenthesized query or single row expression.
+ */
+  final public SqlNode ParenthesizedExpression(ExprContext exprContext) throws ParseException {
+    SqlNode e;
+    jj_consume_token(LPAREN);
+        // we've now seen left paren, so queries inside should
+        // be allowed as sub-queries
+        switch (exprContext) {
+        case ACCEPT_SUB_QUERY:
+            exprContext = ExprContext.ACCEPT_NONCURSOR;
+            break;
+        case ACCEPT_CURSOR:
+            exprContext = ExprContext.ACCEPT_ALL;
+            break;
+        }
+    e = OrderedQueryOrExpr(exprContext);
+    jj_consume_token(RPAREN);
+        {if (true) return e;}
+    throw new Error("Missing return statement in function");
+  }
+
+/**
+ * Parses a parenthesized query or comma-list of row expressions.
+ *
+ * <p>REVIEW jvs 8-Feb-2004: There's a small hole in this production.  It can be
+ * used to construct something like
+ *
+ * <blockquote><pre>
+ * WHERE x IN (select count(*) from t where c=d,5)</pre>
+ * </blockquote>
+ *
+ * <p>which should be illegal.  The above is interpreted as equivalent to
+ *
+ * <blockquote><pre>
+ * WHERE x IN ((select count(*) from t where c=d),5)</pre>
+ * </blockquote>
+ *
+ * <p>which is a legal use of a sub-query.  The only way to fix the hole is to
+ * be able to remember whether a subexpression was parenthesized or not, which
+ * means preserving parentheses in the SqlNode tree.  This is probably
+ * desirable anyway for use in purely syntactic parsing applications (e.g. SQL
+ * pretty-printer).  However, if this is done, it's important to also make
+ * isA() on the paren node call down to its operand so that we can
+ * always correctly discriminate a query from a row expression.
+ */
+  final public SqlNodeList ParenthesizedQueryOrCommaList(ExprContext exprContext) throws ParseException {
+    SqlNode e;
+    List<SqlNode> list;
+    ExprContext firstExprContext = exprContext;
+    final Span s;
+    jj_consume_token(LPAREN);
+        // we've now seen left paren, so a query by itself should
+        // be interpreted as a sub-query
+        s = span();
+        switch (exprContext) {
+        case ACCEPT_SUB_QUERY:
+            firstExprContext = ExprContext.ACCEPT_NONCURSOR;
+            break;
+        case ACCEPT_CURSOR:
+            firstExprContext = ExprContext.ACCEPT_ALL;
+            break;
+        }
+    e = OrderedQueryOrExpr(firstExprContext);
+        list = startList(e);
+    label_1:
+    while (true) {
+      if (jj_2_18(2)) {
+        ;
+      } else {
+        break label_1;
+      }
+      jj_consume_token(COMMA);
+            // a comma-list can't appear where only a query is expected
+            checkNonQueryExpression(exprContext);
+      e = Expression(exprContext);
+            list.add(e);
+    }
+    jj_consume_token(RPAREN);
+        {if (true) return new SqlNodeList(list, s.end(this));}
+    throw new Error("Missing return statement in function");
+  }
+
+/** As ParenthesizedQueryOrCommaList, but allows DEFAULT
+ * in place of any of the expressions. For example,
+ * {@code (x, DEFAULT, null, DEFAULT)}. */
+  final public SqlNodeList ParenthesizedQueryOrCommaListWithDefault(ExprContext exprContext) throws ParseException {
+    SqlNode e;
+    List<SqlNode> list;
+    ExprContext firstExprContext = exprContext;
+    final Span s;
+    jj_consume_token(LPAREN);
+        // we've now seen left paren, so a query by itself should
+        // be interpreted as a sub-query
+        s = span();
+        switch (exprContext) {
+        case ACCEPT_SUB_QUERY:
+            firstExprContext = ExprContext.ACCEPT_NONCURSOR;
+            break;
+        case ACCEPT_CURSOR:
+            firstExprContext = ExprContext.ACCEPT_ALL;
+            break;
+        }
+    if (jj_2_19(2)) {
+      e = OrderedQueryOrExpr(firstExprContext);
+    } else if (jj_2_20(2)) {
+      e = Default();
+    } else {
+      jj_consume_token(-1);
+      throw new ParseException();
+    }
+        list = startList(e);
+    label_2:
+    while (true) {
+      if (jj_2_21(2)) {
+        ;
+      } else {
+        break label_2;
+      }
+      jj_consume_token(COMMA);
+            // a comma-list can't appear where only a query is expected
+            checkNonQueryExpression(exprContext);
+      if (jj_2_22(2)) {
+        e = Expression(exprContext);
+      } else if (jj_2_23(2)) {
+        e = Default();
+      } else {
+        jj_consume_token(-1);
+        throw new ParseException();
+      }
+            list.add(e);
+    }
+    jj_consume_token(RPAREN);
+        {if (true) return new SqlNodeList(list, s.end(this));}
+    throw new Error("Missing return statement in function");
+  }
+
+/**
+ * Parses function parameter lists.
+ * If the list starts with DISTINCT or ALL, it is discarded.
+ */
+  final public List UnquantifiedFunctionParameterList(ExprContext exprContext) throws ParseException {
+    final List args;
+    args = FunctionParameterList(exprContext);
+        final SqlLiteral quantifier = (SqlLiteral) args.get(0);
+        args.remove(0); // remove DISTINCT or ALL, if present
+        {if (true) return args;}
+    throw new Error("Missing return statement in function");
+  }
+
+/**
+ * Parses function parameter lists including DISTINCT keyword recognition,
+ * DEFAULT, and named argument assignment.
+ */
+  final public List FunctionParameterList(ExprContext exprContext) throws ParseException {
+    final SqlLiteral qualifier;
+    final List list = new ArrayList();
+    jj_consume_token(LPAREN);
+    if (jj_2_24(2)) {
+      qualifier = AllOrDistinct();
+                                      list.add(qualifier);
+    } else {
+          list.add(null);
+    }
+    Arg0(list, exprContext);
+    label_3:
+    while (true) {
+      if (jj_2_25(2)) {
+        ;
+      } else {
+        break label_3;
+      }
+      jj_consume_token(COMMA);
+            // a comma-list can't appear where only a query is expected
+            checkNonQueryExpression(exprContext);
+      Arg(list, exprContext);
+    }
+    jj_consume_token(RPAREN);
+        {if (true) return list;}
+    throw new Error("Missing return statement in function");
+  }
+
+  final public SqlLiteral AllOrDistinct() throws ParseException {
+    if (jj_2_26(2)) {
+      jj_consume_token(DISTINCT);
+                 {if (true) return SqlSelectKeyword.DISTINCT.symbol(getPos());}
+    } else if (jj_2_27(2)) {
+      jj_consume_token(ALL);
+            {if (true) return SqlSelectKeyword.ALL.symbol(getPos());}
+    } else {
+      jj_consume_token(-1);
+      throw new ParseException();
+    }
+    throw new Error("Missing return statement in function");
+  }
+
+  final public void Arg0(List list, ExprContext exprContext) throws ParseException {
+    SqlIdentifier name = null;
+    SqlNode e = null;
+    final ExprContext firstExprContext;
+    {
+        // we've now seen left paren, so queries inside should
+        // be allowed as sub-queries
+        switch (exprContext) {
+        case ACCEPT_SUB_QUERY:
+            firstExprContext = ExprContext.ACCEPT_NONCURSOR;
+            break;
+        case ACCEPT_CURSOR:
+            firstExprContext = ExprContext.ACCEPT_ALL;
+            break;
+        default:
+            firstExprContext = exprContext;
+            break;
+        }
+    }
+    if (jj_2_28(2)) {
+      name = SimpleIdentifier();
+      jj_consume_token(NAMED_ARGUMENT_ASSIGNMENT);
+    } else {
+      ;
+    }
+    if (jj_2_29(2)) {
+      e = Default();
+    } else if (jj_2_30(2)) {
+      e = OrderedQueryOrExpr(firstExprContext);
+    } else {
+      jj_consume_token(-1);
+      throw new ParseException();
+    }
+        if (e != null) {
+            if (name != null) {
+                e = SqlStdOperatorTable.ARGUMENT_ASSIGNMENT.createCall(
+                    Span.of(name, e).pos(), e, name);
+            }
+            list.add(e);
+        }
+  }
+
+  final public void Arg(List list, ExprContext exprContext) throws ParseException {
+    SqlIdentifier name = null;
+    SqlNode e = null;
+    if (jj_2_31(2)) {
+      name = SimpleIdentifier();
+      jj_consume_token(NAMED_ARGUMENT_ASSIGNMENT);
+    } else {
+      ;
+    }
+    if (jj_2_32(2)) {
+      e = Default();
+    } else if (jj_2_33(2)) {
+      e = Expression(exprContext);
+    } else {
+      jj_consume_token(-1);
+      throw new ParseException();
+    }
+        if (e != null) {
+            if (name != null) {
+                e = SqlStdOperatorTable.ARGUMENT_ASSIGNMENT.createCall(
+                    Span.of(name, e).pos(), e, name);
+            }
+            list.add(e);
+        }
+  }
+
+  final public SqlNode Default() throws ParseException {
+    jj_consume_token(DEFAULT_);
+        {if (true) return SqlStdOperatorTable.DEFAULT.createCall(getPos());}
+    throw new Error("Missing return statement in function");
+  }
+
+/**
+ * Parses a query (SELECT, UNION, INTERSECT, EXCEPT, VALUES, TABLE) followed by
+ * the end-of-file symbol.
+ */
+  final public SqlNode SqlQueryEof() throws ParseException {
+    SqlNode query;
+    query = OrderedQueryOrExpr(ExprContext.ACCEPT_QUERY);
+    jj_consume_token(0);
+      {if (true) return query;}
+    throw new Error("Missing return statement in function");
+  }
+
+/**
+ * Parses a list of SQL statements separated by semicolon.
+ * The semicolon is required between statements, but is
+ * optional at the end.
+ */
+  final public SqlNodeList SqlStmtList() throws ParseException {
+    final List<SqlNode> stmtList = new ArrayList<SqlNode>();
+    SqlNode stmt;
+    stmt = SqlStmt();
+        stmtList.add(stmt);
+    label_4:
+    while (true) {
+      if (jj_2_34(2)) {
+        ;
+      } else {
+        break label_4;
+      }
+      jj_consume_token(SEMICOLON);
+      if (jj_2_35(2)) {
+        stmt = SqlStmt();
+                stmtList.add(stmt);
+      } else {
+        ;
+      }
+    }
+    jj_consume_token(0);
+        {if (true) return new SqlNodeList(stmtList, Span.of(stmtList).pos());}
+    throw new Error("Missing return statement in function");
+  }
+
+/**
+ * Parses an SQL statement.
+ */
+  final public SqlNode SqlStmt() throws ParseException {
+    SqlNode stmt;
+    if (jj_2_36(2)) {
+      stmt = SqlAlterTable();
+    } else if (jj_2_37(2)) {
+      stmt = SqlAlterUser();
+    } else if (jj_2_38(2)) {
+      stmt = SqlKillScanQuery();
+    } else if (jj_2_39(2)) {
+      stmt = SqlKillContinuousQuery();
+    } else if (jj_2_40(2)) {
+      stmt = SqlKillService();
+    } else if (jj_2_41(2)) {
+      stmt = SqlKillTransaction();
+    } else if (jj_2_42(2)) {
+      stmt = SqlKillComputeTask();
+    } else if (jj_2_43(2)) {
+      stmt = SqlKillQuery();
+    } else if (jj_2_44(2)) {
+      stmt = SqlCommitTransaction();
+    } else if (jj_2_45(2)) {
+      stmt = SqlRollbackTransaction();
+    } else if (jj_2_46(2)) {
+      stmt = SqlSetOption(Span.of(), null);
+    } else if (jj_2_47(2)) {
+      stmt = SqlAlter();
+    } else if (jj_2_48(2)) {
+      stmt = SqlCreate();
+    } else if (jj_2_49(2)) {
+      stmt = SqlDrop();
+    } else if (jj_2_50(2)) {
+      stmt = OrderedQueryOrExpr(ExprContext.ACCEPT_QUERY);
+    } else if (jj_2_51(2)) {
+      stmt = SqlExplain();
+    } else if (jj_2_52(2)) {
+      stmt = SqlDescribe();
+    } else if (jj_2_53(2)) {
+      stmt = SqlInsert();
+    } else if (jj_2_54(2)) {
+      stmt = SqlDelete();
+    } else if (jj_2_55(2)) {
+      stmt = SqlUpdate();
+    } else if (jj_2_56(2)) {
+      stmt = SqlMerge();
+    } else if (jj_2_57(2)) {
+      stmt = SqlProcedureCall();
+    } else {
+      jj_consume_token(-1);
+      throw new ParseException();
+    }
+        {if (true) return stmt;}
+    throw new Error("Missing return statement in function");
+  }
+
+/**
+ * Parses an SQL statement followed by the end-of-file symbol.
+ */
+  final public SqlNode SqlStmtEof() throws ParseException {
+    SqlNode stmt;
+    stmt = SqlStmt();
+    jj_consume_token(0);
+        {if (true) return stmt;}
+    throw new Error("Missing return statement in function");
+  }
+
+  final public boolean IfNotExistsOpt() throws ParseException {
+    if (jj_2_58(2)) {
+      jj_consume_token(IF);
+      jj_consume_token(NOT);
+      jj_consume_token(EXISTS);
+                          {if (true) return true;}
+    } else {
+      {if (true) return false;}
+    }
+    throw new Error("Missing return statement in function");
+  }
+
+  final public SqlNodeList WithCreateTableOptionList() throws ParseException {
+    List<SqlNode> list = new ArrayList<SqlNode>();
+    final Span s;
+    if (jj_2_60(2)) {
+      jj_consume_token(WITH);
+                 s = span();
+      CreateTableOption(list);
+      label_5:
+      while (true) {
+        if (jj_2_59(2)) {
+          ;
+        } else {
+          break label_5;
+        }
+        jj_consume_token(COMMA);
+                      s.add(this);
+        CreateTableOption(list);
+      }
+            {if (true) return new SqlNodeList(list, s.end(this));}
+    } else {
+      ;
+    }
+      {if (true) return null;}
+    throw new Error("Missing return statement in function");
+  }
+
+  final public SqlLiteral CreateTableOptionKey() throws ParseException {
+    if (jj_2_61(2)) {
+      jj_consume_token(TEMPLATE);
+                 {if (true) return SqlLiteral.createSymbol(IgniteSqlCreateTableOptionEnum.TEMPLATE, getPos());}
+    } else if (jj_2_62(2)) {
+      jj_consume_token(BACKUPS);
+                {if (true) return SqlLiteral.createSymbol(IgniteSqlCreateTableOptionEnum.BACKUPS, getPos());}
+    } else if (jj_2_63(2)) {
+      jj_consume_token(AFFINITY_KEY);
+                     {if (true) return SqlLiteral.createSymbol(IgniteSqlCreateTableOptionEnum.AFFINITY_KEY, getPos());}
+    } else if (jj_2_64(2)) {
+      jj_consume_token(ATOMICITY);
+                  {if (true) return SqlLiteral.createSymbol(IgniteSqlCreateTableOptionEnum.ATOMICITY, getPos());}
+    } else if (jj_2_65(2)) {
+      jj_consume_token(WRITE_SYNCHRONIZATION_MODE);
+                                   {if (true) return SqlLiteral.createSymbol(IgniteSqlCreateTableOptionEnum.WRITE_SYNCHRONIZATION_MODE, getPos());}
+    } else if (jj_2_66(2)) {
+      jj_consume_token(CACHE_GROUP);
+                    {if (true) return SqlLiteral.createSymbol(IgniteSqlCreateTableOptionEnum.CACHE_GROUP, getPos());}
+    } else if (jj_2_67(2)) {
+      jj_consume_token(CACHE_NAME);
+                   {if (true) return SqlLiteral.createSymbol(IgniteSqlCreateTableOptionEnum.CACHE_NAME, getPos());}
+    } else if (jj_2_68(2)) {
+      jj_consume_token(DATA_REGION);
+                    {if (true) return SqlLiteral.createSymbol(IgniteSqlCreateTableOptionEnum.DATA_REGION, getPos());}
+    } else if (jj_2_69(2)) {
+      jj_consume_token(KEY_TYPE);
+                 {if (true) return SqlLiteral.createSymbol(IgniteSqlCreateTableOptionEnum.KEY_TYPE, getPos());}
+    } else if (jj_2_70(2)) {
+      jj_consume_token(VALUE_TYPE);
+                   {if (true) return SqlLiteral.createSymbol(IgniteSqlCreateTableOptionEnum.VALUE_TYPE, getPos());}
+    } else if (jj_2_71(2)) {
+      jj_consume_token(ENCRYPTED);
+                  {if (true) return SqlLiteral.createSymbol(IgniteSqlCreateTableOptionEnum.ENCRYPTED, getPos());}
+    } else {
+      jj_consume_token(-1);
+      throw new ParseException();
+    }
+    throw new Error("Missing return statement in function");
+  }
+
+  final public void CreateTableOption(List<SqlNode> list) throws ParseException {
+    final Span s;
+    final SqlLiteral key;
+    final SqlNode val;
+    key = CreateTableOptionKey();
+                                   s = span();
+    jj_consume_token(EQ);
+    if (jj_2_72(2)) {
+      val = Literal();
+    } else if (jj_2_73(2)) {
+      val = SimpleIdentifier();
+    } else {
+      jj_consume_token(-1);
+      throw new ParseException();
+    }
+        list.add(new IgniteSqlCreateTableOption(key, val, s.end(this)));
+  }
+
+  final public SqlDataTypeSpec DataTypeEx() throws ParseException {
+    final SqlDataTypeSpec dt;
+    if (jj_2_74(2)) {
+      dt = DataType();
+    } else if (jj_2_75(2)) {
+      dt = IntervalType();
+    } else if (jj_2_76(2)) {
+      dt = UuidType();
+    } else {
+      jj_consume_token(-1);
+      throw new ParseException();
+    }
+        {if (true) return dt;}
+    throw new Error("Missing return statement in function");
+  }
+
+  final public SqlDataTypeSpec IntervalType() throws ParseException {
+    final Span s;
+    final SqlIntervalQualifier intervalQualifier;
+    jj_consume_token(INTERVAL);
+                 s = span();
+    intervalQualifier = IntervalQualifier();
+        {if (true) return new SqlDataTypeSpec(new IgniteSqlIntervalTypeNameSpec(intervalQualifier, s.end(this)), s.pos());}
+    throw new Error("Missing return statement in function");
+  }
+
+  final public SqlDataTypeSpec UuidType() throws ParseException {
+        final Span s;
+    jj_consume_token(UUID);
+             s = span();
+        {if (true) return new SqlDataTypeSpec(new SqlUserDefinedTypeNameSpec("UUID", s.end(this)), s.pos());}
+    throw new Error("Missing return statement in function");
+  }
+
+  final public void TableElement(List<SqlNode> list) throws ParseException {
+    final SqlDataTypeSpec type;
+    final boolean nullable;
+    final SqlNodeList columnList;
+    final Span s = Span.of();
+    final ColumnStrategy strategy;
+    final SqlNode dflt;
+    SqlIdentifier id = null;
+    if (jj_2_80(2)) {
+      id = SimpleIdentifier();
+      type = DataTypeEx();
+      nullable = NullableOptDefaultTrue();
+      if (jj_2_77(2)) {
+        jj_consume_token(DEFAULT_);
+                     s.add(this);
+        dflt = Literal();
+            strategy = ColumnStrategy.DEFAULT;
+      } else {
+            dflt = null;
+            strategy = nullable ? ColumnStrategy.NULLABLE
+                : ColumnStrategy.NOT_NULLABLE;
+      }
+      if (jj_2_78(2)) {
+        jj_consume_token(PRIMARY);
+                    s.add(this);
+        jj_consume_token(KEY);
+            columnList = SqlNodeList.of(id);
+            list.add(SqlDdlNodes.primary(s.end(columnList), null, columnList));
+      } else {
+        ;
+      }
+        list.add(
+            SqlDdlNodes.column(s.add(id).end(this), id,
+                type.withNullable(nullable), dflt, strategy));
+    } else if (jj_2_81(2)) {
+      if (jj_2_79(2)) {
+        jj_consume_token(CONSTRAINT);
+                     s.add(this);
+        id = SimpleIdentifier();
+      } else {
+        ;
+      }
+      jj_consume_token(PRIMARY);
+                s.add(this);
+      jj_consume_token(KEY);
+      columnList = ParenthesizedSimpleIdentifierList();
+        list.add(SqlDdlNodes.primary(s.end(columnList), id, columnList));
+    } else {
+      jj_consume_token(-1);
+      throw new ParseException();
+    }
+  }
+
+  final public SqlNodeList TableElementList() throws ParseException {
+    final Span s;
+    final List<SqlNode> list = new ArrayList<SqlNode>();
+    jj_consume_token(LPAREN);
+               s = span();
+    TableElement(list);
+    label_6:
+    while (true) {
+      if (jj_2_82(2)) {
+        ;
+      } else {
+        break label_6;
+      }
+      jj_consume_token(COMMA);
+      TableElement(list);
+    }
+    jj_consume_token(RPAREN);
+        {if (true) return new SqlNodeList(list, s.end(this));}
+    throw new Error("Missing return statement in function");
+  }
+
+  final public SqlCreate SqlCreateTable(Span s, boolean replace) throws ParseException {
+    final boolean ifNotExists;
+    final SqlIdentifier id;
+    final SqlNodeList columnList;
+    final SqlNodeList optionList;
+    final SqlNode query;
+    jj_consume_token(TABLE);
+    ifNotExists = IfNotExistsOpt();
+    id = CompoundIdentifier();
+    if (jj_2_84(3)) {
+      columnList = TableElementList();
+      optionList = WithCreateTableOptionList();
+          query = null;
+    } else if (jj_2_85(2)) {
+      if (jj_2_83(2)) {
+        columnList = ParenthesizedSimpleIdentifierList();
+      } else {
+              columnList = null;
+      }
+      optionList = WithCreateTableOptionList();
+      jj_consume_token(AS);
+               s.add(this);
+      query = OrderedQueryOrExpr(ExprContext.ACCEPT_QUERY);
+    } else {
+      jj_consume_token(-1);
+      throw new ParseException();
+    }
+        {if (true) return new IgniteSqlCreateTable(s.end(this), ifNotExists, id, columnList, query, optionList);}
+    throw new Error("Missing return statement in function");
+  }
+
+  final public SqlNode IndexedColumn() throws ParseException {
+    final Span s;
+    SqlNode col;
+    col = SimpleIdentifier();
+    if (jj_2_88(2)) {
+      if (jj_2_86(2)) {
+        jj_consume_token(ASC);
+      } else if (jj_2_87(2)) {
+        jj_consume_token(DESC);
+            col = SqlStdOperatorTable.DESC.createCall(getPos(), col);
+      } else {
+        jj_consume_token(-1);
+        throw new ParseException();
+      }
+    } else {
+      ;
+    }
+        {if (true) return col;}
+    throw new Error("Missing return statement in function");
+  }
+
+  final public SqlNodeList IndexedColumnList() throws ParseException {
+    final Span s;
+    final List<SqlNode> list = new ArrayList<SqlNode>();
+    SqlNode col = null;
+    jj_consume_token(LPAREN);
+               s = span();
+    col = IndexedColumn();
+                            list.add(col);
+    label_7:
+    while (true) {
+      if (jj_2_89(2)) {
+        ;
+      } else {
+        break label_7;
+      }
+      jj_consume_token(COMMA);
+      col = IndexedColumn();
+                                        list.add(col);
+    }
+    jj_consume_token(RPAREN);
+        {if (true) return new SqlNodeList(list, s.end(this));}
+    throw new Error("Missing return statement in function");
+  }
+
+  final public SqlCreate SqlCreateIndex(Span s, boolean replace) throws ParseException {
+    final boolean ifNotExists;
+    final SqlIdentifier idxId;
+    final SqlIdentifier tblId;
+    final SqlNodeList columnList;
+    SqlNumericLiteral parallel = null;
+    SqlNumericLiteral inlineSize = null;
+    jj_consume_token(INDEX);
+    ifNotExists = IfNotExistsOpt();
+    idxId = SimpleIdentifier();
+    jj_consume_token(ON);
+    tblId = CompoundIdentifier();
+    columnList = IndexedColumnList();
+    label_8:
+    while (true) {
+      if (jj_2_90(2)) {
+        ;
+      } else {
+        break label_8;
+      }
+      if (jj_2_91(2)) {
+        jj_consume_token(PARALLEL);
+        jj_consume_token(UNSIGNED_INTEGER_LITERAL);
+            if (parallel != null)
+                {if (true) throw SqlUtil.newContextException(getPos(), IgniteResource.INSTANCE.optionAlreadyDefined("PARALLEL"));}
+
+            parallel = SqlLiteral.createExactNumeric(token.image, getPos());
+      } else if (jj_2_92(2)) {
+        jj_consume_token(INLINE_SIZE);
+        jj_consume_token(UNSIGNED_INTEGER_LITERAL);
+            if (inlineSize != null)
+                {if (true) throw SqlUtil.newContextException(getPos(), IgniteResource.INSTANCE.optionAlreadyDefined("INLINE_SIZE"));}
+
+            inlineSize = SqlLiteral.createExactNumeric(token.image, getPos());
+      } else {
+        jj_consume_token(-1);
+        throw new ParseException();
+      }
+    }
+        {if (true) return new IgniteSqlCreateIndex(s.end(this), ifNotExists, idxId, tblId, columnList, parallel, inlineSize);}
+    throw new Error("Missing return statement in function");
+  }
+
+  final public boolean IfExistsOpt() throws ParseException {
+    if (jj_2_93(2)) {
+      jj_consume_token(IF);
+      jj_consume_token(EXISTS);
+                    {if (true) return true;}
+    } else {
+      {if (true) return false;}
+    }
+    throw new Error("Missing return statement in function");
+  }
+
+  final public SqlDrop SqlDropTable(Span s, boolean replace) throws ParseException {
+    final boolean ifExists;
+    final SqlIdentifier id;
+    jj_consume_token(TABLE);
+    ifExists = IfExistsOpt();
+    id = CompoundIdentifier();
+        {if (true) return SqlDdlNodes.dropTable(s.end(this), ifExists, id);}
+    throw new Error("Missing return statement in function");
+  }
+
+  final public SqlDrop SqlDropIndex(Span s, boolean replace) throws ParseException {
+    final boolean ifExists;
+    final SqlIdentifier id;
+    jj_consume_token(INDEX);
+    ifExists = IfExistsOpt();
+    id = CompoundIdentifier();
+        {if (true) return new IgniteSqlDropIndex(s.end(this), ifExists, id);}
+    throw new Error("Missing return statement in function");
+  }
+
+  final public void InfixCast(List<Object> list, ExprContext exprContext, Span s) throws ParseException {
+    final SqlDataTypeSpec dt;
+    jj_consume_token(INFIX_CAST);
+        checkNonQueryExpression(exprContext);
+    dt = DataTypeEx();
+        list.add(
+            new SqlParserUtil.ToTreeListItem(SqlLibraryOperators.INFIX_CAST,
+                s.pos()));
+        list.add(dt);
+  }
+
+  final public SqlNodeList ColumnWithTypeList() throws ParseException {
+    final Span s;
+    List<SqlNode> list = new ArrayList<SqlNode>();
+    SqlNode col;
+    jj_consume_token(LPAREN);
+               s = span();
+    col = ColumnWithType();
+                             list.add(col);
+    label_9:
+    while (true) {
+      if (jj_2_94(2)) {
+        ;
+      } else {
+        break label_9;
+      }
+      jj_consume_token(COMMA);
+      col = ColumnWithType();
+                                         list.add(col);
+    }
+    jj_consume_token(RPAREN);
+        {if (true) return new SqlNodeList(list, s.end(this));}
+    throw new Error("Missing return statement in function");
+  }
+
+  final public SqlNode ColumnWithType() throws ParseException {
+    SqlIdentifier id;
+    SqlDataTypeSpec type;
+    boolean nullable = true;
+    final Span s = Span.of();
+    id = SimpleIdentifier();
+    type = DataTypeEx();
+    if (jj_2_95(2)) {
+      jj_consume_token(NOT);
+      jj_consume_token(NULL);
+            nullable = false;
+    } else {
+      ;
+    }
+        {if (true) return SqlDdlNodes.column(s.add(id).end(this), id, type.withNullable(nullable), null, null);}
+    throw new Error("Missing return statement in function");
+  }
+
+  final public SqlNodeList ColumnWithTypeOrList() throws ParseException {
+    SqlNode col;
+    SqlNodeList list;
+    if (jj_2_96(2)) {
+      col = ColumnWithType();
+                             {if (true) return new SqlNodeList(Collections.singletonList(col), col.getParserPosition());}
+    } else if (jj_2_97(2)) {
+      list = ColumnWithTypeList();
+                                  {if (true) return list;}
+    } else {
+      jj_consume_token(-1);
+      throw new ParseException();
+    }
+    throw new Error("Missing return statement in function");
+  }
+
+  final public SqlNode SqlAlterTable() throws ParseException {
+    final Span s;
+    final boolean ifExists;
+    final SqlIdentifier id;
+    boolean colIgnoreErr;
+    SqlNode col;
+    SqlNodeList cols;
+    jj_consume_token(ALTER);
+              s = span();
+    jj_consume_token(TABLE);
+    ifExists = IfExistsOpt();
+    id = CompoundIdentifier();
+    if (jj_2_100(2)) {
+      jj_consume_token(LOGGING);
+                    {if (true) return new IgniteSqlAlterTable(s.end(this), ifExists, id, true);}
+    } else if (jj_2_101(2)) {
+      jj_consume_token(NOLOGGING);
+                       {if (true) return new IgniteSqlAlterTable(s.end(this), ifExists, id, false);}
+    } else if (jj_2_102(2)) {
+      jj_consume_token(ADD);
+      if (jj_2_98(2)) {
+        jj_consume_token(COLUMN);
+      } else {
+        ;
+      }
+      colIgnoreErr = IfNotExistsOpt();
+      cols = ColumnWithTypeOrList();
+            {if (true) return new IgniteSqlAlterTableAddColumn(s.end(this), ifExists, id, colIgnoreErr, cols);}
+    } else if (jj_2_103(2)) {
+      jj_consume_token(DROP);
+      if (jj_2_99(2)) {
+        jj_consume_token(COLUMN);
+      } else {
+        ;
+      }
+      colIgnoreErr = IfExistsOpt();
+      cols = SimpleIdentifierOrList();
+            {if (true) return new IgniteSqlAlterTableDropColumn(s.end(this), ifExists, id, colIgnoreErr, cols);}
+    } else {
+      jj_consume_token(-1);
+      throw new ParseException();
+    }
+    throw new Error("Missing return statement in function");
+  }
+
+  final public SqlCreate SqlCreateUser(Span s, boolean replace) throws ParseException {
+    final SqlIdentifier user;
+    final SqlNode password;
+    jj_consume_token(USER);
+    user = SimpleIdentifier();
+    jj_consume_token(WITH);
+    jj_consume_token(PASSWORD);
+    password = StringLiteral();
+        {if (true) return new IgniteSqlCreateUser(s.end(this), user, SqlLiteral.unchain(password));}
+    throw new Error("Missing return statement in function");
+  }
+
+  final public SqlNode SqlAlterUser() throws ParseException {
+    final Span s;
+    final SqlIdentifier user;
+    final SqlNode password;
+    jj_consume_token(ALTER);
+              s = span();
+    jj_consume_token(USER);
+    user = SimpleIdentifier();
+    jj_consume_token(WITH);
+    jj_consume_token(PASSWORD);
+    password = StringLiteral();
+        {if (true) return new IgniteSqlAlterUser(s.end(this), user, SqlLiteral.unchain(password));}
+    throw new Error("Missing return statement in function");
+  }
+
+  final public SqlDrop SqlDropUser(Span s, boolean replace) throws ParseException {
+    final SqlIdentifier user;
+    jj_consume_token(USER);
+    user = SimpleIdentifier();
+        {if (true) return new IgniteSqlDropUser(s.end(this), user);}
+    throw new Error("Missing return statement in function");
+  }
+
+  final public SqlNumericLiteral SignedIntegerLiteral() throws ParseException {
+    final Span s;
+    if (jj_2_104(2)) {
+      jj_consume_token(PLUS);
+      jj_consume_token(UNSIGNED_INTEGER_LITERAL);
+        {if (true) return SqlLiteral.createExactNumeric(token.image, getPos());}
+    } else if (jj_2_105(2)) {
+      jj_consume_token(MINUS);
+              s = span();
+      jj_consume_token(UNSIGNED_INTEGER_LITERAL);
+        {if (true) return SqlLiteral.createNegative(SqlLiteral.createExactNumeric(token.image, getPos()), s.end(this));}
+    } else if (jj_2_106(2)) {
+      jj_consume_token(UNSIGNED_INTEGER_LITERAL);
+        {if (true) return SqlLiteral.createExactNumeric(token.image, getPos());}
+    } else {
+      jj_consume_token(-1);
+      throw new ParseException();
+    }
+    throw new Error("Missing return statement in function");
+  }
+
+  final public SqlCharStringLiteral UuidLiteral() throws ParseException {
+    final Span s;
+    final String rawUuuid;
+    jj_consume_token(QUOTED_STRING);
+        String rawUuid = SqlParserUtil.parseString(token.image);
+        try {
+            java.util.UUID.fromString(rawUuid);
+            {if (true) return SqlLiteral.createCharString(rawUuid, getPos());}
+        }
+        catch (Exception e) {
+            {if (true) throw SqlUtil.newContextException(getPos(), IgniteResource.INSTANCE.illegalUuid(rawUuid));}
+        }
+    throw new Error("Missing return statement in function");
+  }
+
+  final public SqlCharStringLiteral IgniteUuidLiteral() throws ParseException {
+    final Span s;
+    final String rawUuuid;
+    jj_consume_token(QUOTED_STRING);
+        String rawUuid = SqlParserUtil.parseString(token.image);
+        try {
+            IgniteUuid.fromString(rawUuid);
+            {if (true) return SqlLiteral.createCharString(rawUuid, getPos());}
+        }
+        catch (Exception e) {
+            {if (true) throw SqlUtil.newContextException(getPos(), IgniteResource.INSTANCE.illegalIgniteUuid(rawUuid));}
+        }
+    throw new Error("Missing return statement in function");
+  }
+
+  final public SqlNode SqlKillScanQuery() throws ParseException {
+    final Span s;
+    final SqlCharStringLiteral originNodeId;
+    final SqlCharStringLiteral cacheName;
+    final SqlNumericLiteral queryId;
+    jj_consume_token(KILL);
+             s = span();
+    jj_consume_token(SCAN);
+    originNodeId = UuidLiteral();
+    jj_consume_token(QUOTED_STRING);
+        cacheName = SqlLiteral.createCharString(SqlParserUtil.parseString(token.image), getPos());
+    queryId = SignedIntegerLiteral();
+        {if (true) return IgniteSqlKill.createScanQueryKill(s.end(this), originNodeId, cacheName, queryId);}
+    throw new Error("Missing return statement in function");
+  }
+
+  final public SqlNode SqlKillContinuousQuery() throws ParseException {
+    final Span s;
+    final SqlCharStringLiteral originNodeId;
+    final SqlCharStringLiteral routineId;
+    jj_consume_token(KILL);
+             s = span();
+    jj_consume_token(CONTINUOUS);
+    originNodeId = UuidLiteral();
+    routineId = UuidLiteral();
+        {if (true) return IgniteSqlKill.createContinuousQueryKill(s.end(this), originNodeId, routineId);}
+    throw new Error("Missing return statement in function");
+  }
+
+  final public SqlNode SqlKillTransaction() throws ParseException {
+    final Span s;
+    final SqlCharStringLiteral xid;
+    jj_consume_token(KILL);
+             s = span();
+    jj_consume_token(TRANSACTION);
+    xid = IgniteUuidLiteral();
+        {if (true) return IgniteSqlKill.createTransactionKill(s.end(this), xid);}
+    throw new Error("Missing return statement in function");
+  }
+
+  final public SqlNode SqlKillService() throws ParseException {
+    final Span s;
+    final SqlCharStringLiteral srvName;
+    jj_consume_token(KILL);
+             s = span();
+    jj_consume_token(SERVICE);
+    jj_consume_token(QUOTED_STRING);
+        srvName = SqlLiteral.createCharString(SqlParserUtil.parseString(token.image), getPos());
+        {if (true) return IgniteSqlKill.createServiceKill(s.end(this), srvName);}
+    throw new Error("Missing return statement in function");
+  }
+
+  final public SqlNode SqlKillComputeTask() throws ParseException {
+    final Span s;
+    final SqlCharStringLiteral sesId;
+    jj_consume_token(KILL);
+             s = span();
+    jj_consume_token(COMPUTE);
+    sesId = IgniteUuidLiteral();
+        {if (true) return IgniteSqlKill.createComputeTaskKill(s.end(this), sesId);}
+    throw new Error("Missing return statement in function");
+  }
+
+  final public boolean IsAsyncOpt() throws ParseException {
+    if (jj_2_107(2)) {
+      jj_consume_token(ASYNC);
+              {if (true) return true;}
+    } else {
+                                 {if (true) return false;}
+    }
+    throw new Error("Missing return statement in function");
+  }
+
+  final public SqlNode SqlKillQuery() throws ParseException {
+    final Span s;
+    final boolean isAsync;
+    jj_consume_token(KILL);
+             s = span();
+    jj_consume_token(QUERY);
+    isAsync = IsAsyncOpt();
+    jj_consume_token(QUOTED_STRING);
+        String rawQueryId = SqlParserUtil.parseString(token.image);
+        SqlCharStringLiteral queryIdLiteral = SqlLiteral.createCharString(rawQueryId, getPos());
+        Pair<UUID, Long> id = IgniteSqlKill.parseGlobalQueryId(rawQueryId);
+        if (id == null) {
+            {if (true) throw SqlUtil.newContextException(getPos(), IgniteResource.INSTANCE.illegalGlobalQueryId(rawQueryId));}
+        }
+        {if (true) return IgniteSqlKill.createQueryKill(s.end(this), queryIdLiteral, id.getKey(), id.getValue(), isAsync);}
+    throw new Error("Missing return statement in function");
+  }
+
+  final public SqlNode SqlCommitTransaction() throws ParseException {
+    final Span s;
+    jj_consume_token(COMMIT);
+               s = span();
+    if (jj_2_108(2)) {
+      jj_consume_token(TRANSACTION);
+    } else {
+      ;
+    }
+        {if (true) return new IgniteSqlCommit(s.end(this));}
+    throw new Error("Missing return statement in function");
+  }
+
+  final public SqlNode SqlRollbackTransaction() throws ParseException {
+    final Span s;
+    jj_consume_token(ROLLBACK);
+                 s = span();
+    if (jj_2_109(2)) {
+      jj_consume_token(TRANSACTION);
+    } else {
+      ;
+    }
+        {if (true) return new IgniteSqlRollback(s.end(this));}
+    throw new Error("Missing return statement in function");
+  }
+
+  final public SqlNodeList ParenthesizedKeyValueOptionCommaList() throws ParseException {
+    final Span s;
+    final List<SqlNode> list = new ArrayList<SqlNode>();
+      s = span();
+    jj_consume_token(LPAREN);
+    KeyValueOption(list);
+    label_10:
+    while (true) {
+      if (jj_2_110(2)) {
+        ;
+      } else {
+        break label_10;
+      }
+      jj_consume_token(COMMA);
+      KeyValueOption(list);
+    }
+    jj_consume_token(RPAREN);
+        {if (true) return new SqlNodeList(list, s.end(this));}
+    throw new Error("Missing return statement in function");
+  }
+
+/**
+* Parses an option with format key=val whose key is a simple identifier or string literal
+* and value is a string literal.
+*/
+  final public void KeyValueOption(List<SqlNode> list) throws ParseException {
+    final SqlNode key;
+    final SqlNode value;
+    if (jj_2_111(2)) {
+      key = SimpleIdentifier();
+    } else if (jj_2_112(2)) {
+      key = StringLiteral();
+    } else {
+      jj_consume_token(-1);
+      throw new ParseException();
+    }
+    jj_consume_token(EQ);
+    value = StringLiteral();
+        list.add(key);
+        list.add(value);
+  }
+
+/**
+* Parses an option value, it's either a string or a numeric.
+*/
+  final public SqlNode OptionValue() throws ParseException {
+    final SqlNode value;
+    if (jj_2_113(2)) {
+      value = NumericLiteral();
+    } else if (jj_2_114(2)) {
+      value = StringLiteral();
+    } else {
+      jj_consume_token(-1);
+      throw new ParseException();
+    }
+        {if (true) return value;}
+    throw new Error("Missing return statement in function");
+  }
+
+/**
+ * Parses a literal list separated by comma. The literal is either a string or a numeric.
+ */
+  final public SqlNodeList ParenthesizedLiteralOptionCommaList() throws ParseException {
+    final Span s;
+    final List<SqlNode> list = new ArrayList<SqlNode>();
+    SqlNode optionVal;
+      s = span();
+    jj_consume_token(LPAREN);
+    optionVal = OptionValue();
+        list.add(optionVal);
+    label_11:
+    while (true) {
+      if (jj_2_115(2)) {
+        ;
+      } else {
+        break label_11;
+      }
+      jj_consume_token(COMMA);
+      optionVal = OptionValue();
+            list.add(optionVal);
+    }
+    jj_consume_token(RPAREN);
+        {if (true) return new SqlNodeList(list, s.end(this));}
+    throw new Error("Missing return statement in function");
+  }
+
+  final public void CommaSeparatedSqlHints(List<SqlNode> hints) throws ParseException {
+    SqlIdentifier hintName;
+    SqlNodeList hintOptions;
+    SqlNode optionVal;
+    SqlHint.HintOptionFormat optionFormat;
+    hintName = SimpleIdentifier();
+    if (jj_2_117(5)) {
+      hintOptions = ParenthesizedKeyValueOptionCommaList();
+            optionFormat = SqlHint.HintOptionFormat.KV_LIST;
+    } else if (jj_2_118(3)) {
+      hintOptions = ParenthesizedSimpleIdentifierList();
+            optionFormat = SqlHint.HintOptionFormat.ID_LIST;
+    } else if (jj_2_119(3)) {
+      hintOptions = ParenthesizedLiteralOptionCommaList();
+            optionFormat = SqlHint.HintOptionFormat.LITERAL_LIST;
+    } else {
+      if (jj_2_116(2)) {
+        jj_consume_token(LPAREN);
+        jj_consume_token(RPAREN);
+      } else {
+        ;
+      }
+            hintOptions = SqlNodeList.EMPTY;
+            optionFormat = SqlHint.HintOptionFormat.EMPTY;
+    }
+        hints.add(new SqlHint(Span.of(hintOptions).end(this), hintName, hintOptions, optionFormat));
+    label_12:
+    while (true) {
+      if (jj_2_120(2)) {
+        ;
+      } else {
+        break label_12;
+      }
+      jj_consume_token(COMMA);
+      hintName = SimpleIdentifier();
+      if (jj_2_122(5)) {
+        hintOptions = ParenthesizedKeyValueOptionCommaList();
+                optionFormat = SqlHint.HintOptionFormat.KV_LIST;
+      } else if (jj_2_123(3)) {
+        hintOptions = ParenthesizedSimpleIdentifierList();
+                optionFormat = SqlHint.HintOptionFormat.ID_LIST;
+      } else if (jj_2_124(3)) {
+        hintOptions = ParenthesizedLiteralOptionCommaList();
+                optionFormat = SqlHint.HintOptionFormat.LITERAL_LIST;
+      } else {
+        if (jj_2_121(2)) {
+          jj_consume_token(LPAREN);
+          jj_consume_token(RPAREN);
+        } else {
+          ;
+        }
+                hintOptions = SqlNodeList.EMPTY;
+                optionFormat = SqlHint.HintOptionFormat.EMPTY;
+      }
+            hints.add(new SqlHint(Span.of(hintOptions).end(this), hintName, hintOptions, optionFormat));
+    }
+  }
+
+/**
+ * Parses a table reference with optional hints.
+ */
+  final public SqlNode TableRefWithHintsOpt() throws ParseException {
+    SqlNode tableRef;
+    SqlNodeList hintList;
+    final List<SqlNode> hints = new ArrayList<SqlNode>();
+    final Span s;
+      s = span();
+    tableRef = CompoundTableIdentifier();
+    if (jj_2_125(2)) {
+      jj_consume_token(HINT_BEG);
+      CommaSeparatedSqlHints(hints);
+      jj_consume_token(COMMENT_END);
+            hintList = new SqlNodeList(hints, s.addAll(hints).end(this));
+            tableRef = new SqlTableRef(Span.of(tableRef, hintList).pos(),
+                    (SqlIdentifier) tableRef, hintList);
+    } else {
+      ;
+    }
+        {if (true) return tableRef;}
+    throw new Error("Missing return statement in function");
+  }
+
+/**
+ * Parses a leaf SELECT expression without ORDER BY.
+ */
+  final public SqlSelect SqlSelect() throws ParseException {
+    final List<SqlLiteral> keywords = new ArrayList<SqlLiteral>();
+    final SqlLiteral keyword;
+    final SqlNodeList keywordList;
+    List<SqlNode> selectList;
+    final SqlNode fromClause;
+    final SqlNode where;
+    final SqlNodeList groupBy;
+    final SqlNode having;
+    final SqlNodeList windowDecls;
+    final List<SqlNode> hints = new ArrayList<SqlNode>();
+    final Span s;
+    jj_consume_token(SELECT);
+        s = span();
+    if (jj_2_126(2)) {
+      jj_consume_token(HINT_BEG);
+      CommaSeparatedSqlHints(hints);
+      jj_consume_token(COMMENT_END);
+    } else {
+      ;
+    }
+    SqlSelectKeywords(keywords);
+    if (jj_2_127(2)) {
+      jj_consume_token(STREAM);
+            keywords.add(SqlSelectKeyword.STREAM.symbol(getPos()));
+    } else {
+      ;
+    }
+    if (jj_2_128(2)) {
+      keyword = AllOrDistinct();
+                                    keywords.add(keyword);
+    } else {
+      ;
+    }
+        keywordList = new SqlNodeList(keywords, s.addAll(keywords).pos());
+    selectList = SelectList();
+    if (jj_2_129(2)) {
+      jj_consume_token(FROM);
+      fromClause = FromClause();
+      where = WhereOpt();
+      groupBy = GroupByOpt();
+      having = HavingOpt();
+      windowDecls = WindowOpt();
+    } else {
+      E();
+            fromClause = null;
+            where = null;
+            groupBy = null;
+            having = null;
+            windowDecls = null;
+    }
+        {if (true) return new SqlSelect(s.end(this), keywordList,
+            new SqlNodeList(selectList, Span.of(selectList).pos()),
+            fromClause, where, groupBy, having, windowDecls, null, null, null,
+            new SqlNodeList(hints, getPos()));}
+    throw new Error("Missing return statement in function");
+  }
+
+/*
+ * Abstract production:
+ *
+ *    void SqlSelectKeywords(List keywords)
+ *
+ * Parses dialect-specific keywords immediately following the SELECT keyword.
+ */
+
+/**
+ * Parses an EXPLAIN PLAN statement.
+ */
+  final public SqlNode SqlExplain() throws ParseException {
+    SqlNode stmt;
+    SqlExplainLevel detailLevel = SqlExplainLevel.EXPPLAN_ATTRIBUTES;
+    SqlExplain.Depth depth;
+    final SqlExplainFormat format;
+    jj_consume_token(EXPLAIN);
+    jj_consume_token(PLAN);
+    if (jj_2_130(2)) {
+      detailLevel = ExplainDetailLevel();
+    } else {
+      ;
+    }
+    depth = ExplainDepth();
+    if (jj_2_131(2)) {
+      jj_consume_token(AS);
+      jj_consume_token(XML);
+                     format = SqlExplainFormat.XML;
+    } else if (jj_2_132(2)) {
+      jj_consume_token(AS);
+      jj_consume_token(JSON);
+                      format = SqlExplainFormat.JSON;
+    } else if (jj_2_133(2)) {
+      jj_consume_token(AS);
+      jj_consume_token(DOT_FORMAT);
+                            format = SqlExplainFormat.DOT;
+    } else {
+          format = SqlExplainFormat.TEXT;
+    }
+    jj_consume_token(FOR);
+    stmt = SqlQueryOrDml();
+        {if (true) return new SqlExplain(getPos(),
+            stmt,
+            detailLevel.symbol(SqlParserPos.ZERO),
+            depth.symbol(SqlParserPos.ZERO),
+            format.symbol(SqlParserPos.ZERO),
+            nDynamicParams);}
+    throw new Error("Missing return statement in function");
+  }
+
+/** Parses a query (SELECT or VALUES)
+ * or DML statement (INSERT, UPDATE, DELETE, MERGE). */
+  final public SqlNode SqlQueryOrDml() throws ParseException {
+    SqlNode stmt;
+    if (jj_2_134(2)) {
+      stmt = OrderedQueryOrExpr(ExprContext.ACCEPT_QUERY);
+    } else if (jj_2_135(2)) {
+      stmt = SqlInsert();
+    } else if (jj_2_136(2)) {
+      stmt = SqlDelete();
+    } else if (jj_2_137(2)) {
+      stmt = SqlUpdate();
+    } else if (jj_2_138(2)) {
+      stmt = SqlMerge();
+    } else {
+      jj_consume_token(-1);
+      throw new ParseException();
+    }
+        {if (true) return stmt;}
+    throw new Error("Missing return statement in function");
+  }
+
+/**
+ * Parses WITH TYPE | WITH IMPLEMENTATION | WITHOUT IMPLEMENTATION modifier for
+ * EXPLAIN PLAN.
+ */
+  final public SqlExplain.Depth ExplainDepth() throws ParseException {
+    if (jj_2_139(2)) {
+      jj_consume_token(WITH);
+      jj_consume_token(TYPE);
+            {if (true) return SqlExplain.Depth.TYPE;}
+    } else if (jj_2_140(2)) {
+      jj_consume_token(WITH);
+      jj_consume_token(IMPLEMENTATION);
+            {if (true) return SqlExplain.Depth.PHYSICAL;}
+    } else if (jj_2_141(2)) {
+      jj_consume_token(WITHOUT);
+      jj_consume_token(IMPLEMENTATION);
+            {if (true) return SqlExplain.Depth.LOGICAL;}
+    } else {
+            {if (true) return SqlExplain.Depth.PHYSICAL;}
+    }
+    throw new Error("Missing return statement in function");
+  }
+
+/**
+ * Parses INCLUDING ALL ATTRIBUTES modifier for EXPLAIN PLAN.
+ */
+  final public SqlExplainLevel ExplainDetailLevel() throws ParseException {
+    SqlExplainLevel level = SqlExplainLevel.EXPPLAN_ATTRIBUTES;
+    if (jj_2_143(2)) {
+      jj_consume_token(EXCLUDING);
+      jj_consume_token(ATTRIBUTES);
+            level = SqlExplainLevel.NO_ATTRIBUTES;
+    } else if (jj_2_144(2)) {
+      jj_consume_token(INCLUDING);
+      if (jj_2_142(2)) {
+        jj_consume_token(ALL);
+                  level = SqlExplainLevel.ALL_ATTRIBUTES;
+      } else {
+        ;
+      }
+      jj_consume_token(ATTRIBUTES);
+
+    } else {
+      jj_consume_token(-1);
+      throw new ParseException();
+    }
+        {if (true) return level;}
+    throw new Error("Missing return statement in function");
+  }
+
+/**
+ * Parses a DESCRIBE statement.
+ */
+  final public SqlNode SqlDescribe() throws ParseException {
+   final Span s;
+   final SqlIdentifier table;
+   final SqlIdentifier column;
+   final SqlIdentifier id;
+   final SqlNode stmt;
+    jj_consume_token(DESCRIBE);
+                 s = span();
+    if (jj_2_150(2)) {
+      if (jj_2_145(2)) {
+        jj_consume_token(DATABASE);
+      } else if (jj_2_146(2)) {
+        jj_consume_token(CATALOG);
+      } else if (jj_2_147(2)) {
+        jj_consume_token(SCHEMA);
+      } else {
+        jj_consume_token(-1);
+        throw new ParseException();
+      }
+      id = CompoundIdentifier();
+            // DESCRIBE DATABASE and DESCRIBE CATALOG currently do the same as
+            // DESCRIBE SCHEMA but should be different. See
+            //   [CALCITE-1221] Implement DESCRIBE DATABASE, CATALOG, STATEMENT
+            {if (true) return new SqlDescribeSchema(s.end(id), id);}
+    } else if (jj_2_151(2147483647)) {
+      if (jj_2_148(2)) {
+        jj_consume_token(TABLE);
+      } else {
+        ;
+      }
+      table = CompoundIdentifier();
+      if (jj_2_149(2)) {
+        column = SimpleIdentifier();
+      } else {
+        E();
+                  column = null;
+      }
+            {if (true) return new SqlDescribeTable(s.add(table).addIf(column).pos(),
+                table, column);}
+    } else if (jj_2_152(2)) {
+      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+      case STATEMENT:
+        jj_consume_token(STATEMENT);
+        break;
+      default:
+        jj_la1[0] = jj_gen;
+        ;
+      }
+      stmt = SqlQueryOrDml();
+            // DESCRIBE STATEMENT currently does the same as EXPLAIN. See
+            //   [CALCITE-1221] Implement DESCRIBE DATABASE, CATALOG, STATEMENT
+            final SqlExplainLevel detailLevel = SqlExplainLevel.EXPPLAN_ATTRIBUTES;
+            final SqlExplain.Depth depth = SqlExplain.Depth.PHYSICAL;
+            final SqlExplainFormat format = SqlExplainFormat.TEXT;
+            {if (true) return new SqlExplain(s.end(stmt),
+                stmt,
+                detailLevel.symbol(SqlParserPos.ZERO),
+                depth.symbol(SqlParserPos.ZERO),
+                format.symbol(SqlParserPos.ZERO),
+                nDynamicParams);}
+    } else {
+      jj_consume_token(-1);
+      throw new ParseException();
+    }
+    throw new Error("Missing return statement in function");
+  }
+
+/**
+ * Parses a CALL statement.
+ */
+  final public SqlNode SqlProcedureCall() throws ParseException {
+    final Span s;
+    SqlNode routineCall;
+    jj_consume_token(CALL);
+        s = span();
+    routineCall = NamedRoutineCall(SqlFunctionCategory.USER_DEFINED_PROCEDURE,
+            ExprContext.ACCEPT_SUB_QUERY);
+        {if (true) return SqlStdOperatorTable.PROCEDURE_CALL.createCall(
+            s.end(routineCall), routineCall);}
+    throw new Error("Missing return statement in function");
+  }
+
+  final public SqlNode NamedRoutineCall(SqlFunctionCategory routineType,
+    ExprContext exprContext) throws ParseException {
+    SqlIdentifier name;
+    final List<SqlNode> list = new ArrayList<SqlNode>();
+    final Span s;
+    name = CompoundIdentifier();
+        s = span();
+    jj_consume_token(LPAREN);
+    if (jj_2_154(2)) {
+      Arg0(list, exprContext);
+      label_13:
+      while (true) {
+        if (jj_2_153(2)) {
+          ;
+        } else {
+          break label_13;
+        }
+        jj_consume_token(COMMA);
+                // a comma-list can't appear where only a query is expected
+                checkNonQueryExpression(exprContext);
+        Arg(list, exprContext);
+      }
+    } else {
+      ;
+    }
+    jj_consume_token(RPAREN);
+        {if (true) return createCall(name, s.end(this), routineType, null, list);}
+    throw new Error("Missing return statement in function");
+  }
+
+/**
+ * Parses an INSERT statement.
+ */
+  final public SqlNode SqlInsert() throws ParseException {
+    final List<SqlLiteral> keywords = new ArrayList<SqlLiteral>();
+    final SqlNodeList keywordList;
+    SqlNode table;
+    SqlNodeList extendList = null;
+    SqlNode source;
+    SqlNodeList columnList = null;
+    final Span s;
+    if (jj_2_155(2)) {
+      jj_consume_token(INSERT);
+    } else if (jj_2_156(2)) {
+      jj_consume_token(UPSERT);
+                   keywords.add(SqlInsertKeyword.UPSERT.symbol(getPos()));
+    } else {
+      jj_consume_token(-1);
+      throw new ParseException();
+    }
+      s = span();
+    SqlInsertKeywords(keywords);
+        keywordList = new SqlNodeList(keywords, s.addAll(keywords).pos());
+    jj_consume_token(INTO);
+    table = TableRefWithHintsOpt();
+    if (jj_2_158(5)) {
+      if (jj_2_157(2)) {
+        jj_consume_token(EXTEND);
+      } else {
+        ;
+      }
+      extendList = ExtendList();
+            table = extend(table, extendList);
+    } else {
+      ;
+    }
+    if (jj_2_159(2)) {
+          final Pair<SqlNodeList, SqlNodeList> p;
+      p = ParenthesizedCompoundIdentifierList();
+            if (p.right.size() > 0) {
+                table = extend(table, p.right);
+            }
+            if (p.left.size() > 0) {
+                columnList = p.left;
+            }
+    } else {
+      ;
+    }
+    source = OrderedQueryOrExpr(ExprContext.ACCEPT_QUERY);
+        {if (true) return new SqlInsert(s.end(source), keywordList, table, source,
+            columnList);}
+    throw new Error("Missing return statement in function");
+  }
+
+/*
+ * Abstract production:
+ *
+ *    void SqlInsertKeywords(List keywords)
+ *
+ * Parses dialect-specific keywords immediately following the INSERT keyword.
+ */
+
+/**
+ * Parses a DELETE statement.
+ */
+  final public SqlNode SqlDelete() throws ParseException {
+    SqlNode table;
+    SqlNodeList extendList = null;
+    SqlIdentifier alias = null;
+    final SqlNode condition;
+    final Span s;
+    jj_consume_token(DELETE);
+        s = span();
+    jj_consume_token(FROM);
+    table = TableRefWithHintsOpt();
+    if (jj_2_161(2)) {
+      if (jj_2_160(2)) {
+        jj_consume_token(EXTEND);
+      } else {
+        ;
+      }
+      extendList = ExtendList();
+            table = extend(table, extendList);
+    } else {
+      ;
+    }
+    if (jj_2_163(2)) {
+      if (jj_2_162(2)) {
+        jj_consume_token(AS);
+      } else {
+        ;
+      }
+      alias = SimpleIdentifier();
+    } else {
+      ;
+    }
+    condition = WhereOpt();
+        {if (true) return new SqlDelete(s.add(table).addIf(extendList).addIf(alias)
+            .addIf(condition).pos(), table, condition, null, alias);}
+    throw new Error("Missing return statement in function");
+  }
+
+/**
+ * Parses an UPDATE statement.
+ */
+  final public SqlNode SqlUpdate() throws ParseException {
+    SqlNode table;
+    SqlNodeList extendList = null;
+    SqlIdentifier alias = null;
+    SqlNode condition;
+    SqlNodeList sourceExpressionList;
+    SqlNodeList targetColumnList;
+    SqlIdentifier id;
+    SqlNode exp;
+    final Span s;
+    jj_consume_token(UPDATE);
+               s = span();
+    table = TableRefWithHintsOpt();
+        targetColumnList = new SqlNodeList(s.pos());
+        sourceExpressionList = new SqlNodeList(s.pos());
+    if (jj_2_165(2)) {
+      if (jj_2_164(2)) {
+        jj_consume_token(EXTEND);
+      } else {
+        ;
+      }
+      extendList = ExtendList();
+            table = extend(table, extendList);
+    } else {
+      ;
+    }
+    if (jj_2_167(2)) {
+      if (jj_2_166(2)) {
+        jj_consume_token(AS);
+      } else {
+        ;
+      }
+      alias = SimpleIdentifier();
+    } else {
+      ;
+    }
+    jj_consume_token(SET);
+    id = SimpleIdentifier();
+        targetColumnList.add(id);
+    jj_consume_token(EQ);
+    exp = Expression(ExprContext.ACCEPT_SUB_QUERY);
+        // TODO:  support DEFAULT also
+        sourceExpressionList.add(exp);
+    label_14:
+    while (true) {
+      if (jj_2_168(2)) {
+        ;
+      } else {
+        break label_14;
+      }
+      jj_consume_token(COMMA);
+      id = SimpleIdentifier();
+            targetColumnList.add(id);
+      jj_consume_token(EQ);
+      exp = Expression(ExprContext.ACCEPT_SUB_QUERY);
+            sourceExpressionList.add(exp);
+    }
+    condition = WhereOpt();
+        {if (true) return new SqlUpdate(s.addAll(targetColumnList)
+            .addAll(sourceExpressionList).addIf(condition).pos(), table,
+            targetColumnList, sourceExpressionList, condition, null, alias);}
+    throw new Error("Missing return statement in function");
+  }
+
+/**
+ * Parses a MERGE statement.
+ */
+  final public SqlNode SqlMerge() throws ParseException {
+    SqlNode table;
+    SqlNodeList extendList = null;
+    SqlIdentifier alias = null;
+    SqlNode sourceTableRef;
+    SqlNode condition;
+    SqlUpdate updateCall = null;
+    SqlInsert insertCall = null;
+    final Span s;
+    jj_consume_token(MERGE);
+              s = span();
+    jj_consume_token(INTO);
+    table = TableRefWithHintsOpt();
+    if (jj_2_170(2)) {
+      if (jj_2_169(2)) {
+        jj_consume_token(EXTEND);
+      } else {
+        ;
+      }
+      extendList = ExtendList();
+            table = extend(table, extendList);
+    } else {
+      ;
+    }
+    if (jj_2_172(2)) {
+      if (jj_2_171(2)) {
+        jj_consume_token(AS);
+      } else {
+        ;
+      }
+      alias = SimpleIdentifier();
+    } else {
+      ;
+    }
+    jj_consume_token(USING);
+    sourceTableRef = TableRef();
+    jj_consume_token(ON);
+    condition = Expression(ExprContext.ACCEPT_SUB_QUERY);
+    if (jj_2_174(2)) {
+      updateCall = WhenMatchedClause(table, alias);
+      if (jj_2_173(2)) {
+        insertCall = WhenNotMatchedClause(table);
+      } else {
+        ;
+      }
+    } else if (jj_2_175(2)) {
+      insertCall = WhenNotMatchedClause(table);
+    } else {
+      jj_consume_token(-1);
+      throw new ParseException();
+    }
+        {if (true) return new SqlMerge(s.addIf(updateCall).addIf(insertCall).pos(), table,
+            condition, sourceTableRef, updateCall, insertCall, null, alias);}
+    throw new Error("Missing return statement in function");
+  }
+
+  final public SqlUpdate WhenMatchedClause(SqlNode table, SqlIdentifier alias) throws ParseException {
+    SqlIdentifier id;
+    final Span s;
+    final SqlNodeList updateColumnList = new SqlNodeList(SqlParserPos.ZERO);
+    SqlNode exp;
+    final SqlNodeList updateExprList = new SqlNodeList(SqlParserPos.ZERO);
+    jj_consume_token(WHEN);
+             s = span();
+    jj_consume_token(MATCHED);
+    jj_consume_token(THEN);
+    jj_consume_token(UPDATE);
+    jj_consume_token(SET);
+    id = CompoundIdentifier();
+        updateColumnList.add(id);
+    jj_consume_token(EQ);
+    exp = Expression(ExprContext.ACCEPT_SUB_QUERY);
+        updateExprList.add(exp);
+    label_15:
+    while (true) {
+      if (jj_2_176(2)) {
+        ;
+      } else {
+        break label_15;
+      }
+      jj_consume_token(COMMA);
+      id = CompoundIdentifier();
+            updateColumnList.add(id);
+      jj_consume_token(EQ);
+      exp = Expression(ExprContext.ACCEPT_SUB_QUERY);
+            updateExprList.add(exp);
+    }
+        {if (true) return new SqlUpdate(s.addAll(updateExprList).pos(), table,
+            updateColumnList, updateExprList, null, null, alias);}
+    throw new Error("Missing return statement in function");
+  }
+
+  final public SqlInsert WhenNotMatchedClause(SqlNode table) throws ParseException {
+    final Span insertSpan, valuesSpan;
+    final List<SqlLiteral> keywords = new ArrayList<SqlLiteral>();
+    final SqlNodeList keywordList;
+    SqlNodeList insertColumnList = null;
+    SqlNode rowConstructor;
+    SqlNode insertValues;
+    jj_consume_token(WHEN);
+    jj_consume_token(NOT);
+    jj_consume_token(MATCHED);
+    jj_consume_token(THEN);
+    jj_consume_token(INSERT);
+        insertSpan = span();
+    SqlInsertKeywords(keywords);
+        keywordList = new SqlNodeList(keywords, insertSpan.end(this));
+    if (jj_2_177(2)) {
+      insertColumnList = ParenthesizedSimpleIdentifierList();
+    } else {
+      ;
+    }
+    if (jj_2_178(2)) {
+      jj_consume_token(LPAREN);
+    } else {
+      ;
+    }
+    jj_consume_token(VALUES);
+               valuesSpan = span();
+    rowConstructor = RowConstructor();
+    if (jj_2_179(2)) {
+      jj_consume_token(RPAREN);
+    } else {
+      ;
+    }
+        // TODO zfong 5/26/06: note that extra parentheses are accepted above
+        // around the VALUES clause as a hack for unparse, but this is
+        // actually invalid SQL; should fix unparse
+        insertValues = SqlStdOperatorTable.VALUES.createCall(
+            valuesSpan.end(this), rowConstructor);
+        {if (true) return new SqlInsert(insertSpan.end(this), keywordList,
+            table, insertValues, insertColumnList);}
+    throw new Error("Missing return statement in function");
+  }
+
+/**
+ * Parses the select list of a SELECT statement.
+ */
+  final public List<SqlNode> SelectList() throws ParseException {
+    final List<SqlNode> list = new ArrayList<SqlNode>();
+    SqlNode item;
+    item = SelectItem();
+        list.add(item);
+    label_16:
+    while (true) {
+      if (jj_2_180(2)) {
+        ;
+      } else {
+        break label_16;
+      }
+      jj_consume_token(COMMA);
+      item = SelectItem();
+            list.add(item);
+    }
+        {if (true) return list;}
+    throw new Error("Missing return statement in function");
+  }
+
+/**
+ * Parses one item in a select list.
+ */
+  final public SqlNode SelectItem() throws ParseException {
+    SqlNode e;
+    final SqlIdentifier id;
+    e = SelectExpression();
+    if (jj_2_183(2)) {
+      if (jj_2_181(2)) {
+        jj_consume_token(AS);
+      } else {
+        ;
+      }
+      if (jj_2_182(2)) {
+        id = SimpleIdentifier();
+      } else {
+        switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+        case QUOTED_STRING:
+          id = SimpleIdentifierFromStringLiteral();
+          break;
+        default:
+          jj_la1[1] = jj_gen;
+          jj_consume_token(-1);
+          throw new ParseException();
+        }
+      }
+            e = SqlStdOperatorTable.AS.createCall(span().end(e), e, id);
+    } else {
+      ;
+    }
+        {if (true) return e;}
+    throw new Error("Missing return statement in function");
+  }
+
+/**
+ * Parses one unaliased expression in a select list.
+ */
+  final public SqlNode SelectExpression() throws ParseException {
+    SqlNode e;
+    if (jj_2_184(2)) {
+      jj_consume_token(STAR);
+        {if (true) return SqlIdentifier.star(getPos());}
+    } else if (jj_2_185(2)) {
+      e = Expression(ExprContext.ACCEPT_SUB_QUERY);
+        {if (true) return e;}
+    } else {
+      jj_consume_token(-1);
+      throw new ParseException();
+    }
+    throw new Error("Missing return statement in function");
+  }
+
+  final public SqlLiteral Natural() throws ParseException {
+    if (jj_2_186(2)) {
+      jj_consume_token(NATURAL);
+                {if (true) return SqlLiteral.createBoolean(true, getPos());}
+    } else {
+      {if (true) return SqlLiteral.createBoolean(false, getPos());}
+    }
+    throw new Error("Missing return statement in function");
+  }
+
+  final public SqlLiteral JoinType() throws ParseException {
+    JoinType joinType;
+    if (jj_2_190(3)) {
+      jj_consume_token(JOIN);
+                 joinType = JoinType.INNER;
+    } else if (jj_2_191(2)) {
+      jj_consume_token(INNER);
+      jj_consume_token(JOIN);
+                         joinType = JoinType.INNER;
+    } else if (jj_2_192(2)) {
+      jj_consume_token(LEFT);
+      if (jj_2_187(2)) {
+        jj_consume_token(OUTER);
+      } else {
+        ;
+      }
+      jj_consume_token(JOIN);
+                                    joinType = JoinType.LEFT;
+    } else if (jj_2_193(2)) {
+      jj_consume_token(RIGHT);
+      if (jj_2_188(2)) {
+        jj_consume_token(OUTER);
+      } else {
+        ;
+      }
+      jj_consume_token(JOIN);
+                                     joinType = JoinType.RIGHT;
+    } else if (jj_2_194(2)) {
+      jj_consume_token(FULL);
+      if (jj_2_189(2)) {
+        jj_consume_token(OUTER);
+      } else {
+        ;
+      }
+      jj_consume_token(JOIN);
+                                    joinType = JoinType.FULL;
+    } else if (jj_2_195(2)) {
+      jj_consume_token(CROSS);
+      jj_consume_token(JOIN);
+                         joinType = JoinType.CROSS;
+    } else {
+      jj_consume_token(-1);
+      throw new ParseException();
+    }
+        {if (true) return joinType.symbol(getPos());}
+    throw new Error("Missing return statement in function");
+  }
+
+/** Matches "LEFT JOIN t ON ...", "RIGHT JOIN t USING ...", "JOIN t". */
+  final public SqlNode JoinTable(SqlNode e) throws ParseException {
+    SqlNode e2, condition;
+    final SqlLiteral natural, joinType, on, using;
+    SqlNodeList list;
+    natural = Natural();
+    joinType = JoinType();
+    e2 = TableRef();
+    if (jj_2_196(2)) {
+      jj_consume_token(ON);
+               on = JoinConditionType.ON.symbol(getPos());
+      condition = Expression(ExprContext.ACCEPT_SUB_QUERY);
+            {if (true) return new SqlJoin(joinType.getParserPosition(),
+                e,
+                natural,
+                joinType,
+                e2,
+                on,
+                condition);}
+    } else if (jj_2_197(2)) {
+      jj_consume_token(USING);
+                  using = JoinConditionType.USING.symbol(getPos());
+      list = ParenthesizedSimpleIdentifierList();
+            {if (true) return new SqlJoin(joinType.getParserPosition(),
+                e,
+                natural,
+                joinType,
+                e2,
+                using,
+                new SqlNodeList(list, Span.of(using).end(this)));}
+    } else {
+            {if (true) return new SqlJoin(joinType.getParserPosition(),
+                e,
+                natural,
+                joinType,
+                e2,
+                JoinConditionType.NONE.symbol(joinType.getParserPosition()),
+                null);}
+    }
+    throw new Error("Missing return statement in function");
+  }
+
+// TODO jvs 15-Nov-2003:  SQL standard allows parentheses in the FROM list for
+// building up non-linear join trees (e.g. OUTER JOIN two tables, and then INNER
+// JOIN the result).  Also note that aliases on parenthesized FROM expressions
+// "hide" all table names inside the parentheses (without aliases, they're
+// visible).
+//
+// We allow CROSS JOIN to have a join condition, even though that is not valid
+// SQL; the validator will catch it.
+/**
+ * Parses the FROM clause for a SELECT.
+ *
+ * <p>FROM is mandatory in standard SQL, optional in dialects such as MySQL,
+ * PostgreSQL. The parser allows SELECT without FROM, but the validator fails
+ * if conformance is, say, STRICT_2003.
+ */
+  final public SqlNode FromClause() throws ParseException {
+    SqlNode e, e2, condition;
+    SqlLiteral natural, joinType, joinConditionType;
+    SqlNodeList list;
+    SqlParserPos pos;
+    e = TableRef();
+    label_17:
+    while (true) {
+      if (jj_2_198(2)) {
+        ;
+      } else {
+        break label_17;
+      }
+      if (jj_2_201(3)) {
+        natural = Natural();
+        joinType = JoinType();
+        e2 = TableRef();
+        if (jj_2_199(2)) {
+          jj_consume_token(ON);
+                    joinConditionType = JoinConditionType.ON.symbol(getPos());
+          condition = Expression(ExprContext.ACCEPT_SUB_QUERY);
+                    e = new SqlJoin(joinType.getParserPosition(),
+                        e,
+                        natural,
+                        joinType,
+                        e2,
+                        joinConditionType,
+                        condition);
+        } else if (jj_2_200(2)) {
+          jj_consume_token(USING);
+                    joinConditionType = JoinConditionType.USING.symbol(getPos());
+          list = ParenthesizedSimpleIdentifierList();
+                    e = new SqlJoin(joinType.getParserPosition(),
+                        e,
+                        natural,
+                        joinType,
+                        e2,
+                        joinConditionType,
+                        new SqlNodeList(list.getList(), Span.of(joinConditionType).end(this)));
+        } else {
+                    e = new SqlJoin(joinType.getParserPosition(),
+                        e,
+                        natural,
+                        joinType,
+                        e2,
+                        JoinConditionType.NONE.symbol(joinType.getParserPosition()),
+                        null);
+        }
+      } else if (jj_2_202(2)) {
+        jj_consume_token(COMMA);
+                      joinType = JoinType.COMMA.symbol(getPos());
+        e2 = TableRef();
+                e = new SqlJoin(joinType.getParserPosition(),
+                    e,
+                    SqlLiteral.createBoolean(false, joinType.getParserPosition()),
+                    joinType,
+                    e2,
+                    JoinConditionType.NONE.symbol(SqlParserPos.ZERO),
+                    null);
+      } else if (jj_2_203(2)) {
+        jj_consume_token(CROSS);
+                      joinType = JoinType.CROSS.symbol(getPos());
+        jj_consume_token(APPLY);
+        e2 = TableRef2(true);
+                if (!this.conformance.isApplyAllowed()) {
+                    {if (true) throw SqlUtil.newContextException(getPos(), RESOURCE.applyNotAllowed());}
+                }
+                e = new SqlJoin(joinType.getParserPosition(),
+                    e,
+                    SqlLiteral.createBoolean(false, joinType.getParserPosition()),
+                    joinType,
+                    e2,
+                    JoinConditionType.NONE.symbol(SqlParserPos.ZERO),
+                    null);
+      } else if (jj_2_204(2)) {
+        jj_consume_token(OUTER);
+                      joinType = JoinType.LEFT.symbol(getPos());
+        jj_consume_token(APPLY);
+        e2 = TableRef2(true);
+                if (!this.conformance.isApplyAllowed()) {
+                    {if (true) throw SqlUtil.newContextException(getPos(), RESOURCE.applyNotAllowed());}
+                }
+                e = new SqlJoin(joinType.getParserPosition(),
+                    e,
+                    SqlLiteral.createBoolean(false, joinType.getParserPosition()),
+                    joinType,
+                    e2,
+                    JoinConditionType.ON.symbol(SqlParserPos.ZERO),
+                    SqlLiteral.createBoolean(true, joinType.getParserPosition()));
+      } else {
+        jj_consume_token(-1);
+        throw new ParseException();
+      }
+    }
+        {if (true) return e;}
+    throw new Error("Missing return statement in function");
+  }
+
+/**
+ * Parses a table reference in a FROM clause, not lateral unless LATERAL
+ * is explicitly specified.
+ */
+  final public SqlNode TableRef() throws ParseException {
+    final SqlNode e;
+    e = TableRef2(false);
+                           {if (true) return e;}
+    throw new Error("Missing return statement in function");
+  }
+
+/**
+ * Parses a table reference in a FROM clause.
+ */
+  final public SqlNode TableRef2(boolean lateral) throws ParseException {
+    SqlNode tableRef;
+    final SqlNode over;
+    final SqlNode snapshot;
+    final SqlNode match;
+    SqlNodeList extendList = null;
+    final SqlIdentifier alias;
+    final Span s, s2;
+    SqlNodeList args;
+    SqlNode sample;
+    boolean isBernoulli;
+    SqlNumericLiteral samplePercentage;
+    boolean isRepeatable = false;
+    int repeatableSeed = 0;
+    SqlNodeList columnAliasList = null;
+    SqlUnnestOperator unnestOp = SqlStdOperatorTable.UNNEST;
+    if (jj_2_213(2)) {
+      tableRef = TableRefWithHintsOpt();
+      if (jj_2_206(2)) {
+        if (jj_2_205(2)) {
+          jj_consume_token(EXTEND);
+        } else {
+          ;
+        }
+        extendList = ExtendList();
+                tableRef = extend(tableRef, extendList);
+      } else {
+        ;
+      }
+      over = TableOverOpt();
+            if (over != null) {
+                tableRef = SqlStdOperatorTable.OVER.createCall(
+                    getPos(), tableRef, over);
+            }
+      if (jj_2_207(2)) {
+        tableRef = Snapshot(tableRef);
+      } else {
+        ;
+      }
+      if (jj_2_208(2)) {
+        tableRef = MatchRecognize(tableRef);
+      } else {
+        ;
+      }
+    } else if (jj_2_214(2)) {
+      if (jj_2_209(2)) {
+        jj_consume_token(LATERAL);
+                      lateral = true;
+      } else {
+        ;
+      }
+      tableRef = ParenthesizedExpression(ExprContext.ACCEPT_QUERY);
+      over = TableOverOpt();
+            if (over != null) {
+                tableRef = SqlStdOperatorTable.OVER.createCall(
+                    getPos(), tableRef, over);
+            }
+            if (lateral) {
+                tableRef = SqlStdOperatorTable.LATERAL.createCall(
+                    getPos(), tableRef);
+            }
+      if (jj_2_210(2)) {
+        tableRef = MatchRecognize(tableRef);
+      } else {
+        ;
+      }
+    } else if (jj_2_215(2)) {
+      jj_consume_token(UNNEST);
+                   s = span();
+      args = ParenthesizedQueryOrCommaList(ExprContext.ACCEPT_SUB_QUERY);
+      if (jj_2_211(2)) {
+        jj_consume_token(WITH);
+        jj_consume_token(ORDINALITY);
+                unnestOp = SqlStdOperatorTable.UNNEST_WITH_ORDINALITY;
+      } else {
+        ;
+      }
+            tableRef = unnestOp.createCall(s.end(this), (List<SqlNode>) args);
+    } else if (jj_2_216(2)) {
+      if (jj_2_212(2)) {
+        jj_consume_token(LATERAL);
+                     lateral = true;
+      } else {
+        ;
+      }
+      jj_consume_token(TABLE);
+                  s = span();
+      jj_consume_token(LPAREN);
+      tableRef = TableFunctionCall(s.pos());
+      jj_consume_token(RPAREN);
+            if (lateral) {
+                tableRef = SqlStdOperatorTable.LATERAL.createCall(
+                    s.end(this), tableRef);
+            }
+    } else if (jj_2_217(2)) {
+      tableRef = ExtendedTableRef();
+    } else {
+      jj_consume_token(-1);
+      throw new ParseException();
+    }
+    if (jj_2_218(2)) {
+      tableRef = Pivot(tableRef);
+    } else {
+      ;
+    }
+    if (jj_2_219(2)) {
+      tableRef = Unpivot(tableRef);
+    } else {
+      ;
+    }
+    if (jj_2_222(2)) {
+      if (jj_2_220(2)) {
+        jj_consume_token(AS);
+      } else {
+        ;
+      }
+      alias = SimpleIdentifier();
+      if (jj_2_221(2)) {
+        columnAliasList = ParenthesizedSimpleIdentifierList();
+      } else {
+        ;
+      }
+            if (columnAliasList == null) {
+                tableRef = SqlStdOperatorTable.AS.createCall(
+                    Span.of(tableRef).end(this), tableRef, alias);
+            } else {
+                List<SqlNode> idList = new ArrayList<SqlNode>();
+                idList.add(tableRef);
+                idList.add(alias);
+                idList.addAll(columnAliasList.getList());
+                tableRef = SqlStdOperatorTable.AS.createCall(
+                    Span.of(tableRef).end(this), idList);
+            }
+    } else {
+      ;
+    }
+    if (jj_2_228(2)) {
+      jj_consume_token(TABLESAMPLE);
+                        s2 = span();
+      if (jj_2_226(2)) {
+        jj_consume_token(SUBSTITUTE);
+        jj_consume_token(LPAREN);
+        sample = StringLiteral();
+        jj_consume_token(RPAREN);
+                String sampleName =
+                    SqlLiteral.unchain(sample).getValueAs(String.class);
+                SqlSampleSpec sampleSpec = SqlSampleSpec.createNamed(sampleName);
+                final SqlLiteral sampleLiteral =
+                    SqlLiteral.createSample(sampleSpec, s2.end(this));
+                tableRef = SqlStdOperatorTable.TABLESAMPLE.createCall(
+                    s2.add(tableRef).end(this), tableRef, sampleLiteral);
+      } else if (jj_2_227(2)) {
+        if (jj_2_223(2)) {
+          jj_consume_token(BERNOULLI);
+                    isBernoulli = true;
+        } else if (jj_2_224(2)) {
+          jj_consume_token(SYSTEM);
+                    isBernoulli = false;
+        } else {
+          jj_consume_token(-1);
+          throw new ParseException();
+        }
+        jj_consume_token(LPAREN);
+        samplePercentage = UnsignedNumericLiteral();
+        jj_consume_token(RPAREN);
+        if (jj_2_225(2)) {
+          jj_consume_token(REPEATABLE);
+          jj_consume_token(LPAREN);
+          repeatableSeed = IntLiteral();
+          jj_consume_token(RPAREN);
+                    isRepeatable = true;
+        } else {
+          ;
+        }
+                final BigDecimal ONE_HUNDRED = BigDecimal.valueOf(100L);
+                BigDecimal rate = samplePercentage.bigDecimalValue();
+                if (rate.compareTo(BigDecimal.ZERO) < 0
+                    || rate.compareTo(ONE_HUNDRED) > 0)
+                {
+                    {if (true) throw SqlUtil.newContextException(getPos(), RESOURCE.invalidSampleSize());}
+                }
+
+                // Treat TABLESAMPLE(0) and TABLESAMPLE(100) as no table
+                // sampling at all.  Not strictly correct: TABLESAMPLE(0)
+                // should produce no output, but it simplifies implementation
+                // to know that some amount of sampling will occur.
+                // In practice values less than ~1E-43% are treated as 0.0 and
+                // values greater than ~99.999997% are treated as 1.0
+                float fRate = rate.divide(ONE_HUNDRED).floatValue();
+                if (fRate > 0.0f && fRate < 1.0f) {
+                    SqlSampleSpec tableSampleSpec =
+                    isRepeatable
+                        ? SqlSampleSpec.createTableSample(
+                            isBernoulli, fRate, repeatableSeed)
+                        : SqlSampleSpec.createTableSample(isBernoulli, fRate);
+
+                    SqlLiteral tableSampleLiteral =
+                        SqlLiteral.createSample(tableSampleSpec, s2.end(this));
+                    tableRef = SqlStdOperatorTable.TABLESAMPLE.createCall(
+                        s2.end(this), tableRef, tableSampleLiteral);
+                }
+      } else {
+        jj_consume_token(-1);
+        throw new ParseException();
+      }
+    } else {
+      ;
+    }
+        {if (true) return tableRef;}
+    throw new Error("Missing return statement in function");
+  }
+
+  final public SqlNodeList ExtendList() throws ParseException {
+    final Span s;
+    List<SqlNode> list = new ArrayList<SqlNode>();
+    jj_consume_token(LPAREN);
+               s = span();
+    ColumnType(list);
+    label_18:
+    while (true) {
+      if (jj_2_229(2)) {
+        ;
+      } else {
+        break label_18;
+      }
+      jj_consume_token(COMMA);
+      ColumnType(list);
+    }
+    jj_consume_token(RPAREN);
+        {if (true) return new SqlNodeList(list, s.end(this));}
+    throw new Error("Missing return statement in function");
+  }
+
+  final public void ColumnType(List<SqlNode> list) throws ParseException {
+    SqlIdentifier name;
+    SqlDataTypeSpec type;
+    boolean nullable = true;
+    name = CompoundIdentifier();
+    type = DataType();
+    if (jj_2_230(2)) {
+      jj_consume_token(NOT);
+      jj_consume_token(NULL);
+            nullable = false;
+    } else {
+      ;
+    }
+        list.add(name);
+        list.add(type.withNullable(nullable, getPos()));
+  }
+
+/**
+ * Parses a compound identifier with optional type.
+ */
+  final public void CompoundIdentifierType(List<SqlNode> list, List<SqlNode> extendList) throws ParseException {
+    final SqlIdentifier name;
+    SqlDataTypeSpec type = null;
+    boolean nullable = true;
+    name = CompoundIdentifier();
+    if (jj_2_232(2)) {
+      type = DataType();
+      if (jj_2_231(2)) {
+        jj_consume_token(NOT);
+        jj_consume_token(NULL);
+                nullable = false;
+      } else {
+        ;
+      }
+    } else {
+      ;
+    }
+        if (type != null) {
+            if (!this.conformance.allowExtend()) {
+                {if (true) throw SqlUtil.newContextException(type.getParserPosition(),
+                    RESOURCE.extendNotAllowed());}
+            }
+            extendList.add(name);
+            extendList.add(type.withNullable(nullable, getPos()));
+        }
+        list.add(name);
+  }
+
+  final public SqlNode TableFunctionCall(SqlParserPos pos) throws ParseException {
+    SqlNode call;
+    SqlFunctionCategory funcType = SqlFunctionCategory.USER_DEFINED_TABLE_FUNCTION;
+    if (jj_2_233(2)) {
+      jj_consume_token(SPECIFIC);
+            funcType = SqlFunctionCategory.USER_DEFINED_TABLE_SPECIFIC_FUNCTION;
+    } else {
+      ;
+    }
+    call = NamedRoutineCall(funcType, ExprContext.ACCEPT_CURSOR);
+        {if (true) return SqlStdOperatorTable.COLLECTION_TABLE.createCall(pos, call);}
+    throw new Error("Missing return statement in function");
+  }
+
+/**
+ * Abstract production:
+ *    SqlNode ExtendedTableRef()
+ *
+ * <p>Allows parser to be extended with new types of table references.  The
+ * default implementation of this production is empty.
+ */
+
+/*
+ * Abstract production:
+ *
+ *    SqlNode TableOverOpt()
+ *
+ * Allows an OVER clause following a table expression as an extension to
+ * standard SQL syntax. The default implementation of this production is empty.
+ */
+
+/**
+ * Parses an explicit TABLE t reference.
+ */
+  final public SqlNode ExplicitTable(SqlParserPos pos) throws ParseException {
+    SqlNode tableRef;
+    jj_consume_token(TABLE);
+    tableRef = CompoundIdentifier();
+        {if (true) return SqlStdOperatorTable.EXPLICIT_TABLE.createCall(pos, tableRef);}
+    throw new Error("Missing return statement in function");
+  }
+
+/**
+ * Parses a VALUES leaf query expression.
+ */
+  final public SqlNode TableConstructor() throws ParseException {
+    final List<SqlNode> rowConstructorList = new ArrayList<SqlNode>();
+    final Span s;
+    jj_consume_token(VALUES);
+               s = span();
+    RowConstructorList(rowConstructorList);
+        {if (true) return SqlStdOperatorTable.VALUES.createCall(
+            s.end(this), rowConstructorList);}
+    throw new Error("Missing return statement in function");
+  }
+
+/**
+ * Parses one or more rows in a VALUES expression.
+ */
+  final public void RowConstructorList(List<SqlNode> list) throws ParseException {
+    SqlNode rowConstructor;
+    rowConstructor = RowConstructor();
+                                        list.add(rowConstructor);
+    label_19:
+    while (true) {
+      if (jj_2_234(2)) {
+        ;
+      } else {
+        break label_19;
+      }
+      jj_consume_token(COMMA);
+      rowConstructor = RowConstructor();
+                                                    list.add(rowConstructor);
+    }
+  }
+
+/**
+ * Parses a row constructor in the context of a VALUES expression.
+ */
+  final public SqlNode RowConstructor() throws ParseException {
+    SqlNodeList valueList;
+    SqlNode value;
+    final Span s;
+    if (jj_2_236(3)) {
+      jj_consume_token(LPAREN);
+                   s = span();
+      jj_consume_token(ROW);
+      valueList = ParenthesizedQueryOrCommaListWithDefault(ExprContext.ACCEPT_NONCURSOR);
+      jj_consume_token(RPAREN);
+                   s.add(this);
+    } else if (jj_2_237(3)) {
+      if (jj_2_235(2)) {
+        jj_consume_token(ROW);
+                    s = span();
+      } else {
+              s = Span.of();
+      }
+      valueList = ParenthesizedQueryOrCommaListWithDefault(ExprContext.ACCEPT_NONCURSOR);
+    } else if (jj_2_238(2)) {
+      value = Expression(ExprContext.ACCEPT_NONCURSOR);
+            // NOTE: A bare value here is standard SQL syntax, believe it or
+            // not.  Taken together with multi-row table constructors, it leads
+            // to very easy mistakes if you forget the parentheses on a
+            // single-row constructor.  This is also the reason for the
+            // LOOKAHEAD in RowConstructorList().  It would be so much more
+            // reasonable to require parentheses.  Sigh.
+            s = Span.of(value);
+            valueList = new SqlNodeList(Collections.singletonList(value),
+                value.getParserPosition());
+    } else {
+      jj_consume_token(-1);
+      throw new ParseException();
+    }
+        // REVIEW jvs 8-Feb-2004: Should we discriminate between scalar
+        // sub-queries inside of ROW and row sub-queries?  The standard does,
+        // but the distinction seems to be purely syntactic.
+        {if (true) return SqlStdOperatorTable.ROW.createCall(s.end(valueList),
+            (List<SqlNode>) valueList);}
+    throw new Error("Missing return statement in function");
+  }
+
+/**
+ * Parses the optional WHERE clause for SELECT, DELETE, and UPDATE.
+ */
+  final public SqlNode WhereOpt() throws ParseException {
+    SqlNode condition;
+    if (jj_2_239(2)) {
+      jj_consume_token(WHERE);
+      condition = Expression(ExprContext.ACCEPT_SUB_QUERY);
+        {if (true) return condition;}
+    } else {
+        {if (true) return null;}
+    }
+    throw new Error("Missing return statement in function");
+  }
+
+/**
+ * Parses the optional GROUP BY clause for SELECT.
+ */
+  final public SqlNodeList GroupByOpt() throws ParseException {
+    List<SqlNode> list = new ArrayList<SqlNode>();
+    final Span s;
+    if (jj_2_240(2)) {
+      jj_consume_token(GROUP);
+              s = span();
+      jj_consume_token(BY);
+      list = GroupingElementList();
+        {if (true) return new SqlNodeList(list, s.addAll(list).pos());}
+    } else {
+        {if (true) return null;}
+    }
+    throw new Error("Missing return statement in function");
+  }
+
+  final public List<SqlNode> GroupingElementList() throws ParseException {
+    List<SqlNode> list = new ArrayList<SqlNode>();
+    SqlNode e;
+    e = GroupingElement();
+                            list.add(e);
+    label_20:
+    while (true) {
+      if (jj_2_241(2)) {
+        ;
+      } else {
+        break label_20;
+      }
+      jj_consume_token(COMMA);
+      e = GroupingElement();
+                                list.add(e);
+    }
+      {if (true) return list;}
+    throw new Error("Missing return statement in function");
+  }
+
+  final public SqlNode GroupingElement() throws ParseException {
+    List<SqlNode> list;
+    final SqlNodeList nodes;
+    final SqlNode e;
+    final Span s;
+    if (jj_2_242(2)) {
+      jj_consume_token(GROUPING);
+                 s = span();
+      jj_consume_token(SETS);
+      jj_consume_token(LPAREN);
+      list = GroupingElementList();
+      jj_consume_token(RPAREN);
+        {if (true) return SqlStdOperatorTable.GROUPING_SETS.createCall(s.end(this), list);}
+    } else if (jj_2_243(2)) {
+      jj_consume_token(ROLLUP);
+               s = span();
+      jj_consume_token(LPAREN);
+      nodes = ExpressionCommaList(s, ExprContext.ACCEPT_SUB_QUERY);
+      jj_consume_token(RPAREN);
+        {if (true) return SqlStdOperatorTable.ROLLUP.createCall(s.end(this),
+            nodes.getList());}
+    } else if (jj_2_244(2)) {
+      jj_consume_token(CUBE);
+             s = span();
+      jj_consume_token(LPAREN);
+      nodes = ExpressionCommaList(s, ExprContext.ACCEPT_SUB_QUERY);
+      jj_consume_token(RPAREN);
+        {if (true) return SqlStdOperatorTable.CUBE.createCall(s.end(this),
+            nodes.getList());}
+    } else if (jj_2_245(3)) {
+      jj_consume_token(LPAREN);
+      jj_consume_token(RPAREN);
+        {if (true) return new SqlNodeList(getPos());}
+    } else if (jj_2_246(2)) {
+      e = Expression(ExprContext.ACCEPT_SUB_QUERY);
+        {if (true) return e;}
+    } else {
+      jj_consume_token(-1);
+      throw new ParseException();
+    }
+    throw new Error("Missing return statement in function");
+  }
+
+/**
+ * Parses a list of expressions separated by commas.
+ */
+  final public SqlNodeList ExpressionCommaList(final Span s,
+    ExprContext exprContext) throws ParseException {
+    final List<SqlNode> list = new ArrayList<SqlNode>();
+    ExpressionCommaList2(list, exprContext);
+        {if (true) return new SqlNodeList(list, s.addAll(list).pos());}
+    throw new Error("Missing return statement in function");
+  }
+
+/**
+ * Parses a list of expressions separated by commas,
+ * appending expressions to a given list.
+ */
+  final public void ExpressionCommaList2(List<SqlNode> list, ExprContext exprContext) throws ParseException {
+    SqlNode e;
+    e = Expression(exprContext);
+                                  list.add(e);
+    label_21:
+    while (true) {
+      if (jj_2_247(2)) {
+        ;
+      } else {
+        break label_21;
+      }
+      jj_consume_token(COMMA);
+      e = Expression(ExprContext.ACCEPT_SUB_QUERY);
+            list.add(e);
+    }
+  }
+
+/**
+ * Parses the optional HAVING clause for SELECT.
+ */
+  final public SqlNode HavingOpt() throws ParseException {
+    SqlNode e;
+    if (jj_2_248(2)) {
+      jj_consume_token(HAVING);
+      e = Expression(ExprContext.ACCEPT_SUB_QUERY);
+                                                            {if (true) return e;}
+    } else {
+      {if (true) return null;}
+    }
+    throw new Error("Missing return statement in function");
+  }
+
+/**
+ * Parses the optional WINDOW clause for SELECT
+ */
+  final public SqlNodeList WindowOpt() throws ParseException {
+    SqlIdentifier id;
+    SqlWindow e;
+    List<SqlNode> list;
+    final Span s;
+    if (jj_2_250(2)) {
+      jj_consume_token(WINDOW);
+               s = span();
+      id = SimpleIdentifier();
+      jj_consume_token(AS);
+      e = WindowSpecification();
+        e.setDeclName(id);
+        list = startList(e);
+      label_22:
+      while (true) {
+        if (jj_2_249(2)) {
+          ;
+        } else {
+          break label_22;
+        }
+        jj_consume_token(COMMA);
+        id = SimpleIdentifier();
+        jj_consume_token(AS);
+        e = WindowSpecification();
+            e.setDeclName(id);
+            list.add(e);
+      }
+        {if (true) return new SqlNodeList(list, s.addAll(list).pos());}
+    } else {
+        {if (true) return null;}
+    }
+    throw new Error("Missing return statement in function");
+  }
+
+/**
+ * Parses a window specification.
+ */
+  final public SqlWindow WindowSpecification() throws ParseException {
+    SqlIdentifier id;
+    List list;
+    SqlNodeList partitionList;
+    SqlNodeList orderList;
+    SqlLiteral isRows = SqlLiteral.createBoolean(false, SqlParserPos.ZERO);
+    SqlNode lowerBound = null, upperBound = null;
+    SqlParserPos startPos;
+    final Span s, s1, s2;
+    SqlLiteral allowPartial = null;
+    jj_consume_token(LPAREN);
+               s = span();
+    if (jj_2_251(2)) {
+      id = SimpleIdentifier();
+    } else {
+          id = null;
+    }
+    if (jj_2_252(2)) {
+      jj_consume_token(PARTITION);
+                      s1 = span();
+      jj_consume_token(BY);
+      partitionList = ExpressionCommaList(s1, ExprContext.ACCEPT_NON_QUERY);
+    } else {
+          partitionList = SqlNodeList.EMPTY;
+    }
+    if (jj_2_253(2)) {
+      orderList = OrderBy(true);
+    } else {
+          orderList = SqlNodeList.EMPTY;
+    }
+    if (jj_2_258(2)) {
+      if (jj_2_254(2)) {
+        jj_consume_token(ROWS);
+                     isRows = SqlLiteral.createBoolean(true, getPos());
+      } else if (jj_2_255(2)) {
+        jj_consume_token(RANGE);
+                      isRows = SqlLiteral.createBoolean(false, getPos());
+      } else {
+        jj_consume_token(-1);
+        throw new ParseException();
+      }
+      if (jj_2_256(2)) {
+        jj_consume_token(BETWEEN);
+        lowerBound = WindowRange();
+        jj_consume_token(AND);
+        upperBound = WindowRange();
+      } else if (jj_2_257(2)) {
+        lowerBound = WindowRange();
+      } else {
+        jj_consume_token(-1);
+        throw new ParseException();
+      }
+    } else {
+      ;
+    }
+    if (jj_2_261(2)) {
+      if (jj_2_259(2)) {
+        jj_consume_token(ALLOW);
+                  s2 = span();
+        jj_consume_token(PARTIAL);
+            allowPartial = SqlLiteral.createBoolean(true, s2.end(this));
+      } else if (jj_2_260(2)) {
+        jj_consume_token(DISALLOW);
+                     s2 = span();
+        jj_consume_token(PARTIAL);
+            allowPartial = SqlLiteral.createBoolean(false, s2.end(this));
+      } else {
+        jj_consume_token(-1);
+        throw new ParseException();
+      }
+    } else {
+      ;
+    }
+    jj_consume_token(RPAREN);
+        {if (true) return SqlWindow.create(
+            null, id, partitionList, orderList,
+            isRows, lowerBound, upperBound, allowPartial, s.end(this));}
+    throw new Error("Missing return statement in function");
+  }
+
+  final public SqlNode WindowRange() throws ParseException {
+    final SqlNode e;
+    final Span s;
+    if (jj_2_266(2)) {
+      jj_consume_token(CURRENT);
+                s = span();
+      jj_consume_token(ROW);
+        {if (true) return SqlWindow.createCurrentRow(s.end(this));}
+    } else if (jj_2_267(2)) {
+      jj_consume_token(UNBOUNDED);
+                  s = span();
+      if (jj_2_262(2)) {
+        jj_consume_token(PRECEDING);
+            {if (true) return SqlWindow.createUnboundedPreceding(s.end(this));}
+      } else if (jj_2_263(2)) {
+        jj_consume_token(FOLLOWING);
+            {if (true) return SqlWindow.createUnboundedFollowing(s.end(this));}
+      } else {
+        jj_consume_token(-1);
+        throw new ParseException();
+      }
+    } else if (jj_2_268(2)) {
+      e = Expression(ExprContext.ACCEPT_NON_QUERY);
+      if (jj_2_264(2)) {
+        jj_consume_token(PRECEDING);
+            {if (true) return SqlWindow.createPreceding(e, getPos());}
+      } else if (jj_2_265(2)) {
+        jj_consume_token(FOLLOWING);
+            {if (true) return SqlWindow.createFollowing(e, getPos());}
+      } else {
+        jj_consume_token(-1);
+        throw new ParseException();
+      }
+    } else {
+      jj_consume_token(-1);
+      throw new ParseException();
+    }
+    throw new Error("Missing return statement in function");
+  }
+
+/**
+ * Parses an ORDER BY clause.
+ */
+  final public SqlNodeList OrderBy(boolean accept) throws ParseException {
+    List<SqlNode> list;
+    SqlNode e;
+    final Span s;
+    jj_consume_token(ORDER);
+        s = span();
+        if (!accept) {
+            // Someone told us ORDER BY wasn't allowed here.  So why
+            // did they bother calling us?  To get the correct
+            // parser position for error reporting.
+            {if (true) throw SqlUtil.newContextException(s.pos(), RESOURCE.illegalOrderBy());}
+        }
+    jj_consume_token(BY);
+    e = OrderItem();
+        list = startList(e);
+    label_23:
+    while (true) {
+      if (jj_2_269(2)) {
+        ;
+      } else {
+        break label_23;
+      }
+      jj_consume_token(COMMA);
+      e = OrderItem();
+                                               list.add(e);
+    }
+        {if (true) return new SqlNodeList(list, s.addAll(list).pos());}
+    throw new Error("Missing return statement in function");
+  }
+
+/**
+ * Parses one list item in an ORDER BY clause.
+ */
+  final public SqlNode OrderItem() throws ParseException {
+    SqlNode e;
+    e = Expression(ExprContext.ACCEPT_SUB_QUERY);
+    if (jj_2_272(2)) {
+      if (jj_2_270(2)) {
+        jj_consume_token(ASC);
+      } else if (jj_2_271(2)) {
+        jj_consume_token(DESC);
+            e = SqlStdOperatorTable.DESC.createCall(getPos(), e);
+      } else {
+        jj_consume_token(-1);
+        throw new ParseException();
+      }
+    } else {
+      ;
+    }
+    if (jj_2_275(2)) {
+      if (jj_2_273(2)) {
+        jj_consume_token(NULLS);
+        jj_consume_token(FIRST);
+            e = SqlStdOperatorTable.NULLS_FIRST.createCall(getPos(), e);
+      } else if (jj_2_274(2)) {
+        jj_consume_token(NULLS);
+        jj_consume_token(LAST);
+            e = SqlStdOperatorTable.NULLS_LAST.createCall(getPos(), e);
+      } else {
+        jj_consume_token(-1);
+        throw new ParseException();
+      }
+    } else {
+      ;
+    }
+        {if (true) return e;}
+    throw new Error("Missing return statement in function");
+  }
+
+/**
+ * Parses a FOR SYSTEM_TIME clause following a table expression.
+ */
+  final public SqlSnapshot Snapshot(SqlNode tableRef) throws ParseException {
+    final Span s;
+    final SqlNode e;
+      s = span();
+    jj_consume_token(FOR);
+    jj_consume_token(SYSTEM_TIME);
+    jj_consume_token(AS);
+    jj_consume_token(OF);
+    // Syntax for temporal table in
+        // standard SQL 2011 IWD 9075-2:201?(E) 7.6 <table reference>
+        // supports grammar as following:
+        // 1. datetime literal
+        // 2. datetime value function, i.e. CURRENT_TIMESTAMP
+        // 3. datetime term in 1 or 2 +(or -) interval term
+    
+        // We extend to support column reference, use Expression
+        // to simplify the parsing code.
+        e = Expression(ExprContext.ACCEPT_NON_QUERY);
+        {if (true) return new SqlSnapshot(s.end(this), tableRef, e);}
+    throw new Error("Missing return statement in function");
+  }
+
+/** Parses a PIVOT clause following a table expression. */
+  final public SqlNode Pivot(SqlNode tableRef) throws ParseException {
+    final Span s;
+    final Span s2;
+    final List<SqlNode> aggList = new ArrayList<SqlNode>();
+    final List<SqlNode> valueList = new ArrayList<SqlNode>();
+    final SqlNodeList axisList;
+    final SqlNodeList inList;
+    jj_consume_token(PIVOT);
+              s = span();
+    jj_consume_token(LPAREN);
+    PivotAgg(aggList);
+    label_24:
+    while (true) {
+      if (jj_2_276(2)) {
+        ;
+      } else {
+        break label_24;
+      }
+      jj_consume_token(COMMA);
+      PivotAgg(aggList);
+    }
+    jj_consume_token(FOR);
+    axisList = SimpleIdentifierOrList();
+    jj_consume_token(IN);
+    jj_consume_token(LPAREN);
+                    s2 = span();
+    if (jj_2_278(2)) {
+      PivotValue(valueList);
+      label_25:
+      while (true) {
+        if (jj_2_277(2)) {
+          ;
+        } else {
+          break label_25;
+        }
+        jj_consume_token(COMMA);
+        PivotValue(valueList);
+      }
+    } else {
+      ;
+    }
+    jj_consume_token(RPAREN);
+        inList = new SqlNodeList(valueList, s2.end(this));
+    jj_consume_token(RPAREN);
+        {if (true) return new SqlPivot(s.end(this), tableRef,
+            new SqlNodeList(aggList, SqlParserPos.sum(aggList)),
+            axisList, inList);}
+    throw new Error("Missing return statement in function");
+  }
+
+  final public void PivotAgg(List<SqlNode> list) throws ParseException {
+    final SqlNode e;
+    final SqlIdentifier alias;
+    e = NamedFunctionCall();
+    if (jj_2_280(2)) {
+      if (jj_2_279(2)) {
+        jj_consume_token(AS);
+      } else {
+        ;
+      }
+      alias = SimpleIdentifier();
+            list.add(
+                SqlStdOperatorTable.AS.createCall(Span.of(e).end(this), e,
+                    alias));
+    } else {
+          list.add(e);
+    }
+  }
+
+  final public void PivotValue(List<SqlNode> list) throws ParseException {
+    final SqlNode e;
+    final SqlNodeList tuple;
+    final SqlIdentifier alias;
+    e = RowConstructor();
+                           tuple = SqlParserUtil.stripRow(e);
+    if (jj_2_282(2)) {
+      if (jj_2_281(2)) {
+        jj_consume_token(AS);
+      } else {
+        ;
+      }
+      alias = SimpleIdentifier();
+            list.add(
+                SqlStdOperatorTable.AS.createCall(Span.of(tuple).end(this),
+                    tuple, alias));
+    } else {
+          list.add(tuple);
+    }
+  }
+
+/** Parses an UNPIVOT clause following a table expression. */
+  final public SqlNode Unpivot(SqlNode tableRef) throws ParseException {
+    final Span s;
+    final boolean includeNulls;
+    final SqlNodeList measureList;
+    final SqlNodeList axisList;
+    final Span s2;
+    final List<SqlNode> values = new ArrayList<SqlNode>();
+    final SqlNodeList inList;
+    jj_consume_token(UNPIVOT);
+                s = span();
+    if (jj_2_283(2)) {
+      jj_consume_token(INCLUDE);
+      jj_consume_token(NULLS);
+                            includeNulls = true;
+    } else if (jj_2_284(2)) {
+      jj_consume_token(EXCLUDE);
+      jj_consume_token(NULLS);
+                            includeNulls = false;
+    } else {
+          includeNulls = false;
+    }
+    jj_consume_token(LPAREN);
+    measureList = SimpleIdentifierOrList();
+    jj_consume_token(FOR);
+    axisList = SimpleIdentifierOrList();
+    jj_consume_token(IN);
+    jj_consume_token(LPAREN);
+               s2 = span();
+    UnpivotValue(values);
+    label_26:
+    while (true) {
+      if (jj_2_285(2)) {
+        ;
+      } else {
+        break label_26;
+      }
+      jj_consume_token(COMMA);
+      UnpivotValue(values);
+    }
+    jj_consume_token(RPAREN);
+      inList = new SqlNodeList(values, s2.end(this));
+    jj_consume_token(RPAREN);
+        {if (true) return new SqlUnpivot(s.end(this), tableRef, includeNulls, measureList,
+            axisList, inList);}
+    throw new Error("Missing return statement in function");
+  }
+
+  final public void UnpivotValue(List<SqlNode> list) throws ParseException {
+    final SqlNodeList columnList;
+    final SqlNode values;
+    columnList = SimpleIdentifierOrList();
+    if (jj_2_286(2)) {
+      jj_consume_token(AS);
+      values = RowConstructor();
+            final SqlNodeList valueList = SqlParserUtil.stripRow(values);
+            list.add(
+                SqlStdOperatorTable.AS.createCall(Span.of(columnList).end(this),
+                    columnList, valueList));
+    } else {
+          list.add(columnList);
+    }
+  }
+
+/**
+ * Parses a MATCH_RECOGNIZE clause following a table expression.
+ */
+  final public SqlMatchRecognize MatchRecognize(SqlNode tableRef) throws ParseException {
+    final Span s, s0, s1, s2;
+    SqlNodeList measureList = SqlNodeList.EMPTY;
+    SqlNodeList partitionList = SqlNodeList.EMPTY;
+    SqlNodeList orderList = SqlNodeList.EMPTY;
+    SqlNode pattern;
+    SqlLiteral interval;
+    SqlNodeList patternDefList;
+    final SqlNode after;
+    SqlParserPos pos;
+    final SqlNode var;
+    final SqlLiteral rowsPerMatch;
+    SqlNodeList subsetList = SqlNodeList.EMPTY;
+    SqlLiteral isStrictStarts = SqlLiteral.createBoolean(false, getPos());
+    SqlLiteral isStrictEnds = SqlLiteral.createBoolean(false, getPos());
+    jj_consume_token(MATCH_RECOGNIZE);
+                        s = span();
+    jj_consume_token(LPAREN);
+    if (jj_2_287(2)) {
+      jj_consume_token(PARTITION);
+                      s2 = span();
+      jj_consume_token(BY);
+      partitionList = ExpressionCommaList(s2, ExprContext.ACCEPT_NON_QUERY);
+    } else {
+      ;
+    }
+    if (jj_2_288(2)) {
+      orderList = OrderBy(true);
+    } else {
+      ;
+    }
+    if (jj_2_289(2)) {
+      jj_consume_token(MEASURES);
+      measureList = MeasureColumnCommaList(span());
+    } else {
+      ;
+    }
+    if (jj_2_290(2)) {
+      jj_consume_token(ONE);
+                s0 = span();
+      jj_consume_token(ROW);
+      jj_consume_token(PER);
+      jj_consume_token(MATCH);
+            rowsPerMatch = SqlMatchRecognize.RowsPerMatchOption.ONE_ROW.symbol(s0.end(this));
+    } else if (jj_2_291(2)) {
+      jj_consume_token(ALL);
+                s0 = span();
+      jj_consume_token(ROWS);
+      jj_consume_token(PER);
+      jj_consume_token(MATCH);
+            rowsPerMatch = SqlMatchRecognize.RowsPerMatchOption.ALL_ROWS.symbol(s0.end(this));
+    } else {
+            rowsPerMatch = null;
+    }
+    if (jj_2_297(2)) {
+      jj_consume_token(AFTER);
+                  s1 = span();
+      jj_consume_token(MATCH);
+      jj_consume_token(SKIP_);
+      if (jj_2_295(2)) {
+        jj_consume_token(TO);
+        if (jj_2_293(2)) {
+          jj_consume_token(NEXT);
+          jj_consume_token(ROW);
+                    after = SqlMatchRecognize.AfterOption.SKIP_TO_NEXT_ROW
+                        .symbol(s1.end(this));
+        } else if (jj_2_294(2)) {
+          jj_consume_token(FIRST);
+          var = SimpleIdentifier();
+                    after = SqlMatchRecognize.SKIP_TO_FIRST.createCall(
+                        s1.end(var), var);
+        } else if (true) {
+          if (jj_2_292(2)) {
+            jj_consume_token(LAST);
+          } else {
+            ;
+          }
+          var = SimpleIdentifier();
+                    after = SqlMatchRecognize.SKIP_TO_LAST.createCall(
+                        s1.end(var), var);
+        } else {
+          jj_consume_token(-1);
+          throw new ParseException();
+        }
+      } else if (jj_2_296(2)) {
+        jj_consume_token(PAST);
+        jj_consume_token(LAST);
+        jj_consume_token(ROW);
+                 after = SqlMatchRecognize.AfterOption.SKIP_PAST_LAST_ROW
+                     .symbol(s1.end(this));
+      } else {
+        jj_consume_token(-1);
+        throw new ParseException();
+      }
+    } else {
+          after = null;
+    }
+    jj_consume_token(PATTERN);
+    jj_consume_token(LPAREN);
+    if (jj_2_298(2)) {
+      jj_consume_token(CARET);
+                  isStrictStarts = SqlLiteral.createBoolean(true, getPos());
+    } else {
+          isStrictStarts = SqlLiteral.createBoolean(false, getPos());
+    }
+    pattern = PatternExpression();
+    if (jj_2_299(2)) {
+      jj_consume_token(DOLLAR);
+                   isStrictEnds = SqlLiteral.createBoolean(true, getPos());
+    } else {
+          isStrictEnds = SqlLiteral.createBoolean(false, getPos());
+    }
+    jj_consume_token(RPAREN);
+    if (jj_2_300(2)) {
+      jj_consume_token(WITHIN);
+      interval = IntervalLiteral();
+    } else {
+          interval = null;
+    }
+    if (jj_2_301(2)) {
+      jj_consume_token(SUBSET);
+      subsetList = SubsetDefinitionCommaList(span());
+    } else {
+      ;
+    }
+    jj_consume_token(DEFINE);
+    patternDefList = PatternDefinitionCommaList(span());
+    jj_consume_token(RPAREN);
+        {if (true) return new SqlMatchRecognize(s.end(this), tableRef,
+            pattern, isStrictStarts, isStrictEnds, patternDefList, measureList,
+            after, subsetList, rowsPerMatch, partitionList, orderList, interval);}
+    throw new Error("Missing return statement in function");
+  }
+
+  final public SqlNodeList MeasureColumnCommaList(Span s) throws ParseException {
+    SqlNode e;
+    final List<SqlNode> eList = new ArrayList<SqlNode>();
+    e = MeasureColumn();
+        eList.add(e);
+    label_27:
+    while (true) {
+      if (jj_2_302(2)) {
+        ;
+      } else {
+        break label_27;
+      }
+      jj_consume_token(COMMA);
+      e = MeasureColumn();
+            eList.add(e);
+    }
+        {if (true) return new SqlNodeList(eList, s.addAll(eList).pos());}
+    throw new Error("Missing return statement in function");
+  }
+
+  final public SqlNode MeasureColumn() throws ParseException {
+    SqlNode e;
+    SqlIdentifier alias;
+    e = Expression(ExprContext.ACCEPT_NON_QUERY);
+    jj_consume_token(AS);
+    alias = SimpleIdentifier();
+        {if (true) return SqlStdOperatorTable.AS.createCall(Span.of(e).end(this), e, alias);}
+    throw new Error("Missing return statement in function");
+  }
+
+  final public SqlNode PatternExpression() throws ParseException {
+    SqlNode left;
+    SqlNode right;
+    left = PatternTerm();
+    label_28:
+    while (true) {
+      if (jj_2_303(2)) {
+        ;
+      } else {
+        break label_28;
+      }
+      jj_consume_token(VERTICAL_BAR);
+      right = PatternTerm();
+            left = SqlStdOperatorTable.PATTERN_ALTER.createCall(
+                Span.of(left).end(right), left, right);
+    }
+        {if (true) return left;}
+    throw new Error("Missing return statement in function");
+  }
+
+  final public SqlNode PatternTerm() throws ParseException {
+    SqlNode left;
+    SqlNode right;
+    left = PatternFactor();
+    label_29:
+    while (true) {
+      if (jj_2_304(2)) {
+        ;
+      } else {
+        break label_29;
+      }
+      right = PatternFactor();
+            left = SqlStdOperatorTable.PATTERN_CONCAT.createCall(
+                Span.of(left).end(right), left, right);
+    }
+        {if (true) return left;}
+    throw new Error("Missing return statement in function");
+  }
+
+  final public SqlNode PatternFactor() throws ParseException {
+    SqlNode e;
+    SqlNode extra;
+    SqlLiteral startNum = null;
+    SqlLiteral endNum = null;
+    SqlLiteral reluctant = SqlLiteral.createBoolean(false, SqlParserPos.ZERO);
+    e = PatternPrimary();
+    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+    case LBRACE:
+    case HOOK:
+    case PLUS:
+    case STAR:
+      if (jj_2_310(2)) {
+        jj_consume_token(STAR);
+                startNum = SqlLiteral.createExactNumeric("0", SqlParserPos.ZERO);
+                endNum = SqlLiteral.createExactNumeric("-1", SqlParserPos.ZERO);
+      } else if (jj_2_311(2)) {
+        jj_consume_token(PLUS);
+                startNum = SqlLiteral.createExactNumeric("1", SqlParserPos.ZERO);
+                endNum = SqlLiteral.createExactNumeric("-1", SqlParserPos.ZERO);
+      } else if (jj_2_312(2)) {
+        jj_consume_token(HOOK);
+                startNum = SqlLiteral.createExactNumeric("0", SqlParserPos.ZERO);
+                endNum = SqlLiteral.createExactNumeric("1", SqlParserPos.ZERO);
+      } else if (jj_2_313(2)) {
+        jj_consume_token(LBRACE);
+        if (jj_2_307(2)) {
+          startNum = UnsignedNumericLiteral();
+                                                      endNum = startNum;
+          if (jj_2_306(2)) {
+            jj_consume_token(COMMA);
+                        endNum = SqlLiteral.createExactNumeric("-1", SqlParserPos.ZERO);
+            if (jj_2_305(2)) {
+              endNum = UnsignedNumericLiteral();
+            } else {
+              ;
+            }
+          } else {
+            ;
+          }
+          jj_consume_token(RBRACE);
+        } else if (jj_2_308(2)) {
+                    startNum = SqlLiteral.createExactNumeric("-1", SqlParserPos.ZERO);
+          jj_consume_token(COMMA);
+          endNum = UnsignedNumericLiteral();
+          jj_consume_token(RBRACE);
+        } else if (jj_2_309(2)) {
+          jj_consume_token(MINUS);
+          extra = PatternExpression();
+          jj_consume_token(MINUS);
+          jj_consume_token(RBRACE);
+                    extra = SqlStdOperatorTable.PATTERN_EXCLUDE.createCall(
+                        Span.of(extra).end(this), extra);
+                    e = SqlStdOperatorTable.PATTERN_CONCAT.createCall(
+                        Span.of(e).end(this), e, extra);
+                    {if (true) return e;}
+        } else {
+          jj_consume_token(-1);
+          throw new ParseException();
+        }
+      } else {
+        jj_consume_token(-1);
+        throw new ParseException();
+      }
+      if (jj_2_314(2)) {
+        jj_consume_token(HOOK);
+                if (startNum.intValue(true) != endNum.intValue(true)) {
+                    reluctant = SqlLiteral.createBoolean(true, SqlParserPos.ZERO);
+                }
+      } else {
+        ;
+      }
+      break;
+    default:
+      jj_la1[2] = jj_gen;
+      ;
+    }
+        if (startNum == null) {
+            {if (true) return e;}
+        } else {
+            {if (true) return SqlStdOperatorTable.PATTERN_QUANTIFIER.createCall(
+                span().end(e), e, startNum, endNum, reluctant);}
+        }
+    throw new Error("Missing return statement in function");
+  }
+
+  final public SqlNode PatternPrimary() throws ParseException {
+    final Span s;
+    SqlNode e;
+    List<SqlNode> eList;
+    if (jj_2_316(2)) {
+      e = SimpleIdentifier();
+    } else if (jj_2_317(2)) {
+      jj_consume_token(LPAREN);
+      e = PatternExpression();
+      jj_consume_token(RPAREN);
+    } else if (jj_2_318(2)) {
+      jj_consume_token(LBRACE);
+                   s = span();
+      jj_consume_token(MINUS);
+      e = PatternExpression();
+      jj_consume_token(MINUS);
+      jj_consume_token(RBRACE);
+            e = SqlStdOperatorTable.PATTERN_EXCLUDE.createCall(s.end(this), e);
+    } else if (jj_2_319(2)) {
+      jj_consume_token(PERMUTE);
+                        s = span();
+      jj_consume_token(LPAREN);
+      e = PatternExpression();
+                eList = new ArrayList<SqlNode>();
+                eList.add(e);
+      label_30:
+      while (true) {
+        if (jj_2_315(2)) {
+          ;
+        } else {
+          break label_30;
+        }
+        jj_consume_token(COMMA);
+        e = PatternExpression();
+                    eList.add(e);
+      }
+      jj_consume_token(RPAREN);
+                e = SqlStdOperatorTable.PATTERN_PERMUTE.createCall(
+                    s.end(this), eList);
+    } else {
+      jj_consume_token(-1);
+      throw new ParseException();
+    }
+        {if (true) return e;}
+    throw new Error("Missing return statement in function");
+  }
+
+  final public SqlNodeList SubsetDefinitionCommaList(Span s) throws ParseException {
+    SqlNode e;
+    final List<SqlNode> eList = new ArrayList<SqlNode>();
+    e = SubsetDefinition();
+        eList.add(e);
+    label_31:
+    while (true) {
+      if (jj_2_320(2)) {
+        ;
+      } else {
+        break label_31;
+      }
+      jj_consume_token(COMMA);
+      e = SubsetDefinition();
+            eList.add(e);
+    }
+        {if (true) return new SqlNodeList(eList, s.addAll(eList).pos());}
+    throw new Error("Missing return statement in function");
+  }
+
+  final public SqlNode SubsetDefinition() throws ParseException {
+    final SqlNode var;
+    final SqlNodeList varList;
+    var = SimpleIdentifier();
+    jj_consume_token(EQ);
+    jj_consume_token(LPAREN);
+    varList = ExpressionCommaList(span(), ExprContext.ACCEPT_NON_QUERY);
+    jj_consume_token(RPAREN);
+        {if (true) return SqlStdOperatorTable.EQUALS.createCall(span().end(var), var,
+            varList);}
+    throw new Error("Missing return statement in function");
+  }
+
+  final public SqlNodeList PatternDefinitionCommaList(Span s) throws ParseException {
+    SqlNode e;
+    final List<SqlNode> eList = new ArrayList<SqlNode>();
+    e = PatternDefinition();
+        eList.add(e);
+    label_32:
+    while (true) {
+      if (jj_2_321(2)) {
+        ;
+      } else {
+        break label_32;
+      }
+      jj_consume_token(COMMA);
+      e = PatternDefinition();
+            eList.add(e);
+    }
+        {if (true) return new SqlNodeList(eList, s.addAll(eList).pos());}
+    throw new Error("Missing return statement in function");
+  }
+
+  final public SqlNode PatternDefinition() throws ParseException {
+    final SqlNode var;
+    final SqlNode e;
+    var = SimpleIdentifier();
+    jj_consume_token(AS);
+    e = Expression(ExprContext.ACCEPT_SUB_QUERY);
+        {if (true) return SqlStdOperatorTable.AS.createCall(Span.of(var, e).pos(), e, var);}
+    throw new Error("Missing return statement in function");
+  }
+
+// ----------------------------------------------------------------------------
+// Expressions
+
+/**
+ * Parses a SQL expression (such as might occur in a WHERE clause) followed by
+ * the end-of-file symbol.
+ */
+  final public SqlNode SqlExpressionEof() throws ParseException {
+    SqlNode e;
+    e = Expression(ExprContext.ACCEPT_SUB_QUERY);
+    jj_consume_token(0);
+        {if (true) return e;}
+    throw new Error("Missing return statement in function");
+  }
+
+/**
+ * Parses either a row expression or a query expression without ORDER BY.
+ */
+  final public SqlNode QueryOrExpr(ExprContext exprContext) throws ParseException {
+    SqlNodeList withList = null;
+    SqlNode e;
+    SqlOperator op;
+    SqlParserPos pos;
+    SqlParserPos withPos;
+    List<Object> list;
+    if (jj_2_322(2)) {
+      withList = WithList();
+    } else {
+      ;
+    }
+    e = LeafQueryOrExpr(exprContext);
+        list = startList(e);
+    label_33:
+    while (true) {
+      if (jj_2_323(2)) {
+        ;
+      } else {
+        break label_33;
+      }
+            if (!e.isA(SqlKind.QUERY)) {
+                // whoops, expression we just parsed wasn't a query,
+                // but we're about to see something like UNION, so
+                // force an exception retroactively
+                checkNonQueryExpression(ExprContext.ACCEPT_QUERY);
+            }
+      op = BinaryQueryOperator();
+            // ensure a query is legal in this context
+            pos = getPos();
+            checkQueryExpression(exprContext);
+      e = LeafQueryOrExpr(ExprContext.ACCEPT_QUERY);
+            list.add(new SqlParserUtil.ToTreeListItem(op, pos));
+            list.add(e);
+    }
+        e = SqlParserUtil.toTree(list);
+        if (withList != null) {
+            e = new SqlWith(withList.getParserPosition(), withList, e);
+        }
+        {if (true) return e;}
+    throw new Error("Missing return statement in function");
+  }
+
+  final public SqlNodeList WithList() throws ParseException {
+    SqlWithItem withItem;
+    SqlParserPos pos;
+    SqlNodeList list;
+    jj_consume_token(WITH);
+             list = new SqlNodeList(getPos());
+    withItem = WithItem();
+                           list.add(withItem);
+    label_34:
+    while (true) {
+      if (jj_2_324(2)) {
+        ;
+      } else {
+        break label_34;
+      }
+      jj_consume_token(COMMA);
+      withItem = WithItem();
+                                       list.add(withItem);
+    }
+      {if (true) return list;}
+    throw new Error("Missing return statement in function");
+  }
+
+  final public SqlWithItem WithItem() throws ParseException {
+    SqlIdentifier id;
+    SqlNodeList columnList = null;
+    SqlNode definition;
+    id = SimpleIdentifier();
+    if (jj_2_325(2)) {
+      columnList = ParenthesizedSimpleIdentifierList();
+    } else {
+      ;
+    }
+    jj_consume_token(AS);
+    definition = ParenthesizedExpression(ExprContext.ACCEPT_QUERY);
+        {if (true) return new SqlWithItem(id.getParserPosition(), id, columnList,
+            definition);}
+    throw new Error("Missing return statement in function");
+  }
+
+/**
+ * Parses either a row expression, a leaf query expression, or
+ * a parenthesized expression of any kind.
+ */
+  final public SqlNode LeafQueryOrExpr(ExprContext exprContext) throws ParseException {
+    SqlNode e;
+    if (jj_2_326(2)) {
+      e = Expression(exprContext);
+                                  {if (true) return e;}
+    } else if (jj_2_327(2)) {
+      e = LeafQuery(exprContext);
+                                 {if (true) return e;}
+    } else {
+      jj_consume_token(-1);
+      throw new ParseException();
+    }
+    throw new Error("Missing return statement in function");
+  }
+
+/**
+ * Parses a row expression or a parenthesized expression of any kind.
+ */
+  final public SqlNode Expression(ExprContext exprContext) throws ParseException {
+    List<Object> list;
+    SqlNode e;
+    list = Expression2(exprContext);
+        e = SqlParserUtil.toTree(list);
+        {if (true) return e;}
+    throw new Error("Missing return statement in function");
+  }
+
+// TODO jvs 15-Nov-2003:  ANY/ALL
+  final public void Expression2b(ExprContext exprContext, List<Object> list) throws ParseException {
+    SqlNode e;
+    SqlOperator op;
+    SqlNode ext;
+    label_35:
+    while (true) {
+      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+      case EXISTS:
+      case NOT:
+      case UNIQUE:
+      case PLUS:
+      case MINUS:
+        ;
+        break;
+      default:
+        jj_la1[3] = jj_gen;
+        break label_35;
+      }
+      op = PrefixRowOperator();
+            checkNonQueryExpression(exprContext);
+            list.add(new SqlParserUtil.ToTreeListItem(op, getPos()));
+    }
+    e = Expression3(exprContext);
+        list.add(e);
+    label_36:
+    while (true) {
+      if (jj_2_328(2)) {
+        ;
+      } else {
+        break label_36;
+      }
+      jj_consume_token(DOT);
+      ext = RowExpressionExtension();
+            list.add(
+                new SqlParserUtil.ToTreeListItem(
+                    SqlStdOperatorTable.DOT, getPos()));
+            list.add(ext);
+    }
+  }
+
+/**
+ * Parses a binary row expression, or a parenthesized expression of any
+ * kind.
+ *
+ * <p>The result is as a flat list of operators and operands. The top-level
+ * call to get an expression should call {@link #Expression}, but lower-level
+ * calls should call this, to give the parser the opportunity to associate
+ * operator calls.
+ *
+ * <p>For example 'a = b like c = d' should come out '((a = b) like c) = d'
+ * because LIKE and '=' have the same precedence, but tends to come out as '(a
+ * = b) like (c = d)' because (a = b) and (c = d) are parsed as separate
+ * expressions.
+ */
+  final public List<Object> Expression2(ExprContext exprContext) throws ParseException {
+    final List<Object> list = new ArrayList();
+    List<Object> list2;
+    final List<Object> list3 = new ArrayList();
+    SqlNodeList nodeList;
+    SqlNode e;
+    SqlOperator op;
+    SqlIdentifier p;
+    final Span s = span();
+    Expression2b(exprContext, list);
+    if (jj_2_367(2)) {
+      label_37:
+      while (true) {
+        if (jj_2_359(2)) {
+                    checkNonQueryExpression(exprContext);
+          if (jj_2_332(2)) {
+            jj_consume_token(NOT);
+            jj_consume_token(IN);
+                                 op = SqlStdOperatorTable.NOT_IN;
+          } else if (jj_2_333(2)) {
+            jj_consume_token(IN);
+                           op = SqlStdOperatorTable.IN;
+          } else if (jj_2_334(2)) {
+                      final SqlKind k;
+            k = comp();
+            if (jj_2_329(2)) {
+              jj_consume_token(SOME);
+                                 op = SqlStdOperatorTable.some(k);
+            } else if (jj_2_330(2)) {
+              jj_consume_token(ANY);
+                                op = SqlStdOperatorTable.some(k);
+            } else if (jj_2_331(2)) {
+              jj_consume_token(ALL);
+                                op = SqlStdOperatorTable.all(k);
+            } else {
+              jj_consume_token(-1);
+              throw new ParseException();
+            }
+          } else {
+            jj_consume_token(-1);
+            throw new ParseException();
+          }
+                  s.clear().add(this);
+          nodeList = ParenthesizedQueryOrCommaList(ExprContext.ACCEPT_NONCURSOR);
+                    list.add(new SqlParserUtil.ToTreeListItem(op, s.pos()));
+                    s.add(nodeList);
+                    // special case for stuff like IN (s1 UNION s2)
+                    if (nodeList.size() == 1) {
+                        SqlNode item = nodeList.get(0);
+                        if (item.isA(SqlKind.QUERY)) {
+                            list.add(item);
+                        } else {
+                            list.add(nodeList);
+                        }
+                    } else {
+                        list.add(nodeList);
+                    }
+        } else if (jj_2_360(2)) {
+                    checkNonQueryExpression(exprContext);
+          if (jj_2_341(2)) {
+            jj_consume_token(NOT);
+            jj_consume_token(BETWEEN);
+                        op = SqlStdOperatorTable.NOT_BETWEEN;
+                        s.clear().add(this);
+            if (jj_2_337(2)) {
+              if (jj_2_335(2)) {
+                jj_consume_token(SYMMETRIC);
+                                      op = SqlStdOperatorTable.SYMMETRIC_NOT_BETWEEN;
+              } else if (jj_2_336(2)) {
+                jj_consume_token(ASYMMETRIC);
+              } else {
+                jj_consume_token(-1);
+                throw new ParseException();
+              }
+            } else {
+              ;
+            }
+          } else if (jj_2_342(2)) {
+            jj_consume_token(BETWEEN);
+                        op = SqlStdOperatorTable.BETWEEN;
+                        s.clear().add(this);
+            if (jj_2_340(2)) {
+              if (jj_2_338(2)) {
+                jj_consume_token(SYMMETRIC);
+                                      op = SqlStdOperatorTable.SYMMETRIC_BETWEEN;
+              } else if (jj_2_339(2)) {
+                jj_consume_token(ASYMMETRIC);
+              } else {
+                jj_consume_token(-1);
+                throw new ParseException();
+              }
+            } else {
+              ;
+            }
+          } else {
+            jj_consume_token(-1);
+            throw new ParseException();
+          }
+          Expression2b(ExprContext.ACCEPT_SUB_QUERY, list3);
+                    list.add(new SqlParserUtil.ToTreeListItem(op, s.pos()));
+                    list.addAll(list3);
+                    list3.clear();
+        } else if (jj_2_361(2)) {
+                    checkNonQueryExpression(exprContext);
+                    s.clear().add(this);
+          if (jj_2_354(2)) {
+            if (jj_2_347(2)) {
+              jj_consume_token(NOT);
+              if (jj_2_343(2)) {
+                jj_consume_token(LIKE);
+                                     op = SqlStdOperatorTable.NOT_LIKE;
+              } else if (jj_2_344(2)) {
+                jj_consume_token(ILIKE);
+                                      op = SqlLibraryOperators.NOT_ILIKE;
+              } else if (jj_2_345(2)) {
+                jj_consume_token(RLIKE);
+                                      op = SqlLibraryOperators.NOT_RLIKE;
+              } else if (jj_2_346(2)) {
+                jj_consume_token(SIMILAR);
+                jj_consume_token(TO);
+                                             op = SqlStdOperatorTable.NOT_SIMILAR_TO;
+              } else {
+                jj_consume_token(-1);
+                throw new ParseException();
+              }
+            } else if (jj_2_348(2)) {
+              jj_consume_token(LIKE);
+                                 op = SqlStdOperatorTable.LIKE;
+            } else if (jj_2_349(2)) {
+              jj_consume_token(ILIKE);
+                                  op = SqlLibraryOperators.ILIKE;
+            } else if (jj_2_350(2)) {
+              jj_consume_token(RLIKE);
+                                  op = SqlLibraryOperators.RLIKE;
+            } else if (jj_2_351(2)) {
+              jj_consume_token(SIMILAR);
+              jj_consume_token(TO);
+                                         op = SqlStdOperatorTable.SIMILAR_TO;
+            } else {
+              jj_consume_token(-1);
+              throw new ParseException();
+            }
+          } else if (jj_2_355(2)) {
+            jj_consume_token(NEGATE);
+            jj_consume_token(TILDE);
+                                       op = SqlStdOperatorTable.NEGATED_POSIX_REGEX_CASE_SENSITIVE;
+            if (jj_2_352(2)) {
+              jj_consume_token(STAR);
+                               op = SqlStdOperatorTable.NEGATED_POSIX_REGEX_CASE_INSENSITIVE;
+            } else {
+              ;
+            }
+          } else if (jj_2_356(2)) {
+            jj_consume_token(TILDE);
+                              op = SqlStdOperatorTable.POSIX_REGEX_CASE_SENSITIVE;
+            if (jj_2_353(2)) {
+              jj_consume_token(STAR);
+                               op = SqlStdOperatorTable.POSIX_REGEX_CASE_INSENSITIVE;
+            } else {
+              ;
+            }
+          } else {
+            jj_consume_token(-1);
+            throw new ParseException();
+          }
+          list2 = Expression2(ExprContext.ACCEPT_SUB_QUERY);
+                    list.add(new SqlParserUtil.ToTreeListItem(op, s.pos()));
+                    list.addAll(list2);
+          if (jj_2_357(2)) {
+            jj_consume_token(ESCAPE);
+            e = Expression3(ExprContext.ACCEPT_SUB_QUERY);
+                        s.clear().add(this);
+                        list.add(
+                            new SqlParserUtil.ToTreeListItem(
+                                SqlStdOperatorTable.ESCAPE, s.pos()));
+                        list.add(e);
+          } else {
+            ;
+          }
+        } else if (jj_2_362(2)) {
+          InfixCast(list, exprContext, s);
+        } else if (jj_2_363(3)) {
+          op = BinaryRowOperator();
+                    checkNonQueryExpression(exprContext);
+                    list.add(new SqlParserUtil.ToTreeListItem(op, getPos()));
+          Expression2b(ExprContext.ACCEPT_SUB_QUERY, list);
+        } else if (jj_2_364(2)) {
+          jj_consume_token(LBRACKET);
+          e = Expression(ExprContext.ACCEPT_SUB_QUERY);
+          jj_consume_token(RBRACKET);
+                    list.add(
+                        new SqlParserUtil.ToTreeListItem(
+                            SqlStdOperatorTable.ITEM, getPos()));
+                    list.add(e);
+          label_38:
+          while (true) {
+            if (jj_2_358(2)) {
+              ;
+            } else {
+              break label_38;
+            }
+            jj_consume_token(DOT);
+            p = SimpleIdentifier();
+                        list.add(
+                            new SqlParserUtil.ToTreeListItem(
+                                SqlStdOperatorTable.DOT, getPos()));
+                        list.add(p);
+          }
+        } else if (jj_2_365(2)) {
+                    checkNonQueryExpression(exprContext);
+          op = PostfixRowOperator();
+                    list.add(new SqlParserUtil.ToTreeListItem(op, getPos()));
+        } else {
+          jj_consume_token(-1);
+          throw new ParseException();
+        }
+        if (jj_2_366(2)) {
+          ;
+        } else {
+          break label_37;
+        }
+      }
+            {if (true) return list;}
+    } else {
+            {if (true) return list;}
+    }
+    throw new Error("Missing return statement in function");
+  }
+
+/** Parses a comparison operator inside a SOME / ALL predicate. */
+  final public SqlKind comp() throws ParseException {
+    if (jj_2_368(2)) {
+      jj_consume_token(LT);
+           {if (true) return SqlKind.LESS_THAN;}
+    } else if (jj_2_369(2)) {
+      jj_consume_token(LE);
+           {if (true) return SqlKind.LESS_THAN_OR_EQUAL;}
+    } else if (jj_2_370(2)) {
+      jj_consume_token(GT);
+           {if (true) return SqlKind.GREATER_THAN;}
+    } else if (jj_2_371(2)) {
+      jj_consume_token(GE);
+           {if (true) return SqlKind.GREATER_THAN_OR_EQUAL;}
+    } else if (jj_2_372(2)) {
+      jj_consume_token(EQ);
+           {if (true) return SqlKind.EQUALS;}
+    } else if (jj_2_373(2)) {
+      jj_consume_token(NE);
+           {if (true) return SqlKind.NOT_EQUALS;}
+    } else if (jj_2_374(2)) {
+      jj_consume_token(NE2);
+        if (!this.conformance.isBangEqualAllowed()) {
+            {if (true) throw SqlUtil.newContextException(getPos(), RESOURCE.bangEqualNotAllowed());}
+        }
+        {if (true) return SqlKind.NOT_EQUALS;}
+    } else {
+      jj_consume_token(-1);
+      throw new ParseException();
+    }
+    throw new Error("Missing return statement in function");
+  }
+
+/**
+ * Parses a unary row expression, or a parenthesized expression of any
+ * kind.
+ */
+  final public SqlNode Expression3(ExprContext exprContext) throws ParseException {
+    final SqlNode e;
+    final SqlNodeList list;
+    final SqlNodeList list1;
+    final SqlNodeList list2;
+    final SqlOperator op;
+    final Span s;
+    Span rowSpan = null;
+    if (jj_2_377(2)) {
+      e = AtomicRowExpression();
+        checkNonQueryExpression(exprContext);
+        {if (true) return e;}
+    } else if (jj_2_378(2)) {
+      e = CursorExpression(exprContext);
+                                        {if (true) return e;}
+    } else if (jj_2_379(3)) {
+      jj_consume_token(ROW);
+        s = span();
+      list = ParenthesizedQueryOrCommaList(exprContext);
+        if (exprContext != ExprContext.ACCEPT_ALL
+            && exprContext != ExprContext.ACCEPT_CURSOR
+            && !this.conformance.allowExplicitRowValueConstructor())
+        {
+            {if (true) throw SqlUtil.newContextException(s.end(list),
+                RESOURCE.illegalRowExpression());}
+        }
+        {if (true) return SqlStdOperatorTable.ROW.createCall(list);}
+    } else if (jj_2_380(2)) {
+      if (jj_2_375(2)) {
+        jj_consume_token(ROW);
+                rowSpan = span();
+      } else {
+        ;
+      }
+      list1 = ParenthesizedQueryOrCommaList(exprContext);
+        if (rowSpan != null) {
+            // interpret as row constructor
+            {if (true) return SqlStdOperatorTable.ROW.createCall(rowSpan.end(list1),
+                (List<SqlNode>) list1);}
+        }
+      if (jj_2_376(2)) {
+        e = IntervalQualifier();
+                if ((list1.size() == 1)
+                    && list1.get(0) instanceof SqlCall)
+                {
+                    final SqlCall call = (SqlCall) list1.get(0);
+                    if (call.getKind() == SqlKind.MINUS
+                            && call.operandCount() == 2) {
+                        List<SqlNode> list3 = startList(call.operand(0));
+                        list3.add(call.operand(1));
+                        list3.add(e);
+                        {if (true) return SqlStdOperatorTable.MINUS_DATE.createCall(
+                            Span.of(list1).end(this), list3);}
+                     }
+                }
+                {if (true) throw SqlUtil.newContextException(span().end(list1),
+                    RESOURCE.illegalMinusDate());}
+      } else {
+        ;
+      }
+        if (list1.size() == 1) {
+            // interpret as single value or query
+            {if (true) return list1.get(0);}
+        } else {
+            // interpret as row constructor
+            {if (true) return SqlStdOperatorTable.ROW.createCall(span().end(list1),
+                (List<SqlNode>) list1);}
+        }
+    } else {
+      jj_consume_token(-1);
+      throw new ParseException();
+    }
+    throw new Error("Missing return statement in function");
+  }
+
+  final public SqlOperator periodOperator() throws ParseException {
+    if (jj_2_381(2)) {
+      jj_consume_token(OVERLAPS);
+                  {if (true) return SqlStdOperatorTable.OVERLAPS;}
+    } else if (jj_2_382(2)) {
+      jj_consume_token(IMMEDIATELY);
+      jj_consume_token(PRECEDES);
+                                {if (true) return SqlStdOperatorTable.IMMEDIATELY_PRECEDES;}
+    } else if (jj_2_383(2)) {
+      jj_consume_token(PRECEDES);
+                  {if (true) return SqlStdOperatorTable.PRECEDES;}
+    } else if (jj_2_384(2)) {
+      jj_consume_token(IMMEDIATELY);
+      jj_consume_token(SUCCEEDS);
+                                {if (true) return SqlStdOperatorTable.IMMEDIATELY_SUCCEEDS;}
+    } else if (jj_2_385(2)) {
+      jj_consume_token(SUCCEEDS);
+                  {if (true) return SqlStdOperatorTable.SUCCEEDS;}
+    } else if (jj_2_386(2)) {
+      jj_consume_token(EQUALS);
+                {if (true) return SqlStdOperatorTable.PERIOD_EQUALS;}
+    } else {
+      jj_consume_token(-1);
+      throw new ParseException();
+    }
+    throw new Error("Missing return statement in function");
+  }
+
+/**
+ * Parses a COLLATE clause
+ */
+  final public SqlCollation CollateClause() throws ParseException {
+    jj_consume_token(COLLATE);
+    jj_consume_token(COLLATION_ID);
+        {if (true) return new SqlCollation(
+            getToken(0).image, SqlCollation.Coercibility.EXPLICIT);}
+    throw new Error("Missing return statement in function");
+  }
+
+/**
+ * Numeric literal or parameter; used in LIMIT, OFFSET and FETCH clauses.
+ */
+  final public SqlNode UnsignedNumericLiteralOrParam() throws ParseException {
+    final SqlNode e;
+    if (jj_2_387(2)) {
+      e = UnsignedNumericLiteral();
+    } else if (jj_2_388(2)) {
+      e = DynamicParam();
+    } else {
+      jj_consume_token(-1);
+      throw new ParseException();
+    }
+      {if (true) return e;}
+    throw new Error("Missing return statement in function");
+  }
+
+/**
+ * Parses a row expression extension, it can be either an identifier,
+ * or a call to a named function.
+ */
+  final public SqlNode RowExpressionExtension() throws ParseException {
+    final SqlFunctionCategory funcType;
+    final SqlIdentifier p;
+    final Span s;
+    final List<SqlNode> args;
+    SqlCall call;
+    SqlNode e;
+    SqlLiteral quantifier = null;
+    p = SimpleIdentifier();
+        e = p;
+    if (jj_2_392(2147483647)) {
+                                s = span();
+            funcType = SqlFunctionCategory.USER_DEFINED_FUNCTION;
+      if (jj_2_389(2)) {
+        jj_consume_token(LPAREN);
+        jj_consume_token(STAR);
+                args = startList(SqlIdentifier.star(getPos()));
+        jj_consume_token(RPAREN);
+      } else if (jj_2_390(2)) {
+        jj_consume_token(LPAREN);
+        jj_consume_token(RPAREN);
+                args = Collections.emptyList();
+      } else if (jj_2_391(2)) {
+        args = FunctionParameterList(ExprContext.ACCEPT_SUB_QUERY);
+                quantifier = (SqlLiteral) args.get(0);
+                args.remove(0);
+      } else {
+        jj_consume_token(-1);
+        throw new ParseException();
+      }
+            call = createCall(p, s.end(this), funcType, quantifier, args);
+            e = call;
+    } else {
+      ;
+    }
+        {if (true) return e;}
+    throw new Error("Missing return statement in function");
+  }
+
+/**
+ * Parses a call to the STRING_AGG aggregate function (or to an aggregate
+ * function with similar syntax: ARRAY_AGG, ARRAY_CONCAT_AGG, GROUP_CONCAT).
+ */
+  final public SqlCall StringAggFunctionCall() throws ParseException {
+    final Span s, s2;
+    final SqlOperator op;
+    final List<SqlNode> args = new ArrayList();
+    final SqlLiteral qualifier;
+    final SqlNodeList orderBy;
+    final Pair<SqlParserPos, SqlOperator> nullTreatment;
+    final SqlNode separator;
+    if (jj_2_393(2)) {
+      jj_consume_token(ARRAY_AGG);
+                      s = span(); op = SqlLibraryOperators.ARRAY_AGG;
+    } else if (jj_2_394(2)) {
+      jj_consume_token(ARRAY_CONCAT_AGG);
+                             s = span(); op = SqlLibraryOperators.ARRAY_CONCAT_AGG;
+    } else if (jj_2_395(2)) {
+      jj_consume_token(GROUP_CONCAT);
+                         s = span(); op = SqlLibraryOperators.GROUP_CONCAT;
+    } else if (jj_2_396(2)) {
+      jj_consume_token(STRING_AGG);
+                       s = span(); op = SqlLibraryOperators.STRING_AGG;
+    } else {
+      jj_consume_token(-1);
+      throw new ParseException();
+    }
+    jj_consume_token(LPAREN);
+    if (jj_2_397(2)) {
+      qualifier = AllOrDistinct();
+    } else {
+          qualifier = null;
+    }
+    Arg(args, ExprContext.ACCEPT_SUB_QUERY);
+    label_39:
+    while (true) {
+      if (jj_2_398(2)) {
+        ;
+      } else {
+        break label_39;
+      }
+      jj_consume_token(COMMA);
+            // a comma-list can't appear where only a query is expected
+            checkNonQueryExpression(ExprContext.ACCEPT_SUB_QUERY);
+      Arg(args, ExprContext.ACCEPT_SUB_QUERY);
+    }
+    if (jj_2_399(2)) {
+      nullTreatment = NullTreatment();
+    } else {
+          nullTreatment = null;
+    }
+    if (jj_2_400(2)) {
+      orderBy = OrderBy(true);
+            args.add(orderBy);
+    } else {
+      ;
+    }
+    if (jj_2_401(2)) {
+      jj_consume_token(SEPARATOR);
+                      s2 = span();
+      separator = StringLiteral();
+            args.add(SqlInternalOperators.SEPARATOR.createCall(s2.end(this), separator));
+    } else {
+      ;
+    }
+    jj_consume_token(RPAREN);
+        SqlCall call = op.createCall(qualifier, s.end(this), args);
+        if (nullTreatment != null) {
+            // Wrap in RESPECT_NULLS or IGNORE_NULLS.
+            call = nullTreatment.right.createCall(nullTreatment.left, call);
+        }
+        {if (true) return call;}
+    throw new Error("Missing return statement in function");
+  }
+
+/**
+ * Parses an atomic row expression.
+ */
+  final public SqlNode AtomicRowExpression() throws ParseException {
+    final SqlNode e;
+    if (jj_2_402(2)) {
+      e = LiteralOrIntervalExpression();
+    } else if (jj_2_403(2)) {
+      e = DynamicParam();
+    } else if (jj_2_404(2)) {
+      e = BuiltinFunctionCall();
+    } else if (jj_2_405(2)) {
+      e = JdbcFunctionCall();
+    } else if (jj_2_406(2)) {
+      e = MultisetConstructor();
+    } else if (jj_2_407(2)) {
+      e = ArrayConstructor();
+    } else if (jj_2_408(3)) {
+      e = MapConstructor();
+    } else if (jj_2_409(2)) {
+      e = PeriodConstructor();
+    } else if (jj_2_410(2147483647)) {
+      e = NamedFunctionCall();
+    } else if (jj_2_411(2)) {
+      e = ContextVariable();
+    } else if (jj_2_412(2)) {
+      e = CompoundIdentifier();
+    } else if (jj_2_413(2)) {
+      e = NewSpecification();
+    } else if (jj_2_414(2)) {
+      e = CaseExpression();
+    } else if (jj_2_415(2)) {
+      e = SequenceExpression();
+    } else {
+      jj_consume_token(-1);
+      throw new ParseException();
+    }
+      {if (true) return e;}
+    throw new Error("Missing return statement in function");
+  }
+
+  final public SqlNode CaseExpression() throws ParseException {
+    final Span whenSpan = Span.of();
+    final Span thenSpan = Span.of();
+    final Span s;
+    SqlNode e;
+    SqlNode caseIdentifier = null;
+    SqlNode elseClause = null;
+    List<SqlNode> whenList = new ArrayList<SqlNode>();
+    List<SqlNode> thenList = new ArrayList<SqlNode>();
+    jj_consume_token(CASE);
+             s = span();
+    if (jj_2_416(2)) {
+      caseIdentifier = Expression(ExprContext.ACCEPT_SUB_QUERY);
+    } else {
+      ;
+    }
+    label_40:
+    while (true) {
+      jj_consume_token(WHEN);
+                 whenSpan.add(this);
+      e = ExpressionCommaList(s, ExprContext.ACCEPT_SUB_QUERY);
+            if (((SqlNodeList) e).size() == 1) {
+                e = ((SqlNodeList) e).get(0);
+            }
+            whenList.add(e);
+      jj_consume_token(THEN);
+                 thenSpan.add(this);
+      e = Expression(ExprContext.ACCEPT_SUB_QUERY);
+            thenList.add(e);
+      if (jj_2_417(2)) {
+        ;
+      } else {
+        break label_40;
+      }
+    }
+    if (jj_2_418(2)) {
+      jj_consume_token(ELSE);
+      elseClause = Expression(ExprContext.ACCEPT_SUB_QUERY);
+    } else {
+      ;
+    }
+    jj_consume_token(END);
+        {if (true) return SqlCase.createSwitched(s.end(this), caseIdentifier,
+            new SqlNodeList(whenList, whenSpan.addAll(whenList).pos()),
+            new SqlNodeList(thenList, thenSpan.addAll(thenList).pos()),
+            elseClause);}
+    throw new Error("Missing return statement in function");
+  }
+
+  final public SqlCall SequenceExpression() throws ParseException {
+    final Span s;
+    final SqlOperator f;
+    final SqlNode sequenceRef;
+    if (jj_2_419(2)) {
+      jj_consume_token(NEXT);
+                 f = SqlStdOperatorTable.NEXT_VALUE; s = span();
+    } else if (jj_2_420(3)) {
+      jj_consume_token(CURRENT);
+                    f = SqlStdOperatorTable.CURRENT_VALUE; s = span();
+    } else {
+      jj_consume_token(-1);
+      throw new ParseException();
+    }
+    jj_consume_token(VALUE);
+    jj_consume_token(FOR);
+    sequenceRef = CompoundIdentifier();
+        {if (true) return f.createCall(s.end(sequenceRef), sequenceRef);}
+    throw new Error("Missing return statement in function");
+  }
+
+/**
+ * Parses "SET &lt;NAME&gt; = VALUE" or "RESET &lt;NAME&gt;", without a leading
+ * "ALTER &lt;SCOPE&gt;".
+ */
+  final public SqlSetOption SqlSetOption(Span s, String scope) throws ParseException {
+    SqlIdentifier name;
+    final SqlNode val;
+    if (jj_2_426(2)) {
+      jj_consume_token(SET);
+            s.add(this);
+      name = CompoundIdentifier();
+      jj_consume_token(EQ);
+      if (jj_2_421(2)) {
+        val = Literal();
+      } else if (jj_2_422(2)) {
+        val = SimpleIdentifier();
+      } else if (jj_2_423(2)) {
+        jj_consume_token(ON);
+                // OFF is handled by SimpleIdentifier, ON handled here.
+                val = new SqlIdentifier(token.image.toUpperCase(Locale.ROOT),
+                    getPos());
+      } else {
+        jj_consume_token(-1);
+        throw new ParseException();
+      }
+            {if (true) return new SqlSetOption(s.end(val), scope, name, val);}
+    } else if (jj_2_427(2)) {
+      jj_consume_token(RESET);
+            s.add(this);
+      if (jj_2_424(2)) {
+        name = CompoundIdentifier();
+      } else if (jj_2_425(2)) {
+        jj_consume_token(ALL);
+                name = new SqlIdentifier(token.image.toUpperCase(Locale.ROOT),
+                    getPos());
+      } else {
+        jj_consume_token(-1);
+        throw new ParseException();
+      }
+            {if (true) return new SqlSetOption(s.end(name), scope, name, null);}
+    } else {
+      jj_consume_token(-1);
+      throw new ParseException();
+    }
+    throw new Error("Missing return statement in function");
+  }
+
+/**
+ * Parses an expression for setting or resetting an option in SQL, such as QUOTED_IDENTIFIERS,
+ * or explain plan level (physical/logical).
+ */
+  final public SqlAlter SqlAlter() throws ParseException {
+    final Span s;
+    final String scope;
+    final SqlAlter alterNode;
+    jj_consume_token(ALTER);
+              s = span();
+    scope = Scope();
+    alterNode = SqlSetOption(s, scope);
+        {if (true) return alterNode;}
+    throw new Error("Missing return statement in function");
+  }
+
+  final public String Scope() throws ParseException {
+    if (jj_2_428(2)) {
+      jj_consume_token(SYSTEM);
+    } else if (jj_2_429(2)) {
+      jj_consume_token(SESSION);
+    } else {
+      jj_consume_token(-1);
+      throw new ParseException();
+    }
+                               {if (true) return token.image.toUpperCase(Locale.ROOT);}
+    throw new Error("Missing return statement in function");
+  }
+
+/**
+ * Parses a CREATE statement.
+ */
+  final public SqlCreate SqlCreate() throws ParseException {
+    final Span s;
+    boolean replace = false;
+    final SqlCreate create;
+    jj_consume_token(CREATE);
+               s = span();
+    if (jj_2_430(2)) {
+      jj_consume_token(OR);
+      jj_consume_token(REPLACE);
+            replace = true;
+    } else {
+      ;
+    }
+    if (jj_2_431(2)) {
+      create = SqlCreateTable(s, replace);
+    } else if (jj_2_432(2)) {
+      create = SqlCreateIndex(s, replace);
+    } else if (jj_2_433(2)) {
+      create = SqlCreateUser(s, replace);
+    } else {
+      jj_consume_token(-1);
+      throw new ParseException();
+    }
+        {if (true) return create;}
+    throw new Error("Missing return statement in function");
+  }
+
+/**
+ * Parses a DROP statement.
+ */
+  final public SqlDrop SqlDrop() throws ParseException {
+    final Span s;
+    boolean replace = false;
+    final SqlDrop drop;
+    jj_consume_token(DROP);
+             s = span();
+    if (jj_2_434(2)) {
+      drop = SqlDropTable(s, replace);
+    } else if (jj_2_435(2)) {
+      drop = SqlDropIndex(s, replace);
+    } else if (jj_2_436(2)) {
+      drop = SqlDropUser(s, replace);
+    } else {
+      jj_consume_token(-1);
+      throw new ParseException();
+    }
+        {if (true) return drop;}
+    throw new Error("Missing return statement in function");
+  }
+
+/**
+ * Parses a literal expression, allowing continued string literals.
+ * Usually returns an SqlLiteral, but a continued string literal
+ * is an SqlCall expression, which concatenates 2 or more string
+ * literals; the validator reduces this.
+ *
+ * <p>If the context allows both literals and expressions,
+ * use {@link #LiteralOrIntervalExpression}, which requires less
+ * lookahead.
+ */
+  final public SqlNode Literal() throws ParseException {
+    SqlNode e;
+    if (jj_2_437(2)) {
+      e = NonIntervalLiteral();
+    } else if (jj_2_438(2)) {
+      e = IntervalLiteral();
+    } else {
+      jj_consume_token(-1);
+      throw new ParseException();
+    }
+      {if (true) return e;}
+    throw new Error("Missing return statement in function");
+  }
+
+/** Parses a literal that is not an interval literal. */
+  final public SqlNode NonIntervalLiteral() throws ParseException {
+    final SqlNode e;
+    if (jj_2_439(2)) {
+      e = NumericLiteral();
+    } else if (jj_2_440(2)) {
+      e = StringLiteral();
+    } else if (jj_2_441(2)) {
+      e = SpecialLiteral();
+    } else if (jj_2_442(2)) {
+      e = DateTimeLiteral();
+    } else {
+      jj_consume_token(-1);
+      throw new ParseException();
+    }
+        {if (true) return e;}
+    throw new Error("Missing return statement in function");
+  }
+
+/** Parses a literal or an interval expression.
+ *
+ * <p>We include them in the same production because it is difficult to
+ * distinguish interval literals from interval expression (both of which
+ * start with the {@code INTERVAL} keyword); this way, we can use less
+ * LOOKAHEAD. */
+  final public SqlNode LiteralOrIntervalExpression() throws ParseException {
+    final SqlNode e;
+    if (jj_2_443(2)) {
+      e = IntervalLiteralOrExpression();
+    } else if (jj_2_444(2)) {
+      e = NonIntervalLiteral();
+    } else {
+      jj_consume_token(-1);
+      throw new ParseException();
+    }
+      {if (true) return e;}
+    throw new Error("Missing return statement in function");
+  }
+
+/** Parses a unsigned numeric literal */
+  final public SqlNumericLiteral UnsignedNumericLiteral() throws ParseException {
+    if (jj_2_445(2)) {
+      jj_consume_token(UNSIGNED_INTEGER_LITERAL);
+        {if (true) return SqlLiteral.createExactNumeric(token.image, getPos());}
+    } else if (jj_2_446(2)) {
+      jj_consume_token(DECIMAL_NUMERIC_LITERAL);
+        {if (true) return SqlLiteral.createExactNumeric(token.image, getPos());}
+    } else if (jj_2_447(2)) {
+      jj_consume_token(APPROX_NUMERIC_LITERAL);
+        {if (true) return SqlLiteral.createApproxNumeric(token.image, getPos());}
+    } else {
+      jj_consume_token(-1);
+      throw new ParseException();
+    }
+    throw new Error("Missing return statement in function");
+  }
+
+/** Parses a numeric literal (can be signed) */
+  final public SqlLiteral NumericLiteral() throws ParseException {
+    final SqlNumericLiteral num;
+    final Span s;
+    if (jj_2_448(2)) {
+      jj_consume_token(PLUS);
+      num = UnsignedNumericLiteral();
+        {if (true) return num;}
+    } else if (jj_2_449(2)) {
+      jj_consume_token(MINUS);
+              s = span();
+      num = UnsignedNumericLiteral();
+        {if (true) return SqlLiteral.createNegative(num, s.end(this));}
+    } else if (jj_2_450(2)) {
+      num = UnsignedNumericLiteral();
+        {if (true) return num;}
+    } else {
+      jj_consume_token(-1);
+      throw new ParseException();
+    }
+    throw new Error("Missing return statement in function");
+  }
+
+/** Parse a special literal keyword */
+  final public SqlLiteral SpecialLiteral() throws ParseException {
+    if (jj_2_451(2)) {
+      jj_consume_token(TRUE);
+             {if (true) return SqlLiteral.createBoolean(true, getPos());}
+    } else if (jj_2_452(2)) {
+      jj_consume_token(FALSE);
+              {if (true) return SqlLiteral.createBoolean(false, getPos());}
+    } else if (jj_2_453(2)) {
+      jj_consume_token(UNKNOWN);
+                {if (true) return SqlLiteral.createUnknown(getPos());}
+    } else if (jj_2_454(2)) {
+      jj_consume_token(NULL);
+             {if (true) return SqlLiteral.createNull(getPos());}
+    } else {
+      jj_consume_token(-1);
+      throw new ParseException();
+    }
+    throw new Error("Missing return statement in function");
+  }
+
+/**
+ * Parses a string literal. The literal may be continued onto several
+ * lines.  For a simple literal, the result is an SqlLiteral.  For a continued
+ * literal, the result is an SqlCall expression, which concatenates 2 or more
+ * string literals; the validator reduces this.
+ *
+ * @see SqlLiteral#unchain(SqlNode)
+ * @see SqlLiteral#stringValue(SqlNode)
+ *
+ * @return a literal expression
+ */
+  final public SqlNode StringLiteral() throws ParseException {
+    String p;
+    int nfrags = 0;
+    List<SqlLiteral> frags = null;
+    char unicodeEscapeChar = 0;
+    String charSet = null;
+    SqlCharStringLiteral literal;
+    if (jj_2_459(2)) {
+      jj_consume_token(BINARY_STRING_LITERAL);
+        try {
+            p = SqlParserUtil.trim(token.image, "xX'");
+            frags = startList(SqlLiteral.createBinaryString(p, getPos()));
+            nfrags++;
+        } catch (NumberFormatException ex) {
+            {if (true) throw SqlUtil.newContextException(getPos(),
+                RESOURCE.illegalBinaryString(token.image));}
+        }
+      label_41:
+      while (true) {
+        switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+        case QUOTED_STRING:
+          ;
+          break;
+        default:
+          jj_la1[4] = jj_gen;
+          break label_41;
+        }
+        jj_consume_token(QUOTED_STRING);
+            try {
+                p = SqlParserUtil.trim(token.image, "'"); // no embedded quotes
+                frags.add(SqlLiteral.createBinaryString(p, getPos()));
+                nfrags++;
+            } catch (NumberFormatException ex) {
+                {if (true) throw SqlUtil.newContextException(getPos(),
+                    RESOURCE.illegalBinaryString(token.image));}
+            }
+      }
+        assert (nfrags > 0);
+        if (nfrags == 1) {
+            {if (true) return frags.get(0);} // just the head fragment
+        } else {
+            SqlParserPos pos2 = SqlParserPos.sum(frags);
+            {if (true) return SqlStdOperatorTable.LITERAL_CHAIN.createCall(pos2, frags);}
+        }
+    } else if (jj_2_460(2)) {
+      if (jj_2_455(2)) {
+        jj_consume_token(PREFIXED_STRING_LITERAL);
+          charSet = SqlParserUtil.getCharacterSet(token.image);
+      } else if (jj_2_456(2)) {
+        jj_consume_token(QUOTED_STRING);
+      } else if (jj_2_457(2)) {
+        jj_consume_token(UNICODE_STRING_LITERAL);
+            // TODO jvs 2-Feb-2009:  support the explicit specification of
+            // a character set for Unicode string literals, per SQL:2003
+            unicodeEscapeChar = BACKSLASH;
+            charSet = "UTF16";
+      } else {
+        jj_consume_token(-1);
+        throw new ParseException();
+      }
+        p = SqlParserUtil.parseString(token.image);
+        try {
+            literal = SqlLiteral.createCharString(p, charSet, getPos());
+        } catch (java.nio.charset.UnsupportedCharsetException e) {
+            {if (true) throw SqlUtil.newContextException(getPos(),
+                RESOURCE.unknownCharacterSet(charSet));}
+        }
+        frags = startList(literal);
+        nfrags++;
+      label_42:
+      while (true) {
+        switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+        case QUOTED_STRING:
+          ;
+          break;
+        default:
+          jj_la1[5] = jj_gen;
+          break label_42;
+        }
+        jj_consume_token(QUOTED_STRING);
+            p = SqlParserUtil.parseString(token.image);
+            try {
+                literal = SqlLiteral.createCharString(p, charSet, getPos());
+            } catch (java.nio.charset.UnsupportedCharsetException e) {
+                {if (true) throw SqlUtil.newContextException(getPos(),
+                    RESOURCE.unknownCharacterSet(charSet));}
+            }
+            frags.add(literal);
+            nfrags++;
+      }
+      if (jj_2_458(2)) {
+        jj_consume_token(UESCAPE);
+        jj_consume_token(QUOTED_STRING);
+            if (unicodeEscapeChar == 0) {
+                {if (true) throw SqlUtil.newContextException(getPos(),
+                    RESOURCE.unicodeEscapeUnexpected());}
+            }
+            String s = SqlParserUtil.parseString(token.image);
+            unicodeEscapeChar = SqlParserUtil.checkUnicodeEscapeChar(s);
+      } else {
+        ;
+      }
+        assert nfrags > 0;
+        if (nfrags == 1) {
+            // just the head fragment
+            SqlLiteral lit = (SqlLiteral) frags.get(0);
+            {if (true) return lit.unescapeUnicode(unicodeEscapeChar);}
+        } else {
+            SqlNode[] rands = (SqlNode[]) frags.toArray(new SqlNode[nfrags]);
+            for (int i = 0; i < rands.length; ++i) {
+                rands[i] = ((SqlLiteral) rands[i]).unescapeUnicode(
+                    unicodeEscapeChar);
+            }
+            SqlParserPos pos2 = SqlParserPos.sum(rands);
+            {if (true) return SqlStdOperatorTable.LITERAL_CHAIN.createCall(pos2, rands);}
+        }
+    } else if (jj_2_461(2)) {
+      jj_consume_token(BIG_QUERY_DOUBLE_QUOTED_STRING);
+        p = SqlParserUtil.stripQuotes(getToken(0).image, DQ, DQ, "\\\"",
+            Casing.UNCHANGED);
+        try {
+            {if (true) return SqlLiteral.createCharString(p, charSet, getPos());}
+        } catch (java.nio.charset.UnsupportedCharsetException e) {
+            {if (true) throw SqlUtil.newContextException(getPos(),
+                RESOURCE.unknownCharacterSet(charSet));}
+        }
+    } else if (jj_2_462(2)) {
+      jj_consume_token(BIG_QUERY_QUOTED_STRING);
+        p = SqlParserUtil.stripQuotes(getToken(0).image, "'", "'", "\\'",
+            Casing.UNCHANGED);
+        try {
+            {if (true) return SqlLiteral.createCharString(p, charSet, getPos());}
+        } catch (java.nio.charset.UnsupportedCharsetException e) {
+            {if (true) throw SqlUtil.newContextException(getPos(),
+                RESOURCE.unknownCharacterSet(charSet));}
+        }
+    } else {
+      jj_consume_token(-1);
+      throw new ParseException();
+    }
+    throw new Error("Missing return statement in function");
+  }
+
+/**
+ * Parses a date/time literal.
+ */
+  final public SqlLiteral DateTimeLiteral() throws ParseException {
+    final String  p;
+    final Span s;
+    if (jj_2_463(2)) {
+      jj_consume_token(LBRACE_D);
+      jj_consume_token(QUOTED_STRING);
+        p = token.image;
+      jj_consume_token(RBRACE);
+        {if (true) return SqlParserUtil.parseDateLiteral(p, getPos());}
+    } else if (jj_2_464(2)) {
+      jj_consume_token(LBRACE_T);
+      jj_consume_token(QUOTED_STRING);
+        p = token.image;
+      jj_consume_token(RBRACE);
+        {if (true) return SqlParserUtil.parseTimeLiteral(p, getPos());}
+    } else if (jj_2_465(2)) {
+      jj_consume_token(LBRACE_TS);
+                  s = span();
+      jj_consume_token(QUOTED_STRING);
+        p = token.image;
+      jj_consume_token(RBRACE);
+        {if (true) return SqlParserUtil.parseTimestampLiteral(p, s.end(this));}
+    } else if (jj_2_466(2)) {
+      jj_consume_token(DATE);
+             s = span();
+      jj_consume_token(QUOTED_STRING);
+        {if (true) return SqlParserUtil.parseDateLiteral(token.image, s.end(this));}
+    } else if (jj_2_467(2)) {
+      jj_consume_token(TIME);
+             s = span();
+      jj_consume_token(QUOTED_STRING);
+        {if (true) return SqlParserUtil.parseTimeLiteral(token.image, s.end(this));}
+    } else if (jj_2_468(2)) {
+      jj_consume_token(TIMESTAMP);
+                  s = span();
+      jj_consume_token(QUOTED_STRING);
+        {if (true) return SqlParserUtil.parseTimestampLiteral(token.image, s.end(this));}
+    } else {
+      jj_consume_token(-1);
+      throw new ParseException();
+    }
+    throw new Error("Missing return statement in function");
+  }
+
+/** Parses a MULTISET constructor */
+  final public SqlNode MultisetConstructor() throws ParseException {
+    List<SqlNode> args;
+    SqlNode e;
+    final Span s;
+    jj_consume_token(MULTISET);
+                 s = span();
+    if (jj_2_470(2)) {
+      jj_consume_token(LPAREN);
+      // by sub query "MULTISET(SELECT * FROM T)"
+              e = LeafQueryOrExpr(ExprContext.ACCEPT_QUERY);
+      jj_consume_token(RPAREN);
+            {if (true) return SqlStdOperatorTable.MULTISET_QUERY.createCall(
+                s.end(this), e);}
+    } else if (jj_2_471(2)) {
+      jj_consume_token(LBRACKET);
+      // TODO: do trigraph as well ??( ??)
+              e = Expression(ExprContext.ACCEPT_NON_QUERY);
+                                                       args = startList(e);
+      label_43:
+      while (true) {
+        if (jj_2_469(2)) {
+          ;
+        } else {
+          break label_43;
+        }
+        jj_consume_token(COMMA);
+        e = Expression(ExprContext.ACCEPT_NON_QUERY);
+                                                                   args.add(e);
+      }
+      jj_consume_token(RBRACKET);
+            {if (true) return SqlStdOperatorTable.MULTISET_VALUE.createCall(
+                s.end(this), args);}
+    } else {
+      jj_consume_token(-1);
+      throw new ParseException();
+    }
+    throw new Error("Missing return statement in function");
+  }
+
+/** Parses an ARRAY constructor */
+  final public SqlNode ArrayConstructor() throws ParseException {
+    SqlNodeList args;
+    SqlNode e;
+    final Span s;
+    jj_consume_token(ARRAY);
+              s = span();
+    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+    case LPAREN:
+      jj_consume_token(LPAREN);
+      // by sub query "MULTISET(SELECT * FROM T)"
+              e = LeafQueryOrExpr(ExprContext.ACCEPT_QUERY);
+      jj_consume_token(RPAREN);
+            {if (true) return SqlStdOperatorTable.ARRAY_QUERY.createCall(
+                s.end(this), e);}
+      break;
+    default:
+      jj_la1[6] = jj_gen;
+      if (jj_2_473(2)) {
+        jj_consume_token(LBRACKET);
+        if (jj_2_472(2)) {
+          args = ExpressionCommaList(s, ExprContext.ACCEPT_NON_QUERY);
+        } else {
+              args = SqlNodeList.EMPTY;
+        }
+        jj_consume_token(RBRACKET);
+            {if (true) return SqlStdOperatorTable.ARRAY_VALUE_CONSTRUCTOR.createCall(
+                s.end(this), args.getList());}
+      } else {
+        jj_consume_token(-1);
+        throw new ParseException();
+      }
+    }
+    throw new Error("Missing return statement in function");
+  }
+
+/** Parses a MAP constructor */
+  final public SqlNode MapConstructor() throws ParseException {
+    SqlNodeList args;
+    SqlNode e;
+    final Span s;
+    jj_consume_token(MAP);
+            s = span();
+    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+    case LPAREN:
+      jj_consume_token(LPAREN);
+      // by sub query "MAP (SELECT empno, deptno FROM emp)"
+              e = LeafQueryOrExpr(ExprContext.ACCEPT_QUERY);
+      jj_consume_token(RPAREN);
+            {if (true) return SqlStdOperatorTable.MAP_QUERY.createCall(
+                s.end(this), e);}
+      break;
+    default:
+      jj_la1[7] = jj_gen;
+      if (jj_2_475(2)) {
+        jj_consume_token(LBRACKET);
+        if (jj_2_474(2)) {
+          args = ExpressionCommaList(s, ExprContext.ACCEPT_NON_QUERY);
+        } else {
+              args = SqlNodeList.EMPTY;
+        }
+        jj_consume_token(RBRACKET);
+            {if (true) return SqlStdOperatorTable.MAP_VALUE_CONSTRUCTOR.createCall(
+                s.end(this), args.getList());}
+      } else {
+        jj_consume_token(-1);
+        throw new ParseException();
+      }
+    }
+    throw new Error("Missing return statement in function");
+  }
+
+/** Parses a PERIOD constructor */
+  final public SqlNode PeriodConstructor() throws ParseException {
+    final SqlNode e0, e1;
+    final Span s;
+    jj_consume_token(PERIOD);
+               s = span();
+    jj_consume_token(LPAREN);
+    e0 = Expression(ExprContext.ACCEPT_SUB_QUERY);
+    jj_consume_token(COMMA);
+    e1 = Expression(ExprContext.ACCEPT_SUB_QUERY);
+    jj_consume_token(RPAREN);
+        {if (true) return SqlStdOperatorTable.ROW.createCall(s.end(this), e0, e1);}
+    throw new Error("Missing return statement in function");
+  }
+
+/**
+ * Parses an interval literal.
+ */
+  final public SqlLiteral IntervalLiteral() throws ParseException {
+    final String p;
+    final SqlIntervalQualifier intervalQualifier;
+    int sign = 1;
+    final Span s;
+    jj_consume_token(INTERVAL);
+                 s = span();
+    if (jj_2_478(2)) {
+      if (jj_2_476(2)) {
+        jj_consume_token(MINUS);
+                  sign = -1;
+      } else if (jj_2_477(2)) {
+        jj_consume_token(PLUS);
+                 sign = 1;
+      } else {
+        jj_consume_token(-1);
+        throw new ParseException();
+      }
+    } else {
+      ;
+    }
+    jj_consume_token(QUOTED_STRING);
+                      p = token.image;
+    intervalQualifier = IntervalQualifier();
+        {if (true) return SqlParserUtil.parseIntervalLiteral(s.end(intervalQualifier),
+            sign, p, intervalQualifier);}
+    throw new Error("Missing return statement in function");
+  }
+
+/** Parses an interval literal (e.g. {@code INTERVAL '2:3' HOUR TO MINUTE})
+ * or an interval expression (e.g. {@code INTERVAL emp.empno MINUTE}
+ * or {@code INTERVAL 3 MONTHS}). */
+  final public SqlNode IntervalLiteralOrExpression() throws ParseException {
+    final String p;
+    final SqlIntervalQualifier intervalQualifier;
+    int sign = 1;
+    final Span s;
+    SqlNode e;
+    jj_consume_token(INTERVAL);
+                 s = span();
+    if (jj_2_481(2)) {
+      if (jj_2_479(2)) {
+        jj_consume_token(MINUS);
+                  sign = -1;
+      } else if (jj_2_480(2)) {
+        jj_consume_token(PLUS);
+                 sign = 1;
+      } else {
+        jj_consume_token(-1);
+        throw new ParseException();
+      }
+    } else {
+      ;
+    }
+    if (jj_2_485(2)) {
+      jj_consume_token(QUOTED_STRING);
+                          p = token.image;
+      intervalQualifier = IntervalQualifier();
+            {if (true) return SqlParserUtil.parseIntervalLiteral(s.end(intervalQualifier),
+                sign, p, intervalQualifier);}
+    } else if (jj_2_486(2)) {
+      if (jj_2_482(2)) {
+        jj_consume_token(LPAREN);
+        e = Expression(ExprContext.ACCEPT_SUB_QUERY);
+        jj_consume_token(RPAREN);
+      } else if (jj_2_483(2)) {
+        e = UnsignedNumericLiteral();
+      } else if (jj_2_484(2)) {
+        e = CompoundIdentifier();
+      } else {
+        jj_consume_token(-1);
+        throw new ParseException();
+      }
+      intervalQualifier = IntervalQualifierStart();
+            if (sign == -1) {
+                e = SqlStdOperatorTable.UNARY_MINUS.createCall(e.getParserPosition(), e);
+            }
+            {if (true) return SqlStdOperatorTable.INTERVAL.createCall(s.end(this), e,
+                intervalQualifier);}
+    } else {
+      jj_consume_token(-1);
+      throw new ParseException();
+    }
+    throw new Error("Missing return statement in function");
+  }
+
+  final public TimeUnit Year() throws ParseException {
+    if (jj_2_487(2)) {
+      jj_consume_token(YEAR);
+             {if (true) return TimeUnit.YEAR;}
+    } else if (jj_2_488(2)) {
+      jj_consume_token(YEARS);
+              {if (true) return warn(TimeUnit.YEAR);}
+    } else {
+      jj_consume_token(-1);
+      throw new ParseException();
+    }
+    throw new Error("Missing return statement in function");
+  }
+
+  final public TimeUnit Month() throws ParseException {
+    if (jj_2_489(2)) {
+      jj_consume_token(MONTH);
+              {if (true) return TimeUnit.MONTH;}
+    } else if (jj_2_490(2)) {
+      jj_consume_token(MONTHS);
+               {if (true) return warn(TimeUnit.MONTH);}
+    } else {
+      jj_consume_token(-1);
+      throw new ParseException();
+    }
+    throw new Error("Missing return statement in function");
+  }
+
+  final public TimeUnit Day() throws ParseException {
+    if (jj_2_491(2)) {
+      jj_consume_token(DAY);
+            {if (true) return TimeUnit.DAY;}
+    } else if (jj_2_492(2)) {
+      jj_consume_token(DAYS);
+             {if (true) return warn(TimeUnit.DAY);}
+    } else {
+      jj_consume_token(-1);
+      throw new ParseException();
+    }
+    throw new Error("Missing return statement in function");
+  }
+
+  final public TimeUnit Hour() throws ParseException {
+    if (jj_2_493(2)) {
+      jj_consume_token(HOUR);
+             {if (true) return TimeUnit.HOUR;}
+    } else if (jj_2_494(2)) {
+      jj_consume_token(HOURS);
+              {if (true) return warn(TimeUnit.HOUR);}
+    } else {
+      jj_consume_token(-1);
+      throw new ParseException();
+    }
+    throw new Error("Missing return statement in function");
+  }
+
+  final public TimeUnit Minute() throws ParseException {
+    if (jj_2_495(2)) {
+      jj_consume_token(MINUTE);
+               {if (true) return TimeUnit.MINUTE;}
+    } else if (jj_2_496(2)) {
+      jj_consume_token(MINUTES);
+                {if (true) return warn(TimeUnit.MINUTE);}
+    } else {
+      jj_consume_token(-1);
+      throw new ParseException();
+    }
+    throw new Error("Missing return statement in function");
+  }
+
+  final public TimeUnit Second() throws ParseException {
+    if (jj_2_497(2)) {
+      jj_consume_token(SECOND);
+               {if (true) return TimeUnit.SECOND;}
+    } else if (jj_2_498(2)) {
+      jj_consume_token(SECONDS);
+                {if (true) return warn(TimeUnit.SECOND);}
+    } else {
+      jj_consume_token(-1);
+      throw new ParseException();
+    }
+    throw new Error("Missing return statement in function");
+  }
+
+  final public SqlIntervalQualifier IntervalQualifier() throws ParseException {
+    final Span s;
+    final TimeUnit start;
+    TimeUnit end = null;
+    int startPrec = RelDataType.PRECISION_NOT_SPECIFIED;
+    int secondFracPrec = RelDataType.PRECISION_NOT_SPECIFIED;
+    if (jj_2_512(2)) {
+      start = Year();
+                         s = span();
+      startPrec = PrecisionOpt();
+      if (jj_2_499(2)) {
+        jj_consume_token(TO);
+        end = Month();
+      } else {
+        ;
+      }
+    } else if (jj_2_513(2)) {
+      start = Month();
+                          s = span();
+      startPrec = PrecisionOpt();
+    } else if (jj_2_514(2)) {
+      start = Day();
+                        s = span();
+      startPrec = PrecisionOpt();
+      if (jj_2_503(2)) {
+        jj_consume_token(TO);
+        if (jj_2_500(2)) {
+          end = Hour();
+        } else if (jj_2_501(2)) {
+          end = Minute();
+        } else if (jj_2_502(2)) {
+          end = Second();
+          secondFracPrec = PrecisionOpt();
+        } else {
+          jj_consume_token(-1);
+          throw new ParseException();
+        }
+      } else {
+        ;
+      }
+    } else if (jj_2_515(2)) {
+      start = Hour();
+                         s = span();
+      startPrec = PrecisionOpt();
+      if (jj_2_507(2)) {
+        jj_consume_token(TO);
+        if (jj_2_505(2)) {
+          end = Minute();
+        } else if (jj_2_506(2)) {
+          end = Second();
+          if (jj_2_504(2)) {
+            jj_consume_token(LPAREN);
+            secondFracPrec = UnsignedIntLiteral();
+            jj_consume_token(RPAREN);
+          } else {
+            ;
+          }
+        } else {
+          jj_consume_token(-1);
+          throw new ParseException();
+        }
+      } else {
+        ;
+      }
+    } else if (jj_2_516(2)) {
+      start = Minute();
+                           s = span();
+      startPrec = PrecisionOpt();
+      if (jj_2_509(2)) {
+        jj_consume_token(TO);
+        end = Second();
+        if (jj_2_508(2)) {
+          jj_consume_token(LPAREN);
+          secondFracPrec = UnsignedIntLiteral();
+          jj_consume_token(RPAREN);
+        } else {
+          ;
+        }
+      } else {
+        ;
+      }
+    } else if (jj_2_517(2)) {
+      start = Second();
+                           s = span();
+      if (jj_2_511(2)) {
+        jj_consume_token(LPAREN);
+        startPrec = UnsignedIntLiteral();
+        if (jj_2_510(2)) {
+          jj_consume_token(COMMA);
+          secondFracPrec = UnsignedIntLiteral();
+        } else {
+          ;
+        }
+        jj_consume_token(RPAREN);
+      } else {
+        ;
+      }
+    } else {
+      jj_consume_token(-1);
+      throw new ParseException();
+    }
+        {if (true) return new SqlIntervalQualifier(start, startPrec, end, secondFracPrec,
+            s.end(this));}
+    throw new Error("Missing return statement in function");
+  }
+
+/** Interval qualifier without 'TO unit'. */
+  final public SqlIntervalQualifier IntervalQualifierStart() throws ParseException {
+    final Span s;
+    final TimeUnit start;
+    int startPrec = RelDataType.PRECISION_NOT_SPECIFIED;
+    int secondFracPrec = RelDataType.PRECISION_NOT_SPECIFIED;
+    if (jj_2_525(2)) {
+      if (jj_2_518(2)) {
+        start = Year();
+      } else if (jj_2_519(2)) {
+        start = Month();
+      } else if (jj_2_520(2)) {
+        start = Day();
+      } else if (jj_2_521(2)) {
+        start = Hour();
+      } else if (jj_2_522(2)) {
+        start = Minute();
+      } else {
+        jj_consume_token(-1);
+        throw new ParseException();
+      }
+          s = span();
+      startPrec = PrecisionOpt();
+    } else if (jj_2_526(2)) {
+      start = Second();
+                           s = span();
+      if (jj_2_524(2)) {
+        jj_consume_token(LPAREN);
+        startPrec = UnsignedIntLiteral();
+        if (jj_2_523(2)) {
+          jj_consume_token(COMMA);
+          secondFracPrec = UnsignedIntLiteral();
+        } else {
+          ;
+        }
+        jj_consume_token(RPAREN);
+      } else {
+        ;
+      }
+    } else {
+      jj_consume_token(-1);
+      throw new ParseException();
+    }
+        {if (true) return new SqlIntervalQualifier(start, startPrec, null, secondFracPrec,
+            s.end(this));}
+    throw new Error("Missing return statement in function");
+  }
+
+/**
+ * Parses time unit for EXTRACT, CEIL and FLOOR functions.
+ * Note that it does't include NANOSECOND and MICROSECOND.
+ */
+  final public TimeUnit TimeUnit() throws ParseException {
+    if (jj_2_527(2)) {
+      jj_consume_token(MILLISECOND);
+                    {if (true) return TimeUnit.MILLISECOND;}
+    } else if (jj_2_528(2)) {
+      jj_consume_token(SECOND);
+               {if (true) return TimeUnit.SECOND;}
+    } else if (jj_2_529(2)) {
+      jj_consume_token(MINUTE);
+               {if (true) return TimeUnit.MINUTE;}
+    } else if (jj_2_530(2)) {
+      jj_consume_token(HOUR);
+             {if (true) return TimeUnit.HOUR;}
+    } else if (jj_2_531(2)) {
+      jj_consume_token(DAY);
+            {if (true) return TimeUnit.DAY;}
+    } else if (jj_2_532(2)) {
+      jj_consume_token(DOW);
+            {if (true) return TimeUnit.DOW;}
+    } else if (jj_2_533(2)) {
+      jj_consume_token(DOY);
+            {if (true) return TimeUnit.DOY;}
+    } else if (jj_2_534(2)) {
+      jj_consume_token(ISODOW);
+               {if (true) return TimeUnit.ISODOW;}
+    } else if (jj_2_535(2)) {
+      jj_consume_token(ISOYEAR);
+                {if (true) return TimeUnit.ISOYEAR;}
+    } else if (jj_2_536(2)) {
+      jj_consume_token(WEEK);
+             {if (true) return TimeUnit.WEEK;}
+    } else if (jj_2_537(2)) {
+      jj_consume_token(MONTH);
+              {if (true) return TimeUnit.MONTH;}
+    } else if (jj_2_538(2)) {
+      jj_consume_token(QUARTER);
+                {if (true) return TimeUnit.QUARTER;}
+    } else if (jj_2_539(2)) {
+      jj_consume_token(YEAR);
+             {if (true) return TimeUnit.YEAR;}
+    } else if (jj_2_540(2)) {
+      jj_consume_token(EPOCH);
+              {if (true) return TimeUnit.EPOCH;}
+    } else if (jj_2_541(2)) {
+      jj_consume_token(DECADE);
+               {if (true) return TimeUnit.DECADE;}
+    } else if (jj_2_542(2)) {
+      jj_consume_token(CENTURY);
+                {if (true) return TimeUnit.CENTURY;}
+    } else if (jj_2_543(2)) {
+      jj_consume_token(MILLENNIUM);
+                   {if (true) return TimeUnit.MILLENNIUM;}
+    } else {
+      jj_consume_token(-1);
+      throw new ParseException();
+    }
+    throw new Error("Missing return statement in function");
+  }
+
+  final public TimeUnit TimestampInterval() throws ParseException {
+    if (jj_2_544(2)) {
+      jj_consume_token(FRAC_SECOND);
+                    {if (true) return TimeUnit.MICROSECOND;}
+    } else if (jj_2_545(2)) {
+      jj_consume_token(MICROSECOND);
+                    {if (true) return TimeUnit.MICROSECOND;}
+    } else if (jj_2_546(2)) {
+      jj_consume_token(NANOSECOND);
+                   {if (true) return TimeUnit.NANOSECOND;}
+    } else if (jj_2_547(2)) {
+      jj_consume_token(SQL_TSI_FRAC_SECOND);
+                            {if (true) return TimeUnit.NANOSECOND;}
+    } else if (jj_2_548(2)) {
+      jj_consume_token(SQL_TSI_MICROSECOND);
+                            {if (true) return TimeUnit.MICROSECOND;}
+    } else if (jj_2_549(2)) {
+      jj_consume_token(SECOND);
+               {if (true) return TimeUnit.SECOND;}
+    } else if (jj_2_550(2)) {
+      jj_consume_token(SQL_TSI_SECOND);
+                       {if (true) return TimeUnit.SECOND;}
+    } else if (jj_2_551(2)) {
+      jj_consume_token(MINUTE);
+               {if (true) return TimeUnit.MINUTE;}
+    } else if (jj_2_552(2)) {
+      jj_consume_token(SQL_TSI_MINUTE);
+                       {if (true) return TimeUnit.MINUTE;}
+    } else if (jj_2_553(2)) {
+      jj_consume_token(HOUR);
+             {if (true) return TimeUnit.HOUR;}
+    } else if (jj_2_554(2)) {
+      jj_consume_token(SQL_TSI_HOUR);
+                     {if (true) return TimeUnit.HOUR;}
+    } else if (jj_2_555(2)) {
+      jj_consume_token(DAY);
+            {if (true) return TimeUnit.DAY;}
+    } else if (jj_2_556(2)) {
+      jj_consume_token(SQL_TSI_DAY);
+                    {if (true) return TimeUnit.DAY;}
+    } else if (jj_2_557(2)) {
+      jj_consume_token(WEEK);
+             {if (true) return TimeUnit.WEEK;}
+    } else if (jj_2_558(2)) {
+      jj_consume_token(SQL_TSI_WEEK);
+                     {if (true) return TimeUnit.WEEK;}
+    } else if (jj_2_559(2)) {
+      jj_consume_token(MONTH);
+              {if (true) return TimeUnit.MONTH;}
+    } else if (jj_2_560(2)) {
+      jj_consume_token(SQL_TSI_MONTH);
+                      {if (true) return TimeUnit.MONTH;}
+    } else if (jj_2_561(2)) {
+      jj_consume_token(QUARTER);
+                {if (true) return TimeUnit.QUARTER;}
+    } else if (jj_2_562(2)) {
+      jj_consume_token(SQL_TSI_QUARTER);
+                        {if (true) return TimeUnit.QUARTER;}
+    } else if (jj_2_563(2)) {
+      jj_consume_token(YEAR);
+             {if (true) return TimeUnit.YEAR;}
+    } else if (jj_2_564(2)) {
+      jj_consume_token(SQL_TSI_YEAR);
+                     {if (true) return TimeUnit.YEAR;}
+    } else {
+      jj_consume_token(-1);
+      throw new ParseException();
+    }
+    throw new Error("Missing return statement in function");
+  }
+
+/**
+ * Parses a dynamic parameter marker.
+ */
+  final public SqlDynamicParam DynamicParam() throws ParseException {
+    jj_consume_token(HOOK);
+        {if (true) return new SqlDynamicParam(nDynamicParams++, getPos());}
+    throw new Error("Missing return statement in function");
+  }
+
+/**
+ * Parses one segment of an identifier that may be composite.
+ *
+ * <p>Each time it reads an identifier it writes one element to each list;
+ * the entry in {@code positions} records its position and whether the
+ * segment was quoted.
+ */
+  final public void IdentifierSegment(List<String> names, List<SqlParserPos> positions) throws ParseException {
+    final String id;
+    char unicodeEscapeChar = BACKSLASH;
+    final SqlParserPos pos;
+    final Span span;
+    if (jj_2_566(2)) {
+      jj_consume_token(IDENTIFIER);
+            id = unquotedIdentifier();
+            pos = getPos();
+    } else if (jj_2_567(2)) {
+      jj_consume_token(HYPHENATED_IDENTIFIER);
+            id = unquotedIdentifier();
+            pos = getPos();
+    } else if (jj_2_568(2)) {
+      jj_consume_token(QUOTED_IDENTIFIER);
+            id = SqlParserUtil.stripQuotes(getToken(0).image, DQ, DQ, DQDQ,
+                quotedCasing);
+            pos = getPos().withQuoting(true);
+    } else if (jj_2_569(2)) {
+      jj_consume_token(BACK_QUOTED_IDENTIFIER);
+            id = SqlParserUtil.stripQuotes(getToken(0).image, "`", "`", "``",
+                quotedCasing);
+            pos = getPos().withQuoting(true);
+    } else if (jj_2_570(2)) {
+      jj_consume_token(BIG_QUERY_BACK_QUOTED_IDENTIFIER);
+            id = SqlParserUtil.stripQuotes(getToken(0).image, "`", "`", "\\`",
+                quotedCasing);
+            pos = getPos().withQuoting(true);
+    } else if (jj_2_571(2)) {
+      jj_consume_token(BRACKET_QUOTED_IDENTIFIER);
+            id = SqlParserUtil.stripQuotes(getToken(0).image, "[", "]", "]]",
+                quotedCasing);
+            pos = getPos().withQuoting(true);
+    } else if (jj_2_572(2)) {
+      jj_consume_token(UNICODE_QUOTED_IDENTIFIER);
+            span = span();
+            String image = getToken(0).image;
+            image = image.substring(image.indexOf('"'));
+            image = SqlParserUtil.stripQuotes(image, DQ, DQ, DQDQ, quotedCasing);
+      if (jj_2_565(2)) {
+        jj_consume_token(UESCAPE);
+        jj_consume_token(QUOTED_STRING);
+                String s = SqlParserUtil.parseString(token.image);
+                unicodeEscapeChar = SqlParserUtil.checkUnicodeEscapeChar(s);
+      } else {
+        ;
+      }
+            pos = span.end(this).withQuoting(true);
+            SqlLiteral lit = SqlLiteral.createCharString(image, "UTF16", pos);
+            lit = lit.unescapeUnicode(unicodeEscapeChar);
+            id = lit.toValue();
+    } else if (jj_2_573(2)) {
+      id = NonReservedKeyWord();
+            pos = getPos();
+    } else {
+      jj_consume_token(-1);
+      throw new ParseException();
+    }
+        if (id.length() > this.identifierMaxLength) {
+            {if (true) throw SqlUtil.newContextException(pos,
+                RESOURCE.identifierTooLong(id, this.identifierMaxLength));}
+        }
+        names.add(id);
+        if (positions != null) {
+            positions.add(pos);
+        }
+  }
+
+/** As {@link #IdentifierSegment} but part of a table name (for example,
+ * following {@code FROM}, {@code INSERT} or {@code UPDATE}).
+ *
+ * <p>In some dialects the lexical rules for table names are different from
+ * for other identifiers. For example, in BigQuery, table names may contain
+ * hyphens. */
+  final public void TableIdentifierSegment(List<String> names, List<SqlParserPos> positions) throws ParseException {
+    IdentifierSegment(names, positions);
+        final int n = names.size();
+        if (n > 0
+                && positions.size() == n
+                && names.get(n - 1).contains(".")
+                && positions.get(n - 1).isQuoted()
+                && this.conformance.splitQuotedTableName()) {
+            final String name = names.remove(n - 1);
+            final SqlParserPos pos = positions.remove(n - 1);
+            final String[] splitNames = name.split("\\.");
+            for (String splitName : splitNames) {
+                names.add(splitName);
+                positions.add(pos);
+            }
+        }
+  }
+
+/**
+ * Parses a simple identifier as a String.
+ */
+  final public String Identifier() throws ParseException {
+    final List<String> names = new ArrayList<String>();
+    IdentifierSegment(names, null);
+        {if (true) return names.get(0);}
+    throw new Error("Missing return statement in function");
+  }
+
+/**
+ * Parses a simple identifier as an SqlIdentifier.
+ */
+  final public SqlIdentifier SimpleIdentifier() throws ParseException {
+    final List<String> names = new ArrayList<String>();
+    final List<SqlParserPos> positions = new ArrayList<SqlParserPos>();
+    IdentifierSegment(names, positions);
+        {if (true) return new SqlIdentifier(names.get(0), positions.get(0));}
+    throw new Error("Missing return statement in function");
+  }
+
+/**
+ * Parses a character literal as an SqlIdentifier.
+ * Only valid for column aliases in certain dialects.
+ */
+  final public SqlIdentifier SimpleIdentifierFromStringLiteral() throws ParseException {
+    jj_consume_token(QUOTED_STRING);
+        if (!this.conformance.allowCharLiteralAlias()) {
+            {if (true) throw SqlUtil.newContextException(getPos(), RESOURCE.charLiteralAliasNotValid());}
+        }
+        final String s = SqlParserUtil.parseString(token.image);
+        {if (true) return new SqlIdentifier(s, getPos());}
+    throw new Error("Missing return statement in function");
+  }
+
+/**
+ * Parses a comma-separated list of simple identifiers.
+ */
+  final public void SimpleIdentifierCommaList(List<SqlNode> list) throws ParseException {
+    SqlIdentifier id;
+    id = SimpleIdentifier();
+                             list.add(id);
+    label_44:
+    while (true) {
+      if (jj_2_574(2)) {
+        ;
+      } else {
+        break label_44;
+      }
+      jj_consume_token(COMMA);
+      id = SimpleIdentifier();
+            list.add(id);
+    }
+  }
+
+/**
+  * List of simple identifiers in parentheses. The position extends from the
+  * open parenthesis to the close parenthesis.
+  */
+  final public SqlNodeList ParenthesizedSimpleIdentifierList() throws ParseException {
+    final Span s;
+    final List<SqlNode> list = new ArrayList<SqlNode>();
+    jj_consume_token(LPAREN);
+               s = span();
+    SimpleIdentifierCommaList(list);
+    jj_consume_token(RPAREN);
+        {if (true) return new SqlNodeList(list, s.end(this));}
+    throw new Error("Missing return statement in function");
+  }
+
+/** List of simple identifiers in parentheses or one simple identifier.
+ *
+ * <ul>Examples:
+ * <li>{@code DEPTNO}
+ * <li>{@code (EMPNO, DEPTNO)}
+ * </ul>
+ */
+  final public SqlNodeList SimpleIdentifierOrList() throws ParseException {
+    SqlIdentifier id;
+    SqlNodeList list;
+    if (jj_2_575(2)) {
+      id = SimpleIdentifier();
+        {if (true) return new SqlNodeList(Collections.singletonList(id), id.getParserPosition());}
+    } else if (jj_2_576(2)) {
+      list = ParenthesizedSimpleIdentifierList();
+        {if (true) return list;}
+    } else {
+      jj_consume_token(-1);
+      throw new ParseException();
+    }
+    throw new Error("Missing return statement in function");
+  }
+
+/**
+ * Parses a compound identifier.
+ */
+  final public SqlIdentifier CompoundIdentifier() throws ParseException {
+    final List<String> nameList = new ArrayList<String>();
+    final List<SqlParserPos> posList = new ArrayList<SqlParserPos>();
+    boolean star = false;
+    IdentifierSegment(nameList, posList);
+    label_45:
+    while (true) {
+      if (jj_2_577(2)) {
+        ;
+      } else {
+        break label_45;
+      }
+      jj_consume_token(DOT);
+      IdentifierSegment(nameList, posList);
+    }
+    if (jj_2_578(2)) {
+      jj_consume_token(DOT);
+      jj_consume_token(STAR);
+            star = true;
+            nameList.add("");
+            posList.add(getPos());
+    } else {
+      ;
+    }
+        SqlParserPos pos = SqlParserPos.sum(posList);
+        if (star) {
+            {if (true) return SqlIdentifier.star(nameList, pos, posList);}
+        }
+        {if (true) return new SqlIdentifier(nameList, null, pos, posList);}
+    throw new Error("Missing return statement in function");
+  }
+
+/**
+ * Parses a compound identifier in the FROM clause.
+ */
+  final public SqlIdentifier CompoundTableIdentifier() throws ParseException {
+    final List<String> nameList = new ArrayList<String>();
+    final List<SqlParserPos> posList = new ArrayList<SqlParserPos>();
+    TableIdentifierSegment(nameList, posList);
+    label_46:
+    while (true) {
+      if (jj_2_579(2)) {
+        ;
+      } else {
+        break label_46;
+      }
+      jj_consume_token(DOT);
+      TableIdentifierSegment(nameList, posList);
+    }
+        SqlParserPos pos = SqlParserPos.sum(posList);
+        {if (true) return new SqlIdentifier(nameList, null, pos, posList);}
+    throw new Error("Missing return statement in function");
+  }
+
+/**
+ * Parses a comma-separated list of compound identifiers.
+ */
+  final public void CompoundIdentifierTypeCommaList(List<SqlNode> list, List<SqlNode> extendList) throws ParseException {
+    CompoundIdentifierType(list, extendList);
+    label_47:
+    while (true) {
+      if (jj_2_580(2)) {
+        ;
+      } else {
+        break label_47;
+      }
+      jj_consume_token(COMMA);
+      CompoundIdentifierType(list, extendList);
+    }
+  }
+
+/**
+ * List of compound identifiers in parentheses. The position extends from the
+ * open parenthesis to the close parenthesis.
+ */
+  final public Pair<SqlNodeList, SqlNodeList> ParenthesizedCompoundIdentifierList() throws ParseException {
+    final Span s;
+    final List<SqlNode> list = new ArrayList<SqlNode>();
+    final List<SqlNode> extendList = new ArrayList<SqlNode>();
+    jj_consume_token(LPAREN);
+               s = span();
+    CompoundIdentifierTypeCommaList(list, extendList);
+    jj_consume_token(RPAREN);
+        {if (true) return Pair.of(new SqlNodeList(list, s.end(this)), new SqlNodeList(extendList, s.end(this)));}
+    throw new Error("Missing return statement in function");
+  }
+
+/**
+ * Parses a NEW UDT(...) expression.
+ */
+  final public SqlNode NewSpecification() throws ParseException {
+    final Span s;
+    final SqlNode routineCall;
+    jj_consume_token(NEW);
+            s = span();
+    routineCall = NamedRoutineCall(SqlFunctionCategory.USER_DEFINED_CONSTRUCTOR,
+                ExprContext.ACCEPT_SUB_QUERY);
+        {if (true) return SqlStdOperatorTable.NEW.createCall(s.end(routineCall), routineCall);}
+    throw new Error("Missing return statement in function");
+  }
+
+//TODO: real parse errors.
+  final public int UnsignedIntLiteral() throws ParseException {
+    Token t;
+    t = jj_consume_token(UNSIGNED_INTEGER_LITERAL);
+        try {
+            {if (true) return Integer.parseInt(t.image);}
+        } catch (NumberFormatException ex) {
+            {if (true) throw SqlUtil.newContextException(getPos(),
+                RESOURCE.invalidLiteral(t.image, Integer.class.getCanonicalName()));}
+        }
+    throw new Error("Missing return statement in function");
+  }
+
+  final public int IntLiteral() throws ParseException {
+    Token t;
+    if (jj_2_583(2)) {
+      if (jj_2_581(2)) {
+        t = jj_consume_token(UNSIGNED_INTEGER_LITERAL);
+      } else if (jj_2_582(2)) {
+        jj_consume_token(PLUS);
+        t = jj_consume_token(UNSIGNED_INTEGER_LITERAL);
+      } else {
+        jj_consume_token(-1);
+        throw new ParseException();
+      }
+        try {
+            {if (true) return Integer.parseInt(t.image);}
+        } catch (NumberFormatException ex) {
+            {if (true) throw SqlUtil.newContextException(getPos(),
+                RESOURCE.invalidLiteral(t.image, Integer.class.getCanonicalName()));}
+        }
+    } else if (jj_2_584(2)) {
+      jj_consume_token(MINUS);
+      t = jj_consume_token(UNSIGNED_INTEGER_LITERAL);
+        try {
+            {if (true) return -Integer.parseInt(t.image);}
+        } catch (NumberFormatException ex) {
+            {if (true) throw SqlUtil.newContextException(getPos(),
+                RESOURCE.invalidLiteral(t.image, Integer.class.getCanonicalName()));}
+        }
+    } else {
+      jj_consume_token(-1);
+      throw new ParseException();
+    }
+    throw new Error("Missing return statement in function");
+  }
+
+// Type name with optional scale and precision.
+  final public SqlDataTypeSpec DataType() throws ParseException {
+    SqlTypeNameSpec typeName;
+    final Span s;
+    typeName = TypeName();
+        s = Span.of(typeName.getParserPos());
+    label_48:
+    while (true) {
+      if (jj_2_585(2)) {
+        ;
+      } else {
+        break label_48;
+      }
+      typeName = CollectionsTypeName(typeName);
+    }
+        {if (true) return new SqlDataTypeSpec(typeName, s.add(typeName.getParserPos()).pos());}
+    throw new Error("Missing return statement in function");
+  }
+
+// Some SQL type names need special handling due to the fact that they have
+// spaces in them but are not quoted.
+  final public SqlTypeNameSpec TypeName() throws ParseException {
+    final SqlTypeNameSpec typeNameSpec;
+    final SqlIdentifier typeName;
+    final Span s = Span.of();
+    if (jj_2_586(2)) {
+      typeNameSpec = SqlTypeName(s);
+    } else if (jj_2_587(2)) {
+      typeNameSpec = RowTypeName();
+    } else if (jj_2_588(2)) {
+      typeName = CompoundIdentifier();
+            typeNameSpec = new SqlUserDefinedTypeNameSpec(typeName, s.end(this));
+    } else {
+      jj_consume_token(-1);
+      throw new ParseException();
+    }
+        {if (true) return typeNameSpec;}
+    throw new Error("Missing return statement in function");
+  }
+
+// Types used for JDBC and ODBC scalar conversion function
+  final public SqlTypeNameSpec SqlTypeName(Span s) throws ParseException {
+    final SqlTypeNameSpec sqlTypeNameSpec;
+    if (jj_2_589(2)) {
+      sqlTypeNameSpec = SqlTypeName1(s);
+    } else if (jj_2_590(2)) {
+      sqlTypeNameSpec = SqlTypeName2(s);
+    } else if (jj_2_591(2)) {
+      sqlTypeNameSpec = SqlTypeName3(s);
+    } else if (jj_2_592(2)) {
+      sqlTypeNameSpec = CharacterTypeName(s);
+    } else if (jj_2_593(2)) {
+      sqlTypeNameSpec = DateTimeTypeName();
+    } else {
+      jj_consume_token(-1);
+      throw new ParseException();
+    }
+        {if (true) return sqlTypeNameSpec;}
+    throw new Error("Missing return statement in function");
+  }
+
+// Parse sql type name that don't allow any extra specifications except the type name.
+// For extra specification, we mean precision, scale, charSet, etc.
+  final public SqlTypeNameSpec SqlTypeName1(Span s) throws ParseException {
+    final SqlTypeName sqlTypeName;
+    if (jj_2_597(2)) {
+      jj_consume_token(GEOMETRY);
+            if (!this.conformance.allowGeometry()) {
+                {if (true) throw SqlUtil.newContextException(getPos(), RESOURCE.geometryDisabled());}
+            }
+            s.add(this);
+            sqlTypeName = SqlTypeName.GEOMETRY;
+    } else if (jj_2_598(2)) {
+      jj_consume_token(BOOLEAN);
+                    s.add(this); sqlTypeName = SqlTypeName.BOOLEAN;
+    } else if (jj_2_599(2)) {
+      if (jj_2_594(2)) {
+        jj_consume_token(INTEGER);
+      } else if (jj_2_595(2)) {
+        jj_consume_token(INT);
+      } else {
+        jj_consume_token(-1);
+        throw new ParseException();
+      }
+                                s.add(this); sqlTypeName = SqlTypeName.INTEGER;
+    } else if (jj_2_600(2)) {
+      jj_consume_token(TINYINT);
+                    s.add(this); sqlTypeName = SqlTypeName.TINYINT;
+    } else if (jj_2_601(2)) {
+      jj_consume_token(SMALLINT);
+                     s.add(this); sqlTypeName = SqlTypeName.SMALLINT;
+    } else if (jj_2_602(2)) {
+      jj_consume_token(BIGINT);
+                   s.add(this); sqlTypeName = SqlTypeName.BIGINT;
+    } else if (jj_2_603(2)) {
+      jj_consume_token(REAL);
+                 s.add(this); sqlTypeName = SqlTypeName.REAL;
+    } else if (jj_2_604(2)) {
+      jj_consume_token(DOUBLE);
+                   s.add(this);
+      if (jj_2_596(2)) {
+        jj_consume_token(PRECISION);
+      } else {
+        ;
+      }
+                          sqlTypeName = SqlTypeName.DOUBLE;
+    } else if (jj_2_605(2)) {
+      jj_consume_token(FLOAT);
+                  s.add(this); sqlTypeName = SqlTypeName.FLOAT;
+    } else {
+      jj_consume_token(-1);
+      throw new ParseException();
+    }
+        {if (true) return new SqlBasicTypeNameSpec(sqlTypeName, s.end(this));}
+    throw new Error("Missing return statement in function");
+  }
+
+// Parse sql type name that allows precision specification.
+  final public SqlTypeNameSpec SqlTypeName2(Span s) throws ParseException {
+    final SqlTypeName sqlTypeName;
+    int precision = -1;
+    if (jj_2_607(2)) {
+      jj_consume_token(BINARY);
+                   s.add(this);
+      if (jj_2_606(2)) {
+        jj_consume_token(VARYING);
+                        sqlTypeName = SqlTypeName.VARBINARY;
+      } else {
+              sqlTypeName = SqlTypeName.BINARY;
+      }
+    } else if (jj_2_608(2)) {
+      jj_consume_token(VARBINARY);
+                      s.add(this); sqlTypeName = SqlTypeName.VARBINARY;
+    } else {
+      jj_consume_token(-1);
+      throw new ParseException();
+    }
+    precision = PrecisionOpt();
+        {if (true) return new SqlBasicTypeNameSpec(sqlTypeName, precision, s.end(this));}
+    throw new Error("Missing return statement in function");
+  }
+
+// Parse sql type name that allows precision and scale specifications.
+  final public SqlTypeNameSpec SqlTypeName3(Span s) throws ParseException {
+    final SqlTypeName sqlTypeName;
+    int precision = -1;
+    int scale = -1;
+    if (jj_2_612(2)) {
+      if (jj_2_609(2)) {
+        jj_consume_token(DECIMAL);
+      } else if (jj_2_610(2)) {
+        jj_consume_token(DEC);
+      } else if (jj_2_611(2)) {
+        jj_consume_token(NUMERIC);
+      } else {
+        jj_consume_token(-1);
+        throw new ParseException();
+      }
+                                          s.add(this); sqlTypeName = SqlTypeName.DECIMAL;
+    } else if (jj_2_613(2)) {
+      jj_consume_token(ANY);
+                s.add(this); sqlTypeName = SqlTypeName.ANY;
+    } else {
+      jj_consume_token(-1);
+      throw new ParseException();
+    }
+    if (jj_2_615(2)) {
+      jj_consume_token(LPAREN);
+      precision = UnsignedIntLiteral();
+      if (jj_2_614(2)) {
+        jj_consume_token(COMMA);
+        scale = UnsignedIntLiteral();
+      } else {
+        ;
+      }
+      jj_consume_token(RPAREN);
+    } else {
+      ;
+    }
+        {if (true) return new SqlBasicTypeNameSpec(sqlTypeName, precision, scale, s.end(this));}
+    throw new Error("Missing return statement in function");
+  }
+
+// Types used for for JDBC and ODBC scalar conversion function
+  final public SqlJdbcDataTypeName JdbcOdbcDataTypeName() throws ParseException {
+    if (jj_2_650(2)) {
+      if (jj_2_616(2)) {
+        jj_consume_token(SQL_CHAR);
+      } else if (jj_2_617(2)) {
+        jj_consume_token(CHAR);
+      } else {
+        jj_consume_token(-1);
+        throw new ParseException();
+      }
+                            {if (true) return SqlJdbcDataTypeName.SQL_CHAR;}
+    } else if (jj_2_651(2)) {
+      if (jj_2_618(2)) {
+        jj_consume_token(SQL_VARCHAR);
+      } else if (jj_2_619(2)) {
+        jj_consume_token(VARCHAR);
+      } else {
+        jj_consume_token(-1);
+        throw new ParseException();
+      }
+                                  {if (true) return SqlJdbcDataTypeName.SQL_VARCHAR;}
+    } else if (jj_2_652(2)) {
+      if (jj_2_620(2)) {
+        jj_consume_token(SQL_DATE);
+      } else if (jj_2_621(2)) {
+        jj_consume_token(DATE);
+      } else {
+        jj_consume_token(-1);
+        throw new ParseException();
+      }
+                            {if (true) return SqlJdbcDataTypeName.SQL_DATE;}
+    } else if (jj_2_653(2)) {
+      if (jj_2_622(2)) {
+        jj_consume_token(SQL_TIME);
+      } else if (jj_2_623(2)) {
+        jj_consume_token(TIME);
+      } else {
+        jj_consume_token(-1);
+        throw new ParseException();
+      }
+                            {if (true) return SqlJdbcDataTypeName.SQL_TIME;}
+    } else if (jj_2_654(2)) {
+      if (jj_2_624(2)) {
+        jj_consume_token(SQL_TIMESTAMP);
+      } else if (jj_2_625(2)) {
+        jj_consume_token(TIMESTAMP);
+      } else {
+        jj_consume_token(-1);
+        throw new ParseException();
+      }
+                                      {if (true) return SqlJdbcDataTypeName.SQL_TIMESTAMP;}
+    } else if (jj_2_655(2)) {
+      if (jj_2_626(2)) {
+        jj_consume_token(SQL_DECIMAL);
+      } else if (jj_2_627(2)) {
+        jj_consume_token(DECIMAL);
+      } else {
+        jj_consume_token(-1);
+        throw new ParseException();
+      }
+                                  {if (true) return SqlJdbcDataTypeName.SQL_DECIMAL;}
+    } else if (jj_2_656(2)) {
+      if (jj_2_628(2)) {
+        jj_consume_token(SQL_NUMERIC);
+      } else if (jj_2_629(2)) {
+        jj_consume_token(NUMERIC);
+      } else {
+        jj_consume_token(-1);
+        throw new ParseException();
+      }
+                                  {if (true) return SqlJdbcDataTypeName.SQL_NUMERIC;}
+    } else if (jj_2_657(2)) {
+      if (jj_2_630(2)) {
+        jj_consume_token(SQL_BOOLEAN);
+      } else if (jj_2_631(2)) {
+        jj_consume_token(BOOLEAN);
+      } else {
+        jj_consume_token(-1);
+        throw new ParseException();
+      }
+                                  {if (true) return SqlJdbcDataTypeName.SQL_BOOLEAN;}
+    } else if (jj_2_658(2)) {
+      if (jj_2_632(2)) {
+        jj_consume_token(SQL_INTEGER);
+      } else if (jj_2_633(2)) {
+        jj_consume_token(INTEGER);
+      } else {
+        jj_consume_token(-1);
+        throw new ParseException();
+      }
+                                  {if (true) return SqlJdbcDataTypeName.SQL_INTEGER;}
+    } else if (jj_2_659(2)) {
+      if (jj_2_634(2)) {
+        jj_consume_token(SQL_BINARY);
+      } else if (jj_2_635(2)) {
+        jj_consume_token(BINARY);
+      } else {
+        jj_consume_token(-1);
+        throw new ParseException();
+      }
+                                {if (true) return SqlJdbcDataTypeName.SQL_BINARY;}
+    } else if (jj_2_660(2)) {
+      if (jj_2_636(2)) {
+        jj_consume_token(SQL_VARBINARY);
+      } else if (jj_2_637(2)) {
+        jj_consume_token(VARBINARY);
+      } else {
+        jj_consume_token(-1);
+        throw new ParseException();
+      }
+                                      {if (true) return SqlJdbcDataTypeName.SQL_VARBINARY;}
+    } else if (jj_2_661(2)) {
+      if (jj_2_638(2)) {
+        jj_consume_token(SQL_TINYINT);
+      } else if (jj_2_639(2)) {
+        jj_consume_token(TINYINT);
+      } else {
+        jj_consume_token(-1);
+        throw new ParseException();
+      }
+                                  {if (true) return SqlJdbcDataTypeName.SQL_TINYINT;}
+    } else if (jj_2_662(2)) {
+      if (jj_2_640(2)) {
+        jj_consume_token(SQL_SMALLINT);
+      } else if (jj_2_641(2)) {
+        jj_consume_token(SMALLINT);
+      } else {
+        jj_consume_token(-1);
+        throw new ParseException();
+      }
+                                    {if (true) return SqlJdbcDataTypeName.SQL_SMALLINT;}
+    } else if (jj_2_663(2)) {
+      if (jj_2_642(2)) {
+        jj_consume_token(SQL_BIGINT);
+      } else if (jj_2_643(2)) {
+        jj_consume_token(BIGINT);
+      } else {
+        jj_consume_token(-1);
+        throw new ParseException();
+      }
+                                {if (true) return SqlJdbcDataTypeName.SQL_BIGINT;}
+    } else if (jj_2_664(2)) {
+      if (jj_2_644(2)) {
+        jj_consume_token(SQL_REAL);
+      } else if (jj_2_645(2)) {
+        jj_consume_token(REAL);
+      } else {
+        jj_consume_token(-1);
+        throw new ParseException();
+      }
+                           {if (true) return SqlJdbcDataTypeName.SQL_REAL;}
+    } else if (jj_2_665(2)) {
+      if (jj_2_646(2)) {
+        jj_consume_token(SQL_DOUBLE);
+      } else if (jj_2_647(2)) {
+        jj_consume_token(DOUBLE);
+      } else {
+        jj_consume_token(-1);
+        throw new ParseException();
+      }
+                                {if (true) return SqlJdbcDataTypeName.SQL_DOUBLE;}
+    } else if (jj_2_666(2)) {
+      if (jj_2_648(2)) {
+        jj_consume_token(SQL_FLOAT);
+      } else if (jj_2_649(2)) {
+        jj_consume_token(FLOAT);
+      } else {
+        jj_consume_token(-1);
+        throw new ParseException();
+      }
+                              {if (true) return SqlJdbcDataTypeName.SQL_FLOAT;}
+    } else if (jj_2_667(2)) {
+      jj_consume_token(SQL_INTERVAL_YEAR);
+                          {if (true) return SqlJdbcDataTypeName.SQL_INTERVAL_YEAR;}
+    } else if (jj_2_668(2)) {
+      jj_consume_token(SQL_INTERVAL_YEAR_TO_MONTH);
+                                   {if (true) return SqlJdbcDataTypeName.SQL_INTERVAL_YEAR_TO_MONTH;}
+    } else if (jj_2_669(2)) {
+      jj_consume_token(SQL_INTERVAL_MONTH);
+                           {if (true) return SqlJdbcDataTypeName.SQL_INTERVAL_MONTH;}
+    } else if (jj_2_670(2)) {
+      jj_consume_token(SQL_INTERVAL_DAY);
+                         {if (true) return SqlJdbcDataTypeName.SQL_INTERVAL_DAY;}
+    } else if (jj_2_671(2)) {
+      jj_consume_token(SQL_INTERVAL_DAY_TO_HOUR);
+                                 {if (true) return SqlJdbcDataTypeName.SQL_INTERVAL_DAY_TO_HOUR;}
+    } else if (jj_2_672(2)) {
+      jj_consume_token(SQL_INTERVAL_DAY_TO_MINUTE);
+                                   {if (true) return SqlJdbcDataTypeName.SQL_INTERVAL_DAY_TO_MINUTE;}
+    } else if (jj_2_673(2)) {
+      jj_consume_token(SQL_INTERVAL_DAY_TO_SECOND);
+                                   {if (true) return SqlJdbcDataTypeName.SQL_INTERVAL_DAY_TO_SECOND;}
+    } else if (jj_2_674(2)) {
+      jj_consume_token(SQL_INTERVAL_HOUR);
+                          {if (true) return SqlJdbcDataTypeName.SQL_INTERVAL_HOUR;}
+    } else if (jj_2_675(2)) {
+      jj_consume_token(SQL_INTERVAL_HOUR_TO_MINUTE);
+                                    {if (true) return SqlJdbcDataTypeName.SQL_INTERVAL_HOUR_TO_MINUTE;}
+    } else if (jj_2_676(2)) {
+      jj_consume_token(SQL_INTERVAL_HOUR_TO_SECOND);
+                                    {if (true) return SqlJdbcDataTypeName.SQL_INTERVAL_HOUR_TO_SECOND;}
+    } else if (jj_2_677(2)) {
+      jj_consume_token(SQL_INTERVAL_MINUTE);
+                            {if (true) return SqlJdbcDataTypeName.SQL_INTERVAL_MINUTE;}
+    } else if (jj_2_678(2)) {
+      jj_consume_token(SQL_INTERVAL_MINUTE_TO_SECOND);
+                                      {if (true) return SqlJdbcDataTypeName.SQL_INTERVAL_MINUTE_TO_SECOND;}
+    } else if (jj_2_679(2)) {
+      jj_consume_token(SQL_INTERVAL_SECOND);
+                            {if (true) return SqlJdbcDataTypeName.SQL_INTERVAL_SECOND;}
+    } else {
+      jj_consume_token(-1);
+      throw new ParseException();
+    }
+    throw new Error("Missing return statement in function");
+  }
+
+  final public SqlLiteral JdbcOdbcDataType() throws ParseException {
+    SqlJdbcDataTypeName typeName;
+    typeName = JdbcOdbcDataTypeName();
+        {if (true) return typeName.symbol(getPos());}
+    throw new Error("Missing return statement in function");
+  }
+
+/**
+* Parse a collection type name, the input element type name may
+* also be a collection type.
+*/
+  final public SqlTypeNameSpec CollectionsTypeName(SqlTypeNameSpec elementTypeName) throws ParseException {
+    final SqlTypeName collectionTypeName;
+    if (jj_2_680(2)) {
+      jj_consume_token(MULTISET);
+                     collectionTypeName = SqlTypeName.MULTISET;
+    } else if (jj_2_681(2)) {
+      jj_consume_token(ARRAY);
+                  collectionTypeName = SqlTypeName.ARRAY;
+    } else {
+      jj_consume_token(-1);
+      throw new ParseException();
+    }
+        {if (true) return new SqlCollectionTypeNameSpec(elementTypeName,
+                collectionTypeName, getPos());}
+    throw new Error("Missing return statement in function");
+  }
+
+/**
+* Parse a nullable option, default is true.
+*/
+  final public boolean NullableOptDefaultTrue() throws ParseException {
+    if (jj_2_682(2)) {
+      jj_consume_token(NULL);
+             {if (true) return true;}
+    } else if (jj_2_683(2)) {
+      jj_consume_token(NOT);
+      jj_consume_token(NULL);
+                   {if (true) return false;}
+    } else {
+      {if (true) return true;}
+    }
+    throw new Error("Missing return statement in function");
+  }
+
+/**
+* Parse a nullable option, default is false.
+*/
+  final public boolean NullableOptDefaultFalse() throws ParseException {
+    if (jj_2_684(2)) {
+      jj_consume_token(NULL);
+             {if (true) return true;}
+    } else if (jj_2_685(2)) {
+      jj_consume_token(NOT);
+      jj_consume_token(NULL);
+                   {if (true) return false;}
+    } else {
+      {if (true) return false;}
+    }
+    throw new Error("Missing return statement in function");
+  }
+
+/**
+* Parse a "name1 type1 [NULL | NOT NULL], name2 type2 [NULL | NOT NULL] ..." list,
+* the field type default is not nullable.
+*/
+  final public void FieldNameTypeCommaList(List<SqlIdentifier> fieldNames,
+        List<SqlDataTypeSpec> fieldTypes) throws ParseException {
+    SqlIdentifier fName;
+    SqlDataTypeSpec fType;
+    boolean nullable;
+    fName = SimpleIdentifier();
+    fType = DataType();
+    nullable = NullableOptDefaultFalse();
+        fieldNames.add(fName);
+        fieldTypes.add(fType.withNullable(nullable, getPos()));
+    label_49:
+    while (true) {
+      if (jj_2_686(2)) {
+        ;
+      } else {
+        break label_49;
+      }
+      jj_consume_token(COMMA);
+      fName = SimpleIdentifier();
+      fType = DataType();
+      nullable = NullableOptDefaultFalse();
+            fieldNames.add(fName);
+            fieldTypes.add(fType.withNullable(nullable, getPos()));
+    }
+  }
+
+/**
+* Parse Row type with format: Row(name1 type1, name2 type2).
+* Every field type can have suffix of `NULL` or `NOT NULL` to indicate if this type is nullable.
+* i.e. Row(f0 int not null, f1 varchar null).
+*/
+  final public SqlTypeNameSpec RowTypeName() throws ParseException {
+    List<SqlIdentifier> fieldNames = new ArrayList<SqlIdentifier>();
+    List<SqlDataTypeSpec> fieldTypes = new ArrayList<SqlDataTypeSpec>();
+    jj_consume_token(ROW);
+    jj_consume_token(LPAREN);
+    FieldNameTypeCommaList(fieldNames, fieldTypes);
+    jj_consume_token(RPAREN);
+        {if (true) return new SqlRowTypeNameSpec(getPos(), fieldNames, fieldTypes);}
+    throw new Error("Missing return statement in function");
+  }
+
+/**
+* Parse character types: char, varchar.
+*/
+  final public SqlTypeNameSpec CharacterTypeName(Span s) throws ParseException {
+    int precision = -1;
+    final SqlTypeName sqlTypeName;
+    String charSetName = null;
+    if (jj_2_690(2)) {
+      if (jj_2_687(2)) {
+        jj_consume_token(CHARACTER);
+      } else if (jj_2_688(2)) {
+        jj_consume_token(CHAR);
+      } else {
+        jj_consume_token(-1);
+        throw new ParseException();
+      }
+                                 s.add(this);
+      if (jj_2_689(2)) {
+        jj_consume_token(VARYING);
+                        sqlTypeName = SqlTypeName.VARCHAR;
+      } else {
+              sqlTypeName = SqlTypeName.CHAR;
+      }
+    } else if (jj_2_691(2)) {
+      jj_consume_token(VARCHAR);
+                    s.add(this); sqlTypeName = SqlTypeName.VARCHAR;
+    } else {
+      jj_consume_token(-1);
+      throw new ParseException();
+    }
+    precision = PrecisionOpt();
+    if (jj_2_692(2)) {
+      jj_consume_token(CHARACTER);
+      jj_consume_token(SET);
+      charSetName = Identifier();
+    } else {
+      ;
+    }
+        {if (true) return new SqlBasicTypeNameSpec(sqlTypeName, precision, charSetName, s.end(this));}
+    throw new Error("Missing return statement in function");
+  }
+
+/**
+* Parse datetime types: date, time, timestamp.
+*/
+  final public SqlTypeNameSpec DateTimeTypeName() throws ParseException {
+    int precision = -1;
+    SqlTypeName typeName;
+    boolean withLocalTimeZone = false;
+    final Span s;
+    if (jj_2_693(2)) {
+      jj_consume_token(DATE);
+        typeName = SqlTypeName.DATE;
+        {if (true) return new SqlBasicTypeNameSpec(typeName, getPos());}
+    } else if (jj_2_694(2)) {
+      jj_consume_token(TIME);
+             s = span();
+      precision = PrecisionOpt();
+      withLocalTimeZone = TimeZoneOpt();
+        if (withLocalTimeZone) {
+            typeName = SqlTypeName.TIME_WITH_LOCAL_TIME_ZONE;
+        } else {
+            typeName = SqlTypeName.TIME;
+        }
+        {if (true) return new SqlBasicTypeNameSpec(typeName, precision, s.end(this));}
+    } else if (jj_2_695(2)) {
+      jj_consume_token(TIMESTAMP);
+                  s = span();
+      precision = PrecisionOpt();
+      withLocalTimeZone = TimeZoneOpt();
+        if (withLocalTimeZone) {
+            typeName = SqlTypeName.TIMESTAMP_WITH_LOCAL_TIME_ZONE;
+        } else {
+            typeName = SqlTypeName.TIMESTAMP;
+        }
+        {if (true) return new SqlBasicTypeNameSpec(typeName, precision, s.end(this));}
+    } else {
+      jj_consume_token(-1);
+      throw new ParseException();
+    }
+    throw new Error("Missing return statement in function");
+  }
+
+// Parse an optional data type precision, default is -1.
+  final public int PrecisionOpt() throws ParseException {
+    int precision = -1;
+    if (jj_2_696(2)) {
+      jj_consume_token(LPAREN);
+      precision = UnsignedIntLiteral();
+      jj_consume_token(RPAREN);
+      {if (true) return precision;}
+    } else {
+      {if (true) return -1;}
+    }
+    throw new Error("Missing return statement in function");
+  }
+
+/**
+* Parse a time zone suffix for DateTime types. According to SQL-2011,
+* "with time zone" and "without time zone" belong to standard SQL but we
+* only implement the "without time zone".
+*
+* <p>We also support "with local time zone".
+*
+* @return true if this is "with local time zone".
+*/
+  final public boolean TimeZoneOpt() throws ParseException {
+    if (jj_2_697(3)) {
+      jj_consume_token(WITHOUT);
+      jj_consume_token(TIME);
+      jj_consume_token(ZONE);
+                              {if (true) return false;}
+    } else if (jj_2_698(2)) {
+      jj_consume_token(WITH);
+      jj_consume_token(LOCAL);
+      jj_consume_token(TIME);
+      jj_consume_token(ZONE);
+                                   {if (true) return true;}
+    } else {
+      {if (true) return false;}
+    }
+    throw new Error("Missing return statement in function");
+  }
+
+/**
+ * Parses a CURSOR(query) expression.  The parser allows these
+ * anywhere, but the validator restricts them to appear only as
+ * arguments to table functions.
+ */
+  final public SqlNode CursorExpression(ExprContext exprContext) throws ParseException {
+    final SqlNode e;
+    final Span s;
+    jj_consume_token(CURSOR);
+        s = span();
+        if (exprContext != ExprContext.ACCEPT_ALL
+                && exprContext != ExprContext.ACCEPT_CURSOR) {
+            {if (true) throw SqlUtil.newContextException(s.end(this),
+                RESOURCE.illegalCursorExpression());}
+        }
+    e = Expression(ExprContext.ACCEPT_QUERY);
+        {if (true) return SqlStdOperatorTable.CURSOR.createCall(s.end(e), e);}
+    throw new Error("Missing return statement in function");
+  }
+
+/**
+ * Parses a call to a builtin function with special syntax.
+ */
+  final public SqlNode BuiltinFunctionCall() throws ParseException {
+    final SqlIdentifier name;
+    List<SqlNode> args = null;
+    SqlNode e = null;
+    final Span s;
+    SqlDataTypeSpec dt;
+    TimeUnit interval;
+    final TimeUnit unit;
+    final SqlNode node;
+    if (jj_2_724(2)) {
+      jj_consume_token(CAST);
+                 s = span();
+      jj_consume_token(LPAREN);
+      e = Expression(ExprContext.ACCEPT_SUB_QUERY);
+                                                                args = startList(e);
+      jj_consume_token(AS);
+      if (jj_2_699(2)) {
+        dt = DataType();
+                              args.add(dt);
+      } else if (jj_2_700(2)) {
+        jj_consume_token(INTERVAL);
+        e = IntervalQualifier();
+                                                 args.add(e);
+      } else {
+        jj_consume_token(-1);
+        throw new ParseException();
+      }
+      jj_consume_token(RPAREN);
+            {if (true) return SqlStdOperatorTable.CAST.createCall(s.end(this), args);}
+    } else if (jj_2_725(2)) {
+      jj_consume_token(EXTRACT);
+            s = span();
+      jj_consume_token(LPAREN);
+      if (jj_2_701(2)) {
+        jj_consume_token(NANOSECOND);
+                           unit = TimeUnit.NANOSECOND;
+      } else if (jj_2_702(2)) {
+        jj_consume_token(MICROSECOND);
+                            unit = TimeUnit.MICROSECOND;
+      } else if (jj_2_703(2)) {
+        unit = TimeUnit();
+      } else {
+        jj_consume_token(-1);
+        throw new ParseException();
+      }
+          args = startList(new SqlIntervalQualifier(unit, null, getPos()));
+      jj_consume_token(FROM);
+      e = Expression(ExprContext.ACCEPT_SUB_QUERY);
+                                                       args.add(e);
+      jj_consume_token(RPAREN);
+            {if (true) return SqlStdOperatorTable.EXTRACT.createCall(s.end(this), args);}
+    } else if (jj_2_726(2)) {
+      jj_consume_token(POSITION);
+                     s = span();
+      jj_consume_token(LPAREN);
+      // FIXME jvs 31-Aug-2006:  FRG-192:  This should be
+              // Expression(ExprContext.ACCEPT_SUB_QUERY), but that doesn't work
+              // because it matches the other kind of IN.
+              e = AtomicRowExpression();
+                                    args = startList(e);
+      jj_consume_token(IN);
+      e = Expression(ExprContext.ACCEPT_SUB_QUERY);
+                                                       args.add(e);
+      if (jj_2_704(2)) {
+        jj_consume_token(FROM);
+        e = Expression(ExprContext.ACCEPT_SUB_QUERY);
+                                                           args.add(e);
+      } else {
+        ;
+      }
+      jj_consume_token(RPAREN);
+            {if (true) return SqlStdOperatorTable.POSITION.createCall(s.end(this), args);}
+    } else if (jj_2_727(2)) {
+      jj_consume_token(CONVERT);
+                    s = span();
+      jj_consume_token(LPAREN);
+      e = Expression(ExprContext.ACCEPT_SUB_QUERY);
+            args = startList(e);
+      jj_consume_token(USING);
+      name = SimpleIdentifier();
+            args.add(name);
+      jj_consume_token(RPAREN);
+            {if (true) return SqlStdOperatorTable.CONVERT.createCall(s.end(this), args);}
+    } else if (jj_2_728(2)) {
+      jj_consume_token(TRANSLATE);
+                      s = span();
+      jj_consume_token(LPAREN);
+      e = Expression(ExprContext.ACCEPT_SUB_QUERY);
+            args = startList(e);
+      if (jj_2_706(2)) {
+        jj_consume_token(USING);
+        name = SimpleIdentifier();
+                args.add(name);
+        jj_consume_token(RPAREN);
+                {if (true) return SqlStdOperatorTable.TRANSLATE.createCall(s.end(this),
+                    args);}
+      } else if (jj_2_707(2)) {
+        label_50:
+        while (true) {
+          if (jj_2_705(2)) {
+            ;
+          } else {
+            break label_50;
+          }
+          jj_consume_token(COMMA);
+          e = Expression(ExprContext.ACCEPT_SUB_QUERY);
+                    args.add(e);
+        }
+        jj_consume_token(RPAREN);
+                {if (true) return SqlLibraryOperators.TRANSLATE3.createCall(s.end(this),
+                    args);}
+      } else {
+        jj_consume_token(-1);
+        throw new ParseException();
+      }
+    } else if (jj_2_729(2)) {
+      jj_consume_token(OVERLAY);
+                    s = span();
+      jj_consume_token(LPAREN);
+      e = Expression(ExprContext.ACCEPT_SUB_QUERY);
+            args = startList(e);
+      jj_consume_token(PLACING);
+      e = Expression(ExprContext.ACCEPT_SUB_QUERY);
+            args.add(e);
+      jj_consume_token(FROM);
+      e = Expression(ExprContext.ACCEPT_SUB_QUERY);
+            args.add(e);
+      if (jj_2_708(2)) {
+        jj_consume_token(FOR);
+        e = Expression(ExprContext.ACCEPT_SUB_QUERY);
+                args.add(e);
+      } else {
+        ;
+      }
+      jj_consume_token(RPAREN);
+            {if (true) return SqlStdOperatorTable.OVERLAY.createCall(s.end(this), args);}
+    } else if (jj_2_730(2)) {
+      jj_consume_token(FLOOR);
+                  s = span();
+      e = FloorCeilOptions(s, true);
+            {if (true) return e;}
+    } else if (jj_2_731(2)) {
+      if (jj_2_709(2)) {
+        jj_consume_token(CEIL);
+      } else if (jj_2_710(2)) {
+        jj_consume_token(CEILING);
+      } else {
+        jj_consume_token(-1);
+        throw new ParseException();
+      }
+                                s = span();
+      e = FloorCeilOptions(s, false);
+            {if (true) return e;}
+    } else if (jj_2_732(2)) {
+      jj_consume_token(SUBSTRING);
+                      s = span();
+      jj_consume_token(LPAREN);
+      e = Expression(ExprContext.ACCEPT_SUB_QUERY);
+          args = startList(e);
+      if (jj_2_711(2)) {
+        jj_consume_token(FROM);
+      } else if (jj_2_712(2)) {
+        jj_consume_token(COMMA);
+      } else {
+        jj_consume_token(-1);
+        throw new ParseException();
+      }
+      e = Expression(ExprContext.ACCEPT_SUB_QUERY);
+          args.add(e);
+      if (jj_2_715(2)) {
+        if (jj_2_713(2)) {
+          jj_consume_token(FOR);
+        } else if (jj_2_714(2)) {
+          jj_consume_token(COMMA);
+        } else {
+          jj_consume_token(-1);
+          throw new ParseException();
+        }
+        e = Expression(ExprContext.ACCEPT_SUB_QUERY);
+              args.add(e);
+      } else {
+        ;
+      }
+      jj_consume_token(RPAREN);
+            {if (true) return SqlStdOperatorTable.SUBSTRING.createCall(
+                s.end(this), args);}
+    } else if (jj_2_733(2)) {
+      jj_consume_token(TRIM);
+            SqlLiteral flag = null;
+            SqlNode trimChars = null;
+            s = span();
+      jj_consume_token(LPAREN);
+      if (jj_2_723(2)) {
+        if (jj_2_719(2)) {
+          if (jj_2_716(2)) {
+            jj_consume_token(BOTH);
+                    s.add(this);
+                    flag = SqlTrimFunction.Flag.BOTH.symbol(getPos());
+          } else if (jj_2_717(2)) {
+            jj_consume_token(TRAILING);
+                    s.add(this);
+                    flag = SqlTrimFunction.Flag.TRAILING.symbol(getPos());
+          } else if (jj_2_718(2)) {
+            jj_consume_token(LEADING);
+                    s.add(this);
+                    flag = SqlTrimFunction.Flag.LEADING.symbol(getPos());
+          } else {
+            jj_consume_token(-1);
+            throw new ParseException();
+          }
+        } else {
+          ;
+        }
+        if (jj_2_720(2)) {
+          trimChars = Expression(ExprContext.ACCEPT_SUB_QUERY);
+        } else {
+          ;
+        }
+        if (jj_2_721(2)) {
+          jj_consume_token(FROM);
+                    if (null == flag && null == trimChars) {
+                        {if (true) throw SqlUtil.newContextException(getPos(),
+                            RESOURCE.illegalFromEmpty());}
+                    }
+        } else if (jj_2_722(2)) {
+          jj_consume_token(RPAREN);
+                    // This is to handle the case of TRIM(x)
+                    // (FRG-191).
+                    if (flag == null) {
+                        flag = SqlTrimFunction.Flag.BOTH.symbol(SqlParserPos.ZERO);
+                    }
+                    args = startList(flag);
+                    args.add(null); // no trim chars
+                    args.add(trimChars); // reinterpret trimChars as source
+                    {if (true) return SqlStdOperatorTable.TRIM.createCall(s.end(this),
+                        args);}
+        } else {
+          jj_consume_token(-1);
+          throw new ParseException();
+        }
+      } else {
+        ;
+      }
+      e = Expression(ExprContext.ACCEPT_SUB_QUERY);
+            if (flag == null) {
+                flag = SqlTrimFunction.Flag.BOTH.symbol(SqlParserPos.ZERO);
+            }
+            args = startList(flag);
+            args.add(trimChars);
+            args.add(e);
+      jj_consume_token(RPAREN);
+            {if (true) return SqlStdOperatorTable.TRIM.createCall(s.end(this), args);}
+    } else if (jj_2_734(2)) {
+      node = TimestampAddFunctionCall();
+                                            {if (true) return node;}
+    } else if (jj_2_735(2)) {
+      node = TimestampDiffFunctionCall();
+                                             {if (true) return node;}
+    } else if (jj_2_736(2)) {
+      node = MatchRecognizeFunctionCall();
+                                              {if (true) return node;}
+    } else if (jj_2_737(2)) {
+      node = JsonExistsFunctionCall();
+                                          {if (true) return node;}
+    } else if (jj_2_738(2)) {
+      node = JsonValueFunctionCall();
+                                         {if (true) return node;}
+    } else if (jj_2_739(2)) {
+      node = JsonQueryFunctionCall();
+                                         {if (true) return node;}
+    } else if (jj_2_740(2)) {
+      node = JsonObjectFunctionCall();
+                                          {if (true) return node;}
+    } else if (jj_2_741(2)) {
+      node = JsonObjectAggFunctionCall();
+                                             {if (true) return node;}
+    } else if (jj_2_742(2)) {
+      node = JsonArrayFunctionCall();
+                                         {if (true) return node;}
+    } else if (jj_2_743(2)) {
+      node = JsonArrayAggFunctionCall();
+                                            {if (true) return node;}
+    } else if (jj_2_744(2)) {
+      node = GroupByWindowingCall();
+                                        {if (true) return node;}
+    } else {
+      jj_consume_token(-1);
+      throw new ParseException();
+    }
+    throw new Error("Missing return statement in function");
+  }
+
+  final public SqlJsonEncoding JsonRepresentation() throws ParseException {
+    jj_consume_token(JSON);
+    if (jj_2_748(2)) {
+      jj_consume_token(ENCODING);
+      if (jj_2_745(2)) {
+        jj_consume_token(UTF8);
+                     {if (true) return SqlJsonEncoding.UTF8;}
+      } else if (jj_2_746(2)) {
+        jj_consume_token(UTF16);
+                      {if (true) return SqlJsonEncoding.UTF16;}
+      } else if (jj_2_747(2)) {
+        jj_consume_token(UTF32);
+                      {if (true) return SqlJsonEncoding.UTF32;}
+      } else {
+        jj_consume_token(-1);
+        throw new ParseException();
+      }
+    } else {
+      ;
+    }
+        {if (true) return SqlJsonEncoding.UTF8;}
+    throw new Error("Missing return statement in function");
+  }
+
+  final public void JsonInputClause() throws ParseException {
+    jj_consume_token(FORMAT);
+    JsonRepresentation();
+  }
+
+  final public SqlDataTypeSpec JsonReturningClause() throws ParseException {
+    SqlDataTypeSpec dt;
+    jj_consume_token(RETURNING);
+    dt = DataType();
+                                  {if (true) return dt;}
+    throw new Error("Missing return statement in function");
+  }
+
+  final public SqlDataTypeSpec JsonOutputClause() throws ParseException {
+    SqlDataTypeSpec dataType;
+    dataType = JsonReturningClause();
+    if (jj_2_749(2)) {
+      jj_consume_token(FORMAT);
+      JsonRepresentation();
+    } else {
+      ;
+    }
+        {if (true) return dataType;}
+    throw new Error("Missing return statement in function");
+  }
+
+  final public SqlNode JsonPathSpec() throws ParseException {
+    SqlNode e;
+    e = StringLiteral();
+        {if (true) return e;}
+    throw new Error("Missing return statement in function");
+  }
+
+  final public List<SqlNode> JsonApiCommonSyntax() throws ParseException {
+    SqlNode e;
+    List<SqlNode> args = new ArrayList<SqlNode>();
+    e = Expression(ExprContext.ACCEPT_NON_QUERY);
+        args.add(e);
+    jj_consume_token(COMMA);
+    e = Expression(ExprContext.ACCEPT_NON_QUERY);
+            args.add(e);
+    if (jj_2_751(2)) {
+      jj_consume_token(PASSING);
+      e = Expression(ExprContext.ACCEPT_NON_QUERY);
+
+      jj_consume_token(AS);
+      e = SimpleIdentifier();
+
+      label_51:
+      while (true) {
+        if (jj_2_750(2)) {
+          ;
+        } else {
+          break label_51;
+        }
+        jj_consume_token(COMMA);
+        e = Expression(ExprContext.ACCEPT_NON_QUERY);
+
+        jj_consume_token(AS);
+        e = SimpleIdentifier();
+
+      }
+    } else {
+      ;
+    }
+        {if (true) return args;}
+    throw new Error("Missing return statement in function");
+  }
+
+  final public SqlJsonExistsErrorBehavior JsonExistsErrorBehavior() throws ParseException {
+    if (jj_2_752(2)) {
+      jj_consume_token(TRUE);
+             {if (true) return SqlJsonExistsErrorBehavior.TRUE;}
+    } else if (jj_2_753(2)) {
+      jj_consume_token(FALSE);
+              {if (true) return SqlJsonExistsErrorBehavior.FALSE;}
+    } else if (jj_2_754(2)) {
+      jj_consume_token(UNKNOWN);
+                {if (true) return SqlJsonExistsErrorBehavior.UNKNOWN;}
+    } else if (jj_2_755(2)) {
+      jj_consume_token(ERROR);
+              {if (true) return SqlJsonExistsErrorBehavior.ERROR;}
+    } else {
+      jj_consume_token(-1);
+      throw new ParseException();
+    }
+    throw new Error("Missing return statement in function");
+  }
+
+  final public SqlCall JsonExistsFunctionCall() throws ParseException {
+    List<SqlNode> args = new ArrayList<SqlNode>();
+    List<SqlNode> commonSyntax;
+    final Span span;
+    SqlJsonExistsErrorBehavior errorBehavior;
+    jj_consume_token(JSON_EXISTS);
+                    span = span();
+    jj_consume_token(LPAREN);
+    commonSyntax = JsonApiCommonSyntax();
+        args.addAll(commonSyntax);
+    if (jj_2_756(2)) {
+      errorBehavior = JsonExistsErrorBehavior();
+                                                    args.add(errorBehavior.symbol(getPos()));
+      jj_consume_token(ON);
+      jj_consume_token(ERROR);
+    } else {
+      ;
+    }
+    jj_consume_token(RPAREN);
+        {if (true) return SqlStdOperatorTable.JSON_EXISTS.createCall(span.end(this), args);}
+    throw new Error("Missing return statement in function");
+  }
+
+  final public List<SqlNode> JsonValueEmptyOrErrorBehavior() throws ParseException {
+    final List<SqlNode> list = new ArrayList<SqlNode>();
+    final SqlNode e;
+    if (jj_2_757(2)) {
+      jj_consume_token(ERROR);
+            list.add(SqlJsonValueEmptyOrErrorBehavior.ERROR.symbol(getPos()));
+    } else if (jj_2_758(2)) {
+      jj_consume_token(NULL);
+            list.add(SqlJsonValueEmptyOrErrorBehavior.NULL.symbol(getPos()));
+    } else if (jj_2_759(2)) {
+      jj_consume_token(DEFAULT_);
+      e = Expression(ExprContext.ACCEPT_NON_QUERY);
+            list.add(SqlJsonValueEmptyOrErrorBehavior.DEFAULT.symbol(getPos()));
+            list.add(e);
+    } else {
+      jj_consume_token(-1);
+      throw new ParseException();
+    }
+    jj_consume_token(ON);
+    if (jj_2_760(2)) {
+      jj_consume_token(EMPTY);
+            list.add(SqlJsonEmptyOrError.EMPTY.symbol(getPos()));
+    } else if (jj_2_761(2)) {
+      jj_consume_token(ERROR);
+            list.add(SqlJsonEmptyOrError.ERROR.symbol(getPos()));
+    } else {
+      jj_consume_token(-1);
+      throw new ParseException();
+    }
+      {if (true) return list;}
+    throw new Error("Missing return statement in function");
+  }
+
+  final public SqlCall JsonValueFunctionCall() throws ParseException {
+    final List<SqlNode> args = new ArrayList<SqlNode>(7);
+    SqlNode e;
+    List<SqlNode> commonSyntax;
+    final Span span;
+    List<SqlNode> behavior;
+    jj_consume_token(JSON_VALUE);
+                   span = span();
+    jj_consume_token(LPAREN);
+    commonSyntax = JsonApiCommonSyntax();
+        args.addAll(commonSyntax);
+    if (jj_2_762(2)) {
+      e = JsonReturningClause();
+            args.add(SqlJsonValueReturning.RETURNING.symbol(getPos()));
+            args.add(e);
+    } else {
+      ;
+    }
+    label_52:
+    while (true) {
+      if (jj_2_763(2)) {
+        ;
+      } else {
+        break label_52;
+      }
+      behavior = JsonValueEmptyOrErrorBehavior();
+            args.addAll(behavior);
+    }
+    jj_consume_token(RPAREN);
+        {if (true) return SqlStdOperatorTable.JSON_VALUE.createCall(span.end(this), args);}
+    throw new Error("Missing return statement in function");
+  }
+
+  final public List<SqlNode> JsonQueryEmptyOrErrorBehavior() throws ParseException {
+    final List<SqlNode> list = new ArrayList<SqlNode>();
+    SqlNode e;
+    if (jj_2_764(2)) {
+      jj_consume_token(ERROR);
+            list.add(SqlLiteral.createSymbol(SqlJsonQueryEmptyOrErrorBehavior.ERROR, getPos()));
+    } else if (jj_2_765(2)) {
+      jj_consume_token(NULL);
+            list.add(SqlLiteral.createSymbol(SqlJsonQueryEmptyOrErrorBehavior.NULL, getPos()));
+    } else if (jj_2_766(2)) {
+      jj_consume_token(EMPTY);
+      jj_consume_token(ARRAY);
+            list.add(SqlLiteral.createSymbol(SqlJsonQueryEmptyOrErrorBehavior.EMPTY_ARRAY, getPos()));
+    } else if (jj_2_767(2)) {
+      jj_consume_token(EMPTY);
+      jj_consume_token(OBJECT);
+            list.add(SqlLiteral.createSymbol(SqlJsonQueryEmptyOrErrorBehavior.EMPTY_OBJECT, getPos()));
+    } else {
+      jj_consume_token(-1);
+      throw new ParseException();
+    }
+    jj_consume_token(ON);
+    if (jj_2_768(2)) {
+      jj_consume_token(EMPTY);
+            list.add(SqlLiteral.createSymbol(SqlJsonEmptyOrError.EMPTY, getPos()));
+    } else if (jj_2_769(2)) {
+      jj_consume_token(ERROR);
+            list.add(SqlLiteral.createSymbol(SqlJsonEmptyOrError.ERROR, getPos()));
+    } else {
+      jj_consume_token(-1);
+      throw new ParseException();
+    }
+      {if (true) return list;}
+    throw new Error("Missing return statement in function");
+  }
+
+  final public SqlNode JsonQueryWrapperBehavior() throws ParseException {
+    SqlNode e;
+    if (jj_2_774(2)) {
+      jj_consume_token(WITHOUT);
+      if (jj_2_770(2)) {
+        jj_consume_token(ARRAY);
+      } else {
+        ;
+      }
+        {if (true) return SqlLiteral.createSymbol(SqlJsonQueryWrapperBehavior.WITHOUT_ARRAY, getPos());}
+    } else if (jj_2_775(2)) {
+      jj_consume_token(WITH);
+      jj_consume_token(CONDITIONAL);
+      if (jj_2_771(2)) {
+        jj_consume_token(ARRAY);
+      } else {
+        ;
+      }
+        {if (true) return SqlLiteral.createSymbol(SqlJsonQueryWrapperBehavior.WITH_CONDITIONAL_ARRAY, getPos());}
+    } else if (jj_2_776(2)) {
+      jj_consume_token(WITH);
+      if (jj_2_772(2)) {
+        jj_consume_token(UNCONDITIONAL);
+      } else {
+        ;
+      }
+      if (jj_2_773(2)) {
+        jj_consume_token(ARRAY);
+      } else {
+        ;
+      }
+        {if (true) return SqlLiteral.createSymbol(SqlJsonQueryWrapperBehavior.WITH_UNCONDITIONAL_ARRAY, getPos());}
+    } else {
+      jj_consume_token(-1);
+      throw new ParseException();
+    }
+    throw new Error("Missing return statement in function");
+  }
+
+  final public SqlCall JsonQueryFunctionCall() throws ParseException {
+    final SqlNode[] args = new SqlNode[5];
+    SqlNode e;
+    List<SqlNode> commonSyntax;
+    final Span span;
+    List<SqlNode> behavior;
+    jj_consume_token(JSON_QUERY);
+                   span = span();
+    jj_consume_token(LPAREN);
+    commonSyntax = JsonApiCommonSyntax();
+        args[0] = commonSyntax.get(0);
+        args[1] = commonSyntax.get(1);
+    if (jj_2_777(2)) {
+      e = JsonQueryWrapperBehavior();
+      jj_consume_token(WRAPPER);
+            args[2] = e;
+    } else {
+      ;
+    }
+    label_53:
+    while (true) {
+      if (jj_2_778(2)) {
+        ;
+      } else {
+        break label_53;
+      }
+      behavior = JsonQueryEmptyOrErrorBehavior();
+            final SqlJsonEmptyOrError symbol =
+                ((SqlLiteral) behavior.get(1)).getValueAs(SqlJsonEmptyOrError.class);
+            switch (symbol) {
+            case EMPTY:
+                args[3] = behavior.get(0);
+                break;
+            case ERROR:
+                args[4] = behavior.get(0);
+                break;
+            }
+    }
+    jj_consume_token(RPAREN);
+        {if (true) return SqlStdOperatorTable.JSON_QUERY.createCall(span.end(this), args);}
+    throw new Error("Missing return statement in function");
+  }
+
+  final public SqlNode JsonName() throws ParseException {
+    final SqlNode e;
+    e = Expression(ExprContext.ACCEPT_NON_QUERY);
+        {if (true) return e;}
+    throw new Error("Missing return statement in function");
+  }
+
+  final public List<SqlNode> JsonNameAndValue() throws ParseException {
+    final List<SqlNode> list = new ArrayList<SqlNode>();
+    SqlNode e;
+    boolean kvMode = false;
+    if (jj_2_779(2)) {
+      jj_consume_token(KEY);
+                kvMode = true;
+    } else {
+      ;
+    }
+    e = JsonName();
+        list.add(e);
+    if (jj_2_780(2)) {
+      jj_consume_token(VALUE);
+    } else if (jj_2_781(2)) {
+      jj_consume_token(COLON);
+            if (kvMode) {
+                {if (true) throw SqlUtil.newContextException(getPos(), RESOURCE.illegalColon());}
+            }
+    } else {
+      jj_consume_token(-1);
+      throw new ParseException();
+    }
+    e = Expression(ExprContext.ACCEPT_NON_QUERY);
+        list.add(e);
+        {if (true) return list;}
+    throw new Error("Missing return statement in function");
+  }
+
+  final public SqlNode JsonConstructorNullClause() throws ParseException {
+    if (jj_2_782(2)) {
+      jj_consume_token(NULL);
+      jj_consume_token(ON);
+      jj_consume_token(NULL);
+        {if (true) return SqlLiteral.createSymbol(SqlJsonConstructorNullClause.NULL_ON_NULL, getPos());}
+    } else if (jj_2_783(2)) {
+      jj_consume_token(ABSENT);
+      jj_consume_token(ON);
+      jj_consume_token(NULL);
+        {if (true) return SqlLiteral.createSymbol(SqlJsonConstructorNullClause.ABSENT_ON_NULL, getPos());}
+    } else {
+      jj_consume_token(-1);
+      throw new ParseException();
+    }
+    throw new Error("Missing return statement in function");
+  }
+
+  final public SqlCall JsonObjectFunctionCall() throws ParseException {
+    final List<SqlNode> nvArgs = new ArrayList<SqlNode>();
+    final SqlNode[] otherArgs = new SqlNode[1];
+    SqlNode e;
+    List<SqlNode> list;
+    final Span span;
+    jj_consume_token(JSON_OBJECT);
+                    span = span();
+    jj_consume_token(LPAREN);
+    if (jj_2_785(2)) {
+      list = JsonNameAndValue();
+            nvArgs.addAll(list);
+      label_54:
+      while (true) {
+        if (jj_2_784(2)) {
+          ;
+        } else {
+          break label_54;
+        }
+        jj_consume_token(COMMA);
+        list = JsonNameAndValue();
+                nvArgs.addAll(list);
+      }
+    } else {
+      ;
+    }
+    if (jj_2_786(2)) {
+      e = JsonConstructorNullClause();
+            otherArgs[0] = e;
+    } else {
+      ;
+    }
+    jj_consume_token(RPAREN);
+        final List<SqlNode> args = new ArrayList();
+        args.addAll(Arrays.asList(otherArgs));
+        args.addAll(nvArgs);
+        {if (true) return SqlStdOperatorTable.JSON_OBJECT.createCall(span.end(this), args);}
+    throw new Error("Missing return statement in function");
+  }
+
+  final public SqlCall JsonObjectAggFunctionCall() throws ParseException {
+    final SqlNode[] args = new SqlNode[2];
+    List<SqlNode> list;
+    final Span span;
+    SqlJsonConstructorNullClause nullClause =
+        SqlJsonConstructorNullClause.NULL_ON_NULL;
+    final SqlNode e;
+    jj_consume_token(JSON_OBJECTAGG);
+                       span = span();
+    jj_consume_token(LPAREN);
+    list = JsonNameAndValue();
+        args[0] = list.get(0);
+        args[1] = list.get(1);
+    if (jj_2_787(2)) {
+      e = JsonConstructorNullClause();
+            nullClause = (SqlJsonConstructorNullClause) ((SqlLiteral) e).getValue();
+    } else {
+      ;
+    }
+    jj_consume_token(RPAREN);
+        {if (true) return SqlStdOperatorTable.JSON_OBJECTAGG.with(nullClause)
+            .createCall(span.end(this), args);}
+    throw new Error("Missing return statement in function");
+  }
+
+  final public SqlCall JsonArrayFunctionCall() throws ParseException {
+    final List<SqlNode> elements = new ArrayList<SqlNode>();
+    final SqlNode[] otherArgs = new SqlNode[1];
+    SqlNode e;
+    final Span span;
+    jj_consume_token(JSON_ARRAY);
+                   span = span();
+    jj_consume_token(LPAREN);
+    if (jj_2_789(2)) {
+      e = Expression(ExprContext.ACCEPT_NON_QUERY);
+            elements.add(e);
+      label_55:
+      while (true) {
+        if (jj_2_788(2)) {
+          ;
+        } else {
+          break label_55;
+        }
+        jj_consume_token(COMMA);
+        e = Expression(ExprContext.ACCEPT_NON_QUERY);
+                elements.add(e);
+      }
+    } else {
+      ;
+    }
+    if (jj_2_790(2)) {
+      e = JsonConstructorNullClause();
+            otherArgs[0] = e;
+    } else {
+      ;
+    }
+    jj_consume_token(RPAREN);
+        final List<SqlNode> args = new ArrayList();
+        args.addAll(Arrays.asList(otherArgs));
+        args.addAll(elements);
+        {if (true) return SqlStdOperatorTable.JSON_ARRAY.createCall(span.end(this), args);}
+    throw new Error("Missing return statement in function");
+  }
+
+  final public SqlNodeList JsonArrayAggOrderByClause() throws ParseException {
+    final SqlNodeList orderList;
+    if (jj_2_791(2)) {
+      orderList = OrderBy(true);
+    } else {
+          orderList = null;
+    }
+        {if (true) return orderList;}
+    throw new Error("Missing return statement in function");
+  }
+
+  final public SqlCall JsonArrayAggFunctionCall() throws ParseException {
+    final SqlNode valueExpr;
+    final SqlNodeList orderList;
+    List<SqlNode> list;
+    final Span span;
+    SqlJsonConstructorNullClause nullClause =
+        SqlJsonConstructorNullClause.ABSENT_ON_NULL;
+    SqlNode e = null;
+    final SqlNode aggCall;
+    jj_consume_token(JSON_ARRAYAGG);
+                      span = span();
+    jj_consume_token(LPAREN);
+    e = Expression(ExprContext.ACCEPT_NON_QUERY);
+        valueExpr = e;
+    orderList = JsonArrayAggOrderByClause();
+    if (jj_2_792(2)) {
+      e = JsonConstructorNullClause();
+            nullClause = (SqlJsonConstructorNullClause) ((SqlLiteral) e).getValue();
+    } else {
+      ;
+    }
+    jj_consume_token(RPAREN);
+        aggCall = SqlStdOperatorTable.JSON_ARRAYAGG.with(nullClause)
+            .createCall(span.end(this), valueExpr, orderList);
+    if (jj_2_793(2)) {
+      e = withinGroup(aggCall);
+            if (orderList != null) {
+                {if (true) throw SqlUtil.newContextException(span.pos().plus(e.getParserPosition()),
+                    RESOURCE.ambiguousSortOrderInJsonArrayAggFunc());}
+            }
+            {if (true) return (SqlCall) e;}
+    } else {
+      ;
+    }
+        if (orderList == null) {
+            {if (true) return SqlStdOperatorTable.JSON_ARRAYAGG.with(nullClause)
+                .createCall(span.end(this), valueExpr);}
+        }
+        {if (true) return SqlStdOperatorTable.JSON_ARRAYAGG.with(nullClause)
+            .createCall(span.end(this), valueExpr, orderList);}
+    throw new Error("Missing return statement in function");
+  }
+
+/**
+ * Parses a call to TIMESTAMPADD.
+ */
+  final public SqlCall TimestampAddFunctionCall() throws ParseException {
+    List<SqlNode> args;
+    SqlNode e;
+    final Span s;
+    TimeUnit interval;
+    SqlNode node;
+    jj_consume_token(TIMESTAMPADD);
+                     s = span();
+    jj_consume_token(LPAREN);
+    interval = TimestampInterval();
+        args = startList(SqlLiteral.createSymbol(interval, getPos()));
+    jj_consume_token(COMMA);
+    e = Expression(ExprContext.ACCEPT_SUB_QUERY);
+                                                   args.add(e);
+    jj_consume_token(COMMA);
+    e = Expression(ExprContext.ACCEPT_SUB_QUERY);
+                                                   args.add(e);
+    jj_consume_token(RPAREN);
+        {if (true) return SqlStdOperatorTable.TIMESTAMP_ADD.createCall(
+            s.end(this), args);}
+    throw new Error("Missing return statement in function");
+  }
+
+/**
+ * Parses a call to TIMESTAMPDIFF.
+ */
+  final public SqlCall TimestampDiffFunctionCall() throws ParseException {
+    List<SqlNode> args;
+    SqlNode e;
+    final Span s;
+    TimeUnit interval;
+    SqlNode node;
+    jj_consume_token(TIMESTAMPDIFF);
+                      s = span();
+    jj_consume_token(LPAREN);
+    interval = TimestampInterval();
+        args = startList(SqlLiteral.createSymbol(interval, getPos()));
+    jj_consume_token(COMMA);
+    e = Expression(ExprContext.ACCEPT_SUB_QUERY);
+                                                   args.add(e);
+    jj_consume_token(COMMA);
+    e = Expression(ExprContext.ACCEPT_SUB_QUERY);
+                                                   args.add(e);
+    jj_consume_token(RPAREN);
+        {if (true) return SqlStdOperatorTable.TIMESTAMP_DIFF.createCall(
+            s.end(this), args);}
+    throw new Error("Missing return statement in function");
+  }
+
+/**
+ * Parses a call to a grouping function inside the GROUP BY clause,
+ * for example {@code TUMBLE(rowtime, INTERVAL '1' MINUTE)}.
+ */
+  final public SqlCall GroupByWindowingCall() throws ParseException {
+    final Span s;
+    final List<SqlNode> args;
+    final SqlOperator op;
+    if (jj_2_794(2)) {
+      jj_consume_token(TUMBLE);
+            op = SqlStdOperatorTable.TUMBLE_OLD;
+    } else if (jj_2_795(2)) {
+      jj_consume_token(HOP);
+            op = SqlStdOperatorTable.HOP_OLD;
+    } else if (jj_2_796(2)) {
+      jj_consume_token(SESSION);
+            op = SqlStdOperatorTable.SESSION_OLD;
+    } else {
+      jj_consume_token(-1);
+      throw new ParseException();
+    }
+        s = span();
+    args = UnquantifiedFunctionParameterList(ExprContext.ACCEPT_SUB_QUERY);
+        {if (true) return op.createCall(s.end(this), args);}
+    throw new Error("Missing return statement in function");
+  }
+
+  final public SqlCall MatchRecognizeFunctionCall() throws ParseException {
+    final SqlCall func;
+    final Span s;
+    if (jj_2_797(2)) {
+      jj_consume_token(CLASSIFIER);
+                       s = span();
+      jj_consume_token(LPAREN);
+      jj_consume_token(RPAREN);
+            func = SqlStdOperatorTable.CLASSIFIER.createCall(s.end(this));
+    } else if (jj_2_798(2)) {
+      jj_consume_token(MATCH_NUMBER);
+                         s = span();
+      jj_consume_token(LPAREN);
+      jj_consume_token(RPAREN);
+            func = SqlStdOperatorTable.MATCH_NUMBER.createCall(s.end(this));
+    } else if (jj_2_799(3)) {
+      func = MatchRecognizeNavigationLogical();
+    } else if (jj_2_800(2)) {
+      func = MatchRecognizeNavigationPhysical();
+    } else if (jj_2_801(2)) {
+      func = MatchRecognizeCallWithModifier();
+    } else {
+      jj_consume_token(-1);
+      throw new ParseException();
+    }
+      {if (true) return func;}
+    throw new Error("Missing return statement in function");
+  }
+
+  final public SqlCall MatchRecognizeCallWithModifier() throws ParseException {
+    final Span s;
+    final SqlOperator runningOp;
+    final SqlNode func;
+    if (jj_2_802(2)) {
+      jj_consume_token(RUNNING);
+                    runningOp = SqlStdOperatorTable.RUNNING;
+    } else if (jj_2_803(2)) {
+      jj_consume_token(FINAL);
+                  runningOp = SqlStdOperatorTable.FINAL;
+    } else {
+      jj_consume_token(-1);
+      throw new ParseException();
+    }
+      s = span();
+    func = NamedFunctionCall();
+        {if (true) return runningOp.createCall(s.end(func), func);}
+    throw new Error("Missing return statement in function");
+  }
+
+  final public SqlCall MatchRecognizeNavigationLogical() throws ParseException {
+    final Span s = Span.of();
+    SqlCall func;
+    final SqlOperator funcOp;
+    final SqlOperator runningOp;
+    SqlNode arg0;
+    SqlNode arg1 = SqlLiteral.createExactNumeric("0", SqlParserPos.ZERO);
+    if (jj_2_804(2)) {
+      jj_consume_token(RUNNING);
+                    runningOp = SqlStdOperatorTable.RUNNING; s.add(this);
+    } else if (jj_2_805(2)) {
+      jj_consume_token(FINAL);
+                  runningOp = SqlStdOperatorTable.FINAL; s.add(this);
+    } else {
+          runningOp = null;
+    }
+    if (jj_2_806(2)) {
+      jj_consume_token(FIRST);
+                  funcOp = SqlStdOperatorTable.FIRST;
+    } else if (jj_2_807(2)) {
+      jj_consume_token(LAST);
+                 funcOp = SqlStdOperatorTable.LAST;
+    } else {
+      jj_consume_token(-1);
+      throw new ParseException();
+    }
+      s.add(this);
+    jj_consume_token(LPAREN);
+    arg0 = Expression(ExprContext.ACCEPT_SUB_QUERY);
+    if (jj_2_808(2)) {
+      jj_consume_token(COMMA);
+      arg1 = NumericLiteral();
+    } else {
+      ;
+    }
+    jj_consume_token(RPAREN);
+        func = funcOp.createCall(s.end(this), arg0, arg1);
+        if (runningOp != null) {
+            {if (true) return runningOp.createCall(s.end(this), func);}
+        } else {
+            {if (true) return func;}
+        }
+    throw new Error("Missing return statement in function");
+  }
+
+  final public SqlCall MatchRecognizeNavigationPhysical() throws ParseException {
+    final Span s;
+    SqlCall func;
+    SqlOperator funcOp;
+    SqlNode arg0;
+    SqlNode arg1 = SqlLiteral.createExactNumeric("1", SqlParserPos.ZERO);
+    if (jj_2_809(2)) {
+      jj_consume_token(PREV);
+                 funcOp = SqlStdOperatorTable.PREV;
+    } else if (jj_2_810(2)) {
+      jj_consume_token(NEXT);
+                 funcOp = SqlStdOperatorTable.NEXT;
+    } else {
+      jj_consume_token(-1);
+      throw new ParseException();
+    }
+      s = span();
+    jj_consume_token(LPAREN);
+    arg0 = Expression(ExprContext.ACCEPT_SUB_QUERY);
+    if (jj_2_811(2)) {
+      jj_consume_token(COMMA);
+      arg1 = NumericLiteral();
+    } else {
+      ;
+    }
+    jj_consume_token(RPAREN);
+        {if (true) return funcOp.createCall(s.end(this), arg0, arg1);}
+    throw new Error("Missing return statement in function");
+  }
+
+  final public SqlCall withinDistinct(SqlNode arg) throws ParseException {
+    final Span s;
+    final SqlNodeList distinctList;
+    jj_consume_token(WITHIN);
+               s = span();
+    jj_consume_token(DISTINCT);
+    jj_consume_token(LPAREN);
+    distinctList = ExpressionCommaList(s, ExprContext.ACCEPT_SUB_QUERY);
+    jj_consume_token(RPAREN);
+        {if (true) return SqlStdOperatorTable.WITHIN_DISTINCT.createCall(
+            s.end(this), arg, distinctList);}
+    throw new Error("Missing return statement in function");
+  }
+
+  final public SqlCall withinGroup(SqlNode arg) throws ParseException {
+    final Span s;
+    final SqlNodeList orderList;
+    jj_consume_token(WITHIN);
+               s = span();
+    jj_consume_token(GROUP);
+    jj_consume_token(LPAREN);
+    orderList = OrderBy(true);
+    jj_consume_token(RPAREN);
+        {if (true) return SqlStdOperatorTable.WITHIN_GROUP.createCall(
+            s.end(this), arg, orderList);}
+    throw new Error("Missing return statement in function");
+  }
+
+  final public Pair<SqlParserPos, SqlOperator> NullTreatment() throws ParseException {
+    final Span span;
+    if (jj_2_812(2)) {
+      jj_consume_token(IGNORE);
+               span = span();
+      jj_consume_token(NULLS);
+        {if (true) return Pair.of(span.end(this), SqlStdOperatorTable.IGNORE_NULLS);}
+    } else if (jj_2_813(2)) {
+      jj_consume_token(RESPECT);
+                span = span();
+      jj_consume_token(NULLS);
+        {if (true) return Pair.of(span.end(this), SqlStdOperatorTable.RESPECT_NULLS);}
+    } else {
+      jj_consume_token(-1);
+      throw new ParseException();
+    }
+    throw new Error("Missing return statement in function");
+  }
+
+  final public SqlCall nullTreatment(SqlCall arg) throws ParseException {
+    final Pair<SqlParserPos, SqlOperator> pair;
+    pair = NullTreatment();
+                             {if (true) return pair.right.createCall(pair.left, arg);}
+    throw new Error("Missing return statement in function");
+  }
+
+/**
+ * Parses a call to a named function (could be a builtin with regular
+ * syntax, or else a UDF).
+ *
+ * <p>NOTE: every UDF has two names: an <em>invocation name</em> and a
+ * <em>specific name</em>.  Normally, function calls are resolved via overload
+ * resolution and invocation names.  The SPECIFIC prefix allows overload
+ * resolution to be bypassed.  Note that usage of the SPECIFIC prefix in
+ * queries is non-standard; it is used internally by Farrago, e.g. in stored
+ * view definitions to permanently bind references to a particular function
+ * after the overload resolution performed by view creation.
+ *
+ * <p>TODO jvs 25-Mar-2005:  Once we have SQL-Flagger support, flag SPECIFIC
+ * as non-standard.
+ */
+  final public SqlNode NamedFunctionCall() throws ParseException {
+    SqlCall call;
+    final Span filterSpan;
+    final SqlNode filter;
+    final Span overSpan;
+    final SqlNode over;
+    final Span withinGroupSpan;
+    if (jj_2_814(2)) {
+      call = StringAggFunctionCall();
+    } else if (jj_2_815(2)) {
+      call = NamedCall();
+    } else {
+      jj_consume_token(-1);
+      throw new ParseException();
+    }
+    if (jj_2_816(2)) {
+      call = nullTreatment(call);
+    } else {
+      ;
+    }
+    if (jj_2_817(2)) {
+      // decide between WITHIN DISTINCT and WITHIN GROUP
+              call = withinDistinct(call);
+    } else {
+      ;
+    }
+    if (jj_2_818(2)) {
+      call = withinGroup(call);
+    } else {
+      ;
+    }
+    if (jj_2_819(2)) {
+      jj_consume_token(FILTER);
+                   filterSpan = span();
+      jj_consume_token(LPAREN);
+      jj_consume_token(WHERE);
+      filter = Expression(ExprContext.ACCEPT_SUB_QUERY);
+      jj_consume_token(RPAREN);
+            call = SqlStdOperatorTable.FILTER.createCall(
+                filterSpan.end(this), call, filter);
+    } else {
+      ;
+    }
+    if (jj_2_822(2)) {
+      jj_consume_token(OVER);
+                 overSpan = span();
+      if (jj_2_820(2)) {
+        over = SimpleIdentifier();
+      } else if (jj_2_821(2)) {
+        over = WindowSpecification();
+      } else {
+        jj_consume_token(-1);
+        throw new ParseException();
+      }
+            call = SqlStdOperatorTable.OVER.createCall(overSpan.end(over), call, over);
+    } else {
+      ;
+    }
+        {if (true) return call;}
+    throw new Error("Missing return statement in function");
+  }
+
+  final public SqlCall NamedCall() throws ParseException {
+    final SqlFunctionCategory funcType;
+    final SqlIdentifier qualifiedName;
+    final Span s;
+    final List<SqlNode> args;
+    SqlLiteral quantifier = null;
+    if (jj_2_823(2)) {
+      jj_consume_token(SPECIFIC);
+            funcType = SqlFunctionCategory.USER_DEFINED_SPECIFIC_FUNCTION;
+    } else {
+          funcType = SqlFunctionCategory.USER_DEFINED_FUNCTION;
+    }
+    qualifiedName = FunctionName();
+        s = span();
+    if (jj_2_824(2)) {
+      jj_consume_token(LPAREN);
+      jj_consume_token(STAR);
+            args = startList(SqlIdentifier.star(getPos()));
+      jj_consume_token(RPAREN);
+    } else if (jj_2_825(2)) {
+      jj_consume_token(LPAREN);
+      jj_consume_token(RPAREN);
+            args = Collections.emptyList();
+    } else if (jj_2_826(2)) {
+      args = FunctionParameterList(ExprContext.ACCEPT_SUB_QUERY);
+            quantifier = (SqlLiteral) args.get(0);
+            args.remove(0);
+    } else {
+      jj_consume_token(-1);
+      throw new ParseException();
+    }
+        {if (true) return createCall(qualifiedName, s.end(this), funcType, quantifier, args);}
+    throw new Error("Missing return statement in function");
+  }
+
+/*
+* Parse Floor/Ceil function parameters
+*/
+  final public SqlNode StandardFloorCeilOptions(Span s, boolean floorFlag) throws ParseException {
+    SqlNode e;
+    final List<SqlNode> args;
+    TimeUnit unit;
+    SqlCall function;
+    final Span s1;
+    jj_consume_token(LPAREN);
+    e = Expression(ExprContext.ACCEPT_SUB_QUERY);
+        args = startList(e);
+    if (jj_2_827(2)) {
+      jj_consume_token(TO);
+      unit = TimeUnit();
+            args.add(new SqlIntervalQualifier(unit, null, getPos()));
+    } else {
+      ;
+    }
+    jj_consume_token(RPAREN);
+        SqlOperator op = floorFlag
+            ? SqlStdOperatorTable.FLOOR
+            : SqlStdOperatorTable.CEIL;
+        function =  op.createCall(s.end(this), args);
+    if (jj_2_830(2)) {
+      jj_consume_token(OVER);
+                 s1 = span();
+      if (jj_2_828(2)) {
+        e = SimpleIdentifier();
+      } else if (jj_2_829(2)) {
+        e = WindowSpecification();
+      } else {
+        jj_consume_token(-1);
+        throw new ParseException();
+      }
+            {if (true) return SqlStdOperatorTable.OVER.createCall(s1.end(this), function, e);}
+    } else {
+          {if (true) return function;}
+    }
+    throw new Error("Missing return statement in function");
+  }
+
+/**
+ * Parses the name of a JDBC function that is a token but is not reserved.
+ */
+  final public String NonReservedJdbcFunctionName() throws ParseException {
+    jj_consume_token(SUBSTRING);
+        {if (true) return unquotedIdentifier();}
+    throw new Error("Missing return statement in function");
+  }
+
+/**
+ * Parses the name of a function (either a compound identifier or
+ * a reserved word which can be used as a function name).
+ */
+  final public SqlIdentifier FunctionName() throws ParseException {
+    SqlIdentifier qualifiedName;
+    if (jj_2_831(2)) {
+      qualifiedName = CompoundIdentifier();
+    } else if (jj_2_832(2)) {
+      qualifiedName = ReservedFunctionName();
+    } else {
+      jj_consume_token(-1);
+      throw new ParseException();
+    }
+        {if (true) return qualifiedName;}
+    throw new Error("Missing return statement in function");
+  }
+
+/**
+ * Parses a reserved word which is used as the name of a function.
+ */
+  final public SqlIdentifier ReservedFunctionName() throws ParseException {
+    if (jj_2_833(2)) {
+      jj_consume_token(ABS);
+    } else if (jj_2_834(2)) {
+      jj_consume_token(AVG);
+    } else if (jj_2_835(2)) {
+      jj_consume_token(CARDINALITY);
+    } else if (jj_2_836(2)) {
+      jj_consume_token(CEILING);
+    } else if (jj_2_837(2)) {
+      jj_consume_token(CHAR_LENGTH);
+    } else if (jj_2_838(2)) {
+      jj_consume_token(CHARACTER_LENGTH);
+    } else if (jj_2_839(2)) {
+      jj_consume_token(COALESCE);
+    } else if (jj_2_840(2)) {
+      jj_consume_token(COLLECT);
+    } else if (jj_2_841(2)) {
+      jj_consume_token(COVAR_POP);
+    } else if (jj_2_842(2)) {
+      jj_consume_token(COVAR_SAMP);
+    } else if (jj_2_843(2)) {
+      jj_consume_token(CUME_DIST);
+    } else if (jj_2_844(2)) {
+      jj_consume_token(COUNT);
+    } else if (jj_2_845(2)) {
+      jj_consume_token(CURRENT_DATE);
+    } else if (jj_2_846(2)) {
+      jj_consume_token(CURRENT_TIME);
+    } else if (jj_2_847(2)) {
+      jj_consume_token(CURRENT_TIMESTAMP);
+    } else if (jj_2_848(2)) {
+      jj_consume_token(DENSE_RANK);
+    } else if (jj_2_849(2)) {
+      jj_consume_token(ELEMENT);
+    } else if (jj_2_850(2)) {
+      jj_consume_token(EVERY);
+    } else if (jj_2_851(2)) {
+      jj_consume_token(EXP);
+    } else if (jj_2_852(2)) {
+      jj_consume_token(FIRST_VALUE);
+    } else if (jj_2_853(2)) {
+      jj_consume_token(FLOOR);
+    } else if (jj_2_854(2)) {
+      jj_consume_token(FUSION);
+    } else if (jj_2_855(2)) {
+      jj_consume_token(INTERSECTION);
+    } else if (jj_2_856(2)) {
+      jj_consume_token(GROUPING);
+    } else if (jj_2_857(2)) {
+      jj_consume_token(HOUR);
+    } else if (jj_2_858(2)) {
+      jj_consume_token(LAG);
+    } else if (jj_2_859(2)) {
+      jj_consume_token(LEAD);
+    } else if (jj_2_860(2)) {
+      jj_consume_token(LEFT);
+    } else if (jj_2_861(2)) {
+      jj_consume_token(LAST_VALUE);
+    } else if (jj_2_862(2)) {
+      jj_consume_token(LN);
+    } else if (jj_2_863(2)) {
+      jj_consume_token(LOCALTIME);
+    } else if (jj_2_864(2)) {
+      jj_consume_token(LOCALTIMESTAMP);
+    } else if (jj_2_865(2)) {
+      jj_consume_token(LOWER);
+    } else if (jj_2_866(2)) {
+      jj_consume_token(MAX);
+    } else if (jj_2_867(2)) {
+      jj_consume_token(MIN);
+    } else if (jj_2_868(2)) {
+      jj_consume_token(MINUTE);
+    } else if (jj_2_869(2)) {
+      jj_consume_token(MOD);
+    } else if (jj_2_870(2)) {
+      jj_consume_token(MONTH);
+    } else if (jj_2_871(2)) {
+      jj_consume_token(NTH_VALUE);
+    } else if (jj_2_872(2)) {
+      jj_consume_token(NTILE);
+    } else if (jj_2_873(2)) {
+      jj_consume_token(NULLIF);
+    } else if (jj_2_874(2)) {
+      jj_consume_token(OCTET_LENGTH);
+    } else if (jj_2_875(2)) {
+      jj_consume_token(PERCENT_RANK);
+    } else if (jj_2_876(2)) {
+      jj_consume_token(PERCENTILE_CONT);
+    } else if (jj_2_877(2)) {
+      jj_consume_token(PERCENTILE_DISC);
+    } else if (jj_2_878(2)) {
+      jj_consume_token(POWER);
+    } else if (jj_2_879(2)) {
+      jj_consume_token(RANK);
+    } else if (jj_2_880(2)) {
+      jj_consume_token(REGR_COUNT);
+    } else if (jj_2_881(2)) {
+      jj_consume_token(REGR_SXX);
+    } else if (jj_2_882(2)) {
+      jj_consume_token(REGR_SYY);
+    } else if (jj_2_883(2)) {
+      jj_consume_token(RIGHT);
+    } else if (jj_2_884(2)) {
+      jj_consume_token(ROW_NUMBER);
+    } else if (jj_2_885(2)) {
+      jj_consume_token(SECOND);
+    } else if (jj_2_886(2)) {
+      jj_consume_token(SOME);
+    } else if (jj_2_887(2)) {
+      jj_consume_token(SQRT);
+    } else if (jj_2_888(2)) {
+      jj_consume_token(STDDEV_POP);
+    } else if (jj_2_889(2)) {
+      jj_consume_token(STDDEV_SAMP);
+    } else if (jj_2_890(2)) {
+      jj_consume_token(SUM);
+    } else if (jj_2_891(2)) {
+      jj_consume_token(UPPER);
+    } else if (jj_2_892(2)) {
+      jj_consume_token(TRUNCATE);
+    } else if (jj_2_893(2)) {
+      jj_consume_token(USER);
+    } else if (jj_2_894(2)) {
+      jj_consume_token(VAR_POP);
+    } else if (jj_2_895(2)) {
+      jj_consume_token(VAR_SAMP);
+    } else if (jj_2_896(2)) {
+      jj_consume_token(YEAR);
+    } else {
+      jj_consume_token(-1);
+      throw new ParseException();
+    }
+        {if (true) return new SqlIdentifier(unquotedIdentifier(), getPos());}
+    throw new Error("Missing return statement in function");
+  }
+
+  final public SqlIdentifier ContextVariable() throws ParseException {
+    if (jj_2_897(2)) {
+      jj_consume_token(CURRENT_CATALOG);
+    } else if (jj_2_898(2)) {
+      jj_consume_token(CURRENT_DATE);
+    } else if (jj_2_899(2)) {
+      jj_consume_token(CURRENT_DEFAULT_TRANSFORM_GROUP);
+    } else if (jj_2_900(2)) {
+      jj_consume_token(CURRENT_PATH);
+    } else if (jj_2_901(2)) {
+      jj_consume_token(CURRENT_ROLE);
+    } else if (jj_2_902(2)) {
+      jj_consume_token(CURRENT_SCHEMA);
+    } else if (jj_2_903(2)) {
+      jj_consume_token(CURRENT_TIME);
+    } else if (jj_2_904(2)) {
+      jj_consume_token(CURRENT_TIMESTAMP);
+    } else if (jj_2_905(2)) {
+      jj_consume_token(CURRENT_USER);
+    } else if (jj_2_906(2)) {
+      jj_consume_token(LOCALTIME);
+    } else if (jj_2_907(2)) {
+      jj_consume_token(LOCALTIMESTAMP);
+    } else if (jj_2_908(2)) {
+      jj_consume_token(SESSION_USER);
+    } else if (jj_2_909(2)) {
+      jj_consume_token(SYSTEM_USER);
+    } else if (jj_2_910(2)) {
+      jj_consume_token(USER);
+    } else {
+      jj_consume_token(-1);
+      throw new ParseException();
+    }
+        {if (true) return new SqlIdentifier(unquotedIdentifier(), getPos());}
+    throw new Error("Missing return statement in function");
+  }
+
+/**
+ * Parses a function call expression with JDBC syntax.
+ */
+  final public SqlNode JdbcFunctionCall() throws ParseException {
+    String name;
+    SqlIdentifier id;
+    SqlNode e;
+    SqlLiteral tl;
+    SqlNodeList args;
+    SqlCall call;
+    final Span s, s1;
+    jj_consume_token(LBRACE_FN);
+        s = span();
+    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+    case TIMESTAMPADD:
+      call = TimestampAddFunctionCall();
+            name = call.getOperator().getName();
+            args = new SqlNodeList(call.getOperandList(), getPos());
+      break;
+    default:
+      jj_la1[9] = jj_gen;
+      if (jj_2_921(3)) {
+        call = TimestampDiffFunctionCall();
+            name = call.getOperator().getName();
+            args = new SqlNodeList(call.getOperandList(), getPos());
+      } else if (jj_2_922(2)) {
+        jj_consume_token(CONVERT);
+                    name = unquotedIdentifier();
+        jj_consume_token(LPAREN);
+        e = Expression(ExprContext.ACCEPT_SUB_QUERY);
+            args = new SqlNodeList(getPos());
+            args.add(e);
+        jj_consume_token(COMMA);
+        tl = JdbcOdbcDataType();
+                                  args.add(tl);
+        jj_consume_token(RPAREN);
+      } else if (jj_2_923(2)) {
+        switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+        case INSERT:
+        case LEFT:
+        case RIGHT:
+        case TRUNCATE:
+          if (jj_2_911(2)) {
+            jj_consume_token(INSERT);
+          } else if (jj_2_912(2)) {
+            jj_consume_token(LEFT);
+          } else if (jj_2_913(2)) {
+            jj_consume_token(RIGHT);
+          } else if (jj_2_914(2)) {
+            jj_consume_token(TRUNCATE);
+          } else {
+            jj_consume_token(-1);
+            throw new ParseException();
+          }
+                                                           name = unquotedIdentifier();
+          break;
+        default:
+          jj_la1[8] = jj_gen;
+          if (jj_2_915(2)) {
+            // For cases like {fn power(1,2)} and {fn lower('a')}
+                        id = ReservedFunctionName();
+                                          name = id.getSimple();
+          } else if (jj_2_916(2)) {
+            // For cases like {fn substring('foo', 1,2)}
+                        name = NonReservedJdbcFunctionName();
+          } else if (jj_2_917(2)) {
+            name = Identifier();
+          } else {
+            jj_consume_token(-1);
+            throw new ParseException();
+          }
+        }
+        if (jj_2_918(2)) {
+          jj_consume_token(LPAREN);
+          jj_consume_token(STAR);
+                                           s1 = span();
+          jj_consume_token(RPAREN);
+                args = new SqlNodeList(s1.pos());
+                args.add(SqlIdentifier.star(s1.pos()));
+        } else if (jj_2_919(2)) {
+          jj_consume_token(LPAREN);
+          jj_consume_token(RPAREN);
+                                             args = SqlNodeList.EMPTY;
+        } else if (jj_2_920(2)) {
+          args = ParenthesizedQueryOrCommaList(ExprContext.ACCEPT_SUB_QUERY);
+        } else {
+          jj_consume_token(-1);
+          throw new ParseException();
+        }
+      } else {
+        jj_consume_token(-1);
+        throw new ParseException();
+      }
+    }
+    jj_consume_token(RBRACE);
+        {if (true) return new SqlJdbcFunctionCall(name).createCall(s.end(this),
+            args.getList());}
+    throw new Error("Missing return statement in function");
+  }
+
+/**
+ * Parses a binary query operator like UNION.
+ */
+  final public SqlBinaryOperator BinaryQueryOperator() throws ParseException {
+    if (jj_2_932(2)) {
+      jj_consume_token(UNION);
+      if (jj_2_924(2)) {
+        jj_consume_token(ALL);
+                    {if (true) return SqlStdOperatorTable.UNION_ALL;}
+      } else if (jj_2_925(2)) {
+        jj_consume_token(DISTINCT);
+                         {if (true) return SqlStdOperatorTable.UNION;}
+      } else {
+              {if (true) return SqlStdOperatorTable.UNION;}
+      }
+    } else if (jj_2_933(2)) {
+      jj_consume_token(INTERSECT);
+      if (jj_2_926(2)) {
+        jj_consume_token(ALL);
+                    {if (true) return SqlStdOperatorTable.INTERSECT_ALL;}
+      } else if (jj_2_927(2)) {
+        jj_consume_token(DISTINCT);
+                         {if (true) return SqlStdOperatorTable.INTERSECT;}
+      } else {
+              {if (true) return SqlStdOperatorTable.INTERSECT;}
+      }
+    } else if (jj_2_934(2)) {
+      if (jj_2_928(2)) {
+        jj_consume_token(EXCEPT);
+      } else if (jj_2_929(2)) {
+        jj_consume_token(SET_MINUS);
+                if (!this.conformance.isMinusAllowed()) {
+                    {if (true) throw SqlUtil.newContextException(getPos(), RESOURCE.minusNotAllowed());}
+                }
+      } else {
+        jj_consume_token(-1);
+        throw new ParseException();
+      }
+      if (jj_2_930(2)) {
+        jj_consume_token(ALL);
+                    {if (true) return SqlStdOperatorTable.EXCEPT_ALL;}
+      } else if (jj_2_931(2)) {
+        jj_consume_token(DISTINCT);
+                         {if (true) return SqlStdOperatorTable.EXCEPT;}
+      } else {
+              {if (true) return SqlStdOperatorTable.EXCEPT;}
+      }
+    } else {
+      jj_consume_token(-1);
+      throw new ParseException();
+    }
+    throw new Error("Missing return statement in function");
+  }
+
+/**
+ * Parses a binary multiset operator.
+ */
+  final public SqlBinaryOperator BinaryMultisetOperator() throws ParseException {
+    jj_consume_token(MULTISET);
+    if (jj_2_944(2)) {
+      jj_consume_token(UNION);
+      if (jj_2_937(2)) {
+        if (jj_2_935(2)) {
+          jj_consume_token(ALL);
+        } else if (jj_2_936(2)) {
+          jj_consume_token(DISTINCT);
+                         {if (true) return SqlStdOperatorTable.MULTISET_UNION_DISTINCT;}
+        } else {
+          jj_consume_token(-1);
+          throw new ParseException();
+        }
+      } else {
+        ;
+      }
+          {if (true) return SqlStdOperatorTable.MULTISET_UNION;}
+    } else if (jj_2_945(2)) {
+      jj_consume_token(INTERSECT);
+      if (jj_2_940(2)) {
+        if (jj_2_938(2)) {
+          jj_consume_token(ALL);
+        } else if (jj_2_939(2)) {
+          jj_consume_token(DISTINCT);
+                         {if (true) return SqlStdOperatorTable.MULTISET_INTERSECT_DISTINCT;}
+        } else {
+          jj_consume_token(-1);
+          throw new ParseException();
+        }
+      } else {
+        ;
+      }
+          {if (true) return SqlStdOperatorTable.MULTISET_INTERSECT;}
+    } else if (jj_2_946(2)) {
+      jj_consume_token(EXCEPT);
+      if (jj_2_943(2)) {
+        if (jj_2_941(2)) {
+          jj_consume_token(ALL);
+        } else if (jj_2_942(2)) {
+          jj_consume_token(DISTINCT);
+                         {if (true) return SqlStdOperatorTable.MULTISET_EXCEPT_DISTINCT;}
+        } else {
+          jj_consume_token(-1);
+          throw new ParseException();
+        }
+      } else {
+        ;
+      }
+          {if (true) return SqlStdOperatorTable.MULTISET_EXCEPT;}
+    } else {
+      jj_consume_token(-1);
+      throw new ParseException();
+    }
+    throw new Error("Missing return statement in function");
+  }
+
+/**
+ * Parses a binary row operator like AND.
+ */
+  final public SqlBinaryOperator BinaryRowOperator() throws ParseException {
+    SqlBinaryOperator op;
+    if (jj_2_947(2)) {
+      jj_consume_token(EQ);
+           {if (true) return SqlStdOperatorTable.EQUALS;}
+    } else if (jj_2_948(2)) {
+      jj_consume_token(GT);
+           {if (true) return SqlStdOperatorTable.GREATER_THAN;}
+    } else if (jj_2_949(2)) {
+      jj_consume_token(LT);
+           {if (true) return SqlStdOperatorTable.LESS_THAN;}
+    } else if (jj_2_950(2)) {
+      jj_consume_token(LE);
+           {if (true) return SqlStdOperatorTable.LESS_THAN_OR_EQUAL;}
+    } else if (jj_2_951(2)) {
+      jj_consume_token(GE);
+           {if (true) return SqlStdOperatorTable.GREATER_THAN_OR_EQUAL;}
+    } else if (jj_2_952(2)) {
+      jj_consume_token(NE);
+           {if (true) return SqlStdOperatorTable.NOT_EQUALS;}
+    } else if (jj_2_953(2)) {
+      jj_consume_token(NE2);
+        if (!this.conformance.isBangEqualAllowed()) {
+            {if (true) throw SqlUtil.newContextException(getPos(), RESOURCE.bangEqualNotAllowed());}
+        }
+        {if (true) return SqlStdOperatorTable.NOT_EQUALS;}
+    } else if (jj_2_954(2)) {
+      jj_consume_token(PLUS);
+             {if (true) return SqlStdOperatorTable.PLUS;}
+    } else if (jj_2_955(2)) {
+      jj_consume_token(MINUS);
+              {if (true) return SqlStdOperatorTable.MINUS;}
+    } else if (jj_2_956(2)) {
+      jj_consume_token(STAR);
+             {if (true) return SqlStdOperatorTable.MULTIPLY;}
+    } else if (jj_2_957(2)) {
+      jj_consume_token(SLASH);
+              {if (true) return SqlStdOperatorTable.DIVIDE;}
+    } else if (jj_2_958(2)) {
+      jj_consume_token(PERCENT_REMAINDER);
+        if (!this.conformance.isPercentRemainderAllowed()) {
+            {if (true) throw SqlUtil.newContextException(getPos(), RESOURCE.percentRemainderNotAllowed());}
+        }
+        {if (true) return SqlStdOperatorTable.PERCENT_REMAINDER;}
+    } else if (jj_2_959(2)) {
+      jj_consume_token(CONCAT);
+               {if (true) return SqlStdOperatorTable.CONCAT;}
+    } else if (jj_2_960(2)) {
+      jj_consume_token(AND);
+            {if (true) return SqlStdOperatorTable.AND;}
+    } else if (jj_2_961(2)) {
+      jj_consume_token(OR);
+           {if (true) return SqlStdOperatorTable.OR;}
+    } else if (jj_2_962(2)) {
+      jj_consume_token(IS);
+      jj_consume_token(DISTINCT);
+      jj_consume_token(FROM);
+                                          {if (true) return SqlStdOperatorTable.IS_DISTINCT_FROM;}
+    } else if (jj_2_963(2)) {
+      jj_consume_token(IS);
+      jj_consume_token(NOT);
+      jj_consume_token(DISTINCT);
+      jj_consume_token(FROM);
+                                   {if (true) return SqlStdOperatorTable.IS_NOT_DISTINCT_FROM;}
+    } else if (jj_2_964(2)) {
+      jj_consume_token(MEMBER);
+      jj_consume_token(OF);
+                    {if (true) return SqlStdOperatorTable.MEMBER_OF;}
+    } else if (jj_2_965(2)) {
+      jj_consume_token(SUBMULTISET);
+      jj_consume_token(OF);
+                                      {if (true) return SqlStdOperatorTable.SUBMULTISET_OF;}
+    } else if (jj_2_966(2)) {
+      jj_consume_token(NOT);
+      jj_consume_token(SUBMULTISET);
+      jj_consume_token(OF);
+                               {if (true) return SqlStdOperatorTable.NOT_SUBMULTISET_OF;}
+    } else if (jj_2_967(2)) {
+      jj_consume_token(CONTAINS);
+                 {if (true) return SqlStdOperatorTable.CONTAINS;}
+    } else if (jj_2_968(2)) {
+      jj_consume_token(OVERLAPS);
+                 {if (true) return SqlStdOperatorTable.OVERLAPS;}
+    } else if (jj_2_969(2)) {
+      jj_consume_token(EQUALS);
+               {if (true) return SqlStdOperatorTable.PERIOD_EQUALS;}
+    } else if (jj_2_970(2)) {
+      jj_consume_token(PRECEDES);
+                 {if (true) return SqlStdOperatorTable.PRECEDES;}
+    } else if (jj_2_971(2)) {
+      jj_consume_token(SUCCEEDS);
+                 {if (true) return SqlStdOperatorTable.SUCCEEDS;}
+    } else if (jj_2_972(2)) {
+      jj_consume_token(IMMEDIATELY);
+      jj_consume_token(PRECEDES);
+                                            {if (true) return SqlStdOperatorTable.IMMEDIATELY_PRECEDES;}
+    } else if (jj_2_973(2)) {
+      jj_consume_token(IMMEDIATELY);
+      jj_consume_token(SUCCEEDS);
+                               {if (true) return SqlStdOperatorTable.IMMEDIATELY_SUCCEEDS;}
+    } else if (jj_2_974(2)) {
+      op = BinaryMultisetOperator();
+                                    {if (true) return op;}
+    } else {
+      jj_consume_token(-1);
+      throw new ParseException();
+    }
+    throw new Error("Missing return statement in function");
+  }
+
+/**
+ * Parses a prefix row operator like NOT.
+ */
+  final public SqlPrefixOperator PrefixRowOperator() throws ParseException {
+    if (jj_2_975(2)) {
+      jj_consume_token(PLUS);
+             {if (true) return SqlStdOperatorTable.UNARY_PLUS;}
+    } else if (jj_2_976(2)) {
+      jj_consume_token(MINUS);
+              {if (true) return SqlStdOperatorTable.UNARY_MINUS;}
+    } else if (jj_2_977(2)) {
+      jj_consume_token(NOT);
+            {if (true) return SqlStdOperatorTable.NOT;}
+    } else if (jj_2_978(2)) {
+      jj_consume_token(EXISTS);
+               {if (true) return SqlStdOperatorTable.EXISTS;}
+    } else if (jj_2_979(2)) {
+      jj_consume_token(UNIQUE);
+               {if (true) return SqlStdOperatorTable.UNIQUE;}
+    } else {
+      jj_consume_token(-1);
+      throw new ParseException();
+    }
+    throw new Error("Missing return statement in function");
+  }
+
+/**
+ * Parses a postfix row operator like IS NOT NULL.
+ */
+  final public SqlPostfixOperator PostfixRowOperator() throws ParseException {
+    if (jj_2_1004(2)) {
+      jj_consume_token(IS);
+      if (jj_2_1001(2)) {
+        jj_consume_token(A);
+        jj_consume_token(SET);
+                    {if (true) return SqlStdOperatorTable.IS_A_SET;}
+      } else if (jj_2_1002(2)) {
+        jj_consume_token(NOT);
+        if (jj_2_980(2)) {
+          jj_consume_token(NULL);
+                     {if (true) return SqlStdOperatorTable.IS_NOT_NULL;}
+        } else if (jj_2_981(2)) {
+          jj_consume_token(TRUE);
+                     {if (true) return SqlStdOperatorTable.IS_NOT_TRUE;}
+        } else if (jj_2_982(2)) {
+          jj_consume_token(FALSE);
+                      {if (true) return SqlStdOperatorTable.IS_NOT_FALSE;}
+        } else if (jj_2_983(2)) {
+          jj_consume_token(UNKNOWN);
+                        {if (true) return SqlStdOperatorTable.IS_NOT_UNKNOWN;}
+        } else if (jj_2_984(2)) {
+          jj_consume_token(A);
+          jj_consume_token(SET);
+                        {if (true) return SqlStdOperatorTable.IS_NOT_A_SET;}
+        } else if (jj_2_985(2)) {
+          jj_consume_token(EMPTY);
+                      {if (true) return SqlStdOperatorTable.IS_NOT_EMPTY;}
+        } else if (jj_2_986(2)) {
+          jj_consume_token(JSON);
+          jj_consume_token(VALUE);
+                                          {if (true) return SqlStdOperatorTable.IS_NOT_JSON_VALUE;}
+        } else if (jj_2_987(2)) {
+          jj_consume_token(JSON);
+          jj_consume_token(OBJECT);
+                                           {if (true) return SqlStdOperatorTable.IS_NOT_JSON_OBJECT;}
+        } else if (jj_2_988(2)) {
+          jj_consume_token(JSON);
+          jj_consume_token(ARRAY);
+                                          {if (true) return SqlStdOperatorTable.IS_NOT_JSON_ARRAY;}
+        } else if (jj_2_989(2)) {
+          jj_consume_token(JSON);
+          jj_consume_token(SCALAR);
+                                           {if (true) return SqlStdOperatorTable.IS_NOT_JSON_SCALAR;}
+        } else if (jj_2_990(2)) {
+          jj_consume_token(JSON);
+                     {if (true) return SqlStdOperatorTable.IS_NOT_JSON_VALUE;}
+        } else {
+          jj_consume_token(-1);
+          throw new ParseException();
+        }
+      } else if (jj_2_1003(2)) {
+        if (jj_2_991(2)) {
+          jj_consume_token(NULL);
+                     {if (true) return SqlStdOperatorTable.IS_NULL;}
+        } else if (jj_2_992(2)) {
+          jj_consume_token(TRUE);
+                     {if (true) return SqlStdOperatorTable.IS_TRUE;}
+        } else if (jj_2_993(2)) {
+          jj_consume_token(FALSE);
+                      {if (true) return SqlStdOperatorTable.IS_FALSE;}
+        } else if (jj_2_994(2)) {
+          jj_consume_token(UNKNOWN);
+                        {if (true) return SqlStdOperatorTable.IS_UNKNOWN;}
+        } else if (jj_2_995(2)) {
+          jj_consume_token(EMPTY);
+                      {if (true) return SqlStdOperatorTable.IS_EMPTY;}
+        } else if (jj_2_996(2)) {
+          jj_consume_token(JSON);
+          jj_consume_token(VALUE);
+                                          {if (true) return SqlStdOperatorTable.IS_JSON_VALUE;}
+        } else if (jj_2_997(2)) {
+          jj_consume_token(JSON);
+          jj_consume_token(OBJECT);
+                                           {if (true) return SqlStdOperatorTable.IS_JSON_OBJECT;}
+        } else if (jj_2_998(2)) {
+          jj_consume_token(JSON);
+          jj_consume_token(ARRAY);
+                                          {if (true) return SqlStdOperatorTable.IS_JSON_ARRAY;}
+        } else if (jj_2_999(2)) {
+          jj_consume_token(JSON);
+          jj_consume_token(SCALAR);
+                                           {if (true) return SqlStdOperatorTable.IS_JSON_SCALAR;}
+        } else if (jj_2_1000(2)) {
+          jj_consume_token(JSON);
+                     {if (true) return SqlStdOperatorTable.IS_JSON_VALUE;}
+        } else {
+          jj_consume_token(-1);
+          throw new ParseException();
+        }
+      } else {
+        jj_consume_token(-1);
+        throw new ParseException();
+      }
+    } else if (jj_2_1005(2)) {
+      jj_consume_token(FORMAT);
+      JsonRepresentation();
+            {if (true) return SqlStdOperatorTable.JSON_VALUE_EXPRESSION;}
+    } else {
+      jj_consume_token(-1);
+      throw new ParseException();
+    }
+    throw new Error("Missing return statement in function");
+  }
+
+/**
+ * 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>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
+ */
+  final public String NonReservedKeyWord() throws ParseException {
+    if (jj_2_1006(2)) {
+      NonReservedKeyWord0of3();
+    } else if (jj_2_1007(2)) {
+      NonReservedKeyWord1of3();
+    } else if (jj_2_1008(2)) {
+      NonReservedKeyWord2of3();
+    } else {
+      jj_consume_token(-1);
+      throw new ParseException();
+    }
+        {if (true) return unquotedIdentifier();}
+    throw new Error("Missing return statement in function");
+  }
+
+/** @see #NonReservedKeyWord */
+  final public void NonReservedKeyWord0of3() throws ParseException {
+    if (jj_2_1009(2)) {
+      jj_consume_token(SEMI);
+    } else if (jj_2_1010(2)) {
+      jj_consume_token(AFFINITY_KEY);
+    } else if (jj_2_1011(2)) {
+      jj_consume_token(CACHE_GROUP);
+    } else if (jj_2_1012(2)) {
+      jj_consume_token(VALUE_TYPE);
+    } else if (jj_2_1013(2)) {
+      jj_consume_token(INLINE_SIZE);
+    } else if (jj_2_1014(2)) {
+      jj_consume_token(PASSWORD);
+    } else if (jj_2_1015(2)) {
+      jj_consume_token(CONTINUOUS);
+    } else if (jj_2_1016(2)) {
+      jj_consume_token(ASYNC);
+    } else if (jj_2_1017(2)) {
+      jj_consume_token(A);
+    } else if (jj_2_1018(2)) {
+      jj_consume_token(ACTION);
+    } else if (jj_2_1019(2)) {
+      jj_consume_token(ALLOCATE);
+    } else if (jj_2_1020(2)) {
+      jj_consume_token(AND);
+    } else if (jj_2_1021(2)) {
+      jj_consume_token(ARRAY_MAX_CARDINALITY);
+    } else if (jj_2_1022(2)) {
+      jj_consume_token(ASENSITIVE);
+    } else if (jj_2_1023(2)) {
+      jj_consume_token(AT);
+    } else if (jj_2_1024(2)) {
+      jj_consume_token(AVG);
+    } else if (jj_2_1025(2)) {
+      jj_consume_token(BEGIN_FRAME);
+    } else if (jj_2_1026(2)) {
+      jj_consume_token(BIGINT);
+    } else if (jj_2_1027(2)) {
+      jj_consume_token(BLOB);
+    } else if (jj_2_1028(2)) {
+      jj_consume_token(BREADTH);
+    } else if (jj_2_1029(2)) {
+      jj_consume_token(CALLED);
+    } else if (jj_2_1030(2)) {
+      jj_consume_token(CASCADED);
+    } else if (jj_2_1031(2)) {
+      jj_consume_token(CEIL);
+    } else if (jj_2_1032(2)) {
+      jj_consume_token(CHARACTER);
+    } else if (jj_2_1033(2)) {
+      jj_consume_token(CHECK);
+    } else if (jj_2_1034(2)) {
+      jj_consume_token(CLOSE);
+    } else if (jj_2_1035(2)) {
+      jj_consume_token(COLLATION);
+    } else if (jj_2_1036(2)) {
+      jj_consume_token(COMMIT);
+    } else if (jj_2_1037(2)) {
+      jj_consume_token(CONNECTION);
+    } else if (jj_2_1038(2)) {
+      jj_consume_token(CONTAINS);
+    } else if (jj_2_1039(2)) {
+      jj_consume_token(CORR);
+    } else if (jj_2_1040(2)) {
+      jj_consume_token(COVAR_POP);
+    } else if (jj_2_1041(2)) {
+      jj_consume_token(CUME_DIST);
+    } else if (jj_2_1042(2)) {
+      jj_consume_token(CURRENT_DEFAULT_TRANSFORM_GROUP);
+    } else if (jj_2_1043(2)) {
+      jj_consume_token(CURRENT_ROW);
+    } else if (jj_2_1044(2)) {
+      jj_consume_token(CURRENT_TIMESTAMP);
+    } else if (jj_2_1045(2)) {
+      jj_consume_token(CYCLE);
+    } else if (jj_2_1046(2)) {
+      jj_consume_token(DAY);
+    } else if (jj_2_1047(2)) {
+      jj_consume_token(DECIMAL);
+    } else if (jj_2_1048(2)) {
+      jj_consume_token(DEFERRED);
+    } else if (jj_2_1049(2)) {
+      jj_consume_token(DEREF);
+    } else if (jj_2_1050(2)) {
+      jj_consume_token(DETERMINISTIC);
+    } else if (jj_2_1051(2)) {
+      jj_consume_token(DISCONNECT);
+    } else if (jj_2_1052(2)) {
+      jj_consume_token(DYNAMIC);
+    } else if (jj_2_1053(2)) {
+      jj_consume_token(ELSE);
+    } else if (jj_2_1054(2)) {
+      jj_consume_token(END_FRAME);
+    } else if (jj_2_1055(2)) {
+      jj_consume_token(ESCAPE);
+    } else if (jj_2_1056(2)) {
+      jj_consume_token(EXEC);
+    } else if (jj_2_1057(2)) {
+      jj_consume_token(EXP);
+    } else if (jj_2_1058(2)) {
+      jj_consume_token(EXTRACT);
+    } else if (jj_2_1059(2)) {
+      jj_consume_token(FIRST);
+    } else if (jj_2_1060(2)) {
+      jj_consume_token(FLOOR);
+    } else if (jj_2_1061(2)) {
+      jj_consume_token(FOUND);
+    } else if (jj_2_1062(2)) {
+      jj_consume_token(FUNCTION);
+    } else if (jj_2_1063(2)) {
+      jj_consume_token(GENERAL);
+    } else if (jj_2_1064(2)) {
+      jj_consume_token(GO);
+    } else if (jj_2_1065(2)) {
+      jj_consume_token(HOLD);
+    } else if (jj_2_1066(2)) {
+      jj_consume_token(IMMEDIATE);
+    } else if (jj_2_1067(2)) {
+      jj_consume_token(INDICATOR);
+    } else if (jj_2_1068(2)) {
+      jj_consume_token(INOUT);
+    } else if (jj_2_1069(2)) {
+      jj_consume_token(INT);
+    } else if (jj_2_1070(2)) {
+      jj_consume_token(IS);
+    } else if (jj_2_1071(2)) {
+      jj_consume_token(JSON_ARRAYAGG);
+    } else if (jj_2_1072(2)) {
+      jj_consume_token(JSON_OBJECTAGG);
+    } else if (jj_2_1073(2)) {
+      jj_consume_token(K);
+    } else if (jj_2_1074(2)) {
+      jj_consume_token(LANGUAGE);
+    } else if (jj_2_1075(2)) {
+      jj_consume_token(LAST_VALUE);
+    } else if (jj_2_1076(2)) {
+      jj_consume_token(LENGTH);
+    } else if (jj_2_1077(2)) {
+      jj_consume_token(LIKE_REGEX);
+    } else if (jj_2_1078(2)) {
+      jj_consume_token(LOCALTIME);
+    } else if (jj_2_1079(2)) {
+      jj_consume_token(LOWER);
+    } else if (jj_2_1080(2)) {
+      jj_consume_token(MATCH);
+    } else if (jj_2_1081(2)) {
+      jj_consume_token(MAX);
+    } else if (jj_2_1082(2)) {
+      jj_consume_token(METHOD);
+    } else if (jj_2_1083(2)) {
+      jj_consume_token(MOD);
+    } else if (jj_2_1084(2)) {
+      jj_consume_token(MONTH);
+    } else if (jj_2_1085(2)) {
+      jj_consume_token(NAMES);
+    } else if (jj_2_1086(2)) {
+      jj_consume_token(NCLOB);
+    } else if (jj_2_1087(2)) {
+      jj_consume_token(NORMALIZE);
+    } else if (jj_2_1088(2)) {
+      jj_consume_token(NTILE);
+    } else if (jj_2_1089(2)) {
+      jj_consume_token(OBJECT);
+    } else if (jj_2_1090(2)) {
+      jj_consume_token(OF);
+    } else if (jj_2_1091(2)) {
+      jj_consume_token(ONE);
+    } else if (jj_2_1092(2)) {
+      jj_consume_token(OPTION);
+    } else if (jj_2_1093(2)) {
+      jj_consume_token(OUT);
+    } else if (jj_2_1094(2)) {
+      jj_consume_token(OVERLAY);
+    } else if (jj_2_1095(2)) {
+      jj_consume_token(PARTIAL);
+    } else if (jj_2_1096(2)) {
+      jj_consume_token(PERCENT);
+    } else if (jj_2_1097(2)) {
+      jj_consume_token(PERCENT_RANK);
+    } else if (jj_2_1098(2)) {
+      jj_consume_token(PORTION);
+    } else if (jj_2_1099(2)) {
+      jj_consume_token(POWER);
+    } else if (jj_2_1100(2)) {
+      jj_consume_token(PREPARE);
+    } else if (jj_2_1101(2)) {
+      jj_consume_token(PRIOR);
+    } else if (jj_2_1102(2)) {
+      jj_consume_token(PUBLIC);
+    } else if (jj_2_1103(2)) {
+      jj_consume_token(READ);
+    } else if (jj_2_1104(2)) {
+      jj_consume_token(RECURSIVE);
+    } else if (jj_2_1105(2)) {
+      jj_consume_token(REFERENCING);
+    } else if (jj_2_1106(2)) {
+      jj_consume_token(REGR_COUNT);
+    } else if (jj_2_1107(2)) {
+      jj_consume_token(REGR_SLOPE);
+    } else if (jj_2_1108(2)) {
+      jj_consume_token(REGR_SYY);
+    } else if (jj_2_1109(2)) {
+      jj_consume_token(REPLACE);
+    } else if (jj_2_1110(2)) {
+      jj_consume_token(RESULT);
+    } else if (jj_2_1111(2)) {
+      jj_consume_token(REVOKE);
+    } else if (jj_2_1112(2)) {
+      jj_consume_token(ROUTINE);
+    } else if (jj_2_1113(2)) {
+      jj_consume_token(SAVEPOINT);
+    } else if (jj_2_1114(2)) {
+      jj_consume_token(SCROLL);
+    } else if (jj_2_1115(2)) {
+      jj_consume_token(SECTION);
+    } else if (jj_2_1116(2)) {
+      jj_consume_token(SESSION);
+    } else if (jj_2_1117(2)) {
+      jj_consume_token(SIMILAR);
+    } else if (jj_2_1118(2)) {
+      jj_consume_token(SPACE);
+    } else if (jj_2_1119(2)) {
+      jj_consume_token(SQL);
+    } else if (jj_2_1120(2)) {
+      jj_consume_token(SQLWARNING);
+    } else if (jj_2_1121(2)) {
+      jj_consume_token(STATE);
+    } else if (jj_2_1122(2)) {
+      jj_consume_token(STDDEV_SAMP);
+    } else if (jj_2_1123(2)) {
+      jj_consume_token(SUBSTRING);
+    } else if (jj_2_1124(2)) {
+      jj_consume_token(SUM);
+    } else if (jj_2_1125(2)) {
+      jj_consume_token(SYSTEM_TIME);
+    } else if (jj_2_1126(2)) {
+      jj_consume_token(TIMEZONE_HOUR);
+    } else if (jj_2_1127(2)) {
+      jj_consume_token(TO);
+    } else if (jj_2_1128(2)) {
+      jj_consume_token(TRANSLATE);
+    } else if (jj_2_1129(2)) {
+      jj_consume_token(TREAT);
+    } else if (jj_2_1130(2)) {
+      jj_consume_token(TRIM_ARRAY);
+    } else if (jj_2_1131(2)) {
+      jj_consume_token(UESCAPE);
+    } else if (jj_2_1132(2)) {
+      jj_consume_token(UNKNOWN);
+    } else if (jj_2_1133(2)) {
+      jj_consume_token(USAGE);
+    } else if (jj_2_1134(2)) {
+      jj_consume_token(VALUE_OF);
+    } else if (jj_2_1135(2)) {
+      jj_consume_token(VARYING);
+    } else if (jj_2_1136(2)) {
+      jj_consume_token(VERSION);
+    } else if (jj_2_1137(2)) {
+      jj_consume_token(WEEK);
+    } else if (jj_2_1138(2)) {
+      jj_consume_token(WITHIN);
+    } else if (jj_2_1139(2)) {
+      jj_consume_token(WRITE);
+    } else {
+      jj_consume_token(-1);
+      throw new ParseException();
+    }
+  }
+
+/** @see #NonReservedKeyWord */
+  final public void NonReservedKeyWord1of3() throws ParseException {
+    if (jj_2_1140(2)) {
+      jj_consume_token(TEMPLATE);
+    } else if (jj_2_1141(2)) {
+      jj_consume_token(ATOMICITY);
+    } else if (jj_2_1142(2)) {
+      jj_consume_token(CACHE_NAME);
+    } else if (jj_2_1143(2)) {
+      jj_consume_token(ENCRYPTED);
+    } else if (jj_2_1144(2)) {
+      jj_consume_token(LOGGING);
+    } else if (jj_2_1145(2)) {
+      jj_consume_token(KILL);
+    } else if (jj_2_1146(2)) {
+      jj_consume_token(SERVICE);
+    } else if (jj_2_1147(2)) {
+      jj_consume_token(QUERY);
+    } else if (jj_2_1148(2)) {
+      jj_consume_token(ABS);
+    } else if (jj_2_1149(2)) {
+      jj_consume_token(ADD);
+    } else if (jj_2_1150(2)) {
+      jj_consume_token(ALLOW);
+    } else if (jj_2_1151(2)) {
+      jj_consume_token(ARE);
+    } else if (jj_2_1152(2)) {
+      jj_consume_token(AS);
+    } else if (jj_2_1153(2)) {
+      jj_consume_token(ASSERTION);
+    } else if (jj_2_1154(2)) {
+      jj_consume_token(ATOMIC);
+    } else if (jj_2_1155(2)) {
+      jj_consume_token(BEFORE);
+    } else if (jj_2_1156(2)) {
+      jj_consume_token(BEGIN_PARTITION);
+    } else if (jj_2_1157(2)) {
+      jj_consume_token(BINARY);
+    } else if (jj_2_1158(2)) {
+      jj_consume_token(BOOLEAN);
+    } else if (jj_2_1159(2)) {
+      jj_consume_token(BY);
+    } else if (jj_2_1160(2)) {
+      jj_consume_token(CARDINALITY);
+    } else if (jj_2_1161(2)) {
+      jj_consume_token(CAST);
+    } else if (jj_2_1162(2)) {
+      jj_consume_token(CEILING);
+    } else if (jj_2_1163(2)) {
+      jj_consume_token(CHARACTER_LENGTH);
+    } else if (jj_2_1164(2)) {
+      jj_consume_token(CLASSIFIER);
+    } else if (jj_2_1165(2)) {
+      jj_consume_token(COALESCE);
+    } else if (jj_2_1166(2)) {
+      jj_consume_token(COLLECT);
+    } else if (jj_2_1167(2)) {
+      jj_consume_token(CONDITION);
+    } else if (jj_2_1168(2)) {
+      jj_consume_token(CONSTRAINTS);
+    } else if (jj_2_1169(2)) {
+      jj_consume_token(CONTINUE);
+    } else if (jj_2_1170(2)) {
+      jj_consume_token(CORRESPONDING);
+    } else if (jj_2_1171(2)) {
+      jj_consume_token(COVAR_SAMP);
+    } else if (jj_2_1172(2)) {
+      jj_consume_token(CURRENT_CATALOG);
+    } else if (jj_2_1173(2)) {
+      jj_consume_token(CURRENT_PATH);
+    } else if (jj_2_1174(2)) {
+      jj_consume_token(CURRENT_SCHEMA);
+    } else if (jj_2_1175(2)) {
+      jj_consume_token(CURRENT_TRANSFORM_GROUP_FOR_TYPE);
+    } else if (jj_2_1176(2)) {
+      jj_consume_token(DATA);
+    } else if (jj_2_1177(2)) {
+      jj_consume_token(DEALLOCATE);
+    } else if (jj_2_1178(2)) {
+      jj_consume_token(DECLARE);
+    } else if (jj_2_1179(2)) {
+      jj_consume_token(DENSE_RANK);
+    } else if (jj_2_1180(2)) {
+      jj_consume_token(DESC);
+    } else if (jj_2_1181(2)) {
+      jj_consume_token(DIAGNOSTICS);
+    } else if (jj_2_1182(2)) {
+      jj_consume_token(DOMAIN);
+    } else if (jj_2_1183(2)) {
+      jj_consume_token(EACH);
+    } else if (jj_2_1184(2)) {
+      jj_consume_token(EMPTY);
+    } else if (jj_2_1185(2)) {
+      jj_consume_token(END_PARTITION);
+    } else if (jj_2_1186(2)) {
+      jj_consume_token(EVERY);
+    } else if (jj_2_1187(2)) {
+      jj_consume_token(EXECUTE);
+    } else if (jj_2_1188(2)) {
+      jj_consume_token(EXTEND);
+    } else if (jj_2_1189(2)) {
+      jj_consume_token(FALSE);
+    } else if (jj_2_1190(2)) {
+      jj_consume_token(FIRST_VALUE);
+    } else if (jj_2_1191(2)) {
+      jj_consume_token(FOR);
+    } else if (jj_2_1192(2)) {
+      jj_consume_token(FRAME_ROW);
+    } else if (jj_2_1193(2)) {
+      jj_consume_token(FUSION);
+    } else if (jj_2_1194(2)) {
+      jj_consume_token(GET);
+    } else if (jj_2_1195(2)) {
+      jj_consume_token(GOTO);
+    } else if (jj_2_1196(2)) {
+      jj_consume_token(HOUR);
+    } else if (jj_2_1197(2)) {
+      jj_consume_token(IMMEDIATELY);
+    } else if (jj_2_1198(2)) {
+      jj_consume_token(INITIAL);
+    } else if (jj_2_1199(2)) {
+      jj_consume_token(INPUT);
+    } else if (jj_2_1200(2)) {
+      jj_consume_token(INTEGER);
+    } else if (jj_2_1201(2)) {
+      jj_consume_token(ISOLATION);
+    } else if (jj_2_1202(2)) {
+      jj_consume_token(JSON_EXISTS);
+    } else if (jj_2_1203(2)) {
+      jj_consume_token(JSON_QUERY);
+    } else if (jj_2_1204(2)) {
+      jj_consume_token(KEY);
+    } else if (jj_2_1205(2)) {
+      jj_consume_token(LARGE);
+    } else if (jj_2_1206(2)) {
+      jj_consume_token(LEAD);
+    } else if (jj_2_1207(2)) {
+      jj_consume_token(LEVEL);
+    } else if (jj_2_1208(2)) {
+      jj_consume_token(LN);
+    } else if (jj_2_1209(2)) {
+      jj_consume_token(LOCALTIMESTAMP);
+    } else if (jj_2_1210(2)) {
+      jj_consume_token(M);
+    } else if (jj_2_1211(2)) {
+      jj_consume_token(MATCHES);
+    } else if (jj_2_1212(2)) {
+      jj_consume_token(MEASURES);
+    } else if (jj_2_1213(2)) {
+      jj_consume_token(MIN);
+    } else if (jj_2_1214(2)) {
+      jj_consume_token(MODIFIES);
+    } else if (jj_2_1215(2)) {
+      jj_consume_token(MULTISET);
+    } else if (jj_2_1216(2)) {
+      jj_consume_token(NATIONAL);
+    } else if (jj_2_1217(2)) {
+      jj_consume_token(NO);
+    } else if (jj_2_1218(2)) {
+      jj_consume_token(NOT);
+    } else if (jj_2_1219(2)) {
+      jj_consume_token(NULLIF);
+    } else if (jj_2_1220(2)) {
+      jj_consume_token(OCCURRENCES_REGEX);
+    } else if (jj_2_1221(2)) {
+      jj_consume_token(OLD);
+    } else if (jj_2_1222(2)) {
+      jj_consume_token(ONLY);
+    } else if (jj_2_1223(2)) {
+      jj_consume_token(OR);
+    } else if (jj_2_1224(2)) {
+      jj_consume_token(OUTPUT);
+    } else if (jj_2_1225(2)) {
+      jj_consume_token(PAD);
+    } else if (jj_2_1226(2)) {
+      jj_consume_token(PATH);
+    } else if (jj_2_1227(2)) {
+      jj_consume_token(PERCENTILE_CONT);
+    } else if (jj_2_1228(2)) {
+      jj_consume_token(PERIOD);
+    } else if (jj_2_1229(2)) {
+      jj_consume_token(POSITION);
+    } else if (jj_2_1230(2)) {
+      jj_consume_token(PRECEDES);
+    } else if (jj_2_1231(2)) {
+      jj_consume_token(PRESERVE);
+    } else if (jj_2_1232(2)) {
+      jj_consume_token(PRIVILEGES);
+    } else if (jj_2_1233(2)) {
+      jj_consume_token(QUARTER);
+    } else if (jj_2_1234(2)) {
+      jj_consume_token(READS);
+    } else if (jj_2_1235(2)) {
+      jj_consume_token(REF);
+    } else if (jj_2_1236(2)) {
+      jj_consume_token(REGR_AVGX);
+    } else if (jj_2_1237(2)) {
+      jj_consume_token(REGR_INTERCEPT);
+    } else if (jj_2_1238(2)) {
+      jj_consume_token(REGR_SXX);
+    } else if (jj_2_1239(2)) {
+      jj_consume_token(RELATIVE);
+    } else if (jj_2_1240(2)) {
+      jj_consume_token(RESET);
+    } else if (jj_2_1241(2)) {
+      jj_consume_token(RETURN);
+    } else if (jj_2_1242(2)) {
+      jj_consume_token(ROLE);
+    } else if (jj_2_1243(2)) {
+      jj_consume_token(ROW_NUMBER);
+    } else if (jj_2_1244(2)) {
+      jj_consume_token(SCHEMA);
+    } else if (jj_2_1245(2)) {
+      jj_consume_token(SEARCH);
+    } else if (jj_2_1246(2)) {
+      jj_consume_token(SEEK);
+    } else if (jj_2_1247(2)) {
+      jj_consume_token(SESSION_USER);
+    } else if (jj_2_1248(2)) {
+      jj_consume_token(SIZE);
+    } else if (jj_2_1249(2)) {
+      jj_consume_token(SPECIFIC);
+    } else if (jj_2_1250(2)) {
+      jj_consume_token(SQLEXCEPTION);
+    } else if (jj_2_1251(2)) {
+      jj_consume_token(SQRT);
+    } else if (jj_2_1252(2)) {
+      jj_consume_token(STATIC);
+    } else if (jj_2_1253(2)) {
+      jj_consume_token(SUBMULTISET);
+    } else if (jj_2_1254(2)) {
+      jj_consume_token(SUBSTRING_REGEX);
+    } else if (jj_2_1255(2)) {
+      jj_consume_token(SYMMETRIC);
+    } else if (jj_2_1256(2)) {
+      jj_consume_token(SYSTEM_USER);
+    } else if (jj_2_1257(2)) {
+      jj_consume_token(TIMEZONE_MINUTE);
+    } else if (jj_2_1258(2)) {
+      jj_consume_token(TRAILING);
+    } else if (jj_2_1259(2)) {
+      jj_consume_token(TRANSLATE_REGEX);
+    } else if (jj_2_1260(2)) {
+      jj_consume_token(TRIGGER);
+    } else if (jj_2_1261(2)) {
+      jj_consume_token(TRUE);
+    } else if (jj_2_1262(2)) {
+      jj_consume_token(UNDER);
+    } else if (jj_2_1263(2)) {
+      jj_consume_token(UPPER);
+    } else if (jj_2_1264(2)) {
+      jj_consume_token(USER);
+    } else if (jj_2_1265(2)) {
+      jj_consume_token(VARBINARY);
+    } else if (jj_2_1266(2)) {
+      jj_consume_token(VAR_POP);
+    } else if (jj_2_1267(2)) {
+      jj_consume_token(VERSIONING);
+    } else if (jj_2_1268(2)) {
+      jj_consume_token(WHENEVER);
+    } else if (jj_2_1269(2)) {
+      jj_consume_token(WITHOUT);
+    } else if (jj_2_1270(2)) {
+      jj_consume_token(YEAR);
+    } else {
+      jj_consume_token(-1);
+      throw new ParseException();
+    }
+  }
+
+/** @see #NonReservedKeyWord */
+  final public void NonReservedKeyWord2of3() throws ParseException {
+    if (jj_2_1271(2)) {
+      jj_consume_token(BACKUPS);
+    } else if (jj_2_1272(2)) {
+      jj_consume_token(WRITE_SYNCHRONIZATION_MODE);
+    } else if (jj_2_1273(2)) {
+      jj_consume_token(DATA_REGION);
+    } else if (jj_2_1274(2)) {
+      jj_consume_token(PARALLEL);
+    } else if (jj_2_1275(2)) {
+      jj_consume_token(NOLOGGING);
+    } else if (jj_2_1276(2)) {
+      jj_consume_token(SCAN);
+    } else if (jj_2_1277(2)) {
+      jj_consume_token(COMPUTE);
+    } else if (jj_2_1278(2)) {
+      jj_consume_token(UUID);
+    } else if (jj_2_1279(2)) {
+      jj_consume_token(ABSOLUTE);
+    } else if (jj_2_1280(2)) {
+      jj_consume_token(AFTER);
+    } else if (jj_2_1281(2)) {
+      jj_consume_token(ALTER);
+    } else if (jj_2_1282(2)) {
+      jj_consume_token(ARRAY);
+    } else if (jj_2_1283(2)) {
+      jj_consume_token(ASC);
+    } else if (jj_2_1284(2)) {
+      jj_consume_token(ASYMMETRIC);
+    } else if (jj_2_1285(2)) {
+      jj_consume_token(AUTHORIZATION);
+    } else if (jj_2_1286(2)) {
+      jj_consume_token(BEGIN);
+    } else if (jj_2_1287(2)) {
+      jj_consume_token(BETWEEN);
+    } else if (jj_2_1288(2)) {
+      jj_consume_token(BIT);
+    } else if (jj_2_1289(2)) {
+      jj_consume_token(BOTH);
+    } else if (jj_2_1290(2)) {
+      jj_consume_token(C);
+    } else if (jj_2_1291(2)) {
+      jj_consume_token(CASCADE);
+    } else if (jj_2_1292(2)) {
+      jj_consume_token(CATALOG);
+    } else if (jj_2_1293(2)) {
+      jj_consume_token(CHAR);
+    } else if (jj_2_1294(2)) {
+      jj_consume_token(CHAR_LENGTH);
+    } else if (jj_2_1295(2)) {
+      jj_consume_token(CLOB);
+    } else if (jj_2_1296(2)) {
+      jj_consume_token(COLLATE);
+    } else if (jj_2_1297(2)) {
+      jj_consume_token(COLUMN);
+    } else if (jj_2_1298(2)) {
+      jj_consume_token(CONNECT);
+    } else if (jj_2_1299(2)) {
+      jj_consume_token(CONSTRUCTOR);
+    } else if (jj_2_1300(2)) {
+      jj_consume_token(CONVERT);
+    } else if (jj_2_1301(2)) {
+      jj_consume_token(COUNT);
+    } else if (jj_2_1302(2)) {
+      jj_consume_token(CUBE);
+    } else if (jj_2_1303(2)) {
+      jj_consume_token(CURRENT_DATE);
+    } else if (jj_2_1304(2)) {
+      jj_consume_token(CURRENT_ROLE);
+    } else if (jj_2_1305(2)) {
+      jj_consume_token(CURRENT_TIME);
+    } else if (jj_2_1306(2)) {
+      jj_consume_token(CURRENT_USER);
+    } else if (jj_2_1307(2)) {
+      jj_consume_token(DATE);
+    } else if (jj_2_1308(2)) {
+      jj_consume_token(DEC);
+    } else if (jj_2_1309(2)) {
+      jj_consume_token(DEFERRABLE);
+    } else if (jj_2_1310(2)) {
+      jj_consume_token(DEPTH);
+    } else if (jj_2_1311(2)) {
+      jj_consume_token(DESCRIPTOR);
+    } else if (jj_2_1312(2)) {
+      jj_consume_token(DISALLOW);
+    } else if (jj_2_1313(2)) {
+      jj_consume_token(DOUBLE);
+    } else if (jj_2_1314(2)) {
+      jj_consume_token(ELEMENT);
+    } else if (jj_2_1315(2)) {
+      jj_consume_token(END);
+    } else if (jj_2_1316(2)) {
+      jj_consume_token(EQUALS);
+    } else if (jj_2_1317(2)) {
+      jj_consume_token(EXCEPTION);
+    } else if (jj_2_1318(2)) {
+      jj_consume_token(EXISTS);
+    } else if (jj_2_1319(2)) {
+      jj_consume_token(EXTERNAL);
+    } else if (jj_2_1320(2)) {
+      jj_consume_token(FILTER);
+    } else if (jj_2_1321(2)) {
+      jj_consume_token(FLOAT);
+    } else if (jj_2_1322(2)) {
+      jj_consume_token(FOREIGN);
+    } else if (jj_2_1323(2)) {
+      jj_consume_token(FREE);
+    } else if (jj_2_1324(2)) {
+      jj_consume_token(G);
+    } else if (jj_2_1325(2)) {
+      jj_consume_token(GLOBAL);
+    } else if (jj_2_1326(2)) {
+      jj_consume_token(GROUPS);
+    } else if (jj_2_1327(2)) {
+      jj_consume_token(IDENTITY);
+    } else if (jj_2_1328(2)) {
+      jj_consume_token(IMPORT);
+    } else if (jj_2_1329(2)) {
+      jj_consume_token(INITIALLY);
+    } else if (jj_2_1330(2)) {
+      jj_consume_token(INSENSITIVE);
+    } else if (jj_2_1331(2)) {
+      jj_consume_token(INTERSECTION);
+    } else if (jj_2_1332(2)) {
+      jj_consume_token(JSON_ARRAY);
+    } else if (jj_2_1333(2)) {
+      jj_consume_token(JSON_OBJECT);
+    } else if (jj_2_1334(2)) {
+      jj_consume_token(JSON_VALUE);
+    } else if (jj_2_1335(2)) {
+      jj_consume_token(LAG);
+    } else if (jj_2_1336(2)) {
+      jj_consume_token(LAST);
+    } else if (jj_2_1337(2)) {
+      jj_consume_token(LEADING);
+    } else if (jj_2_1338(2)) {
+      jj_consume_token(LIKE);
+    } else if (jj_2_1339(2)) {
+      jj_consume_token(LOCAL);
+    } else if (jj_2_1340(2)) {
+      jj_consume_token(LOCATOR);
+    } else if (jj_2_1341(2)) {
+      jj_consume_token(MAP);
+    } else if (jj_2_1342(2)) {
+      jj_consume_token(MATCH_NUMBER);
+    } else if (jj_2_1343(2)) {
+      jj_consume_token(MEMBER);
+    } else if (jj_2_1344(2)) {
+      jj_consume_token(MINUTE);
+    } else if (jj_2_1345(2)) {
+      jj_consume_token(MODULE);
+    } else if (jj_2_1346(2)) {
+      jj_consume_token(NAME);
+    } else if (jj_2_1347(2)) {
+      jj_consume_token(NCHAR);
+    } else if (jj_2_1348(2)) {
+      jj_consume_token(NONE);
+    } else if (jj_2_1349(2)) {
+      jj_consume_token(NTH_VALUE);
+    } else if (jj_2_1350(2)) {
+      jj_consume_token(NUMERIC);
+    } else if (jj_2_1351(2)) {
+      jj_consume_token(OCTET_LENGTH);
+    } else if (jj_2_1352(2)) {
+      jj_consume_token(OMIT);
+    } else if (jj_2_1353(2)) {
+      jj_consume_token(OPEN);
+    } else if (jj_2_1354(2)) {
+      jj_consume_token(ORDINALITY);
+    } else if (jj_2_1355(2)) {
+      jj_consume_token(OVERLAPS);
+    } else if (jj_2_1356(2)) {
+      jj_consume_token(PARAMETER);
+    } else if (jj_2_1357(2)) {
+      jj_consume_token(PER);
+    } else if (jj_2_1358(2)) {
+      jj_consume_token(PERCENTILE_DISC);
+    } else if (jj_2_1359(2)) {
+      jj_consume_token(PERMUTE);
+    } else if (jj_2_1360(2)) {
+      jj_consume_token(POSITION_REGEX);
+    } else if (jj_2_1361(2)) {
+      jj_consume_token(PRECISION);
+    } else if (jj_2_1362(2)) {
+      jj_consume_token(PREV);
+    } else if (jj_2_1363(2)) {
+      jj_consume_token(PROCEDURE);
+    } else if (jj_2_1364(2)) {
+      jj_consume_token(RANK);
+    } else if (jj_2_1365(2)) {
+      jj_consume_token(REAL);
+    } else if (jj_2_1366(2)) {
+      jj_consume_token(REFERENCES);
+    } else if (jj_2_1367(2)) {
+      jj_consume_token(REGR_AVGY);
+    } else if (jj_2_1368(2)) {
+      jj_consume_token(REGR_R2);
+    } else if (jj_2_1369(2)) {
+      jj_consume_token(REGR_SXY);
+    } else if (jj_2_1370(2)) {
+      jj_consume_token(RELEASE);
+    } else if (jj_2_1371(2)) {
+      jj_consume_token(RESTRICT);
+    } else if (jj_2_1372(2)) {
+      jj_consume_token(RETURNS);
+    } else if (jj_2_1373(2)) {
+      jj_consume_token(ROLLBACK);
+    } else if (jj_2_1374(2)) {
+      jj_consume_token(RUNNING);
+    } else if (jj_2_1375(2)) {
+      jj_consume_token(SCOPE);
+    } else if (jj_2_1376(2)) {
+      jj_consume_token(SECOND);
+    } else if (jj_2_1377(2)) {
+      jj_consume_token(SENSITIVE);
+    } else if (jj_2_1378(2)) {
+      jj_consume_token(SHOW);
+    } else if (jj_2_1379(2)) {
+      jj_consume_token(SMALLINT);
+    } else if (jj_2_1380(2)) {
+      jj_consume_token(SPECIFICTYPE);
+    } else if (jj_2_1381(2)) {
+      jj_consume_token(SQLSTATE);
+    } else if (jj_2_1382(2)) {
+      jj_consume_token(START);
+    } else if (jj_2_1383(2)) {
+      jj_consume_token(STDDEV_POP);
+    } else if (jj_2_1384(2)) {
+      jj_consume_token(SUBSET);
+    } else if (jj_2_1385(2)) {
+      jj_consume_token(SUCCEEDS);
+    } else if (jj_2_1386(2)) {
+      jj_consume_token(SYSTEM);
+    } else if (jj_2_1387(2)) {
+      jj_consume_token(TEMPORARY);
+    } else if (jj_2_1388(2)) {
+      jj_consume_token(TINYINT);
+    } else if (jj_2_1389(2)) {
+      jj_consume_token(TRANSACTION);
+    } else if (jj_2_1390(2)) {
+      jj_consume_token(TRANSLATION);
+    } else if (jj_2_1391(2)) {
+      jj_consume_token(TRIM);
+    } else if (jj_2_1392(2)) {
+      jj_consume_token(TRUNCATE);
+    } else if (jj_2_1393(2)) {
+      jj_consume_token(UNIQUE);
+    } else if (jj_2_1394(2)) {
+      jj_consume_token(UPSERT);
+    } else if (jj_2_1395(2)) {
+      jj_consume_token(VALUE);
+    } else if (jj_2_1396(2)) {
+      jj_consume_token(VARCHAR);
+    } else if (jj_2_1397(2)) {
+      jj_consume_token(VAR_SAMP);
+    } else if (jj_2_1398(2)) {
+      jj_consume_token(VIEW);
+    } else if (jj_2_1399(2)) {
+      jj_consume_token(WIDTH_BUCKET);
+    } else if (jj_2_1400(2)) {
+      jj_consume_token(WORK);
+    } else if (jj_2_1401(2)) {
+      jj_consume_token(ZONE);
+    } else {
+      jj_consume_token(-1);
+      throw new ParseException();
+    }
+  }
+
+/**
+ * Defines a production which can never be accepted by the parser.
+ * In effect, it tells the parser, "If you got here, you've gone too far."
+ * It is used as the default production for parser extension points;
+ * derived parsers replace it with a real production when they want to
+ * implement a particular extension point.
+ */
+  final public void UnusedExtension() throws ParseException {
+    if (false) {
+
+    } else {
+      jj_consume_token(-1);
+      throw new ParseException();
+    }
+    jj_consume_token(ZONE);
+  }
+
+  final private boolean jj_2_1(int xla) {
+    jj_la = xla; jj_lastpos = jj_scanpos = token;
+    try { return !jj_3_1(); }
+    catch(LookaheadSuccess ls) { return true; }
+    finally { jj_save(0, xla); }
+  }
+
+  final private boolean jj_2_2(int xla) {
+    jj_la = xla; jj_lastpos = jj_scanpos = token;
+    try { return !jj_3_2(); }
+    catch(LookaheadSuccess ls) { return true; }
+    finally { jj_save(1, xla); }
+  }
+
+  final private boolean jj_2_3(int xla) {
+    jj_la = xla; jj_lastpos = jj_scanpos = token;
+    try { return !jj_3_3(); }
+    catch(LookaheadSuccess ls) { return true; }
+    finally { jj_save(2, xla); }
+  }
+
+  final private boolean jj_2_4(int xla) {
+    jj_la = xla; jj_lastpos = jj_scanpos = token;
+    try { return !jj_3_4(); }
+    catch(LookaheadSuccess ls) { return true; }
+    finally { jj_save(3, xla); }
+  }
+
+  final private boolean jj_2_5(int xla) {
+    jj_la = xla; jj_lastpos = jj_scanpos = token;
+    try { return !jj_3_5(); }
+    catch(LookaheadSuccess ls) { return true; }
+    finally { jj_save(4, xla); }
+  }
+
+  final private boolean jj_2_6(int xla) {
+    jj_la = xla; jj_lastpos = jj_scanpos = token;
+    try { return !jj_3_6(); }
+    catch(LookaheadSuccess ls) { return true; }
+    finally { jj_save(5, xla); }
+  }
+
+  final private boolean jj_2_7(int xla) {
+    jj_la = xla; jj_lastpos = jj_scanpos = token;
+    try { return !jj_3_7(); }
+    catch(LookaheadSuccess ls) { return true; }
+    finally { jj_save(6, xla); }
+  }
+
+  final private boolean jj_2_8(int xla) {
+    jj_la = xla; jj_lastpos = jj_scanpos = token;
+    try { return !jj_3_8(); }
+    catch(LookaheadSuccess ls) { return true; }
+    finally { jj_save(7, xla); }
+  }
+
+  final private boolean jj_2_9(int xla) {
+    jj_la = xla; jj_lastpos = jj_scanpos = token;
+    try { return !jj_3_9(); }
+    catch(LookaheadSuccess ls) { return true; }
+    finally { jj_save(8, xla); }
+  }
+
+  final private boolean jj_2_10(int xla) {
+    jj_la = xla; jj_lastpos = jj_scanpos = token;
+    try { return !jj_3_10(); }
+    catch(LookaheadSuccess ls) { return true; }
+    finally { jj_save(9, xla); }
+  }
... 52684 lines suppressed ...