/*
 * 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.
 */

// To have Drill use this parser grammar instead of Calcite's (normally
// in order to exclude incompatibilities that have been introduced
// upstream), rename this file to Parser.jj, otherwise use the name
// Parser.jj.disabled. Currently this parser grammar is in effect because of
// CALCITE-5469 which should be resolved by CALCITE-5579 after which it can be
// disabled. Also see the calcite-parser-grammar profile in
// exec/java-exec/pom.xml.

<@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!default.parser.imports) as importStr>
import ${importStr};
</#list>

import org.apache.calcite.avatica.util.Casing;
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.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.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.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.Pair;
import org.apache.calcite.util.SourceStringReader;
import org.apache.calcite.util.Util;
import org.apache.calcite.util.trace.CalciteTrace;

import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import org.slf4j.Logger;

import java.io.Reader;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Locale;
import java.util.Map;

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 final SqlLiteral LITERAL_ZERO =
        SqlLiteral.createExactNumeric("0", SqlParserPos.ZERO);
    private static final SqlLiteral LITERAL_ONE =
        SqlLiteral.createExactNumeric("1", SqlParserPos.ZERO);
    private static final SqlLiteral LITERAL_MINUS_ONE =
        SqlLiteral.createExactNumeric("-1", SqlParserPos.ZERO);

    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 ${parser.class} parser = new ${parser.class}(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 (${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(SqlAbstractParserImpl.LexicalState state) {
        final int stateOrdinal =
            Arrays.asList(${parser.class}TokenManager.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();
    }

    public SqlNode parseArray() throws SqlParseException {
        switchTo(LexicalState.BQID);
        try {
          return ArrayLiteral();
        } catch (ParseException ex) {
          throw normalizeException(ex);
        } catch (TokenMgrError ex) {
          throw normalizeException(ex);
        }
    }

    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;
    }
}

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.toCase(getToken(0).image, unquotedCasing);
}

/**
 * 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()
}

/*
* Parse Floor/Ceil function parameters
*/
SqlNode FloorCeilOptions(Span s, boolean floorFlag) :
{
    SqlNode node;
}
{
    node = StandardFloorCeilOptions(s, 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() {}

/** @Deprecated */
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 protected SqlParserPos getPos()
{
    return new SqlParserPos(
        token.beginLine,
        token.beginColumn,
        token.endLine,
        token.endColumn);
}

/** Starts a span at the current position. */
JAVACODE Span span()
{
    return Span.of(getPos());
}

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());
    }
}

JAVACODE SqlNode checkNotJoin(SqlNode e)
{
    if (e instanceof SqlJoin) {
        throw SqlUtil.newContextException(e.getParserPosition(),
            RESOURCE.illegalJoinExpression());
    }
    return e;
}

/**
 * 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;
            // 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) {
        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 = 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}
    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              *
 *****************************************/

SqlNode ExprOrJoinOrOrderedQuery(ExprContext exprContext) :
{
    SqlNode e;
    final List<Object> list = new ArrayList<Object>();
}
{
    // Lookhead to distinguish between "TABLE emp" (which will be
    // matched by ExplicitTable() via Query())
    // and "TABLE fun(args)" (which will be matched by TableRef())
    (
        LOOKAHEAD(2)
        e = Query(exprContext)
        e = OrderByLimitOpt(e)
        { return e; }
    |
        e = TableRef1(ExprContext.ACCEPT_QUERY_OR_JOIN)
        ( e = JoinTable(e) )*
        { list.add(e); }
        ( AddSetOpQuery(list, exprContext) )*
        { return SqlParserUtil.toTree(list); }
    )
}

/**
 * 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>Trino syntax for limit:
 *
 * <blockquote><pre>
 *    [ OFFSET start ]
 *    [ LIMIT { count | ALL } ]</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>
 */
SqlNode OrderedQueryOrExpr(ExprContext exprContext) :
{
    SqlNode e;
}
{
    e = QueryOrExpr(exprContext)
    e = OrderByLimitOpt(e)
    { return e; }
}

/** Reads optional "ORDER BY", "LIMIT", "OFFSET", "FETCH" following a query,
 * {@code e}. If any of them are present, adds them to the query;
 * otherwise returns the query unchanged.
 * Throws if they are present and {@code e} is not a query. */
SqlNode OrderByLimitOpt(SqlNode e) :
{
    final SqlNodeList orderBy;
    final Span s = Span.of();
    SqlNode[] offsetFetch = {null, null};
}
{
    (
        // use the syntactic type of the expression we just parsed
        // to decide whether ORDER BY makes sense
        orderBy = OrderBy(e.isA(SqlKind.QUERY))
    |   { orderBy = null; }
    )
    [
        LimitClause(s, offsetFetch)
        [ OffsetClause(s, offsetFetch) ]
    |
        OffsetClause(s, offsetFetch)
        [
            LimitClause(s, offsetFetch) {
                if (!this.conformance.isOffsetLimitAllowed()) {
                    throw SqlUtil.newContextException(s.end(this),
                        RESOURCE.offsetLimitNotAllowed());
                }
            }
        |
            FetchClause(offsetFetch)
        ]
    |
        FetchClause(offsetFetch)
    ]
    {
        if (orderBy != null || offsetFetch[0] != null || offsetFetch[1] != null) {
            return new SqlOrderBy(getPos(), e,
                Util.first(orderBy, SqlNodeList.EMPTY),
                offsetFetch[0], offsetFetch[1]);
        }
        return e;
    }
}

/**
 * Parses an OFFSET clause in an ORDER BY expression.
 */
void OffsetClause(Span s, SqlNode[] offsetFetch) :
{
}
{
    // ROW or ROWS is required in SQL:2008 but we make it optional
    // because it is not present in Postgres-style syntax.
    <OFFSET> { s.add(this); }
    offsetFetch[0] = UnsignedNumericLiteralOrParam()
    [ <ROW> | <ROWS> ]
}

/**
 * Parses a FETCH clause in an ORDER BY expression.
 */
void FetchClause(SqlNode[] offsetFetch) :
{
}
{
    // SQL:2008-style syntax. "OFFSET ... FETCH ...".
    // If you specify both LIMIT and FETCH, FETCH wins.
    <FETCH> ( <FIRST> | <NEXT> ) offsetFetch[1] = UnsignedNumericLiteralOrParam()
    ( <ROW> | <ROWS> ) <ONLY>
}

/**
 * Parses a LIMIT clause in an ORDER BY expression.
 */
void LimitClause(Span s, SqlNode[] offsetFetch) :
{
}
{
    // Postgres-style syntax. "LIMIT ... OFFSET ..."
    <LIMIT> { s.add(this); }
    (
        // MySQL-style syntax. "LIMIT start, count"
        LOOKAHEAD(2)
        offsetFetch[0] = UnsignedNumericLiteralOrParam()
        <COMMA> offsetFetch[1] = UnsignedNumericLiteralOrParam() {
            if (!this.conformance.isLimitStartCountAllowed()) {
                throw SqlUtil.newContextException(s.end(this),
                    RESOURCE.limitStartCountNotAllowed());
            }
        }
    |
        offsetFetch[1] = UnsignedNumericLiteralOrParam()
    |
        <ALL>
    )
}

/**
 * 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.
 * Depending on {@code exprContext}, may also accept a join.
 */
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 = ExprOrJoinOrOrderedQuery(exprContext)
    <RPAREN>
    {
        exprContext.throwIfNotCompatible(e);
        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
 *
 * <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.
 */
SqlNodeList ParenthesizedQueryOrCommaList(
    ExprContext exprContext) :
{
    SqlNode e;
    final List<SqlNode> list = new ArrayList<SqlNode>();
    ExprContext firstExprContext = exprContext;
    final Span s;
}
{
    <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.add(e); }
    (
        <COMMA>
        {
            // a comma-list can't appear where only a query is expected
            checkNonQueryExpression(exprContext);
        }
        AddExpression(list, exprContext)
    )*
    <RPAREN>
    {
        return new SqlNodeList(list, s.end(this));
    }
}

/** As ParenthesizedQueryOrCommaList, but allows DEFAULT
 * in place of any of the expressions. For example,
 * {@code (x, DEFAULT, null, DEFAULT)}. */
SqlNodeList ParenthesizedQueryOrCommaListWithDefault(
    ExprContext exprContext) :
{
    SqlNode e;
    final List<SqlNode> list = new ArrayList<SqlNode>();
    ExprContext firstExprContext = exprContext;
    final Span s;
}
{
    <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.add(e); }
    |
        e = Default() { list.add(e); }
    )
    (
        <COMMA>
        {
            // a comma-list can't appear where only a query is expected
            checkNonQueryExpression(exprContext);
        }
        (
            e = Expression(exprContext) { list.add(e); }
        |
            e = Default() { list.add(e); }
        )
    )*
    <RPAREN>
    {
        return new SqlNodeList(list, s.end(this));
    }
}

/**
 * Parses function parameter lists.
 * If the list starts with DISTINCT or ALL, it is discarded.
 */
List<SqlNode> UnquantifiedFunctionParameterList(ExprContext exprContext) :
{
    final List<SqlNode> args;
}
{
    args = FunctionParameterList(exprContext) {
        args.remove(0); // remove DISTINCT or ALL, if present
        return args;
    }
}

/**
 * Parses function parameter lists including DISTINCT keyword recognition,
 * DEFAULT, and named argument assignment.
 */
List<SqlNode> FunctionParameterList(ExprContext exprContext) :
{
    final SqlLiteral qualifier;
    final List<SqlNode> list = new ArrayList<SqlNode>();
}
{
    <LPAREN>
    (
        qualifier = AllOrDistinct() { list.add(qualifier); }
    |
        { list.add(null); }
    )
    AddArg0(list, exprContext)
    (
        <COMMA> {
            // a comma-list can't appear where only a query is expected
            checkNonQueryExpression(exprContext);
        }
        AddArg(list, exprContext)
    )*
    <RPAREN>
    {
        return list;
    }
}

SqlLiteral AllOrDistinct() :
{
}
{
    <DISTINCT> { return SqlSelectKeyword.DISTINCT.symbol(getPos()); }
|
    <ALL> { return SqlSelectKeyword.ALL.symbol(getPos()); }
}

void AddArg0(List<SqlNode> list, ExprContext exprContext) :
{
    final SqlIdentifier name;
    SqlNode e;
    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;
        }
    }
}
{
    (
        LOOKAHEAD(2) name = SimpleIdentifier() <NAMED_ARGUMENT_ASSIGNMENT>
    |   { name = null; }
    )
    (
        e = Default()
    |
        LOOKAHEAD(3)
        e = TableParam()
    |
        e = PartitionedQueryOrQueryOrExpr(firstExprContext)
    )
    {
        if (name != null) {
            e = SqlStdOperatorTable.ARGUMENT_ASSIGNMENT.createCall(
                Span.of(name, e).pos(), e, name);
        }
        list.add(e);
    }
}

void AddArg(List<SqlNode> list, ExprContext exprContext) :
{
    final SqlIdentifier name;
    SqlNode e;
}
{
    (
        LOOKAHEAD(2) name = SimpleIdentifier() <NAMED_ARGUMENT_ASSIGNMENT>
    |   { name = null; }
    )
    (
        e = Default()
    |
        e = Expression(exprContext)
    |
        e = TableParam()
    )
    {
        if (name != null) {
            e = SqlStdOperatorTable.ARGUMENT_ASSIGNMENT.createCall(
                Span.of(name, e).pos(), e, name);
        }
        list.add(e);
    }
}

SqlNode Default() : {}
{
    <DEFAULT_> {
        return SqlStdOperatorTable.DEFAULT.createCall(getPos());
    }
}

/**
 * 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 a list of SQL statements separated by semicolon.
 * The semicolon is required between statements, but is
 * optional at the end.
 */
SqlNodeList SqlStmtList() :
{
    final List<SqlNode> stmtList = new ArrayList<SqlNode>();
    SqlNode stmt;
}
{
    stmt = SqlStmt() {
        stmtList.add(stmt);
    }
    (
        <SEMICOLON>
        [
            stmt = SqlStmt() {
                stmtList.add(stmt);
            }
        ]
    )*
    <EOF>
    {
        return new SqlNodeList(stmtList, Span.of(stmtList).pos());
    }
}

/**
 * Parses an SQL statement.
 */
SqlNode SqlStmt() :
{
    SqlNode stmt;
}
{
    (
<#-- Add methods to parse additional statements here -->
<#list (parser.statementParserMethods!default.parser.statementParserMethods) as method>
        LOOKAHEAD(2) stmt = ${method}
    |
</#list>
        stmt = SqlSetOption(Span.of(), null)
    |
        stmt = SqlAlter()
    |
<#if (parser.createStatementParserMethods!default.parser.createStatementParserMethods)?size != 0>
        stmt = SqlCreate()
    |
</#if>
<#if (parser.dropStatementParserMethods!default.parser.dropStatementParserMethods)?size != 0>
        stmt = SqlDrop()
    |
</#if>
        stmt = OrderedQueryOrExpr(ExprContext.ACCEPT_QUERY)
    |
        stmt = SqlExplain()
    |
        stmt = SqlDescribe()
    |
        stmt = SqlInsert()
    |
        stmt = SqlDelete()
    |
        stmt = SqlUpdate()
    |
        stmt = SqlMerge()
    |
        stmt = SqlProcedureCall()
    )
    {
        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!default.parser.implementationFiles) as file>
    <#include "/@includes/"+file />
</#list>

SqlNodeList ParenthesizedKeyValueOptionCommaList() :
{
    final Span s;
    final List<SqlNode> list = new ArrayList<SqlNode>();
}
{
    { s = span(); }
    <LPAREN>
    AddKeyValueOption(list)
    (
        <COMMA>
        AddKeyValueOption(list)
    )*
    <RPAREN> {
        return new SqlNodeList(list, s.end(this));
    }
}

/**
* Parses an option with format key=val whose key is a simple identifier or string literal
* and value is a string literal.
*/
void AddKeyValueOption(List<SqlNode> list) :
{
    final SqlNode key;
    final SqlNode value;
}
{
    (
        key = SimpleIdentifier()
    |
        key = StringLiteral()
    )
    <EQ>
    value = StringLiteral() {
        list.add(key);
        list.add(value);
    }
}

/** Parses an option value (either a string or a numeric) and adds to a list. */
void AddOptionValue(List<SqlNode> list) :
{
    final SqlNode value;
}
{
    (
        value = NumericLiteral() { list.add(value); }
    |
        value = StringLiteral() { list.add(value); }
    )
}

/**
 * Parses a literal list separated by comma. The literal is either a string or a numeric.
 */
SqlNodeList ParenthesizedLiteralOptionCommaList() :
{
    final Span s;
    final List<SqlNode> list = new ArrayList<SqlNode>();
}
{
    { s = span(); }
    <LPAREN>
    AddOptionValue(list) ( <COMMA> AddOptionValue(list) )*
    <RPAREN> {
        return new SqlNodeList(list, s.end(this));
    }
}

void AddHint(List<SqlNode> hints) :
{
    final SqlIdentifier hintName;
    final SqlNodeList hintOptions;
    final SqlHint.HintOptionFormat optionFormat;
}
{
    hintName = SimpleIdentifier()
    (
       LOOKAHEAD(5)
        hintOptions = ParenthesizedKeyValueOptionCommaList() {
            optionFormat = SqlHint.HintOptionFormat.KV_LIST;
        }
    |
        LOOKAHEAD(3)
        hintOptions = ParenthesizedSimpleIdentifierList() {
            optionFormat = SqlHint.HintOptionFormat.ID_LIST;
        }
    |
        LOOKAHEAD(3)
        hintOptions = ParenthesizedLiteralOptionCommaList() {
            optionFormat = SqlHint.HintOptionFormat.LITERAL_LIST;
        }
    |
        LOOKAHEAD(2)
        [<LPAREN> <RPAREN>]
        {
            hintOptions = SqlNodeList.EMPTY;
            optionFormat = SqlHint.HintOptionFormat.EMPTY;
        }
    )
    {
        hints.add(
           new SqlHint(Span.of(hintOptions).end(this), hintName, hintOptions,
               optionFormat));
    }
}

/** Parses hints following a table reference,
 * and returns the wrapped table reference. */
SqlNode TableHints(SqlIdentifier tableName) :
{
    final List<SqlNode> hints = new ArrayList<SqlNode>();
}
{
    <HINT_BEG> AddHint(hints) ( <COMMA> AddHint(hints) )* <COMMENT_END> {
        final SqlParserPos pos = Span.of(tableName).addAll(hints).end(this);
        final SqlNodeList hintList = new SqlNodeList(hints, pos);
        return new SqlTableRef(pos, tableName, hintList);
    }
}

/**
 * Parses a leaf SELECT expression without ORDER BY.
 */
SqlSelect SqlSelect() :
{
    final List<SqlLiteral> keywords = new ArrayList<SqlLiteral>();
    final SqlLiteral keyword;
    final SqlNodeList keywordList;
    final List<SqlNode> selectList = new ArrayList<SqlNode>();
    final SqlNode fromClause;
    final SqlNode where;
    final SqlNodeList groupBy;
    final SqlNode having;
    final SqlNodeList windowDecls;
    final SqlNode qualify;
    final List<SqlNode> hints = new ArrayList<SqlNode>();
    final Span s;
}
{
    <SELECT> { s = span(); }
    [ <HINT_BEG> AddHint(hints) ( <COMMA> AddHint(hints) )* <COMMENT_END> ]
    SqlSelectKeywords(keywords)
    (
        <STREAM> {
            keywords.add(SqlSelectKeyword.STREAM.symbol(getPos()));
        }
    )?
    (
        keyword = AllOrDistinct() { keywords.add(keyword); }
    )?
    {
        keywordList = new SqlNodeList(keywords, s.addAll(keywords).pos());
    }
    AddSelectItem(selectList)
    ( <COMMA> AddSelectItem(selectList) )*
    (
        <FROM> fromClause = FromClause()
        ( where = Where() | { where = null; } )
        ( groupBy = GroupBy() | { groupBy = null; } )
        ( having = Having() | { having = null; } )
        ( windowDecls = Window() | { windowDecls = null; } )
        ( qualify = Qualify() | { qualify = null; } )
    |
        E() {
            fromClause = null;
            where = null;
            groupBy = null;
            having = null;
            windowDecls = null;
            qualify = null;
        }
    )
    {
        return new SqlSelect(s.end(this), keywordList,
            new SqlNodeList(selectList, Span.of(selectList).pos()),
            fromClause, where, groupBy, having, windowDecls, qualify,
            null, null, null, new SqlNodeList(hints, getPos()));
    }
}

/*
 * 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;
    final SqlExplainFormat format;
}
{
    <EXPLAIN> <PLAN>
    [ detailLevel = ExplainDetailLevel() ]
    depth = ExplainDepth()
    (
        LOOKAHEAD(2)
        <AS> <XML> { format = SqlExplainFormat.XML; }
    |
        LOOKAHEAD(2)
        <AS> <JSON> { format = SqlExplainFormat.JSON; }
    |
        <AS> <DOT_FORMAT> { format = SqlExplainFormat.DOT; }
    |
        { format = SqlExplainFormat.TEXT; }
    )
    <FOR> stmt = SqlQueryOrDml() {
        return new SqlExplain(getPos(),
            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 Span s;
   final SqlIdentifier table;
   final SqlIdentifier column;
   final SqlIdentifier id;
   final SqlNode stmt;
}
{
    <DESCRIBE> { s = span(); }
    (
        LOOKAHEAD(2) (<DATABASE> | <CATALOG> | <SCHEMA>)
        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
            return new SqlDescribeSchema(s.end(id), id);
        }
    |
        // Use syntactic lookahead to determine whether a table name is coming.
        // We do not allow SimpleIdentifier() because that includes <STATEMENT>.
        LOOKAHEAD( <TABLE>
           | <IDENTIFIER>
           | <HYPHENATED_IDENTIFIER>
           | <QUOTED_IDENTIFIER>
           | <BACK_QUOTED_IDENTIFIER>
           | <BIG_QUERY_BACK_QUOTED_IDENTIFIER>
           | <BRACKET_QUOTED_IDENTIFIER> )
        (<TABLE>)?
        table = CompoundIdentifier()
        ( column = SimpleIdentifier() | { column = null; } )
        {
            return new SqlDescribeTable(s.add(table).addIf(column).pos(),
                table, column);
        }
    |
        (LOOKAHEAD(1) <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(s.end(stmt),
                stmt,
                detailLevel.symbol(SqlParserPos.ZERO),
                depth.symbol(SqlParserPos.ZERO),
                format.symbol(SqlParserPos.ZERO),
                nDynamicParams);
        }
    )
}

/**
 * Parses a CALL statement.
 */
SqlNode SqlProcedureCall() :
{
    final Span s;
    SqlNode routineCall;
}
{
    <CALL> {
        s = span();
    }
    routineCall = NamedRoutineCall(
        SqlFunctionCategory.USER_DEFINED_PROCEDURE,
        ExprContext.ACCEPT_SUB_QUERY)
    {
        return SqlStdOperatorTable.PROCEDURE_CALL.createCall(
            s.end(routineCall), routineCall);
    }
}

SqlNode NamedRoutineCall(
    SqlFunctionCategory routineType,
    ExprContext exprContext) :
{
    final SqlIdentifier name;
    final List<SqlNode> list = new ArrayList<SqlNode>();
    final Span s;
}
{
    name = CompoundIdentifier() {
        s = span();
    }
    <LPAREN>
    [
        AddArg0(list, exprContext)
        (
            <COMMA> {
                // a comma-list can't appear where only a query is expected
                checkNonQueryExpression(exprContext);
            }
            AddArg(list, exprContext)
        )*
    ]
    <RPAREN>
    {
        return createCall(name, s.end(this), routineType, null, list);
    }
}

/**
 * Table parameter of a table function.
 * The input table with set semantics may be partitioned/ordered on one or more columns.
 */
SqlNode TableParam() :
{
    final Span s;
    final SqlNodeList partitionList;
    final SqlNodeList orderList;
    SqlNode tableRef;
}
{
    { s = span(); }
    tableRef = ExplicitTable(getPos())
    (
        <PARTITION> <BY>
        partitionList = SimpleIdentifierOrList()
    |   { partitionList = SqlNodeList.EMPTY; }
    )
    (
        orderList = OrderByOfSetSemanticsTable()
     |  { orderList = SqlNodeList.EMPTY; }
    )
    { return CreateSetSemanticsTableIfNeeded(s, tableRef, partitionList, orderList); }
}

SqlNode PartitionedQueryOrQueryOrExpr(ExprContext exprContext) :
{
    SqlNode e;
}
{
    e = OrderedQueryOrExpr(exprContext)
    e = PartitionedByAndOrderBy(e)

    { return e; }
}

SqlNode PartitionedByAndOrderBy(SqlNode e) :
{
    final Span s;
    final SqlNodeList partitionList;
    final SqlNodeList orderList;
}
{
    { s = span(); }
    (
        <PARTITION> <BY>
        partitionList = SimpleIdentifierOrList()
    |   { partitionList = SqlNodeList.EMPTY; }
    )
    (
        orderList = OrderByOfSetSemanticsTable()
     |  { orderList = SqlNodeList.EMPTY; }
    )
    { return CreateSetSemanticsTableIfNeeded(s, e, partitionList, orderList); }
}

SqlNodeList OrderByOfSetSemanticsTable() :
{
    final List<SqlNode> list = new ArrayList<SqlNode>();
    final Span s;
}
{
  <ORDER>
  { s = span(); }
  <BY>
  (
      LOOKAHEAD(2)
      <LPAREN> AddOrderItem(list)
      (
        // NOTE jvs 6-Feb-2004:  See comments at top of file for why
        // hint is necessary here.
        LOOKAHEAD(2) <COMMA> AddOrderItem(list)
      )*
      <RPAREN> {
          return new SqlNodeList(list, s.addAll(list).pos());
      }
  |
      AddOrderItem(list)
      {
          return new SqlNodeList(list, s.addAll(list).pos());
      }
  )
}

SqlNode CreateSetSemanticsTableIfNeeded(
    final Span s,
    final SqlNode e,
    final SqlNodeList partitionList,
    final SqlNodeList orderList) :
{

}
{

    {
        if (partitionList.isEmpty() && orderList.isEmpty()) {
            return e;
        } else {
            return SqlStdOperatorTable.SET_SEMANTICS_TABLE.createCall(
                s.pos(), e, partitionList, orderList);
        }
    }
}

/**
 * Parses an INSERT statement.
 */
SqlNode SqlInsert() :
{
    final List<SqlLiteral> keywords = new ArrayList<SqlLiteral>();
    final SqlNodeList keywordList;
    final SqlIdentifier tableName;
    SqlNode tableRef;
    SqlNode source;
    final SqlNodeList columnList;
    final Span s;
    final Pair<SqlNodeList, SqlNodeList> p;
}
{
    (
        <INSERT>
    |
        <UPSERT> { keywords.add(SqlInsertKeyword.UPSERT.symbol(getPos())); }
    )
    { s = span(); }
    SqlInsertKeywords(keywords) {
        keywordList = new SqlNodeList(keywords, s.addAll(keywords).pos());
    }
    <INTO> tableName = CompoundTableIdentifier()
    ( tableRef = TableHints(tableName) | { tableRef = tableName; } )
    [ LOOKAHEAD(5) tableRef = ExtendTable(tableRef) ]
    (
        LOOKAHEAD(2)
        p = ParenthesizedCompoundIdentifierList() {
            if (p.right.size() > 0) {
                tableRef = extend(tableRef, p.right);
            }
            if (p.left.size() > 0) {
                columnList = p.left;
            } else {
                columnList = null;
            }
        }
    |   { columnList = null; }
    )
    source = OrderedQueryOrExpr(ExprContext.ACCEPT_QUERY) {
        return new SqlInsert(s.end(source), keywordList, tableRef, source,
            columnList);
    }
}

/*
 * Abstract production:
 *
 *    void SqlInsertKeywords(List keywords)
 *
 * Parses dialect-specific keywords immediately following the INSERT keyword.
 */

/**
 * Parses a DELETE statement.
 */
SqlNode SqlDelete() :
{
    final SqlIdentifier tableName;
    SqlNode tableRef;
    final SqlIdentifier alias;
    final SqlNode where;
    final Span s;
}
{
    <DELETE> {
        s = span();
    }
    <FROM> tableName = CompoundTableIdentifier()
    ( tableRef = TableHints(tableName) | { tableRef = tableName; } )
    [ tableRef = ExtendTable(tableRef) ]
    ( [ <AS> ] alias = SimpleIdentifier() | { alias = null; } )
    ( where = Where() | { where = null; } )
    {
        return new SqlDelete(s.add(tableRef).addIf(alias).addIf(where).pos(),
            tableRef, where, null, alias);
    }
}

/**
 * Parses an UPDATE statement.
 */
SqlNode SqlUpdate() :
{
    final SqlIdentifier tableName;
    SqlNode tableRef;
    final SqlIdentifier alias;
    final SqlNode where;
    final SqlNodeList sourceExpressionList;
    final SqlNodeList targetColumnList;
    SqlIdentifier id;
    final Span s;
}
{
    <UPDATE> {
        s = span();
        targetColumnList = new SqlNodeList(s.pos());
        sourceExpressionList = new SqlNodeList(s.pos());
    }
    tableName = CompoundTableIdentifier()
    ( tableRef = TableHints(tableName) | { tableRef = tableName; } )
    [ tableRef = ExtendTable(tableRef) ]
    ( [ <AS> ] alias = SimpleIdentifier() | { alias = null; } )
    <SET> id = SimpleIdentifier() {
        targetColumnList.add(id);
    }
    // TODO:  support DEFAULT also
    <EQ> AddExpression(sourceExpressionList, ExprContext.ACCEPT_SUB_QUERY)
    (
        <COMMA>
        id = SimpleIdentifier() { targetColumnList.add(id); }
        <EQ> AddExpression(sourceExpressionList, ExprContext.ACCEPT_SUB_QUERY)
    )*
    ( where = Where() | { where = null; } )
    {
        final SqlParserPos pos = s.addAll(targetColumnList)
            .addAll(sourceExpressionList).addIf(where).pos();
        return new SqlUpdate(pos, tableRef, targetColumnList,
            sourceExpressionList, where, null, alias);
    }
}

/**
 * Parses a MERGE statement.
 */
SqlNode SqlMerge() :
{
    final SqlIdentifier tableName;
    SqlNode tableRef;
    final SqlIdentifier alias;
    final SqlNode sourceTableRef;
    final SqlNode condition;
    final SqlUpdate updateCall;
    final SqlInsert insertCall;
    final Span s;
}
{
    <MERGE> { s = span(); } <INTO> tableName = CompoundTableIdentifier()
    ( tableRef = TableHints(tableName) | { tableRef = tableName; } )
    [ tableRef = ExtendTable(tableRef) ]
    ( [ <AS> ] alias = SimpleIdentifier() | { alias = null; } )
    <USING> sourceTableRef = TableRef()
    <ON> condition = Expression(ExprContext.ACCEPT_SUB_QUERY)
    (
        LOOKAHEAD(2)
        updateCall = WhenMatchedClause(tableRef, alias)
        ( insertCall = WhenNotMatchedClause(tableRef) | { insertCall = null; } )
    |
        { updateCall = null; }
        insertCall = WhenNotMatchedClause(tableRef)
    )
    {
        final SqlParserPos pos = s.addIf(updateCall).addIf(insertCall).pos();
        return new SqlMerge(pos, tableRef, condition, sourceTableRef,
            updateCall, insertCall, null, alias);
    }
}

SqlUpdate WhenMatchedClause(SqlNode table, SqlIdentifier alias) :
{
    SqlIdentifier id;
    final Span s;
    final SqlNodeList updateColumnList = new SqlNodeList(SqlParserPos.ZERO);
    final SqlNodeList updateExprList = new SqlNodeList(SqlParserPos.ZERO);
}
{
    <WHEN> { s = span(); } <MATCHED> <THEN>
    <UPDATE> <SET> id = CompoundIdentifier() {
        updateColumnList.add(id);
    }
    <EQ> AddExpression(updateExprList, ExprContext.ACCEPT_SUB_QUERY)
    (
        <COMMA>
        id = CompoundIdentifier() {
            updateColumnList.add(id);
        }
        <EQ> AddExpression(updateExprList, ExprContext.ACCEPT_SUB_QUERY)
    )*
    {
        return new SqlUpdate(s.addAll(updateExprList).pos(), table,
            updateColumnList, updateExprList, null, null, alias);
    }
}

SqlInsert WhenNotMatchedClause(SqlNode table) :
{
    final Span insertSpan, valuesSpan;
    final List<SqlLiteral> keywords = new ArrayList<SqlLiteral>();
    final SqlNodeList keywordList;
    final SqlNodeList insertColumnList;
    SqlNode rowConstructor;
    SqlNode insertValues;
}
{
    <WHEN> <NOT> <MATCHED> <THEN> <INSERT> {
        insertSpan = span();
    }
    SqlInsertKeywords(keywords) {
        keywordList = new SqlNodeList(keywords, insertSpan.end(this));
    }
    (
        LOOKAHEAD(2)
        insertColumnList = ParenthesizedSimpleIdentifierList()
    |   { insertColumnList = null; }
    )
    (
        <LPAREN>
        <VALUES> { valuesSpan = span(); } rowConstructor = RowConstructor()
        <RPAREN>
    |
        <VALUES> { valuesSpan = span(); } rowConstructor = RowConstructor()
    )
    {
        // 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);
        return new SqlInsert(insertSpan.end(this), keywordList,
            table, insertValues, insertColumnList);
    }
}

/**
 * Parses one item in a select list.
 */
void AddSelectItem(List<SqlNode> list) :
{
    final SqlNode e;
    final SqlIdentifier id;
}
{
    e = SelectExpression()
    (
        [ <AS> ]
        (
            id = SimpleIdentifier()
        |
            // Mute the warning about ambiguity between alias and continued
            // string literal.
            LOOKAHEAD(1)
            id = SimpleIdentifierFromStringLiteral()
        )
        { list.add(SqlStdOperatorTable.AS.createCall(span().end(e), e, id)); }
    |   { list.add(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;
}
{
    (
    LOOKAHEAD(3) // required for "LEFT SEMI JOIN" in Babel
<#list (parser.joinTypes!default.parser.joinTypes) as method>
        joinType = ${method}()
    |
</#list>
        <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());
    }
}

/**
 * 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;
    SqlLiteral joinType;
}
{
    e = Join()
    (
        // Comma joins should only occur at top-level in the FROM clause.
        // Valid:
        //  * FROM a, b
        //  * FROM (a CROSS JOIN b), c
        // Not valid:
        //  * FROM a CROSS JOIN (b, c)
        LOOKAHEAD(1)
        <COMMA> { joinType = JoinType.COMMA.symbol(getPos()); }
        e2 = Join() {
            e = new SqlJoin(joinType.getParserPosition(),
                e,
                SqlLiteral.createBoolean(false, joinType.getParserPosition()),
                joinType,
                e2,
                JoinConditionType.NONE.symbol(SqlParserPos.ZERO),
                null);
        }
    )*
    { return e; }
}

SqlNode Join() :
{
    SqlNode e;
}
{
    e = TableRef1(ExprContext.ACCEPT_QUERY_OR_JOIN)
    (
        LOOKAHEAD(2)
        e = JoinTable(e)
    )*
    {
        return e;
    }
}

/** Matches "LEFT JOIN t ON ...", "RIGHT JOIN t USING ...", "JOIN t". */
SqlNode JoinTable(SqlNode e) :
{
    SqlNode e2, condition;
    final SqlLiteral natural, joinType, on, using;
    SqlNodeList list;
}
{
    // LOOKAHEAD(3) is needed here rather than a LOOKAHEAD(2) because JavaCC
    // calculates minimum lookahead count incorrectly for choice that contains
    // zero size child. For instance, with the generated code,
    // "LOOKAHEAD(2, Natural(), JoinType())"
    // returns true immediately if it sees a single "<CROSS>" token. Where we
    // expect the lookahead succeeds after "<CROSS> <APPLY>".
    //
    // For more information about the issue,
    // see https://github.com/javacc/javacc/issues/86
    //
    // We allow CROSS JOIN (joinType = CROSS_JOIN) to have a join condition,
    // even though that is not valid SQL; the validator will catch it.
    LOOKAHEAD(3)
    natural = Natural()
    joinType = JoinType()
    e2 = TableRef1(ExprContext.ACCEPT_QUERY_OR_JOIN)
    (
        <ON> { on = JoinConditionType.ON.symbol(getPos()); }
        condition = Expression(ExprContext.ACCEPT_SUB_QUERY) {
            return new SqlJoin(joinType.getParserPosition(),
                e,
                natural,
                joinType,
                e2,
                on,
                condition);
        }
    |
        <USING> { using = JoinConditionType.USING.symbol(getPos()); }
        list = ParenthesizedSimpleIdentifierList() {
            return new SqlJoin(joinType.getParserPosition(),
                e,
                natural,
                joinType,
                e2,
                using,
                new SqlNodeList(list, Span.of(using).end(this)));
        }
    |
        {
            return new SqlJoin(joinType.getParserPosition(),
                e,
                natural,
                joinType,
                e2,
                JoinConditionType.NONE.symbol(joinType.getParserPosition()),
                null);
        }
    )
|
    <CROSS> { joinType = JoinType.CROSS.symbol(getPos()); } <APPLY>
    e2 = TableRef2(true) {
        if (!this.conformance.isApplyAllowed()) {
            throw SqlUtil.newContextException(getPos(), RESOURCE.applyNotAllowed());
        }
        return new SqlJoin(joinType.getParserPosition(),
            e,
            SqlLiteral.createBoolean(false, joinType.getParserPosition()),
            joinType,
            e2,
            JoinConditionType.NONE.symbol(SqlParserPos.ZERO),
            null);
    }
|
    <OUTER> { joinType = JoinType.LEFT.symbol(getPos()); } <APPLY>
    e2 = TableRef2(true) {
        if (!this.conformance.isApplyAllowed()) {
            throw SqlUtil.newContextException(getPos(), RESOURCE.applyNotAllowed());
        }
        return new SqlJoin(joinType.getParserPosition(),
            e,
            SqlLiteral.createBoolean(false, joinType.getParserPosition()),
            joinType,
            e2,
            JoinConditionType.ON.symbol(SqlParserPos.ZERO),
            SqlLiteral.createBoolean(true, joinType.getParserPosition()));
    }
}

/**
 * Parses a table reference in a FROM clause, not lateral unless LATERAL
 * is explicitly specified.
 */
SqlNode TableRef() :
{
    final SqlNode e;
}
{
    e = TableRef3(ExprContext.ACCEPT_QUERY, false) { return e; }
}

SqlNode TableRef1(ExprContext exprContext) :
{
    final SqlNode e;
}
{
    e = TableRef3(exprContext, false) { return e; }
}

/**
 * Parses a table reference in a FROM clause.
 */
SqlNode TableRef2(boolean lateral) :
{
    final SqlNode e;
}
{
    e = TableRef3(ExprContext.ACCEPT_QUERY, lateral) { return e; }
}

SqlNode TableRef3(ExprContext exprContext, boolean lateral) :
{
    final SqlIdentifier tableName;
    SqlNode tableRef;
    final SqlIdentifier alias;
    final Span s;
    SqlNodeList args;
    final SqlNodeList columnAliasList;
    SqlUnnestOperator unnestOp = SqlStdOperatorTable.UNNEST;
}
{
    (
        LOOKAHEAD(2)
        tableName = CompoundTableIdentifier()
        ( tableRef = TableHints(tableName) | { tableRef = tableName; } )
        [ tableRef = ExtendTable(tableRef) ]
        tableRef = Over(tableRef)
        [ tableRef = Snapshot(tableRef) ]
        [ tableRef = MatchRecognize(tableRef) ]
    |
        LOOKAHEAD(2)
        [ <LATERAL> { lateral = true; } ]
        tableRef = ParenthesizedExpression(exprContext)
        tableRef = Over(tableRef)
        tableRef = addLateral(tableRef, lateral)
        [ tableRef = MatchRecognize(tableRef) ]
    |
        <UNNEST> { s = span(); }
        args = ParenthesizedQueryOrCommaList(ExprContext.ACCEPT_SUB_QUERY)
        [
            <WITH> <ORDINALITY> {
                unnestOp = SqlStdOperatorTable.UNNEST_WITH_ORDINALITY;
            }
        ]
        {
            tableRef = unnestOp.createCall(s.end(this), (List<SqlNode>) args);
        }
    |
        [ <LATERAL> { lateral = true; } ]
        tableRef = TableFunctionCall()
        tableRef = addLateral(tableRef, lateral)
    |
        tableRef = ExtendedTableRef()
    )
    [
        LOOKAHEAD(2)
        tableRef = Pivot(tableRef)
    ]
    [
        LOOKAHEAD(2)
        tableRef = Unpivot(tableRef)
    ]
    [
        [ <AS> ] alias = SimpleIdentifier()
        (
            columnAliasList = ParenthesizedSimpleIdentifierList()
        |   { columnAliasList = null; }
        )
        {
            // Standard SQL (and Postgres) allow applying "AS alias" to a JOIN,
            // e.g. "FROM (a CROSS JOIN b) AS c". The new alias obscures the
            // internal aliases, and columns cannot be referenced if they are
            // not unique. TODO: Support this behavior; see
            // [CALCITE-5168] Allow AS after parenthesized JOIN
            checkNotJoin(tableRef);
            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);
            }
        }
    ]
    [ tableRef = Tablesample(tableRef) ]
    { return tableRef; }
}

SqlNode Tablesample(SqlNode tableRef) :
{
    final Span s;
    final SqlNode sample;
    final boolean isBernoulli;
    final SqlNumericLiteral samplePercentage;
    boolean isRepeatable = false;
    int repeatableSeed = 0;
}
{
    <TABLESAMPLE> { s = span(); checkNotJoin(tableRef); }
    (
        <SUBSTITUTE> <LPAREN> sample = StringLiteral() <RPAREN>
        {
            String sampleName =
                SqlLiteral.unchain(sample).getValueAs(String.class);
            SqlSampleSpec sampleSpec = SqlSampleSpec.createNamed(sampleName);
            final SqlLiteral sampleLiteral =
                SqlLiteral.createSample(sampleSpec, s.end(this));
            tableRef = SqlStdOperatorTable.TABLESAMPLE.createCall(
                s.add(tableRef).end(this), 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 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, s.end(this));
                tableRef = SqlStdOperatorTable.TABLESAMPLE.createCall(
                    s.end(this), tableRef, tableSampleLiteral);
            }
        }
    )
    { return tableRef; }
}

/** Wraps a table reference in a call to EXTEND if an optional "EXTEND" clause
 * is present. */
SqlNode ExtendTable(SqlNode tableRef) :
{
    final SqlNodeList extendList;
}
{
    [ <EXTEND> ]
    extendList = ExtendList() {
        return extend(tableRef, extendList);
    }
}

SqlNodeList ExtendList() :
{
    final Span s;
    List<SqlNode> list = new ArrayList<SqlNode>();
}
{
    <LPAREN> { s = span(); }
    AddColumnType(list)
    (
        <COMMA> AddColumnType(list)
    )*
    <RPAREN> {
        return new SqlNodeList(list, s.end(this));
    }
}

void AddColumnType(List<SqlNode> list) :
{
    final SqlIdentifier name;
    final SqlDataTypeSpec type;
    final boolean nullable;
}
{
    name = CompoundIdentifier()
    type = DataType()
    nullable = NotNullOpt()
    {
        list.add(name);
        list.add(type.withNullable(nullable, getPos()));
    }
}

/**
 * Parses a compound identifier with optional type.
 */
void AddCompoundIdentifierType(List<SqlNode> list, List<SqlNode> extendList) :
{
    final SqlIdentifier name;
    final SqlDataTypeSpec type;
    final boolean nullable;
}
{
    name = CompoundIdentifier()
    (
        type = DataType()
        nullable = NotNullOpt()
    |
        { type = null; nullable = true; }
    )
    {
        if (type != null) {
            if (!this.conformance.allowExtend()) {
                throw SqlUtil.newContextException(type.getParserPosition(),
                    RESOURCE.extendNotAllowed());
            }
            extendList.add(name);
            extendList.add(type.withNullable(nullable, getPos()));
        }
        list.add(name);
    }
}

SqlNode TableFunctionCall() :
{
    final Span s;
    final SqlNode call;
    SqlFunctionCategory funcType = SqlFunctionCategory.USER_DEFINED_TABLE_FUNCTION;
}
{
    <TABLE> { s = span(); } <LPAREN>
    [
        <SPECIFIC>
        {
            funcType = SqlFunctionCategory.USER_DEFINED_TABLE_SPECIFIC_FUNCTION;
        }
    ]
    call = NamedRoutineCall(funcType, ExprContext.ACCEPT_CURSOR)
    <RPAREN>
    {
        return SqlStdOperatorTable.COLLECTION_TABLE.createCall(s.end(this), call);
    }
}

/**
 * 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.
 */
SqlNode ExplicitTable(SqlParserPos pos) :
{
    SqlNode tableRef;
}
{
    <TABLE> tableRef = CompoundIdentifier()
    {
        return SqlStdOperatorTable.EXPLICIT_TABLE.createCall(pos, tableRef);
    }
}

/**
 * Parses a VALUES leaf query expression.
 */
SqlNode TableConstructor() :
{
    final List<SqlNode> list = new ArrayList<SqlNode>();
    final Span s;
}
{
    (
        <VALUES> { s = span(); }
    |
        <VALUE>
        {
            s = span();
            if (!this.conformance.isValueAllowed()) {
                throw SqlUtil.newContextException(getPos(), RESOURCE.valueNotAllowed());
            }
        }
    )
    AddRowConstructor(list)
    (
        LOOKAHEAD(2)
        <COMMA> AddRowConstructor(list)
    )*
    {
        return SqlStdOperatorTable.VALUES.createCall(s.end(this), list);
    }
}

/** Parses a row constructor and adds it to a list. */
void AddRowConstructor(List<SqlNode> list) :
{
    SqlNode e;
}
{
    e = RowConstructor() { list.add(e); }
}

/**
 * Parses a row constructor in the context of a VALUES expression.
 */
SqlNode RowConstructor() :
{
    final SqlNodeList valueList;
    final SqlNode value;
    final Span s;
}
{
    // 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> { s = span(); }
        <ROW>
        valueList = ParenthesizedQueryOrCommaListWithDefault(ExprContext.ACCEPT_NONCURSOR)
        <RPAREN> { s.add(this); }
    |
        LOOKAHEAD(3)
        (
            <ROW> { s = span(); }
        |
            { s = Span.of(); }
        )
        valueList = ParenthesizedQueryOrCommaListWithDefault(ExprContext.ACCEPT_NONCURSOR)
    |
        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 TableConstructor().  It would be so much more
            // reasonable to require parentheses.  Sigh.
            s = Span.of(value);
            valueList = new SqlNodeList(ImmutableList.of(value),
                value.getParserPosition());
        }
    )
    {
        // 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(s.end(valueList),
            (List<SqlNode>) valueList);
    }
}

/** Parses a WHERE clause for SELECT, DELETE, and UPDATE. */
SqlNode Where() :
{
    SqlNode condition;
}
{
    <WHERE> condition = Expression(ExprContext.ACCEPT_SUB_QUERY) {
        return condition;
    }
}

/** Parses a GROUP BY clause for SELECT. */
SqlNodeList GroupBy() :
{
    final List<SqlNode> list;
    final boolean distinct;
    final Span s;
}
{
    <GROUP> { s = span(); }
    <BY>
    (
        <DISTINCT> { distinct = true; }
    |   <ALL> { distinct = false; }
    |   { distinct = false; }
    )
    list = GroupingElementList() {
        final SqlParserPos pos = s.end(this);
        final List<SqlNode> list2 = distinct
            ? ImmutableList.of(
                SqlInternalOperators.GROUP_BY_DISTINCT.createCall(pos, list))
            : list;
        return new SqlNodeList(list2, pos);
    }
}

List<SqlNode> GroupingElementList() :
{
    final List<SqlNode> list = new ArrayList<SqlNode>();
}
{
    AddGroupingElement(list)
    ( LOOKAHEAD(2) <COMMA> AddGroupingElement(list) )*
    { return list; }
}

void AddGroupingElement(List<SqlNode> list) :
{
    final List<SqlNode> subList;
    final SqlNodeList nodes;
    final Span s;
}
{
    LOOKAHEAD(2)
    <GROUPING> { s = span(); }
    <SETS> <LPAREN> subList = GroupingElementList() <RPAREN> {
        list.add(
            SqlStdOperatorTable.GROUPING_SETS.createCall(s.end(this), subList));
    }
|   <ROLLUP> { s = span(); }
    <LPAREN> nodes = ExpressionCommaList(s, ExprContext.ACCEPT_SUB_QUERY)
    <RPAREN> {
        list.add(
            SqlStdOperatorTable.ROLLUP.createCall(s.end(this), nodes.getList()));
    }
|   <CUBE> { s = span(); }
    <LPAREN> nodes = ExpressionCommaList(s, ExprContext.ACCEPT_SUB_QUERY)
    <RPAREN> {
        list.add(
            SqlStdOperatorTable.CUBE.createCall(s.end(this), nodes.getList()));
    }
|   LOOKAHEAD(3)
    <LPAREN> { s = span(); } <RPAREN> {
        list.add(new SqlNodeList(s.end(this)));
    }
|   AddExpression(list, ExprContext.ACCEPT_SUB_QUERY)
}

/**
 * Parses a list of expressions separated by commas.
 */
SqlNodeList ExpressionCommaList(
    final Span s,
    ExprContext exprContext) :
{
    final List<SqlNode> list = new ArrayList<SqlNode>();
}
{
    AddExpressions(list, exprContext) {
        return new SqlNodeList(list, s.addAll(list).pos());
    }
}

/**
 * Parses a list of expressions separated by commas,
 * appending expressions to a given list.
 */
void AddExpressions(List<SqlNode> list, ExprContext exprContext) :
{
}
{
    AddExpression(list, exprContext)
    (
        // NOTE jvs 6-Feb-2004:  See comments at top of file for why
        // hint is necessary here.
        LOOKAHEAD(2)
        <COMMA> AddExpression(list, ExprContext.ACCEPT_SUB_QUERY)
    )*
}

/** Parses a HAVING clause for SELECT. */
SqlNode Having() :
{
    SqlNode e;
}
{
    <HAVING> e = Expression(ExprContext.ACCEPT_SUB_QUERY) { return e; }
}

/** Parses a WINDOW clause for SELECT. */
SqlNodeList Window() :
{
    final List<SqlNode> list = new ArrayList<SqlNode>();
    final Span s;
}
{
    <WINDOW> { s = span(); }
    AddWindowSpec(list)
    (
        LOOKAHEAD(2)
        <COMMA> AddWindowSpec(list)
    )*
    {
        return new SqlNodeList(list, s.addAll(list).pos());
    }
}

void AddWindowSpec(List<SqlNode> list) :
{
    final SqlIdentifier id;
    final SqlWindow e;
}
{
    id = SimpleIdentifier() <AS> e = WindowSpecification() {
        e.setDeclName(id);
        list.add(e);
    }
}

/**
 * Parses a window specification.
 */
SqlWindow WindowSpecification() :
{
    final SqlIdentifier id;
    final SqlNodeList partitionList;
    final SqlNodeList orderList;
    final SqlLiteral isRows;
    final SqlNode lowerBound, upperBound;
    final Span s, s1, s2;
    final SqlLiteral allowPartial;
}
{
    <LPAREN> { s = span(); }
    (
        id = SimpleIdentifier()
    |   { id = null; }
    )
    (
        <PARTITION> { s1 = span(); }
        <BY>
        partitionList = ExpressionCommaList(s1, 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()
            { upperBound = null; }
        )
    |
        {
            isRows = SqlLiteral.createBoolean(false, SqlParserPos.ZERO);
            lowerBound = upperBound = null;
        }
    )
    (
        <ALLOW> { s2 = span(); } <PARTIAL> {
            allowPartial = SqlLiteral.createBoolean(true, s2.end(this));
        }
    |
        <DISALLOW> { s2 = span(); } <PARTIAL> {
            allowPartial = SqlLiteral.createBoolean(false, s2.end(this));
        }
    |   { allowPartial = null; }
    )
    <RPAREN>
    {
        return SqlWindow.create(null, id, partitionList, orderList,
            isRows, lowerBound, upperBound, allowPartial, s.end(this));
    }
}

SqlNode WindowRange() :
{
    final SqlNode e;
    final Span s;
}
{
    LOOKAHEAD(2)
    <CURRENT> { s = span(); } <ROW> {
        return SqlWindow.createCurrentRow(s.end(this));
    }
|
    LOOKAHEAD(2)
    <UNBOUNDED> { s = span(); }
    (
        <PRECEDING> {
            return SqlWindow.createUnboundedPreceding(s.end(this));
        }
    |
        <FOLLOWING> {
            return SqlWindow.createUnboundedFollowing(s.end(this));
        }
    )
|
    e = Expression(ExprContext.ACCEPT_NON_QUERY)
    (
        <PRECEDING> {
            return SqlWindow.createPreceding(e, getPos());
        }
    |
        <FOLLOWING> {
            return SqlWindow.createFollowing(e, getPos());
        }
    )
}

/** Parses a QUALIFY clause for SELECT. */
SqlNode Qualify() :
{
    SqlNode e;
}
{
    <QUALIFY> e = Expression(ExprContext.ACCEPT_SUB_QUERY) { return e; }
}

/**
 * Parses an ORDER BY clause.
 */
SqlNodeList OrderBy(boolean accept) :
{
    final List<SqlNode> list = new ArrayList<SqlNode>();
    final Span s;
}
{
    <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.
            throw SqlUtil.newContextException(s.pos(), RESOURCE.illegalOrderBy());
        }
    }
    <BY> AddOrderItem(list)
    (
        // NOTE jvs 6-Feb-2004:  See comments at top of file for why
        // hint is necessary here.
        LOOKAHEAD(2) <COMMA> AddOrderItem(list)
    )*
    {
        return new SqlNodeList(list, s.addAll(list).pos());
    }
}

/**
 * Parses one item in an ORDER BY clause, and adds it to a list.
 */
void AddOrderItem(List<SqlNode> list) :
{
    SqlNode e;
}
{
    e = Expression(ExprContext.ACCEPT_SUB_QUERY)
    (
        <ASC>
    |   <DESC> {
            e = SqlStdOperatorTable.DESC.createCall(getPos(), e);
        }
    )?
    (
        LOOKAHEAD(2)
        <NULLS> <FIRST> {
            e = SqlStdOperatorTable.NULLS_FIRST.createCall(getPos(), e);
        }
    |
        <NULLS> <LAST> {
            e = SqlStdOperatorTable.NULLS_LAST.createCall(getPos(), e);
        }
    )?
    {
        list.add(e);
    }
}

/** Wraps a table reference in a call to OVER if an optional "OVER" clause
 * is present (if the dialect supports OVER for table expressions). */
SqlNode Over(SqlNode tableRef) :
{
    final SqlNode over;
}
{
    over = TableOverOpt() {
        if (over != null) {
            return SqlStdOperatorTable.OVER.createCall(
                getPos(), checkNotJoin(tableRef), over);
        } else {
            return tableRef;
        }
    }
}

/** Wraps a table reference in a call to LATERAL if {@code lateral} is true. */
JAVACODE SqlNode addLateral(SqlNode tableRef, boolean lateral) {
    return lateral
        ? SqlStdOperatorTable.LATERAL.createCall(getPos(),
            checkNotJoin(tableRef))
        : tableRef;
}

/**
 * Parses a FOR SYSTEM_TIME clause following a table expression.
 */
SqlSnapshot Snapshot(SqlNode tableRef) :
{
    final Span s;
    final SqlNode e;
}
{
    { s = span(); } <FOR> <SYSTEM_TIME> <AS> <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) {
        return new SqlSnapshot(s.end(this), tableRef, e);
    }
}

/** Parses a PIVOT clause following a table expression. */
SqlNode Pivot(SqlNode tableRef) :
{
    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;
}
{
    <PIVOT> { s = span(); checkNotJoin(tableRef); }
    <LPAREN>
    AddPivotAgg(aggList) ( <COMMA> AddPivotAgg(aggList) )*
    <FOR> axisList = SimpleIdentifierOrList()
    <IN> <LPAREN> { s2 = span(); }
    [ AddPivotValue(valueList) ( <COMMA> AddPivotValue(valueList) )* ]
    <RPAREN> {
        inList = new SqlNodeList(valueList, s2.end(this));
    }
    <RPAREN>
    {
        return new SqlPivot(s.end(this), tableRef,
            new SqlNodeList(aggList, SqlParserPos.sum(aggList)),
            axisList, inList);
    }
}

void AddPivotAgg(List<SqlNode> list) :
{
    final SqlNode e;
    final SqlIdentifier alias;
}
{
    e = NamedFunctionCall()
    (
        // Because babel put FOR into non-reserved keyword set.
        LOOKAHEAD({getToken(1).kind != COMMA && getToken(1).kind != FOR})
        [ <AS> ] alias = SimpleIdentifier() {
            list.add(
                SqlStdOperatorTable.AS.createCall(Span.of(e).end(this), e,
                    alias));
        }
    |
        { list.add(e); }
    )
}

void AddPivotValue(List<SqlNode> list) :
{
    final SqlNode e;
    final SqlNodeList tuple;
    final SqlIdentifier alias;
}
{
    e = RowConstructor() { tuple = SqlParserUtil.stripRow(e); }
    (
        [ <AS> ] alias = SimpleIdentifier() {
            list.add(
                SqlStdOperatorTable.AS.createCall(Span.of(tuple).end(this),
                    tuple, alias));
        }
    |
        { list.add(tuple); }
    )
}

/** Parses an UNPIVOT clause following a table expression. */
SqlNode Unpivot(SqlNode tableRef) :
{
    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;
}
{
    <UNPIVOT> { s = span(); checkNotJoin(tableRef); }
    (
        <INCLUDE> <NULLS> { includeNulls = true; }
    |   <EXCLUDE> <NULLS> { includeNulls = false; }
    |   { includeNulls = false; }
    )
    <LPAREN>
    measureList = SimpleIdentifierOrList()
    <FOR> axisList = SimpleIdentifierOrList()
    <IN>
    <LPAREN> { s2 = span(); }
    AddUnpivotValue(values) ( <COMMA> AddUnpivotValue(values) )*
    <RPAREN>
    { inList = new SqlNodeList(values, s2.end(this)); }
    <RPAREN> {
        return new SqlUnpivot(s.end(this), tableRef, includeNulls, measureList,
            axisList, inList);
    }
}

void AddUnpivotValue(List<SqlNode> list) :
{
    final SqlNodeList columnList;
    final SqlNode values;
}
{
    columnList = SimpleIdentifierOrList()
    (
        <AS> values = RowConstructor() {
            final SqlNodeList valueList = SqlParserUtil.stripRow(values);
            list.add(
                SqlStdOperatorTable.AS.createCall(Span.of(columnList).end(this),
                    columnList, valueList));
        }
    |
        { list.add(columnList); }
    )
}

/**
 * Parses a MATCH_RECOGNIZE clause following a table expression.
 */
SqlMatchRecognize MatchRecognize(SqlNode tableRef) :
{
    final Span s, s0, s1, s2;
    final SqlNodeList measureList;
    final SqlNodeList partitionList;
    final SqlNodeList orderList;
    final SqlNode pattern;
    final SqlLiteral interval;
    final SqlNodeList patternDefList;
    final SqlNode after;
    final SqlNode var;
    final SqlLiteral rowsPerMatch;
    final SqlNodeList subsetList;
    final SqlLiteral isStrictStarts;
    final SqlLiteral isStrictEnds;
}
{
    <MATCH_RECOGNIZE> { s = span(); checkNotJoin(tableRef); } <LPAREN>
    (
        <PARTITION> { s2 = span(); } <BY>
        partitionList = ExpressionCommaList(s2, ExprContext.ACCEPT_NON_QUERY)
    |
        { partitionList = SqlNodeList.EMPTY; }
    )
    (
        orderList = OrderBy(true)
    |
        { orderList = SqlNodeList.EMPTY; }
    )
    (
        <MEASURES>
        measureList = MeasureColumnCommaList(span())
    |
        { measureList = SqlNodeList.EMPTY; }
    )
    (
        <ONE> { s0 = span(); } <ROW> <PER> <MATCH> {
            rowsPerMatch = SqlMatchRecognize.RowsPerMatchOption.ONE_ROW.symbol(s0.end(this));
        }
    |
        <ALL> { s0 = span(); } <ROWS> <PER> <MATCH> {
            rowsPerMatch = SqlMatchRecognize.RowsPerMatchOption.ALL_ROWS.symbol(s0.end(this));
        }
    |   { rowsPerMatch = null; }
    )
    (
        <AFTER> { s1 = span(); } <MATCH> <SKIP_>
        (
            <TO>
            (
                LOOKAHEAD(2)
                <NEXT> <ROW> {
                    after = SqlMatchRecognize.AfterOption.SKIP_TO_NEXT_ROW
                        .symbol(s1.end(this));
                }
            |
                LOOKAHEAD(2)
                <FIRST> var = SimpleIdentifier() {
                    after = SqlMatchRecognize.SKIP_TO_FIRST.createCall(
                        s1.end(var), var);
                }
            |
                // This "LOOKAHEAD({true})" is a workaround for Babel.
                // Because of babel parser uses option "LOOKAHEAD=2" globally,
                // JavaCC generates something like "LOOKAHEAD(2, [<LAST>] SimpleIdentifier())"
                // here. But the correct LOOKAHEAD should be
                // "LOOKAHEAD(2, [ LOOKAHEAD(2, <LAST> SimpleIdentifier()) <LAST> ]
                // SimpleIdentifier())" which have the syntactic lookahead for <LAST> considered.
                //
                // Overall LOOKAHEAD({true}) is even better as this is the last branch in the
                // choice.
                LOOKAHEAD({true})
                [ LOOKAHEAD(2, <LAST> SimpleIdentifier()) <LAST> ] var = SimpleIdentifier() {
                    after = SqlMatchRecognize.SKIP_TO_LAST.createCall(
                        s1.end(var), var);
                }
            )
        |
            <PAST> <LAST> <ROW> {
                 after = SqlMatchRecognize.AfterOption.SKIP_PAST_LAST_ROW
                     .symbol(s1.end(this));
            }
        )
    |   { after = null; }
    )
    <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>
    (
        <WITHIN> interval = IntervalLiteral()
    |   { interval = null; }
    )
    (
        <SUBSET> subsetList = SubsetDefinitionCommaList(span())
    |   { subsetList = SqlNodeList.EMPTY; }
    )
    <DEFINE>
    patternDefList = PatternDefinitionCommaList(span())
    <RPAREN> {
        return new SqlMatchRecognize(s.end(this), tableRef,
            pattern, isStrictStarts, isStrictEnds, patternDefList, measureList,
            after, subsetList, rowsPerMatch, partitionList, orderList, interval);
    }
}

SqlNodeList MeasureColumnCommaList(Span s) :
{
    final List<SqlNode> list = new ArrayList<SqlNode>();
}
{
    AddMeasureColumn(list)
    ( <COMMA> AddMeasureColumn(list) )*
    { return new SqlNodeList(list, s.addAll(list).pos()); }
}

void AddMeasureColumn(List<SqlNode> list) :
{
    final SqlNode e;
    final SqlIdentifier alias;
}
{
    e = Expression(ExprContext.ACCEPT_NON_QUERY)
    <AS>
    alias = SimpleIdentifier() {
        list.add(SqlStdOperatorTable.AS.createCall(Span.of(e).end(this), e, alias));
    }
}

SqlNode PatternExpression() :
{
    SqlNode left;
    SqlNode right;
}
{
    left = PatternTerm()
    (
        <VERTICAL_BAR>
        right = PatternTerm() {
            left = SqlStdOperatorTable.PATTERN_ALTER.createCall(
                Span.of(left).end(right), left, right);
        }
    )*
    {
        return left;
    }
}

SqlNode PatternTerm() :
{
    SqlNode left;
    SqlNode right;
}
{
    left = PatternFactor()
    (
        right = PatternFactor() {
            left = SqlStdOperatorTable.PATTERN_CONCAT.createCall(
                Span.of(left).end(right), left, right);
        }
    )*
    {
        return left;
    }
}

SqlNode PatternFactor() :
{
    final SqlNode e;
    final SqlNode extra;
    final SqlLiteral startNum;
    final SqlLiteral endNum;
    final SqlLiteral reluctant;
}
{
    e = PatternPrimary()
    (
        LOOKAHEAD(1)
        (
            <STAR> {
                startNum = LITERAL_ZERO;
                endNum = LITERAL_MINUS_ONE;
            }
        |
            <PLUS> {
                startNum = LITERAL_ONE;
                endNum = LITERAL_MINUS_ONE;
            }
        |
            <HOOK> {
                startNum = LITERAL_ZERO;
                endNum = LITERAL_ONE;
            }
        |
            <LBRACE>
            (
                startNum = UnsignedNumericLiteral()
                (
                    <COMMA>
                    (
                        endNum = UnsignedNumericLiteral()
                    |
                        { endNum = LITERAL_MINUS_ONE; }
                    )
                |
                     { endNum = startNum; }
                )
                <RBRACE>
            |
                <COMMA>
                endNum = UnsignedNumericLiteral()
                <RBRACE>
                { startNum = LITERAL_MINUS_ONE; }
            |
                <MINUS> extra = PatternExpression() <MINUS> <RBRACE> {
                    return SqlStdOperatorTable.PATTERN_CONCAT.createCall(
                        Span.of(e).end(this), e,
                        SqlStdOperatorTable.PATTERN_EXCLUDE.createCall(
                            Span.of(extra).end(this), extra));
                }
            )
        )
        (
            <HOOK> {
                reluctant = SqlLiteral.createBoolean(
                    startNum.intValue(true) != endNum.intValue(true),
                    SqlParserPos.ZERO);
            }
        |
            { reluctant = SqlLiteral.createBoolean(false, SqlParserPos.ZERO); }
        )
    |
        { return e; }
    )
    {
        return SqlStdOperatorTable.PATTERN_QUANTIFIER.createCall(
            span().end(e), e, startNum, endNum, reluctant);
    }
}

SqlNode PatternPrimary() :
{
    final Span s;
    SqlNode e;
    final List<SqlNode> list;
}
{
    e = SimpleIdentifier() { return e; }
|
    <LPAREN> e = PatternExpression() <RPAREN> { return e; }
|
    <LBRACE> { s = span(); }
    <MINUS> e = PatternExpression()
    <MINUS> <RBRACE> {
        return SqlStdOperatorTable.PATTERN_EXCLUDE.createCall(s.end(this), e);
    }
|
    (
        <PERMUTE> { s = span(); list = new ArrayList<SqlNode>(); }
        <LPAREN>
        e = PatternExpression() { list.add(e); }
        ( <COMMA> e = PatternExpression() { list.add(e); } )*
        <RPAREN> {
            return SqlStdOperatorTable.PATTERN_PERMUTE.createCall(
                s.end(this), list);
        }
    )
}

SqlNodeList SubsetDefinitionCommaList(Span s) :
{
    final List<SqlNode> list = new ArrayList<SqlNode>();
}
{
    AddSubsetDefinition(list)
    ( <COMMA> AddSubsetDefinition(list) )*
    { return new SqlNodeList(list, s.addAll(list).pos()); }
}

void AddSubsetDefinition(List<SqlNode> list) :
{
    final SqlNode var;
    final SqlNodeList varList;
}
{
    var = SimpleIdentifier()
    <EQ>
    <LPAREN>
    varList = ExpressionCommaList(span(), ExprContext.ACCEPT_NON_QUERY)
    <RPAREN> {
        list.add(
            SqlStdOperatorTable.EQUALS.createCall(span().end(var), var,
                varList));
    }
}

SqlNodeList PatternDefinitionCommaList(Span s) :
{
    SqlNode e;
    final List<SqlNode> eList = new ArrayList<SqlNode>();
}
{
    e = PatternDefinition() {
        eList.add(e);
    }
    (
        <COMMA>
        e = PatternDefinition() {
            eList.add(e);
        }
    )*
    {
        return new SqlNodeList(eList, s.addAll(eList).pos());
    }
}

SqlNode PatternDefinition() :
{
    final SqlNode var;
    final SqlNode e;
}
{
    var = SimpleIdentifier()
    <AS>
    e = Expression(ExprContext.ACCEPT_SUB_QUERY) {
        return SqlStdOperatorTable.AS.createCall(Span.of(var, e).pos(), 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.
 *
 * <p>Examples of valid queries:
 * <ul>
 * <li>{@code SELECT c FROM t}
 * <li>{@code SELECT c} (valid in some dialects)
 * <li>{@code SELECT c FROM t UNION SELECT c2 FROM t2}
 * <li>{@code WITH q AS (SELECT 1) SELECT * FROM q}
 * <li>{@code VALUES (1, 2)}
 * <li>{@code TABLE t}
 * </ul>
 *
 * <p>Non-examples:
 * <ul>
 * <li>{@code emp CROSS JOIN dept}
 * <li>{@code SELECT c FROM t ORDER BY c}
 * <li>{@code (SELECT c FROM t)}
 * </ul>
 */
SqlNode QueryOrExpr(ExprContext exprContext) :
{
    SqlNodeList withList = null;
    final SqlNode e;
    final List<Object> list = new ArrayList<Object>();
}
{
    [ withList = WithList() ]
    e = LeafQueryOrExpr(exprContext) { list.add(e); }
    ( AddSetOpQuery(list, exprContext) )*
    { return addWith(withList, SqlParserUtil.toTree(list)); }
}

SqlNode Query(ExprContext exprContext) :
{
    SqlNodeList withList = null;
    final SqlNode e;
    final List<Object> list = new ArrayList<Object>();
}
{
    [ withList = WithList() ]
    e = LeafQuery(exprContext) { list.add(e); }
    ( AddSetOpQuery(list, exprContext) )*
    { return addWith(withList, SqlParserUtil.toTree(list)); }
}

JAVACODE SqlNode addWith(SqlNodeList withList, SqlNode e) {
    return withList == null
        ? e
        : new SqlWith(withList.getParserPosition(), withList, e);
}

/** Parses a set operator (e.g. UNION or INTERSECT)
 * followed by a query or expression,
 * and adds both to {@code list}. */
void AddSetOpQueryOrExpr(List<Object> list, ExprContext exprContext) :
{
    final SqlOperator op;
    final SqlParserPos pos;
    final SqlNode e;
}
{
    {
        if (list.size() == 1 && !((SqlNode) list.get(0)).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);
    }
}

/** Parses a set operator (e.g. UNION or INTERSECT)
 * followed by a query,
 * and adds both to {@code list}. */
void AddSetOpQuery(List<Object> list, ExprContext exprContext) :
{
    final SqlOperator op;
    final SqlParserPos pos;
    final SqlNode e;
}
{
    {
        if (list.size() == 1 && !((SqlNode) list.get(0)).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);
    }
}

SqlNodeList WithList() :
{
    final Span s;
    final List<SqlWithItem> list = new ArrayList<SqlWithItem>();
}
{
    <WITH> { s = span(); }
    AddWithItem(list) ( <COMMA> AddWithItem(list) )*
    { return new SqlNodeList(list, s.end(this)); }
}

void AddWithItem(List<SqlWithItem> list) :
{
    final SqlIdentifier id;
    final SqlNodeList columnList;
    final SqlNode definition;
}
{
    id = SimpleIdentifier()
    ( columnList = ParenthesizedSimpleIdentifierList() | { columnList = null; } )
    <AS>
    definition = ParenthesizedExpression(ExprContext.ACCEPT_QUERY)
    { list.add(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 = LeafQuery(exprContext) { return e; }
|
    e = Expression(exprContext) { return e; }
}

/** As {@link #Expression} but appends to a list. */
void AddExpression(List<SqlNode> list, ExprContext exprContext) :
{
    final SqlNode e;
}
{
    e = Expression(exprContext) { list.add(e); }
}

/**
 * Parses a row expression or a parenthesized expression of any kind.
 */
SqlNode Expression(ExprContext exprContext) :
{
    final List<Object> list;
}
{
    list = Expression2(exprContext) { return SqlParserUtil.toTree(list); }
}

void AddExpression2b(List<Object> list, ExprContext exprContext) :
{
    SqlNode e;
    SqlOperator op;
    SqlNode ext;
}
{
    (
        LOOKAHEAD(1)
        op = PrefixRowOperator() {
            checkNonQueryExpression(exprContext);
            list.add(new SqlParserUtil.ToTreeListItem(op, getPos()));
        }
    )*
    e = Expression3(exprContext) {
        list.add(e);
    }
    (
        LOOKAHEAD(2) <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.
 */
List<Object> Expression2(ExprContext exprContext) :
{
    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();
}
{
    AddExpression2b(list, exprContext)
    (
        LOOKAHEAD(2)
        (
            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; }
                |
                    <IN> { op = SqlStdOperatorTable.IN; }
                |
                    { final SqlKind k; }
                    k = comp()
                    (
                        <SOME> { op = SqlStdOperatorTable.some(k); }
                    |
                        <ANY> { op = SqlStdOperatorTable.some(k); }
                    |
                        <ALL> { op = SqlStdOperatorTable.all(k); }
                    )
                )
                { 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);
                    }
                }
            |
                LOOKAHEAD(2) {
                    checkNonQueryExpression(exprContext);
                }
                (
                    <NOT> <BETWEEN> {
                        op = SqlStdOperatorTable.NOT_BETWEEN;
                        s.clear().add(this);
                    }
                    [
                        <SYMMETRIC> { op = SqlStdOperatorTable.SYMMETRIC_NOT_BETWEEN; }
                    |
                        <ASYMMETRIC>
                    ]
                |
                    <BETWEEN>
                    {
                        op = SqlStdOperatorTable.BETWEEN;
                        s.clear().add(this);
                    }
                    [
                        <SYMMETRIC> { op = SqlStdOperatorTable.SYMMETRIC_BETWEEN; }
                    |
                        <ASYMMETRIC>
                    ]
                )
                AddExpression2b(list3, ExprContext.ACCEPT_SUB_QUERY) {
                    list.add(new SqlParserUtil.ToTreeListItem(op, s.pos()));
                    list.addAll(list3);
                    list3.clear();
                }
            |
                LOOKAHEAD(2) {
                    checkNonQueryExpression(exprContext);
                    s.clear().add(this);
                }
                (
                    (
                        <NOT>
                        (
                            <LIKE> { op = SqlStdOperatorTable.NOT_LIKE; }
                        |
                            <ILIKE> { op = SqlLibraryOperators.NOT_ILIKE; }
                        |
                            <RLIKE> { op = SqlLibraryOperators.NOT_RLIKE; }
                        |
                            <SIMILAR> <TO> { op = SqlStdOperatorTable.NOT_SIMILAR_TO; }
                        )
                    |
                        <LIKE> { op = SqlStdOperatorTable.LIKE; }
                    |
                        <ILIKE> { op = SqlLibraryOperators.ILIKE; }
                    |
                        <RLIKE> { op = SqlLibraryOperators.RLIKE; }
                    |
                        <SIMILAR> <TO> { op = SqlStdOperatorTable.SIMILAR_TO; }
                    )
                <#if (parser.includePosixOperators!default.parser.includePosixOperators)>
                |
                    <NEGATE> <TILDE> { op = SqlStdOperatorTable.NEGATED_POSIX_REGEX_CASE_SENSITIVE; }
                    [ <STAR> { op = SqlStdOperatorTable.NEGATED_POSIX_REGEX_CASE_INSENSITIVE; } ]
                |
                    <TILDE> { op = SqlStdOperatorTable.POSIX_REGEX_CASE_SENSITIVE; }
                    [ <STAR> { op = SqlStdOperatorTable.POSIX_REGEX_CASE_INSENSITIVE; } ]
                </#if>
                )
                list2 = Expression2(ExprContext.ACCEPT_SUB_QUERY) {
                    list.add(new SqlParserUtil.ToTreeListItem(op, s.pos()));
                    list.addAll(list2);
                }
                [
                    LOOKAHEAD(2)
                    <ESCAPE> e = Expression3(ExprContext.ACCEPT_SUB_QUERY) {
                        s.clear().add(this);
                        list.add(
                            new SqlParserUtil.ToTreeListItem(
                                SqlStdOperatorTable.ESCAPE, s.pos()));
                        list.add(e);
                    }
                ]
            |
            <#list (parser.extraBinaryExpressions!default.parser.extraBinaryExpressions) as extra >
                ${extra}(list, exprContext, s)
            |
            </#list>
                LOOKAHEAD(3) op = BinaryRowOperator() {
                    checkNonQueryExpression(exprContext);
                    list.add(new SqlParserUtil.ToTreeListItem(op, getPos()));
                }
                AddExpression2b(list, ExprContext.ACCEPT_SUB_QUERY)
            |
                <LBRACKET>
                e = Expression(ExprContext.ACCEPT_SUB_QUERY)
                <RBRACKET> {
                    list.add(
                        new SqlParserUtil.ToTreeListItem(
                            SqlStdOperatorTable.ITEM, getPos()));
                    list.add(e);
                }
                (
                    LOOKAHEAD(2) <DOT>
                    p = SimpleIdentifier() {
                        list.add(
                            new SqlParserUtil.ToTreeListItem(
                                SqlStdOperatorTable.DOT, getPos()));
                        list.add(p);
                    }
                )*
            |
                {
                    checkNonQueryExpression(exprContext);
                }
                op = PostfixRowOperator() {
                    list.add(new SqlParserUtil.ToTreeListItem(op, getPos()));
                }
            )
        )+
        {
            return list;
        }
    |
        {
            return list;
        }
    )
}

/** Parses a comparison operator inside a SOME / ALL predicate. */
SqlKind comp() :
{
}
{
    <LT> { return SqlKind.LESS_THAN; }
|
    <LE> { return SqlKind.LESS_THAN_OR_EQUAL; }
|
    <GT> { return SqlKind.GREATER_THAN; }
|
    <GE> { return SqlKind.GREATER_THAN_OR_EQUAL; }
|
    <EQ> { return SqlKind.EQUALS; }
|
    <NE> { return SqlKind.NOT_EQUALS; }
|
    <NE2> {
        if (!this.conformance.isBangEqualAllowed()) {
            throw SqlUtil.newContextException(getPos(), RESOURCE.bangEqualNotAllowed());
        }
        return SqlKind.NOT_EQUALS;
    }
}

/**
 * Parses a unary row expression, or a parenthesized expression of any
 * kind.
 */
SqlNode Expression3(ExprContext exprContext) :
{
    final SqlNode e;
    final SqlNodeList list;
    final SqlNodeList list1;
    final Span s;
    final Span rowSpan;
}
{
    LOOKAHEAD(2)
    e = AtomicRowExpression()
    {
        checkNonQueryExpression(exprContext);
        return e;
    }
|
    e = CursorExpression(exprContext) { return e; }
|
    LOOKAHEAD(3)
    <ROW> {
        s = span();
    }
    list = ParenthesizedQueryOrCommaList(exprContext) {
        if (exprContext != ExprContext.ACCEPT_ALL
            && exprContext != ExprContext.ACCEPT_CURSOR
            && !this.conformance.allowExplicitRowValueConstructor())
        {
            throw SqlUtil.newContextException(s.end(list),
                RESOURCE.illegalRowExpression());
        }
        return SqlStdOperatorTable.ROW.createCall(list);
    }
|
    (
        <ROW> { rowSpan = span(); }
    |   { rowSpan = null; }
    )
    list1 = ParenthesizedQueryOrCommaList(exprContext) {
        if (rowSpan != null) {
            // interpret as row constructor
            return SqlStdOperatorTable.ROW.createCall(rowSpan.end(list1),
                (List<SqlNode>) list1);
        }
    }
    [
        LOOKAHEAD(2)
        /* TODO:
        (
            op = periodOperator()
            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 op.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) {
                        return SqlStdOperatorTable.MINUS_DATE.createCall(
                            Span.of(list1).end(this), call.operand(0),
                            call.operand(1), e);
                     }
                }
                throw SqlUtil.newContextException(span().end(list1),
                    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(span().end(list1),
                (List<SqlNode>) list1);
        }
    }
}

SqlOperator periodOperator() :
{
}
{
     <OVERLAPS> { return SqlStdOperatorTable.OVERLAPS; }
|
     LOOKAHEAD(2)
     <IMMEDIATELY> <PRECEDES> { return SqlStdOperatorTable.IMMEDIATELY_PRECEDES; }
|
     <PRECEDES> { return SqlStdOperatorTable.PRECEDES; }
|
     <IMMEDIATELY> <SUCCEEDS> { return SqlStdOperatorTable.IMMEDIATELY_SUCCEEDS; }
|
     <SUCCEEDS> { return SqlStdOperatorTable.SUCCEEDS; }
|
     <EQUALS> { return SqlStdOperatorTable.PERIOD_EQUALS; }
}

/**
 * Parses a COLLATE clause
 */
SqlCollation CollateClause() :
{
}
{
    <COLLATE> <COLLATION_ID>
    {
        return new SqlCollation(
            getToken(0).image, SqlCollation.Coercibility.EXPLICIT);
    }
}

/**
 * Numeric literal or parameter; used in LIMIT, OFFSET and FETCH clauses.
 */
SqlNode UnsignedNumericLiteralOrParam() :
{
    final SqlNode e;
}
{
    (
        e = UnsignedNumericLiteral()
    |
        e = DynamicParam()
    )
    { return e; }
}

/**
 * Parses a row expression extension, it can be either an identifier,
 * or a call to a named function.
 */
SqlNode RowExpressionExtension() :
{
    final SqlFunctionCategory funcType = SqlFunctionCategory.USER_DEFINED_FUNCTION;
    final SqlIdentifier p;
    final Span s;
    final List<SqlNode> args;
    final SqlLiteral quantifier;
}
{
    p = SimpleIdentifier()
    (
        LOOKAHEAD( <LPAREN> ) { s = span(); }
        (
            LOOKAHEAD(2) <LPAREN> <STAR> {
                quantifier = null;
                args = ImmutableList.of(SqlIdentifier.star(getPos()));
            }
            <RPAREN>
        |
            LOOKAHEAD(2) <LPAREN> <RPAREN> {
                quantifier = null;
                args = ImmutableList.of();
            }
        |
            args = FunctionParameterList(ExprContext.ACCEPT_SUB_QUERY) {
                quantifier = (SqlLiteral) args.get(0);
                args.remove(0);
            }
        )
        { return createCall(p, s.end(this), funcType, quantifier, args); }
    |
        { return p; }
    )
}

/**
 * Parses a call to the STRING_AGG aggregate function (or to an aggregate
 * function with similar syntax: ARRAY_AGG, ARRAY_CONCAT_AGG, GROUP_CONCAT).
 */
SqlCall StringAggFunctionCall() :
{
    final Span s, s2;
    final SqlOperator op;
    final List<SqlNode> args = new ArrayList<SqlNode>();
    final SqlLiteral qualifier;
    final SqlNodeList orderBy;
    final Pair<SqlParserPos, SqlOperator> nullTreatment;
    final SqlNode separator;
}
{
    (
        <ARRAY_AGG> { s = span(); op = SqlLibraryOperators.ARRAY_AGG; }
    |   <ARRAY_CONCAT_AGG> { s = span(); op = SqlLibraryOperators.ARRAY_CONCAT_AGG; }
    |   <GROUP_CONCAT> { s = span(); op = SqlLibraryOperators.GROUP_CONCAT; }
    |   <STRING_AGG> { s = span(); op = SqlLibraryOperators.STRING_AGG; }
    )
    <LPAREN>
    (
        qualifier = AllOrDistinct()
    |   { qualifier = null; }
    )
    AddArg(args, ExprContext.ACCEPT_SUB_QUERY)
    (
        <COMMA> {
            // a comma-list can't appear where only a query is expected
            // TODO: the following line is a no-op; remove it?
            checkNonQueryExpression(ExprContext.ACCEPT_SUB_QUERY);
        }
        AddArg(args, ExprContext.ACCEPT_SUB_QUERY)
    )*
    (
        nullTreatment = NullTreatment()
    |   { nullTreatment = null; }
    )
    [
        orderBy = OrderBy(true) {
            args.add(orderBy);
        }
    ]
    [
        <SEPARATOR> { s2 = span(); } separator = StringLiteral() {
            args.add(SqlInternalOperators.SEPARATOR.createCall(s2.end(this), separator));
        }
    ]
    <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);
        }
        return call;
    }
}

/**
 * Parses an atomic row expression.
 */
SqlNode AtomicRowExpression() :
{
    final SqlNode e;
}
{
    (
        LOOKAHEAD(2)
        e = LiteralOrIntervalExpression()
    |
        e = DynamicParam()
    |
        LOOKAHEAD(2)
        e = BuiltinFunctionCall()
    |
        e = JdbcFunctionCall()
    |
        e = MultisetConstructor()
    |
        e = ArrayConstructor()
    |
        LOOKAHEAD(3)
        e = MapConstructor()
    |
        e = PeriodConstructor()
    |
        // 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()
    |
        e = ContextVariable()
    |
        e = CompoundIdentifier()
    |
        e = NewSpecification()
    |
        e = CaseExpression()
    |
        e = SequenceExpression()
    )
    { return e; }
}

SqlNode CaseExpression() :
{
    final Span whenSpan = Span.of();
    final Span thenSpan = Span.of();
    final Span s;
    SqlNode e;
    final SqlNode caseIdentifier;
    final SqlNode elseClause;
    final List<SqlNode> whenList = new ArrayList<SqlNode>();
    final List<SqlNode> thenList = new ArrayList<SqlNode>();
}
{
    <CASE> { s = span(); }
    (
        caseIdentifier = Expression(ExprContext.ACCEPT_SUB_QUERY)
    |   { caseIdentifier = null; }
    )
    (
        <WHEN> { whenSpan.add(this); }
        e = ExpressionCommaList(s, ExprContext.ACCEPT_SUB_QUERY) {
            if (((SqlNodeList) e).size() == 1) {
                e = ((SqlNodeList) e).get(0);
            }
            whenList.add(e);
        }
        <THEN> { thenSpan.add(this); }
        e = Expression(ExprContext.ACCEPT_SUB_QUERY) {
            thenList.add(e);
        }
    )+
    (
        <ELSE> elseClause = Expression(ExprContext.ACCEPT_SUB_QUERY)
    |   { elseClause = null; }
    )
    <END> {
        return SqlCase.createSwitched(s.end(this), caseIdentifier,
            new SqlNodeList(whenList, whenSpan.addAll(whenList).pos()),
            new SqlNodeList(thenList, thenSpan.addAll(thenList).pos()),
            elseClause);
    }
}

SqlCall SequenceExpression() :
{
    final Span s;
    final SqlOperator f;
    final SqlNode sequenceRef;
}
{
    (
        <NEXT> { f = SqlStdOperatorTable.NEXT_VALUE; s = span(); }
    |
        LOOKAHEAD(3)
        <CURRENT> { f = SqlStdOperatorTable.CURRENT_VALUE; s = span(); }
    )
    <VALUE> <FOR> sequenceRef = CompoundIdentifier() {
        return f.createCall(s.end(sequenceRef), sequenceRef);
    }
}

/**
 * Parses "SET &lt;NAME&gt; = VALUE" or "RESET &lt;NAME&gt;", without a leading
 * "ALTER &lt;SCOPE&gt;".
 */
SqlSetOption SqlSetOption(Span s, String scope) :
{
    SqlIdentifier name;
    final SqlNode val;
}
{
    (
        <SET> {
            s.add(this);
        }
        name = CompoundIdentifier()
        <EQ>
        (
            val = Literal()
        |
            val = SimpleIdentifier()
        |
            <ON> {
                // OFF is handled by SimpleIdentifier, ON handled here.
                val = new SqlIdentifier(token.image.toUpperCase(Locale.ROOT),
                    getPos());
            }
        )
        {
            return new SqlSetOption(s.end(val), scope, name, val);
        }
    |
        <RESET> {
            s.add(this);
        }
        (
            name = CompoundIdentifier()
        |
            <ALL> {
                name = new SqlIdentifier(token.image.toUpperCase(Locale.ROOT),
                    getPos());
            }
        )
        {
            return new SqlSetOption(s.end(name), scope, name, null);
        }
    )
}

/**
 * Parses an expression for setting or resetting an option in SQL, such as QUOTED_IDENTIFIERS,
 * or explain plan level (physical/logical).
 */
SqlAlter SqlAlter() :
{
    final Span s;
    final String scope;
    final SqlAlter alterNode;
}
{
    <ALTER> { s = span(); }
    scope = Scope()
    (
<#-- additional literal parser methods are included here -->
<#list (parser.alterStatementParserMethods!default.parser.alterStatementParserMethods) as method>
        alterNode = ${method}(s, scope)
    |
</#list>

        alterNode = SqlSetOption(s, scope)
    )
    {
        return alterNode;
    }
}

String Scope() :
{
}
{
    ( <SYSTEM> | <SESSION> ) { return token.image.toUpperCase(Locale.ROOT); }
}

<#if (parser.createStatementParserMethods!default.parser.createStatementParserMethods)?size != 0>
/**
 * Parses a CREATE statement.
 */
SqlCreate SqlCreate() :
{
    final Span s;
    boolean replace = false;
    final SqlCreate create;
}
{
    <CREATE> { s = span(); }
    [
        <OR> <REPLACE> {
            replace = true;
        }
    ]
    (
<#-- additional literal parser methods are included here -->
<#list (parser.createStatementParserMethods!default.parser.createStatementParserMethods) as method>
        create = ${method}(s, replace)
        <#sep>| LOOKAHEAD(2) </#sep>
</#list>
    )
    {
        return create;
    }
}
</#if>

<#if (parser.dropStatementParserMethods!default.parser.dropStatementParserMethods)?size != 0>
/**
 * Parses a DROP statement.
 */
SqlDrop SqlDrop() :
{
    final Span s;
    boolean replace = false;
    final SqlDrop drop;
}
{
    <DROP> { s = span(); }
    (
<#-- additional literal parser methods are included here -->
<#list (parser.dropStatementParserMethods!default.parser.dropStatementParserMethods) as method>
        drop = ${method}(s, replace)
        <#sep>|</#sep>
</#list>
    )
    {
        return drop;
    }
}
</#if>

/**
 * 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.
 */
SqlNode Literal() :
{
    SqlNode e;
}
{
    (
        e = NonIntervalLiteral()
    |
        e = IntervalLiteral()
    )
    { return e; }
}

/** Parses a literal that is not an interval literal. */
SqlNode NonIntervalLiteral() :
{
    final SqlNode e;
}
{
    (
        e = NumericLiteral()
    |
        e = StringLiteral()
    |
        e = SpecialLiteral()
    |
        e = DateTimeLiteral()
<#-- additional literal parser methods are included here -->
<#list (parser.literalParserMethods!default.parser.literalParserMethods) as method>
    |
        e = ${method}
</#list>
    )
    {
        return e;
    }
}

/** 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. */
SqlNode LiteralOrIntervalExpression() :
{
    final SqlNode e;
}
{
    (
        e = IntervalLiteralOrExpression()
    |
        e = NonIntervalLiteral()
    )
    { return e; }
}

/** Parses a unsigned numeric literal */
SqlNumericLiteral UnsignedNumericLiteral() :
{
}
{
    <UNSIGNED_INTEGER_LITERAL> {
        return SqlLiteral.createExactNumeric(token.image, getPos());
    }
|
    <DECIMAL_NUMERIC_LITERAL> {
        return SqlLiteral.createExactNumeric(token.image, getPos());
    }
|
    <APPROX_NUMERIC_LITERAL> {
        return SqlLiteral.createApproxNumeric(token.image, getPos());
    }
}

/** Parses a numeric literal (can be signed) */
SqlLiteral NumericLiteral() :
{
    final SqlNumericLiteral num;
    final Span s;
}
{
    <PLUS> num = UnsignedNumericLiteral() {
        return num;
    }
|
    <MINUS> { s = span(); } num = UnsignedNumericLiteral() {
        return SqlLiteral.createNegative(num, s.end(this));
    }
|
    num = UnsignedNumericLiteral() {
        return num;
    }
}

/** Parse a special literal keyword */
SqlLiteral SpecialLiteral() :
{
}
{
    <TRUE> { return SqlLiteral.createBoolean(true, getPos()); }
|
    <FALSE> { return SqlLiteral.createBoolean(false, getPos()); }
|
    <UNKNOWN> { return SqlLiteral.createUnknown(getPos()); }
|
    <NULL> { return SqlLiteral.createNull(getPos()); }
}

/**
 * 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
 */
SqlNode StringLiteral() :
{
    String p;
    final List<SqlLiteral> frags;
    char unicodeEscapeChar = 0;
    String charSet = null;
    SqlCharStringLiteral literal;
}
{
    // A continued string literal consists of a head fragment and one or more
    // tail fragments. Since comments may occur between the fragments, and
    // comments are special tokens, each fragment is a token. But since spaces
    // or comments may not occur between the prefix and the first quote, the
    // head fragment, with any prefix, is one token.

    <BINARY_STRING_LITERAL>
    {
        frags = new ArrayList<SqlLiteral>();
        try {
            p = SqlParserUtil.trim(token.image, "xX'");
            frags.add(SqlLiteral.createBinaryString(p, getPos()));
        } catch (NumberFormatException ex) {
            throw SqlUtil.newContextException(getPos(),
                RESOURCE.illegalBinaryString(token.image));
        }
    }
    (
        // The grammar is ambiguous when a continued literals and a character
        // string alias are both possible. For example, in
        //   SELECT x'01'\n'ab'
        // we prefer that 'ab' continues the literal, and is not an alias.
        // The following LOOKAHEAD mutes the warning about ambiguity.
        LOOKAHEAD(1)
        <QUOTED_STRING>
        {
            try {
                p = SqlParserUtil.trim(token.image, "'"); // no embedded quotes
                frags.add(SqlLiteral.createBinaryString(p, getPos()));
            } catch (NumberFormatException ex) {
                throw SqlUtil.newContextException(getPos(),
                    RESOURCE.illegalBinaryString(token.image));
            }
        }
    )*
    {
        assert !frags.isEmpty();
        if (frags.size() == 1) {
            return frags.get(0); // just the head fragment
        } else {
            SqlParserPos pos2 = SqlParserPos.sum(frags);
            return SqlStdOperatorTable.LITERAL_CHAIN.createCall(pos2, frags);
        }
    }
|
    (
        <PREFIXED_STRING_LITERAL>
        { charSet = SqlParserUtil.getCharacterSet(token.image); }
    |   <QUOTED_STRING>
    |   <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";
        }
    )
    {
        frags = new ArrayList<SqlLiteral>();
        p = SqlParserUtil.parseString(token.image);
        try {
            literal = SqlLiteral.createCharString(p, charSet, getPos());
            frags.add(literal);
        } catch (java.nio.charset.UnsupportedCharsetException e) {
            throw SqlUtil.newContextException(getPos(),
                RESOURCE.unknownCharacterSet(charSet));
        }
    }
    (
        // The grammar is ambiguous when a continued literals and a character
        // string alias are both possible. For example, in
        //   SELECT 'taxi'\n'cab'
        // we prefer that 'cab' continues the literal, and is not an alias.
        // The following LOOKAHEAD mutes the warning about ambiguity.
        LOOKAHEAD(1)
        <QUOTED_STRING>
        {
            p = SqlParserUtil.parseString(token.image);
            try {
                literal = SqlLiteral.createCharString(p, charSet, getPos());
                frags.add(literal);
            } catch (java.nio.charset.UnsupportedCharsetException e) {
                throw SqlUtil.newContextException(getPos(),
                    RESOURCE.unknownCharacterSet(charSet));
            }
        }
    )*
    [
        <UESCAPE> <QUOTED_STRING>
        {
            if (unicodeEscapeChar == 0) {
                throw SqlUtil.newContextException(getPos(),
                    RESOURCE.unicodeEscapeUnexpected());
            }
            String s = SqlParserUtil.parseString(token.image);
            unicodeEscapeChar = SqlParserUtil.checkUnicodeEscapeChar(s);
        }
    ]
    {
        assert !frags.isEmpty();
        if (frags.size() == 1) {
            // just the head fragment
            SqlLiteral lit = (SqlLiteral) frags.get(0);
            return lit.unescapeUnicode(unicodeEscapeChar);
        } else {
            SqlNode[] rands = (SqlNode[]) frags.toArray(new SqlNode[0]);
            for (int i = 0; i < rands.length; ++i) {
                rands[i] = ((SqlLiteral) rands[i]).unescapeUnicode(
                    unicodeEscapeChar);
            }
            SqlParserPos pos2 = SqlParserPos.sum(rands);
            return SqlStdOperatorTable.LITERAL_CHAIN.createCall(pos2, rands);
        }
    }
|
    <C_STYLE_ESCAPED_STRING_LITERAL>
    {
        try {
            p = SqlParserUtil.parseCString(getToken(0).image);
        } catch (SqlParserUtil.MalformedUnicodeEscape e) {
            throw SqlUtil.newContextException(getPos(),
                RESOURCE.unicodeEscapeMalformed(e.i));
       }
       return SqlLiteral.createCharString(p, "UTF16", getPos());
    }
|
    <BIG_QUERY_DOUBLE_QUOTED_STRING>
    {
        p = SqlParserUtil.stripQuotes(getToken(0).image, DQ, DQ, "\\\"",
            Casing.UNCHANGED);
        try {
            return SqlLiteral.createCharString(p, charSet, getPos());
        } catch (java.nio.charset.UnsupportedCharsetException e) {
            throw SqlUtil.newContextException(getPos(),
                RESOURCE.unknownCharacterSet(charSet));
        }
    }
|
    <BIG_QUERY_QUOTED_STRING>
    {
        p = SqlParserUtil.stripQuotes(getToken(0).image, "'", "'", "\\'",
            Casing.UNCHANGED);
        try {
            return SqlLiteral.createCharString(p, charSet, getPos());
        } catch (java.nio.charset.UnsupportedCharsetException e) {
            throw SqlUtil.newContextException(getPos(),
                RESOURCE.unknownCharacterSet(charSet));
        }
    }
}

/** Parses a character literal.
 * Matches a single-quoted string, such as 'foo';
 * on BigQuery also matches a double-quoted string, such as "foo".
 * Returns the value of the string with quotes removed. */
String SimpleStringLiteral() :
{
}
{
    <QUOTED_STRING> {
        return SqlParserUtil.parseString(token.image);
    }
|
    <BIG_QUERY_QUOTED_STRING> {
        return SqlParserUtil.stripQuotes(token.image, "'", "'", "\\'", Casing.UNCHANGED);
    }
|
    <BIG_QUERY_DOUBLE_QUOTED_STRING> {
        return SqlParserUtil.stripQuotes(token.image, DQ, DQ, "\\\"", Casing.UNCHANGED);
    }
}

/**
 * Parses a date/time literal.
 */
SqlLiteral DateTimeLiteral() :
{
    final String p;
    final Span s;
}
{
    <LBRACE_D> <QUOTED_STRING> {
        p = SqlParserUtil.parseString(token.image);
    }
    <RBRACE> {
        return SqlParserUtil.parseDateLiteral(p, getPos());
    }
|
    <LBRACE_T> <QUOTED_STRING> {
        p = SqlParserUtil.parseString(token.image);
    }
    <RBRACE> {
        return SqlParserUtil.parseTimeLiteral(p, getPos());
    }
|
    <LBRACE_TS> { s = span(); } <QUOTED_STRING> {
        p = SqlParserUtil.parseString(token.image);
    }
    <RBRACE> {
        return SqlParserUtil.parseTimestampLiteral(p, s.end(this));
    }
|
    <DATE> { s = span(); } p = SimpleStringLiteral() {
      return SqlLiteral.createUnknown("DATE", p, s.end(this));
    }
|
    <DATETIME> { s = span(); } p = SimpleStringLiteral() {
        return SqlLiteral.createUnknown("DATETIME", p, s.end(this));
    }
|
    <TIME> { s = span(); } p = SimpleStringLiteral() {
      return SqlLiteral.createUnknown("TIME", p, s.end(this));
    }
|
    LOOKAHEAD(2)
    <TIMESTAMP> { s = span(); } p = SimpleStringLiteral() {
        return SqlLiteral.createUnknown("TIMESTAMP", p, s.end(this));
    }
|
    <TIMESTAMP> { s = span(); } <WITH> <LOCAL> <TIME> <ZONE> p = SimpleStringLiteral() {
        return SqlLiteral.createUnknown("TIMESTAMP WITH LOCAL TIME ZONE", p, s.end(this));
    }
}

/** Parses a Date/Time constructor function, for example "DATE(1969, 7, 21)"
 * or "DATETIME(d, t)". Enabled in some libraries (e.g. BigQuery). */
SqlNode DateTimeConstructorCall() :
{
    final SqlFunctionCategory funcType = SqlFunctionCategory.TIMEDATE;
    final SqlIdentifier qualifiedName;
    final Span s;
    final SqlLiteral quantifier;
    final List<? extends SqlNode> args;
}
{
    (<DATE> | <TIME> | <DATETIME> | <TIMESTAMP>) {
        s = span();
        qualifiedName = new SqlIdentifier(unquotedIdentifier(), getPos());
    }
    args = FunctionParameterList(ExprContext.ACCEPT_SUB_QUERY) {
        quantifier = (SqlLiteral) args.get(0);
        args.remove(0);
        return createCall(qualifiedName, s.end(this), funcType, quantifier, args);
    }
}

/** Parses a MULTISET constructor */
SqlNode MultisetConstructor() :
{
    final List<SqlNode> args = new ArrayList<SqlNode>();
    SqlNode e;
    final Span s;
}
{
    <MULTISET> { s = span(); }
    (
        LOOKAHEAD(2)
        <LPAREN>
        // by sub query "MULTISET(SELECT * FROM T)"
        e = LeafQueryOrExpr(ExprContext.ACCEPT_QUERY)
        <RPAREN> {
            return SqlStdOperatorTable.MULTISET_QUERY.createCall(
                s.end(this), e);
        }
    |
        // by enumeration "MULTISET[e0, e1, ..., eN]"
        <LBRACKET> // TODO: do trigraph as well ??( ??)
        AddExpression(args, ExprContext.ACCEPT_NON_QUERY)
        ( <COMMA> AddExpression(args, ExprContext.ACCEPT_NON_QUERY) )*
        <RBRACKET>
        {
            return SqlStdOperatorTable.MULTISET_VALUE.createCall(
                s.end(this), args);
        }
    )
}

/** Parses an ARRAY constructor */
SqlNode ArrayConstructor() :
{
    SqlNodeList args;
    SqlNode e;
    final Span s;
    final String p;
}
{
    <ARRAY> { s = span(); }
    (
        LOOKAHEAD(1)
        <LPAREN>
        // by sub query "MULTISET(SELECT * FROM T)"
        e = OrderedQueryOrExpr(ExprContext.ACCEPT_QUERY)
        <RPAREN>
        {
            return SqlStdOperatorTable.ARRAY_QUERY.createCall(
                s.end(this), e);
        }
    |
        // by enumeration "ARRAY[e0, e1, ..., eN]"
        <LBRACKET> // TODO: do trigraph as well ??( ??)
        (
            args = ExpressionCommaList(s, ExprContext.ACCEPT_NON_QUERY)
        |
            { args = SqlNodeList.EMPTY; }
        )
        <RBRACKET>
        {
            return SqlStdOperatorTable.ARRAY_VALUE_CONSTRUCTOR.createCall(
                s.end(this), args.getList());
        }
<#if (parser.includeParsingStringLiteralAsArrayLiteral!default.parser.includeParsingStringLiteralAsArrayLiteral) >
    |
        p = SimpleStringLiteral() {
            try {
                return SqlParserUtil.parseArrayLiteral(p);
            } catch (SqlParseException ex) {
                throw SqlUtil.newContextException(getPos(),
                    RESOURCE.illegalArrayExpression(p));
            }
        }
</#if>
    )
}

SqlCall ArrayLiteral() :
{
    final List<SqlNode> list;
    SqlNode e;
    final Span s;
}
{
    <LBRACE> { s = span(); }
    (
        e = Literal() { list = startList(e); }
        ( <COMMA> e = Literal() { list.add(e); } )*
    |
        e = ArrayLiteral() { list = startList(e); }
        ( <COMMA> e = ArrayLiteral() { list.add(e); } )*
    |
        { list = Collections.emptyList(); }
    )
    <RBRACE> {
       return SqlStdOperatorTable.ARRAY_VALUE_CONSTRUCTOR.createCall(s.end(this), list);
    }
}

/** Parses a MAP constructor */
SqlNode MapConstructor() :
{
    SqlNodeList args;
    SqlNode e;
    final Span s;
}
{
    <MAP> { s = span(); }
    (
        LOOKAHEAD(1)
        <LPAREN>
        // by sub query "MAP (SELECT empno, deptno FROM emp)"
        e = LeafQueryOrExpr(ExprContext.ACCEPT_QUERY)
        <RPAREN>
        {
            return SqlStdOperatorTable.MAP_QUERY.createCall(
                s.end(this), e);
        }
    |
        // by enumeration "MAP[k0, v0, ..., kN, vN]"
        <LBRACKET> // TODO: do trigraph as well ??( ??)
        (
            args = ExpressionCommaList(s, ExprContext.ACCEPT_NON_QUERY)
        |
            { args = SqlNodeList.EMPTY; }
        )
        <RBRACKET>
        {
            return SqlStdOperatorTable.MAP_VALUE_CONSTRUCTOR.createCall(
                s.end(this), args.getList());
        }
    )
}

/** Parses a PERIOD constructor */
SqlNode PeriodConstructor() :
{
    final List<SqlNode> args = new ArrayList<SqlNode>();
    final Span s;
}
{
    <PERIOD> { s = span(); }
    <LPAREN>
    AddExpression(args, ExprContext.ACCEPT_SUB_QUERY)
    <COMMA>
    AddExpression(args, ExprContext.ACCEPT_SUB_QUERY)
    <RPAREN> {
        return SqlStdOperatorTable.ROW.createCall(s.end(this), args);
    }
}

/**
 * Parses an interval literal.
 */
SqlLiteral IntervalLiteral() :
{
    final String p;
    final SqlIntervalQualifier intervalQualifier;
    int sign = 1;
    final Span s;
}
{
    <INTERVAL> { s = span(); }
    [
        <MINUS> { sign = -1; }
    |
        <PLUS> { sign = 1; }
    ]
    p = SimpleStringLiteral()
    intervalQualifier = IntervalQualifier() {
        return SqlParserUtil.parseIntervalLiteral(s.end(intervalQualifier),
            sign, p, intervalQualifier);
    }
}

/** 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}). */
SqlNode IntervalLiteralOrExpression() :
{
    final String p;
    final SqlIntervalQualifier intervalQualifier;
    int sign = 1;
    final Span s;
    SqlNode e;
}
{
    <INTERVAL> { s = span(); }
    [
        <MINUS> { sign = -1; }
    |
        <PLUS> { sign = 1; }
    ]
    (
        // literal (with quoted string)
        p = SimpleStringLiteral()
        intervalQualifier = IntervalQualifier() {
            return SqlParserUtil.parseIntervalLiteral(s.end(intervalQualifier),
                sign, p, intervalQualifier);
        }
    |
        // To keep parsing simple, any expressions besides numeric literal and
        // identifiers must be enclosed in parentheses.
        (
            <LPAREN>
            e = Expression(ExprContext.ACCEPT_SUB_QUERY)
            <RPAREN>
        |
            e = UnsignedNumericLiteral()
        |
            e = CompoundIdentifier()
        )
        intervalQualifier = IntervalQualifierStart() {
            if (sign == -1) {
                e = SqlStdOperatorTable.UNARY_MINUS.createCall(e.getParserPosition(), e);
            }
            return SqlStdOperatorTable.INTERVAL.createCall(s.end(this), e,
                intervalQualifier);
        }
    )
}

TimeUnit Year() :
{
}
{
    <YEAR> { return TimeUnit.YEAR; }
|
    <YEARS> { return warn(TimeUnit.YEAR); }
}

TimeUnit Quarter() :
{
}
{
    <QUARTER> { return TimeUnit.QUARTER; }
|
    <QUARTERS> { return warn(TimeUnit.QUARTER); }
}

TimeUnit Month() :
{
}
{
    <MONTH> { return TimeUnit.MONTH; }
|
    <MONTHS> { return warn(TimeUnit.MONTH); }
}

TimeUnit Week() :
{
}
{
    <WEEK> { return TimeUnit.WEEK; }
|
    <WEEKS> { return warn(TimeUnit.WEEK); }
}

TimeUnit Day() :
{
}
{
    <DAY> { return TimeUnit.DAY; }
|
    <DAYS> { return warn(TimeUnit.DAY); }
}

TimeUnit Hour() :
{
}
{
    <HOUR> { return TimeUnit.HOUR; }
|
    <HOURS> { return warn(TimeUnit.HOUR); }
}

TimeUnit Minute() :
{
}
{
    <MINUTE> { return TimeUnit.MINUTE; }
|
    <MINUTES> { return warn(TimeUnit.MINUTE); }
}

TimeUnit Second() :
{
}
{
    <SECOND> { return TimeUnit.SECOND; }
|
    <SECONDS> { return warn(TimeUnit.SECOND); }
}

SqlIntervalQualifier IntervalQualifier() :
{
    final Span s;
    final TimeUnit start;
    final TimeUnit end;
    final int startPrec;
    int secondFracPrec = RelDataType.PRECISION_NOT_SPECIFIED;
}
{
    (
        start = Year() { s = span(); } startPrec = PrecisionOpt()
        (
            LOOKAHEAD(2) <TO> end = Month()
        |   { end = null; }
        )
    |
        start = Quarter() { s = span(); } startPrec = PrecisionOpt()
        { end = null; }
    |
        start = Month() { s = span(); } startPrec = PrecisionOpt()
        { end = null; }
    |
        start = Week() { s = span(); } startPrec = PrecisionOpt()
        { end = null; }
    |
        start = Day() { s = span(); } startPrec = PrecisionOpt()
        (
            LOOKAHEAD(2) <TO>
            (
                end = Hour()
            |
                end = Minute()
            |
                end = Second() secondFracPrec = PrecisionOpt()
            )
        |   { end = null; }
        )
    |
        start = Hour() { s = span(); } startPrec = PrecisionOpt()
        (
            LOOKAHEAD(2) <TO>
            (
                end = Minute()
            |
                end = Second()
                [ <LPAREN> secondFracPrec = UnsignedIntLiteral() <RPAREN> ]
            )
        |   { end = null; }
        )
    |
        start = Minute() { s = span(); } startPrec = PrecisionOpt()
        (
            LOOKAHEAD(2) <TO>
            end = Second()
            [ <LPAREN> secondFracPrec = UnsignedIntLiteral() <RPAREN> ]
        |   { end = null; }
        )
    |
        start = Second() { s = span(); }
        (
            <LPAREN> startPrec = UnsignedIntLiteral()
            [ <COMMA> secondFracPrec = UnsignedIntLiteral() ]
            <RPAREN>
        |   { startPrec = -1; }
        )
        { end = null; }
    )
    {
        return new SqlIntervalQualifier(start, startPrec, end, secondFracPrec,
            s.end(this));
    }
}

/** Interval qualifier without 'TO unit'. */
SqlIntervalQualifier IntervalQualifierStart() :
{
    final Span s;
    final TimeUnit start;
    int startPrec = RelDataType.PRECISION_NOT_SPECIFIED;
    int secondFracPrec = RelDataType.PRECISION_NOT_SPECIFIED;
}
{
    (
        (
            start = Year()
        |   start = Quarter()
        |   start = Month()
        |   start = Week()
        |   start = Day()
        |   start = Hour()
        |   start = Minute()
        )
        { s = span(); }
        startPrec = PrecisionOpt()
    |
        start = Second() { s = span(); }
        [   <LPAREN> startPrec = UnsignedIntLiteral()
            [ <COMMA> secondFracPrec = UnsignedIntLiteral() ]
            <RPAREN>
        ]
    )
    {
        return new SqlIntervalQualifier(start, startPrec, null, secondFracPrec,
            s.end(this));
    }
}

/** Parses a built-in time unit (e.g. "YEAR")
 * or user-defined time frame (e.g. "MINUTE15")
 * and in each case returns a {@link SqlIntervalQualifier}.
 *
 * <p>The units are used in several functions, incuding CEIL, FLOOR, EXTRACT.
 * Includes NANOSECOND, MILLISECOND, which were previously allowed in EXTRACT
 * but not CEIL, FLOOR.
 *
 * <p>Includes {@code WEEK} and {@code WEEK(SUNDAY)} through
  {@code WEEK(SATURDAY)}.
 *
 * <p>Does not include SQL_TSI_DAY, SQL_TSI_FRAC_SECOND etc. These will be
 * parsed as identifiers and can be resolved in the validator if they are
 * registered as abbreviations in your time frame set.
 */
SqlIntervalQualifier TimeUnitOrName() : {
    final SqlIdentifier unitName;
    final SqlIntervalQualifier intervalQualifier;
}
{
    // When we see a time unit that is also a non-reserved keyword, such as
    // NANOSECOND, there is a choice between using the TimeUnit enum
    // (TimeUnit.NANOSECOND) or the name. The following LOOKAHEAD directive
    // tells the parser that we prefer the former.
    //
    // Reserved keywords, such as SECOND, cannot be identifiers, and are
    // therefore not ambiguous.
    LOOKAHEAD(2)
    intervalQualifier = TimeUnit() {
        return intervalQualifier;
    }
|   unitName = SimpleIdentifier() {
        return new SqlIntervalQualifier(unitName.getSimple(),
            unitName.getParserPosition());
    }
}

/** Parses a built-in time unit (e.g. "YEAR")
 * and returns a {@link SqlIntervalQualifier}.
 *
 * <p>Includes {@code WEEK} and {@code WEEK(SUNDAY)} through
  {@code WEEK(SATURDAY)}.
 *
 * <p>Does not include SQL_TSI_DAY, SQL_TSI_FRAC_SECOND etc. These will be
 * parsed as identifiers and can be resolved in the validator if they are
 * registered as abbreviations in your time frame set.
 */
SqlIntervalQualifier TimeUnit() : {
    final Span span;
    final String w;
}
{
    <NANOSECOND> { return new SqlIntervalQualifier(TimeUnit.NANOSECOND, null, getPos()); }
|   <MICROSECOND> { return new SqlIntervalQualifier(TimeUnit.MICROSECOND, null, getPos()); }
|   <MILLISECOND> { return new SqlIntervalQualifier(TimeUnit.MILLISECOND, null, getPos()); }
|   <SECOND> { return new SqlIntervalQualifier(TimeUnit.SECOND, null, getPos()); }
|   <MINUTE> { return new SqlIntervalQualifier(TimeUnit.MINUTE, null, getPos()); }
|   <HOUR> { return new SqlIntervalQualifier(TimeUnit.HOUR, null, getPos()); }
|   <DAY> { return new SqlIntervalQualifier(TimeUnit.DAY, null, getPos()); }
|   <DAYOFWEEK> { return new SqlIntervalQualifier(TimeUnit.DOW, null, getPos()); }
|   <DAYOFYEAR> { return new SqlIntervalQualifier(TimeUnit.DOY, null, getPos()); }
|   <DOW> { return new SqlIntervalQualifier(TimeUnit.DOW, null, getPos()); }
|   <DOY> { return new SqlIntervalQualifier(TimeUnit.DOY, null, getPos()); }
|   <ISODOW> { return new SqlIntervalQualifier(TimeUnit.ISODOW, null, getPos()); }
|   <ISOYEAR> { return new SqlIntervalQualifier(TimeUnit.ISOYEAR, null, getPos()); }
|   <WEEK> { span = span(); }
    (
        // There is a choice between "WEEK(weekday)" and "WEEK". We prefer
        // the former, and the parser will look ahead for '('.
        LOOKAHEAD(2)
        <LPAREN> w = weekdayName() <RPAREN> {
            return new SqlIntervalQualifier(w, span.end(this));
        }
    |
        { return new SqlIntervalQualifier(TimeUnit.WEEK, null, getPos()); }
    )
|   <MONTH> { return new SqlIntervalQualifier(TimeUnit.MONTH, null, getPos()); }
|   <QUARTER> { return new SqlIntervalQualifier(TimeUnit.QUARTER, null, getPos()); }
|   <YEAR> { return new SqlIntervalQualifier(TimeUnit.YEAR, null, getPos()); }
|   <EPOCH> { return new SqlIntervalQualifier(TimeUnit.EPOCH, null, getPos()); }
|   <DECADE> { return new SqlIntervalQualifier(TimeUnit.DECADE, null, getPos()); }
|   <CENTURY> { return new SqlIntervalQualifier(TimeUnit.CENTURY, null, getPos()); }
|   <MILLENNIUM> { return new SqlIntervalQualifier(TimeUnit.MILLENNIUM, null, getPos()); }
}

String weekdayName() :
{
}
{
    <SUNDAY> { return "WEEK_SUNDAY"; }
|   <MONDAY> { return "WEEK_MONDAY"; }
|   <TUESDAY> { return "WEEK_TUESDAY"; }
|   <WEDNESDAY> { return "WEEK_WEDNESDAY"; }
|   <THURSDAY> { return "WEEK_THURSDAY"; }
|   <FRIDAY> { return "WEEK_FRIDAY"; }
|   <SATURDAY> { return "WEEK_SATURDAY"; }
}

/**
 * Parses a dynamic parameter marker.
 */
SqlDynamicParam DynamicParam() :
{
}
{
    <HOOK> {
        return new SqlDynamicParam(nDynamicParams++, getPos());
    }
}

/**
 * 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.
 */
void AddIdentifierSegment(List<String> names, List<SqlParserPos> positions) :
{
    final String id;
    char unicodeEscapeChar = BACKSLASH;
    final SqlParserPos pos;
    final Span span;
}
{
    (
        <IDENTIFIER> {
            id = unquotedIdentifier();
            pos = getPos();
        }
    |
        <HYPHENATED_IDENTIFIER> {
            id = unquotedIdentifier();
            pos = getPos();
        }
    |
        <QUOTED_IDENTIFIER> {
            id = SqlParserUtil.stripQuotes(getToken(0).image, DQ, DQ, DQDQ,
                quotedCasing);
            pos = getPos().withQuoting(true);
        }
    |
        <BACK_QUOTED_IDENTIFIER> {
            id = SqlParserUtil.stripQuotes(getToken(0).image, "`", "`", "``",
                quotedCasing);
            pos = getPos().withQuoting(true);
        }
    |
        <BIG_QUERY_BACK_QUOTED_IDENTIFIER> {
            id = SqlParserUtil.stripQuotes(getToken(0).image, "`", "`", "\\`",
                quotedCasing);
            pos = getPos().withQuoting(true);
        }
    |
        <BRACKET_QUOTED_IDENTIFIER> {
            id = SqlParserUtil.stripQuotes(getToken(0).image, "[", "]", "]]",
                quotedCasing);
            pos = getPos().withQuoting(true);
        }
    |
        <UNICODE_QUOTED_IDENTIFIER> {
            span = span();
            String image = getToken(0).image;
            image = image.substring(image.indexOf('"'));
            image = SqlParserUtil.stripQuotes(image, DQ, DQ, DQDQ, quotedCasing);
        }
        [
            <UESCAPE> <QUOTED_STRING> {
                String s = SqlParserUtil.parseString(token.image);
                unicodeEscapeChar = SqlParserUtil.checkUnicodeEscapeChar(s);
            }
        ]
        {
            pos = span.end(this).withQuoting(true);
            SqlLiteral lit = SqlLiteral.createCharString(image, "UTF16", pos);
            lit = lit.unescapeUnicode(unicodeEscapeChar);
            id = lit.toValue();
        }
    |
        id = NonReservedKeyWord() {
            pos = getPos();
        }
    )
    {
        if (id.length() > this.identifierMaxLength) {
            throw SqlUtil.newContextException(pos,
                RESOURCE.identifierTooLong(id, this.identifierMaxLength));
        }
        names.add(id);
        if (positions != null) {
            positions.add(pos);
        }
    }
}

/** As {@link #AddIdentifierSegment} 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. */
void AddTableIdentifierSegment(List<String> names, List<SqlParserPos> positions) :
{
}
{
    AddIdentifierSegment(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.
 */
String Identifier() :
{
    final List<String> names = new ArrayList<String>();
}
{
    AddIdentifierSegment(names, null) {
        return names.get(0);
    }
}

/**
 * Parses a simple identifier as an SqlIdentifier.
 */
SqlIdentifier SimpleIdentifier() :
{
    final List<String> names = new ArrayList<String>();
    final List<SqlParserPos> positions = new ArrayList<SqlParserPos>();
}
{
    AddIdentifierSegment(names, positions) {
        return new SqlIdentifier(names.get(0), positions.get(0));
    }
}

/**
 * Parses a character literal as an SqlIdentifier.
 * Only valid for column aliases in certain dialects.
 */
SqlIdentifier SimpleIdentifierFromStringLiteral() :
{
}
{
    <QUOTED_STRING> {
        if (!this.conformance.allowCharLiteralAlias()) {
            throw SqlUtil.newContextException(getPos(), RESOURCE.charLiteralAliasNotValid());
        }
        final String s = SqlParserUtil.parseString(token.image);
        return new SqlIdentifier(s, getPos());
    }
}

/**
 * Parses a comma-separated list of simple identifiers.
 */
void AddSimpleIdentifiers(List<SqlNode> list) :
{
    SqlIdentifier id;
}
{
    id = SimpleIdentifier() {list.add(id);}
    (
        <COMMA> id = SimpleIdentifier() {
            list.add(id);
        }
    )*
}

/**
  * List of simple identifiers in parentheses. The position extends from the
  * open parenthesis to the close parenthesis.
  */
SqlNodeList ParenthesizedSimpleIdentifierList() :
{
    final Span s;
    final List<SqlNode> list = new ArrayList<SqlNode>();
}
{
    <LPAREN> { s = span(); }
    AddSimpleIdentifiers(list)
    <RPAREN> {
        return new SqlNodeList(list, s.end(this));
    }
}

/** List of simple identifiers in parentheses or one simple identifier.
 *
 * <ul>Examples:
 * <li>{@code DEPTNO}
 * <li>{@code (EMPNO, DEPTNO)}
 * </ul>
 */
SqlNodeList SimpleIdentifierOrList() :
{
    SqlIdentifier id;
    SqlNodeList list;
}
{
    id = SimpleIdentifier() {
        return new SqlNodeList(Collections.singletonList(id), id.getParserPosition());
    }
|
    list = ParenthesizedSimpleIdentifierList() {
        return list;
    }
}

<#if (parser.includeCompoundIdentifier!default.parser.includeCompoundIdentifier) >
/**
 * Parses a compound identifier.
 */
SqlIdentifier CompoundIdentifier() :
{
    final List<String> nameList = new ArrayList<String>();
    final List<SqlParserPos> posList = new ArrayList<SqlParserPos>();
    boolean star = false;
}
{
    AddIdentifierSegment(nameList, posList)
    (
        LOOKAHEAD(2)
        <DOT>
        AddIdentifierSegment(nameList, posList)
    )*
    (
        LOOKAHEAD(2)
        <DOT>
        <STAR> {
            star = true;
            nameList.add("");
            posList.add(getPos());
        }
    )?
    {
        SqlParserPos pos = SqlParserPos.sum(posList);
        if (star) {
            return SqlIdentifier.star(nameList, pos, posList);
        }
        return new SqlIdentifier(nameList, null, pos, posList);
    }
}

/**
 * Parses a compound identifier in the FROM clause.
 */
SqlIdentifier CompoundTableIdentifier() :
{
    final List<String> nameList = new ArrayList<String>();
    final List<SqlParserPos> posList = new ArrayList<SqlParserPos>();
}
{
    AddTableIdentifierSegment(nameList, posList)
    (
        LOOKAHEAD(2)
        <DOT>
        AddTableIdentifierSegment(nameList, posList)
    )*
    {
        SqlParserPos pos = SqlParserPos.sum(posList);
        return new SqlIdentifier(nameList, null, pos, posList);
    }
}

/**
 * Parses a comma-separated list of compound identifiers.
 */
void AddCompoundIdentifierTypes(List<SqlNode> list, List<SqlNode> extendList) :
{
}
{
    AddCompoundIdentifierType(list, extendList)
    (<COMMA> AddCompoundIdentifierType(list, extendList))*
}

/**
 * List of compound identifiers in parentheses. The position extends from the
 * open parenthesis to the close parenthesis.
 */
Pair<SqlNodeList, SqlNodeList> ParenthesizedCompoundIdentifierList() :
{
    final Span s;
    final List<SqlNode> list = new ArrayList<SqlNode>();
    final List<SqlNode> extendList = new ArrayList<SqlNode>();
}
{
    <LPAREN> { s = span(); }
    AddCompoundIdentifierTypes(list, extendList)
    <RPAREN> {
        return Pair.of(new SqlNodeList(list, s.end(this)), new SqlNodeList(extendList, s.end(this)));
    }
}
<#else>
  <#include "/@includes/compoundIdentifier.ftl" />
</#if>

/**
 * Parses a NEW UDT(...) expression.
 */
SqlNode NewSpecification() :
{
    final Span s;
    final SqlNode routineCall;
}
{
    <NEW> { s = span(); }
    routineCall =
        NamedRoutineCall(SqlFunctionCategory.USER_DEFINED_CONSTRUCTOR,
            ExprContext.ACCEPT_SUB_QUERY) {
        return SqlStdOperatorTable.NEW.createCall(s.end(routineCall), routineCall);
    }
}

//TODO: real parse errors.
int UnsignedIntLiteral() :
{
    Token t;
}
{
    t = <UNSIGNED_INTEGER_LITERAL>
    {
        try {
            return Integer.parseInt(t.image);
        } catch (NumberFormatException ex) {
            throw SqlUtil.newContextException(getPos(),
                RESOURCE.invalidLiteral(t.image, Integer.class.getCanonicalName()));
        }
    }
}

int IntLiteral() :
{
    Token t;
}
{
    (
        t = <UNSIGNED_INTEGER_LITERAL>
    |
        <PLUS> t = <UNSIGNED_INTEGER_LITERAL>
    )
    {
        try {
            return Integer.parseInt(t.image);
        } catch (NumberFormatException ex) {
            throw SqlUtil.newContextException(getPos(),
                RESOURCE.invalidLiteral(t.image, Integer.class.getCanonicalName()));
        }
    }
|
    <MINUS> t = <UNSIGNED_INTEGER_LITERAL> {
        try {
            return -Integer.parseInt(t.image);
        } catch (NumberFormatException ex) {
            throw SqlUtil.newContextException(getPos(),
                RESOURCE.invalidLiteral(t.image, Integer.class.getCanonicalName()));
        }
    }
}

// Type name with optional scale and precision.
SqlDataTypeSpec DataType() :
{
    SqlTypeNameSpec typeName;
    final Span s;
}
{
    typeName = TypeName() {
        s = Span.of(typeName.getParserPos());
    }
    (
        typeName = CollectionsTypeName(typeName)
    )*
    {
        return new SqlDataTypeSpec(typeName, s.add(typeName.getParserPos()).pos());
    }
}

// Some SQL type names need special handling due to the fact that they have
// spaces in them but are not quoted.
SqlTypeNameSpec TypeName() :
{
    final SqlTypeNameSpec typeNameSpec;
    final SqlIdentifier typeName;
    final Span s = Span.of();
}
{
    (
<#-- additional types are included here -->
<#-- put custom data types in front of Calcite core data types -->
<#list (parser.dataTypeParserMethods!default.parser.dataTypeParserMethods) as method>
        LOOKAHEAD(2)
        typeNameSpec = ${method}
    |
</#list>
        LOOKAHEAD(2)
        typeNameSpec = SqlTypeName(s)
    |
        typeNameSpec = RowTypeName()
    |
        typeName = CompoundIdentifier() {
            typeNameSpec = new SqlUserDefinedTypeNameSpec(typeName, s.end(this));
        }
    )
    {
        return typeNameSpec;
    }
}

// Types used for JDBC and ODBC scalar conversion function
SqlTypeNameSpec SqlTypeName(Span s) :
{
    final SqlTypeNameSpec sqlTypeNameSpec;
}
{
    (
        sqlTypeNameSpec = SqlTypeName1(s)
    |
        sqlTypeNameSpec = SqlTypeName2(s)
    |
        sqlTypeNameSpec = SqlTypeName3(s)
    |
        sqlTypeNameSpec = CharacterTypeName(s)
    |
        sqlTypeNameSpec = DateTimeTypeName()
    )
    {
        return sqlTypeNameSpec;
    }
}

// Parse sql type name that don't allow any extra specifications except the type name.
// For extra specification, we mean precision, scale, charSet, etc.
SqlTypeNameSpec SqlTypeName1(Span s) :
{
    final SqlTypeName sqlTypeName;
}
{
    (
        <GEOMETRY> {
            if (!this.conformance.allowGeometry()) {
                throw SqlUtil.newContextException(getPos(), RESOURCE.geometryDisabled());
            }
            s.add(this);
            sqlTypeName = SqlTypeName.GEOMETRY;
        }
    |
        <BOOLEAN> { s.add(this); sqlTypeName = SqlTypeName.BOOLEAN; }
    |
        ( <INTEGER> | <INT> ) { s.add(this); sqlTypeName = SqlTypeName.INTEGER; }
    |
        <TINYINT> { s.add(this); sqlTypeName = SqlTypeName.TINYINT; }
    |
        <SMALLINT> { s.add(this); sqlTypeName = SqlTypeName.SMALLINT; }
    |
        <BIGINT> { s.add(this); sqlTypeName = SqlTypeName.BIGINT; }
    |
        <REAL> { s.add(this); sqlTypeName = SqlTypeName.REAL; }
    |
        <DOUBLE> { s.add(this); }
        [ <PRECISION> ] { sqlTypeName = SqlTypeName.DOUBLE; }
    |
        <FLOAT> { s.add(this); sqlTypeName = SqlTypeName.FLOAT; }
    )
    {
        return new SqlBasicTypeNameSpec(sqlTypeName, s.end(this));
    }
}

// Parse sql type name that allows precision specification.
SqlTypeNameSpec SqlTypeName2(Span s) :
{
    final SqlTypeName sqlTypeName;
    int precision = -1;
}
{
    (
        <BINARY> { s.add(this); }
        (
            <VARYING> { sqlTypeName = SqlTypeName.VARBINARY; }
        |
            { sqlTypeName = SqlTypeName.BINARY; }
        )
    |
        <VARBINARY> { s.add(this); sqlTypeName = SqlTypeName.VARBINARY; }
    )
    precision = PrecisionOpt()
    {
        return new SqlBasicTypeNameSpec(sqlTypeName, precision, s.end(this));
    }
}

// Parse sql type name that allows precision and scale specifications.
SqlTypeNameSpec SqlTypeName3(Span s) :
{
    final SqlTypeName sqlTypeName;
    int precision = -1;
    int scale = -1;
}
{
    (
        (<DECIMAL> | <DEC> | <NUMERIC>) { s.add(this); sqlTypeName = SqlTypeName.DECIMAL; }
    |
        <ANY> { s.add(this); sqlTypeName = SqlTypeName.ANY; }
    )
    [
        <LPAREN>
        precision = UnsignedIntLiteral()
        [
            <COMMA>
            scale = UnsignedIntLiteral()
        ]
        <RPAREN>
    ]
    {
        return new SqlBasicTypeNameSpec(sqlTypeName, precision, scale, s.end(this));
    }
}

// Types used for for JDBC and ODBC scalar conversion function
SqlJdbcDataTypeName JdbcOdbcDataTypeName() :
{
}
{
    (<SQL_CHAR> | <CHAR>) { return SqlJdbcDataTypeName.SQL_CHAR; }
|   (<SQL_VARCHAR> | <VARCHAR>) { return SqlJdbcDataTypeName.SQL_VARCHAR; }
|   (<SQL_DATE> | <DATE>) { return SqlJdbcDataTypeName.SQL_DATE; }
|   (<SQL_TIME> | <TIME>) { return SqlJdbcDataTypeName.SQL_TIME; }
|   (<SQL_TIMESTAMP> | <TIMESTAMP>) { return SqlJdbcDataTypeName.SQL_TIMESTAMP; }
|   (<SQL_DECIMAL> | <DECIMAL>) { return SqlJdbcDataTypeName.SQL_DECIMAL; }
|   (<SQL_NUMERIC> | <NUMERIC>) { return SqlJdbcDataTypeName.SQL_NUMERIC; }
|   (<SQL_BOOLEAN> | <BOOLEAN>) { return SqlJdbcDataTypeName.SQL_BOOLEAN; }
|   (<SQL_INTEGER> | <INTEGER>) { return SqlJdbcDataTypeName.SQL_INTEGER; }
|   (<SQL_BINARY> | <BINARY>) { return SqlJdbcDataTypeName.SQL_BINARY; }
|   (<SQL_VARBINARY> | <VARBINARY>) { return SqlJdbcDataTypeName.SQL_VARBINARY; }
|   (<SQL_TINYINT> | <TINYINT>) { return SqlJdbcDataTypeName.SQL_TINYINT; }
|   (<SQL_SMALLINT> | <SMALLINT>) { return SqlJdbcDataTypeName.SQL_SMALLINT; }
|   (<SQL_BIGINT> | <BIGINT>) { return SqlJdbcDataTypeName.SQL_BIGINT; }
|   (<SQL_REAL>| <REAL>) { return SqlJdbcDataTypeName.SQL_REAL; }
|   (<SQL_DOUBLE> | <DOUBLE>) { return SqlJdbcDataTypeName.SQL_DOUBLE; }
|   (<SQL_FLOAT> | <FLOAT>) { return SqlJdbcDataTypeName.SQL_FLOAT; }
|   <SQL_INTERVAL_YEAR> { return SqlJdbcDataTypeName.SQL_INTERVAL_YEAR; }
|   <SQL_INTERVAL_YEAR_TO_MONTH> { return SqlJdbcDataTypeName.SQL_INTERVAL_YEAR_TO_MONTH; }
|   <SQL_INTERVAL_MONTH> { return SqlJdbcDataTypeName.SQL_INTERVAL_MONTH; }
|   <SQL_INTERVAL_DAY> { return SqlJdbcDataTypeName.SQL_INTERVAL_DAY; }
|   <SQL_INTERVAL_DAY_TO_HOUR> { return SqlJdbcDataTypeName.SQL_INTERVAL_DAY_TO_HOUR; }
|   <SQL_INTERVAL_DAY_TO_MINUTE> { return SqlJdbcDataTypeName.SQL_INTERVAL_DAY_TO_MINUTE; }
|   <SQL_INTERVAL_DAY_TO_SECOND> { return SqlJdbcDataTypeName.SQL_INTERVAL_DAY_TO_SECOND; }
|   <SQL_INTERVAL_HOUR> { return SqlJdbcDataTypeName.SQL_INTERVAL_HOUR; }
|   <SQL_INTERVAL_HOUR_TO_MINUTE> { return SqlJdbcDataTypeName.SQL_INTERVAL_HOUR_TO_MINUTE; }
|   <SQL_INTERVAL_HOUR_TO_SECOND> { return SqlJdbcDataTypeName.SQL_INTERVAL_HOUR_TO_SECOND; }
|   <SQL_INTERVAL_MINUTE> { return SqlJdbcDataTypeName.SQL_INTERVAL_MINUTE; }
|   <SQL_INTERVAL_MINUTE_TO_SECOND> { return SqlJdbcDataTypeName.SQL_INTERVAL_MINUTE_TO_SECOND; }
|   <SQL_INTERVAL_SECOND> { return SqlJdbcDataTypeName.SQL_INTERVAL_SECOND; }
}

SqlLiteral JdbcOdbcDataType() :
{
    SqlJdbcDataTypeName typeName;
}
{
    typeName = JdbcOdbcDataTypeName() {
        return typeName.symbol(getPos());
    }
}

/**
* Parse a collection type name, the input element type name may
* also be a collection type.
*/
SqlTypeNameSpec CollectionsTypeName(SqlTypeNameSpec elementTypeName) :
{
    final SqlTypeName collectionTypeName;
}
{
    (
        <MULTISET> { collectionTypeName = SqlTypeName.MULTISET; }
    |
        <ARRAY> { collectionTypeName = SqlTypeName.ARRAY; }
    )
    {
        return new SqlCollectionTypeNameSpec(elementTypeName,
                collectionTypeName, getPos());
    }
}

/**
* Parse a nullable option, default is true.
*/
boolean NullableOptDefaultTrue() :
{
}
{
    <NULL> { return true; }
|
    <NOT> <NULL> { return false; }
|
    { return true; }
}

/**
* Parse a nullable option, default is false.
*/
boolean NullableOptDefaultFalse() :
{
}
{
    <NULL> { return true; }
|
    <NOT> <NULL> { return false; }
|
    { return false; }
}

/** Parses NOT NULL and returns false, or parses nothing and returns true. */
boolean NotNullOpt() :
{
}
{
    <NOT> <NULL> { return false; }
|
    { return true; }
}

/**
* Parse a "name1 type1 [NULL | NOT NULL], name2 type2 [NULL | NOT NULL] ..." list,
* the field type default is not nullable.
*/
void AddFieldNameTypes(List<SqlIdentifier> fieldNames,
    List<SqlDataTypeSpec> fieldTypes) :
{
}
{
    AddFieldNameType(fieldNames, fieldTypes)
    ( <COMMA> AddFieldNameType(fieldNames, fieldTypes) )*
}

void AddFieldNameType(List<SqlIdentifier> fieldNames,
    List<SqlDataTypeSpec> fieldTypes) :
{
    final SqlIdentifier fName;
    final SqlDataTypeSpec fType;
    final boolean nullable;
}
{
    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).
*/
SqlTypeNameSpec RowTypeName() :
{
    List<SqlIdentifier> fieldNames = new ArrayList<SqlIdentifier>();
    List<SqlDataTypeSpec> fieldTypes = new ArrayList<SqlDataTypeSpec>();
}
{
    <ROW>
    <LPAREN> AddFieldNameTypes(fieldNames, fieldTypes) <RPAREN>
    {
        return new SqlRowTypeNameSpec(getPos(), fieldNames, fieldTypes);
    }
}

/**
* Parse character types: char, varchar.
*/
SqlTypeNameSpec CharacterTypeName(Span s) :
{
    int precision = -1;
    final SqlTypeName sqlTypeName;
    String charSetName = null;
}
{
    (
        (<CHARACTER> | <CHAR>) { s.add(this); }
        (
            <VARYING> { sqlTypeName = SqlTypeName.VARCHAR; }
        |
            { sqlTypeName = SqlTypeName.CHAR; }
        )
    |
        <VARCHAR> { s.add(this); sqlTypeName = SqlTypeName.VARCHAR; }
    )
    precision = PrecisionOpt()
    [
        <CHARACTER> <SET>
        charSetName = Identifier()
    ]
    {
        return new SqlBasicTypeNameSpec(sqlTypeName, precision, charSetName, s.end(this));
    }
}

/**
* Parse datetime types: date, time, timestamp.
*/
SqlTypeNameSpec DateTimeTypeName() :
{
    int precision = -1;
    SqlTypeName typeName;
    boolean withLocalTimeZone = false;
    final Span s;
}
{
    <DATE> {
        typeName = SqlTypeName.DATE;
        return new SqlBasicTypeNameSpec(typeName, getPos());
    }
|
    LOOKAHEAD(2)
    <TIME> { s = span(); }
    precision = PrecisionOpt()
    withLocalTimeZone = TimeZoneOpt()
    {
        if (withLocalTimeZone) {
            typeName = SqlTypeName.TIME_WITH_LOCAL_TIME_ZONE;
        } else {
            typeName = SqlTypeName.TIME;
        }
        return new SqlBasicTypeNameSpec(typeName, precision, s.end(this));
    }
|
    <TIMESTAMP> { s = span(); }
    precision = PrecisionOpt()
    withLocalTimeZone = TimeZoneOpt()
    {
        if (withLocalTimeZone) {
            typeName = SqlTypeName.TIMESTAMP_WITH_LOCAL_TIME_ZONE;
        } else {
            typeName = SqlTypeName.TIMESTAMP;
        }
        return new SqlBasicTypeNameSpec(typeName, precision, s.end(this));
    }
}

// Parse an optional data type precision, default is -1.
int PrecisionOpt() :
{
    int precision = -1;
}
{
    <LPAREN>
    precision = UnsignedIntLiteral()
    <RPAREN>
    { return precision; }
|
    { return -1; }
}

/**
* 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".
*/
boolean TimeZoneOpt() :
{
}
{
    LOOKAHEAD(3)
    <WITHOUT> <TIME> <ZONE> { return false; }
|
    <WITH> <LOCAL> <TIME> <ZONE> { return true; }
|
    { return false; }
}

/**
 * Parses a CURSOR(query) expression.  The parser allows these
 * anywhere, but the validator restricts them to appear only as
 * arguments to table functions.
 */
SqlNode CursorExpression(ExprContext exprContext) :
{
    final SqlNode e;
    final Span s;
}
{
    <CURSOR> {
        s = span();
        if (exprContext != ExprContext.ACCEPT_ALL
                && exprContext != ExprContext.ACCEPT_CURSOR) {
            throw SqlUtil.newContextException(s.end(this),
                RESOURCE.illegalCursorExpression());
        }
    }
    e = Expression(ExprContext.ACCEPT_QUERY) {
        return SqlStdOperatorTable.CURSOR.createCall(s.end(e), e);
    }
}

/**
 * Parses a call to a builtin function with special syntax.
 */
SqlNode BuiltinFunctionCall() :
{
    final SqlIdentifier name;
    final List<SqlNode> args = new ArrayList<SqlNode>();
    SqlNode e;
    final Span s;
    SqlDataTypeSpec dt;
    final SqlIntervalQualifier unit;
    final SqlNode node;
    final SqlLiteral style; // mssql convert 'style' operand
    final SqlFunction f;
}
{
    //~ FUNCTIONS WITH SPECIAL SYNTAX ---------------------------------------
    (
        (  <CAST> { f = SqlStdOperatorTable.CAST; }
        | <SAFE_CAST> { f = SqlLibraryOperators.SAFE_CAST; }
        )
        { s = span(); }
        <LPAREN> AddExpression(args, ExprContext.ACCEPT_SUB_QUERY)
        <AS>
        (
            dt = DataType() { args.add(dt); }
        |
            <INTERVAL> e = IntervalQualifier() { args.add(e); }
        )
        <RPAREN> {
            return f.createCall(s.end(this), args);
        }
    |
        <EXTRACT> { s = span(); }
        <LPAREN> unit = TimeUnitOrName() {
            args.add(unit);
        }
        <FROM>
        AddExpression(args, ExprContext.ACCEPT_SUB_QUERY)
        <RPAREN> {
            return SqlStdOperatorTable.EXTRACT.createCall(s.end(this), args);
        }
    |
        <POSITION> { s = span(); }
        <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.add(e); }
        <IN>
        AddExpression(args, ExprContext.ACCEPT_SUB_QUERY)
        [ <FROM> AddExpression(args, ExprContext.ACCEPT_SUB_QUERY) ]
        <RPAREN> {
            return SqlStdOperatorTable.POSITION.createCall(s.end(this), args);
        }
    |
        <CONVERT> { s = span(); }
        <LPAREN>
        (
          // CONVERT in the form of CONVERT(x USING y)

          // "AddExpression" matches INTERVAL,
          // which can also be 1st token in args of MSSQL CONVERT
          // So lookahead another token (to match <USING> vs. <COMMA>)
          LOOKAHEAD(2)
          AddExpression(args, ExprContext.ACCEPT_SUB_QUERY)
          <USING> name = SimpleIdentifier() { args.add(name); }
          <RPAREN> {
              return SqlStdOperatorTable.CONVERT.createCall(s.end(this), args);
          }
        | // mssql CONVERT(type, val [,style])
          (
            dt = DataType() { args.add(dt); }
            |
            <INTERVAL> e = IntervalQualifier() { args.add(e); }
          )
          <COMMA>
          AddExpression(args, ExprContext.ACCEPT_SUB_QUERY)
          [
            <COMMA>
            (
              style = UnsignedNumericLiteral() { args.add(style); }
              |
              <NULL> { args.add(SqlLiteral.createNull(getPos())); }
            )
          ]
          <RPAREN> {
            return SqlLibraryOperators.MSSQL_CONVERT.createCall(s.end(this), args);
          }
        )
    |
        <TRANSLATE> { s = span(); }
        <LPAREN>
        AddExpression(args, ExprContext.ACCEPT_SUB_QUERY)
        (
            <USING> name = SimpleIdentifier() { args.add(name); }
            <RPAREN> {
                return SqlStdOperatorTable.TRANSLATE.createCall(s.end(this),
                    args);
            }
        |
            ( <COMMA> AddExpression(args, ExprContext.ACCEPT_SUB_QUERY) )*
            <RPAREN> {
                return SqlLibraryOperators.TRANSLATE3.createCall(s.end(this),
                    args);
            }
        )
    |
        <OVERLAY> { s = span(); }
        <LPAREN> AddExpression(args, ExprContext.ACCEPT_SUB_QUERY)
        <PLACING> AddExpression(args, ExprContext.ACCEPT_SUB_QUERY)
        <FROM> AddExpression(args, ExprContext.ACCEPT_SUB_QUERY)
        [ <FOR> AddExpression(args, ExprContext.ACCEPT_SUB_QUERY) ]
        <RPAREN> {
            return SqlStdOperatorTable.OVERLAY.createCall(s.end(this), args);
        }
    |
        <FLOOR> { s = span(); }
        e = FloorCeilOptions(s, true) {
            return e;
        }
    |
        ( <CEIL> | <CEILING>) { s = span(); }
        e = FloorCeilOptions(s, false) {
            return e;
        }
    |
        <SUBSTRING> { s = span(); }
        <LPAREN>
        AddExpression(args, ExprContext.ACCEPT_SUB_QUERY)
        ( <FROM> | <COMMA>)
        AddExpression(args, ExprContext.ACCEPT_SUB_QUERY)
        [
            (<FOR> | <COMMA>)
            AddExpression(args, ExprContext.ACCEPT_SUB_QUERY)
        ]
        <RPAREN> {
            return SqlStdOperatorTable.SUBSTRING.createCall(
                s.end(this), args);
        }
    |
        <TRIM> {
            SqlLiteral flag = null;
            SqlNode trimChars = null;
            s = span();
        }
        <LPAREN>
        [
            LOOKAHEAD(2)
            [
                <BOTH> {
                    s.add(this);
                    flag = SqlTrimFunction.Flag.BOTH.symbol(getPos());
                }
            |
                <TRAILING> {
                    s.add(this);
                    flag = SqlTrimFunction.Flag.TRAILING.symbol(getPos());
                }
            |
                <LEADING> {
                    s.add(this);
                    flag = SqlTrimFunction.Flag.LEADING.symbol(getPos());
                }
            ]
            [ trimChars = Expression(ExprContext.ACCEPT_SUB_QUERY) ]
            (
                <FROM> {
                    if (null == flag && null == trimChars) {
                        throw SqlUtil.newContextException(getPos(),
                            RESOURCE.illegalFromEmpty());
                    }
                }
            |
                <RPAREN> {
                    // This is to handle the case of TRIM(x)
                    // (FRG-191).
                    if (flag == null) {
                        flag = SqlTrimFunction.Flag.BOTH.symbol(SqlParserPos.ZERO);
                    }
                    args.add(flag);
                    args.add(null); // no trim chars
                    args.add(trimChars); // reinterpret trimChars as source
                    return SqlStdOperatorTable.TRIM.createCall(s.end(this),
                        args);
                }
            )
        ]
        e = Expression(ExprContext.ACCEPT_SUB_QUERY) {
            if (flag == null) {
                flag = SqlTrimFunction.Flag.BOTH.symbol(SqlParserPos.ZERO);
            }
            args.add(flag);
            args.add(trimChars);
            args.add(e);
        }
        <RPAREN> {
            return SqlStdOperatorTable.TRIM.createCall(s.end(this), args);
        }
    |
        node = DateTimeConstructorCall() { return node; }
    |
        node = DateTruncFunctionCall() { return node; }
    |
        node = TimestampAddFunctionCall() { return node; }
    |
        node = TimestampDiffFunctionCall() { return node; }
    |
        node = TimestampDiff3FunctionCall() { return node; }
    |
        node = TimestampTruncFunctionCall() { return node; }
    |
        node = TimeDiffFunctionCall() { return node; }
    |
        node = TimeTruncFunctionCall() { return node; }
    |
<#list (parser.builtinFunctionCallMethods!default.parser.builtinFunctionCallMethods) as method>
        node = ${method} { return node; }
    |
</#list>
        node = MatchRecognizeFunctionCall() { return node; }
    |
        node = JsonExistsFunctionCall() { return node; }
    |
        node = JsonValueFunctionCall() { return node; }
    |
        node = JsonQueryFunctionCall() { return node; }
    |
        node = JsonObjectFunctionCall() { return node; }
    |
        node = JsonObjectAggFunctionCall() { return node; }
    |
        node = JsonArrayFunctionCall() { return node; }
    |
        node = JsonArrayAggFunctionCall() { return node; }
    |
        node = GroupByWindowingCall() { return node; }
    )
}

SqlJsonEncoding JsonRepresentation() :
{
}
{
    <JSON>
    [
        // Encoding is currently ignored.
        LOOKAHEAD(2) <ENCODING>
        (
            <UTF8> { return SqlJsonEncoding.UTF8; }
        |
            <UTF16> { return SqlJsonEncoding.UTF16; }
        |
            <UTF32> { return SqlJsonEncoding.UTF32; }
        )
    ]
    {
        return SqlJsonEncoding.UTF8;
    }
}

void JsonInputClause() :
{
}
{
    <FORMAT> JsonRepresentation()
}

SqlDataTypeSpec JsonReturningClause() :
{
    SqlDataTypeSpec dt;
}
{
    <RETURNING> dt = DataType() { return dt; }
}

SqlDataTypeSpec JsonOutputClause() :
{
    SqlDataTypeSpec dataType;
}
{
    dataType = JsonReturningClause()
    [
        <FORMAT> JsonRepresentation()
    ]
    {
        return dataType;
    }
}

SqlNode JsonPathSpec() :
{
    SqlNode e;
}
{
    e = StringLiteral() {
        return e;
    }
}

List<SqlNode> JsonApiCommonSyntax() :
{
    SqlNode e;
    final List<SqlNode> args = new ArrayList<SqlNode>();
}
{
    AddExpression(args, ExprContext.ACCEPT_NON_QUERY)
    <COMMA>
    AddExpression(args, ExprContext.ACCEPT_NON_QUERY)
    [
        // We currently don't support JSON passing clause, leave the java code blocks no-op
        <PASSING> e = Expression(ExprContext.ACCEPT_NON_QUERY) {
            // no-op
        }
        <AS> e = SimpleIdentifier() {
            // no-op
        }
        (
            <COMMA>
            e = Expression(ExprContext.ACCEPT_NON_QUERY) {
                // no-op
            }
            <AS> e = SimpleIdentifier() {
                // no-op
            }
        )*
    ]
    {
        return args;
    }
}

SqlJsonExistsErrorBehavior JsonExistsErrorBehavior() :
{

}
{
    <TRUE> { return SqlJsonExistsErrorBehavior.TRUE; }
    |
    <FALSE> { return SqlJsonExistsErrorBehavior.FALSE; }
    |
    <UNKNOWN> { return SqlJsonExistsErrorBehavior.UNKNOWN; }
    |
    <ERROR> { return SqlJsonExistsErrorBehavior.ERROR; }
}

SqlCall JsonExistsFunctionCall() :
{
    List<SqlNode> args = new ArrayList<SqlNode>();
    List<SqlNode> commonSyntax;
    final Span span;
    SqlJsonExistsErrorBehavior errorBehavior;
}
{
    <JSON_EXISTS> { span = span(); }
    <LPAREN> commonSyntax = JsonApiCommonSyntax() {
        args.addAll(commonSyntax);
    }
    [
        errorBehavior = JsonExistsErrorBehavior() { args.add(errorBehavior.symbol(getPos())); }
        <ON> <ERROR>
    ]
    <RPAREN> {
        return SqlStdOperatorTable.JSON_EXISTS.createCall(span.end(this), args);
    }
}

List<SqlNode> JsonValueEmptyOrErrorBehavior() :
{
    final List<SqlNode> list = new ArrayList<SqlNode>();
}
{
    (
        <ERROR> {
            list.add(SqlJsonValueEmptyOrErrorBehavior.ERROR.symbol(getPos()));
        }
    |
        <NULL> {
            list.add(SqlJsonValueEmptyOrErrorBehavior.NULL.symbol(getPos()));
        }
    |
        <DEFAULT_> {
            list.add(SqlJsonValueEmptyOrErrorBehavior.DEFAULT.symbol(getPos()));
        }
        AddExpression(list, ExprContext.ACCEPT_NON_QUERY)
    )
    <ON>
    (
        <EMPTY> {
            list.add(SqlJsonEmptyOrError.EMPTY.symbol(getPos()));
        }
    |
        <ERROR> {
            list.add(SqlJsonEmptyOrError.ERROR.symbol(getPos()));
        }
    )
    { return list; }
}

SqlCall JsonValueFunctionCall() :
{
    final List<SqlNode> args = new ArrayList<SqlNode>(7);
    SqlNode e;
    List<SqlNode> commonSyntax;
    final Span span;
    List<SqlNode> behavior;
}
{
    <JSON_VALUE> { span = span(); }
    <LPAREN> commonSyntax = JsonApiCommonSyntax() {
        args.addAll(commonSyntax);
    }
    [
        e = JsonReturningClause() {
            args.add(SqlJsonValueReturning.RETURNING.symbol(getPos()));
            args.add(e);
        }
    ]
    (
        behavior = JsonValueEmptyOrErrorBehavior() {
            args.addAll(behavior);
        }
    )*
    <RPAREN> {
        return SqlStdOperatorTable.JSON_VALUE.createCall(span.end(this), args);
    }
}

List<SqlNode> JsonQueryEmptyOrErrorBehavior() :
{
    final List<SqlNode> list = new ArrayList<SqlNode>();
}
{
    (
        <ERROR> {
            list.add(SqlLiteral.createSymbol(SqlJsonQueryEmptyOrErrorBehavior.ERROR, getPos()));
        }
    |
        <NULL> {
            list.add(SqlLiteral.createSymbol(SqlJsonQueryEmptyOrErrorBehavior.NULL, getPos()));
        }
    |
        LOOKAHEAD(2)
        <EMPTY> <ARRAY> {
            list.add(SqlLiteral.createSymbol(SqlJsonQueryEmptyOrErrorBehavior.EMPTY_ARRAY, getPos()));
        }
    |
        <EMPTY> <OBJECT> {
            list.add(SqlLiteral.createSymbol(SqlJsonQueryEmptyOrErrorBehavior.EMPTY_OBJECT, getPos()));
        }
    )
    <ON>
    (
        <EMPTY> {
            list.add(SqlLiteral.createSymbol(SqlJsonEmptyOrError.EMPTY, getPos()));
        }
    |
        <ERROR> {
            list.add(SqlLiteral.createSymbol(SqlJsonEmptyOrError.ERROR, getPos()));
        }
    )
    { return list; }
}

SqlNode JsonQueryWrapperBehavior() :
{
}
{
    <WITHOUT> [<ARRAY>] {
        return SqlLiteral.createSymbol(SqlJsonQueryWrapperBehavior.WITHOUT_ARRAY, getPos());
    }
|
    LOOKAHEAD(2)
    <WITH> <CONDITIONAL> [<ARRAY>] {
        return SqlLiteral.createSymbol(SqlJsonQueryWrapperBehavior.WITH_CONDITIONAL_ARRAY, getPos());
    }
|
    <WITH> [<UNCONDITIONAL>] [<ARRAY>] {
        return SqlLiteral.createSymbol(SqlJsonQueryWrapperBehavior.WITH_UNCONDITIONAL_ARRAY, getPos());
    }
}

SqlCall JsonQueryFunctionCall() :
{
    final SqlNode[] args = new SqlNode[5];
    SqlNode e;
    List<SqlNode> commonSyntax;
    final Span span;
    List<SqlNode> behavior;
}
{
    <JSON_QUERY> { span = span(); }
    <LPAREN> commonSyntax = JsonApiCommonSyntax() {
        args[0] = commonSyntax.get(0);
        args[1] = commonSyntax.get(1);
    }
    [
        e = JsonQueryWrapperBehavior() <WRAPPER> {
            args[2] = e;
        }
    ]
    (
        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;
            }
        }
    )*
    <RPAREN> {
        return SqlStdOperatorTable.JSON_QUERY.createCall(span.end(this), args);
    }
}

SqlNode JsonName() :
{
    final SqlNode e;
}
{
     e = Expression(ExprContext.ACCEPT_NON_QUERY) {
        return e;
     }
}

List<SqlNode> JsonNameAndValue() :
{
    final List<SqlNode> list = new ArrayList<SqlNode>();
    final SqlNode e;
    boolean kvMode = false;
}
{
    [
        LOOKAHEAD(2, <KEY> JsonName())
        <KEY> { kvMode = true; }
    ]
    e = JsonName() {
        list.add(e);
    }
    (
        <VALUE>
    |
        <COLON> {
            if (kvMode) {
                throw SqlUtil.newContextException(getPos(), RESOURCE.illegalColon());
            }
        }
    )
    AddExpression(list, ExprContext.ACCEPT_NON_QUERY)
    {
        return list;
    }
}

SqlNode JsonConstructorNullClause() :
{
}
{
    <NULL> <ON> <NULL> {
        return SqlLiteral.createSymbol(SqlJsonConstructorNullClause.NULL_ON_NULL, getPos());
    }
|
    <ABSENT> <ON> <NULL> {
        return SqlLiteral.createSymbol(SqlJsonConstructorNullClause.ABSENT_ON_NULL, getPos());
    }
}

SqlCall JsonObjectFunctionCall() :
{
    final List<SqlNode> nvArgs = new ArrayList<SqlNode>();
    final SqlNode[] otherArgs = new SqlNode[1];
    SqlNode e;
    List<SqlNode> list;
    final Span span;
}
{
    <JSON_OBJECT> { span = span(); }
    <LPAREN> [
        LOOKAHEAD(2)
        list = JsonNameAndValue() {
            nvArgs.addAll(list);
        }
        (
            <COMMA>
            list = JsonNameAndValue() {
                nvArgs.addAll(list);
            }
        )*
    ]
    [
        e = JsonConstructorNullClause() {
            otherArgs[0] = e;
        }
    ]
    <RPAREN> {
        final List<SqlNode> args = new ArrayList();
        args.addAll(Arrays.asList(otherArgs));
        args.addAll(nvArgs);
        return SqlStdOperatorTable.JSON_OBJECT.createCall(span.end(this), args);
    }
}

SqlCall JsonObjectAggFunctionCall() :
{
    final SqlNode[] args = new SqlNode[2];
    List<SqlNode> list;
    final Span span;
    SqlJsonConstructorNullClause nullClause =
        SqlJsonConstructorNullClause.NULL_ON_NULL;
    final SqlNode e;
}
{
    <JSON_OBJECTAGG> { span = span(); }
    <LPAREN> list = JsonNameAndValue() {
        args[0] = list.get(0);
        args[1] = list.get(1);
    }
    [
        e = JsonConstructorNullClause() {
            nullClause = (SqlJsonConstructorNullClause) ((SqlLiteral) e).getValue();
        }
    ]
    <RPAREN> {
        return SqlStdOperatorTable.JSON_OBJECTAGG.with(nullClause)
            .createCall(span.end(this), args);
    }
}

SqlCall JsonArrayFunctionCall() :
{
    final List<SqlNode> elements = new ArrayList<SqlNode>();
    final SqlNode[] otherArgs = new SqlNode[1];
    SqlNode e;
    final Span span;
}
{
    <JSON_ARRAY> { span = span(); }
    <LPAREN> [
        LOOKAHEAD(2)
        AddExpression(elements, ExprContext.ACCEPT_NON_QUERY)
        ( <COMMA> AddExpression(elements, ExprContext.ACCEPT_NON_QUERY) )*
    ]
    [
        e = JsonConstructorNullClause() {
            otherArgs[0] = e;
        }
    ]
    <RPAREN> {
        final List<SqlNode> args = new ArrayList();
        args.addAll(Arrays.asList(otherArgs));
        args.addAll(elements);
        return SqlStdOperatorTable.JSON_ARRAY.createCall(span.end(this), args);
    }
}

SqlNodeList JsonArrayAggOrderByClause() :
{
    final SqlNodeList orderList;
}
{
    orderList = OrderBy(true)
    { return orderList; }
}

SqlCall JsonArrayAggFunctionCall() :
{
    final SqlNode valueExpr;
    final SqlNodeList orderList;
    final Span span;
    final SqlJsonConstructorNullClause nullClause;
    SqlNode e;
    final SqlNode aggCall;
}
{
    <JSON_ARRAYAGG> { span = span(); }
    <LPAREN> e = Expression(ExprContext.ACCEPT_NON_QUERY) {
        valueExpr = e;
    }
    ( orderList = JsonArrayAggOrderByClause() | { orderList = null; } )
    (
        e = JsonConstructorNullClause() {
            nullClause = (SqlJsonConstructorNullClause) ((SqlLiteral) e).getValue();
        }
    |   { nullClause = SqlJsonConstructorNullClause.ABSENT_ON_NULL; }
    )
    <RPAREN>
    {
        aggCall = SqlStdOperatorTable.JSON_ARRAYAGG.with(nullClause)
            .createCall(span.end(this), valueExpr, orderList);
    }
    [
        e = withinGroup(aggCall) {
            if (orderList != null) {
                throw SqlUtil.newContextException(span.pos().plus(e.getParserPosition()),
                    RESOURCE.ambiguousSortOrderInJsonArrayAggFunc());
            }
            return (SqlCall) e;
        }
    ]
    {
        if (orderList == null) {
            return SqlStdOperatorTable.JSON_ARRAYAGG.with(nullClause)
                .createCall(span.end(this), valueExpr);
        }
        return SqlStdOperatorTable.JSON_ARRAYAGG.with(nullClause)
            .createCall(span.end(this), valueExpr, orderList);
    }
}

/**
 * Parses a call to TIMESTAMPADD.
 */
SqlCall TimestampAddFunctionCall() :
{
    final List<SqlNode> args = new ArrayList<SqlNode>();
    final Span s;
    final SqlIntervalQualifier unit;
}
{
    <TIMESTAMPADD> { s = span(); }
    <LPAREN>
    unit = TimeUnitOrName() { args.add(unit); }
    <COMMA>
    AddExpression(args, ExprContext.ACCEPT_SUB_QUERY)
    <COMMA>
    AddExpression(args, ExprContext.ACCEPT_SUB_QUERY)
    <RPAREN> {
        return SqlStdOperatorTable.TIMESTAMP_ADD.createCall(
            s.end(this), args);
    }
}

/**
 * Parses a call to TIMESTAMPDIFF.
 */
SqlCall TimestampDiffFunctionCall() :
{
    final List<SqlNode> args = new ArrayList<SqlNode>();
    final Span s;
    final SqlIntervalQualifier unit;
}
{
    <TIMESTAMPDIFF> { s = span(); }
    <LPAREN>
    unit = TimeUnitOrName() { args.add(unit); }
    <COMMA>
    AddExpression(args, ExprContext.ACCEPT_SUB_QUERY)
    <COMMA>
    AddExpression(args, ExprContext.ACCEPT_SUB_QUERY)
    <RPAREN> {
        return SqlStdOperatorTable.TIMESTAMP_DIFF.createCall(
            s.end(this), args);
    }
}

/**
 * Parses a call to BigQuery's TIMESTAMP_DIFF.
 *
 * <p>The difference between TIMESTAMPDIFF and TIMESTAMP_DIFF is the ordering of
 * the parameters and the arrangement of the subtraction.
 * TIMESTAMPDIFF uses (unit, timestamp1, timestamp2) with (t2 - t1), while
 * TIMESTAMP_DIFF uses (timestamp1, timestamp2, unit) with (t1 - t2).
 */
SqlCall TimestampDiff3FunctionCall() :
{
    final List<SqlNode> args = new ArrayList<SqlNode>();
    final Span s;
    final SqlIntervalQualifier unit;
}
{
    <TIMESTAMP_DIFF> { s = span(); }
    <LPAREN>
    AddExpression(args, ExprContext.ACCEPT_SUB_QUERY)
    <COMMA>
    AddExpression(args, ExprContext.ACCEPT_SUB_QUERY)
    <COMMA>
    unit = TimeUnitOrName() { args.add(unit); }
    <RPAREN> {
        return SqlLibraryOperators.TIMESTAMP_DIFF3.createCall(s.end(this), args);
    }
}

/**
 * Parses a call to DATE_TRUNC.
 */
SqlCall DateTruncFunctionCall() :
{
    final List<SqlNode> args = new ArrayList<SqlNode>();
    final Span s;
    final SqlIntervalQualifier unit;
}
{
    <DATE_TRUNC> { s = span(); }
    <LPAREN>
    AddExpression(args, ExprContext.ACCEPT_SUB_QUERY)
    <COMMA>
    // A choice of arguments allows us to support both
    // the BigQuery variant, e.g. "DATE_TRUNC(d, YEAR)",
    // and the Redshift variant, e.g. "DATE_TRUNC('year', DATE '2008-09-08')".
    (
        LOOKAHEAD(2)
        unit = TimeUnit() { args.add(unit); }
    |
        AddExpression(args, ExprContext.ACCEPT_SUB_QUERY)
    )
    <RPAREN> {
        return SqlLibraryOperators.DATE_TRUNC.createCall(s.end(this), args);
    }
}

/**
 * Parses a call to TIMESTAMP_TRUNC.
 */
SqlCall TimestampTruncFunctionCall() :
{
    final List<SqlNode> args = new ArrayList<SqlNode>();
    final Span s;
    final SqlIntervalQualifier unit;
}
{
    <TIMESTAMP_TRUNC> { s = span(); }
    <LPAREN>
    AddExpression(args, ExprContext.ACCEPT_SUB_QUERY)
    <COMMA>
    unit = TimeUnitOrName() { args.add(unit); }
    <RPAREN> {
        return SqlLibraryOperators.TIMESTAMP_TRUNC.createCall(s.end(this), args);
    }
}

/**
 * Parses a call to BigQuery's TIME_DIFF.
 */
SqlCall TimeDiffFunctionCall() :
{
    final List<SqlNode> args = new ArrayList<SqlNode>();
    final Span s;
    final SqlIntervalQualifier unit;
}
{
    <TIME_DIFF> { s = span(); }
    <LPAREN>
    AddExpression(args, ExprContext.ACCEPT_SUB_QUERY)
    <COMMA>
    AddExpression(args, ExprContext.ACCEPT_SUB_QUERY)
    <COMMA>
    unit = TimeUnitOrName() { args.add(unit); }
    <RPAREN> {
        return SqlLibraryOperators.TIME_DIFF.createCall(s.end(this), args);
    }
}

/**
 * Parses a call to TIME_TRUNC.
 */
SqlCall TimeTruncFunctionCall() :
{
    final List<SqlNode> args = new ArrayList<SqlNode>();
    final Span s;
    final SqlIntervalQualifier unit;
}
{
    <TIME_TRUNC> { s = span(); }
    <LPAREN>
    AddExpression(args, ExprContext.ACCEPT_SUB_QUERY)
    <COMMA>
    unit = TimeUnitOrName() { args.add(unit); }
    <RPAREN> {
        return SqlLibraryOperators.TIME_TRUNC.createCall(s.end(this), args);
    }
}

/**
 * Parses a call to a grouping function inside the GROUP BY clause,
 * for example {@code TUMBLE(rowtime, INTERVAL '1' MINUTE)}.
 */
SqlCall GroupByWindowingCall() :
{
    final Span s;
    final List<SqlNode> args;
    final SqlOperator op;
}
{
    (
        <TUMBLE> { op = SqlStdOperatorTable.TUMBLE_OLD; }
    |
        <HOP> { op = SqlStdOperatorTable.HOP_OLD; }
    |
        <SESSION> { op = SqlStdOperatorTable.SESSION_OLD; }
    )
    { s = span(); }
    args = UnquantifiedFunctionParameterList(ExprContext.ACCEPT_SUB_QUERY) {
        return op.createCall(s.end(this), args);
    }
}

SqlCall MatchRecognizeFunctionCall() :
{
    final SqlCall func;
    final Span s;
}
{
    (
        <CLASSIFIER> { s = span(); } <LPAREN> <RPAREN> {
            func = SqlStdOperatorTable.CLASSIFIER.createCall(s.end(this));
        }
    |
        <MATCH_NUMBER> { s = span(); } <LPAREN> <RPAREN> {
            func = SqlStdOperatorTable.MATCH_NUMBER.createCall(s.end(this));
        }
    |
        LOOKAHEAD(3)
        func = MatchRecognizeNavigationLogical()
    |
        LOOKAHEAD(2)
        func = MatchRecognizeNavigationPhysical()
    |
        func = MatchRecognizeCallWithModifier()
    )
    { return func; }
}

SqlCall MatchRecognizeCallWithModifier() :
{
    final Span s;
    final SqlOperator runningOp;
    final SqlNode func;
}
{
    (
        <RUNNING> { runningOp = SqlStdOperatorTable.RUNNING; }
    |
        <FINAL> { runningOp = SqlStdOperatorTable.FINAL; }
    )
    { s = span(); }
    func = NamedFunctionCall() {
        return runningOp.createCall(s.end(func), func);
    }
}

SqlCall MatchRecognizeNavigationLogical() :
{
    final Span s = Span.of();
    SqlCall func;
    final SqlOperator funcOp;
    final SqlOperator runningOp;
    final List<SqlNode> args = new ArrayList<SqlNode>();
    SqlNode e;
}
{
    (
        <RUNNING> { runningOp = SqlStdOperatorTable.RUNNING; s.add(this); }
    |
        <FINAL> { runningOp = SqlStdOperatorTable.FINAL; s.add(this); }
    |   { runningOp = null; }
    )
    (
        <FIRST> { funcOp = SqlStdOperatorTable.FIRST; }
    |
        <LAST> { funcOp = SqlStdOperatorTable.LAST; }
    )
    { s.add(this); }
    <LPAREN>
    AddExpression(args, ExprContext.ACCEPT_SUB_QUERY)
    (
        <COMMA> e = NumericLiteral() { args.add(e); }
    |
        { args.add(LITERAL_ZERO); }
    )
    <RPAREN> {
        func = funcOp.createCall(s.end(this), args);
        if (runningOp != null) {
            return runningOp.createCall(s.end(this), func);
        } else {
            return func;
        }
    }
}

SqlCall MatchRecognizeNavigationPhysical() :
{
    final Span s;
    final SqlOperator funcOp;
    final List<SqlNode> args = new ArrayList<SqlNode>();
    SqlNode e;
}
{
    (
        <PREV> { funcOp = SqlStdOperatorTable.PREV; }
    |
        <NEXT> { funcOp = SqlStdOperatorTable.NEXT; }
    )
    { s = span(); }
    <LPAREN>
    AddExpression(args, ExprContext.ACCEPT_SUB_QUERY)
    (
        <COMMA> e = NumericLiteral() { args.add(e); }
    |
        { args.add(LITERAL_ONE); }
    )
    <RPAREN> {
        return funcOp.createCall(s.end(this), args);
    }
}

SqlCall withinDistinct(SqlNode arg) :
{
    final Span s;
    final SqlNodeList distinctList;
}
{
    <WITHIN> { s = span(); }
    <DISTINCT>
    <LPAREN>
    distinctList = ExpressionCommaList(s, ExprContext.ACCEPT_SUB_QUERY)
    <RPAREN> {
        return SqlStdOperatorTable.WITHIN_DISTINCT.createCall(
            s.end(this), arg, distinctList);
    }
}

SqlCall withinGroup(SqlNode arg) :
{
    final Span s;
    final SqlNodeList orderList;
}
{
    <WITHIN> { s = span(); }
    <GROUP>
    <LPAREN>
    orderList = OrderBy(true)
    <RPAREN> {
        return SqlStdOperatorTable.WITHIN_GROUP.createCall(
            s.end(this), arg, orderList);
    }
}

Pair<SqlParserPos, SqlOperator> NullTreatment() :
{
    final Span span;
}
{
    <IGNORE> { span = span(); } <NULLS> {
        return Pair.of(span.end(this), SqlStdOperatorTable.IGNORE_NULLS);
    }
|
    <RESPECT> { span = span(); } <NULLS> {
        return Pair.of(span.end(this), SqlStdOperatorTable.RESPECT_NULLS);
    }
}

SqlCall nullTreatment(SqlCall arg) :
{
    final Pair<SqlParserPos, SqlOperator> pair;
}
{
    pair = NullTreatment() { return pair.right.createCall(pair.left, arg); }
}

/**
 * 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.
 */
SqlNode NamedFunctionCall() :
{
    SqlCall call;
    final Span filterSpan;
    final SqlNode filter;
    final Span overSpan;
    final SqlNode over;
}
{
    (
        LOOKAHEAD(2)
        call = StringAggFunctionCall()
    |
        call = NamedCall()
    )
    [
        LOOKAHEAD(2) call = nullTreatment(call)
    ]
    [
        LOOKAHEAD(2) // decide between WITHIN DISTINCT and WITHIN GROUP
        call = withinDistinct(call)
    ]
    [
        call = withinGroup(call)
    ]
    [
        <FILTER> { filterSpan = span(); }
        <LPAREN>
        <WHERE>
        filter = Expression(ExprContext.ACCEPT_SUB_QUERY)
        <RPAREN> {
            call = SqlStdOperatorTable.FILTER.createCall(
                filterSpan.end(this), call, filter);
        }
    ]
    [
        <OVER> { overSpan = span(); }
        (
            over = SimpleIdentifier()
        |
            over = WindowSpecification()
        )
        {
            call = SqlStdOperatorTable.OVER.createCall(overSpan.end(over), call, over);
        }
    ]
    {
        return call;
    }
}

SqlCall NamedCall() :
{
    final SqlFunctionCategory funcType;
    final SqlIdentifier qualifiedName;
    final Span s;
    final List<SqlNode> args;
    SqlLiteral quantifier = null;
}
{
    (
        <SPECIFIC> {
            funcType = SqlFunctionCategory.USER_DEFINED_SPECIFIC_FUNCTION;
        }
    |
        { funcType = SqlFunctionCategory.USER_DEFINED_FUNCTION; }
    )
    qualifiedName = FunctionName() {
        s = span();
    }
    (
        LOOKAHEAD(2) <LPAREN> <STAR> {
            args = ImmutableList.of(SqlIdentifier.star(getPos()));
        }
        <RPAREN>
    |
        LOOKAHEAD(2) <LPAREN> <RPAREN> {
            args = ImmutableList.of();
        }
    |
        args = FunctionParameterList(ExprContext.ACCEPT_SUB_QUERY) {
            quantifier = (SqlLiteral) args.get(0);
            args.remove(0);
        }
    )
    {
        return createCall(qualifiedName, s.end(this), funcType, quantifier, args);
    }
}

/*
* Parse Floor/Ceil function parameters
*/
SqlNode StandardFloorCeilOptions(Span s, boolean floorFlag) :
{
    SqlNode e;
    final List<SqlNode> args = new ArrayList<SqlNode>();
    final SqlIntervalQualifier unit;
    SqlCall function;
    final Span s1;
}
{
    <LPAREN> AddExpression(args, ExprContext.ACCEPT_SUB_QUERY)
    (
        <TO> unit = TimeUnitOrName() {
            args.add(unit);
        }
    )?
    <RPAREN> {
        SqlOperator op = floorFlag
            ? SqlStdOperatorTable.FLOOR
            : SqlStdOperatorTable.CEIL;
        function =  op.createCall(s.end(this), args);
    }
    (
        <OVER> { s1 = span(); }
        (
            e = SimpleIdentifier()
        |
            e = WindowSpecification()
        )
        {
            return SqlStdOperatorTable.OVER.createCall(s1.end(this), function, e);
        }
    |
        { return function; }
    )
}

/**
 * Parses the name of a JDBC function that is a token but is not reserved.
 */
String NonReservedJdbcFunctionName() :
{
}
{
    (
        <SUBSTRING>
    )
    {
        return unquotedIdentifier();
    }
}

/**
 * Parses the name of a function (either a compound identifier or
 * a reserved word which can be used as a function name).
 */
SqlIdentifier FunctionName() :
{
    SqlIdentifier qualifiedName;
}
{
    (
        qualifiedName = CompoundIdentifier()
    |
        qualifiedName = ReservedFunctionName()
    )
    {
        return qualifiedName;
    }
}

/**
 * Parses a reserved word which is used as the name of a function.
 */
SqlIdentifier ReservedFunctionName() :
{
}
{
    (
        <ABS>
    |   <AVG>
    |   <CARDINALITY>
    |   <CEILING>
    |   <CHAR>
    |   <CHAR_LENGTH>
    |   <CHARACTER_LENGTH>
    |   <COALESCE>
    |   <COLLECT>
    |   <COVAR_POP>
    |   <COVAR_SAMP>
    |   <CUME_DIST>
    |   <COUNT>
    |   <CURRENT_DATE>
    |   <CURRENT_TIME>
    |   <CURRENT_TIMESTAMP>
    |   <DENSE_RANK>
    |   <ELEMENT>
    |   <EVERY>
    |   <EXP>
    |   <FIRST_VALUE>
    |   <FLOOR>
    |   <FUSION>
    |   <INTERSECTION>
    |   <GROUPING>
    |   <HOUR>
    |   <LAG>
    |   <LEAD>
    |   <LEFT>
    |   <LAST_VALUE>
    |   <LN>
    |   <LOCALTIME>
    |   <LOCALTIMESTAMP>
    |   <LOWER>
    |   <MAX>
    |   <MIN>
    |   <MINUTE>
    |   <MOD>
    |   <MONTH>
    |   <NTH_VALUE>
    |   <NTILE>
    |   <NULLIF>
    |   <OCTET_LENGTH>
    |   <PERCENT_RANK>
    |   <PERCENTILE_CONT>
    |   <PERCENTILE_DISC>
    |   <POWER>
    |   <RANK>
    |   <REGR_COUNT>
    |   <REGR_SXX>
    |   <REGR_SYY>
    |   <RIGHT>
    |   <ROW_NUMBER>
    |   <SECOND>
    |   <SOME>
    |   <SQRT>
    |   <STDDEV_POP>
    |   <STDDEV_SAMP>
    |   <SUM>
    |   <UPPER>
    |   <TRUNCATE>
    |   <USER>
    |   <VAR_POP>
    |   <VAR_SAMP>
    |   <YEAR>
    )
    {
        return new SqlIdentifier(unquotedIdentifier(), getPos());
    }
}

SqlIdentifier ContextVariable() :
{
}
{
    (
        <CURRENT_CATALOG>
    |   <CURRENT_DATE>
    |   <CURRENT_DEFAULT_TRANSFORM_GROUP>
    |   <CURRENT_PATH>
    |   <CURRENT_ROLE>
    |   <CURRENT_SCHEMA>
    |   <CURRENT_TIME>
    |   <CURRENT_TIMESTAMP>
    |   <CURRENT_USER>
    |   <LOCALTIME>
    |   <LOCALTIMESTAMP>
    |   <SESSION_USER>
    |   <SYSTEM_USER>
    |   <USER>
    )
    {
        return new SqlIdentifier(unquotedIdentifier(), getPos());
    }
}

/**
 * Parses a function call expression with JDBC syntax.
 */
SqlNode JdbcFunctionCall() :
{
    String name;
    SqlIdentifier id;
    SqlNode e;
    SqlLiteral tl;
    SqlNodeList args;
    SqlCall call;
    final Span s, s1;
}
{
    <LBRACE_FN> {
        s = span();
    }
    (
        LOOKAHEAD(1)
        call = TimestampAddFunctionCall() {
            name = call.getOperator().getName();
            args = new SqlNodeList(call.getOperandList(), getPos());
        }
    |
        LOOKAHEAD(1)
        call = DateTruncFunctionCall() {
            name = call.getOperator().getName();
            args = new SqlNodeList(call.getOperandList(), getPos());
        }
    |
        LOOKAHEAD(1)
        call = TimestampTruncFunctionCall() {
            name = call.getOperator().getName();
            args = new SqlNodeList(call.getOperandList(), getPos());
        }
    |
        LOOKAHEAD(1)
        call = TimeTruncFunctionCall() {
            name = call.getOperator().getName();
            args = new SqlNodeList(call.getOperandList(), getPos());
        }
    |
        LOOKAHEAD(1)
        call = TimestampDiff3FunctionCall() {
            name = call.getOperator().getName();
            args = new SqlNodeList(call.getOperandList(), getPos());
        }
    |
        LOOKAHEAD(1)
        call = TimeDiffFunctionCall() {
            name = call.getOperator().getName();
            args = new SqlNodeList(call.getOperandList(), getPos());
        }
    |
        LOOKAHEAD(3)
        call = TimestampDiffFunctionCall() {
            name = call.getOperator().getName();
            args = new SqlNodeList(call.getOperandList(), getPos());
        }
    |
        <CONVERT> { name = unquotedIdentifier(); }
        <LPAREN>
        e = Expression(ExprContext.ACCEPT_SUB_QUERY) {
            args = new SqlNodeList(getPos());
            args.add(e);
        }
        <COMMA>
        tl = JdbcOdbcDataType() { args.add(tl); }
        <RPAREN>
    |
        (
            // INSERT is a reserved word, but we need to handle {fn insert}
            // Similarly LEFT, RIGHT, TRUNCATE
            LOOKAHEAD(1)
            ( <INSERT> | <LEFT> | <RIGHT> | <TRUNCATE> ) { name = unquotedIdentifier(); }
        |
            // For cases like {fn power(1,2)} and {fn lower('a')}
            id = ReservedFunctionName() { name = id.getSimple(); }
        |
            // For cases like {fn substring('foo', 1,2)}
            name = NonReservedJdbcFunctionName()
        |
            name = Identifier()
        )
        (
            LOOKAHEAD(2) <LPAREN> <STAR> { s1 = span(); } <RPAREN>
            {
                args = new SqlNodeList(s1.pos());
                args.add(SqlIdentifier.star(s1.pos()));
            }
        |
            LOOKAHEAD(2) <LPAREN> <RPAREN> { args = SqlNodeList.EMPTY; }
        |
            args = ParenthesizedQueryOrCommaList(ExprContext.ACCEPT_SUB_QUERY)
        )
    )
    <RBRACE> {
        return new SqlJdbcFunctionCall(name).createCall(s.end(this),
            args.getList());
    }
}

/**
 * Parses a binary query operator like UNION.
 */
SqlBinaryOperator BinaryQueryOperator() :
{
}
{
    // If both the ALL or DISTINCT keywords are missing, DISTINCT is implicit.
    (
        <UNION>
        (
            <ALL> { return SqlStdOperatorTable.UNION_ALL; }
        |   <DISTINCT> { return SqlStdOperatorTable.UNION; }
        |   { return SqlStdOperatorTable.UNION; }
        )
    |
        <INTERSECT>
        (
            <ALL> { return SqlStdOperatorTable.INTERSECT_ALL; }
        |   <DISTINCT> { return SqlStdOperatorTable.INTERSECT; }
        |   { return SqlStdOperatorTable.INTERSECT; }
        )
    |
        (
            <EXCEPT>
        |
            <SET_MINUS> {
                if (!this.conformance.isMinusAllowed()) {
                    throw SqlUtil.newContextException(getPos(), RESOURCE.minusNotAllowed());
                }
            }
        )
        (
            <ALL> { return SqlStdOperatorTable.EXCEPT_ALL; }
        |   <DISTINCT> { return SqlStdOperatorTable.EXCEPT; }
        |   { return SqlStdOperatorTable.EXCEPT; }
        )
    )
}

/**
 * Parses a binary multiset operator.
 */
SqlBinaryOperator BinaryMultisetOperator() :
{
}
{
    // If both the ALL or DISTINCT keywords are missing, DISTINCT is implicit
    <MULTISET>
    (
        <UNION>
        [
            <ALL>
        |   <DISTINCT> { return SqlStdOperatorTable.MULTISET_UNION_DISTINCT; }
        ]
        { return SqlStdOperatorTable.MULTISET_UNION; }
    |
        <INTERSECT>
        [
            <ALL>
        |   <DISTINCT> { return SqlStdOperatorTable.MULTISET_INTERSECT_DISTINCT; }
        ]
        { return SqlStdOperatorTable.MULTISET_INTERSECT; }
    |
        <EXCEPT>
        [
            <ALL>
        |   <DISTINCT> { return SqlStdOperatorTable.MULTISET_EXCEPT_DISTINCT; }
        ]
        { return SqlStdOperatorTable.MULTISET_EXCEPT; }
    )
}

/**
 * Parses a binary row operator like AND.
 */
SqlBinaryOperator BinaryRowOperator() :
{
    SqlBinaryOperator op;
}
{
    // <IN> is handled as a special case
    <EQ> { return SqlStdOperatorTable.EQUALS; }
|   <GT> { return SqlStdOperatorTable.GREATER_THAN; }
|   <LT> { return SqlStdOperatorTable.LESS_THAN; }
|   <LE> { return SqlStdOperatorTable.LESS_THAN_OR_EQUAL; }
|   <GE> { return SqlStdOperatorTable.GREATER_THAN_OR_EQUAL; }
|   <NE> { return SqlStdOperatorTable.NOT_EQUALS; }
|   <NE2> {
        if (!this.conformance.isBangEqualAllowed()) {
            throw SqlUtil.newContextException(getPos(), RESOURCE.bangEqualNotAllowed());
        }
        return SqlStdOperatorTable.NOT_EQUALS;
    }
|   <PLUS> { return SqlStdOperatorTable.PLUS; }
|   <MINUS> { return SqlStdOperatorTable.MINUS; }
|   <STAR> { return SqlStdOperatorTable.MULTIPLY; }
|   <SLASH> { return SqlStdOperatorTable.DIVIDE; }
|   <PERCENT_REMAINDER> {
        if (!this.conformance.isPercentRemainderAllowed()) {
            throw SqlUtil.newContextException(getPos(), RESOURCE.percentRemainderNotAllowed());
        }
        return SqlStdOperatorTable.PERCENT_REMAINDER;
    }
|   <CONCAT> { return SqlStdOperatorTable.CONCAT; }
|   <AND> { return SqlStdOperatorTable.AND; }
|   <OR> { return SqlStdOperatorTable.OR; }
|   LOOKAHEAD(2) <IS> <DISTINCT> <FROM> { return SqlStdOperatorTable.IS_DISTINCT_FROM; }
|   <IS> <NOT> <DISTINCT> <FROM> { return SqlStdOperatorTable.IS_NOT_DISTINCT_FROM; }
|   <MEMBER> <OF> { return SqlStdOperatorTable.MEMBER_OF; }
|   LOOKAHEAD(2) <SUBMULTISET> <OF> { return SqlStdOperatorTable.SUBMULTISET_OF; }
|   <NOT> <SUBMULTISET> <OF> { return SqlStdOperatorTable.NOT_SUBMULTISET_OF; }
|   <CONTAINS> { return SqlStdOperatorTable.CONTAINS; }
|   <OVERLAPS> { return SqlStdOperatorTable.OVERLAPS; }
|   <EQUALS> { return SqlStdOperatorTable.PERIOD_EQUALS; }
|   <PRECEDES> { return SqlStdOperatorTable.PRECEDES; }
|   <SUCCEEDS> { return SqlStdOperatorTable.SUCCEEDS; }
|   LOOKAHEAD(2) <IMMEDIATELY> <PRECEDES> { return SqlStdOperatorTable.IMMEDIATELY_PRECEDES; }
|   <IMMEDIATELY> <SUCCEEDS> { return SqlStdOperatorTable.IMMEDIATELY_SUCCEEDS; }
|   op = BinaryMultisetOperator() { return op; }
}

/**
 * Parses a prefix row operator like NOT.
 */
SqlPrefixOperator PrefixRowOperator() :
{}
{
    <PLUS> { return SqlStdOperatorTable.UNARY_PLUS; }
|   <MINUS> { return SqlStdOperatorTable.UNARY_MINUS; }
|   <NOT> { return SqlStdOperatorTable.NOT; }
|   <EXISTS> { return SqlStdOperatorTable.EXISTS; }
|   <UNIQUE> { return SqlStdOperatorTable.UNIQUE; }
}

/**
 * Parses a postfix row operator like IS NOT NULL.
 */
SqlPostfixOperator PostfixRowOperator() :
{}
{
    <IS>
    (
        <A> <SET> { return SqlStdOperatorTable.IS_A_SET; }
    |
        <NOT>
        (
            <NULL> { return SqlStdOperatorTable.IS_NOT_NULL; }
        |   <TRUE> { return SqlStdOperatorTable.IS_NOT_TRUE; }
        |   <FALSE> { return SqlStdOperatorTable.IS_NOT_FALSE; }
        |   <UNKNOWN> { return SqlStdOperatorTable.IS_NOT_UNKNOWN; }
        |   <A> <SET> { return SqlStdOperatorTable.IS_NOT_A_SET; }
        |   <EMPTY> { return SqlStdOperatorTable.IS_NOT_EMPTY; }
        |   LOOKAHEAD(2) <JSON> <VALUE> { return SqlStdOperatorTable.IS_NOT_JSON_VALUE; }
        |   LOOKAHEAD(2) <JSON> <OBJECT> { return SqlStdOperatorTable.IS_NOT_JSON_OBJECT; }
        |   LOOKAHEAD(2) <JSON> <ARRAY> { return SqlStdOperatorTable.IS_NOT_JSON_ARRAY; }
        |   LOOKAHEAD(2) <JSON> <SCALAR> { return SqlStdOperatorTable.IS_NOT_JSON_SCALAR; }
        |   <JSON> { return SqlStdOperatorTable.IS_NOT_JSON_VALUE; }
        )
    |
        (
            <NULL> { return SqlStdOperatorTable.IS_NULL; }
        |   <TRUE> { return SqlStdOperatorTable.IS_TRUE; }
        |   <FALSE> { return SqlStdOperatorTable.IS_FALSE; }
        |   <UNKNOWN> { return SqlStdOperatorTable.IS_UNKNOWN; }
        |   <EMPTY> { return SqlStdOperatorTable.IS_EMPTY; }
        |   LOOKAHEAD(2) <JSON> <VALUE> { return SqlStdOperatorTable.IS_JSON_VALUE; }
        |   LOOKAHEAD(2) <JSON> <OBJECT> { return SqlStdOperatorTable.IS_JSON_OBJECT; }
        |   LOOKAHEAD(2) <JSON> <ARRAY> { return SqlStdOperatorTable.IS_JSON_ARRAY; }
        |   LOOKAHEAD(2) <JSON> <SCALAR> { return SqlStdOperatorTable.IS_JSON_SCALAR; }
        |   <JSON> { return SqlStdOperatorTable.IS_JSON_VALUE; }
        )
    )
|
    <FORMAT>
    (
        JsonRepresentation() {
            return SqlStdOperatorTable.JSON_VALUE_EXPRESSION;
        }
    )
}


/* KEYWORDS:  anything in this list is a reserved word unless it appears
   in the NonReservedKeyWord() production. */

<DEFAULT, DQID, BTID, BQID, BQHID> TOKEN :
{
    < A: "A" >
|   < ABS: "ABS" >
|   < ABSENT: "ABSENT" >
|   < ABSOLUTE: "ABSOLUTE" >
|   < ACTION: "ACTION" >
|   < ADA: "ADA" >
|   < ADD: "ADD" >
|   < ADMIN: "ADMIN" >
|   < AFTER: "AFTER" >
|   < ALL: "ALL" >
|   < ALLOCATE: "ALLOCATE" >
|   < ALLOW: "ALLOW" >
|   < ALTER: "ALTER" >
|   < ALWAYS: "ALWAYS" >
|   < AND: "AND" >
|   < ANY: "ANY" >
|   < APPLY: "APPLY" >
|   < ARE: "ARE" >
|   < ARRAY: "ARRAY" >
|   < ARRAY_AGG: "ARRAY_AGG" >
|   < ARRAY_CONCAT_AGG: "ARRAY_CONCAT_AGG" >
|   < ARRAY_MAX_CARDINALITY: "ARRAY_MAX_CARDINALITY" >
|   < AS: "AS" >
|   < ASC: "ASC" >
|   < ASENSITIVE: "ASENSITIVE" >
|   < ASSERTION: "ASSERTION" >
|   < ASSIGNMENT: "ASSIGNMENT" >
|   < ASYMMETRIC: "ASYMMETRIC" >
|   < AT: "AT" >
|   < ATOMIC: "ATOMIC" >
|   < ATTRIBUTE: "ATTRIBUTE" >
|   < ATTRIBUTES: "ATTRIBUTES" >
|   < AUTHORIZATION: "AUTHORIZATION" >
|   < AVG: "AVG" >
|   < BEFORE: "BEFORE" >
|   < BEGIN: "BEGIN" >
|   < BEGIN_FRAME: "BEGIN_FRAME" >
|   < BEGIN_PARTITION: "BEGIN_PARTITION" >
|   < BERNOULLI: "BERNOULLI" >
|   < BETWEEN: "BETWEEN" >
|   < BIGINT: "BIGINT" >
|   < BINARY: "BINARY" >
|   < BIT: "BIT" >
|   < BLOB: "BLOB" >
|   < BOOLEAN: "BOOLEAN" >
|   < BOTH: "BOTH" >
|   < BREADTH: "BREADTH" >
|   < BY: "BY" >
|   < C: "C" >
|   < CALL: "CALL" >
|   < CALLED: "CALLED" >
|   < CARDINALITY: "CARDINALITY" >
|   < CASCADE: "CASCADE" >
|   < CASCADED: "CASCADED" >
|   < CASE: "CASE" >
|   < CAST: "CAST" >
|   < CATALOG: "CATALOG" >
|   < CATALOG_NAME: "CATALOG_NAME" >
|   < CEIL: "CEIL" >
|   < CEILING: "CEILING" >
|   < CENTURY: "CENTURY" >
|   < CHAIN: "CHAIN" >
|   < CHAR: "CHAR" >
|   < CHAR_LENGTH: "CHAR_LENGTH" >
|   < CHARACTER: "CHARACTER" >
|   < CHARACTER_LENGTH: "CHARACTER_LENGTH" >
|   < CHARACTER_SET_CATALOG: "CHARACTER_SET_CATALOG" >
|   < CHARACTER_SET_NAME: "CHARACTER_SET_NAME" >
|   < CHARACTER_SET_SCHEMA: "CHARACTER_SET_SCHEMA" >
|   < CHARACTERISTICS: "CHARACTERISTICS" >
|   < CHARACTERS: "CHARACTERS" >
|   < CHECK: "CHECK" >
|   < CLASSIFIER: "CLASSIFIER" >
|   < CLASS_ORIGIN: "CLASS_ORIGIN" >
|   < CLOB: "CLOB" >
|   < CLOSE: "CLOSE" >
|   < COALESCE: "COALESCE" >
|   < COBOL: "COBOL" >
|   < COLLATE: "COLLATE" >
|   < COLLATION: "COLLATION" >
|   < COLLATION_CATALOG: "COLLATION_CATALOG" >
|   < COLLATION_NAME: "COLLATION_NAME" >
|   < COLLATION_SCHEMA: "COLLATION_SCHEMA" >
|   < COLLECT: "COLLECT" >
|   < COLUMN: "COLUMN" >
|   < COLUMN_NAME: "COLUMN_NAME" >
|   < COMMAND_FUNCTION: "COMMAND_FUNCTION" >
|   < COMMAND_FUNCTION_CODE: "COMMAND_FUNCTION_CODE" >
|   < COMMIT: "COMMIT" >
|   < COMMITTED: "COMMITTED" >
|   < CONDITION: "CONDITION" >
|   < CONDITIONAL: "CONDITIONAL" >
|   < CONDITION_NUMBER: "CONDITION_NUMBER" >
|   < CONNECT: "CONNECT" >
|   < CONNECTION: "CONNECTION" >
|   < CONNECTION_NAME: "CONNECTION_NAME" >
|   < CONSTRAINT: "CONSTRAINT" >
|   < CONSTRAINT_CATALOG: "CONSTRAINT_CATALOG" >
|   < CONSTRAINT_NAME: "CONSTRAINT_NAME" >
|   < CONSTRAINT_SCHEMA: "CONSTRAINT_SCHEMA" >
|   < CONSTRAINTS: "CONSTRAINTS" >
|   < CONSTRUCTOR: "CONSTRUCTOR" >
|   < CONTAINS: "CONTAINS" >
|   < CONTINUE: "CONTINUE" >
|   < CONVERT: "CONVERT" >
|   < CORR: "CORR" >
|   < CORRESPONDING: "CORRESPONDING" >
|   < COUNT: "COUNT" >
|   < COVAR_POP: "COVAR_POP" >
|   < COVAR_SAMP: "COVAR_SAMP" >
|   < CREATE: "CREATE" >
|   < CROSS: "CROSS" >
|   < CUBE: "CUBE" >
|   < CUME_DIST: "CUME_DIST" >
|   < CURRENT: "CURRENT" >
|   < CURRENT_CATALOG: "CURRENT_CATALOG" >
|   < CURRENT_DATE: "CURRENT_DATE" >
|   < CURRENT_DEFAULT_TRANSFORM_GROUP: "CURRENT_DEFAULT_TRANSFORM_GROUP" >
|   < CURRENT_PATH: "CURRENT_PATH" >
|   < CURRENT_ROLE: "CURRENT_ROLE" >
|   < CURRENT_ROW: "CURRENT_ROW" >
|   < CURRENT_SCHEMA: "CURRENT_SCHEMA" >
|   < CURRENT_TIME: "CURRENT_TIME" >
|   < CURRENT_TIMESTAMP: "CURRENT_TIMESTAMP" >
|   < CURRENT_TRANSFORM_GROUP_FOR_TYPE: "CURRENT_TRANSFORM_GROUP_FOR_TYPE" >
|   < CURRENT_USER: "CURRENT_USER" >
|   < CURSOR: "CURSOR" >
|   < CURSOR_NAME: "CURSOR_NAME" >
|   < CYCLE: "CYCLE" >
|   < DATA: "DATA" >
|   < DATABASE: "DATABASE" >
|   < DATE: "DATE" >
|   < DATE_TRUNC: "DATE_TRUNC" >
|   < DATETIME: "DATETIME" >
|   < DATETIME_INTERVAL_CODE: "DATETIME_INTERVAL_CODE" >
|   < DATETIME_INTERVAL_PRECISION: "DATETIME_INTERVAL_PRECISION" >
|   < DAY: "DAY" >
|   < DAYOFWEEK: "DAYOFWEEK" >
|   < DAYOFYEAR: "DAYOFYEAR" >
|   < DAYS: "DAYS" >
|   < DEALLOCATE: "DEALLOCATE" >
|   < DEC: "DEC" >
|   < DECADE: "DECADE" >
|   < DECIMAL: "DECIMAL" >
|   < DECLARE: "DECLARE" >
|   < DEFAULT_: "DEFAULT" >
|   < DEFAULTS: "DEFAULTS" >
|   < DEFERRABLE: "DEFERRABLE" >
|   < DEFERRED: "DEFERRED" >
|   < DEFINE: "DEFINE" >
|   < DEFINED: "DEFINED" >
|   < DEFINER: "DEFINER" >
|   < DEGREE: "DEGREE" >
|   < DELETE: "DELETE" > { beforeTableName(); }
|   < DENSE_RANK: "DENSE_RANK" >
|   < DEPTH: "DEPTH" >
|   < DEREF: "DEREF" >
|   < DERIVED: "DERIVED" >
|   < DESC: "DESC" >
|   < DESCRIBE: "DESCRIBE" > { beforeTableName(); }
|   < DESCRIPTION: "DESCRIPTION" >
|   < DESCRIPTOR: "DESCRIPTOR" >
|   < DETERMINISTIC: "DETERMINISTIC" >
|   < DIAGNOSTICS: "DIAGNOSTICS" >
|   < DISALLOW: "DISALLOW" >
|   < DISCONNECT: "DISCONNECT" >
|   < DISPATCH: "DISPATCH" >
|   < DISTINCT: "DISTINCT" >
|   < DOMAIN: "DOMAIN" >
|   < DOT_FORMAT: "DOT" >
|   < DOUBLE: "DOUBLE" >
|   < DOW: "DOW" >
|   < DOY: "DOY" >
|   < DROP: "DROP" >
|   < DYNAMIC: "DYNAMIC" >
|   < DYNAMIC_FUNCTION: "DYNAMIC_FUNCTION" >
|   < DYNAMIC_FUNCTION_CODE: "DYNAMIC_FUNCTION_CODE" >
|   < EACH: "EACH" >
|   < ELEMENT: "ELEMENT" >
|   < ELSE: "ELSE" >
|   < EMPTY: "EMPTY" >
|   < ENCODING: "ENCODING">
|   < END: "END" >
|   < END_EXEC: "END-EXEC" >
|   < END_FRAME: "END_FRAME" >
|   < END_PARTITION: "END_PARTITION" >
|   < EPOCH: "EPOCH" >
|   < EQUALS: "EQUALS" >
|   < ERROR: "ERROR" >
|   < ESCAPE: "ESCAPE" >
|   < EVERY: "EVERY" >
|   < EXCEPT: "EXCEPT" >
|   < EXCEPTION: "EXCEPTION" >
|   < EXCLUDE: "EXCLUDE" >
|   < EXCLUDING: "EXCLUDING" >
|   < EXEC: "EXEC" >
|   < EXECUTE: "EXECUTE" >
|   < EXISTS: "EXISTS" >
|   < EXP: "EXP" >
|   < EXPLAIN: "EXPLAIN" >
|   < EXTEND: "EXTEND" >
|   < EXTERNAL: "EXTERNAL" >
|   < EXTRACT: "EXTRACT" >
|   < FALSE: "FALSE" >
|   < FETCH: "FETCH" >
|   < FILTER: "FILTER" >
|   < FINAL: "FINAL" >
|   < FIRST: "FIRST" >
|   < FIRST_VALUE: "FIRST_VALUE">
|   < FLOAT: "FLOAT" >
|   < FLOOR: "FLOOR" >
|   < FOLLOWING: "FOLLOWING" >
|   < FOR: "FOR" >
|   < FORMAT: "FORMAT" >
|   < FOREIGN: "FOREIGN" >
|   < FORTRAN: "FORTRAN" >
|   < FOUND: "FOUND" >
|   < FRAC_SECOND: "FRAC_SECOND" >
|   < FRAME_ROW: "FRAME_ROW" >
|   < FREE: "FREE" >
|   < FRIDAY: "FRIDAY" >
|   < FROM: "FROM" > { beforeTableName(); }
|   < FULL: "FULL" >
|   < FUNCTION: "FUNCTION" >
|   < FUSION: "FUSION" >
|   < G: "G" >
|   < GENERAL: "GENERAL" >
|   < GENERATED: "GENERATED" >
|   < GEOMETRY: "GEOMETRY" >
|   < GET: "GET" >
|   < GLOBAL: "GLOBAL" >
|   < GO: "GO" >
|   < GOTO: "GOTO" >
|   < GRANT: "GRANT" >
|   < GRANTED: "GRANTED" >
|   < GROUP: "GROUP" >
|   < GROUP_CONCAT: "GROUP_CONCAT" >
|   < GROUPING: "GROUPING" >
|   < GROUPS: "GROUPS" >
|   < HAVING: "HAVING" >
|   < HIERARCHY: "HIERARCHY" >
|   < HOLD: "HOLD" >
|   < HOP: "HOP" >
|   < HOUR: "HOUR" >
|   < HOURS: "HOURS" >
|   < IDENTITY: "IDENTITY" >
|   < IGNORE: "IGNORE" >
|   < ILIKE: "ILIKE" >
|   < IMMEDIATE: "IMMEDIATE" >
|   < IMMEDIATELY: "IMMEDIATELY" >
|   < IMPLEMENTATION: "IMPLEMENTATION" >
|   < IMPORT: "IMPORT" >
|   < IN: "IN" >
|   < INCLUDE: "INCLUDE" >
|   < INCLUDING: "INCLUDING" >
|   < INCREMENT: "INCREMENT" >
|   < INDICATOR: "INDICATOR" >
|   < INITIAL: "INITIAL" >
|   < INITIALLY: "INITIALLY" >
|   < INNER: "INNER" >
|   < INOUT: "INOUT" >
|   < INPUT: "INPUT" >
|   < INSENSITIVE: "INSENSITIVE" >
|   < INSERT: "INSERT" > { beforeTableName(); }
|   < INSTANCE: "INSTANCE" >
|   < INSTANTIABLE: "INSTANTIABLE" >
|   < INT: "INT" >
|   < INTEGER: "INTEGER" >
|   < INTERSECT: "INTERSECT" >
|   < INTERSECTION: "INTERSECTION" >
|   < INTERVAL: "INTERVAL" >
|   < INTO: "INTO" >
|   < INVOKER: "INVOKER" >
|   < IS: "IS" >
|   < ISODOW: "ISODOW" >
|   < ISOYEAR: "ISOYEAR" >
|   < ISOLATION: "ISOLATION" >
|   < JAVA: "JAVA" >
|   < JOIN: "JOIN" > { beforeTableName(); }
|   < JSON: "JSON" >
|   < JSON_ARRAY: "JSON_ARRAY">
|   < JSON_ARRAYAGG: "JSON_ARRAYAGG">
|   < JSON_EXISTS: "JSON_EXISTS" >
|   < JSON_OBJECT: "JSON_OBJECT">
|   < JSON_OBJECTAGG: "JSON_OBJECTAGG">
|   < JSON_QUERY: "JSON_QUERY" >
|   < JSON_VALUE: "JSON_VALUE" >
|   < K: "K" >
|   < KEY: "KEY" >
|   < KEY_MEMBER: "KEY_MEMBER" >
|   < KEY_TYPE: "KEY_TYPE" >
|   < LABEL: "LABEL" >
|   < LAG: "LAG" >
|   < LANGUAGE: "LANGUAGE" >
|   < LARGE: "LARGE" >
|   < LAST: "LAST" >
|   < LAST_VALUE: "LAST_VALUE" >
|   < LATERAL: "LATERAL" >
|   < LEAD: "LEAD" >
|   < LEADING: "LEADING" >
|   < LEFT: "LEFT" >
|   < LENGTH: "LENGTH" >
|   < LEVEL: "LEVEL" >
|   < LIBRARY: "LIBRARY" >
|   < LIKE: "LIKE" >
|   < LIKE_REGEX: "LIKE_REGEX" >
|   < LIMIT: "LIMIT" >
|   < LN: "LN" >
|   < LOCAL: "LOCAL" >
|   < LOCALTIME: "LOCALTIME" >
|   < LOCALTIMESTAMP: "LOCALTIMESTAMP" >
|   < LOCATOR: "LOCATOR" >
|   < LOWER: "LOWER" >
|   < M: "M" >
|   < MAP: "MAP" >
|   < MATCH: "MATCH" >
|   < MATCHED: "MATCHED" >
|   < MATCHES: "MATCHES" >
|   < MATCH_NUMBER: "MATCH_NUMBER">
|   < MATCH_RECOGNIZE: "MATCH_RECOGNIZE">
|   < MAX: "MAX" >
|   < MAXVALUE: "MAXVALUE" >
|   < MEASURES: "MEASURES" >
|   < MEMBER: "MEMBER" >
|   < MERGE: "MERGE" > { beforeTableName(); }
|   < MESSAGE_LENGTH: "MESSAGE_LENGTH" >
|   < MESSAGE_OCTET_LENGTH: "MESSAGE_OCTET_LENGTH" >
|   < MESSAGE_TEXT: "MESSAGE_TEXT" >
|   < METHOD: "METHOD" >
|   < MICROSECOND: "MICROSECOND" >
|   < MILLISECOND: "MILLISECOND" >
|   < MILLENNIUM: "MILLENNIUM" >
|   < MIN: "MIN" >
|   < MINUTE: "MINUTE" >
|   < MINUTES: "MINUTES" >
|   < MINVALUE: "MINVALUE" >
|   < MOD: "MOD" >
|   < MODIFIES: "MODIFIES" >
|   < MODULE: "MODULE" >
|   < MONDAY: "MONDAY" >
|   < MONTH: "MONTH" >
|   < MONTHS: "MONTHS" >
|   < MORE_: "MORE" >
|   < MULTISET: "MULTISET" >
|   < MUMPS: "MUMPS" >
|   < NAME: "NAME" >
|   < NAMES: "NAMES" >
|   < NANOSECOND: "NANOSECOND" >
|   < NATIONAL: "NATIONAL" >
|   < NATURAL: "NATURAL" >
|   < NCHAR: "NCHAR" >
|   < NCLOB: "NCLOB" >
|   < NESTING: "NESTING" >
|   < NEW: "NEW" >
|   < NEXT: "NEXT" >
|   < NO: "NO" >
|   < NONE: "NONE" >
|   < NORMALIZE: "NORMALIZE" >
|   < NORMALIZED: "NORMALIZED" >
|   < NOT: "NOT" >
|   < NTH_VALUE: "NTH_VALUE" >
|   < NTILE: "NTILE" >
|   < NULL: "NULL" >
|   < NULLABLE: "NULLABLE" >
|   < NULLIF: "NULLIF" >
|   < NULLS: "NULLS" >
|   < NUMBER: "NUMBER" >
|   < NUMERIC: "NUMERIC" >
|   < OBJECT: "OBJECT" >
|   < OCCURRENCES_REGEX: "OCCURRENCES_REGEX" >
|   < OCTET_LENGTH: "OCTET_LENGTH" >
|   < OCTETS: "OCTETS" >
|   < OF: "OF" >
|   < OFFSET: "OFFSET" >
|   < OLD: "OLD" >
|   < OMIT: "OMIT" >
|   < ON: "ON" >
|   < ONE: "ONE" >
|   < ONLY: "ONLY" >
|   < OPEN: "OPEN" >
|   < OPTION: "OPTION" >
|   < OPTIONS: "OPTIONS" >
|   < OR: "OR" >
|   < ORDER: "ORDER" >
|   < ORDERING: "ORDERING" >
|   < ORDINALITY: "ORDINALITY" >
|   < OTHERS: "OTHERS" >
|   < OUT: "OUT" >
|   < OUTER: "OUTER" >
|   < OUTPUT: "OUTPUT" >
|   < OVER: "OVER" >
|   < OVERLAPS: "OVERLAPS" >
|   < OVERLAY: "OVERLAY" >
|   < OVERRIDING: "OVERRIDING" >
|   < PAD: "PAD" >
|   < PARAMETER: "PARAMETER" >
|   < PARAMETER_MODE: "PARAMETER_MODE" >
|   < PARAMETER_NAME: "PARAMETER_NAME" >
|   < PARAMETER_ORDINAL_POSITION: "PARAMETER_ORDINAL_POSITION" >
|   < PARAMETER_SPECIFIC_CATALOG: "PARAMETER_SPECIFIC_CATALOG" >
|   < PARAMETER_SPECIFIC_NAME: "PARAMETER_SPECIFIC_NAME" >
|   < PARAMETER_SPECIFIC_SCHEMA: "PARAMETER_SPECIFIC_SCHEMA" >
|   < PARTIAL: "PARTIAL" >
|   < PARTITION: "PARTITION" >
|   < PASCAL: "PASCAL" >
|   < PASSING: "PASSING" >
|   < PASSTHROUGH: "PASSTHROUGH" >
|   < PAST: "PAST" >
|   < PATH: "PATH" >
|   < PATTERN: "PATTERN" >
|   < PER: "PER" >
|   < PERCENT: "PERCENT" >
|   < PERCENTILE_CONT: "PERCENTILE_CONT" >
|   < PERCENTILE_DISC: "PERCENTILE_DISC" >
|   < PERCENT_RANK: "PERCENT_RANK" >
|   < PERIOD: "PERIOD" >
|   < PERMUTE: "PERMUTE" >
|   < PIVOT: "PIVOT" >
|   < PLACING: "PLACING" >
|   < PLAN: "PLAN" >
|   < PLI: "PLI" >
|   < PORTION: "PORTION" >
|   < POSITION: "POSITION" >
|   < POSITION_REGEX: "POSITION_REGEX" >
|   < POWER: "POWER" >
|   < PRECEDES: "PRECEDES" >
|   < PRECEDING: "PRECEDING" >
|   < PRECISION: "PRECISION" >
|   < PREPARE: "PREPARE" >
|   < PRESERVE: "PRESERVE" >
|   < PREV: "PREV" >
|   < PRIMARY: "PRIMARY" >
|   < PRIOR: "PRIOR" >
|   < PRIVILEGES: "PRIVILEGES" >
|   < PROCEDURE: "PROCEDURE" >
|   < PUBLIC: "PUBLIC" >
|   < QUALIFY: "QUALIFY" >
|   < QUARTER: "QUARTER" >
|   < QUARTERS: "QUARTERS" >
|   < RANGE: "RANGE" >
|   < RANK: "RANK" >
|   < READ: "READ" >
|   < READS: "READS" >
|   < REAL: "REAL" >
|   < RECURSIVE: "RECURSIVE" >
|   < REF: "REF" >
|   < REFERENCES: "REFERENCES" >
|   < REFERENCING: "REFERENCING" >
|   < REGR_AVGX: "REGR_AVGX" >
|   < REGR_AVGY: "REGR_AVGY" >
|   < REGR_COUNT: "REGR_COUNT" >
|   < REGR_INTERCEPT: "REGR_INTERCEPT" >
|   < REGR_R2: "REGR_R2" >
|   < REGR_SLOPE: "REGR_SLOPE" >
|   < REGR_SXX: "REGR_SXX" >
|   < REGR_SXY: "REGR_SXY" >
|   < REGR_SYY: "REGR_SYY" >
|   < RELATIVE: "RELATIVE" >
|   < RELEASE: "RELEASE" >
|   < REPEATABLE: "REPEATABLE" >
|   < REPLACE: "REPLACE" >
|   < RESET: "RESET" >
|   < RESPECT: "RESPECT" >
|   < RESTART: "RESTART" >
|   < RESTRICT: "RESTRICT" >
|   < RESULT: "RESULT" >
|   < RETURN: "RETURN" >
|   < RETURNED_CARDINALITY: "RETURNED_CARDINALITY" >
|   < RETURNED_LENGTH: "RETURNED_LENGTH" >
|   < RETURNED_OCTET_LENGTH: "RETURNED_OCTET_LENGTH" >
|   < RETURNED_SQLSTATE: "RETURNED_SQLSTATE" >
|   < RETURNING: "RETURNING" >
|   < RETURNS: "RETURNS" >
|   < REVOKE: "REVOKE" >
|   < RIGHT: "RIGHT" >
|   < RLIKE: "RLIKE" >
|   < ROLE: "ROLE" >
|   < ROLLBACK: "ROLLBACK" >
|   < ROLLUP: "ROLLUP" >
|   < ROUTINE: "ROUTINE" >
|   < ROUTINE_CATALOG: "ROUTINE_CATALOG" >
|   < ROUTINE_NAME: "ROUTINE_NAME" >
|   < ROUTINE_SCHEMA: "ROUTINE_SCHEMA" >
|   < ROW: "ROW" >
|   < ROW_COUNT: "ROW_COUNT" >
|   < ROW_NUMBER: "ROW_NUMBER" >
|   < ROWS: "ROWS" >
|   < RUNNING: "RUNNING" >
|   < SAFE_CAST: "SAFE_CAST" >
|   < SATURDAY: "SATURDAY" >
|   < SAVEPOINT: "SAVEPOINT" >
|   < SCALAR: "SCALAR" >
|   < SCALE: "SCALE" >
|   < SCHEMA: "SCHEMA" >
|   < SCHEMA_NAME: "SCHEMA_NAME" >
|   < SCOPE: "SCOPE" >
|   < SCOPE_CATALOGS: "SCOPE_CATALOGS" >
|   < SCOPE_NAME: "SCOPE_NAME" >
|   < SCOPE_SCHEMA: "SCOPE_SCHEMA" >
|   < SCROLL: "SCROLL" >
|   < SEARCH: "SEARCH" >
|   < SECOND: "SECOND" >
|   < SECONDS: "SECONDS" >
|   < SECTION: "SECTION" >
|   < SECURITY: "SECURITY" >
|   < SEEK: "SEEK" >
|   < SELECT: "SELECT" > { afterTableName(); }
|   < SELF: "SELF" >
|   < SENSITIVE: "SENSITIVE" >
|   < SEPARATOR: "SEPARATOR" >
|   < SEQUENCE: "SEQUENCE" >
|   < SERIALIZABLE: "SERIALIZABLE" >
|   < SERVER: "SERVER" >
|   < SERVER_NAME: "SERVER_NAME" >
|   < SESSION: "SESSION" >
|   < SESSION_USER: "SESSION_USER" >
|   < SET: "SET" > { afterTableName(); }
|   < SETS: "SETS" >
|   < SET_MINUS: "MINUS">
|   < SHOW: "SHOW" >
|   < SIMILAR: "SIMILAR" >
|   < SIMPLE: "SIMPLE" >
|   < SIZE: "SIZE" >
|   < SKIP_: "SKIP" >
|   < SMALLINT: "SMALLINT" >
|   < SOME: "SOME" >
|   < SOURCE: "SOURCE" >
|   < SPACE: "SPACE" >
|   < SPECIFIC: "SPECIFIC" >
|   < SPECIFIC_NAME: "SPECIFIC_NAME" >
|   < SPECIFICTYPE: "SPECIFICTYPE" >
|   < SQL: "SQL" >
|   < SQLEXCEPTION: "SQLEXCEPTION" >
|   < SQLSTATE: "SQLSTATE" >
|   < SQLWARNING: "SQLWARNING" >
|   < SQL_BIGINT: "SQL_BIGINT" >
|   < SQL_BINARY: "SQL_BINARY" >
|   < SQL_BIT: "SQL_BIT" >
|   < SQL_BLOB: "SQL_BLOB" >
|   < SQL_BOOLEAN: "SQL_BOOLEAN" >
|   < SQL_CHAR: "SQL_CHAR" >
|   < SQL_CLOB: "SQL_CLOB" >
|   < SQL_DATE: "SQL_DATE" >
|   < SQL_DECIMAL: "SQL_DECIMAL" >
|   < SQL_DOUBLE: "SQL_DOUBLE" >
|   < SQL_FLOAT: "SQL_FLOAT" >
|   < SQL_INTEGER: "SQL_INTEGER" >
|   < SQL_INTERVAL_DAY: "SQL_INTERVAL_DAY" >
|   < SQL_INTERVAL_DAY_TO_HOUR: "SQL_INTERVAL_DAY_TO_HOUR" >
|   < SQL_INTERVAL_DAY_TO_MINUTE: "SQL_INTERVAL_DAY_TO_MINUTE" >
|   < SQL_INTERVAL_DAY_TO_SECOND: "SQL_INTERVAL_DAY_TO_SECOND" >
|   < SQL_INTERVAL_HOUR: "SQL_INTERVAL_HOUR" >
|   < SQL_INTERVAL_HOUR_TO_MINUTE: "SQL_INTERVAL_HOUR_TO_MINUTE" >
|   < SQL_INTERVAL_HOUR_TO_SECOND: "SQL_INTERVAL_HOUR_TO_SECOND" >
|   < SQL_INTERVAL_MINUTE: "SQL_INTERVAL_MINUTE" >
|   < SQL_INTERVAL_MINUTE_TO_SECOND: "SQL_INTERVAL_MINUTE_TO_SECOND" >
|   < SQL_INTERVAL_MONTH: "SQL_INTERVAL_MONTH" >
|   < SQL_INTERVAL_SECOND: "SQL_INTERVAL_SECOND" >
|   < SQL_INTERVAL_YEAR: "SQL_INTERVAL_YEAR" >
|   < SQL_INTERVAL_YEAR_TO_MONTH: "SQL_INTERVAL_YEAR_TO_MONTH" >
|   < SQL_LONGVARBINARY: "SQL_LONGVARBINARY" >
|   < SQL_LONGVARCHAR: "SQL_LONGVARCHAR" >
|   < SQL_LONGVARNCHAR: "SQL_LONGVARNCHAR" >
|   < SQL_NCHAR: "SQL_NCHAR" >
|   < SQL_NCLOB: "SQL_NCLOB" >
|   < SQL_NUMERIC: "SQL_NUMERIC" >
|   < SQL_NVARCHAR: "SQL_NVARCHAR" >
|   < SQL_REAL: "SQL_REAL" >
|   < SQL_SMALLINT: "SQL_SMALLINT" >
|   < SQL_TIME: "SQL_TIME" >
|   < SQL_TIMESTAMP: "SQL_TIMESTAMP" >
|   < SQL_TINYINT: "SQL_TINYINT" >
|   < SQL_TSI_DAY: "SQL_TSI_DAY" >
|   < SQL_TSI_FRAC_SECOND: "SQL_TSI_FRAC_SECOND" >
|   < SQL_TSI_HOUR: "SQL_TSI_HOUR" >
|   < SQL_TSI_MICROSECOND: "SQL_TSI_MICROSECOND" >
|   < SQL_TSI_MINUTE: "SQL_TSI_MINUTE" >
|   < SQL_TSI_MONTH: "SQL_TSI_MONTH" >
|   < SQL_TSI_QUARTER: "SQL_TSI_QUARTER" >
|   < SQL_TSI_SECOND: "SQL_TSI_SECOND" >
|   < SQL_TSI_WEEK: "SQL_TSI_WEEK" >
|   < SQL_TSI_YEAR: "SQL_TSI_YEAR" >
|   < SQL_VARBINARY: "SQL_VARBINARY" >
|   < SQL_VARCHAR: "SQL_VARCHAR" >
|   < SQRT: "SQRT" >
|   < START: "START" >
|   < STATE: "STATE" >
|   < STATEMENT: "STATEMENT" >
|   < STATIC: "STATIC" >
|   < STDDEV_POP: "STDDEV_POP" >
|   < STDDEV_SAMP: "STDDEV_SAMP" >
|   < STREAM: "STREAM" >
|   < STRING_AGG: "STRING_AGG" >
|   < STRUCTURE: "STRUCTURE" >
|   < STYLE: "STYLE" >
|   < SUBCLASS_ORIGIN: "SUBCLASS_ORIGIN" >
|   < SUBMULTISET: "SUBMULTISET" >
|   < SUBSET: "SUBSET" >
|   < SUBSTITUTE: "SUBSTITUTE" >
|   < SUBSTRING: "SUBSTRING" >
|   < SUBSTRING_REGEX: "SUBSTRING_REGEX" >
|   < SUCCEEDS: "SUCCEEDS" >
|   < SUM: "SUM" >
|   < SUNDAY: "SUNDAY" >
|   < SYMMETRIC: "SYMMETRIC" >
|   < SYSTEM: "SYSTEM" >
|   < SYSTEM_TIME: "SYSTEM_TIME" >
|   < SYSTEM_USER: "SYSTEM_USER" >
|   < TABLE: "TABLE" > { beforeTableName(); }
|   < TABLE_NAME: "TABLE_NAME" >
|   < TABLESAMPLE: "TABLESAMPLE" >
|   < TEMPORARY: "TEMPORARY" >
|   < THEN: "THEN" >
|   < THURSDAY: "THURSDAY" >
|   < TIES: "TIES" >
|   < TIME: "TIME" >
|   < TIME_DIFF: "TIME_DIFF" >
|   < TIME_TRUNC: "TIME_TRUNC" >
|   < TIMESTAMP: "TIMESTAMP" >
|   < TIMESTAMPADD: "TIMESTAMPADD" >
|   < TIMESTAMPDIFF: "TIMESTAMPDIFF" >
|   < TIMESTAMP_DIFF: "TIMESTAMP_DIFF" >
|   < TIMESTAMP_TRUNC: "TIMESTAMP_TRUNC" >
|   < TIMEZONE_HOUR: "TIMEZONE_HOUR" >
|   < TIMEZONE_MINUTE: "TIMEZONE_MINUTE" >
|   < TINYINT: "TINYINT" >
|   < TO: "TO" >
|   < TOP_LEVEL_COUNT: "TOP_LEVEL_COUNT" >
|   < TRAILING: "TRAILING" >
|   < TRANSACTION: "TRANSACTION" >
|   < TRANSACTIONS_ACTIVE: "TRANSACTIONS_ACTIVE" >
|   < TRANSACTIONS_COMMITTED: "TRANSACTIONS_COMMITTED" >
|   < TRANSACTIONS_ROLLED_BACK: "TRANSACTIONS_ROLLED_BACK" >
|   < TRANSFORM: "TRANSFORM" >
|   < TRANSFORMS: "TRANSFORMS" >
|   < TRANSLATE: "TRANSLATE" >
|   < TRANSLATE_REGEX: "TRANSLATE_REGEX" >
|   < TRANSLATION: "TRANSLATION" >
|   < TREAT: "TREAT" >
|   < TRIGGER: "TRIGGER" >
|   < TRIGGER_CATALOG: "TRIGGER_CATALOG" >
|   < TRIGGER_NAME: "TRIGGER_NAME" >
|   < TRIGGER_SCHEMA: "TRIGGER_SCHEMA" >
|   < TRIM: "TRIM" >
|   < TRIM_ARRAY: "TRIM_ARRAY" >
|   < TRUE: "TRUE" >
|   < TRUNCATE: "TRUNCATE" >
|   < TUESDAY: "TUESDAY" >
|   < TUMBLE: "TUMBLE" >
|   < TYPE: "TYPE" >
|   < UESCAPE: "UESCAPE" >
|   < UNBOUNDED: "UNBOUNDED" >
|   < UNCOMMITTED: "UNCOMMITTED" >
|   < UNCONDITIONAL: "UNCONDITIONAL" >
|   < UNDER: "UNDER" >
|   < UNION: "UNION" >
|   < UNIQUE: "UNIQUE" >
|   < UNKNOWN: "UNKNOWN" >
|   < UNPIVOT: "UNPIVOT" >
|   < UNNAMED: "UNNAMED" >
|   < UNNEST: "UNNEST" >
|   < UPDATE: "UPDATE" > { beforeTableName(); }
|   < UPPER: "UPPER" >
|   < UPSERT: "UPSERT" >
|   < USAGE: "USAGE" >
|   < USER: "USER" >
|   < USER_DEFINED_TYPE_CATALOG: "USER_DEFINED_TYPE_CATALOG" >
|   < USER_DEFINED_TYPE_CODE: "USER_DEFINED_TYPE_CODE" >
|   < USER_DEFINED_TYPE_NAME: "USER_DEFINED_TYPE_NAME" >
|   < USER_DEFINED_TYPE_SCHEMA: "USER_DEFINED_TYPE_SCHEMA" >
|   < USING: "USING" >
|   < UTF8: "UTF8" >
|   < UTF16: "UTF16" >
|   < UTF32: "UTF32" >
|   < VALUE: "VALUE" >
|   < VALUES: "VALUES" > { afterTableName(); }
|   < VALUE_OF: "VALUE_OF" >
|   < VAR_POP: "VAR_POP" >
|   < VAR_SAMP: "VAR_SAMP" >
|   < VARBINARY: "VARBINARY" >
|   < VARCHAR: "VARCHAR" >
|   < VARYING: "VARYING" >
|   < VERSION: "VERSION" >
|   < VERSIONING: "VERSIONING" >
|   < VIEW: "VIEW" >
|   < WEDNESDAY: "WEDNESDAY" >
|   < WEEK: "WEEK" >
|   < WEEKS: "WEEKS" >
|   < WHEN: "WHEN" >
|   < WHENEVER: "WHENEVER" >
|   < WHERE: "WHERE" >
|   < WIDTH_BUCKET: "WIDTH_BUCKET" >
|   < WINDOW: "WINDOW" >
|   < WITH: "WITH" >
|   < WITHIN: "WITHIN" >
|   < WITHOUT: "WITHOUT" >
|   < WORK: "WORK" >
|   < WRAPPER: "WRAPPER" >
|   < WRITE: "WRITE" >
|   < XML: "XML" >
|   < YEAR: "YEAR" >
|   < YEARS: "YEARS" >
|   < ZONE: "ZONE" >
<#-- additional parser keywords are included here -->
<#list (parser.keywords!default.parser.keywords) as keyword>
|   < ${keyword}: "${keyword}" >
</#list>
}

/**
 * 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
 */
String NonReservedKeyWord() :
{
}
{
    (
        NonReservedKeyWord0of3()
    |   NonReservedKeyWord1of3()
    |   NonReservedKeyWord2of3()
    )
    {
        return unquotedIdentifier();
    }
}

/** @see #NonReservedKeyWord */
void NonReservedKeyWord0of3() :
{
}
{
    (
<#list (parser.nonReservedKeywords!default.parser.nonReservedKeywords) + (parser.nonReservedKeywordsToAdd!default.parser.nonReservedKeywordsToAdd) as keyword>
<#if keyword?index == 0>
        <${keyword}>
<#elseif keyword?index % 3 == 0>
    |   <${keyword}>
</#if>
</#list>
    )
}

/** @see #NonReservedKeyWord */
void NonReservedKeyWord1of3() :
{
}
{
    (
<#list (parser.nonReservedKeywords!default.parser.nonReservedKeywords) + (parser.nonReservedKeywordsToAdd!default.parser.nonReservedKeywordsToAdd) as keyword>
<#if keyword?index == 1>
        <${keyword}>
<#elseif keyword?index % 3 == 1>
    |   <${keyword}>
</#if>
</#list>
    )
}

/** @see #NonReservedKeyWord */
void NonReservedKeyWord2of3() :
{
}
{
    (
<#list (parser.nonReservedKeywords!default.parser.nonReservedKeywords) + (parser.nonReservedKeywordsToAdd!default.parser.nonReservedKeywordsToAdd) as keyword>
<#if keyword?index == 2>
        <${keyword}>
<#elseif keyword?index % 3 == 2>
    |   <${keyword}>
</#if>
</#list>
    )
}

/* LITERALS */

<DEFAULT, DQID, BTID, BQID, BQHID> TOKEN :
{
    < UNSIGNED_INTEGER_LITERAL: (["0"-"9"])+ >
|
    < APPROX_NUMERIC_LITERAL:
    (<UNSIGNED_INTEGER_LITERAL> | <DECIMAL_NUMERIC_LITERAL>) <EXPONENT> >
|
    < DECIMAL_NUMERIC_LITERAL:
    (["0"-"9"])+(".")?(["0"-"9"])*
    | "."(["0"-"9"])+
    >
|
    < #EXPONENT: ["e","E"] (["+","-"])? (["0"-"9"])+ >
|
    < #HEXDIGIT: ["0"-"9","a"-"f","A"-"F"] >
|
    < #WHITESPACE:
    [ " ","\t","\n","\r","\f" ]
    >
|
    /* To improve error reporting, we allow all kinds of characters,
     * not just hexits, in a binary string literal. */
    < BINARY_STRING_LITERAL: ["x","X"] <QUOTE> ( (~["'"]) | ("''"))* <QUOTE> >
}

// All databases except BigQuery support standard single-quoted literals,
// which use single-quote as the escape character.
<DEFAULT, DQID, BTID> TOKEN :
{
    < QUOTED_STRING: <QUOTE> ( (~["'"]) | ("''"))* <QUOTE> >
|
    < PREFIXED_STRING_LITERAL: ("_" <CHARSETNAME> | "N") <QUOTED_STRING> >
|
    < UNICODE_STRING_LITERAL: "U" "&" <QUOTED_STRING> >
|
    < C_STYLE_ESCAPED_STRING_LITERAL: "E" <QUOTE> ( (~["'", "\\"]) | ("\\" ~[]) | "''")* <QUOTE> >
|
    < #CHARSETNAME: (["a"-"z","A"-"Z","0"-"9"])
    (["a"-"z","A"-"Z","0"-"9",":",".","-","_"])*
    >
}

// BigQuery supports single- and double-quoted literals with back-slash
// as the escape character.
<BQID, BQHID> TOKEN :
{
    // BigQuery-style double-quoted string, escaped using backslash
    < BIG_QUERY_DOUBLE_QUOTED_STRING:
      <DOUBLE_QUOTE> ( (~["\\", "\""]) | ("\\" ~[]) )* <DOUBLE_QUOTE>
    >
|
    // BigQuery-style single-quoted string, escaped using backslash
    < BIG_QUERY_QUOTED_STRING:
      <QUOTE> ( (~["\\", "'"]) | ("\\" ~[]) )* <QUOTE>
    >
}

<DEFAULT, DQID, BTID, BQID, BQHID> TOKEN :
{
    < UNICODE_QUOTED_ESCAPE_CHAR:
    <QUOTE>
    (~["0"-"9","a"-"f","A"-"F","+","\""," ","\t","\n","\r","\f"])
    <QUOTE>
    >
}

/* SEPARATORS */

<DEFAULT, DQID, BTID, BQID, BQHID> TOKEN :
{
    < LPAREN: "(">
|   < RPAREN: ")">
<#if (parser.includeBraces!default.parser.includeBraces) >
|   < LBRACE_D: "{" (" ")* ["d","D"] >
|   < LBRACE_T: "{" (" ")* ["t","T"] >
|   < LBRACE_TS: "{" (" ")* ["t","T"] ["s","S"] >
|   < LBRACE_FN: "{" (" ")* ["f","F"] ["n","N"] >
|   < LBRACE: "{" >
|   < RBRACE: "}" >
<#else>
<#include "/@includes/braces.ftl" />
</#if>
|   < LBRACKET: "[" >
|   < RBRACKET: "]" >
|   < SEMICOLON: ";" >
|   < DOT: "." >
|   < COMMA: "," >
}

/* OPERATORS */

<DEFAULT, DQID, BTID, BQID, BQHID> TOKEN :
{
    < EQ: "=" >
|   < GT: ">" >
|   < LT: "<" >
|   < HOOK: "?" >
|   < COLON: ":" >
|   < LE: "<=" >
|   < GE: ">=" >
|   < NE: "<>" >
|   < NE2: "!=" >
|   < PLUS: "+" >
|   < MINUS: "-" >
|   < STAR: "*" >
|   < SLASH: "/" >
|   < PERCENT_REMAINDER: "%" >
|   < CONCAT: "||" >
|   < NAMED_ARGUMENT_ASSIGNMENT: "=>" >
|   < DOUBLE_PERIOD: ".." >
|   < QUOTE: "'" >
|   < DOUBLE_QUOTE: "\"" >
|   < VERTICAL_BAR: "|" >
|   < CARET: "^" >
|   < DOLLAR: "$" >
<#list (parser.binaryOperatorsTokens!default.parser.binaryOperatorsTokens) as operator>
|   ${operator}
</#list>
}


/*****************************************
 * Lexical Descriptions                  *
 *****************************************/

TOKEN_MGR_DECLS : {
    final List<Integer> lexicalStateStack = new ArrayList<Integer>();

    void pushState() {
      lexicalStateStack.add(curLexState);
    }

    void popState() {
      SwitchTo(lexicalStateStack.remove(lexicalStateStack.size() - 1));
    }

    void beforeTableName() {
      if (curLexState == BQID) {
        pushState();
        SwitchTo(BQHID);
      }
    }

    void afterTableName() {
      if (curLexState == BQHID) {
        popState();
      }
    }

<#if (parser.includeAdditionalDeclarations!default.parser.includeAdditionalDeclarations)>
  <#include "/@includes/tokenManagerDeclarations.ftl" />
</#if>
}

/*
Lexical states:

DEFAULT: Identifiers are quoted in brackets, e.g. [My Identifier]
DQID:    Identifiers are double-quoted, e.g. "My Identifier"
BTID:    Identifiers are enclosed in back-ticks, escaped using back-ticks,
         e.g. `My ``Quoted`` Identifier`
BQID:    Identifiers are enclosed in back-ticks, escaped using backslash,
         e.g. `My \`Quoted\` Identifier`,
         and with the potential to shift into BQHID in contexts where table
         names are expected, and thus allow hyphen-separated identifiers as
         part of table names
BQHID:   Identifiers are enclosed in back-ticks, escaped using backslash,
         e.g. `My \`Quoted\` Identifier`
         and unquoted identifiers may contain hyphens, e.g. foo-bar
IN_SINGLE_LINE_COMMENT:
IN_FORMAL_COMMENT:
IN_MULTI_LINE_COMMENT:

DEFAULT, DQID, BTID, BQID are the 4 'normal states'. Behavior is identical
except for how quoted identifiers are recognized.

The BQHID state exists only at the start of a table name (e.g. immediately after
FROM or INSERT INTO). As soon as an identifier is seen, the state shifts back
to BTID.

After a comment has completed, the lexer returns to the previous state, one
of the 'normal states'.
*/

/* WHITE SPACE */

<DEFAULT, DQID, BTID, BQID, BQHID> SKIP :
{
    " "
|   "\t"
|   "\n"
|   "\r"
|   "\f"
}

/* COMMENTS */

<DEFAULT, DQID, BTID, BQID, BQHID> TOKEN :
{
    < HINT_BEG: "/*+">
|   < COMMENT_END: "*/" >
}

<DEFAULT, DQID, BTID, BQID, BQHID> MORE :
{
    <"/**" ~["/"]> { pushState(); } : IN_FORMAL_COMMENT
}

<DEFAULT, DQID, BTID, BQID, BQHID> MORE :
{
    "/*" { pushState(); } : IN_MULTI_LINE_COMMENT
}

<DEFAULT, DQID, BTID, BQID, BQHID> SKIP :
{
    <SINGLE_LINE_COMMENT: ("//"|"--")(~["\n","\r"])* ("\n"|"\r"|"\r\n")? >
}

<IN_FORMAL_COMMENT>
SPECIAL_TOKEN :
{
    <FORMAL_COMMENT: <COMMENT_END> > { popState(); }
}

<IN_MULTI_LINE_COMMENT>
SPECIAL_TOKEN :
{
    <MULTI_LINE_COMMENT: <COMMENT_END> > { popState(); }
}

<IN_FORMAL_COMMENT,IN_MULTI_LINE_COMMENT>
MORE :
{
    < ~[] >
}


/* IDENTIFIERS */

<DEFAULT> TOKEN :
{
    < BRACKET_QUOTED_IDENTIFIER:
    "["
    (
        (~["]","\n","\r"])
    |
        ("]]")
    )+
    "]"
    >
}

<DQID> TOKEN :
{
    < QUOTED_IDENTIFIER:
    "\""
    (
        (~["\"","\n","\r"])
    |
        ("\"\"")
    )+
    "\""
    >
}

<BTID> TOKEN :
{
    < BACK_QUOTED_IDENTIFIER:
    "`"
    (
        (~["`","\n","\r"])
    |
        ("``")
    )+
    "`"
    >
}

<BQID, BQHID> TOKEN :
{
    // BigQuery-style backtick-quoted identifier, escaped using backslash
    < BIG_QUERY_BACK_QUOTED_IDENTIFIER:
    "`"
    (
        (~["\\", "`"])
    |
        ("\\" ~[])
    )*
    "`"
    >
}

<BQHID> TOKEN :
{
    // Per BigQuery: "Project IDs must contain 6-63 lowercase letters, digits,
    // or dashes. IDs must start with a letter and may not end with a dash."
    // We do not restrict length, or prevent identifiers from ending in a dash.
    < HYPHENATED_IDENTIFIER: <LETTER> (<LETTER>|<DIGIT>|"-")* > { popState(); }
}

<DEFAULT, DQID, BTID, BQID> TOKEN :
{
    < IDENTIFIER: <LETTER> (<LETTER>|<DIGIT>)* >
}

<DEFAULT, DQID, BTID, BQID, BQHID> TOKEN :
{
    < COLLATION_ID:
    (<LETTER>|<DIGIT>)+ (<LETTER>|<DIGIT>|":"|"."|"-"|"_")*
    "$"
    (<LETTER>|"_")+
    ("$" (<LETTER>|<DIGIT>|"_")+)?
    >
|
    < UNICODE_QUOTED_IDENTIFIER: "U" "&" <QUOTED_IDENTIFIER> >
|
    < #LETTER:
    [
        "\u0024",
        "\u0041"-"\u005a",
        "\u005f",
        "\u0061"-"\u007a",
        "\u00c0"-"\u00d6",
        "\u00d8"-"\u00f6",
        "\u00f8"-"\u00ff",
        "\u0100"-"\u1fff",
        "\u3040"-"\u318f",
        "\u3300"-"\u337f",
        "\u3400"-"\u3d2d",
        "\u4e00"-"\u9fff",
        "\uf900"-"\ufaff"
    ]
    >
|
    < #DIGIT:
    [
        "\u0030"-"\u0039",
        "\u0660"-"\u0669",
        "\u06f0"-"\u06f9",
        "\u0966"-"\u096f",
        "\u09e6"-"\u09ef",
        "\u0a66"-"\u0a6f",
        "\u0ae6"-"\u0aef",
        "\u0b66"-"\u0b6f",
        "\u0be7"-"\u0bef",
        "\u0c66"-"\u0c6f",
        "\u0ce6"-"\u0cef",
        "\u0d66"-"\u0d6f",
        "\u0e50"-"\u0e59",
        "\u0ed0"-"\u0ed9",
        "\u1040"-"\u1049"
    ]
    >
}

/* Special token to throw a wrench in the works. It is never valid in SQL,
   and so when it occurs, it causes the parser to print which tokens would
   have been valid at that point. Used by SqlAdvisor. */
<DEFAULT, DQID, BTID, BQID, BQHID> TOKEN :
{
    < BEL:
    [
        "\u0007"
    ]
    >
}

/**
 * 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.
 */
void UnusedExtension() :
{
}
{
    (
        LOOKAHEAD({false}) <ZONE>
    )
}
