You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@calcite.apache.org by el...@apache.org on 2017/04/01 20:36:04 UTC

[12/51] [partial] calcite-avatica git commit: [CALCITE-1717] Remove Calcite code and lift avatica

http://git-wip-us.apache.org/repos/asf/calcite-avatica/blob/fc7b26c8/core/src/main/codegen/templates/Parser.jj
----------------------------------------------------------------------
diff --git a/core/src/main/codegen/templates/Parser.jj b/core/src/main/codegen/templates/Parser.jj
deleted file mode 100644
index c30794d..0000000
--- a/core/src/main/codegen/templates/Parser.jj
+++ /dev/null
@@ -1,6623 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to you under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-<@pp.dropOutputFile />
-
-<@pp.changeOutputFile name="javacc/Parser.jj" />
-
-options {
-    STATIC = false;
-    IGNORE_CASE = true;
-    UNICODE_INPUT = true;
-}
-
-
-PARSER_BEGIN(${parser.class})
-
-package ${parser.package};
-
-<#list parser.imports as importStr>
-import ${importStr};
-</#list>
-
-
-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.SqlBinaryOperator;
-import org.apache.calcite.sql.SqlCall;
-import org.apache.calcite.sql.SqlCharStringLiteral;
-import org.apache.calcite.sql.SqlCollation;
-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.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.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.SqlPostfixOperator;
-import org.apache.calcite.sql.SqlPrefixOperator;
-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.SqlTimeLiteral;
-import org.apache.calcite.sql.SqlTimestampLiteral;
-import org.apache.calcite.sql.SqlUnnestOperator;
-import org.apache.calcite.sql.SqlUpdate;
-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.OracleSqlOperatorTable;
-import org.apache.calcite.sql.fun.SqlStdOperatorTable;
-import org.apache.calcite.sql.fun.SqlTrimFunction;
-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.Util;
-import org.apache.calcite.util.trace.CalciteTrace;
-
-import com.google.common.collect.Lists;
-
-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 ${parser.class} extends SqlAbstractParserImpl
-{
-    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 stream) {
-            return new ${parser.class}(stream);
-        }
-    };
-
-    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 (${parser.class}.class) {
-            if (metadata == null) {
-                metadata = new MetadataImpl(
-                    new ${parser.class}(new java.io.StringReader("")));
-            }
-            return metadata;
-        }
-    }
-
-    public void setTabSize(int tabSize)
-    {
-        jj_input_stream.setTabSize(tabSize);
-    }
-
-    public void switchTo(String stateName)
-    {
-        int state = Arrays.asList(${parser.class}TokenManager.lexStateNames)
-            .indexOf(stateName);
-        token_source.SwitchTo(state);
-    }
-
-    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();
-    }
-
-    private SqlNode extend(SqlNode table, SqlNodeList extendList) {
-        return SqlStdOperatorTable.EXTEND.createCall(
-            table.getParserPosition().plus(extendList.getParserPosition()),
-            table, extendList);
-    }
-}
-
-PARSER_END(${parser.class})
-
-
-/***************************************
- * Utility Codes for Semantic Analysis *
- ***************************************/
-
-/* For Debug */
-JAVACODE
-void debug_message1() {
-    LOGGER.info("{} , {}", getToken(0).image, getToken(1).image);
-}
-
-JAVACODE String unquotedIdentifier() {
-    return SqlParserUtil.strip(getToken(0).image, null, null, null,
-        unquotedCasing);
-}
-
-String NonReservedKeyWord() :
-{
-    String kw;
-}
-{
-    kw = CommonNonReservedKeyWord()
-    {
-        return kw;
-    }
-}
-
-/**
- * Allows parser to be extended with new types of table references.  The
- * default implementation of this production is empty.
- */
-SqlNode ExtendedTableRef() :
-{
-}
-{
-    UnusedExtension()
-    {
-        return null;
-    }
-}
-
-/**
- * Allows an OVER clause following a table expression as an extension to
- * standard SQL syntax. The default implementation of this production is empty.
- */
-SqlNode TableOverOpt() :
-{
-}
-{
-    {
-        return null;
-    }
-}
-
-/*
- * Parses dialect-specific keywords immediately following the SELECT keyword.
- */
-void SqlSelectKeywords(List<SqlLiteral> keywords) :
-{}
-{
-    E()
-}
-
-/*
- * Parses dialect-specific keywords immediately following the INSERT keyword.
- */
-void SqlInsertKeywords(List<SqlLiteral> keywords) :
-{}
-{
-    E()
-}
-
-SqlNode ExtendedBuiltinFunctionCall() :
-{
-}
-{
-    UnusedExtension()
-    {
-        return null;
-    }
-}
-
-/*
-* Parse Floor/Ceil function parameters
-*/
-SqlNode FloorCeilOptions(SqlParserPos pos, boolean floorFlag) :
-{
-    SqlNode node;
-}
-{
-    node = StandardFloorCeilOptions(pos, floorFlag)
-    {
-        return node;
-    }
-}
-
-/*
-// This file contains the heart of a parser for SQL SELECT statements.
-// code can be shared between various parsers (for example, a DDL parser and a
-// DML parser) but is not a standalone JavaCC file. You need to prepend a
-// parser declaration (such as that in Parser.jj).
-*/
-
-/* Epsilon */
-JAVACODE
-void E() {}
-
-JAVACODE List startList(Object o)
-{
-    List list = new ArrayList();
-    list.add(o);
-    return list;
-}
-
-/*
- * NOTE jvs 6-Feb-2004: The straightforward way to implement the SQL grammar is
- * to keep query expressions (SELECT, UNION, etc) separate from row expressions
- * (+, LIKE, etc).  However, this is not possible with an LL(k) parser, because
- * both kinds of expressions allow parenthesization, so no fixed amount of left
- * context is ever good enough.  A sub-query can be a leaf in a row expression,
- * and can include operators like UNION, so it's not even possible to use a
- * syntactic lookahead rule like "look past an indefinite number of parentheses
- * until you see SELECT, VALUES, or TABLE" (since at that point we still
- * don't know whether we're parsing a sub-query like ((select ...) + x)
- * vs. (select ... union select ...).
- *
- * The somewhat messy solution is to unify the two kinds of expression,
- * and to enforce syntax rules using parameterized context.  This
- * is the purpose of the ExprContext parameter.  It is passed to
- * most expression productions, which check the expressions encountered
- * against the context for correctness.  When a query
- * element like SELECT is encountered, the production calls
- * checkQueryExpression, which will throw an exception if
- * a row expression was expected instead.  When a row expression like
- * IN is encountered, the production calls checkNonQueryExpression
- * instead.  It is very important to understand how this works
- * when modifying the grammar.
- *
- * The commingling of expressions results in some bogus ambiguities which are
- * resolved with LOOKAHEAD hints.  The worst example is comma.  SQL allows both
- * (WHERE x IN (1,2)) and (WHERE x IN (select ...)).  This means when we parse
- * the right-hand-side of an IN, we have to allow any kind of expression inside
- * the parentheses.  Now consider the expression "WHERE x IN(SELECT a FROM b
- * GROUP BY c,d)".  When the parser gets to "c,d" it doesn't know whether the
- * comma indicates the end of the GROUP BY or the end of one item in an IN
- * list.  Luckily, we know that select and comma-list are mutually exclusive
- * within IN, so we use maximal munch for the GROUP BY comma.  However, this
- * usage of hints could easily mask unintended ambiguities resulting from
- * future changes to the grammar, making it very brittle.
- */
-
-JAVACODE SqlParserPos getPos()
-{
-    return new SqlParserPos(
-        token.beginLine,
-        token.beginColumn,
-        token.endLine,
-        token.endColumn);
-}
-
-JAVACODE void checkQueryExpression(ExprContext exprContext)
-{
-    switch (exprContext) {
-    case ACCEPT_NON_QUERY:
-    case ACCEPT_SUB_QUERY:
-    case ACCEPT_CURSOR:
-        throw SqlUtil.newContextException(getPos(),
-            RESOURCE.illegalQueryExpression());
-    }
-}
-
-JAVACODE void checkNonQueryExpression(ExprContext exprContext)
-{
-    switch (exprContext) {
-    case ACCEPT_QUERY:
-        throw SqlUtil.newContextException(getPos(),
-            RESOURCE.illegalNonQueryExpression());
-    }
-}
-
-// The date/time parse utilities have to live here, instead of in the
-// SqlParserUtil class because ParseException is ambiguous, and
-// CommonParser has to live in multiple packages.
-
-JAVACODE SqlDateLiteral parseDateLiteral(String s, SqlParserPos pos) {
-    String dateStr = SqlParserUtil.parseString(s);
-    Calendar cal = DateTimeUtils.parseDateFormat(
-        dateStr, DateTimeUtils.DATE_FORMAT_STRING, DateTimeUtils.GMT_ZONE);
-    if (null == cal) {
-        throw SqlUtil.newContextException(pos,
-            RESOURCE.illegalLiteral("DATE", s,
-                RESOURCE.badFormat(DateTimeUtils.DATE_FORMAT_STRING).str()));
-    }
-    return SqlLiteral.createDate(cal, pos);
-}
-
-JAVACODE SqlTimeLiteral parseTimeLiteral(String s, SqlParserPos pos) {
-    String dateStr = SqlParserUtil.parseString(s);
-    DateTimeUtils.PrecisionTime pt =
-    DateTimeUtils.parsePrecisionDateTimeLiteral(
-        dateStr, DateTimeUtils.TIME_FORMAT_STRING, DateTimeUtils.GMT_ZONE);
-    if (null == pt) {
-        throw SqlUtil.newContextException(pos,
-            RESOURCE.illegalLiteral("TIME", s,
-                RESOURCE.badFormat(DateTimeUtils.TIME_FORMAT_STRING).str()));
-    }
-    return SqlLiteral.createTime(pt.getCalendar(), pt.getPrecision(), pos);
-}
-
-JAVACODE SqlTimestampLiteral parseTimestampLiteral(String s, SqlParserPos pos) {
-    String dateStr = SqlParserUtil.parseString(s);
-    DateTimeUtils.PrecisionTime pt =
-    DateTimeUtils.parsePrecisionDateTimeLiteral(
-        dateStr, DateTimeUtils.TIMESTAMP_FORMAT_STRING, DateTimeUtils.GMT_ZONE);
-    if (null == pt) {
-        throw SqlUtil.newContextException(pos,
-            RESOURCE.illegalLiteral("TIMESTAMP", s,
-                RESOURCE.badFormat(DateTimeUtils.TIMESTAMP_FORMAT_STRING).str()));
-    }
-    return SqlLiteral.createTimestamp(pt.getCalendar(), pt.getPrecision(), pos);
-}
-
-JAVACODE SqlIntervalLiteral parseIntervalLiteral(
-    SqlParserPos pos,
-    int sign,
-    String s,
-    SqlIntervalQualifier intervalQualifier) throws ParseException
-{
-    String intervalStr = SqlParserUtil.parseString(s);
-    if ("".equals(intervalStr)) {
-        throw new ParseException(
-            RESOURCE.illegalIntervalLiteral(s + " "
-                + intervalQualifier.toString(), pos.toString()).str());
-    }
-    return SqlLiteral.createInterval(sign, intervalStr, intervalQualifier, pos);
-}
-
-/**
- * Converts a ParseException (local to this particular instantiation
- * of the parser) into a SqlParseException (common to all parsers).
- */
-JAVACODE SqlParseException convertException(Throwable ex)
-{
-    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;
-            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);
-}
-
-/**
- * Removes or transforms misleading information from a parse exception.
- *
- * @param e dirty excn
- *
- * @return clean excn
- */
-JAVACODE ParseException cleanupParseException(ParseException ex)
-{
-    if (ex.expectedTokenSequences == null) {
-        return ex;
-    }
-    int iIdentifier = java.util.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;
-}
-
-JAVACODE boolean matchesPrefix(int[] seq, int[][] prefixes)
-{
-    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:
- *
- *    [ LIMIT { count | ALL } ]
- *    [ OFFSET start ]
- *
- * <p>SQL:2008 syntax for limit:
- *
- *    [ OFFSET start { ROW | ROWS } ]
- *    [ FETCH { FIRST | NEXT } [ count ] { ROW | ROWS } ONLY ]
- */
-SqlNode OrderedQueryOrExpr(ExprContext exprContext) :
-{
-    SqlNode e;
-    SqlNodeList orderBy = null;
-    SqlNode start = null;
-    SqlNode count = null;
-    SqlParserPos pos = null;
-}
-{
-    (
-        e = QueryOrExpr(exprContext)
-    )
-    [
-        // use the syntactic type of the expression we just parsed
-        // to decide whether ORDER BY makes sense
-        orderBy = OrderBy(e.isA(SqlKind.QUERY))
-    ]
-    [
-        // Postgres-style syntax. "LIMIT ... OFFSET ..."
-        <LIMIT> ( count = UnsignedNumericLiteral() | <ALL> )
-    ]
-    [
-        // ROW or ROWS is required in SQL:2008 but we make it optional
-        // because it is not present in Postgres-style syntax.
-        <OFFSET> start = UnsignedNumericLiteral() [ <ROW> | <ROWS> ]
-    ]
-    [
-        // SQL:2008-style syntax. "OFFSET ... FETCH ...".
-        // If you specify both LIMIT and FETCH, FETCH wins.
-        <FETCH> ( <FIRST> | <NEXT> ) count = UnsignedNumericLiteral() ( <ROW> | <ROWS> ) <ONLY>
-    ]
-    {
-        if (orderBy != null || start != null || count != null) {
-            pos = getPos();
-            if (orderBy == null) {
-                orderBy = SqlNodeList.EMPTY;
-            }
-            e = new SqlOrderBy(pos, e, orderBy, start, count);
-
-        }
-        return e;
-    }
-}
-
-/**
- * Parses a leaf in a query expression (SELECT, VALUES or TABLE).
- */
-SqlNode LeafQuery(ExprContext exprContext) :
-{
-    SqlNode e;
-}
-{
-    {
-        // ensure a query is legal in this context
-        checkQueryExpression(exprContext);
-    }
-    e = SqlSelect()
-    {
-        return e;
-    }
-    | e = TableConstructor()
-    {
-        return e;
-    }
-    | e = ExplicitTable(getPos())
-    {
-        return e;
-    }
-}
-
-/**
- * Parses a parenthesized query or single row expression.
- */
-SqlNode ParenthesizedExpression(ExprContext exprContext) :
-{
-    SqlNode e;
-}
-{
-    <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)
-    <RPAREN>
-    {
-        return e;
-    }
-}
-
-/**
- * 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
- *
- * <code>WHERE x IN (select count(*) from t where c=d,5)</code>,
- *
- * which should be illegal.  The above is interpreted as equivalent to
- *
- * <code>WHERE x IN ((select count(*) from t where c=d),5)</code>,
- *
- * 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.
- */
-SqlNodeList ParenthesizedQueryOrCommaList(
-    ExprContext exprContext) :
-{
-    SqlNode e;
-    List<SqlNode> list;
-    ExprContext firstExprContext = exprContext;
-    SqlParserPos pos;
-}
-{
-    <LPAREN>
-    {
-        // we've now seen left paren, so a query by itself should
-        // be interpreted as a sub-query
-        pos = getPos();
-        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);
-    }
-    (
-        <COMMA>
-        {
-            // a comma-list can't appear where only a query is expected
-            checkNonQueryExpression(exprContext);
-        }
-        e = Expression(exprContext)
-        {
-            list.add(e);
-        }
-    ) *
-    <RPAREN>
-    {
-        return new SqlNodeList(list, pos.plus(getPos()));
-    }
-}
-
-/**
- * Parses function parameter lists including DISTINCT keyword recognition,
- * DEFAULT, and named argument assignment.
- */
-List FunctionParameterList(
-    ExprContext exprContext) :
-{
-    SqlNode e = null;
-    List list = new ArrayList();
-}
-{
-    <LPAREN>
-    [
-        <DISTINCT> {
-            e = SqlSelectKeyword.DISTINCT.symbol(getPos());
-        }
-    |
-        <ALL> {
-            e = SqlSelectKeyword.ALL.symbol(getPos());
-        }
-    ]
-    {
-        list.add(e);
-    }
-    Arg0(list, exprContext)
-    (
-        <COMMA> {
-            // a comma-list can't appear where only a query is expected
-            checkNonQueryExpression(exprContext);
-        }
-        Arg(list, exprContext)
-    )*
-    <RPAREN>
-    {
-        return list;
-    }
-}
-
-void Arg0(List list, ExprContext exprContext) :
-{
-    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;
-        }
-    }
-}
-{
-    [
-        name = SimpleIdentifier() <NAMED_ARGUMENT_ASSIGNMENT>
-    ]
-    (
-        <DEFAULT_KW> {
-            e = SqlStdOperatorTable.DEFAULT.createCall(getPos());
-        }
-    |
-        e = OrderedQueryOrExpr(firstExprContext)
-    )
-    {
-        if (e != null) {
-            if (name != null) {
-                e = SqlStdOperatorTable.ARGUMENT_ASSIGNMENT.createCall(
-                    name.getParserPosition().plus(e.getParserPosition()),
-                    e, name);
-            }
-            list.add(e);
-        }
-    }
-}
-
-void Arg(List list, ExprContext exprContext) :
-{
-    SqlIdentifier name = null;
-    SqlNode e = null;
-}
-{
-    [
-        name = SimpleIdentifier() <NAMED_ARGUMENT_ASSIGNMENT>
-    ]
-    (
-        <DEFAULT_KW> {
-            e = SqlStdOperatorTable.DEFAULT.createCall(getPos());
-        }
-    |
-        e = Expression(exprContext)
-    )
-    {
-        if (e != null) {
-            if (name != null) {
-                e = SqlStdOperatorTable.ARGUMENT_ASSIGNMENT.createCall(
-                    name.getParserPosition().plus(e.getParserPosition()),
-                    e, name);
-            }
-            list.add(e);
-        }
-    }
-}
-
-/**
- * Parses a query (SELECT, UNION, INTERSECT, EXCEPT, VALUES, TABLE) followed by
- * the end-of-file symbol.
- */
-SqlNode SqlQueryEof() :
-{
-    SqlNode query;
-}
-{
-    query = OrderedQueryOrExpr(ExprContext.ACCEPT_QUERY)
-    <EOF>
-    { return query; }
-}
-
-/**
- * Parses an SQL statement.
- */
-SqlNode SqlStmt() :
-{
-    SqlNode stmt;
-}
-{
-    (
-        stmt = SqlSetOption(null, null)
-        |
-        stmt = SqlAlter()
-        |
-<#if parser.createStatementParserMethods?size != 0>
-        stmt = SqlCreate()
-        |
-</#if>
-        stmt = OrderedQueryOrExpr(ExprContext.ACCEPT_QUERY)
-        |
-        stmt = SqlExplain()
-        |
-        stmt = SqlDescribe()
-        |
-        stmt = SqlInsert()
-        |
-        stmt = SqlDelete()
-        |
-        stmt = SqlUpdate()
-        |
-        stmt = SqlMerge()
-        |
-        stmt = SqlProcedureCall()
-
-      <#-- Add methods to parse additional statements here -->
-      <#list parser.statementParserMethods as method>
-        |
-        stmt = ${method}
-      </#list>
-    )
-    {
-        return stmt;
-    }
-}
-
-/**
- * Parses an SQL statement followed by the end-of-file symbol.
- */
-SqlNode SqlStmtEof() :
-{
-    SqlNode stmt;
-}
-{
-    stmt = SqlStmt() <EOF>
-    {
-        return stmt;
-    }
-}
-
-<#-- Add implementations of additional parser statement calls here -->
-<#list parser.implementationFiles as file>
-    <#include "/@includes/"+file />
-</#list>
-
-/**
- * Parses a leaf SELECT expression without ORDER BY.
- */
-SqlSelect SqlSelect() :
-{
-    final List<SqlLiteral> keywords = Lists.newArrayList();
-    List<SqlNode> selectList;
-    final SqlNode fromClause;
-    final SqlNode where;
-    final SqlNodeList groupBy;
-    final SqlNode having;
-    final SqlNodeList windowDecls;
-    SqlParserPos pos;
-}
-{
-    <SELECT>
-    {
-        pos = getPos();
-    }
-    SqlSelectKeywords(keywords)
-    (
-        <STREAM> {
-            keywords.add(SqlSelectKeyword.STREAM.symbol(getPos()));
-        }
-    )?
-    (
-        <DISTINCT> {
-            keywords.add(SqlSelectKeyword.DISTINCT.symbol(getPos()));
-        }
-    |   <ALL> {
-            keywords.add(SqlSelectKeyword.ALL.symbol(getPos()));
-        }
-    )?
-    selectList = SelectList()
-    (
-        <FROM> fromClause = FromClause()
-        where = WhereOpt()
-        groupBy = GroupByOpt()
-        having = HavingOpt()
-        windowDecls = WindowOpt()
-    |
-        E() {
-            fromClause = null;
-            where = null;
-            groupBy = null;
-            having = null;
-            windowDecls = null;
-        }
-    )
-    {
-        final SqlNode selectItem = (SqlNode)selectList.get(0);
-        final SqlParserPos selectListPos = selectItem.getParserPosition();
-        return new SqlSelect(pos.plus(getPos()),
-            new SqlNodeList(keywords, pos),
-            new SqlNodeList(selectList, selectListPos.plusAll(selectList)),
-            fromClause, where, groupBy, having, windowDecls, null, null, null);
-    }
-}
-
-/*
- * Abstract production:
- *
- *    void SqlSelectKeywords(List keywords)
- *
- * Parses dialect-specific keywords immediately following the SELECT keyword.
- */
-
-/**
- * Parses an EXPLAIN PLAN statement.
- */
-SqlNode SqlExplain() :
-{
-    SqlNode stmt;
-    SqlExplainLevel detailLevel = SqlExplainLevel.EXPPLAN_ATTRIBUTES;
-    SqlExplain.Depth depth;
-    SqlParserPos pos;
-    final SqlExplainFormat format;
-}
-{
-    <EXPLAIN> <PLAN>
-    [ detailLevel = ExplainDetailLevel() ]
-    depth = ExplainDepth()
-    (
-        <AS> <XML> { format = SqlExplainFormat.XML; }
-    |
-        <AS> <JSON> { format = SqlExplainFormat.JSON; }
-    |
-        { format = SqlExplainFormat.TEXT; }
-    )
-    <FOR> stmt = SqlQueryOrDml() {
-        pos = getPos();
-        return new SqlExplain(pos,
-            stmt,
-            detailLevel.symbol(SqlParserPos.ZERO),
-            depth.symbol(SqlParserPos.ZERO),
-            format.symbol(SqlParserPos.ZERO),
-            nDynamicParams);
-    }
-}
-
-/** Parses a query (SELECT or VALUES)
- * or DML statement (INSERT, UPDATE, DELETE, MERGE). */
-SqlNode SqlQueryOrDml() :
-{
-    SqlNode stmt;
-}
-{
-    (
-        stmt = OrderedQueryOrExpr(ExprContext.ACCEPT_QUERY)
-    |
-        stmt = SqlInsert()
-    |
-        stmt = SqlDelete()
-    |
-        stmt = SqlUpdate()
-    |
-        stmt = SqlMerge()
-    ) { return stmt; }
-}
-
-/**
- * Parses WITH TYPE | WITH IMPLEMENTATION | WITHOUT IMPLEMENTATION modifier for
- * EXPLAIN PLAN.
- */
-SqlExplain.Depth ExplainDepth() :
-{
-}
-{
-    (
-        LOOKAHEAD(2)
-        <WITH> <TYPE>
-        {
-            return SqlExplain.Depth.TYPE;
-        }
-        |
-        <WITH> <IMPLEMENTATION>
-        {
-            return SqlExplain.Depth.PHYSICAL;
-        }
-        |
-        <WITHOUT> <IMPLEMENTATION>
-        {
-            return SqlExplain.Depth.LOGICAL;
-        }
-        |
-        {
-            return SqlExplain.Depth.PHYSICAL;
-        }
-
-    )
-}
-
-/**
- * Parses INCLUDING ALL ATTRIBUTES modifier for EXPLAIN PLAN.
- */
-SqlExplainLevel ExplainDetailLevel() :
-{
-    SqlExplainLevel level = SqlExplainLevel.EXPPLAN_ATTRIBUTES;
-}
-{
-    (
-        <EXCLUDING> <ATTRIBUTES>
-        {
-            level = SqlExplainLevel.NO_ATTRIBUTES;
-        }
-        |
-        <INCLUDING>
-        [ <ALL> { level = SqlExplainLevel.ALL_ATTRIBUTES; } ]
-        <ATTRIBUTES>
-        {
-        }
-    )
-    {
-        return level;
-    }
-}
-
-/**
- * Parses a DESCRIBE statement.
- */
-SqlNode SqlDescribe() :
-{
-   final SqlParserPos pos;
-   final SqlIdentifier table;
-   final SqlIdentifier column;
-   final SqlNode stmt;
-}
-{
-    <DESCRIBE> { pos = getPos(); }
-    (
-        (<DATABASE> | <CATALOG> | <SCHEMA>) {
-            // DESCRIBE DATABASE and DESCRIBE CATALOG currently do the same as
-            // DESCRIBE SCHEMA but should be different. See
-            //   [CALCITE-1221] Implement DESCRIBE DATABASE, CATALOG, STATEMENT
-            return new SqlDescribeSchema(pos, CompoundIdentifier());
-        }
-    |
-        // Use syntactic lookahead to determine whether a table name is coming.
-        // We do not allow SimpleIdentifier() because that includes <STATEMENT>.
-        LOOKAHEAD( <TABLE> | <IDENTIFIER> | <QUOTED_IDENTIFIER>
-           | <BACK_QUOTED_IDENTIFIER> | <BRACKET_QUOTED_IDENTIFIER> )
-        (<TABLE>)?
-        table = CompoundIdentifier()
-        (
-            column = SimpleIdentifier()
-        |
-            E() { column = null; }
-        ) {
-            return new SqlDescribeTable(pos, table, column);
-        }
-    |
-        (<STATEMENT>)?
-        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;
-            return new SqlExplain(pos,
-                stmt,
-                detailLevel.symbol(SqlParserPos.ZERO),
-                depth.symbol(SqlParserPos.ZERO),
-                format.symbol(SqlParserPos.ZERO),
-                nDynamicParams);
-        }
-    )
-}
-
-/**
- * Parses a CALL statement.
- */
-SqlNode SqlProcedureCall() :
-{
-    SqlParserPos callPos;
-    SqlNode routineCall;
-}
-{
-    <CALL>
-    {
-        callPos = getPos();
-    }
-    routineCall = NamedRoutineCall(
-        SqlFunctionCategory.USER_DEFINED_PROCEDURE,
-        ExprContext.ACCEPT_SUB_QUERY)
-    {
-        return SqlStdOperatorTable.PROCEDURE_CALL.createCall(
-            callPos, routineCall);
-    }
-}
-
-SqlNode NamedRoutineCall(
-    SqlFunctionCategory routineType,
-    ExprContext exprContext) :
-{
-    SqlIdentifier name;
-    final List<SqlNode> list = Lists.newArrayList();
-    final SqlParserPos pos;
-}
-{
-    name = CompoundIdentifier() {
-        pos = getPos();
-    }
-    <LPAREN>
-    [
-        Arg0(list, exprContext)
-        (
-            <COMMA> {
-                // a comma-list can't appear where only a query is expected
-                checkNonQueryExpression(exprContext);
-            }
-            Arg(list, exprContext)
-        )*
-    ]
-    <RPAREN>
-    {
-        SqlNode function = createCall(
-            name, pos.plus(getPos()), routineType, null, SqlParserUtil.toNodeArray(list));
-        return function;
-    }
-}
-
-/**
- * Parses an INSERT statement.
- */
-SqlNode SqlInsert() :
-{
-    final List<SqlLiteral> keywords = Lists.newArrayList();
-    SqlNode table;
-    SqlNodeList extendList = null;
-    SqlNode source;
-    SqlNodeList columnList = null;
-    SqlParserPos pos;
-}
-{
-    (
-        <INSERT>
-    |
-        <UPSERT> { keywords.add(SqlInsertKeyword.UPSERT.symbol(getPos())); }
-    )
-    SqlInsertKeywords(keywords)
-    <INTO> table = CompoundIdentifier()
-    [
-        LOOKAHEAD(3)
-        [ <EXTEND> ]
-        extendList = ExtendList() {
-            table = extend(table, extendList);
-        }
-    ]
-    {
-        pos = getPos();
-    }
-    [
-        LOOKAHEAD(2)
-        columnList = ParenthesizedCompoundIdentifierList()
-    ]
-    source = OrderedQueryOrExpr(ExprContext.ACCEPT_QUERY)
-    {
-        return new SqlInsert(pos, new SqlNodeList(keywords, pos), table, source,
-            columnList);
-    }
-}
-
-/*
- * Abstract production:
- *
- *    void SqlInsertKeywords(List keywords)
- *
- * Parses dialect-specific keywords immediately following the INSERT keyword.
- */
-
-/**
- * Parses a DELETE statement.
- */
-SqlNode SqlDelete() :
-{
-    SqlNode table;
-    SqlNodeList extendList = null;
-    SqlIdentifier alias = null;
-    SqlNode condition;
-    SqlParserPos pos;
-}
-{
-    <DELETE>
-    {
-        pos = getPos();
-    }
-    <FROM> table = CompoundIdentifier()
-    {
-
-    }
-    [
-        [ <EXTEND> ]
-        extendList = ExtendList() {
-            table = extend(table, extendList);
-        }
-    ]
-    [ [ <AS> ] alias = SimpleIdentifier() ]
-    condition = WhereOpt()
-    {
-        return new SqlDelete(pos, table, condition, null, alias);
-    }
-}
-
-/**
- * Parses an UPDATE statement.
- */
-SqlNode SqlUpdate() :
-{
-    SqlNode table;
-    SqlNodeList extendList = null;
-    SqlIdentifier alias = null;
-    SqlNode condition;
-    SqlNodeList sourceExpressionList;
-    SqlNodeList targetColumnList;
-    SqlIdentifier id;
-    SqlNode exp;
-    SqlParserPos pos;
-}
-{
-    <UPDATE> table = CompoundIdentifier()
-    {
-        pos = getPos();
-        targetColumnList = new SqlNodeList(pos);
-        sourceExpressionList = new SqlNodeList(pos);
-    }
-    [
-        [ <EXTEND> ]
-        extendList = ExtendList() {
-            table = extend(table, extendList);
-        }
-    ]
-    [ [ <AS> ] alias = SimpleIdentifier() ]
-    <SET> id = SimpleIdentifier()
-    {
-        targetColumnList.add(id);
-    }
-    <EQ> exp = Expression(ExprContext.ACCEPT_SUB_QUERY)
-    {
-        // TODO:  support DEFAULT also
-        sourceExpressionList.add(exp);
-    }
-    (
-        <COMMA>
-        id = SimpleIdentifier()
-        {
-            targetColumnList.add(id);
-        }
-        <EQ> exp = Expression(ExprContext.ACCEPT_SUB_QUERY)
-        {
-            sourceExpressionList.add(exp);
-        }
-    ) *
-    condition = WhereOpt()
-    {
-        return new SqlUpdate(pos, table, targetColumnList, sourceExpressionList,
-            condition, null, alias);
-    }
-}
-
-/**
- * Parses a MERGE statement.
- */
-SqlNode SqlMerge() :
-{
-    SqlNode table;
-    SqlNodeList extendList = null;
-    SqlIdentifier alias = null;
-    SqlNode sourceTableRef;
-    SqlNode condition;
-    SqlUpdate updateCall = null;
-    SqlInsert insertCall = null;
-    SqlParserPos mergePos;
-}
-{
-    <MERGE> <INTO> table = CompoundIdentifier()
-    {
-        mergePos = getPos();
-    }
-    [
-        [ <EXTEND> ]
-        extendList = ExtendList() {
-            table = extend(table, extendList);
-        }
-    ]
-    [ [ <AS> ] alias = SimpleIdentifier() ]
-
-    <USING> sourceTableRef = TableRef()
-
-    <ON> condition = Expression(ExprContext.ACCEPT_SUB_QUERY)
-
-    (
-    LOOKAHEAD(2)
-    updateCall = WhenMatchedClause(table, alias)
-    [ insertCall = WhenNotMatchedClause(table) ]
-    |
-    insertCall = WhenNotMatchedClause(table)
-    )
-    {
-        return new SqlMerge(mergePos, table, condition, sourceTableRef,
-            updateCall, insertCall, null, alias);
-    }
-}
-
-SqlUpdate WhenMatchedClause(SqlNode table, SqlIdentifier alias) :
-{
-    SqlIdentifier id;
-    SqlParserPos pos;
-    SqlNodeList updateColumnList;
-    SqlNode exp;
-    SqlNodeList updateExprList;
-}
-{
-    <WHEN> <MATCHED> <THEN>
-    <UPDATE> <SET> id = SimpleIdentifier()
-    {
-        pos = getPos();
-        updateColumnList = new SqlNodeList(pos);
-        updateExprList = new SqlNodeList(pos);
-        updateColumnList.add(id);
-    }
-    <EQ> exp = Expression(ExprContext.ACCEPT_SUB_QUERY)
-    {
-        updateExprList.add(exp);
-    }
-    (
-        <COMMA>
-        id = SimpleIdentifier()
-        {
-            updateColumnList.add(id);
-        }
-        <EQ> exp = Expression(ExprContext.ACCEPT_SUB_QUERY)
-        {
-            updateExprList.add(exp);
-        }
-    ) *
-    {
-        return new SqlUpdate(pos, table, updateColumnList, updateExprList, null,
-            null, alias);
-    }
-}
-
-SqlInsert WhenNotMatchedClause(SqlNode table) :
-{
-    SqlParserPos pos, insertPos;
-    List<SqlLiteral> keywords = Lists.newArrayList();
-    SqlNodeList insertColumnList = null;
-    SqlNode rowConstructor;
-    SqlNode insertValues;
-}
-{
-    <WHEN> <NOT> <MATCHED> <THEN>
-    <INSERT>
-    {
-        insertPos = getPos();
-    }
-    SqlInsertKeywords(keywords)
-    [
-        LOOKAHEAD(2)
-        insertColumnList = ParenthesizedSimpleIdentifierList()
-    ]
-    [ <LPAREN> ]
-    <VALUES> { pos = getPos(); }
-    rowConstructor = RowConstructor()
-    [ <RPAREN> ]
-    {
-        // 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(
-            pos.plus(rowConstructor.getParserPosition()),
-            rowConstructor);
-        return new SqlInsert(insertPos, new SqlNodeList(keywords, insertPos),
-            table, insertValues, insertColumnList);
-    }
-}
-
-/**
- * Parses the select list of a SELECT statement.
- */
-List<SqlNode> SelectList() :
-{
-    List<SqlNode> list = new ArrayList<SqlNode>();
-    SqlNode item;
-}
-{
-    item = SelectItem() {list.add(item);}
-    ( <COMMA> item = SelectItem() {list.add(item);} ) *
-    {
-        return list;
-    }
-}
-
-/**
- * Parses one item in a select list.
- */
-SqlNode SelectItem() :
-{
-    SqlNode e;
-    SqlIdentifier id;
-    SqlParserPos pos;
-}
-{
-    e = SelectExpression()
-    [
-        [ <AS> ]
-        id = SimpleIdentifier()
-        {
-            pos = e.getParserPosition().plus(getPos());
-            e = SqlStdOperatorTable.AS.createCall(pos, e, id);
-        }
-    ]
-    {
-        return e;
-    }
-}
-
-/**
- * Parses one unaliased expression in a select list.
- */
-SqlNode SelectExpression() :
-{
-    SqlNode e;
-}
-{
-    <STAR>
-    {
-        return SqlIdentifier.star(getPos());
-    }
-    |
-    e = Expression(ExprContext.ACCEPT_SUB_QUERY)
-    {
-        return e;
-    }
-}
-
-SqlLiteral Natural() :
-{
-}
-{
-    (
-        <NATURAL> { return SqlLiteral.createBoolean(true, getPos()); }
-    |
-        { return SqlLiteral.createBoolean(false, getPos()); }
-    )
-}
-
-SqlLiteral JoinType() :
-{
-    JoinType joinType;
-}
-{
-    (
-        <JOIN> { joinType = JoinType.INNER; }
-    |
-        <INNER> <JOIN> { joinType = JoinType.INNER; }
-    |
-        <LEFT> [ <OUTER> ] <JOIN> { joinType = JoinType.LEFT; }
-    |
-        <RIGHT> [ <OUTER> ] <JOIN> { joinType = JoinType.RIGHT; }
-    |
-        <FULL> [ <OUTER> ] <JOIN> { joinType = JoinType.FULL; }
-    |
-        <CROSS> <JOIN> { joinType = JoinType.CROSS; }
-    )
-    {
-        return joinType.symbol(getPos());
-    }
-}
-
-/** Matches "LEFT JOIN t ON ...", "RIGHT JOIN t USING ...", "JOIN t". */
-SqlNode JoinTable(SqlNode e) :
-{
-    SqlNode e2, condition;
-    SqlLiteral natural, joinType;
-    SqlNodeList list;
-    SqlParserPos pos;
-}
-{
-    natural = Natural()
-    joinType = JoinType()
-    e2 = TableRef()
-    (
-        <ON> { pos = getPos(); }
-        condition = Expression(ExprContext.ACCEPT_SUB_QUERY) {
-            SqlParserPos onPos = pos.plus(getPos());
-            return new SqlJoin(joinType.getParserPosition(),
-                e,
-                natural,
-                joinType,
-                e2,
-                JoinConditionType.ON.symbol(onPos),
-                condition);
-        }
-    |
-        <USING> { pos = getPos(); }
-        list = ParenthesizedSimpleIdentifierList() {
-            SqlParserPos usingPos = pos.plus(getPos());
-            return new SqlJoin(joinType.getParserPosition(),
-                e,
-                natural,
-                joinType,
-                e2,
-                JoinConditionType.USING.symbol(usingPos),
-                new SqlNodeList(list.getList(), usingPos));
-        }
-    |
-        {
-            return new SqlJoin(joinType.getParserPosition(),
-                e,
-                natural,
-                joinType,
-                e2,
-                JoinConditionType.NONE.symbol(joinType.getParserPosition()),
-                null);
-        }
-    )
-}
-
-// 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.
- */
-SqlNode FromClause() :
-{
-    SqlNode e, e2, condition;
-    SqlLiteral natural, joinType;
-    SqlNodeList list;
-    SqlParserPos pos;
-}
-{
-    e = TableRef()
-    (
-        // Decide whether to read a JOIN clause or a comma, or to quit having
-        // seen a single entry FROM clause like 'FROM emps'. See comments
-        // elsewhere regarding <COMMA> lookahead.
-        LOOKAHEAD(2)
-        natural = Natural()
-        joinType = JoinType()
-        e2 = TableRef()
-        (
-            <ON> { pos = getPos(); }
-            condition = Expression(ExprContext.ACCEPT_SUB_QUERY) {
-                SqlParserPos onPos = pos.plus(getPos());
-                e = new SqlJoin(joinType.getParserPosition(),
-                    e,
-                    natural,
-                    joinType,
-                    e2,
-                    JoinConditionType.ON.symbol(onPos),
-                    condition);
-            }
-            |
-            <USING> { pos = getPos(); }
-            list = ParenthesizedSimpleIdentifierList() {
-                SqlParserPos usingPos = pos.plus(getPos());
-                e = new SqlJoin(joinType.getParserPosition(),
-                    e,
-                    natural,
-                    joinType,
-                    e2,
-                    JoinConditionType.USING.symbol(usingPos),
-                    new SqlNodeList(list.getList(), usingPos));
-            }
-            |
-            {
-                e = new SqlJoin(joinType.getParserPosition(),
-                    e,
-                    natural,
-                    joinType,
-                    e2,
-                    JoinConditionType.NONE.symbol(joinType.getParserPosition()),
-                    null);
-            }
-        )
-        |
-        // NOTE jvs 6-Feb-2004:  See comments at top of file for why
-        // hint is necessary here.  I had to use this special semantic
-        // lookahead form to get JavaCC to shut up, which makes
-        // me even more uneasy.
-        //LOOKAHEAD({true})
-        <COMMA> { pos = getPos(); }
-        e2 = TableRef() {
-            e = new SqlJoin(pos,
-                e,
-                SqlLiteral.createBoolean(false, pos),
-                JoinType.COMMA.symbol(SqlParserPos.ZERO),
-                e2,
-                JoinConditionType.NONE.symbol(SqlParserPos.ZERO),
-                null);
-        }
-        |
-        <CROSS> { pos = getPos(); } <APPLY>
-        e2 = TableRef2(true) {
-            if (!this.conformance.isApplyAllowed()) {
-                throw new ParseException(RESOURCE.applyNotAllowed().str());
-            }
-            e = new SqlJoin(pos,
-                e,
-                SqlLiteral.createBoolean(false, pos),
-                JoinType.CROSS.symbol(SqlParserPos.ZERO),
-                e2,
-                JoinConditionType.NONE.symbol(SqlParserPos.ZERO),
-                null);
-        }
-        |
-        <OUTER> { pos = getPos(); } <APPLY>
-        e2 = TableRef2(true) {
-            if (!this.conformance.isApplyAllowed()) {
-                throw new ParseException(RESOURCE.applyNotAllowed().str());
-            }
-            e = new SqlJoin(pos,
-                e,
-                SqlLiteral.createBoolean(false, pos),
-                JoinType.LEFT.symbol(SqlParserPos.ZERO),
-                e2,
-                JoinConditionType.ON.symbol(SqlParserPos.ZERO),
-                SqlLiteral.createBoolean(true, pos));
-        }
-    ) *
-    {
-        return e;
-    }
-}
-
-// TODO jvs 15-Nov-2003: SQL standard allows column aliases on table
-// references, e.g. DEPTS AS D1(DEPTNO1,DNAME1); I guess this is syntactic
-// sugar to make it easier for query writers to conform to the column name
-// uniqueness rules without requiring them to write a nested SELECT, but it
-// seems pretty useless for non-trivial tables, since you have to supply names
-// for ALL columns at once.
-/**
- * Parses a table reference in a FROM clause, not lateral unless LATERAL
- * is explicitly specified.
- */
-SqlNode TableRef() :
-{
-    final SqlNode e;
-}
-{
-    e = TableRef2(false) { return e; }
-}
-
-/**
- * Parses a table reference in a FROM clause.
- */
-SqlNode TableRef2(boolean lateral) :
-{
-    SqlNode tableRef;
-    SqlNode over;
-    SqlNodeList extendList = null;
-    String alias;
-    SqlParserPos pos;
-    SqlNodeList args;
-    SqlNode sample;
-    boolean isBernoulli;
-    SqlNumericLiteral samplePercentage;
-    boolean isRepeatable = false;
-    int repeatableSeed = 0;
-    SqlNodeList columnAliasList = null;
-    SqlUnnestOperator unnestOp = SqlStdOperatorTable.UNNEST;
-}
-{
-    (
-        LOOKAHEAD(2)
-        tableRef = CompoundIdentifier()
-        [
-            [ <EXTEND> ]
-            extendList = ExtendList() {
-                tableRef = extend(tableRef, extendList);
-            }
-        ]
-        over = TableOverOpt()
-        {
-            if (over != null) {
-                pos = getPos();
-                tableRef = SqlStdOperatorTable.OVER.createCall(
-                    pos, tableRef, over);
-            }
-        }
-        [
-            over = MatchRecognizeOpt(tableRef)
-            {
-                if (over != null) {
-                    tableRef = over;
-                }
-            }
-        ]
-    |
-        [ <LATERAL> { lateral = true; } ]
-        tableRef = ParenthesizedExpression(ExprContext.ACCEPT_QUERY)
-        over = TableOverOpt()
-        {
-            if (over != null) {
-                pos = getPos();
-                tableRef = SqlStdOperatorTable.OVER.createCall(
-                    pos, tableRef, over);
-            }
-            if (lateral) {
-                tableRef = SqlStdOperatorTable.LATERAL.createCall(
-                    getPos(), tableRef);
-            }
-        }
-        (
-            [ over = MatchRecognizeOpt(tableRef) ]
-            {
-                if (over != null) {
-                    tableRef = over;
-                }
-            }
-        )
-    |
-        <UNNEST> { pos = getPos(); }
-        args = ParenthesizedQueryOrCommaList(ExprContext.ACCEPT_SUB_QUERY)
-        [
-            <WITH> <ORDINALITY> {
-                unnestOp = SqlStdOperatorTable.UNNEST_WITH_ORDINALITY;
-            }
-        ]
-        {
-            tableRef = unnestOp.createCall(pos.plus(getPos()), args.toArray());
-        }
-    |
-        [ <LATERAL> { lateral = true; } ]
-        <TABLE> { pos = getPos(); } <LPAREN>
-        tableRef = TableFunctionCall(pos)
-        <RPAREN>
-        {
-            if (lateral) {
-                tableRef = SqlStdOperatorTable.LATERAL.createCall(
-                    getPos(), tableRef);
-            }
-        }
-    |
-        tableRef = ExtendedTableRef()
-    )
-    [
-        [ <AS> ] alias = Identifier()
-        [ columnAliasList = ParenthesizedSimpleIdentifierList() ]
-        {
-            pos = getPos();
-            if (columnAliasList == null) {
-                tableRef = SqlStdOperatorTable.AS.createCall(
-                    pos, tableRef, new SqlIdentifier(alias, pos));
-            } else {
-                List<SqlNode> idList = new ArrayList<SqlNode>();
-                idList.add(tableRef);
-                idList.add(new SqlIdentifier(alias, pos));
-                idList.addAll(columnAliasList.getList());
-                tableRef = SqlStdOperatorTable.AS.createCall(pos, idList);
-            }
-        }
-    ]
-    [
-        <TABLESAMPLE> { pos = getPos(); }
-        (
-            <SUBSTITUTE> <LPAREN> sample = StringLiteral() <RPAREN>
-            {
-                String sampleName =
-                    ((NlsString) SqlLiteral.value(sample)).getValue();
-                SqlSampleSpec sampleSpec = SqlSampleSpec.createNamed(sampleName);
-                SqlLiteral sampleLiteral = SqlLiteral.createSample(sampleSpec, pos);
-                tableRef = SqlStdOperatorTable.TABLESAMPLE.createCall(
-                    pos.plus(getPos()), tableRef, sampleLiteral);
-             }
-        |
-            (
-                <BERNOULLI>
-                {
-                    isBernoulli = true;
-                }
-            |
-                <SYSTEM>
-                {
-                    isBernoulli = false;
-                }
-            )
-            <LPAREN> samplePercentage = UnsignedNumericLiteral() <RPAREN>
-            [
-                <REPEATABLE> <LPAREN> repeatableSeed = IntLiteral() <RPAREN>
-                {
-                    isRepeatable = true;
-                }
-            ]
-            {
-                final BigDecimal ONE_HUNDRED = BigDecimal.valueOf(100L);
-                BigDecimal rate = samplePercentage.bigDecimalValue();
-                if (rate.compareTo(BigDecimal.ZERO) < 0
-                    || rate.compareTo(ONE_HUNDRED) > 0)
-                {
-                    throw new ParseException(RESOURCE.invalidSampleSize().str());
-                }
-
-                // 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, pos);
-                    tableRef = SqlStdOperatorTable.TABLESAMPLE.createCall(
-                        pos.plus(getPos()), tableRef, tableSampleLiteral);
-                }
-            }
-        )
-    ]
-    {
-        return tableRef;
-    }
-}
-
-SqlNodeList ExtendList() :
-{
-    SqlParserPos pos;
-    List<SqlNode> list = Lists.newArrayList();
-}
-{
-    <LPAREN> { pos = getPos(); }
-    ColumnType(list)
-    (
-        <COMMA> ColumnType(list)
-    )*
-    <RPAREN> {
-        return new SqlNodeList(list, pos.plus(getPos()));
-    }
-}
-
-void ColumnType(List<SqlNode> list) :
-{
-    SqlIdentifier name;
-    SqlDataTypeSpec type;
-    boolean nullable = true;
-}
-{
-    name = SimpleIdentifier()
-    type = DataType()
-    [
-        <NOT> <NULL> {
-            nullable = false;
-        }
-    ]
-    {
-        list.add(name);
-        list.add(type.withNullable(nullable));
-    }
-}
-
-SqlNode TableFunctionCall(SqlParserPos pos) :
-{
-    SqlNode call;
-    SqlFunctionCategory funcType = SqlFunctionCategory.USER_DEFINED_TABLE_FUNCTION;
-}
-{
-    [
-        <SPECIFIC>
-        {
-            funcType = SqlFunctionCategory.USER_DEFINED_TABLE_SPECIFIC_FUNCTION;
-        }
-    ]
-    {
-    }
-    call = NamedRoutineCall(funcType, ExprContext.ACCEPT_CURSOR)
-    {
-        return SqlStdOperatorTable.COLLECTION_TABLE.createCall(pos, call);
-    }
-}
-
-/**
- * Abstract production:
- *    SqlNode ExtendedTableRef()
- *
- * 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.
- */
-SqlNode ExplicitTable(SqlParserPos pos) :
-{
-    SqlNode tableRef;
-}
-{
-    <TABLE> tableRef = CompoundIdentifier()
-    {
-        return SqlStdOperatorTable.EXPLICIT_TABLE.createCall(pos, tableRef);
-    }
-}
-
-/**
- * Parses a VALUES leaf query expression.
- */
-SqlNode TableConstructor() :
-{
-    SqlNodeList rowConstructorList;
-    SqlParserPos pos;
-}
-{
-    <VALUES>
-    {
-        pos = getPos();
-    }
-    rowConstructorList = RowConstructorList(pos)
-    {
-        return SqlStdOperatorTable.VALUES.createCall(
-            pos.plus(getPos()), rowConstructorList.toArray());
-    }
-}
-
-/**
- * Parses one or more rows in a VALUES expression.
- */
-SqlNodeList RowConstructorList(SqlParserPos pos) :
-{
-    List<SqlNode> list = new ArrayList<SqlNode>();
-    SqlNode rowConstructor;
-}
-{
-    rowConstructor = RowConstructor() { list.add(rowConstructor); }
-    (
-        LOOKAHEAD(2)
-        <COMMA> rowConstructor = RowConstructor() { list.add(rowConstructor); }
-    ) *
-    {
-        return new SqlNodeList(list, pos.plus(getPos()));
-    }
-}
-
-/**
- * Parses a row constructor in the context of a VALUES expression.
- */
-SqlNode RowConstructor() :
-{
-    SqlNodeList valueList;
-    SqlNode value;
-    SqlParserPos pos;
-}
-{
-    // hints are necessary here due to common LPAREN prefixes
-    (
-        // TODO jvs 8-Feb-2004: extra parentheses are accepted here as a hack
-        // for unparse, but this is actually invalid SQL; should
-        // fix unparse
-        LOOKAHEAD(3)
-        <LPAREN> { pos = getPos(); }
-        <ROW>
-        valueList = ParenthesizedQueryOrCommaList(ExprContext.ACCEPT_NONCURSOR)
-        <RPAREN> { pos = pos.plus(getPos()); }
-        |
-        LOOKAHEAD(3)
-        { pos = getPos(); }
-        [
-            <ROW>
-        ]
-        valueList = ParenthesizedQueryOrCommaList(ExprContext.ACCEPT_NONCURSOR)
-        { pos = pos.plus(getPos()); }
-        |
-        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.
-            pos = value.getParserPosition();
-            valueList = new SqlNodeList(Collections.singletonList(value), pos);
-        }
-    )
-    {
-        // 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.
-        return SqlStdOperatorTable.ROW.createCall(pos, valueList.toArray());
-    }
-}
-
-/**
- * Parses the optional WHERE clause for SELECT, DELETE, and UPDATE.
- */
-SqlNode WhereOpt() :
-{
-    SqlNode condition;
-}
-{
-    <WHERE> condition = Expression(ExprContext.ACCEPT_SUB_QUERY)
-    {
-        return condition;
-    }
-    |
-    {
-        return null;
-    }
-}
-
-/**
- * Parses the optional GROUP BY clause for SELECT.
- */
-SqlNodeList GroupByOpt() :
-{
-    List<SqlNode> list = Lists.newArrayList();
-    SqlNode e;
-    SqlParserPos pos;
-}
-{
-    <GROUP> { pos = getPos(); }
-    <BY> list = GroupingElementList() {
-        return new SqlNodeList(list, pos.plusAll(list));
-    }
-|
-    {
-        return null;
-    }
-}
-
-List<SqlNode> GroupingElementList() :
-{
-    List<SqlNode> list = Lists.newArrayList();
-    SqlNode e;
-}
-{
-    e = GroupingElement() { list.add(e); }
-    (
-        <COMMA>
-        e = GroupingElement() { list.add(e); }
-    )*
-    { return list; }
-}
-
-SqlNode GroupingElement() :
-{
-    List<SqlNode> list;
-    SqlNodeList nlist;
-    SqlNode e;
-    SqlParserPos pos;
-}
-{
-    <GROUPING> { pos = getPos(); }
-    <SETS> <LPAREN> list = GroupingElementList() <RPAREN> {
-        return SqlStdOperatorTable.GROUPING_SETS.createCall(pos, list);
-    }
-|   <ROLLUP> { pos = getPos(); }
-    <LPAREN> nlist = ExpressionCommaList(pos, ExprContext.ACCEPT_SUB_QUERY)
-    <RPAREN> {
-        return SqlStdOperatorTable.ROLLUP.createCall(nlist);
-    }
-|   <CUBE> { pos = getPos(); }
-    <LPAREN> nlist = ExpressionCommaList(pos, ExprContext.ACCEPT_SUB_QUERY)
-    <RPAREN> {
-        return SqlStdOperatorTable.CUBE.createCall(nlist);
-    }
-|   LOOKAHEAD(3)
-    <LPAREN> <RPAREN> {
-        return new SqlNodeList(getPos());
-    }
-|   e = Expression(ExprContext.ACCEPT_SUB_QUERY) {
-        return e;
-    }
-}
-
-/**
- * Parses a list of expressions separated by commas.
- */
-SqlNodeList ExpressionCommaList(
-    SqlParserPos pos,
-    ExprContext exprContext) :
-{
-    List<SqlNode> list;
-    SqlNode e;
-}
-{
-    e = Expression(exprContext)
-    {
-        if (pos == null) {
-            pos = getPos();
-        }
-        pos = pos.plus(getPos());
-        list = startList(e);
-    }
-    (
-        // NOTE jvs 6-Feb-2004:  See comments at top of file for why
-        // hint is necessary here.
-        LOOKAHEAD(2)
-        <COMMA> e = Expression(ExprContext.ACCEPT_SUB_QUERY)
-        {
-            list.add(e);
-            pos = pos.plus(getPos());
-        }
-    ) *
-    {
-        return new SqlNodeList(list, pos);
-    }
-}
-
-/**
- * Parses the optional HAVING clause for SELECT.
- */
-SqlNode HavingOpt() :
-{
-    SqlNode e;
-}
-{
-    <HAVING> e = Expression(ExprContext.ACCEPT_SUB_QUERY)
-    {
-        return e;
-    }
-    |
-    {
-        return null;
-    }
-}
-
-/**
- * Parses the optional WINDOW clause for SELECT
- */
-SqlNodeList WindowOpt() :
-{
-    SqlIdentifier id;
-    SqlWindow e;
-    List<SqlNode> list;
-    SqlParserPos pos;
-}
-{
-    <WINDOW> id = SimpleIdentifier() <AS> e = WindowSpecification()
-    {
-        pos = getPos();
-        e.setDeclName(id);
-        list = startList(e);
-    }
-    (
-        // NOTE jhyde 22-Oct-2004:  See comments at top of file for why
-        // hint is necessary here.
-        LOOKAHEAD(2)
-        <COMMA> id = SimpleIdentifier() <AS> e = WindowSpecification()
-        {
-            e.setDeclName(id);
-            list.add(e);
-        }
-    ) *
-    {
-        return new SqlNodeList(list, pos);
-    }
-    |
-    {
-        return null;
-    }
-}
-
-/**
- * Parses a window specification.
- */
-SqlWindow WindowSpecification() :
-{
-    SqlIdentifier id;
-    List list;
-    SqlNodeList partitionList;
-    SqlNodeList orderList;
-    SqlLiteral isRows = SqlLiteral.createBoolean(false, SqlParserPos.ZERO);
-    SqlNode lowerBound = null, upperBound = null;
-    SqlParserPos startPos;
-    SqlParserPos endPos;
-    SqlParserPos pos;
-    SqlLiteral allowPartial = null;
-}
-{
-    <LPAREN> { startPos = pos = getPos(); }
-    (
-        id = SimpleIdentifier()
-        |
-        { id = null; }
-    )
-    (
-        <PARTITION>
-        { pos = getPos(); }
-        <BY>
-        partitionList = ExpressionCommaList(pos, ExprContext.ACCEPT_NON_QUERY)
-        |
-        { partitionList = SqlNodeList.EMPTY; }
-    )
-    (
-        orderList = OrderBy(true)
-        |
-        { orderList = SqlNodeList.EMPTY; }
-    )
-    [
-        (
-            <ROWS> { isRows = SqlLiteral.createBoolean(true, getPos()); }
-            |
-            <RANGE> { isRows = SqlLiteral.createBoolean(false, getPos()); }
-        )
-        (
-            <BETWEEN> lowerBound = WindowRange()
-            <AND> upperBound = WindowRange()
-            |
-            lowerBound = WindowRange()
-        )
-    ]
-    [
-        <ALLOW> { pos = getPos(); } <PARTIAL> {
-            allowPartial = SqlLiteral.createBoolean(true, pos.plus(getPos()));
-        }
-    |
-        <DISALLOW> { pos = getPos(); } <PARTIAL> {
-            allowPartial = SqlLiteral.createBoolean(false, pos.plus(getPos()));
-        }
-    ]
-    <RPAREN>
-    {
-        endPos = getPos();
-        return SqlWindow.create(
-            null, id, partitionList, orderList,
-            isRows, lowerBound, upperBound, allowPartial,
-            startPos.plus(endPos));
-    }
-}
-
-SqlNode WindowRange() :
-{
-    SqlNode e;
-    SqlParserPos pos = null;
-    SqlParserPos endPos;
-}
-{
-    <CURRENT> {pos = getPos();} <ROW>
-    {
-        endPos = getPos();
-        return SqlWindow.createCurrentRow(pos.plus(endPos));
-    }
-    |
-    <UNBOUNDED>
-        { pos = getPos();}
-    (
-        <PRECEDING>
-        {
-            endPos = getPos();
-            return SqlWindow.createUnboundedPreceding(pos.plus(endPos));
-        }
-        |
-        <FOLLOWING>
-        {
-            endPos = getPos();
-            return SqlWindow.createUnboundedFollowing(pos.plus(endPos));
-        }
-    )
-    |
-    e = Expression(ExprContext.ACCEPT_NON_QUERY)
-    (
-        <PRECEDING>
-        {
-            return SqlWindow.createPreceding(
-                e, getPos());
-        }
-        |
-        <FOLLOWING>
-        {
-            return SqlWindow.createFollowing(
-                e, getPos());
-        }
-    )
-}
-
-/**
- * Parses an ORDER BY clause.
- */
-SqlNodeList OrderBy(boolean accept) :
-{
-    List<SqlNode> list;
-    SqlNode e;
-    SqlParserPos pos;
-}
-{
-    <ORDER> {
-        pos = getPos();
-        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.
-            throw SqlUtil.newContextException(pos, RESOURCE.illegalOrderBy());
-        }
-    }
-    <BY> e = OrderItem() {
-        list = startList(e);
-    }
-    (
-        // NOTE jvs 6-Feb-2004:  See comments at top of file for why
-        // hint is necessary here.
-        LOOKAHEAD(2) <COMMA> e = OrderItem() { list.add(e); }
-    ) *
-    {
-        return new SqlNodeList(list, pos.plusAll(list));
-    }
-}
-
-/**
- * Parses one list item in an ORDER BY clause.
- */
-SqlNode OrderItem() :
-{
-    SqlNode e;
-}
-{
-    e = Expression(ExprContext.ACCEPT_SUB_QUERY)
-    (
-        <ASC>
-    |   <DESC> {
-            e = SqlStdOperatorTable.DESC.createCall(getPos(), e);
-        }
-    )?
-    (
-        <NULLS> <FIRST> {
-            e = SqlStdOperatorTable.NULLS_FIRST.createCall(getPos(), e);
-        }
-    |
-        <NULLS> <LAST> {
-            e = SqlStdOperatorTable.NULLS_LAST.createCall(getPos(), e);
-        }
-    )?
-    {
-        return e;
-    }
-}
-
-/**
- * Parses a MATCH_RECOGNIZE clause following a table expression.
- */
-SqlMatchRecognize MatchRecognizeOpt(SqlNode tableRef) :
-{
-    final SqlParserPos startPos;
-    SqlParserPos pos;
-    SqlNode pattern;
-    SqlNodeList patternDefList;
-    SqlLiteral isStrictStarts = SqlLiteral.createBoolean(false, getPos());
-    SqlLiteral isStrictEnds = SqlLiteral.createBoolean(false, getPos());
-}
-{
-    <MATCH_RECOGNIZE> { startPos = getPos(); } <LPAREN>
-    <PATTERN>
-    <LPAREN>
-    (
-        <CARET> { isStrictStarts = SqlLiteral.createBoolean(true, getPos()); }
-    |
-        { isStrictStarts = SqlLiteral.createBoolean(false, getPos()); }
-    )
-    pattern = PatternExpression()
-    (
-        <DOLLAR> { isStrictEnds = SqlLiteral.createBoolean(true, getPos()); }
-    |
-        { isStrictEnds = SqlLiteral.createBoolean(false, getPos()); }
-    )
-    <RPAREN>
-    <DEFINE> { pos = getPos(); }
-    patternDefList = PatternDefinitionCommaList(pos)
-    <RPAREN> {
-        return new SqlMatchRecognize(startPos.plus(getPos()), tableRef,
-            pattern, isStrictStarts, isStrictEnds, patternDefList);
-    }
-}
-
-SqlNode PatternExpression() :
-{
-    SqlNode left;
-    SqlNode right;
-}
-{
-    left = PatternTerm()
-    (
-        <VERTICAL_BAR>
-        right = PatternTerm() {
-            left = SqlStdOperatorTable.PATTERN_ALTER.createCall(
-                left.getParserPosition().plus(getPos()), left, right);
-        }
-    )*
-    {
-        return left;
-    }
-}
-
-SqlNode PatternTerm() :
-{
-    SqlNode left;
-    SqlNode right;
-}
-{
-    left = PatternFactor()
-    (
-        right = PatternFactor() {
-            left = SqlStdOperatorTable.PATTERN_CONCAT.createCall(
-                left.getParserPosition().plus(getPos()), left, right);
-        }
-    )*
-    {
-        return left;
-    }
-}
-
-SqlNode PatternFactor() :
-{
-    SqlNode e;
-    SqlNode extra;
-    SqlLiteral startNum = null;
-    SqlLiteral endNum = null;
-    SqlLiteral reluctant = SqlLiteral.createBoolean(false, SqlParserPos.ZERO);
-}
-{
-    e = PatternPrimary()
-    [
-        (
-            <STAR> {
-                startNum = SqlLiteral.createExactNumeric("0", SqlParserPos.ZERO);
-                endNum = SqlLiteral.createExactNumeric("-1", SqlParserPos.ZERO);
-            }
-        |
-            <PLUS> {
-                startNum = SqlLiteral.createExactNumeric("1", SqlParserPos.ZERO);
-                endNum = SqlLiteral.createExactNumeric("-1", SqlParserPos.ZERO);
-            }
-        |
-            <HOOK> {
-                startNum = SqlLiteral.createExactNumeric("0", SqlParserPos.ZERO);
-                endNum = SqlLiteral.createExactNumeric("1", SqlParserPos.ZERO);
-            }
-        |
-            <LBRACE>
-            (
-                startNum = UnsignedNumericLiteral() { endNum = startNum; }
-                [
-                    <COMMA> {
-                        endNum = SqlLiteral.createExactNumeric("-1", SqlParserPos.ZERO);
-                    }
-                    [
-                        endNum = UnsignedNumericLiteral()
-                    ]
-                ]
-                <RBRACE>
-            |
-                {
-                    startNum = SqlLiteral.createExactNumeric("-1", SqlParserPos.ZERO);
-                }
-                <COMMA>
-                endNum = UnsignedNumericLiteral()
-                <RBRACE>
-            |
-                <MINUS> extra = PatternExpression() <MINUS> <RBRACE> {
-                    extra = SqlStdOperatorTable.PATTERN_EXCLUDE.createCall(
-                        extra.getParserPosition().plus(getPos()), extra);
-                    e = SqlStdOperatorTable.PATTERN_CONCAT.createCall(
-                        e.getParserPosition().plus(getPos()), e, extra);
-                    return e;
-                }
-            )
-        )
-        [
-            <HOOK>
-            {
-                if (startNum.intValue(true) != endNum.intValue(true)) {
-                    reluctant = SqlLiteral.createBoolean(true, SqlParserPos.ZERO);
-                }
-            }
-        ]
-    ]
-    {
-        if (startNum == null) {
-            return e;
-        } else {
-            return SqlStdOperatorTable.PATTERN_QUANTIFIER.createCall(
-                e.getParserPosition().plus(getPos()),
-                e, startNum, endNum, reluctant);
-        }
-    }
-}
-
-SqlNode PatternPrimary() :
-{
-    SqlParserPos pos;
-    SqlNode e;
-    List<SqlNode> eList;
-}
-{
-    (
-        e = SimpleIdentifier()
-    |
-        <LPAREN> e = PatternExpression() <RPAREN>
-    |
-        <LBRACE> { pos = getPos(); }
-        <MINUS> e = PatternExpression()
-        <MINUS> <RBRACE> {
-            e = SqlStdOperatorTable.PATTERN_EXCLUDE.createCall(
-                pos.plus(getPos()), e);
-        }
-    |
-        (
-            <PERMUTE> { pos = getPos(); }
-            <LPAREN>
-            e = PatternExpression() {
-                eList = new ArrayList<SqlNode>();
-                eList.add(e);
-            }
-            (
-                <COMMA>
-                e = PatternExpression()
-                {
-                    eList.add(e);
-                }
-            )*
-            <RPAREN> {
-                e = SqlStdOperatorTable.PATTERN_PERMUTE.createCall(
-                    pos.plus(getPos()), eList);
-            }
-        )
-    )
-    {
-        return e;
-    }
-}
-
-SqlNodeList PatternDefinitionCommaList(SqlParserPos pos) :
-{
-    SqlNode e;
-    final List<SqlNode> eList = new ArrayList<SqlNode>();
-}
-{
-    e = PatternDefinition() {
-        if (pos == null) {
-            pos = e.getParserPosition();
-        }
-        eList.add(e);
-    }
-    (
-        <COMMA>
-        e = PatternDefinition() {
-            eList.add(e);
-        }
-    )*
-    {
-        return new SqlNodeList(eList, pos.plus(getPos()));
-    }
-}
-
-SqlNode PatternDefinition() :
-{
-    SqlNode var;
-    SqlNode e;
-}
-{
-    var = SimpleIdentifier()
-    <AS>
-    e = Expression(ExprContext.ACCEPT_SUB_QUERY) {
-        return SqlStdOperatorTable.AS.createCall(
-            var.getParserPosition().plus(getPos()), e, var);
-    }
-}
-
-// ----------------------------------------------------------------------------
-// Expressions
-
-/**
- * Parses a SQL expression (such as might occur in a WHERE clause) followed by
- * the end-of-file symbol.
- */
-SqlNode SqlExpressionEof() :
-{
-    SqlNode e;
-}
-{
-    e = Expression(ExprContext.ACCEPT_SUB_QUERY) (<EOF>)
-    {
-        return e;
-    }
-}
-
-/**
- * Parses either a row expression or a query expression without ORDER BY.
- */
-SqlNode QueryOrExpr(ExprContext exprContext) :
-{
-    SqlNodeList withList = null;
-    SqlNode e;
-    SqlOperator op;
-    SqlParserPos pos;
-    SqlParserPos withPos;
-    List<Object> list;
-}
-{
-    [
-        withList = WithList()
-    ]
-    (
-        e = LeafQueryOrExpr(exprContext)
-    )
-    {
-        list = startList(e);
-    }
-    (
-        {
-            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);
-        }
-        return e;
-    }
-}
-
-SqlNodeList WithList() :
-{
-    SqlWithItem withItem;
-    SqlParserPos pos;
-    SqlNodeList list;
-}
-{
-    <WITH> { list = new SqlNodeList(getPos()); }
-    withItem = WithItem() {list.add(withItem);}
-    (
-        <COMMA> withItem = WithItem() {list.add(withItem);}
-    )*
-    { return list; }
-}
-
-SqlWithItem WithItem() :
-{
-    SqlIdentifier id;
-    SqlNodeList columnList = null;
-    SqlNode definition;
-}
-{
-    id = SimpleIdentifier()
-    [
-        LOOKAHEAD(2)
-        columnList = ParenthesizedSimpleIdentifierList()
-    ]
-    <AS>
-    definition = ParenthesizedExpression(ExprContext.ACCEPT_QUERY)
-    {
-        return new SqlWithItem(id.getParserPosition(), id, columnList,
-            definition);
-    }
-}
-
-/**
- * Parses either a row expression, a leaf query expression, or
- * a parenthesized expression of any kind.
- */
-SqlNode LeafQueryOrExpr(ExprContext exprContext) :
-{
-    SqlNode e;
-}
-{
-    e = Expression(exprContext)
-    {
-        return e;
-    }
-    | e = LeafQuery(exprContext)
-    {
-        return e;
-    }
-}
-
-/**
- * Parses a row expression or a parenthesized expression of any kind.
- */
-SqlNode Expression(ExprContext exprContext) :
-{
-    List<Object> list;
-    SqlNode e;
-}
-{
-    list = Expression2(exprContext)
-    {
-        e = SqlParserUtil.toTree(list);
-        return e;
-    }
-}
-
-// TODO jvs 15-Nov-2003:  ANY/ALL
-
-void Expression2b(ExprContext exprContext, List<Object> list) :
-{
-    SqlNode e;
-    SqlOperator op;
-}
-{
-    (
-        op = PrefixRowOperator() {
-            checkNonQueryExpression(exprContext);
-            list.add(new SqlParserUtil.ToTreeListItem(op, getPos()));
-        }
-    )*
-    e = Expression3(exprContext) {
-        list.add(e);
-    }
-}
-
-/**
- * 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.
- */
-List<Object> Expression2(ExprContext exprContext) :
-{
-    final List<Object> list = new ArrayList();
-    List<Object> list2;
-    SqlNodeList nodeList;
-    SqlNode e;
-    SqlOperator op;
-    SqlParserPos pos = getPos();
-}
-{
-    Expression2b(exprContext, list)
-    (
-        (
-            LOOKAHEAD(2)
-            (
-                // Special case for "IN", because RHS of "IN" is the only place
-                // that an expression-list is allowed ("exp IN (exp1, exp2)").
-                LOOKAHEAD(2)
-                {
-                    checkNonQueryExpression(exprContext);
-                }
-                (
-                    <NOT> <IN>
-                    {
-                        op = SqlStdOperatorTable.NOT_IN;
-                        pos = getPos();
-                    }
-                |
-                    <IN>
-                    {
-                        op = SqlStdOperatorTable.IN;
-                        pos = getPos();
-                    }
-                )
-                nodeList = ParenthesizedQueryOrCommaList(ExprContext.ACCEPT_NONCURSOR)
-                {
-                    list.add(new SqlParserUtil.ToTreeListItem(op, pos));
-                    pos = pos.plus(getPos());
-                    // 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);
-                    }
-                }
-            |
-                LOOKAHEAD(2)
-                {
-                    checkNonQueryExpression(exprContext);
-                }
-                (
-                    <NOT> <BETWEEN>
-                    {
-                        op = SqlStdOperatorTable.NOT_BETWEEN;
-                        pos = getPos();
-                    }
-                    [
-                        <SYMMETRIC> { op = SqlStdOperatorTable.SYMMETRIC_NOT_BETWEEN; }
-                    |
-                        <ASYMMETRIC>
-                    ]
-                |
-                    <BETWEEN>
-                    {
-                        op = SqlStdOperatorTable.BETWEEN;
-                        pos = getPos();
-                    }
-                    [
-                        <SYMMETRIC> { op = SqlStdOperatorTable.SYMMETRIC_BETWEEN; }
-                    |
-                        <ASYMMETRIC>
-                    ]
-                )
-                e = Expression3(ExprContext.ACCEPT_SUB_QUERY)
-                {
-                    list.add(new SqlParserUtil.ToTreeListItem(op, pos));
-                    list.add(e);
-                }
-            |
-                {
-                    checkNonQueryExpression(exprContext);
-                    pos = getPos();
-                }
-                (
-                    <NOT>
-                    (
-                        <LIKE> { op = SqlStdOperatorTable.NOT_LIKE; }
-                    |
-                        <SIMILAR> <TO> { op = SqlStdOperatorTable.NOT_SIMILAR_TO; }
-                    )
-                |
-                    <LIKE> { op = SqlStdOperatorTable.LIKE; }
-                |
-                    <SIMILAR> <TO> { op = SqlStdOperatorTable.SIMILAR_TO; }
-                )
-                list2 = Expression2(ExprContext.ACCEPT_SUB_QUERY)
-                {
-                    list.add(new SqlParserUtil.ToTreeListItem(op, pos));
-                    list.addAll(list2);
-                }
-                [
-                    LOOKAHEAD(2)
-                    <ESCAPE> e = Expression3(ExprContext.ACCEPT_SUB_QUERY)
-                    {
-                        pos = getPos();
-                        list.add(
-                            new SqlParserUtil.ToTreeListItem(
-                                SqlStdOperatorTable.ESCAPE, pos));
-                        list.add(e);
-                    }
-                ]
-            |
-                LOOKAHEAD(3) op = BinaryRowOperator()
-                {
-                    checkNonQueryExpression(exprContext);
-                    list.add(new SqlParserUtil.ToTreeListItem(op, getPos()));
-                }
-                Expression2b(ExprContext.ACCEPT_SUB_QUERY, list)
-            |
-                <LBRACKET>
-                e = Expression(ExprContext.ACCEPT_SUB_QUERY)
-                <RBRACKET>
-                {
-                    list.add(
-                        new SqlParserUtil.ToTreeListItem(
-                            SqlStdOperatorTable.ITEM, getPos()));
-                    list.add(e);
-                }
-            |
-                {
-                    checkNonQueryExpression(exprContext);
-                }
-                op = PostfixRowOperator()
-                {
-                    list.add(new SqlParserUtil.ToTreeListItem(op, getPos()));
-                }
-            )
-        ) +
-        {
-            return list;
-        }
-        |
-        {
-            return list;
-        }
-    )
-}
-
-/**
- * Parses a unary row expression, or a parenthesized expression of any
- * kind.
- */
-SqlNode Expression3(ExprContext exprContext) :
-{
-    SqlNode e;
-    SqlNodeList list;
-    SqlNodeList list1;
-    SqlNodeList list2;
-    SqlPrefixOperator op;
-    boolean rowSeen = false;
-    SqlParserPos pos;
-    SqlParserPos prefixRowOpPos;
-}
-{
-    LOOKAHEAD(2)
-    e = AtomicRowExpression()
-    {
-        checkNonQueryExpression(exprContext);
-        return e;
-    }
-    |
-    e = CursorExpression(exprContext) { return e; }
-    |
-    LOOKAHEAD(3)
-    <ROW> list = ParenthesizedSimpleIdentifierList()
-    {
-        pos = getPos();
-        if (exprContext != ExprContext.ACCEPT_ALL
-            && exprContext != ExprContext.ACCEPT_CURSOR)
-        {
-            throw SqlUtil.newContextException(pos,
-                RESOURCE.illegalRowExpression());
-        }
-        return SqlStdOperatorTable.ROW.createCall(list);
-    }
-    |
-    {
-        pos = getPos();
-    }
-    [
-        <ROW>
-        {
-            pos = getPos(); rowSeen = true;
-        }
-    ]
-    list1 = ParenthesizedQueryOrCommaList(exprContext) {
-        if (rowSeen) {
-            // interpret as row constructor
-            return SqlStdOperatorTable.ROW.createCall(pos, list1.toArray());
-
-        }
-    }
-    [
-        (
-            <OVERLAPS>
-            list2 = ParenthesizedQueryOrCommaList(exprContext)
-            {
-                if (list1.size() != 2 || list2.size() != 2) {
-                    throw SqlUtil.newContextException(
-                        list1.getParserPosition().plus(
-                            list2.getParserPosition()),
-                        RESOURCE.illegalOverlaps());
-                }
-                for (SqlNode node : list2) {
-                    list1.add(node);
-                }
-                return SqlStdOperatorTable.OVERLAPS.createCall(
-                    list1.getParserPosition().plus(list2.getParserPosition()),
-                    list1.toArray());
-            }
-        )
-        |
-        (
-            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);
-                        return SqlStdOperatorTable.MINUS_DATE.createCall(
-                            list1.getParserPosition().plus(getPos()),
-                            SqlParserUtil.toNodeArray(list3));
-                     }
-                }
-                throw SqlUtil.newContextException(
-                    list1.getParserPosition().plus(getPos()),
-                    RESOURCE.illegalMinusDate());
-            }
-        )
-    ]
-    {
-        if (list1.size() == 1) {
-            // interpret as single value or query
-            return list1.get(0);
-        } else {
-            // interpret as row constructor
-            return SqlStdOperatorTable.ROW.createCall(pos, list1.toArray());
-        }
-    }
-}
-
-/**
- * Parses a COLLATE clause
- */
-SqlCollation CollateClause() :
-{
-}
-{
-    <COLLATE> <COLLATION_ID>
-    {
-        return new SqlCollation(
-            getToken(0).image, SqlCollation.Coercibility.EXPLICIT);
-    }
-}
-
-/**
- * Parses an atomic row expression.
- */
-SqlNode AtomicRowExpression() :
-{
-    SqlNode e;
-    SqlParserPos pos;
-}
-{
-    LOOKAHEAD(1)
-    e = Literal() { return e; }
-    |
-    e = DynamicParam() { return e; }
-    |
-    e = BuiltinFunctionCall() { return e; }
-    |
-    e = JdbcFunctionCall() { return e; }
-    |
-    e = MultisetConstructor() { return e; }
-    |
-    e = ArrayConstructor() { return e; }
-    |
-    e = MapConstructor() { return e; }
-    |
-    // NOTE jvs 18-Jan-2005:  use syntactic lookahead to discriminate
-    // compound identifiers from function calls in which the function
-    // name is a compound identifier
-    LOOKAHEAD( [<SPECIFIC>] FunctionName() <LPAREN>)
-    e = NamedFunctionCall() { return e; }
-    |
-    e = ContextVariable() { return e; }
-    |
-    e = CompoundIdentifier() { return e; }
-    |
-    e = NewSpecification(

<TRUNCATED>