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

// Copied from Calcite 1.40.0 and modified for Pinot syntax. Update this file when upgrading Calcite version.
// Modified parts are marked with "PINOT CUSTOMIZATION START/END".

<@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.SqlAsofJoin;
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.SqlLambda;
import org.apache.calcite.sql.SqlLiteral;
import org.apache.calcite.sql.SqlMatchRecognize;
import org.apache.calcite.sql.SqlMerge;
import org.apache.calcite.sql.SqlMapTypeNameSpec;
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.sql.validate.SqlConformanceEnum;
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 final BigDecimal ONE_HUNDRED = BigDecimal.valueOf(100L);

    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);
                parser.jj_input_stream.ReInit(reader, 1, 1, sql.length());
            }
          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) :
{
    final String error;
}
{
    // Postgres-style syntax. "LIMIT ... OFFSET ..."
    <LIMIT> { s.add(this); }
    (
        // MySQL-style syntax. "LIMIT start, count" or "LIMIT start, ALL"
        LOOKAHEAD(2)
        offsetFetch[0] = UnsignedNumericLiteralOrParam()
        <COMMA>
        (
            offsetFetch[1] = UnsignedNumericLiteralOrParam() {
                error = "count";
            }
        |
            <ALL> {
                error = "ALL";
            }
        ) {
            if (!this.conformance.isLimitStartCountAllowed()) {
                throw SqlUtil.newContextException(s.end(this),
                    RESOURCE.limitStartCountOrAllNotAllowed(error));
            }
        }
    |
        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((SimpleIdentifierOrList() | <LPAREN> <RPAREN>) <LAMBDA>)
        e = LambdaExpression()
    |
        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()
    |
        LOOKAHEAD((SimpleIdentifierOrList() | <LPAREN> <RPAREN>) <LAMBDA>)
        e = LambdaExpression()
    |
        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 = ${parser.setOptionParserMethod!default.parser.setOptionParserMethod}(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>
<#if (parser.truncateStatementParserMethods!default.parser.truncateStatementParserMethods)?size != 0>
        LOOKAHEAD(2)
        stmt = SqlTruncate()
    |
</#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.isEmpty()) {
                tableRef = extend(tableRef, p.right);
            }
            if (!p.left.isEmpty()) {
                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 = CompoundIdentifier() {
        targetColumnList.add(id);
    }
    // TODO:  support DEFAULT also
    <EQ> AddExpression(sourceExpressionList, ExprContext.ACCEPT_SUB_QUERY)
    (
        <COMMA>
        id = CompoundIdentifier() { 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) :
{
    SqlNode e;
    final SqlIdentifier id;
}
{
    e = SelectExpression()
    (
        [ <AS>
            [ <MEASURE> {
                    e = SqlInternalOperators.MEASURE.createCall(
                        e.getParserPosition(), e);
                }
            ]
        ]
        (
            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;
    boolean asof = false;
}
{
    (
<#list (parser.joinTypes!default.parser.joinTypes) as method>
        LOOKAHEAD(3) // required for "LEFT SEMI JOIN" and "LEFT ANTI JOIN" in Babel
        joinType = ${method}()
    |
</#list>
        <JOIN> { joinType = JoinType.INNER; }
    |
        <INNER> <JOIN> { joinType = JoinType.INNER; }
    |
        <ASOF> <JOIN> { joinType = JoinType.ASOF; }
    |
        <LEFT> [ <OUTER> | <ASOF> { asof = true; } ] <JOIN> { joinType = asof ? JoinType.LEFT_ASOF : 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 = TableRef1(ExprContext.ACCEPT_QUERY_OR_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)
        e = JoinOrCommaTable(e)
    )*
    { return e; }
}

SqlNode JoinOrCommaTable(SqlNode e) :
{
    SqlNode e2;
    SqlLiteral joinType;
}
{
    LOOKAHEAD(2)
    <COMMA> { joinType = JoinType.COMMA.symbol(getPos()); }
    e2 = TableRef1(ExprContext.ACCEPT_QUERY_OR_JOIN) {
        return new SqlJoin(joinType.getParserPosition(),
            e,
            SqlLiteral.createBoolean(false, joinType.getParserPosition()),
            joinType,
            e2,
            JoinConditionType.NONE.symbol(SqlParserPos.ZERO),
            null);
    }
|
    e2 = JoinTable(e) { return e2; }
}

/** Matches "LEFT JOIN t ON ...", "RIGHT JOIN t USING ...", "JOIN t". */
SqlNode JoinTable(SqlNode e) :
{
    SqlNode e2, condition, matchCondition = null;
    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(4)
    natural = Natural()
    joinType = JoinType()
    e2 = TableRef1(ExprContext.ACCEPT_QUERY_OR_JOIN)
    (
        [ <MATCH_CONDITION> matchCondition = Expression(ExprContext.ACCEPT_SUB_QUERY) ]
        <ON> { on = JoinConditionType.ON.symbol(getPos()); }
        condition = Expression(ExprContext.ACCEPT_SUB_QUERY) {
            JoinType type = joinType.getValueAs(JoinType.class);
            if (matchCondition != null) {
                if (type != JoinType.ASOF && type != JoinType.LEFT_ASOF) {
                    throw SqlUtil.newContextException(getPos(), RESOURCE.matchConditionRequiresAsof());
                }
                return new SqlAsofJoin(joinType.getParserPosition(),
                    e,
                    natural,
                    joinType,
                    e2,
                    on,
                    condition,
                    matchCondition);
            } else {
                if (type == JoinType.ASOF || type == JoinType.LEFT_ASOF) {
                    throw SqlUtil.newContextException(getPos(), RESOURCE.asofRequiresMatchCondition());
                }
            }
            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() { s = span(); }
        (
            // Table call syntax like FROM a.b() instead of FROM TABLE(a.b())
            // Three tokens needed to disambiguate EXTEND syntax from CALCITE-493.
            // Example: "FROM EventLog(lastGCTime TIME)".
            LOOKAHEAD(3)
            tableRef = ImplicitTableFunctionCallArgs(tableName)
        |
            ( 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) ]
    |
        LOOKAHEAD(2)
        [ <LATERAL> ] // "LATERAL" is implicit with "UNNEST", so ignore
        <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));
            return 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;
            }
        ]
        {
            BigDecimal rate =
                samplePercentage.bigDecimalValue().divide(ONE_HUNDRED);
            SqlSampleSpec tableSampleSpec =
                isRepeatable
                    ? SqlSampleSpec.createTableSample(isBernoulli, rate,
                        repeatableSeed)
                    : SqlSampleSpec.createTableSample(isBernoulli, rate);
            SqlLiteral tableSampleLiteral =
                SqlLiteral.createSample(tableSampleSpec, s.end(this));
            return SqlStdOperatorTable.TABLESAMPLE.createCall(
                s.end(this), tableRef, tableSampleLiteral);
        }
    )
}

/** 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 ImplicitTableFunctionCallArgs(SqlIdentifier name) :
{
    final List<SqlNode> tableFuncArgs = new ArrayList<SqlNode>();
    final SqlNode call;
    final Span s;
}
{
    // Table call syntax like FROM a.b() instead of FROM TABLE(a.b())
    // We've already parsed the name, so we don't use NamedRoutineCall.
    { s = span(); }
    <LPAREN>
    [
        AddArg0(tableFuncArgs, ExprContext.ACCEPT_CURSOR)
        (
            <COMMA> {
                // a comma-list can't appear where only a query is expected
                checkNonQueryExpression(ExprContext.ACCEPT_CURSOR);
            }
            AddArg(tableFuncArgs, ExprContext.ACCEPT_CURSOR)
        )*
    ]
    <RPAREN>
    {
        final SqlParserPos pos = s.end(this);
        call = createCall(name, pos,
            SqlFunctionCategory.USER_DEFINED_TABLE_FUNCTION, null,
            tableFuncArgs);
        return SqlStdOperatorTable.COLLECTION_TABLE.createCall(pos,
            call);
    }
}

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 SqlLiteral exclude;
    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; }
        )
        exclude = WindowExclusion()
    |
        {
            isRows = SqlLiteral.createBoolean(false, SqlParserPos.ZERO);
            exclude = SqlWindow.createExcludeNoOthers(getPos());
            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, exclude, 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 an exclusion clause for WINDOW FRAME. */
SqlLiteral WindowExclusion() :
{
}
{
    (
        <EXCLUDE>
        (
            <CURRENT> <ROW> { return SqlWindow.createExcludeCurrentRow(getPos()); }
        |
            <NO> <OTHERS> { return SqlWindow.createExcludeNoOthers(getPos()); }
        |
            <GROUP> { return SqlWindow.createExcludeGroup(getPos()); }
        |
            <TIES> { return SqlWindow.createExcludeTies(getPos()); }
        )
    |
        { return SqlWindow.createExcludeNoOthers(SqlParserPos.ZERO); }
    )
}

/** 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>();
    boolean recursive = false;
}
{
    <WITH> [ <RECURSIVE> { recursive = true; } ]{ s = span(); }
    AddWithItem(list, SqlLiteral.createBoolean(recursive, getPos()))
    ( <COMMA> AddWithItem(list, SqlLiteral.createBoolean(recursive, getPos())) )*
    { return new SqlNodeList(list, s.end(this)); }
}

void AddWithItem(List<SqlWithItem> list, SqlLiteral recursive) :
{
    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, recursive)); }
}

/**
 * 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 itemOp;
    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>
                ( <OFFSET> { itemOp = SqlLibraryOperators.OFFSET; } <LPAREN> { e = Expression(ExprContext.ACCEPT_SUB_QUERY); } <RPAREN>
                | <ORDINAL> { itemOp = SqlLibraryOperators.ORDINAL; } <LPAREN> { e = Expression(ExprContext.ACCEPT_SUB_QUERY); } <RPAREN>
                | <SAFE_OFFSET> { itemOp = SqlLibraryOperators.SAFE_OFFSET; } <LPAREN> { e = Expression(ExprContext.ACCEPT_SUB_QUERY); } <RPAREN>
                | <SAFE_ORDINAL> { itemOp = SqlLibraryOperators.SAFE_ORDINAL; } <LPAREN> { e = Expression(ExprContext.ACCEPT_SUB_QUERY); } <RPAREN>
                | { itemOp = SqlStdOperatorTable.ITEM; } e = Expression(ExprContext.ACCEPT_SUB_QUERY)
                )
                <RBRACKET> {
                    list.add(
                        new SqlParserUtil.ToTreeListItem(
                            itemOp, 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).clone(list1.getParserPosition());
        } else {
            // interpret as row constructor
            return SqlStdOperatorTable.ROW.createCall(span().end(list1),
                (List<SqlNode>) list1);
        }
    }
}

/**
 * Parses a lambda expression.
 */
SqlNode LambdaExpression() :
{
    final SqlNodeList parameters;
    final SqlNode expression;
    final Span s;
}
{
    parameters = SimpleIdentifierOrListOrEmpty()
    <LAMBDA> { s = span(); }
    expression = Expression(ExprContext.ACCEPT_NON_QUERY)
    {
        return new SqlLambda(s.end(this), parameters, expression);
    }
}

/**
 * List of simple identifiers in parentheses or empty parentheses or one simple identifier.
 * <ul>Examples:
 * <li>{@code ()}
 * <li>{@code DEPTNO}
 * <li>{@code (EMPNO, DEPTNO)}
 * </ul>
 */
SqlNodeList SimpleIdentifierOrListOrEmpty() :
{
    SqlNodeList list;
}
{
    LOOKAHEAD(2)
    <LPAREN> <RPAREN> { return SqlNodeList.EMPTY; }
|
    list = SimpleIdentifierOrList() { return list; }
}

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 both the standard and the BigQuery PERCENTILE_CONT/PERCENTILE_DISC
 * functions.
 *
 * <p>The standard is of the form "PERCENTILE_CONT(fraction)" while BigQuery is
 * of the form "PERCENTILE_CONT(value, fraction [ {RESPECT | IGNORE} NULLS ] )".
 * Handles the parsing of the operator and its operands but not the WITHIN GROUP
 * (for the standard) or OVER (for BigQuery) clauses.
 */
SqlCall PercentileFunctionCall() :
{
   final Span s;
   SqlOperator op;
   final SqlNode e;
   final List<SqlNode> args = new ArrayList<SqlNode>();
   final Pair<SqlParserPos, SqlOperator> nullTreatment;
}
{
   (
       <PERCENTILE_CONT> { op = SqlStdOperatorTable.PERCENTILE_CONT; }
   |   <PERCENTILE_DISC> { op = SqlStdOperatorTable.PERCENTILE_DISC; }
   )
   { s = span(); }
   <LPAREN>
   AddArg(args, ExprContext.ACCEPT_SUB_QUERY)
   (
       <RPAREN> {
           return op.createCall(s.end(this), args);
       }
   |
       <COMMA>
       e = NumericLiteral() { args.add(e); }
       (
           nullTreatment = NullTreatment()
       |   { nullTreatment = null; }
       )
       <RPAREN>
       {
           op =
               op == SqlStdOperatorTable.PERCENTILE_CONT
                   ? SqlLibraryOperators.PERCENTILE_CONT2
                   : SqlLibraryOperators.PERCENTILE_DISC2;
           SqlCall call = op.createCall(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, (SqlNode) 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, (SqlNode) 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 = ${parser.setOptionParserMethod!default.parser.setOptionParserMethod}(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>

<#if (parser.truncateStatementParserMethods!default.parser.truncateStatementParserMethods)?size != 0>
/**
 * Parses a TRUNCATE statement.
 */
SqlTruncate SqlTruncate() :
{
    final Span s;
    final SqlTruncate truncate;
}
{
    <TRUNCATE> { s = span(); }
    (
<#-- additional literal parser methods are included here -->
<#list (parser.truncateStatementParserMethods!default.parser.truncateStatementParserMethods) as method>
        truncate = ${method}(s)
        <#sep>|</#sep>
</#list>
    )
    {
        return truncate;
    }
}
</#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() :
{
final String p;
}
{
    <UNSIGNED_INTEGER_LITERAL> {
        return SqlLiteral.createExactNumeric(token.image, getPos());
    }
|
    <DECIMAL_NUMERIC_LITERAL> {
        return SqlLiteral.createExactNumeric(token.image, getPos());
    }
|
    <DECIMAL>
    p = SimpleStringLiteral() {
        return SqlParserUtil.parseDecimalLiteral(SqlParserUtil.trim(p, " "), 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;
    boolean local = false;
}
{
    <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));
    }
|
    LOOKAHEAD(2)
    <TIME> { s = span(); } p = SimpleStringLiteral() {
      return SqlLiteral.createUnknown("TIME", p, s.end(this));
    }
|
    LOOKAHEAD(2)
    <UUID> { s = span(); } p = SimpleStringLiteral() {
        return SqlLiteral.createUnknown("UUID", p, s.end(this));
    }
|
    LOOKAHEAD(2)
    <TIMESTAMP> { s = span(); } p = SimpleStringLiteral() {
        return SqlLiteral.createUnknown("TIMESTAMP", p, s.end(this));
    }
|
    LOOKAHEAD(2)
    <TIME> { s = span(); } <WITH> ( <LOCAL> { local = true; } )? <TIME> <ZONE> p = SimpleStringLiteral() {
        return SqlLiteral.createUnknown("TIME WITH " + (local ? "LOCAL " : "") + "TIME ZONE", p, s.end(this));
    }
|
    LOOKAHEAD(2)
    <TIMESTAMP> { s = span(); } <WITH> ( <LOCAL> { local = true; } )? <TIME> <ZONE> p = SimpleStringLiteral() {
        return SqlLiteral.createUnknown("TIMESTAMP WITH " + (local ? "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() :
{
    final SqlNodeList args;
    SqlNode e;
    final Span s;
    final String p;
}
{
    <ARRAY> { s = span(); }
    (
        (
            // nullary array function call: "array()" (Apache Spark)
            LOOKAHEAD(2)
            <LPAREN> <RPAREN> { args = SqlNodeList.EMPTY; }
        |
            args = ParenthesizedQueryOrCommaList(ExprContext.ACCEPT_ALL)
        )
        {
            if (args.size() == 1 && args.get(0).isA(SqlKind.QUERY)) {
                // Array query constructor, 'ARRAY (SELECT * FROM t)'
                return SqlStdOperatorTable.ARRAY_QUERY.createCall(s.end(this), args.get(0));
            } else {
                // Spark ARRAY function, 'ARRAY(1, 2)',
                // equivalent to standard 'ARRAY [1, 2]'
                return SqlLibraryOperators.ARRAY.createCall(s.end(this), args.getList());
            }
        }
    |
        // by enumeration "ARRAY[e0, e1, ..., eN]"
        <LBRACKET> // TODO: do trigraph as well ??( ??)
        (
            args = ExpressionCommaList(s, ExprContext.ACCEPT_SUB_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;
    final Span s;
}
{
    <MAP> { s = span(); }
    (
        (
            // empty map function call: "map()"
            LOOKAHEAD(2)
            <LPAREN> <RPAREN> { args = SqlNodeList.EMPTY; }
        |
            args = ParenthesizedQueryOrCommaList(ExprContext.ACCEPT_ALL)
        )
        {
            if (args.size() == 1 && args.get(0).isA(SqlKind.QUERY)) {
                // MAP query constructor e.g. "MAP (SELECT empno, deptno FROM emps)"
                return SqlStdOperatorTable.MAP_QUERY.createCall(s.end(this), args.get(0));
            } else {
                // MAP function e.g. "MAP(1, 2)" equivalent to standard "MAP[1, 2]"
                return SqlLibraryOperators.MAP.createCall(s.end(this), args.getList());
            }
        }
    |
        // 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()
    |
        LOOKAHEAD(2)
        typeNameSpec = MapTypeName()
    |
        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; }
        // PINOT CUSTOMIZATION START
        ( <BIGINT> | <LONG> ) { s.add(this); sqlTypeName = SqlTypeName.BIGINT; }
        // PINOT CUSTOMIZATION END
    |
        <REAL> { s.add(this); sqlTypeName = SqlTypeName.REAL; }
    |
        <DOUBLE> { s.add(this); }
        [ <PRECISION> ] { sqlTypeName = SqlTypeName.DOUBLE; }
    |
        <FLOAT> { s.add(this); sqlTypeName = SqlTypeName.FLOAT; }
    |
        <VARIANT> { s.add(this); sqlTypeName = SqlTypeName.VARIANT; }
    |
        <UUID> { s.add(this); sqlTypeName = SqlTypeName.UUID; }
    )
    {
        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; }
        // PINOT CUSTOMIZATION START
        (<VARBINARY> | <BYTES>) { s.add(this); sqlTypeName = SqlTypeName.VARBINARY; }
        // PINOT CUSTOMIZATION END
    )
    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 = RelDataType.PRECISION_NOT_SPECIFIED;
    int scale = RelDataType.SCALE_NOT_SPECIFIED;
}
{
    (
        // (<DECIMAL> | <DEC> | <NUMERIC>) { s.add(this); sqlTypeName = SqlTypeName.DECIMAL; }
        // PINOT CUSTOMIZATION START
        (<DECIMAL> | <DEC> | <NUMERIC> | <BIG_DECIMAL>) { s.add(this); sqlTypeName = SqlTypeName.DECIMAL; }
        // PINOT CUSTOMIZATION END
    |
        <ANY> { s.add(this); sqlTypeName = SqlTypeName.ANY; }
    )
    [
        <LPAREN>
        precision = UnsignedIntLiteral()
        [
            <COMMA>
            scale = IntLiteral()
        ]
        <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);
    }
}

SqlTypeNameSpec MapTypeName() :
{
    SqlDataTypeSpec keyType = null;
    SqlDataTypeSpec valType = null;
}
{
    <MAP>
    <LT>
    keyType = DataType()
    <COMMA>
    valType = DataType()
    <GT>
    {
        return new SqlMapTypeNameSpec(keyType, valType, getPos());
    }
}

/**
* 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; }
        // PINOT CUSTOMIZATION START
        (<VARCHAR> | <STRING>) { s.add(this); sqlTypeName = SqlTypeName.VARCHAR; }
        // PINOT CUSTOMIZATION END
    )
    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;
    final Span s;
}
{
    <DATE> {
        typeName = SqlTypeName.DATE;
        return new SqlBasicTypeNameSpec(typeName, getPos());
    }
|
    LOOKAHEAD(2)
    <TIME> { s = span(); }
    precision = PrecisionOpt()
    typeName = TimeZoneOpt(true)
    {
        return new SqlBasicTypeNameSpec(typeName, precision, s.end(this));
    }
|
    <TIMESTAMP> { s = span(); }
    precision = PrecisionOpt()
    typeName = TimeZoneOpt(false)
    {
        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.
* We also support "with local time zone".
*/
SqlTypeName TimeZoneOpt(boolean timeType) :
{
    boolean local = false;
}
{
    LOOKAHEAD(3)
    <WITHOUT> <TIME> <ZONE> { return timeType ? SqlTypeName.TIME : SqlTypeName.TIMESTAMP;  }
|
    <WITH> ( <LOCAL> { local = true; } )? <TIME> <ZONE> {
        return timeType ? (local ? SqlTypeName.TIME_WITH_LOCAL_TIME_ZONE : SqlTypeName.TIME_TZ)
                        : (local ? SqlTypeName.TIMESTAMP_WITH_LOCAL_TIME_ZONE : SqlTypeName.TIMESTAMP_TZ); }
|
    { return timeType ? SqlTypeName.TIME : SqlTypeName.TIMESTAMP; }
}

/**
 * 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;
    final SqlNode format;
}
{
    //~ FUNCTIONS WITH SPECIAL SYNTAX ---------------------------------------
    (
        (  <CAST> { f = SqlStdOperatorTable.CAST; }
        | <SAFE_CAST> { f = SqlLibraryOperators.SAFE_CAST; }
        | <TRY_CAST> { f = SqlLibraryOperators.TRY_CAST; }
        )
        { s = span(); }
        <LPAREN> AddExpression(args, ExprContext.ACCEPT_SUB_QUERY)
        <AS>
        (
            dt = DataType() { args.add(dt); }
        |
            <INTERVAL> e = IntervalQualifier() { args.add(e); }
        )
        [ <FORMAT> format = StringLiteral() { args.add(format); } ]
        <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.TRANSLATE.createCall(s.end(this), args);
                }
            |
                <COMMA> e = SimpleIdentifier() { args.add(e); }
                (
                    <COMMA> e = SimpleIdentifier() { args.add(e); }
                    <RPAREN> {
                        SqlOperator op = SqlStdOperatorTable.getConvertFuncByConformance(this.conformance);
                        return op.createCall(s.end(this), args);
                    }
                |
                    <RPAREN> {
                        return SqlLibraryOperators.CONVERT_ORACLE.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;
            SqlParserPos fromPos = SqlParserPos.ZERO;
            s = span();
        }
        <LPAREN>
        (
            (
                (
                    <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> { fromPos = getPos(); }
                e = Expression(ExprContext.ACCEPT_SUB_QUERY)
            )
            |
            (
                e = Expression(ExprContext.ACCEPT_SUB_QUERY)
                [
                    <FROM> { trimChars = e; fromPos = getPos(); }
                    e = Expression(ExprContext.ACCEPT_SUB_QUERY)
                ]
            )
        )
        <RPAREN> {
            if (flag == null) {
                flag = SqlTrimFunction.Flag.BOTH.symbol(SqlParserPos.ZERO);
            }
            args.add(flag);
            // trimChars can be null
            args.add(trimChars);
            args.add(e);
            return SqlStdOperatorTable.TRIM.createCall(s.end(this), args);
        }
    |
        node = ContainsSubstrFunctionCall() { return node; }
    |
        node = DateTimeConstructorCall() { return node; }
    |
        node = DateDiffFunctionCall() { return node; }
    |
        node = DateTruncFunctionCall() { return node; }
    |
        node = DatetimeTruncFunctionCall() { return node; }
    |
        node = TimestampAddFunctionCall() { return node; }
    |
        node = DatetimeDiffFunctionCall() { 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[6];
    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 = JsonReturningClause() {
            args[5] = e;
        }
    ]
    [
        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>
    |
        <COMMA> {
            if (kvMode) {
                throw SqlUtil.newContextException(getPos(), RESOURCE.illegalComma());
            }
        }
    |
        <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 the CONTAINS_SUBSTR function, which has a unique optional third argument "JSON_SCOPE"
 * that specifies what scope to search if the first argument is a JSON string.
 */
 SqlCall ContainsSubstrFunctionCall() :
 {
    final List<SqlNode> args = new ArrayList<SqlNode>();
    final Span s;
    SqlNode e;
 }
 {
     <CONTAINS_SUBSTR> { s = span(); }
     <LPAREN>
     AddExpression(args, ExprContext.ACCEPT_SUB_QUERY)
     <COMMA>
     AddExpression(args, ExprContext.ACCEPT_SUB_QUERY)
     (
        <RPAREN>
     |
        <COMMA>
        <JSON_SCOPE>
        <NAMED_ARGUMENT_ASSIGNMENT> e = Expression(ExprContext.ACCEPT_SUB_QUERY)  { args.add(e); }
        <RPAREN>
     ) { return SqlLibraryOperators.CONTAINS_SUBSTR.createCall(s.end(this), args); }
 }

/**
 * Parses a call to BigQuery's DATE_DIFF.
 */
SqlCall DateDiffFunctionCall() :
{
    final List<SqlNode> args = new ArrayList<SqlNode>();
    final Span s;
    final SqlIntervalQualifier unit;
}
{
    <DATE_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.DATE_DIFF.createCall(s.end(this), args);
    }
}

/**
 * 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 BigQuery's built-in DATETIME_DIFF() function.
 */
SqlCall DatetimeDiffFunctionCall() :
{
    final List<SqlNode> args = new ArrayList<SqlNode>();
    final Span s;
    final SqlIntervalQualifier unit;
}
{
    <DATETIME_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.DATETIME_DIFF.createCall(s.end(this), args);
    }
}

// PINOT CUSTOMIZATION START

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

/**
 * Pinot custom DATE_TRUNC function.
 *
 * Arguments:
 * 1. Unit of truncation: SECOND, MINUTE, HOUR, DAY, WEEK, MONTH, QUARTER, YEAR.
 * 2. Timestamp column input (or expression), this should always be in the specified units since epoch UTC.
 * 3. Optional input TimeUnit enum. MILLISECONDS by default.
 * 4. Optional truncation time zone as specified in the zone-index.properties file. These timezones are both DateTime
 *    and JodaTime compatible. UTC by default.
 * 5. Optional output TimeUnit enum. Same as input TimeUnit enum by default.
 */
SqlCall DateTruncFunctionCall() :
{
    final List<SqlNode> args = new ArrayList<SqlNode>();
    final Span s;
    final SqlIntervalQualifier unit;
    SqlNode e;
}
{
    <DATE_TRUNC> { s = span(); }
    <LPAREN>
    (
        unit = TimeUnit() { args.add(unit); }
    |
        e = StringLiteral() { args.add(e); }
    )
    <COMMA>
    AddExpression(args, ExprContext.ACCEPT_SUB_QUERY)
    (
        <RPAREN>
    |
        <COMMA>
        e = StringLiteral() { args.add(e); }
        (
            <RPAREN>
        |
            <COMMA>
            e = StringLiteral() { args.add(e); }
            (
                <RPAREN>
            |
                <COMMA>
                e = StringLiteral() { args.add(e); }
                <RPAREN>
            )
        )
    ) {
        return SqlLibraryOperators.DATE_TRUNC.createCall(s.end(this), args);
    }
}
// PINOT CUSTOMIZATION END

/**
 * 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 DATETIME_TRUNC.
 */
SqlNode DatetimeTruncFunctionCall() :
{
    final List<SqlNode> args = new ArrayList<SqlNode>();
    final Span s;
    final SqlIntervalQualifier unit;
    final SqlNode literal;
}
{
    <DATETIME_TRUNC> { s = span(); }
    <LPAREN>
    AddExpression(args, ExprContext.ACCEPT_SUB_QUERY)
    <COMMA>
    unit = TimeUnitOrName() { args.add(unit); }
    <RPAREN> {
        return SqlLibraryOperators.DATETIME_TRUNC.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()
    |
        LOOKAHEAD(1)
        call = PercentileFunctionCall()
    |
        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 = SqlStdOperatorTable.floorCeil(floorFlag, this.conformance);
        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>
    |   <PERCENTILE_CONT>
    |   <PERCENTILE_DISC>
    |   <PERCENT_RANK>
    |   <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 = ContainsSubstrFunctionCall() {
            name = call.getOperator().getName();
            args = new SqlNodeList(call.getOperandList(), getPos());
        }
    |
        LOOKAHEAD(1)
        call = DateDiffFunctionCall() {
            name = call.getOperator().getName();
            args = new SqlNodeList(call.getOperandList(), getPos());
        }
    |
        LOOKAHEAD(1)
        call = DatetimeDiffFunctionCall() {
            name = call.getOperator().getName();
            args = new SqlNodeList(call.getOperandList(), getPos());
        }
    |
        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" >
|   < ASOF: "ASOF" >
|   < 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" >
|   < CONTAINS_SUBSTR: "CONTAINS_SUBSTR" >
|   < 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_DIFF: "DATE_DIFF" >
|   < DATE_TRUNC: "DATE_TRUNC" >
|   < DATETIME: "DATETIME" >
|   < DATETIME_DIFF: "DATETIME_DIFF" >
|   < DATETIME_INTERVAL_CODE: "DATETIME_INTERVAL_CODE" >
|   < DATETIME_INTERVAL_PRECISION: "DATETIME_INTERVAL_PRECISION" >
|   < DATETIME_TRUNC: "DATETIME_TRUNC" >
|   < 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_SCOPE: "JSON_SCOPE" >
|   < 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_CONDITION: "MATCH_CONDITION">
|   < MATCH_NUMBER: "MATCH_NUMBER">
|   < MATCH_RECOGNIZE: "MATCH_RECOGNIZE">
|   < MAX: "MAX" >
|   < MAXVALUE: "MAXVALUE" >
|   < MEASURE: "MEASURE" >
|   < 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" >
|   < ORDINAL: "ORDINAL" >
|   < 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" >
|   < SAFE_OFFSET: "SAFE_OFFSET" >
|   < SAFE_ORDINAL: "SAFE_ORDINAL" >
|   < 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" >
|   < TRY_CAST: "TRY_CAST" >
|   < 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" >
|   < UUID: "UUID" >
|   < VALUE: "VALUE" >
|   < VALUES: "VALUES" > { afterTableName(); }
|   < VALUE_OF: "VALUE_OF" >
|   < VAR_POP: "VAR_POP" >
|   < VAR_SAMP: "VAR_SAMP" >
|   < VARBINARY: "VARBINARY" >
|   < VARCHAR: "VARCHAR" >
|   < VARIANT: "VARIANT" >
|   < 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: "-" >
|   < LAMBDA: "->" >
|   < 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 :
{
    <#if parser.customIdentifierToken?has_content>
        ${parser.customIdentifierToken}
    <#else>
        < IDENTIFIER: <LETTER> (<LETTER>|<DIGIT>)* >
    </#if>
}

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