//
// 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.
//
options {
  COMMON_TOKEN_ACTION = true;
  STATIC = false;
  TOKEN_EXTENDS = "org.apache.asterix.lang.sqlpp.parser.SqlppToken";
}

PARSER_BEGIN(SQLPPParser)

package org.apache.asterix.lang.sqlpp.parser;

// For SQL++ ParserTokenManager
import java.util.ArrayDeque;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Reader;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import org.apache.asterix.common.annotations.AutoDataGen;
import org.apache.asterix.common.annotations.DateBetweenYearsDataGen;
import org.apache.asterix.common.annotations.DatetimeAddRandHoursDataGen;
import org.apache.asterix.common.annotations.DatetimeBetweenYearsDataGen;
import org.apache.asterix.common.annotations.ExternalSubpathAnnotation;
import org.apache.asterix.common.annotations.FieldIntervalDataGen;
import org.apache.asterix.common.annotations.FieldValFileDataGen;
import org.apache.asterix.common.annotations.FieldValFileSameIndexDataGen;
import org.apache.asterix.common.annotations.IRecordFieldDataGen;
import org.apache.asterix.common.annotations.IndexedNLJoinExpressionAnnotation;
import org.apache.asterix.common.annotations.InsertRandIntDataGen;
import org.apache.asterix.common.annotations.ListDataGen;
import org.apache.asterix.common.annotations.ListValFileDataGen;
import org.apache.asterix.common.annotations.RangeAnnotation;
import org.apache.asterix.common.annotations.SecondaryIndexSearchPreferenceAnnotation;
import org.apache.asterix.common.annotations.SkipSecondaryIndexSearchExpressionAnnotation;
import org.apache.asterix.common.annotations.SpatialJoinAnnotation;
import org.apache.asterix.common.annotations.TypeDataGen;
import org.apache.asterix.common.annotations.UndeclaredFieldsDataGen;
import org.apache.asterix.common.config.DatasetConfig.DatasetType;
import org.apache.asterix.common.config.DatasetConfig.IndexType;
import org.apache.asterix.common.exceptions.AsterixException;
import org.apache.asterix.common.exceptions.CompilationException;
import org.apache.asterix.common.exceptions.ErrorCode;
import org.apache.asterix.common.exceptions.WarningCollector;
import org.apache.asterix.common.functions.FunctionConstants;
import org.apache.asterix.common.functions.FunctionSignature;
import org.apache.asterix.common.metadata.DataverseName;
import org.apache.asterix.common.metadata.DatasetFullyQualifiedName;
import org.apache.asterix.external.dataset.adapter.AdapterIdentifier;
import org.apache.asterix.lang.common.base.AbstractClause;
import org.apache.asterix.lang.common.base.AbstractLangExpression;
import org.apache.asterix.lang.common.base.AbstractStatement;
import org.apache.asterix.lang.common.base.Expression;
import org.apache.asterix.lang.common.base.Literal;
import org.apache.asterix.lang.common.base.IParser;
import org.apache.asterix.lang.common.base.ILangExpression;
import org.apache.asterix.lang.common.base.IParserFactory;
import org.apache.asterix.lang.common.base.Statement;
import org.apache.asterix.lang.common.clause.GroupbyClause;
import org.apache.asterix.lang.common.clause.LetClause;
import org.apache.asterix.lang.common.clause.LimitClause;
import org.apache.asterix.lang.common.clause.OrderbyClause;
import org.apache.asterix.lang.common.clause.UpdateClause;
import org.apache.asterix.lang.common.clause.WhereClause;
import org.apache.asterix.lang.common.context.RootScopeFactory;
import org.apache.asterix.lang.common.context.Scope;
import org.apache.asterix.lang.common.expression.AbstractAccessor;
import org.apache.asterix.lang.common.expression.CallExpr;
import org.apache.asterix.lang.common.expression.FieldAccessor;
import org.apache.asterix.lang.common.expression.FieldBinding;
import org.apache.asterix.lang.common.expression.GbyVariableExpressionPair;
import org.apache.asterix.lang.common.expression.IfExpr;
import org.apache.asterix.lang.common.expression.IndexAccessor;
import org.apache.asterix.lang.common.expression.IndexedTypeExpression;
import org.apache.asterix.lang.common.expression.ListConstructor;
import org.apache.asterix.lang.common.expression.ListSliceExpression;
import org.apache.asterix.lang.common.expression.LiteralExpr;
import org.apache.asterix.lang.common.expression.OperatorExpr;
import org.apache.asterix.lang.common.expression.OrderedListTypeDefinition;
import org.apache.asterix.lang.common.expression.QuantifiedExpression;
import org.apache.asterix.lang.common.expression.RecordConstructor;
import org.apache.asterix.lang.common.expression.RecordTypeDefinition;
import org.apache.asterix.lang.common.expression.TypeExpression;
import org.apache.asterix.lang.common.expression.TypeReferenceExpression;
import org.apache.asterix.lang.common.expression.UnaryExpr;
import org.apache.asterix.lang.common.expression.UnorderedListTypeDefinition;
import org.apache.asterix.lang.common.expression.VariableExpr;
import org.apache.asterix.lang.common.literal.DoubleLiteral;
import org.apache.asterix.lang.common.literal.FalseLiteral;
import org.apache.asterix.lang.common.literal.FloatLiteral;
import org.apache.asterix.lang.common.literal.LongIntegerLiteral;
import org.apache.asterix.lang.common.literal.MissingLiteral;
import org.apache.asterix.lang.common.literal.NullLiteral;
import org.apache.asterix.lang.common.literal.StringLiteral;
import org.apache.asterix.lang.common.literal.TrueLiteral;
import org.apache.asterix.lang.common.parser.ScopeChecker;
import org.apache.asterix.lang.common.statement.AdapterDropStatement;
import org.apache.asterix.lang.common.statement.AnalyzeStatement;
import org.apache.asterix.lang.common.statement.AnalyzeDropStatement;
import org.apache.asterix.lang.common.statement.CompactStatement;
import org.apache.asterix.lang.common.statement.ConnectFeedStatement;
import org.apache.asterix.lang.common.statement.StartFeedStatement;
import org.apache.asterix.lang.common.statement.StopFeedStatement;
import org.apache.asterix.lang.common.statement.CreateAdapterStatement;
import org.apache.asterix.lang.common.statement.CreateDataverseStatement;
import org.apache.asterix.lang.common.statement.CreateFeedPolicyStatement;
import org.apache.asterix.lang.common.statement.CreateFeedStatement;
import org.apache.asterix.lang.common.statement.CreateFunctionStatement;
import org.apache.asterix.lang.common.statement.CreateIndexStatement;
import org.apache.asterix.lang.common.statement.CreateSynonymStatement;
import org.apache.asterix.lang.common.statement.CreateFullTextFilterStatement;
import org.apache.asterix.lang.common.statement.CreateFullTextConfigStatement;
import org.apache.asterix.lang.common.statement.CreateViewStatement;
import org.apache.asterix.lang.common.statement.DatasetDecl;
import org.apache.asterix.lang.common.statement.DataverseDecl;
import org.apache.asterix.lang.common.statement.DataverseDropStatement;
import org.apache.asterix.lang.common.statement.DeleteStatement;
import org.apache.asterix.lang.common.statement.DisconnectFeedStatement;
import org.apache.asterix.lang.common.statement.DropDatasetStatement;
import org.apache.asterix.lang.common.statement.ExternalDetailsDecl;
import org.apache.asterix.lang.common.statement.FeedDropStatement;
import org.apache.asterix.lang.common.statement.FeedPolicyDropStatement;
import org.apache.asterix.lang.common.statement.FunctionDecl;
import org.apache.asterix.lang.common.statement.FunctionDropStatement;
import org.apache.asterix.lang.common.statement.IndexDropStatement;
import org.apache.asterix.lang.common.statement.FullTextFilterDropStatement;
import org.apache.asterix.lang.common.statement.FullTextConfigDropStatement;
import org.apache.asterix.lang.common.statement.InsertStatement;
import org.apache.asterix.lang.common.statement.InternalDetailsDecl;
import org.apache.asterix.lang.common.statement.LoadStatement;
import org.apache.asterix.lang.common.statement.NodeGroupDropStatement;
import org.apache.asterix.lang.common.statement.NodegroupDecl;
import org.apache.asterix.lang.common.statement.Query;
import org.apache.asterix.lang.common.statement.RefreshExternalDatasetStatement;
import org.apache.asterix.lang.common.statement.SetStatement;
import org.apache.asterix.lang.common.statement.SynonymDropStatement;
import org.apache.asterix.lang.common.statement.TypeDecl;
import org.apache.asterix.lang.common.statement.TypeDropStatement;
import org.apache.asterix.lang.common.statement.UpdateStatement;
import org.apache.asterix.lang.common.statement.UpsertStatement;
import org.apache.asterix.lang.common.statement.ViewDecl;
import org.apache.asterix.lang.common.statement.ViewDropStatement;
import org.apache.asterix.lang.common.statement.WriteStatement;
import org.apache.asterix.lang.common.struct.Identifier;
import org.apache.asterix.lang.common.struct.OperatorType;
import org.apache.asterix.lang.common.struct.QuantifiedPair;
import org.apache.asterix.lang.common.struct.VarIdentifier;
import org.apache.asterix.lang.common.util.DatasetDeclParametersUtil;
import org.apache.asterix.lang.common.util.ExpressionUtils;
import org.apache.asterix.lang.common.util.RangeMapBuilder;
import org.apache.asterix.lang.sqlpp.clause.AbstractBinaryCorrelateClause;
import org.apache.asterix.lang.sqlpp.clause.FromClause;
import org.apache.asterix.lang.sqlpp.clause.FromTerm;
import org.apache.asterix.lang.sqlpp.clause.HavingClause;
import org.apache.asterix.lang.sqlpp.clause.JoinClause;
import org.apache.asterix.lang.sqlpp.clause.Projection;
import org.apache.asterix.lang.sqlpp.clause.SelectBlock;
import org.apache.asterix.lang.sqlpp.clause.SelectClause;
import org.apache.asterix.lang.sqlpp.clause.SelectElement;
import org.apache.asterix.lang.sqlpp.clause.SelectRegular;
import org.apache.asterix.lang.sqlpp.clause.SelectSetOperation;
import org.apache.asterix.lang.sqlpp.clause.UnnestClause;
import org.apache.asterix.lang.common.clause.WhereClause;
import org.apache.asterix.lang.sqlpp.expression.CaseExpression;
import org.apache.asterix.lang.sqlpp.expression.SelectExpression;
import org.apache.asterix.lang.sqlpp.expression.WindowExpression;
import org.apache.asterix.lang.sqlpp.optype.JoinType;
import org.apache.asterix.lang.sqlpp.optype.SetOpType;
import org.apache.asterix.lang.sqlpp.optype.UnnestType;
import org.apache.asterix.lang.sqlpp.parser.SqlppGroupingSetsParser;
import org.apache.asterix.lang.sqlpp.parser.SqlppGroupingSetsParser.GroupingElement;
import org.apache.asterix.lang.sqlpp.parser.SqlppGroupingSetsParser.GroupingSet;
import org.apache.asterix.lang.sqlpp.parser.SqlppGroupingSetsParser.GroupingSets;
import org.apache.asterix.lang.sqlpp.parser.SqlppGroupingSetsParser.RollupCube;
import org.apache.asterix.lang.sqlpp.parser.SqlppHint;
import org.apache.asterix.lang.sqlpp.struct.SetOperationInput;
import org.apache.asterix.lang.sqlpp.struct.SetOperationRight;
import org.apache.asterix.lang.sqlpp.util.ExpressionToVariableUtil;
import org.apache.asterix.lang.sqlpp.util.FunctionMapUtil;
import org.apache.asterix.lang.sqlpp.util.SqlppVariableUtil;
import org.apache.asterix.metadata.utils.MetadataConstants;
import org.apache.asterix.om.exceptions.TypeMismatchException;
import org.apache.asterix.om.functions.BuiltinFunctions;
import org.apache.asterix.om.types.BuiltinType;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.hyracks.algebricks.common.utils.Pair;
import org.apache.hyracks.algebricks.common.utils.Triple;
import org.apache.hyracks.algebricks.common.exceptions.AlgebricksException;
import org.apache.hyracks.algebricks.core.algebra.expressions.BroadcastExpressionAnnotation;
import org.apache.hyracks.algebricks.core.algebra.expressions.HashJoinExpressionAnnotation;
import org.apache.hyracks.algebricks.core.algebra.expressions.IExpressionAnnotation;
import org.apache.hyracks.algebricks.core.algebra.expressions.JoinProductivityAnnotation;
import org.apache.hyracks.algebricks.core.algebra.expressions.PredicateCardinalityAnnotation;
import org.apache.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
import org.apache.hyracks.api.exceptions.IWarningCollector;
import org.apache.hyracks.api.exceptions.SourceLocation;
import org.apache.hyracks.api.exceptions.Warning;
import org.apache.hyracks.dataflow.common.data.partition.range.RangeMap;
import org.apache.hyracks.util.LogRedactionUtil;
import org.apache.hyracks.util.StringUtil;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

class SQLPPParser extends ScopeChecker implements IParser {

    // tokens parsed as identifiers
    private static final String CUBE = "CUBE";
    private static final String CURRENT = "CURRENT";
    private static final String DEFAULT = "DEFAULT";
    private static final String EXCLUDE = "EXCLUDE";
    private static final String INCLUDE = "INCLUDE";
    private static final String FIRST = "FIRST";
    private static final String FOLLOWING = "FOLLOWING";
    private static final String FOREIGN = "FOREIGN";
    private static final String GROUPING = "GROUPING";
    private static final String GROUPS = "GROUPS";
    private static final String IGNORE = "IGNORE";
    private static final String LAST = "LAST";
    private static final String META = "META";
    private static final String NO = "NO";
    private static final String NULLS = "NULLS";
    private static final String OTHERS = "OTHERS";
    private static final String PARTITION = "PARTITION";
    private static final String PRECEDING = "PRECEDING";
    private static final String RANGE = "RANGE";
    private static final String REFERENCES = "REFERENCES";
    private static final String RESPECT = "RESPECT";
    private static final String ROLLUP = "ROLLUP";
    private static final String ROW = "ROW";
    private static final String ROWS = "ROWS";
    private static final String SETS = "SETS";
    private static final String TIES = "TIES";
    private static final String UNBOUNDED = "UNBOUNDED";
    private static final String REPLACE = "REPLACE";
    private static final String RETURNS = "RETURNS";
    private static final String CONFIG = "CONFIG";
    private static final String STATISTICS = "STATISTICS";


    private static final String INT_TYPE_NAME = "int";
    private static final String UDF_VARARGS_PARAM_NAME = "args"; // Note: this value is stored in the function metadata

    // error configuration
    protected static final boolean REPORT_EXPECTED_TOKENS = false;

    private int externalVarCounter;

    private DataverseName defaultDataverse;

    private SqlppGroupingSetsParser groupingSetsParser;

    private final WarningCollector warningCollector = new WarningCollector();

    private final Map<SourceLocation, String> hintCollector = new HashMap<SourceLocation, String>();

    private static class IndexParams {
      public IndexType type;
      public int gramLength;
      public String fullTextConfig;

      public IndexParams(IndexType type, int gramLength, String fullTextConfig) {
        this.type = type;
        this.gramLength = gramLength;
        this.fullTextConfig = fullTextConfig;
      }
    }

    private static class FunctionName {
       public DataverseName dataverse;
       public String library;
       public String function;
       public Token hintToken;
       public SourceLocation sourceLoc;
    }

    private IRecordFieldDataGen parseFieldDataGen(Token hintToken) throws ParseException {
      String[] splits = hintToken.hintParams != null ? hintToken.hintParams.split("\\s+") : null;
      switch (hintToken.hint) {
        case VAL_FILE_HINT:
          File[] valFiles = new File[splits.length];
          for (int k=0; k<splits.length; k++) {
            valFiles[k] = new File(splits[k]);
          }
          return new FieldValFileDataGen(valFiles);
        case VAL_FILE_SAME_INDEX_HINT:
          return new FieldValFileSameIndexDataGen(new File(splits[0]), splits[1]);
        case LIST_VAL_FILE_HINT:
          return new ListValFileDataGen(new File(splits[0]), Integer.parseInt(splits[1]), Integer.parseInt(splits[2]));
        case LIST_HINT:
          return new ListDataGen(Integer.parseInt(splits[0]), Integer.parseInt(splits[1]));
        case INTERVAL_HINT:
          FieldIntervalDataGen.ValueType vt;
          switch (splits[0]) {
            case "int":
              vt = FieldIntervalDataGen.ValueType.INT;
              break;
            case "long":
              vt = FieldIntervalDataGen.ValueType.LONG;
              break;
            case "float":
              vt = FieldIntervalDataGen.ValueType.FLOAT;
              break;
            case "double":
              vt = FieldIntervalDataGen.ValueType.DOUBLE;
              break;
            default:
              throw new SqlppParseException(getSourceLocation(hintToken),
                "Unknown type for interval data gen: " + splits[0]);
          }
          return new FieldIntervalDataGen(vt, splits[1], splits[2]);
        case INSERT_RAND_INT_HINT:
          return new InsertRandIntDataGen(splits[0], splits[1]);
        case DATE_BETWEEN_YEARS_HINT:
          return new DateBetweenYearsDataGen(Integer.parseInt(splits[0]), Integer.parseInt(splits[1]));
        case DATETIME_BETWEEN_YEARS_HINT:
          return new DatetimeBetweenYearsDataGen(Integer.parseInt(splits[0]), Integer.parseInt(splits[1]));
        case DATETIME_ADD_RAND_HOURS_HINT:
          return new DatetimeAddRandHoursDataGen(Integer.parseInt(splits[0]), Integer.parseInt(splits[1]), splits[2]);
        case AUTO_HINT:
          return new AutoDataGen(splits[0]);
        default:
          return null;
      }
    }

    public SQLPPParser(String s) {
        this(new StringReader(s));
        super.setInput(s);
    }

    public static void main(String[] args) throws ParseException, TokenMgrError, IOException, FileNotFoundException, CompilationException {
        File file = new File(args[0]);
        Reader fis = new BufferedReader(new InputStreamReader(new FileInputStream(file), "UTF-8"));
        SQLPPParser parser = new SQLPPParser(fis);
        List<Statement> st = parser.parse();
        //st.accept(new SQLPPPrintVisitor(), 0);
    }

    @Override
    public List<Statement> parse() throws CompilationException {
        return parseImpl(new ParseFunction<List<Statement>>() {
            @Override
            public List<Statement> parse() throws ParseException {
                return SQLPPParser.this.Statement();
            }
        });
    }

    @Override
    public Expression parseExpression() throws CompilationException {
        return parseImpl(new ParseFunction<Expression>() {
            @Override
            public Expression parse() throws ParseException {
                return SQLPPParser.this.Expression();
            }
        });
    }

    private static Expression parseExpression(String text) throws CompilationException {
        return new SQLPPParser(text).parseExpression();
    }

    @Override
    public List<String> parseMultipartIdentifier() throws CompilationException {
        return parseImpl(new ParseFunction<List<String>>() {
            @Override
            public List<String> parse() throws ParseException {
                return SQLPPParser.this.MultipartIdentifier().first;
            }
        });
    }

    private List<String> parseParenthesizedIdentifierList() throws CompilationException {
        return parseImpl(new ParseFunction<List<String>>() {
            @Override
            public  List<String> parse() throws ParseException {
                return SQLPPParser.this.ParenthesizedIdentifierList();
            }
        });
    }

    private static List<String> parseParenthesizedIdentifierList(String text) throws CompilationException {
        return new SQLPPParser(text).parseParenthesizedIdentifierList();
    }

    private Pair<HashJoinExpressionAnnotation.BuildOrProbe, String> parseHashJoinParams() throws CompilationException {
        return parseImpl(new ParseFunction<Pair<HashJoinExpressionAnnotation.BuildOrProbe, String>>() {
            @Override
            public  Pair<HashJoinExpressionAnnotation.BuildOrProbe, String> parse() throws ParseException {
                return SQLPPParser.this.buildOrProbeParenthesizedIdentifier();
            }
        });
    }

    private static Pair<HashJoinExpressionAnnotation.BuildOrProbe, String> parseHashJoinParams(String text) throws CompilationException {
        return new SQLPPParser(text).parseHashJoinParams();
    }

    private String parseBroadcastJoinParams() throws CompilationException {
            return parseImpl(new ParseFunction<String>() {
                @Override
                public  String parse() throws ParseException {
                    return SQLPPParser.this.parenthesizedIdentifier();
                }
            });
        }

    private static String parseBroadcastJoinParams(String text) throws CompilationException {
        return new SQLPPParser(text).parseBroadcastJoinParams();
    }

    private List<Literal> parseParenthesizedLiteralList() throws CompilationException {
        return parseImpl(new ParseFunction<List<Literal>>() {
            @Override
            public  List<Literal> parse() throws ParseException {
                return SQLPPParser.this.ParenthesizedLiteralList();
            }
        });
    }

    private static List<Literal> parseParenthesizedLiteralList(String text) throws CompilationException {
        return new SQLPPParser(text).parseParenthesizedLiteralList();
    }

    @Override
    public FunctionDecl parseFunctionBody(FunctionSignature signature, List<String> paramNames, boolean isStored)
      throws CompilationException {
        return parseImpl(new ParseFunction<FunctionDecl>() {
            @Override
            public FunctionDecl parse() throws ParseException {
                DataverseName dataverse = defaultDataverse;
                defaultDataverse = signature.getDataverseName();
                createNewScope();
                List<VarIdentifier> paramVars = new ArrayList<VarIdentifier>(paramNames.size());
                for (String paramName : paramNames) {
                    paramVars.add(SqlppVariableUtil.toInternalVariableIdentifier(paramName));
                }
                Expression functionBodyExpr = SQLPPParser.this.FunctionBody();
                removeCurrentScope();
                defaultDataverse = dataverse;
                return new FunctionDecl(signature, paramVars, functionBodyExpr, isStored);
            }
        });
    }

    @Override
    public ViewDecl parseViewBody(DatasetFullyQualifiedName viewName) throws CompilationException {
        return parseImpl(new ParseFunction<ViewDecl>() {
            @Override
            public ViewDecl parse() throws ParseException {
                DataverseName dataverse = defaultDataverse;
                defaultDataverse = viewName.getDataverseName();
                createNewScope();
                Expression viewBodyExpr = SQLPPParser.this.ViewBody();
                removeCurrentScope();
                defaultDataverse = dataverse;
                return new ViewDecl(viewName, viewBodyExpr);
            }
        });
    }

    private <T> T parseImpl(ParseFunction<T> parseFunction) throws CompilationException {
        warningCollector.clear();
        hintCollector.clear();
        token_source.hintCollector = hintCollector;
        try {
            return parseFunction.parse();
        } catch (SqlppParseException e) {
            if (e.getCause() instanceof AlgebricksException) {
              AlgebricksException cause = (AlgebricksException) e.getCause();
              if (cause.getError().isPresent() && cause.getError().get() instanceof ErrorCode) {
                throw new CompilationException((ErrorCode) cause.getError().get(), e.getSourceLocation(),
                  cause.getParams());
              }
            }
            throw new CompilationException(ErrorCode.PARSE_ERROR, e.getSourceLocation(),
              LogRedactionUtil.userData(getMessage(e)));
        } catch (ParseException e) {
            throw new CompilationException(ErrorCode.PARSE_ERROR, LogRedactionUtil.userData(getMessage(e)));
        } catch (Error e) {
            // this is here as the JavaCharStream that's below the lexer sometimes throws Errors that are not handled
            // by the generated lexer or parser (e.g it does this for invalid backslash u + 4 hex digits escapes)
            final String msg = e.getClass().getSimpleName() + (e.getMessage() != null ? ": " + e.getMessage() : "");
            throw new CompilationException(ErrorCode.PARSE_ERROR, LogRedactionUtil.userData(msg));
        } finally {
            reportUnclaimedHints();
        }
    }

    @FunctionalInterface
    private interface ParseFunction<T> {
        T parse() throws ParseException;
    }

    @Override
    public void getWarnings(IWarningCollector outWarningCollector) {
        warningCollector.getWarnings(outWarningCollector);
    }

    @Override
    public void getWarnings(Collection<? super Warning> outWarnings, long maxWarnings) {
        warningCollector.getWarnings(outWarnings, maxWarnings);
    }

    @Override
    public long getTotalWarningsCount() {
        return warningCollector.getTotalWarningsCount();
    }

    protected String getMessage(ParseException pe) {
        Token currentToken = pe.currentToken;
        if (currentToken == null) {
            return pe.getMessage();
        }
        int[][] expectedTokenSequences = pe.expectedTokenSequences;
        String[] tokenImage = pe.tokenImage;
        String sep = REPORT_EXPECTED_TOKENS ? eol : " ";
        StringBuilder expected = REPORT_EXPECTED_TOKENS ? new StringBuilder() : null;
        int maxSize = appendExpected(expected, expectedTokenSequences, tokenImage);
        Token tok = currentToken.next;
        int line = tok.beginLine;
        StringBuilder message = new StringBuilder(128);
        message.append("In line ").append(line).append(" >>").append(getLine(line)).append("<<").append(sep).append("Encountered ");
        for (int i = 0; i < maxSize; i++) {
            if (i != 0) {
                message.append(' ');
            }
            if (tok.kind == 0) {
                message.append(fixQuotes(tokenImage[0]));
                break;
            }
            final String fixedTokenImage = tokenImage[tok.kind];
            if (! tok.image.equalsIgnoreCase(stripQuotes(fixedTokenImage))) {
                message.append(fixQuotes(fixedTokenImage)).append(' ');
            }
            message.append(quot).append(addEscapes(tok.image)).append(quot);
            tok = tok.next;
        }
        message.append(" at column ").append(currentToken.next.beginColumn).append('.').append(sep);
        if (REPORT_EXPECTED_TOKENS) {
            if (expectedTokenSequences.length == 1) {
                message.append("Was expecting:").append(sep).append("    ");
            } else {
                message.append("Was expecting one of:").append(sep).append("    ");
            }
            message.append(expected);
        }
        return message.toString();
    }

    protected static SourceLocation getSourceLocation(Token token) {
        return
          token == null ? null :
          token.sourceLocation != null ? token.sourceLocation :
          new SourceLocation(token.beginLine, token.beginColumn);
    }

    protected static <T extends AbstractLangExpression> T addSourceLocation(T expr, Token token) {
        expr.setSourceLocation(getSourceLocation(token));
        return expr;
    }

    private boolean isToken(String image) {
      return isToken(token, image);
    }

    private static boolean isToken(Token token, String image) {
      return token.image.equalsIgnoreCase(image);
    }

    private void expectToken(String image) throws SqlppParseException {
      expectToken(token, image);
    }

    private static void expectToken(Token token, String image) throws SqlppParseException {
      if (!isToken(token, image)) {
        throw createUnexpectedTokenError(token);
      }
    }

    private SqlppParseException createUnexpectedTokenError() {
      return createUnexpectedTokenError(token, null);
    }

    private static SqlppParseException createUnexpectedTokenError(Token t) {
      return createUnexpectedTokenError(t, null);
    }

    private SqlppParseException createUnexpectedTokenError(String expected) {
      return createUnexpectedTokenError(token, expected);
    }

    private static SqlppParseException createUnexpectedTokenError(Token t, String expected) {
      String message = "Unexpected token: " + LogRedactionUtil.userData(t.image) +
        (expected == null ? "" : ". Expected: " + LogRedactionUtil.userData(expected));
      return new SqlppParseException(getSourceLocation(t), message);
    }

    private boolean laToken(int idx, int kind) {
      Token t = getToken(idx);
      return t.kind == kind;
    }

    private boolean laToken(int idx, int kind, String image) {
      Token t = getToken(idx);
      return t.kind == kind && t.image.equalsIgnoreCase(image);
    }

    private boolean laIdentifier(int idx, String image) {
      return laToken(idx, IDENTIFIER, image);
    }

    private boolean laIdentifier(String image) {
      return laIdentifier(1, image);
    }

    private Token fetchHint(Token token, SqlppHint... expectedHints) {
      Token hintToken = token.specialToken;
      if (hintToken == null) {
        return null;
      }
      SourceLocation sourceLoc = getSourceLocation(hintToken);
      hintCollector.remove(sourceLoc);
      if (hintToken.hint == null) {
        warnUnexpectedHint(hintToken.hintParams, sourceLoc, expectedHints);
        return null;
      } else if (!ArrayUtils.contains(expectedHints, hintToken.hint)) {
        warnUnexpectedHint(hintToken.hint.getIdentifier(), sourceLoc, expectedHints);
        return null;
      } else {
        return hintToken;
      }
    }

    private void reportUnclaimedHints() {
        for (Map.Entry<SourceLocation, String> me : hintCollector.entrySet()) {
            warnUnexpectedHint(me.getValue(), me.getKey(), "None");
        }
    }

    private void warnUnexpectedHint(String actualHint, SourceLocation sourceLoc, SqlppHint... expectedHints) {
        warnUnexpectedHint(actualHint, sourceLoc, StringUtil.join(expectedHints, ", ", "\""));
    }

    private void warnUnexpectedHint(String actualHint, SourceLocation sourceLoc, String expectedHints) {
        if (warningCollector.shouldWarn()) {
            warningCollector.warn(Warning.of(sourceLoc, ErrorCode.UNEXPECTED_HINT, actualHint, expectedHints));
        }
    }

    private IExpressionAnnotation parseExpressionAnnotation(Token hintToken) {
      // placeholder for the annotation that should be returned if this hint's parameters cannot be parsed
      IExpressionAnnotation onParseErrorReturn = null;
      double selectivity, cardinality, productivity;
      Pattern number = Pattern.compile("\\d+\\.\\d+");
      Pattern stringNumber = Pattern.compile("\\w+\\s+\\d+\\.\\d+");
      Pattern lessThanOnePat = Pattern.compile("0\\.\\d+");
      try {
        switch (hintToken.hint) {
           case SINGLE_DATASET_PREDICATE_SELECTIVITY_HINT:
             if (hintToken.hintParams == null) {
               throw new SqlppParseException(getSourceLocation(hintToken), "Expected selectivity value");
             }
             else {
               selectivity = 1.0; // uninitialized
               Matcher mat = lessThanOnePat.matcher(hintToken.hintParams);
               if (mat.find()) {
                 selectivity = Double.parseDouble (mat.group());
               }
               else {
                 throw new SqlppParseException(getSourceLocation(hintToken), "Selectivity has to be a decimal value greater than 0 and less than 1");
               }
               return new PredicateCardinalityAnnotation(selectivity);
             }
           case JOIN_PREDICATE_PRODUCTIVITY_HINT:
             if (hintToken.hintParams == null) {
               throw new SqlppParseException(getSourceLocation(hintToken), "Expected productivity collection name and value");
             }
             else {
               productivity = 1.0; // uninitialized
               String leftSideDataSet = null;
               Matcher StringNum = stringNumber.matcher(hintToken.hintParams);
               if (StringNum.find()) {
                 String matchedGroup = StringNum.group();
                 Pattern var = Pattern.compile("[a-zA-Z]\\w*"); // any word character [a-zA-Z_0-9]
                 Matcher matVar = var.matcher(matchedGroup);
                 if (matVar.find()) {
                   leftSideDataSet = matVar.group();
                 }
                 else {
                    throw new SqlppParseException(getSourceLocation(hintToken), "Expected productivity collection name");
                 }
                 Matcher numMat = number.matcher(matchedGroup);
                 if (numMat.find()) {
                   productivity = Double.parseDouble (numMat.group());
                 }
                 else {
                   throw new SqlppParseException(getSourceLocation(hintToken), "Productivity has to be a decimal value greater than 0");
                 }
               }
               else {
                 throw new SqlppParseException(getSourceLocation(hintToken), "Invalid format for productivity values");
               }
               // attach hint to global scope
               return new JoinProductivityAnnotation (productivity, leftSideDataSet);
             }
          case HASH_BROADCAST_JOIN_HINT:
            if (hintToken.hintParams == null) {
              return new BroadcastExpressionAnnotation(BroadcastExpressionAnnotation.BroadcastSide.RIGHT);
            }
            else {
              // if parameter parsing fails then ignore this hint.
              String name = parseBroadcastJoinParams(hintToken.hintParams);
              return new BroadcastExpressionAnnotation(name);
            }
          case HASH_JOIN_HINT:
            if (hintToken.hintParams == null) {
              throw new SqlppParseException(getSourceLocation(hintToken), "Expected hash join build/probe collection name");
            }
            else {
              // if parameter parsing fails then ignore this hint.
              Pair<HashJoinExpressionAnnotation.BuildOrProbe, String> pair = parseHashJoinParams(hintToken.hintParams);
              return new HashJoinExpressionAnnotation(pair);
            }
          case INDEXED_NESTED_LOOP_JOIN_HINT:
            if (hintToken.hintParams == null) {
              return IndexedNLJoinExpressionAnnotation.INSTANCE_ANY_INDEX;
            } else {
              // if parameter parsing fails then return hint annotation without parameters
              onParseErrorReturn = IndexedNLJoinExpressionAnnotation.INSTANCE_ANY_INDEX;
              List<String> indexNames = parseParenthesizedIdentifierList(hintToken.hintParams);
              return IndexedNLJoinExpressionAnnotation.newInstance(indexNames);
            }
          case RANGE_HINT:
            Expression rangeExpr = parseExpression(hintToken.hintParams);
            RangeMap rangeMap = RangeMapBuilder.parseHint(rangeExpr);
            return new RangeAnnotation(rangeMap);
          case SKIP_SECONDARY_INDEX_SEARCH_HINT:
            if (hintToken.hintParams == null) {
              return SkipSecondaryIndexSearchExpressionAnnotation.INSTANCE_ANY_INDEX;
            } else {
              // if parameter parsing fails then ignore this hint
              List<String> indexNames = parseParenthesizedIdentifierList(hintToken.hintParams);
              return SkipSecondaryIndexSearchExpressionAnnotation.newInstance(indexNames);
            }
          case SPATIAL_JOIN_HINT:
            List<Literal> hintValues = parseParenthesizedLiteralList(hintToken.hintParams);

            // Handle exceptions
            if (hintValues.size() != 6) {
              throw new SqlppParseException(getSourceLocation(hintToken), String.format("Unexpected hint: %s. 6 arguments are required.",
                                hintToken.hint.toString()));
            }

            for (int i = 0; i < 4; i++) {
              Literal lit = hintValues.get(i);
              if ((lit.getLiteralType() != Literal.Type.DOUBLE)
                    && (lit.getLiteralType() != Literal.Type.FLOAT)
                    && (lit.getLiteralType() != Literal.Type.LONG)
                    && (lit.getLiteralType() != Literal.Type.INTEGER)){
                throw new SqlppParseException(getSourceLocation(hintToken), String.format("Unexpected hint: %s. Numeric value is required for first 4 arguments.",
                                hintToken.hint.toString()));
              }
            }

            for (int i = 4; i < 6; i++) {
              Literal lit = hintValues.get(i);
              if ((lit.getLiteralType() != Literal.Type.LONG)
                    && (lit.getLiteralType() != Literal.Type.INTEGER)) {
                throw new SqlppParseException(getSourceLocation(hintToken), String.format("Unexpected hint: %s. Long/int is required for last 2 arguments.",
                              hintToken.hint.toString()));
              }
            }

            try {
              double minX = ExpressionUtils.getDoubleValue(hintValues.get(0));
              double minY = ExpressionUtils.getDoubleValue(hintValues.get(1));
              double maxX = ExpressionUtils.getDoubleValue(hintValues.get(2));
              double maxY = ExpressionUtils.getDoubleValue(hintValues.get(3));
              int numRows = (int) ExpressionUtils.getLongValue(hintValues.get(4));
              int numColumns = (int) ExpressionUtils.getLongValue(hintValues.get(5));
              SpatialJoinAnnotation spatialJoinAnn = new SpatialJoinAnnotation(minX, minY, maxX, maxY, numRows, numColumns);
              return spatialJoinAnn;
            } catch (TypeMismatchException e) {
              throw new SqlppParseException(getSourceLocation(hintToken), e.getMessage());
            }
          case USE_SECONDARY_INDEX_SEARCH_HINT:
            if (hintToken.hintParams == null) {
              throw new SqlppParseException(getSourceLocation(hintToken), "Expected index name(s)");
            } else {
              // if parameter parsing fails then ignore this hint
              List<String> indexNames = parseParenthesizedIdentifierList(hintToken.hintParams);
              return SecondaryIndexSearchPreferenceAnnotation.newInstance(indexNames);
            }
          default:
            throw new SqlppParseException(getSourceLocation(hintToken), "Unexpected hint");
        }
      } catch (SqlppParseException e) {
        if (warningCollector.shouldWarn()) {
            warningCollector.warn(Warning.of(getSourceLocation(hintToken), ErrorCode.INVALID_HINT,
              hintToken.hint.toString(), e.getMessage()));
        }
        return onParseErrorReturn;
      } catch (CompilationException e) {
        if (warningCollector.shouldWarn()) {
            warningCollector.warn(Warning.of(getSourceLocation(hintToken), ErrorCode.INVALID_HINT,
              hintToken.hint.toString(), e.getMessage()));
        }
        return onParseErrorReturn;
      }
    }

    private void ensureNoTypeDeclsInFunction(String fnName, List<Pair<VarIdentifier, TypeExpression>> paramList,
      TypeExpression returnType, Token startToken) throws SqlppParseException {
      for (Pair<VarIdentifier, TypeExpression> p : paramList) {
        if (p.second != null) {
          String paramName = SqlppVariableUtil.toUserDefinedName(p.first.getValue());
          throw new SqlppParseException(getSourceLocation(startToken),
            "Unexpected type declaration for parameter " + paramName + " in function " + fnName);
        }
      }
      if (returnType != null) {
        throw new SqlppParseException(getSourceLocation(startToken),
          "Unexpected return type declaration for function " + fnName);
      }
    }

    private void ensureIntegerLiteral(LiteralExpr expr, String errorPrefix)  throws SqlppParseException {
        Literal lit = expr.getValue();
        if (lit.getLiteralType() != Literal.Type.INTEGER && lit.getLiteralType() != Literal.Type.LONG) {
            throw new SqlppParseException(expr.getSourceLocation(), errorPrefix + " should be an INTEGER");
        }
    }

    private DataverseName createDataverseName(List<String> parts, int fromIndex, int toIndex, Token startToken)
      throws SqlppParseException {
      try {
        return DataverseName.create(parts, fromIndex, toIndex);
      } catch (AsterixException e) {
        SqlppParseException pe = new SqlppParseException(getSourceLocation(startToken), e.getMessage());
        pe.initCause(e);
        throw pe;
      }
    }
}

PARSER_END(SQLPPParser)

List<Statement> Statement() throws ParseException:
{
  scopeStack.push(RootScopeFactory.createRootScope(this));
  List<Statement> decls = new ArrayList<Statement>();
  Statement stmt = null;
}
{
  (
    (stmt = ExplainStatement()
      {
        decls.add(stmt);
      }
    )?
    (<SEMICOLON>)+
  )*
  <EOF>
  {
    return decls;
  }
}

Statement ExplainStatement() throws ParseException:
{
  Statement stmt = null;
  Token explainToken = null;
}
{
   ( <EXPLAIN> { explainToken = token; } )?
   stmt = SingleStatement()
   {
      if (explainToken != null) {
        if (stmt.getKind() == Statement.Kind.QUERY) {
          ((Query)stmt).setExplain(true);
        } else {
          throw new SqlppParseException(getSourceLocation(explainToken),
            "EXPLAIN is not supported for this kind of statement");
        }
      }
      return stmt;
   }
}

Statement SingleStatement() throws ParseException:
{
  Statement stmt = null;
}
{
  (
    stmt = DataverseDeclaration()
    | stmt = FunctionDeclaration()
    | stmt = CreateStatement()
    | stmt = LoadStatement()
    | stmt = DropStatement()
    | stmt = WriteStatement()
    | stmt = SetStatement()
    | stmt = InsertStatement()
    | stmt = DeleteStatement()
    | stmt = UpdateStatement()
    | stmt = UpsertStatement()
    | stmt = ConnectionStatement()
    | stmt = CompactStatement()
    | stmt = AnalyzeStatement()
    | stmt = Query()
    | stmt = RefreshExternalDatasetStatement()
  )
  {
    return stmt;
  }
}

DataverseDecl DataverseDeclaration() throws ParseException:
{
  Token startToken = null;
  DataverseName dvName = null;
}
{
  <USE> { startToken = token; } dvName = DataverseName()
    {
      defaultDataverse = dvName;
      DataverseDecl dvDecl = new DataverseDecl(defaultDataverse);
      return addSourceLocation(dvDecl, startToken);
    }
}

Statement CreateStatement() throws ParseException:
{
  Token startToken = null;
  Statement stmt = null;
}
{
  <CREATE> { startToken = token; }
  (
    stmt = CreateOrReplaceStatement(startToken)
    | stmt = CreateTypeStatement(startToken)
    | stmt = CreateNodegroupStatement(startToken)
    | stmt = CreateDatasetStatement(startToken)
    | stmt = CreateIndexStatement(startToken)
    | stmt = CreateDataverseStatement(startToken)
    | stmt = CreateFunctionStatement(startToken, false)
    | stmt = CreateAdapterStatement(startToken)
    | stmt = CreateSynonymStatement(startToken)
    | stmt = CreateFeedStatement(startToken)
    | stmt = CreateFeedPolicyStatement(startToken)
    | stmt = CreateFullTextStatement(startToken)
    | stmt = CreateViewStatement(startToken, false)
  )
  {
    return stmt;
  }
}

Statement CreateOrReplaceStatement(Token startStmtToken) throws ParseException:
{
  Statement stmt = null;
  Token replaceToken = null;
}
{
  <OR> <IDENTIFIER> { replaceToken = token; }
  (
    stmt = CreateFunctionStatement(startStmtToken, true)
    | stmt = CreateViewStatement(startStmtToken, true)
  )
  {
    // check expected token here to make the grammar extension plugin happy
    expectToken(replaceToken, REPLACE);
    return stmt;
  }
}

TypeDecl CreateTypeStatement(Token startStmtToken) throws ParseException:
{
  TypeDecl stmt = null;
}
{
  <TYPE> stmt = TypeSpecification(startStmtToken)
  {
    return stmt;
  }
}

TypeDecl TypeSpecification(Token startStmtToken) throws ParseException:
{
  Pair<DataverseName,Identifier> nameComponents = null;
  boolean ifNotExists = false;
  TypeExpression typeExpr = null;
}
{
  nameComponents = TypeName() ifNotExists = IfNotExists()
  <AS> typeExpr = RecordTypeDef()
  {
    boolean dgen = false;
    long numValues = -1;
    String filename = null;
    Token hintToken = fetchHint(startStmtToken, SqlppHint.DGEN_HINT);
    if (hintToken != null) {
        String hintParams = hintToken.hintParams;
        String[] splits = hintParams != null ? hintParams.split("\\s+") : null;
        if (splits == null || splits.length != 2) {
          throw new SqlppParseException(getSourceLocation(hintToken),
            "Expecting /*+ dgen <filename> <numberOfItems> */");
        }
        dgen = true;
        filename = splits[0];
        numValues = Long.parseLong(splits[1]);
    }
    TypeDataGen tddg = new TypeDataGen(dgen, filename, numValues);
    TypeDecl stmt = new TypeDecl(nameComponents.first, nameComponents.second, typeExpr, tddg, ifNotExists);
    return addSourceLocation(stmt, startStmtToken);
  }
}

NodegroupDecl CreateNodegroupStatement(Token startStmtToken) throws ParseException:
{
  NodegroupDecl stmt = null;
}
{
  <NODEGROUP> stmt = NodegroupSpecification(startStmtToken)
  {
    return stmt;
  }
}

NodegroupDecl NodegroupSpecification(Token startStmtToken) throws ParseException:
{
  String name = null;
  String tmp = null;
  boolean ifNotExists = false;
  List<Identifier> ncNames = new ArrayList<Identifier>();
}
{
  name = Identifier() ifNotExists = IfNotExists()
  <ON> tmp = Identifier()
  {
    ncNames.add(new Identifier(tmp));
  }
  ( <COMMA> tmp = Identifier()
    {
      ncNames.add(new Identifier(tmp));
    }
  )*
  {
    NodegroupDecl stmt = new NodegroupDecl(new Identifier(name), ncNames, ifNotExists);
    return addSourceLocation(stmt, startStmtToken);
  }
}

void Dataset() throws ParseException:
{
}
{
    (<DATASET>|<COLLECTION>)
}

void DatasetToken() throws ParseException:
{
}
{
    Dataset()
}

DatasetDecl CreateDatasetStatement(Token startStmtToken) throws ParseException:
{
  DatasetDecl stmt = null;
}
{
  (
    (<INTERNAL>)? Dataset() stmt = DatasetSpecification(startStmtToken)
    | <EXTERNAL> Dataset() stmt = ExternalDatasetSpecification(startStmtToken)
  )
  {
    return stmt;
  }
}

DatasetDecl DatasetSpecification(Token startStmtToken) throws ParseException:
{
  Pair<DataverseName,Identifier> nameComponents = null;
  boolean ifNotExists = false;
  TypeExpression typeExpr = null;
  TypeExpression metaTypeExpr = null;
  Pair<List<Integer>, List<List<String>>> primaryKeyFields = null;
  Map<String,String> hints = new HashMap<String,String>();
  DatasetDecl stmt = null;
  boolean autogenerated = false;
  Pair<Integer, List<String>> filterField = null;
  RecordConstructor withRecord = null;
}
{
  nameComponents = QualifiedName()
  typeExpr = DatasetTypeSpecification()
  (
    { String name; }
    <WITH>
    name = Identifier()
    {
        if (!name.equalsIgnoreCase("meta")){
            throw new SqlppParseException(getSourceLocation(startStmtToken),
                "We can only support one additional associated field called \"meta\".");
        }
    }
    metaTypeExpr = DatasetTypeSpecification()
  )?
  ifNotExists = IfNotExists()
  primaryKeyFields = PrimaryKey()
  (<AUTOGENERATED> { autogenerated = true; } )?
  ( <HINTS> hints = Properties() )?
  ( LOOKAHEAD(2) <WITH> <FILTER> <ON>  filterField = NestedField() )?
  ( <WITH> withRecord = RecordConstructor() )?
  {
    try {
      InternalDetailsDecl idd = new InternalDetailsDecl(primaryKeyFields.second, primaryKeyFields.first, autogenerated,
        filterField == null? null : filterField.first, filterField == null? null : filterField.second);
      DatasetDeclParametersUtil.adjustInlineTypeDecl(typeExpr, primaryKeyFields.second, primaryKeyFields.first, false);
      if (metaTypeExpr != null) {
        DatasetDeclParametersUtil.adjustInlineTypeDecl(metaTypeExpr, primaryKeyFields.second, primaryKeyFields.first,
          true);
      }
      stmt = new DatasetDecl(nameComponents.first, nameComponents.second, typeExpr, metaTypeExpr, hints,
        DatasetType.INTERNAL, idd, withRecord, ifNotExists);
      return addSourceLocation(stmt, startStmtToken);
    } catch (CompilationException e) {
       throw new SqlppParseException(getSourceLocation(startStmtToken), e.getMessage());
    }
  }
}

DatasetDecl ExternalDatasetSpecification(Token startStmtToken) throws ParseException:
{
  Pair<DataverseName,Identifier> nameComponents = null;
  TypeExpression typeExpr = null;
  boolean ifNotExists = false;
  String adapterName = null;
  Map<String,String> properties = null;
  Map<String,String> hints = new HashMap<String,String>();
  DatasetDecl stmt = null;
  RecordConstructor withRecord = null;
}
{
  nameComponents = QualifiedName()
  typeExpr = DatasetTypeSpecification()
  ifNotExists = IfNotExists()
  <USING> adapterName = AdapterName() properties = Configuration()
  ( <HINTS> hints = Properties() )?
  ( <WITH> withRecord = RecordConstructor() )?
  {
    ExternalDetailsDecl edd = new ExternalDetailsDecl();
    edd.setAdapter(adapterName);
    edd.setProperties(properties);
    try {
      stmt = new DatasetDecl(nameComponents.first, nameComponents.second, typeExpr, null, hints, DatasetType.EXTERNAL,
        edd, withRecord, ifNotExists);
      return addSourceLocation(stmt, startStmtToken);
    } catch (CompilationException e) {
       throw new SqlppParseException(getSourceLocation(startStmtToken), e.getMessage());
    }
  }
}

TypeExpression DatasetTypeSpecification() throws ParseException:
{
  TypeExpression typeExpr = null;
}
{
  (
    LOOKAHEAD(3) typeExpr = DatasetRecordTypeSpecification(true)
    | typeExpr = DatasetReferenceTypeSpecification()
  )
  {
    return typeExpr;
  }
}

TypeExpression DatasetReferenceTypeSpecification() throws ParseException:
{
  TypeExpression typeExpr = null;
}
{
  <LEFTPAREN> typeExpr = TypeReference() <RIGHTPAREN>
  {
    return typeExpr;
  }
}

RecordTypeDefinition DatasetRecordTypeSpecification(boolean allowRecordKindModifier) throws ParseException:
{
  RecordTypeDefinition recordTypeDef = null;
  RecordTypeDefinition.RecordKind recordKind = null;
  Token startToken = null, recordKindToken = null;
}
{
   <LEFTPAREN> { startToken = token; } recordTypeDef = DatasetRecordTypeDef() <RIGHTPAREN>
   ( recordKind = RecordTypeKind() { recordKindToken = token; } <TYPE> )?
   {
     if (recordKind == null) {
       recordKind = RecordTypeDefinition.RecordKind.CLOSED;
     } else if (!allowRecordKindModifier) {
       throw createUnexpectedTokenError(recordKindToken);
     }
     recordTypeDef.setRecordKind(recordKind);
     return addSourceLocation(recordTypeDef, startToken);
   }
}

RecordTypeDefinition DatasetRecordTypeDef() throws ParseException:
{
  RecordTypeDefinition recType = new RecordTypeDefinition();
}
{
  DatasetRecordField(recType) ( <COMMA> DatasetRecordField(recType) )*
  {
    return recType;
  }
}

void DatasetRecordField(RecordTypeDefinition recType) throws ParseException:
{
  String fieldName;
  TypeExpression type = null;
  boolean nullable = true, missable = true;
}
{
  fieldName = Identifier()
  type = TypeReference() ( <NOT> <UNKNOWN> { nullable = false; missable = false; } )?
  {
    recType.addField(fieldName, type, nullable, missable);
  }
}

RefreshExternalDatasetStatement RefreshExternalDatasetStatement() throws ParseException:
{
  Token startToken = null;
  Pair<DataverseName,Identifier> nameComponents = null;
  String datasetName = null;
}
{
  <REFRESH> { startToken = token; } <EXTERNAL> Dataset() nameComponents = QualifiedName()
  {
    RefreshExternalDatasetStatement stmt = new RefreshExternalDatasetStatement();
    stmt.setDataverseName(nameComponents.first);
    stmt.setDatasetName(nameComponents.second);
    return addSourceLocation(stmt, startToken);
  }
}

CreateIndexStatement CreateIndexStatement(Token startStmtToken) throws ParseException:
{
  CreateIndexStatement stmt = null;
}
{
  (
    <INDEX> stmt = IndexSpecification(startStmtToken)
    | <PRIMARY> <INDEX> stmt = PrimaryIndexSpecification(startStmtToken)
  )
  {
    return stmt;
  }
}

CreateIndexStatement IndexSpecification(Token startStmtToken) throws ParseException:
{
  Pair<DataverseName,Identifier> nameComponents = null;
  String indexName = null;
  IndexParams indexParams = null;
  CreateIndexStatement.IndexedElement indexedElement = null;
  List<CreateIndexStatement.IndexedElement> indexedElementList = new ArrayList<CreateIndexStatement.IndexedElement>();
  boolean enforced = false;
  boolean ifNotExists = false;
  boolean hasUnnest = false;
  String fullTextConfigName = null;
  Token startElementToken = null;
  Boolean excludeUnknown = null;
  Pair<Map<String, String>, Boolean> castConfigDefaultNull;
  Boolean castDefaultNull = null;
  Map<String, String> castConfig = null;
}
{
  (
    indexName = Identifier() ifNotExists = IfNotExists()
    <ON> nameComponents = QualifiedName()
    <LEFTPAREN> { startElementToken  = token; }
      indexedElement = IndexedElement(startElementToken) {
        indexedElementList.add(indexedElement);
        hasUnnest |= indexedElement.hasUnnest();
      }
      (<COMMA> { startElementToken = token; }
        indexedElement = IndexedElement(startElementToken) {
          indexedElementList.add(indexedElement);
          hasUnnest |= indexedElement.hasUnnest();
        }
      )*
    <RIGHTPAREN>
    ( <TYPE> indexParams = IndexType() )? ( <ENFORCED> { enforced = true; } )?
    ( LOOKAHEAD({laIdentifier(EXCLUDE) || laIdentifier(INCLUDE)}) <IDENTIFIER>
    {
      if (isToken(EXCLUDE)) {
        excludeUnknown = true;
      } else if (isToken(INCLUDE)) {
        excludeUnknown = false;
      } else {
        throw createUnexpectedTokenError();
      }
    } <UNKNOWN> <KEY>
    )?

    ( <CAST><LEFTPAREN> castConfigDefaultNull = CastDefaultNull() <RIGHTPAREN>
      {
        castConfig = castConfigDefaultNull.first;
        castDefaultNull = castConfigDefaultNull.second;
      }
    )?
  )
  {
    IndexType indexType;
    int gramLength;
    if (indexParams != null) {
      indexType = indexParams.type;
      gramLength = indexParams.gramLength;
      fullTextConfigName = indexParams.fullTextConfig;
    } else {
      indexType = hasUnnest ? IndexType.ARRAY : IndexType.BTREE;
      gramLength = -1;
      fullTextConfigName = null;
    }
    CreateIndexStatement stmt = new CreateIndexStatement(nameComponents.first, nameComponents.second,
      new Identifier(indexName), indexType, indexedElementList, enforced, gramLength, fullTextConfigName, ifNotExists,
      excludeUnknown, castDefaultNull, castConfig);
    return addSourceLocation(stmt, startStmtToken);
  }
}

CreateIndexStatement.IndexedElement IndexedElement(Token startElementToken) throws ParseException:
{
  Triple<Integer, List<List<String>>, List<Pair<List<String>, IndexedTypeExpression>>> element = null;
  Pair<List<String>, IndexedTypeExpression> elementSimple = null;
  int elementSimpleSource = 0;
}
{
  (
    element = IndexedElementUnnestSelect()
    | (
        LOOKAHEAD({ laIdentifier(META) && laToken(2, LEFTPAREN) && laToken(3, RIGHTPAREN) })
        <IDENTIFIER> { expectToken(META); } <LEFTPAREN> <RIGHTPAREN>
        <DOT> elementSimple = IndexedField()
        { elementSimpleSource = 1; }
      )
    | elementSimple = IndexedField()
    | <LEFTPAREN> ( element = IndexedElementUnnestSelect() | elementSimple = IndexedField() ) <RIGHTPAREN>
  )
  {
    int source;
    List<List<String>> unnestList;
    List<Pair<List<String>, IndexedTypeExpression>> projectList;
    if (elementSimple != null) {
      source = elementSimpleSource;
      unnestList = null;
      projectList = Collections.singletonList(elementSimple);
    } else {
      source = element.first;
      unnestList = element.second;
      projectList = element.third;
    }
    CreateIndexStatement.IndexedElement ie = new CreateIndexStatement.IndexedElement(source, unnestList, projectList);
    ie.setSourceLocation(getSourceLocation(startElementToken));
    return ie;
  }
}

Triple<Integer, List<List<String>>, List<Pair<List<String>, IndexedTypeExpression>>> IndexedElementUnnestSelect()
  throws ParseException:
{
  int source = 0;
  Pair<List<List<String>>, List<Pair<List<String>, IndexedTypeExpression>>> element = null;
}
{
  <UNNEST>
  (
    (
       LOOKAHEAD({ laIdentifier(META) && laToken(2, LEFTPAREN) && laToken(3, RIGHTPAREN) })
       <IDENTIFIER> { expectToken(META); } <LEFTPAREN> <RIGHTPAREN>
       <DOT> element = IndexedElementUnnestSelectBody() { source = 1; }
    ) | element = IndexedElementUnnestSelectBody()
  )
  {
    return new Triple<Integer, List<List<String>>, List<Pair<List<String>, IndexedTypeExpression>>>(
      source, element.first, element.second
    );
  }
}

Pair<List<List<String>>, List<Pair<List<String>, IndexedTypeExpression>>> IndexedElementUnnestSelectBody()
  throws ParseException:
{
  Triple<List<String>, Token, Token> path = null;
  IndexedTypeExpression type = null;
  List<List<String>> unnestList = new ArrayList();
  List<Pair<List<String>, IndexedTypeExpression>> projectList = new ArrayList();
}
{
  path = MultipartIdentifier() { unnestList.add(path.first); }
  ( <UNNEST> path = MultipartIdentifier() { unnestList.add(path.first); })*
  (
    ( <COLON> type = IndexedTypeExpr(false)
      {
        projectList.add(new Pair<List<String>, IndexedTypeExpression>(null, type));
      }
    ) |
    (
      <SELECT> path = MultipartIdentifier() ( <COLON> type = IndexedTypeExpr(false) )?
      {
        projectList.add(new Pair<List<String>, IndexedTypeExpression>(path.first, type));
      }
      ( <COMMA> path = MultipartIdentifier() ( <COLON> type = IndexedTypeExpr(false) )?
        {
          projectList.add(new Pair<List<String>, IndexedTypeExpression>(path.first, type));
        }
      )*
    )
  )?
  {
    if (projectList.isEmpty()) {
      // To support the case (<UNNEST> IDENTIFIER)* IDENTIFIER w/o any type specification.
      projectList.add(new Pair<List<String>, IndexedTypeExpression>(null, null));
    }

    return new Pair<List<List<String>>, List<Pair<List<String>, IndexedTypeExpression>>>(unnestList, projectList);
  }
}

Pair<List<String>, IndexedTypeExpression> IndexedField() throws ParseException:
{
  Triple<List<String>, Token, Token> path = null;
  IndexedTypeExpression type = null;
}
{
  path = MultipartIdentifier() ( <COLON> type = IndexedTypeExpr(true) )?
  {
    return new Pair<List<String>, IndexedTypeExpression>(path.first, type);
  }
}

CreateIndexStatement PrimaryIndexSpecification(Token startStmtToken) throws ParseException:
{
  Pair<DataverseName,Identifier> nameComponents = null;
  String indexName = null;
  boolean ifNotExists = false;
}
{
  (indexName = Identifier())? ifNotExists = IfNotExists()
  <ON> nameComponents = QualifiedName() (<TYPE> <BTREE>)?
  {
    if (indexName == null) {
      indexName = MetadataConstants.PRIMARY_INDEX_PREFIX + nameComponents.second;
    }
    CreateIndexStatement stmt = new CreateIndexStatement(nameComponents.first, nameComponents.second,
      new Identifier(indexName), IndexType.BTREE, Collections.emptyList(), false, -1, null, ifNotExists, null, null,
      Collections.emptyMap());
    return addSourceLocation(stmt, startStmtToken);
  }
}

String FilterField() throws ParseException :
{
  String filterField = null;
}
{
  filterField = Identifier()
    {
      return filterField;
    }
}

IndexParams IndexType() throws ParseException:
{
  IndexType type = null;
  int gramLength = 0;
  String fullTextConfig = null;
}
{
  (<BTREE>
    {
      type = IndexType.BTREE;
    }
  | <RTREE>
    {
      type = IndexType.RTREE;
    }
  | <KEYWORD>
    {
      type = IndexType.LENGTH_PARTITIONED_WORD_INVIX;
    }
  | <FULLTEXT>
    {
      type = IndexType.SINGLE_PARTITION_WORD_INVIX;
    }
    // For now we don't allow inverted index creation using a full-text config in another data verse.
    // We may want to support corss-dataverse full-text config access later
    // If so, replace the Identifier() with QualifiedName() to get the dataverse name
    ( <USING> Identifier()
      {
        fullTextConfig = token.image;
      }
    )?
  | <NGRAM> <LEFTPAREN> <INTEGER_LITERAL>
    {
      type = IndexType.LENGTH_PARTITIONED_NGRAM_INVIX;
      gramLength = Integer.valueOf(token.image);
    }
  <RIGHTPAREN>)
    {
      return new IndexParams(type, gramLength, fullTextConfig);
    }
}

CreateDataverseStatement CreateDataverseStatement(Token startStmtToken) throws ParseException :
{
  CreateDataverseStatement stmt = null;
}
{
  <DATAVERSE> stmt = DataverseSpecification(startStmtToken)
  {
    return stmt;
  }
}

CreateDataverseStatement DataverseSpecification(Token startStmtToken) throws ParseException :
{
  DataverseName dvName = null;
  boolean ifNotExists = false;
}
{
  dvName = DataverseName() ifNotExists = IfNotExists()
  {
    CreateDataverseStatement stmt = new CreateDataverseStatement(dvName, null, ifNotExists);
    return addSourceLocation(stmt, startStmtToken);
  }
}

CreateAdapterStatement CreateAdapterStatement(Token startStmtToken) throws ParseException:
{
  CreateAdapterStatement stmt = null;
}
{
  <ADAPTER> stmt = AdapterSpecification(startStmtToken)
  {
    return stmt;
  }
}

CreateAdapterStatement AdapterSpecification(Token startStmtToken) throws ParseException:
{
  Pair<DataverseName,Identifier> adapterName = null;
  Pair<DataverseName,Identifier> libraryName = null;
  List<String> externalIdentifier = null;
  boolean ifNotExists = false;
}
{
  adapterName = QualifiedName()
  ifNotExists = IfNotExists()
  <AS> externalIdentifier = FunctionExternalIdentifier()
  <AT> libraryName = QualifiedName()
  {
    CreateAdapterStatement stmt = new CreateAdapterStatement(adapterName.first, adapterName.second.getValue(),
      libraryName.first, libraryName.second.getValue(), externalIdentifier, ifNotExists);
    return addSourceLocation(stmt, startStmtToken);
  }
}

CreateViewStatement CreateViewStatement(Token startStmtToken, boolean orReplace) throws ParseException:
{
  CreateViewStatement stmt = null;
}
{
  <VIEW> stmt = ViewSpecification(startStmtToken, orReplace)
  {
    return stmt;
  }
}

CreateViewStatement ViewSpecification(Token startStmtToken, boolean orReplace) throws ParseException:
{
  Pair<DataverseName, Identifier> nameComponents = null;
  TypeExpression typeExpr = null;
  boolean ifNotExists = false;
  Token beginPos = null, endPos = null;
  Expression viewBodyExpr = null;
  Pair<Map<String, String>, Boolean> viewConfigDefaultNull;
  Boolean defaultNull = null;
  Map<String, String> viewConfig = null;
  Pair<List<Integer>, List<List<String>>> primaryKeyFields = null;
  Pair<List<Integer>, List<List<String>>> foreignKeyFields = null;
  Pair<DataverseName, Identifier> refNameComponents = null;
  List<CreateViewStatement.ForeignKeyDecl> foreignKeyDecls = null;
  DataverseName currentDataverse = defaultDataverse;
}
{
  nameComponents = QualifiedName()
  (
      (
        typeExpr = DatasetTypeSpecification()
        ifNotExists = IfNotExists()
        viewConfigDefaultNull = CastDefaultNull()
        {
          viewConfig = viewConfigDefaultNull.first;
          defaultNull = viewConfigDefaultNull.second;
        }
        (
          <PRIMARY> <KEY> <LEFTPAREN> primaryKeyFields = PrimaryKeyFields() <RIGHTPAREN>
          <NOT> <ENFORCED>
        )?
        (
          <IDENTIFIER> { expectToken(FOREIGN); } <KEY> <LEFTPAREN> foreignKeyFields = PrimaryKeyFields() <RIGHTPAREN>
          <IDENTIFIER> { expectToken(REFERENCES); } refNameComponents = QualifiedName()
          <NOT> <ENFORCED>
          {
            if (foreignKeyDecls == null) {
              foreignKeyDecls = new ArrayList<CreateViewStatement.ForeignKeyDecl>();
            }
            foreignKeyDecls.add(new CreateViewStatement.ForeignKeyDecl(foreignKeyFields.second,
              foreignKeyFields.first, refNameComponents.first, refNameComponents.second));
          }
        )*
      )
      |
      ( ifNotExists = IfNotExists() )
  )
  {
    if (orReplace && ifNotExists) {
      throw new SqlppParseException(getSourceLocation(startStmtToken), "Unexpected IF NOT EXISTS");
    }
  }
  <AS>
  {
    beginPos = token;
    createNewScope();
    if (nameComponents.first != null) {
      defaultDataverse = nameComponents.first;
    }
  }
  viewBodyExpr = ViewBody()
  {
    endPos = token;
    String viewBody = extractFragment(beginPos.beginLine, beginPos.beginColumn + 1, endPos.endLine,
      endPos.endColumn + 1);
    removeCurrentScope();
    defaultDataverse = currentDataverse;
    if (typeExpr != null && primaryKeyFields != null) {
      DatasetDeclParametersUtil.adjustInlineTypeDecl(typeExpr, primaryKeyFields.second, primaryKeyFields.first, false);
    }
    CreateViewStatement.KeyDecl primaryKeyDecl = primaryKeyFields != null ?
      new CreateViewStatement.KeyDecl(primaryKeyFields.second, primaryKeyFields.first) : null;
    CreateViewStatement stmt = new CreateViewStatement(nameComponents.first, nameComponents.second.getValue(),
      typeExpr, viewBody, viewBodyExpr, defaultNull, viewConfig, primaryKeyDecl, foreignKeyDecls, orReplace,
      ifNotExists);
    return addSourceLocation(stmt, startStmtToken);
  }
}

Expression ViewBody() throws ParseException:
{
  Expression viewBodyExpr = null;
}
{
  (
    ( viewBodyExpr = VariableRef() ( viewBodyExpr = FieldAccessor(viewBodyExpr) )* )
    | viewBodyExpr = SelectExpression(true)
  )
  {
    return viewBodyExpr;
  }
}

Pair<Map<String, String>, Boolean> CastDefaultNull() throws ParseException:
{
  Map<String, String> castConfig = null;
  Boolean defaultNull = null;
  String propertyName = null, propertyValue = null;
}
{
  <IDENTIFIER> { expectToken(DEFAULT); } <NULL> { defaultNull = true; }
    (
      LOOKAHEAD(2) <IDENTIFIER> { propertyName = token.image.toLowerCase(); } propertyValue = StringLiteral()
      {
        if (castConfig == null) {
          castConfig = new HashMap<String, String>();
        }
        castConfig.put(propertyName, propertyValue);
      }
    )*
  {
    return new Pair<Map<String, String>, Boolean>(castConfig, defaultNull);
  }
}

CreateFunctionStatement CreateFunctionStatement(Token startStmtToken, boolean orReplace) throws ParseException:
{
  CreateFunctionStatement stmt = null;
}
{
  <FUNCTION> stmt = FunctionSpecification(startStmtToken, orReplace)
  {
    return stmt;
  }
}

CreateFunctionStatement FunctionSpecification(Token startStmtToken, boolean orReplace) throws ParseException:
{
  FunctionSignature signature = null;
  FunctionName fctName = null;
  Pair<Integer, List<Pair<VarIdentifier,TypeExpression>>> paramsWithArity = null;
  List<Pair<VarIdentifier,TypeExpression>> params = null;
  int arity = 0;
  TypeExpression returnType = null;
  Token beginPos = null, endPos = null;
  Expression functionBodyExpr = null;
  Pair<DataverseName,Identifier> libraryName = null;
  List<String> externalIdentifier = null;
  RecordConstructor withOptions = null;
  boolean ifNotExists = false;
  CreateFunctionStatement stmt = null;
  DataverseName currentDataverse = defaultDataverse;
}
{
  fctName = FunctionName()
  {
     defaultDataverse = fctName.dataverse;
  }
  paramsWithArity = FunctionParameters()
  {
    arity = paramsWithArity.first;
    params = paramsWithArity.second;
    signature = new FunctionSignature(fctName.dataverse, fctName.function, arity);
  }
  ifNotExists = IfNotExists()
  {
    if (orReplace && ifNotExists) {
      throw new SqlppParseException(getSourceLocation(token), "Unexpected IF NOT EXISTS");
    }
  }
  returnType = FunctionReturnType()
  (
    (
      <LEFTBRACE>
      {
        beginPos = token;
        createNewScope();
      }
      functionBodyExpr = FunctionBody()
      <RIGHTBRACE>
      {
        endPos = token;
        String functionBody = extractFragment(beginPos.beginLine, beginPos.beginColumn, endPos.beginLine,
          endPos.beginColumn);
        getCurrentScope().addFunctionDescriptor(signature, false);
        removeCurrentScope();
        ensureNoTypeDeclsInFunction(fctName.function, params, returnType, startStmtToken);
        stmt = new CreateFunctionStatement(signature, params, functionBody, functionBodyExpr, orReplace, ifNotExists);
      }
    )
  |
    (
      <AS> externalIdentifier = FunctionExternalIdentifier()
      <AT> libraryName = QualifiedName()
      (<WITH> withOptions = RecordConstructor())?
      {
        try {
          stmt = new CreateFunctionStatement(signature, params, returnType, libraryName.first,
            libraryName.second.getValue(), externalIdentifier, withOptions, orReplace, ifNotExists);
        } catch (AlgebricksException e) {
            throw new SqlppParseException(getSourceLocation(startStmtToken), e.getMessage());
        }
      }
    )
  )
  {
    defaultDataverse = currentDataverse;
    return addSourceLocation(stmt, startStmtToken);
  }
}

Pair<Integer, List<Pair<VarIdentifier, TypeExpression>>> FunctionParameters() :
{
  Pair<Integer, List<Pair<VarIdentifier, TypeExpression>>> params = null;
}
{
  <LEFTPAREN> (params = FunctionParameterList())? <RIGHTPAREN>
  {
    if (params == null) {
      params = new Pair<Integer, List<Pair<VarIdentifier, TypeExpression>>>(
        0, Collections.<Pair<VarIdentifier, TypeExpression>>emptyList()
      );
    }
    return params;
  }
}

Pair<Integer, List<Pair<VarIdentifier, TypeExpression>>> FunctionParameterList() :
{
  List<Pair<VarIdentifier, TypeExpression>> paramList = null;
  Pair<VarIdentifier, TypeExpression> param = null;
  int arity = 0;
}
{
  (
    (
      <DOT> <DOT> <DOT>
      {
        param = new Pair<VarIdentifier, TypeExpression>(
          SqlppVariableUtil.toInternalVariableIdentifier(UDF_VARARGS_PARAM_NAME), null
        );
        paramList = Collections.<Pair<VarIdentifier, TypeExpression>>singletonList(param);
        arity = FunctionIdentifier.VARARGS;
      }
    )
    |
    (
      param = FunctionParameter()
      {
        paramList = new ArrayList<Pair<VarIdentifier, TypeExpression>>();
        paramList.add(param);
      }
      ( <COMMA> param = FunctionParameter() { paramList.add(param); } )*
      {
        arity = paramList.size();
      }
    )
  )
  {
    return new Pair<Integer, List<Pair<VarIdentifier, TypeExpression>>>(arity, paramList);
  }
}

Pair<VarIdentifier,TypeExpression> FunctionParameter() throws ParseException:
{
  String name = null;
  TypeExpression type = null;
}
{
  name = VariableIdentifier()
  ( LOOKAHEAD(3) (<COLON>)? type = TypeExpr(false) )?
  {
    return new Pair<VarIdentifier,TypeExpression>(new VarIdentifier(name), type);
  }
}

TypeExpression FunctionReturnType() throws ParseException:
{
  TypeExpression returnType = null;
}
{
  ( LOOKAHEAD({laIdentifier(RETURNS)}) <IDENTIFIER> returnType = TypeExpr(false) )?
  {
    return returnType;
  }
}

Expression FunctionBody() throws ParseException:
{
  Expression functionBodyExpr = null;
}
{
  ( functionBodyExpr = SelectExpression(true) | functionBodyExpr = Expression() )
  {
    return functionBodyExpr;
  }
}

List<String> FunctionExternalIdentifier() throws ParseException:
{
  String ident = null;
  List<String> identList = new ArrayList(2);
}
{
  ident = StringLiteral() { identList.add(ident.trim()); }
  ( <COMMA> ident = StringLiteral() { identList.add(ident.trim()); } )*
  {
    return identList;
  }
}

CreateFeedStatement CreateFeedStatement(Token startStmtToken) throws ParseException:
{
  CreateFeedStatement stmt = null;
}
{
  <FEED> stmt = FeedSpecification(startStmtToken)
  {
    return stmt;
  }
}

CreateFeedStatement FeedSpecification(Token startStmtToken) throws ParseException:
{
  Pair<DataverseName,Identifier> nameComponents = null;
  boolean ifNotExists = false;
  String adapterName = null;
  Map<String,String> properties = null;
  CreateFeedStatement stmt = null;
  Pair<Identifier,Identifier> sourceNameComponents = null;
  RecordConstructor withRecord = null;
}
{
  nameComponents = QualifiedName() ifNotExists = IfNotExists()
  <WITH> withRecord = RecordConstructor()
  {
    try {
      stmt = new CreateFeedStatement(nameComponents, withRecord, ifNotExists);
      return addSourceLocation(stmt, startStmtToken);
    } catch (AlgebricksException e) {
      throw new SqlppParseException(getSourceLocation(startStmtToken), e.getMessage());
    }
  }
}

CreateFeedPolicyStatement CreateFeedPolicyStatement(Token startStmtToken) throws ParseException:
{
  CreateFeedPolicyStatement stmt = null;
}
{
  <INGESTION> <POLICY> stmt = FeedPolicySpecification(startStmtToken)
  {
    return stmt;
  }
}

CreateFeedPolicyStatement FeedPolicySpecification(Token startStmtToken) throws ParseException:
{
  String policyName = null;
  String basePolicyName = null;
  String sourcePolicyFile = null;
  String definition = null;
  boolean ifNotExists = false;
  Map<String,String> properties = null;
  CreateFeedPolicyStatement stmt = null;
}
{
  policyName = Identifier() ifNotExists = IfNotExists()
  <FROM>
  (<POLICY> basePolicyName = Identifier() properties = Configuration() (<DEFINITION> definition = ConstantString())?
    {
      stmt = new CreateFeedPolicyStatement(policyName, basePolicyName, properties, definition, ifNotExists);
    }
  | <PATH> sourcePolicyFile = ConstantString() (<DEFINITION> definition = ConstantString())?
    {
      stmt = new CreateFeedPolicyStatement(policyName, sourcePolicyFile, definition, ifNotExists);
    }
  )
  {
    return addSourceLocation(stmt, startStmtToken);
  }
}

Statement CreateFullTextStatement(Token startStmtToken) throws ParseException:
{
  Statement stmt = null;
}
{
  (
    <FULLTEXT>
    (
      <FILTER> stmt = CreateFullTextFilterSpec(startStmtToken)
      | (<IDENTIFIER> { expectToken(CONFIG); } stmt = CreateFullTextConfigSpec(startStmtToken))
    )
  )
  {
    return stmt;
  }
}

CreateFullTextFilterStatement CreateFullTextFilterSpec(Token startStmtToken) throws ParseException:
{
  CreateFullTextFilterStatement stmt = null;
  Pair<DataverseName,Identifier> nameComponents = null;
  boolean ifNotExists = false;
  RecordConstructor expr = null;
}
{
  (
    nameComponents = QualifiedName() ifNotExists = IfNotExists()
    <AS>
    expr = RecordConstructor()
  )
  {
    try {
      stmt = new CreateFullTextFilterStatement(nameComponents.first, nameComponents.second.getValue(), ifNotExists, expr);
      return addSourceLocation(stmt, startStmtToken);
    } catch (CompilationException e) {
       throw new SqlppParseException(getSourceLocation(startStmtToken), e.getMessage());
    }
  }
}

CreateFullTextConfigStatement CreateFullTextConfigSpec(Token startStmtToken) throws ParseException:
{
  CreateFullTextConfigStatement stmt = null;
  Pair<DataverseName,Identifier> nameComponents = null;
  boolean ifNotExists = false;
  RecordConstructor expr = null;
}
{
  (
    nameComponents = QualifiedName() ifNotExists = IfNotExists()
    <AS>
    expr = RecordConstructor()
  )
  {
    try {
      stmt = new CreateFullTextConfigStatement(nameComponents.first, nameComponents.second.getValue(), ifNotExists, expr);
      return addSourceLocation(stmt, startStmtToken);
    } catch (CompilationException e) {
       throw new SqlppParseException(getSourceLocation(startStmtToken), e.getMessage());
    }
  }
}

CreateSynonymStatement CreateSynonymStatement(Token startStmtToken) throws ParseException:
{
  CreateSynonymStatement stmt = null;
}
{
  <SYNONYM> stmt = SynonymSpecification(startStmtToken)
  {
    return stmt;
  }
}

CreateSynonymStatement SynonymSpecification(Token startStmtToken) throws ParseException:
{
  Pair<DataverseName,Identifier> nameComponents = null;
  Pair<DataverseName,Identifier> objectNameComponents = null;
  boolean ifNotExists = false;
}
{
  nameComponents = QualifiedName() ifNotExists = IfNotExists()
  <FOR> objectNameComponents = QualifiedName()
  {
    CreateSynonymStatement stmt = new CreateSynonymStatement(nameComponents.first, nameComponents.second.getValue(),
      objectNameComponents.first, objectNameComponents.second.getValue(), ifNotExists);
    return addSourceLocation(stmt, startStmtToken);
  }
}

boolean IfNotExists() throws ParseException:
{
}
{
  ( LOOKAHEAD(1) <IF> <NOT> <EXISTS>
    {
      return true;
    }
  )?
    {
      return false;
    }
}

void ApplyFunction(List<FunctionSignature> funcSigs) throws ParseException:
{
  FunctionName functionName = null;
  String fqFunctionName = null;
}
{
  <APPLY> <FUNCTION> functionName = FunctionName()
  {
     fqFunctionName = functionName.library == null ? functionName.function : functionName.library + "#" + functionName.function;
     funcSigs.add(new FunctionSignature(functionName.dataverse, fqFunctionName, 1));
  }
  (
      <COMMA> functionName = FunctionName()
      {
        fqFunctionName = functionName.library == null ? functionName.function : functionName.library + "#" + functionName.function;
        funcSigs.add(new FunctionSignature(functionName.dataverse, fqFunctionName, 1));
      }
  )*
}

String GetPolicy() throws ParseException:
{
  String policy = null;
}
{
   <USING> <POLICY> policy = Identifier()
   {
     return policy;
   }

}

FunctionSignature FunctionSignature() throws ParseException:
{
  FunctionName fctName = null;
  Pair<Integer, List<Pair<VarIdentifier,TypeExpression>>> params = null;
  int arity = 0;
}
{
  fctName = FunctionName()
  (
    LOOKAHEAD(2) params = FunctionParameters() { arity = params.first; }
  | ( <LEFTPAREN> arity = FunctionArity() <RIGHTPAREN> )
  | ( <ATT> arity = FunctionArity() ) // back-compat
  )
  {
    return new FunctionSignature(fctName.dataverse, fctName.function, arity);
  }
}

int FunctionArity() throws ParseException:
{
  int arity;
}
{
  <INTEGER_LITERAL>
  {
    try {
      arity = Integer.parseInt(token.image);
    } catch (NumberFormatException e) {
      throw new SqlppParseException(getSourceLocation(token), "Invalid arity: " + token.image);
    }
    if (arity < 0 && arity != FunctionIdentifier.VARARGS) {
      throw new SqlppParseException(getSourceLocation(token), "Invalid arity: " + arity);
    }
    return arity;
  }
}

Pair<List<Integer>, List<List<String>>> PrimaryKey() throws ParseException:
{
  Pair<List<Integer>, List<List<String>>> primaryKeyFields = null;
}
{
  <PRIMARY> <KEY> primaryKeyFields = PrimaryKeyFields()
  {
    return primaryKeyFields;
  }
}

Pair<List<Integer>, List<List<String>>> PrimaryKeyFields() throws ParseException:
{
  Pair<Integer, List<String>> tmp = null;
  List<Integer> keyFieldSourceIndicators = new ArrayList<Integer>();
  List<List<String>> primaryKeyFields = new ArrayList<List<String>>();
}
{
  tmp = NestedField()
    {
      keyFieldSourceIndicators.add(tmp.first);
      primaryKeyFields.add(tmp.second);
    }
  ( <COMMA> tmp = NestedField()
    {
      keyFieldSourceIndicators.add(tmp.first);
      primaryKeyFields.add(tmp.second);
    }
  )*
    {
      return new Pair<List<Integer>, List<List<String>>> (keyFieldSourceIndicators, primaryKeyFields);
    }
}

Statement DropStatement() throws ParseException:
{
  Token startToken = null;
  Statement stmt = null;
}
{
  <DROP> { startToken = token; }
  (
    stmt = DropDatasetStatement(startToken)
    | stmt = DropIndexStatement(startToken)
    | stmt = DropNodeGroupStatement(startToken)
    | stmt = DropTypeStatement(startToken)
    | stmt = DropDataverseStatement(startToken)
    | stmt = DropAdapterStatement(startToken)
    | stmt = DropFunctionStatement(startToken)
    | stmt = DropFeedStatement(startToken)
    | stmt = DropFeedPolicyStatement(startToken)
    | stmt = DropSynonymStatement(startToken)
    | stmt = DropFullTextStatement(startToken)
    | stmt = DropViewStatement(startToken)
  )
  {
    return stmt;
  }
}

DropDatasetStatement DropDatasetStatement(Token startStmtToken) throws ParseException:
{
  DropDatasetStatement stmt = null;
}
{
  Dataset() stmt = DropDatasetSpecification(startStmtToken)
  {
    return stmt;
  }
}

DropDatasetStatement DropDatasetSpecification(Token startStmtToken) throws ParseException:
{
  Pair<DataverseName,Identifier> pairId = null;
  boolean ifExists = false;
}
{
  pairId = QualifiedName() ifExists = IfExists()
  {
    DropDatasetStatement stmt = new DropDatasetStatement(pairId.first, pairId.second, ifExists);
    return addSourceLocation(stmt, startStmtToken);
  }
}

ViewDropStatement DropViewStatement(Token startStmtToken) throws ParseException:
{
  ViewDropStatement stmt = null;
}
{
  <VIEW> stmt = DropViewSpecification(startStmtToken)
  {
    return stmt;
  }
}

ViewDropStatement DropViewSpecification(Token startStmtToken) throws ParseException:
{
  Pair<DataverseName,Identifier> pairId = null;
  boolean ifExists = false;
}
{
  pairId = QualifiedName() ifExists = IfExists()
  {
    ViewDropStatement stmt = new ViewDropStatement(pairId.first, pairId.second, ifExists);
    return addSourceLocation(stmt, startStmtToken);
  }
}

IndexDropStatement DropIndexStatement(Token startStmtToken) throws ParseException:
{
  IndexDropStatement stmt = null;
}
{
  <INDEX> stmt = DropIndexSpecification(startStmtToken)
  {
    return stmt;
  }
}

IndexDropStatement DropIndexSpecification(Token startStmtToken) throws ParseException:
{
  Triple<DataverseName,Identifier,Identifier> tripleId = null;
  boolean ifExists = false;
}
{
  tripleId = DoubleQualifiedName() ifExists = IfExists()
  {
    IndexDropStatement stmt = new IndexDropStatement(tripleId.first, tripleId.second, tripleId.third, ifExists);
    return addSourceLocation(stmt, startStmtToken);
  }
}

Statement DropFullTextStatement(Token startStmtToken) throws ParseException:
{
  Statement stmt = null;
}
{
  <FULLTEXT>
  (
    <FILTER> stmt = DropFullTextFilterSpec(startStmtToken)
     | (<IDENTIFIER> { expectToken(CONFIG); } stmt = DropFullTextConfigSpec(startStmtToken))
  )
  {
    return stmt;
  }
}

FullTextFilterDropStatement DropFullTextFilterSpec(Token startStmtToken) throws ParseException:
{
  FullTextFilterDropStatement stmt = null;
  Pair<DataverseName,Identifier> nameComponents = null;
  boolean ifExists = false;
}
{
  nameComponents = QualifiedName() ifExists = IfExists()
  {
    stmt = new FullTextFilterDropStatement(nameComponents.first, nameComponents.second.getValue(), ifExists);
    return addSourceLocation(stmt, startStmtToken);
  }
}

FullTextConfigDropStatement DropFullTextConfigSpec(Token startStmtToken) throws ParseException:
{
  FullTextConfigDropStatement stmt = null;
  Pair<DataverseName,Identifier> nameComponents = null;
  boolean ifExists = false;
}
{
  nameComponents = QualifiedName() ifExists = IfExists()
  {
    stmt = new FullTextConfigDropStatement(nameComponents.first, nameComponents.second.getValue(), ifExists);
    return addSourceLocation(stmt, startStmtToken);
  }
}


NodeGroupDropStatement DropNodeGroupStatement(Token startStmtToken) throws ParseException:
{
  NodeGroupDropStatement stmt = null;
}
{
  <NODEGROUP> stmt = DropNodeGroupSpecification(startStmtToken)
  {
    return stmt;
  }
}

NodeGroupDropStatement DropNodeGroupSpecification(Token startStmtToken) throws ParseException:
{
  String id = null;
  boolean ifExists = false;
}
{
  id = Identifier() ifExists = IfExists()
  {
    NodeGroupDropStatement stmt = new NodeGroupDropStatement(new Identifier(id), ifExists);
    return addSourceLocation(stmt, startStmtToken);
  }
}

TypeDropStatement DropTypeStatement(Token startStmtToken) throws ParseException:
{
  TypeDropStatement stmt = null;
}
{
  <TYPE> stmt = DropTypeSpecification(startStmtToken)
  {
    return stmt;
  }
}

TypeDropStatement DropTypeSpecification(Token startStmtToken) throws ParseException:
{
  Pair<DataverseName,Identifier> pairId = null;
  boolean ifExists = false;
}
{
  pairId = TypeName() ifExists = IfExists()
  {
    TypeDropStatement stmt = new TypeDropStatement(pairId.first, pairId.second, ifExists);
    return addSourceLocation(stmt, startStmtToken);
  }
}

DataverseDropStatement DropDataverseStatement(Token startStmtToken) throws ParseException:
{
  DataverseDropStatement stmt = null;
}
{
  <DATAVERSE> stmt = DropDataverseSpecification(startStmtToken)
  {
    return stmt;
  }
}

DataverseDropStatement DropDataverseSpecification(Token startStmtToken) throws ParseException:
{
  DataverseName dvName = null;
  boolean ifExists = false;
}
{
  dvName = DataverseName() ifExists = IfExists()
  {
    DataverseDropStatement stmt = new DataverseDropStatement(dvName, ifExists);
    return addSourceLocation(stmt, startStmtToken);
  }
}

AdapterDropStatement DropAdapterStatement(Token startStmtToken) throws ParseException:
{
  AdapterDropStatement stmt = null;
}
{
  <ADAPTER> stmt = DropAdapterSpecification(startStmtToken)
  {
    return stmt;
  }
}

AdapterDropStatement DropAdapterSpecification(Token startStmtToken) throws ParseException:
{
  Pair<DataverseName,Identifier> adapterName = null;
  boolean ifExists = false;
}
{
  adapterName = QualifiedName() ifExists = IfExists()
  {
    AdapterDropStatement stmt = new AdapterDropStatement(adapterName.first, adapterName.second.getValue(), ifExists);
    return addSourceLocation(stmt, startStmtToken);
  }
}

FunctionDropStatement DropFunctionStatement(Token startStmtToken) throws ParseException:
{
  FunctionDropStatement stmt = null;
}
{
  <FUNCTION> stmt = DropFunctionSpecification(startStmtToken)
  {
    return stmt;
  }
}

FunctionDropStatement DropFunctionSpecification(Token startStmtToken) throws ParseException:
{
  FunctionSignature funcSig = null;
  boolean ifExists = false;
}
{
  funcSig = FunctionSignature() ifExists = IfExists()
  {
    FunctionDropStatement stmt = new FunctionDropStatement(funcSig, ifExists);
    return addSourceLocation(stmt, startStmtToken);
  }
}

FeedDropStatement DropFeedStatement(Token startStmtToken) throws ParseException:
{
  FeedDropStatement stmt = null;
}
{
  <FEED> stmt = DropFeedSpecification(startStmtToken)
  {
    return stmt;
  }
}

FeedDropStatement DropFeedSpecification(Token startStmtToken) throws ParseException:
{
  Pair<DataverseName,Identifier> pairId = null;
  boolean ifExists = false;
}
{
  pairId = QualifiedName() ifExists = IfExists()
  {
    FeedDropStatement stmt = new FeedDropStatement(pairId.first, pairId.second, ifExists);
    return addSourceLocation(stmt, startStmtToken);
  }
}

FeedPolicyDropStatement DropFeedPolicyStatement(Token startStmtToken) throws ParseException:
{
  FeedPolicyDropStatement stmt = null;
}
{
  <INGESTION> <POLICY> stmt = DropFeedPolicySpecification(startStmtToken)
  {
    return stmt;
  }
}

FeedPolicyDropStatement DropFeedPolicySpecification(Token startStmtToken) throws ParseException:
{
  Pair<DataverseName,Identifier> pairId = null;
  boolean ifExists = false;
}
{
  pairId = QualifiedName() ifExists = IfExists()
  {
    FeedPolicyDropStatement stmt = new FeedPolicyDropStatement(pairId.first, pairId.second, ifExists);
    return addSourceLocation(stmt, startStmtToken);
  }
}

SynonymDropStatement DropSynonymStatement(Token startStmtToken) throws ParseException:
{
  SynonymDropStatement stmt = null;
}
{
  <SYNONYM> stmt = DropSynonymSpecification(startStmtToken)
  {
    return stmt;
  }
}

SynonymDropStatement DropSynonymSpecification(Token startStmtToken) throws ParseException:
{
  Pair<DataverseName,Identifier> pairId = null;
  boolean ifExists = false;
}
{
  pairId = QualifiedName() ifExists = IfExists()
  {
    SynonymDropStatement stmt = new SynonymDropStatement(pairId.first, pairId.second.getValue(), ifExists);
    return addSourceLocation(stmt, startStmtToken);
  }
}

boolean IfExists() throws ParseException :
{
}
{
  ( LOOKAHEAD(1) <IF> <EXISTS>
    {
      return true;
    }
  )?
    {
      return false;
    }
}

InsertStatement InsertStatement() throws ParseException:
{
  Token startToken = null;
  Pair<DataverseName,Identifier> nameComponents = null;
  VariableExpr var = null;
  Query query = null;
  Expression returnExpression = null;
}
{
  <INSERT> { startToken = token; } <INTO> nameComponents = QualifiedName() (<AS> var = Variable())?
    query = Query()
    ( <RETURNING> returnExpression = Expression())?
    {
      if (var == null && returnExpression != null) {
        var = new VariableExpr(SqlppVariableUtil.toInternalVariableIdentifier(nameComponents.second.getValue()));
        addSourceLocation(var, startToken);
      }
      query.setTopLevel(true);
      InsertStatement stmt = new InsertStatement(nameComponents.first, nameComponents.second.getValue(), query,
        getVarCounter(), var, returnExpression);
      return addSourceLocation(stmt, startToken);
    }
}

UpsertStatement UpsertStatement() throws ParseException:
{
  Token startToken = null;
  Pair<DataverseName,Identifier> nameComponents = null;
  VariableExpr var = null;
  Query query = null;
  Expression returnExpression = null;
}
{
  <UPSERT> { startToken = token; } <INTO> nameComponents = QualifiedName() (<AS> var = Variable())?
    query = Query()
    ( <RETURNING> returnExpression = Expression())?
    {
      if (var == null && returnExpression != null) {
          var = new VariableExpr(SqlppVariableUtil.toInternalVariableIdentifier(nameComponents.second.getValue()));
          addSourceLocation(var, startToken);
      }
      query.setTopLevel(true);
      UpsertStatement stmt = new UpsertStatement(nameComponents.first, nameComponents.second.getValue(), query,
        getVarCounter(), var, returnExpression);
      return addSourceLocation(stmt, startToken);
    }
}

DeleteStatement DeleteStatement() throws ParseException:
{
  Token startToken = null;
  VariableExpr var = null;
  Expression condition = null;
  Pair<DataverseName, Identifier> nameComponents;
}
{
  <DELETE> { startToken = token; }
  <FROM> nameComponents  = QualifiedName() ((<AS>)? var = Variable())?
  (<WHERE> condition = Expression())?
  {
      if (var == null) {
        var = new VariableExpr(SqlppVariableUtil.toInternalVariableIdentifier(nameComponents.second.getValue()));
        addSourceLocation(var, startToken);
      }
      DeleteStatement stmt = new DeleteStatement(var, nameComponents.first, nameComponents.second.getValue(),
          condition, getVarCounter());
      return addSourceLocation(stmt, startToken);
  }
}

UpdateStatement UpdateStatement() throws ParseException:
{
  Token startToken = null;
  VariableExpr vars;
  Expression target;
  Expression condition;
  UpdateClause uc;
  List<UpdateClause> ucs = new ArrayList<UpdateClause>();
}
{
  <UPDATE> { startToken = token; } vars = Variable() <IN> target = Expression()
  <WHERE> condition = Expression()
  <LEFTPAREN> (uc = UpdateClause()
    {
      ucs.add(uc);
    }
  (<COMMA> uc = UpdateClause()
    {
      ucs.add(uc);
    }
  )*) <RIGHTPAREN>
    {
      UpdateStatement stmt = new UpdateStatement(vars, target, condition, ucs);
      return addSourceLocation(stmt, startToken);
    }
}

UpdateClause UpdateClause() throws ParseException:
{
  Expression target = null;
  Expression value = null ;
  InsertStatement is = null;
  DeleteStatement ds = null;
  UpdateStatement us = null;
  Expression condition = null;
  UpdateClause ifbranch = null;
  UpdateClause elsebranch = null;
}
{
   (<SET> target = Expression() <EQ> value = Expression()
   | is = InsertStatement()
   | ds = DeleteStatement()
   | us = UpdateStatement()
   | <IF> <LEFTPAREN> condition = Expression() <RIGHTPAREN>
     <THEN> ifbranch = UpdateClause()
     [LOOKAHEAD(1) <ELSE> elsebranch = UpdateClause()]
     {
       return new UpdateClause(target, value, is, ds, us, condition, ifbranch, elsebranch);
     }
   )
}

Statement SetStatement() throws ParseException:
{
  Token startToken = null;
  String pn = null;
  String pv = null;
}
{
  <SET> { startToken = token; } pn = Identifier() pv = ConstantString()
    {
      SetStatement stmt = new SetStatement(pn, pv);
      return addSourceLocation(stmt, startToken);
    }
}

Statement WriteStatement() throws ParseException:
{
  Token startToken = null;
  String nodeName = null;
  String fileName = null;
  Query query;
  String writerClass = null;
  Pair<Identifier,Identifier> nameComponents = null;
}
{
  <WRITE> { startToken = token; } <OUTPUT> <TO> nodeName = Identifier() <COLON> fileName = ConstantString()
    ( <USING> writerClass = ConstantString() )?
    {
      WriteStatement stmt = new WriteStatement(new Identifier(nodeName), fileName, writerClass);
      return addSourceLocation(stmt, startToken);
    }
}

LoadStatement LoadStatement() throws ParseException:
{
  Token startToken = null;
  DataverseName dataverseName = null;
  Identifier datasetName = null;
  boolean alreadySorted = false;
  String adapterName;
  Map<String,String> properties;
  Pair<DataverseName,Identifier> nameComponents = null;
}
{
  <LOAD> { startToken = token; } Dataset() nameComponents = QualifiedName()
    {
      dataverseName = nameComponents.first;
      datasetName = nameComponents.second;
    }
  <USING> adapterName = AdapterName() properties = Configuration()
  (<PRESORTED>
    {
      alreadySorted = true;
    }
  )?
    {
      LoadStatement stmt = new LoadStatement(dataverseName, datasetName.getValue(), adapterName, properties,
        alreadySorted);
      return addSourceLocation(stmt, startToken);
    }
}


String AdapterName() throws ParseException :
{
  String adapterName = null;
}
{
  adapterName = Identifier()
    {
      return adapterName;
    }
}

Statement AnalyzeStatement() throws ParseException:
{
  Token startToken = null;
  Statement stmt = null;
  Pair<DataverseName,Identifier> nameComponents = null;
}
{
  <ANALYZE> { startToken = token; } DatasetToken() nameComponents = QualifiedName()
  (
    stmt = AnalyzeDatasetDropStatement(startToken, nameComponents.first, nameComponents.second)
    | stmt = AnalyzeDatasetStatement(startToken, nameComponents.first, nameComponents.second)
  )
  {
    return stmt;
  }
}

Statement AnalyzeDatasetStatement(Token startToken, DataverseName dvName, Identifier identifier) throws ParseException:
{
  RecordConstructor withRecord = null;
}
{
  ( <WITH> withRecord = RecordConstructor() )?
  {
    try {
    AnalyzeStatement stmt = new AnalyzeStatement(dvName, identifier.getValue(), withRecord);
    return addSourceLocation(stmt, startToken);
    } catch (CompilationException e) {
       throw new SqlppParseException(getSourceLocation(startToken), e.getMessage());
    }
  }
}

Statement AnalyzeDatasetDropStatement(Token startToken, DataverseName dvName, Identifier identifier) throws ParseException:
{
}
{
  <DROP> <IDENTIFIER> { expectToken(STATISTICS); }
  {
    AnalyzeDropStatement stmt = new AnalyzeDropStatement(dvName, identifier.getValue());
    return addSourceLocation(stmt, startToken);
  }
}

Statement CompactStatement() throws ParseException:
{
  Token startToken = null;
  Pair<DataverseName,Identifier> nameComponents = null;
}
{
  <COMPACT> { startToken = token; } Dataset() nameComponents = QualifiedName()
    {
      CompactStatement stmt = new CompactStatement(nameComponents.first, nameComponents.second);
      return addSourceLocation(stmt, startToken);
    }
}

Statement ConnectionStatement() throws ParseException:
{
  Token startToken = null;
  Statement stmt = null;
}
{
  (
    <CONNECT> { startToken = token; } stmt = ConnectStatement(startToken)
  | <DISCONNECT> { startToken = token; } stmt = DisconnectStatement(startToken)
  | <START> { startToken = token; } stmt = StartStatement(startToken)
  | <STOP> { startToken = token; } stmt = StopStatement(startToken)
  )
  {
    return stmt;
  }
}

Statement StartStatement(Token startStmtToken) throws ParseException:
{
  Pair<DataverseName,Identifier> feedNameComponents = null;
  AbstractStatement stmt = null;
}
{
  <FEED> feedNameComponents = QualifiedName()
  {
    stmt = new StartFeedStatement (feedNameComponents);
    return addSourceLocation(stmt, startStmtToken);
  }
}

AbstractStatement StopStatement(Token startStmtToken) throws ParseException:
{
  Pair<DataverseName,Identifier> feedNameComponents = null;
  AbstractStatement stmt = null;
}
{
  <FEED> feedNameComponents = QualifiedName()
  {
    stmt = new StopFeedStatement (feedNameComponents);
    return addSourceLocation(stmt, startStmtToken);
  }
}

AbstractStatement DisconnectStatement(Token startStmtToken) throws ParseException:
{
  Pair<DataverseName,Identifier> feedNameComponents = null;
  Pair<DataverseName,Identifier> datasetNameComponents = null;

  AbstractStatement stmt = null;
}
{
  (
    <FEED> feedNameComponents = QualifiedName() <FROM> Dataset() datasetNameComponents = QualifiedName()
      {
        stmt = new DisconnectFeedStatement(feedNameComponents, datasetNameComponents);
      }
  )
  {
    return addSourceLocation(stmt, startStmtToken);
  }
}

AbstractStatement ConnectStatement(Token startStmtToken) throws ParseException:
{
  Pair<DataverseName,Identifier> feedNameComponents = null;
  Pair<DataverseName,Identifier> datasetNameComponents = null;

  Map<String,String> configuration = null;
  List<FunctionSignature> appliedFunctions = new ArrayList<FunctionSignature>();
  AbstractStatement stmt = null;
  String policy = null;
  String whereClauseBody = null;
  WhereClause whereClause = null;
  Token beginPos = null;
  Token endPos = null;
}
{
  (
    <FEED> feedNameComponents = QualifiedName() <TO> Dataset() datasetNameComponents = QualifiedName()
    (ApplyFunction(appliedFunctions))?
    (policy = GetPolicy())?
    (
      <WHERE>
      {
        beginPos = token;
        whereClause = new WhereClause();
        Expression whereExpr;
      }
      whereExpr = Expression()
      {
        whereClause.setWhereExpr(whereExpr);
      }
    )?
    {
      if (whereClause != null) {
        endPos = token;
        whereClauseBody = extractFragment(beginPos.endLine, beginPos.endColumn, endPos.endLine, endPos.endColumn + 1);
      }
    }
      {
        stmt = new ConnectFeedStatement(feedNameComponents, datasetNameComponents, appliedFunctions,
         policy, whereClauseBody, getVarCounter());
      }
  )
  {
    return addSourceLocation(stmt, startStmtToken);
  }
}

Map<String,String> Configuration()  throws ParseException :
{
    Map<String,String> configuration = new LinkedHashMap<String,String>();
    Pair<String, String> keyValuePair = null;
}
{
  <LEFTPAREN> ( keyValuePair = KeyValuePair()
    {
      configuration.put(keyValuePair.first, keyValuePair.second);
    }
  ( <COMMA> keyValuePair = KeyValuePair()
    {
      configuration.put(keyValuePair.first, keyValuePair.second);
    }
  )* )? <RIGHTPAREN>
    {
      return configuration;
    }
}

Pair<String, String> KeyValuePair() throws ParseException:
{
  String key;
  String value;
}
{
  <LEFTPAREN> key = ConstantString()
  <EQ> ( value = ConstantString() | (<TRUE> | <FALSE>) {value = token.image.toLowerCase();} )
  <RIGHTPAREN>
    {
      return new Pair<String, String>(key, value);
    }
}

Map<String,String> Properties() throws ParseException:
{
  Map<String,String> properties = new HashMap<String,String>();
  Pair<String, String> property;
}
{
  (LOOKAHEAD(1) <LEFTPAREN> property = Property()
    {
      properties.put(property.first, property.second);
    }
  ( <COMMA> property = Property()
    {
      properties.put(property.first, property.second);
    }
  )* <RIGHTPAREN> )?
    {
      return properties;
    }
}

Pair<String, String> Property() throws ParseException:
{
  String key = null;
  String value = null;
}
{
  (key = Identifier() | key = StringLiteral())
  <EQ>
  ( value = ConstantString() | <INTEGER_LITERAL>
    {
      try {
        value = String.valueOf(Long.parseLong(token.image));
      } catch (NumberFormatException nfe) {
        throw new SqlppParseException(getSourceLocation(token), "inapproriate value: " + token.image);
      }
    }
  )
    {
      return new Pair<String, String>(key.toUpperCase(), value);
    }
}

IndexedTypeExpression IndexedTypeExpr(boolean allowQues) throws ParseException:
{
  TypeExpression typeExpr = null;
  boolean isUnknownable = !allowQues;
}
{
  typeExpr = TypeExpr(false)
  ( <QUES>
    {
      if (!allowQues) {
        throw new SqlppParseException(getSourceLocation(token), "'?' quantifier is illegal for the type expression.");
      }
      isUnknownable = true;
    }
  )?
  {
    return new IndexedTypeExpression(typeExpr, isUnknownable);
  }
}

TypeExpression TypeExpr(boolean allowRecordTypeDef) throws ParseException:
{
  TypeExpression typeExpr = null;
}
{
  (
    typeExpr = TypeReference()
    | typeExpr = OrderedListTypeDef(allowRecordTypeDef)
    | typeExpr = UnorderedListTypeDef(allowRecordTypeDef)
    | typeExpr = RecordTypeDef() {
      if (!allowRecordTypeDef) {
        throw new SqlppParseException(typeExpr.getSourceLocation(), "Unexpected record type declaration");
      }
    }
  )
  {
    return typeExpr;
  }
}

RecordTypeDefinition.RecordKind RecordTypeKind() throws ParseException:
{
  RecordTypeDefinition.RecordKind recordKind = null;
}
{
  (
    <CLOSED> { recordKind = RecordTypeDefinition.RecordKind.CLOSED; }
    | <OPEN> { recordKind = RecordTypeDefinition.RecordKind.OPEN; }
  )
  {
    return recordKind;
  }
}

RecordTypeDefinition RecordTypeDef() throws ParseException:
{
  Token startToken = null;
  RecordTypeDefinition recType = new RecordTypeDefinition();
  RecordTypeDefinition.RecordKind recordKind = RecordTypeDefinition.RecordKind.OPEN;
}
{
   ( recordKind = RecordTypeKind() )?
   <LEFTBRACE>
    {
      startToken = token;
      Token hintToken = fetchHint(token, SqlppHint.GEN_FIELDS_HINT);
      if (hintToken != null) {
        String hintParams = hintToken.hintParams;
        String[] splits = hintParams != null ? hintParams.split("\\s+") : null;
        if (splits == null || splits.length != 4) {
          throw new SqlppParseException(getSourceLocation(hintToken),
            "Expecting: /*+ gen-fields <type> <min> <max> <prefix>*/");
        }
        if (!splits[0].equals("int")) {
          throw new SqlppParseException(getSourceLocation(hintToken),
            "The only supported type for gen-fields is int.");
        }
        UndeclaredFieldsDataGen ufdg = new UndeclaredFieldsDataGen(UndeclaredFieldsDataGen.Type.INT,
          Integer.parseInt(splits[1]), Integer.parseInt(splits[2]), splits[3]);
          recType.setUndeclaredFieldsDataGen(ufdg);
      }
    }
    (
      RecordField(recType)
      ( <COMMA>  RecordField(recType) )*
    )?
   <RIGHTBRACE>
   {
      recType.setRecordKind(recordKind);
      return addSourceLocation(recType, startToken);
   }
}

void RecordField(RecordTypeDefinition recType) throws ParseException:
{
  String fieldName;
  TypeExpression type = null;
  boolean nullable = false, missable = false;
}
{
  fieldName = Identifier()
    {
      Token hintToken = fetchHint(token, SqlppHint.VAL_FILE_HINT, SqlppHint.VAL_FILE_SAME_INDEX_HINT,
        SqlppHint.LIST_VAL_FILE_HINT, SqlppHint.LIST_HINT, SqlppHint.INTERVAL_HINT, SqlppHint.INSERT_RAND_INT_HINT,
        SqlppHint.DATE_BETWEEN_YEARS_HINT, SqlppHint.DATETIME_ADD_RAND_HOURS_HINT, SqlppHint.AUTO_HINT);
      IRecordFieldDataGen rfdg = hintToken != null ? parseFieldDataGen(hintToken) : null;
    }
  <COLON> type = TypeExpr(true) ( <QUES> { nullable = true; missable = true; } )?
    {
      recType.addField(fieldName, type, nullable, missable, rfdg);
    }
}

TypeReferenceExpression TypeReference() throws ParseException:
{
  Pair<DataverseName,Identifier> id = null;
}
{
  id = QualifiedName()
  {
    if (id.first == null && id.second.getValue().equalsIgnoreCase(INT_TYPE_NAME)) {
      id.second = new Identifier(BuiltinType.AINT64.getTypeName());
    }

    TypeReferenceExpression typeRef = new TypeReferenceExpression(id);
    return addSourceLocation(typeRef, token);
  }
}

OrderedListTypeDefinition OrderedListTypeDef(boolean allowRecordTypeDef) throws ParseException:
{
  Token startToken = null;
  TypeExpression type = null;
}
{
  <LEFTBRACKET> { startToken = token; }
    ( type = TypeExpr(allowRecordTypeDef) )
  <RIGHTBRACKET>
  {
    OrderedListTypeDefinition typeDef = new OrderedListTypeDefinition(type);
    return addSourceLocation(typeDef, startToken);
  }
}

UnorderedListTypeDefinition UnorderedListTypeDef(boolean allowRecordTypeDef) throws ParseException:
{
  Token startToken = null;
  TypeExpression type = null;
}
{
  <LEFTDBLBRACE> { startToken = token; }
    ( type = TypeExpr(allowRecordTypeDef) )
  <RIGHTDBLBRACE>
  {
    UnorderedListTypeDefinition typeDef = new UnorderedListTypeDefinition(type);
    return addSourceLocation(typeDef, startToken);
  }
}

FunctionName FunctionName() throws ParseException:
{
  Triple<List<String>, Token, Token> prefix = null;
  String suffix = null;
}
{
  // Note: there's a copy of this production in PrimaryExpr() (LOOKAHEAD for FunctionCallExpr())
  //       that copy must be kept in sync with this code
  prefix = MultipartIdentifierWithHints(
    SqlppHint.INDEXED_NESTED_LOOP_JOIN_HINT, SqlppHint.RANGE_HINT, SqlppHint.HASH_JOIN_HINT, SqlppHint.SKIP_SECONDARY_INDEX_SEARCH_HINT,
    SqlppHint.SPATIAL_JOIN_HINT, SqlppHint.USE_SECONDARY_INDEX_SEARCH_HINT
  )
  (<SHARP> suffix = Identifier())?
  {
    Token startToken = prefix.second;
    FunctionName result = new FunctionName();
    result.sourceLoc = getSourceLocation(startToken);
    result.hintToken = prefix.third;
    List<String> list = prefix.first;
    int ln = list.size();
    String last = list.get(ln - 1);
    if (suffix == null) {
      // prefix = (dv_part1.dv_part2...dv_partN.)?func_name
      // no library name
      result.function = last;
    } else {
      // prefix = (dv_part1.dv_part2...dv_partN.)?lib_name
      // suffix = func_name
      result.library = last;
      result.function = suffix;
    }
    if (ln > 1) {
      result.dataverse = createDataverseName(list, 0, ln - 1, startToken);
    } else {
      result.dataverse = defaultDataverse;
    }

    if (result.function.equalsIgnoreCase(INT_TYPE_NAME)) {
       result.function = BuiltinType.AINT64.getTypeName();
    }
    return result;
  }
}

Pair<DataverseName,Identifier> TypeName() throws ParseException:
{
  Pair<DataverseName,Identifier> name = null;
}
{
  name = QualifiedName()
    {
      if (name.first == null) {
        name.first = defaultDataverse;
      }
      return name;
    }
}

String Identifier() throws ParseException:
{
  String lit = null;
}
{
  (<IDENTIFIER>
    {
      return token.image;
    }
  | lit = QuotedString()
    {
      return lit;
    }
  )
}

List<String> ParenthesizedIdentifierList() throws ParseException:
{
  List<String> list = new ArrayList<String>();
  String ident = null;
}
{
  <LEFTPAREN>
  ident = Identifier() { list.add(ident); }
  ( <COMMA> ident = Identifier() { list.add(ident); } )*
  <RIGHTPAREN>
  {
    return list;
  }
}

Pair<HashJoinExpressionAnnotation.BuildOrProbe, String> buildOrProbeParenthesizedIdentifier() throws ParseException:
{
  String ident1 = null;
  String ident2 = null;
}
{
  ident1 = Identifier() <LEFTPAREN> ident2 = Identifier() <RIGHTPAREN>
  {
    // check
    if (ident1.equals("build")) {
        return new Pair<HashJoinExpressionAnnotation.BuildOrProbe, String>(HashJoinExpressionAnnotation.BuildOrProbe.BUILD, ident2);
    }
    else if (ident1.equals("probe")) {
            return new Pair<HashJoinExpressionAnnotation.BuildOrProbe, String>(HashJoinExpressionAnnotation.BuildOrProbe.PROBE, ident2);
    }
    else {
        throw new SqlppParseException(getSourceLocation(token), "The string after hashjoin has to be \"build\" or \"probe\".");
    }
    return null;
  }
}

String parenthesizedIdentifier() throws ParseException:
{
  String ident = null;
}
{
  <LEFTPAREN> ident = Identifier() <RIGHTPAREN>
  {
    return ident;
  }
}

List<Literal> ParenthesizedLiteralList() throws ParseException:
{
  List<Literal> list = new ArrayList<Literal>();
  boolean minus = false;
  Expression litExpr = null;
  Literal lit = null;
}
{
  <LEFTPAREN>
  (<MINUS> { minus = true; })? litExpr = Literal()
  {
    lit = ((LiteralExpr) litExpr).getValue();
    if (minus)
    {
      try {
        lit = ExpressionUtils.reverseSign(lit);
      } catch (TypeMismatchException e) {
        throw new SqlppParseException(getSourceLocation(token), e.getMessage());
      }
      minus = false;
    }
    list.add(lit);
  }
  ( <COMMA> (<MINUS> { minus = true; })? litExpr = Literal()
  {
    lit = ((LiteralExpr) litExpr).getValue();
    if (minus)
    {
      try {
        lit = ExpressionUtils.reverseSign(lit);
      } catch (TypeMismatchException e) {
        throw new SqlppParseException(getSourceLocation(token), e.getMessage());
      }
      minus = false;
    }
    list.add(lit);
  } )*
  <RIGHTPAREN>
  {
    return list;
  }
}

Pair<Integer, Pair<List<String>, IndexedTypeExpression>> OpenField() throws ParseException:
{
  IndexedTypeExpression fieldType = null;
  Pair<Integer, List<String>> fieldList = null;
}
{
  fieldList = NestedField()
  ( <COLON> fieldType = IndexedTypeExpr(true) )?
  {
    return new Pair<Integer, Pair<List<String>, IndexedTypeExpression>>
            (fieldList.first, new Pair<List<String>, IndexedTypeExpression>(fieldList.second, fieldType));
  }
}

Pair<Integer, List<String>> NestedField() throws ParseException:
{
  List<String> exprList = new ArrayList<String>();
  String lit = null;
  Token litToken = null;
  int source = 0;
}
{
  lit = Identifier()
  {
    boolean meetParens = false;
    litToken = token;
  }
  (
    LOOKAHEAD(1)
    <LEFTPAREN><RIGHTPAREN>
    {
        if(!lit.equalsIgnoreCase("meta")){
            throw new SqlppParseException(getSourceLocation(litToken), "The string before () has to be \"meta\".");
        }
        meetParens = true;
        source = 1;
    }
  )?
  {
    if(!meetParens){
        exprList.add(lit);
    }
  }
  (<DOT>
    lit = Identifier()
    {
      exprList.add(lit);
    }
  )*
  {
    return new Pair<Integer, List<String>>(source, exprList);
  }
}

String ConstantString() throws ParseException:
{
  String value = null;
}
{
  (value = QuotedString() | value = StringLiteral())
  {
     return value;
  }
}

String QuotedString() throws ParseException:
{
}
{
  <QUOTED_STRING>
    {
      return removeQuotesAndEscapes(token.image);
    }
}

String StringLiteral() throws ParseException:
{
  StringBuilder str = null;
  char quote = 0;
  boolean ext = false;
  Token litToken = null;
  String lit = null;
}
{
  ( <STRING_LITERAL>
    {
      String quoted = token.image;
      char q = quoted.charAt(0);
      boolean e = q == 'E';
      if (e) {
        q = quoted.charAt(1);
        quoted = quoted.substring(1);
      }
      if (lit == null) {
        quote = q;
        ext = e;
      } else {
        boolean isAdjacent = litToken.endLine == token.beginLine && litToken.endColumn + 1 == token.beginColumn;
        if (!isAdjacent || ext || e || (q != quote)) {
          throw new SqlppParseException(getSourceLocation(token), "Invalid string literal");
        }
        if (str == null) {
          str = new StringBuilder();
        }
        str.append(lit);
        str.append(quote);
      }
      lit = removeQuotesAndEscapes(quoted);
      litToken = token;
    }
  )+
  {
    if (str == null) {
      return lit;
    } else {
      str.append(lit);
      return str.toString();
    }
  }
}

Triple<List<String>, Token, Token> MultipartIdentifier() throws ParseException:
{
  Triple<List<String>, Token, Token> result = null;
}
{
  result = MultipartIdentifierWithHints(null)
  {
    return result;
  }
}

Triple<List<String>, Token, Token> MultipartIdentifierWithHints(SqlppHint... expectedHints)
  throws ParseException:
{
  List<String> list = new ArrayList<String>();
  SourceLocation sourceLoc = null;
  Token startToken, hintToken = null;
  String item = null;
}
{
  item = Identifier()
  {
    list.add(item);
    startToken = token;
    if (expectedHints != null && expectedHints.length > 0) {
      hintToken = fetchHint(token, expectedHints);
    }
  }
  (<DOT> item = Identifier() { list.add(item); } )*
  {
    return new Triple<List<String>, Token, Token>(list, startToken, hintToken);
  }
}

DataverseName DataverseName() throws ParseException:
{
  Triple<List<String>, Token, Token> ident = null;
}
{
  ident = MultipartIdentifier()
  {
    List<String> list = ident.first;
    Token startToken = ident.second;
    return createDataverseName(list, 0, list.size(), startToken);
  }
}

Pair<DataverseName,Identifier> QualifiedName() throws ParseException:
{
  Triple<List<String>, Token, Token> ident = null;
}
{
  ident = MultipartIdentifier()
  {
    List<String> list = ident.first;
    Token startToken = ident.second;
    int len = list.size();
    DataverseName id1 = len > 1 ? createDataverseName(list, 0, len - 1, startToken) : null;
    Identifier id2 = new Identifier(list.get(len - 1));
    return new Pair<DataverseName,Identifier>(id1, id2);
  }
}

Triple<DataverseName, Identifier, Identifier> DoubleQualifiedName() throws ParseException:
{
  List<String> list = new ArrayList<String>();
  String item = null;
  Token startToken = null;
}
{
  item = Identifier() { list.add(item); startToken = token; }
  (<DOT> item = Identifier() { list.add(item); } )+
  {
    int len = list.size();
    DataverseName id1 = len > 2 ? createDataverseName(list, 0, len - 2, startToken) : null;
    Identifier id2 = new Identifier(list.get(len - 2));
    Identifier id3 = new Identifier(list.get(len - 1));
    return new Triple<DataverseName,Identifier,Identifier>(id1, id2, id3);
  }
}

FunctionDecl FunctionDeclaration() throws ParseException:
{
  Token startToken = null;
  String functionName;
  Pair<Integer, List<Pair<VarIdentifier,TypeExpression>>> paramsWithArity = null;
  Expression funcBody;
  createNewScope();
}
{
  <DECLARE> { startToken = token; } <FUNCTION>
    functionName = Identifier()
    paramsWithArity = FunctionParameters()
  <LEFTBRACE>
    funcBody = FunctionBody()
  <RIGHTBRACE>
  {
    int arity = paramsWithArity.first;
    List<Pair<VarIdentifier,TypeExpression>> paramList = paramsWithArity.second;
    FunctionSignature signature = new FunctionSignature(defaultDataverse, functionName, arity);
    getCurrentScope().addFunctionDescriptor(signature, false);
    ensureNoTypeDeclsInFunction(functionName, paramList, null, startToken);
    List<VarIdentifier> params = new ArrayList<VarIdentifier>(paramList.size());
    for (Pair<VarIdentifier,TypeExpression> p: paramList) {
        params.add(p.getFirst());
    }
    FunctionDecl stmt = new FunctionDecl(signature, params, funcBody, false);
    removeCurrentScope();
    return addSourceLocation(stmt, startToken);
  }
}

Query Query() throws ParseException:
{
  Query query = new Query();
  Expression expr;
}
{
  (
  expr = Expression()
  |
  expr = SelectExpression(false)
  )
  {
    query.setBody(expr);
    query.setSourceLocation(expr.getSourceLocation());
    return query;
  }
}


Expression Expression():
{
  Expression expr = null;
  Expression exprP = null;
}
{
(
    LOOKAHEAD(2)
    expr = OperatorExpr()
    | expr = QuantifiedExpression()
)
    {
      return (exprP==null) ? expr : exprP;
    }
}

Expression OperatorExpr() throws ParseException:
{
  OperatorExpr op = null;
  Expression operand = null;
}
{
    operand = AndExpr()
    (
      <OR>
      {
        if (op == null) {
          op = new OperatorExpr();
          op.addOperand(operand);
          op.setCurrentop(true);
          addSourceLocation(op, token);
        }
        try{
            op.addOperator(token.image.toLowerCase());
        } catch (Exception e){
            throw new SqlppParseException(getSourceLocation(token), e.getMessage());
        }
      }

      operand = AndExpr()
      {
        op.addOperand(operand);
      }

    )*

    {
      return op==null? operand: op;
    }
}

Expression AndExpr() throws ParseException:
{
  OperatorExpr op = null;
  Expression operand = null;
}
{
    operand = NotExpr()
    (
      <AND>
      {
        if (op == null) {
          op = new OperatorExpr();
          op.addOperand(operand);
          op.setCurrentop(true);
          addSourceLocation(op, token);
        }
        try{
           op.addOperator(token.image.toLowerCase());
        } catch (CompilationException e){
           throw new SqlppParseException(getSourceLocation(token), e.getMessage());
        }
    }

    operand = NotExpr()
    {
      op.addOperand(operand);
    }

    )*

    {
      return op==null ? operand: op;
    }
}

Expression NotExpr() throws ParseException:
{
   Expression inputExpr;
   boolean not = false;
   Token startToken = null;
}
{
  (LOOKAHEAD(2) <NOT> { not = true; startToken = token; } )? inputExpr = RelExpr()
  {
    if(not) {
        FunctionSignature signature = new FunctionSignature(BuiltinFunctions.NOT);
        CallExpr callExpr = new CallExpr(signature, new ArrayList<Expression>(Collections.singletonList(inputExpr)));
        return addSourceLocation(callExpr, startToken);
    } else {
        return inputExpr;
    }
  }
}

Expression RelExpr() throws ParseException:
{
  boolean not = false;
  OperatorExpr op = null;
  Token opToken = null;
  Expression operand = null;
  IExpressionAnnotation annotation = null;
  List<IExpressionAnnotation> annotationList = new ArrayList<IExpressionAnnotation>();
}
{
    operand = BetweenExpr()

    (
      LOOKAHEAD(3)( <LT> | <GT> | <LE> | <GE> | <EQ> | <NE> | <LG> |<SIMILAR> | (<NOT> { not = true; })? <IN> |
                    <IS> (<NOT> { not = true; })? <DISTINCT> { opToken = token; } <FROM> )
        {
          if (opToken == null) {
            opToken = token;
          }
          Token hintToken = fetchHint(token,
            SqlppHint.HASH_BROADCAST_JOIN_HINT, SqlppHint.INDEXED_NESTED_LOOP_JOIN_HINT,
            SqlppHint.HASH_JOIN_HINT, SqlppHint.SKIP_SECONDARY_INDEX_SEARCH_HINT, SqlppHint.USE_SECONDARY_INDEX_SEARCH_HINT,
            SqlppHint.SINGLE_DATASET_PREDICATE_SELECTIVITY_HINT, SqlppHint.JOIN_PREDICATE_PRODUCTIVITY_HINT
          );
          while (hintToken != null) {
            annotation = parseExpressionAnnotation(hintToken);
            if (annotation != null) {
                // annotation may be null if hints are malformed
                annotationList.add(annotation);
            }
            hintToken = hintToken.specialToken;
            if (hintToken != null) {
                SourceLocation sourceLoc = getSourceLocation(hintToken);
                hintCollector.remove(sourceLoc);
            }
          }
          String operator = opToken.image.toLowerCase();
          if (operator.equals("<>")){
              operator = "!=";
          }
          if (not) {
            operator = "not_" + operator;
          }
          if (op == null) {
            op = new OperatorExpr();
            op.addOperand(operand);
            op.setCurrentop(true);
            addSourceLocation(op, token);
          }
          try{
            op.addOperator(operator);
          } catch (CompilationException e){
            throw new SqlppParseException(getSourceLocation(token), e.getMessage());
          }
        }

       operand = BetweenExpr()
       {
         op.addOperand(operand);
       }
    )?

     {
       if (annotation != null) {
         op.addHints(annotationList);
       }
       return op==null? operand: op;
     }
}

Expression BetweenExpr() throws ParseException:
{
  boolean not = false;
  OperatorExpr op = null;
  Expression operand = null;
  IExpressionAnnotation annotation = null;
}
{
    operand = IsExpr()
    (
      LOOKAHEAD(2)
      (<NOT> { not = true; })? <BETWEEN>
        {
          Token hintToken = fetchHint(token,
            SqlppHint.INDEXED_NESTED_LOOP_JOIN_HINT, SqlppHint.SKIP_SECONDARY_INDEX_SEARCH_HINT, SqlppHint.HASH_JOIN_HINT,
            SqlppHint.USE_SECONDARY_INDEX_SEARCH_HINT, SqlppHint.SINGLE_DATASET_PREDICATE_SELECTIVITY_HINT
          );
          if (hintToken != null) {
            annotation = parseExpressionAnnotation(hintToken);
          }
          String operator = token.image.toLowerCase();
          if(not){
            operator = "not_" + operator;
          }
          if (op == null) {
            op = new OperatorExpr();
            op.addOperand(operand);
            op.setCurrentop(true);
            addSourceLocation(op, token);
          }
          try{
            op.addOperator(operator);
          } catch (CompilationException e){
            throw new SqlppParseException(getSourceLocation(token), e.getMessage());
          }
        }

       operand = IsExpr()
       {
         op.addOperand(operand);
       }

       <AND>
       operand = IsExpr()
       {
         op.addOperator(OperatorType.AND);
         op.addOperand(operand);
       }
    )?

    {
       if (annotation != null) {
         op.addHint(annotation);
       }
       return op==null ? operand: op;
    }
}

Expression IsExpr() throws ParseException:
{
    Token notToken = null;
    CallExpr expr = null;
    Expression operand = null;
    boolean not = false;
    FunctionIdentifier fn = null;
}
{
    operand = LikeExpr()
    (
      LOOKAHEAD(3)
      <IS>
        (<NOT> { not = true; notToken = token; })?
        (
            <NULL> { fn = BuiltinFunctions.IS_NULL; } |
            <MISSING> { fn = BuiltinFunctions.IS_MISSING; } |
            <UNKNOWN> { fn = BuiltinFunctions.IS_UNKNOWN; } |
            (<KNOWN> | <VALUED>) { not = !not; fn = BuiltinFunctions.IS_UNKNOWN; }
        )
      {
        FunctionSignature signature = new FunctionSignature(fn);
        expr = new CallExpr(signature, new ArrayList<Expression>(Collections.singletonList(operand)));
        addSourceLocation(expr, token);
        if (not) {
           FunctionSignature notSignature = new FunctionSignature(BuiltinFunctions.NOT);
           expr = new CallExpr(notSignature, new ArrayList<Expression>(Collections.singletonList(expr)));
           addSourceLocation(expr, notToken);
        }
      }
    )?
    {
        return expr == null ? operand : expr;
    }
}

Expression LikeExpr() throws ParseException:
{
  boolean not = false;
  OperatorExpr op = null;
  Expression operand = null;
  IExpressionAnnotation annotation = null;
}
{
    operand = ConcatExpr()
    (
        LOOKAHEAD(2)
        (<NOT> { not = true; })? <LIKE>
        {
          Token hintToken = fetchHint(token, SqlppHint.SINGLE_DATASET_PREDICATE_SELECTIVITY_HINT);
          if (hintToken != null) {
               annotation = parseExpressionAnnotation(hintToken);
          }
          op = new OperatorExpr();
          op.addOperand(operand);
          op.setCurrentop(true);
          addSourceLocation(op, token);

          String operator = token.image.toLowerCase();
          if (not) {
            operator = "not_" + operator;
          }
          try {
            op.addOperator(operator);
          } catch (CompilationException e){
            throw new SqlppParseException(getSourceLocation(token), e.getMessage());
          }
          if (annotation != null) {
             op.addHint(annotation);
          }
        }

        operand = ConcatExpr()
        {
          op.addOperand(operand);
        }
     )?

     {
       return op == null ? operand : op;
     }
}

Expression ConcatExpr() throws ParseException:
{
  OperatorExpr op = null;
  Expression operand = null;
}
{
    operand = AddExpr()
    (
      LOOKAHEAD(1)
      <CONCAT>
      {
        if (op == null) {
          op = new OperatorExpr();
          op.addOperand(operand);
          op.setCurrentop(true);
          addSourceLocation(op, token);
        }
        op.addOperator(OperatorType.CONCAT);
    }
    operand = AddExpr()
    {
      op.addOperand(operand);
    }
    )*

    {
       return op == null ? operand : op;
    }
}

Expression AddExpr() throws ParseException:
{
  OperatorExpr op = null;
  OperatorType opType = null;
  Expression operand = null;
}
{
    operand = MultExpr()
    (
      LOOKAHEAD(1)
      (<PLUS> { opType = OperatorType.PLUS; } | <MINUS> { opType = OperatorType.MINUS; } )
      {
        if (op == null) {
          op = new OperatorExpr();
          op.addOperand(operand);
          op.setCurrentop(true);
          addSourceLocation(op, token);
        }
        op.addOperator(opType);
    }

    operand = MultExpr()
    {
      op.addOperand(operand);
    }
    )*

    {
       return op == null ? operand : op;
    }
}

Expression MultExpr() throws ParseException:
{
  OperatorExpr op = null;
  OperatorType opType = null;
  Expression operand = null;
}
{
    operand = ExponentExpr()

    ( (
        <MUL> { opType = OperatorType.MUL; } |
        <DIVIDE> { opType = OperatorType.DIVIDE; } |
        <DIV> { opType = OperatorType.DIV; } |
        ( <MOD> | <PERCENT> ) { opType = OperatorType.MOD; }
      )
      {
        if (op == null) {
          op = new OperatorExpr();
          op.addOperand(operand);
          op.setCurrentop(true);
          addSourceLocation(op, token);
        }
        op.addOperator(opType);
    }
    operand = ExponentExpr()
    {
       op.addOperand(operand);
    }
    )*

     {
       return op == null ? operand : op;
     }
}

Expression ExponentExpr() throws ParseException:
{
  OperatorExpr op = null;
  Expression operand = null;
}
{
    operand = UnaryExpr()
    (<CARET>
    {
        if (op == null) {
          op = new OperatorExpr();
          op.addOperand(operand);
          op.setCurrentop(true);
          addSourceLocation(op, token);
        }
        op.addOperator(OperatorType.CARET);
    }
    operand = UnaryExpr()
    {
       op.addOperand(operand);
    }
    )?
    {
       return op == null ? operand : op;
    }
}

Expression UnaryExpr() throws ParseException:
{
    boolean not = false;
    UnaryExpr uexpr = null;
    Expression expr = null;
}
{
    ( (<PLUS> | <MINUS> | (<NOT> { not = true; } )? <EXISTS> )
    {
        String exprType = token.image.toLowerCase();
        if (not) {
           exprType = "not_" + exprType;
        }
        uexpr = new UnaryExpr();
        addSourceLocation(uexpr, token);
        try {
            uexpr.setExprType(exprType);
        } catch (CompilationException e){
            throw new SqlppParseException(getSourceLocation(token), e.getMessage());
        }
    }
    )?

    expr = ValueExpr()
    {
       if (uexpr == null) {
         return expr;
       } else {
         uexpr.setExpr(expr);
         return uexpr;
       }
    }
}

Expression ValueExpr() throws ParseException:
{
  Expression expr = null;
  AbstractAccessor accessor = null;
}
{
  expr = PrimaryExpr()
  (
    accessor = FieldAccessor(accessor != null ? accessor : expr)
    |
    accessor = IndexAccessor(accessor != null ? accessor : expr)
  )*
  {
    return accessor == null ? expr : accessor;
  }
}

FieldAccessor FieldAccessor(Expression inputExpr) throws ParseException:
{
  Token startToken = null;
  String ident = null;
}
{
   <DOT> { startToken = token; } ident = Identifier()
    {
      FieldAccessor fa = new FieldAccessor(inputExpr, new Identifier(ident));
      return addSourceLocation(fa, startToken);
    }
}

AbstractAccessor IndexAccessor(Expression inputExpr) throws ParseException:
{
  Token startToken = null;
  boolean star = false, slice = false;
  Expression expr1 = null, expr2 = null;
}
{
  <LEFTBRACKET> { startToken = token; }
  (
    <MUL> { star = true; }
    |
    ( expr1 = Expression() ( <COLON> { slice = true; } ( expr2 = Expression() )? )? )
  )
  <RIGHTBRACKET>
  {
    if (expr1 != null && expr1.getKind() == Expression.Kind.LITERAL_EXPRESSION) {
      ensureIntegerLiteral( (LiteralExpr) expr1, "Index");
    }
    if (expr2 != null && expr2.getKind() == Expression.Kind.LITERAL_EXPRESSION) {
      ensureIntegerLiteral( (LiteralExpr) expr2, "Index");
    }
    AbstractAccessor resultAccessor;
    if (slice) {
      resultAccessor = new ListSliceExpression(inputExpr, expr1, expr2);
    } else if (star) {
      resultAccessor = new IndexAccessor(inputExpr, IndexAccessor.IndexKind.STAR, null);
    } else {
      resultAccessor = new IndexAccessor(inputExpr, IndexAccessor.IndexKind.ELEMENT, expr1);
    }
    return addSourceLocation(resultAccessor, startToken);
  }
}

Expression PrimaryExpr() throws ParseException:
{
  Expression expr = null;
}
{
  (
    LOOKAHEAD(Identifier() (<DOT> Identifier())* (<SHARP> Identifier())? <LEFTPAREN>) expr = FunctionCallExpr()
  | expr = CaseExpr()
  | expr = Literal()
  | expr = VariableRef()
  | expr = ExternalVariableRef()
  | expr = ListConstructor()
  | expr = RecordConstructor()
  | expr = ParenthesizedExpression()
  )
    {
      return expr;
    }
}

Expression Literal() throws ParseException:
{
  LiteralExpr lit = new LiteralExpr();
  String str = null;
}
{
  ( str = StringLiteral()
    {
      lit.setValue(new StringLiteral(str));
    }
  | <INTEGER_LITERAL>
    {
        try {
            lit.setValue(new LongIntegerLiteral(Long.valueOf(token.image)));
        } catch (NumberFormatException e) {
            throw new SqlppParseException(getSourceLocation(token), "Could not parse numeric literal \"" + LogRedactionUtil.userData(token.image) +'"');
        }
    }
  | <FLOAT_LITERAL>
    {
        try {
            lit.setValue(new FloatLiteral(Float.valueOf(token.image)));
        } catch (NumberFormatException e) {
            throw new SqlppParseException(getSourceLocation(token), "Could not parse numeric literal \"" + LogRedactionUtil.userData(token.image) +'"');
        }
    }
  | <DOUBLE_LITERAL>
    {
        try {
            lit.setValue(new DoubleLiteral(Double.valueOf(token.image)));
        } catch (NumberFormatException e) {
            throw new SqlppParseException(getSourceLocation(token), "Could not parse numeric literal \"" + LogRedactionUtil.userData(token.image) +'"');
        }
    }
  | <MISSING>
    {
      lit.setValue(MissingLiteral.INSTANCE);
    }
  | <NULL>
    {
      lit.setValue(NullLiteral.INSTANCE);
    }
  | <TRUE>
    {
      lit.setValue(TrueLiteral.INSTANCE);
    }
  | <FALSE>
    {
      lit.setValue(FalseLiteral.INSTANCE);
    }
  )
    {
      return addSourceLocation(lit, token);
    }
}

VariableExpr VariableRef() throws ParseException:
{
    String id = null;
}
{
    id = VariableIdentifier()
    {
     Identifier ident = lookupSymbol(id);
     if (isInForbiddenScopes(id)) {
       throw new SqlppParseException(getSourceLocation(token),
        "Inside limit clauses, it is disallowed to reference a variable having the same name as any variable bound in the same scope as the limit clause.");
     }
     VariableExpr varExp;
     if (ident != null) { // exist such ident
       varExp = new VariableExpr((VarIdentifier)ident);
     } else {
       varExp = new VariableExpr(new VarIdentifier(id));
       varExp.setIsNewVar(false);
     }
     return addSourceLocation(varExp, token);
    }
}

VariableExpr Variable() throws ParseException:
{
    String id = null;
}
{
    id = VariableIdentifier()
    {
     Identifier ident = lookupSymbol(id);
     VariableExpr varExp = new VariableExpr(new VarIdentifier(id));
     if (ident != null) { // exist such ident
       varExp.setIsNewVar(false);
     }
     return addSourceLocation(varExp, token);
    }
}

String VariableIdentifier() throws ParseException:
{
  String id = null;
}
{
  (<IDENTIFIER> { id = token.image; } | id = QuotedString())
  {
    return SqlppVariableUtil.toInternalVariableName(id); // prefix user-defined variables with "$".
  }
}

Pair<VariableExpr, List<Pair<Expression, Identifier>>> VariableWithFieldMap() throws ParseException:
{
  VariableExpr var = null;
  List<Pair<Expression, Identifier>> fieldList = new ArrayList<Pair<Expression, Identifier>>();
}
{
  var = Variable()
  ( LOOKAHEAD(1)
    {
      VariableExpr fieldVarExpr = null;
      String fieldIdentifierStr = null;
    }
    <LEFTPAREN>
    fieldVarExpr = VariableRef() <AS> fieldIdentifierStr = Identifier()
    {
      fieldList.add(new Pair<Expression, Identifier>(fieldVarExpr, new Identifier(fieldIdentifierStr)));
    }
    (<COMMA>
      fieldVarExpr = VariableRef() <AS> fieldIdentifierStr = Identifier()
      {
        fieldList.add(new Pair<Expression, Identifier>(fieldVarExpr, new Identifier(fieldIdentifierStr)));
      }
    )*
    <RIGHTPAREN>
  )?
  {
    return new Pair<VariableExpr, List<Pair<Expression, Identifier>>>(var, fieldList);
  }
}

VariableExpr ExternalVariableRef() throws ParseException:
{
  String name = null;
}
{
  (
      <DOLLAR_IDENTIFIER> { name = token.image.substring(1); }
    | <DOLLAR_INTEGER_LITERAL> { name = token.image.substring(1); }
    | <DOLLAR_QUOTED_STRING> { name = removeQuotesAndEscapes(token.image.substring(1)); }
    | <QUES> { name = String.valueOf(++externalVarCounter); }
  )
  {
     String idName = SqlppVariableUtil.toExternalVariableName(name);
     VarIdentifier id = new VarIdentifier(idName);
     VariableExpr varExp = new VariableExpr(id);
     return addSourceLocation(varExp, token);
  }
}

Expression ListConstructor() throws ParseException:
{
    Expression expr = null;
}
{
    (
      expr = OrderedListConstructor() |
      expr = UnorderedListConstructor()
    )
    {
      return expr;
    }
}

ListConstructor OrderedListConstructor() throws ParseException:
{
  Token startToken = null;
  List<Expression> exprList = null;
}
{
  <LEFTBRACKET> { startToken = token; }
  exprList = ExpressionList()
  <RIGHTBRACKET>
  {
    ListConstructor expr = new ListConstructor(ListConstructor.Type.ORDERED_LIST_CONSTRUCTOR, exprList);
    return addSourceLocation(expr, startToken);
  }
}

ListConstructor UnorderedListConstructor() throws ParseException:
{
  Token startToken = null;
  List<Expression> exprList = null;
}
{
  <LEFTDBLBRACE> { startToken = token; }
  exprList = ExpressionList()
  <RIGHTDBLBRACE>
  {
    ListConstructor expr = new ListConstructor(ListConstructor.Type.UNORDERED_LIST_CONSTRUCTOR, exprList);
    return addSourceLocation(expr, startToken);
  }
}

List<Expression> ExpressionList() throws ParseException:
{
  Expression expr = null;
  List<Expression> exprList = new ArrayList<Expression>();
}
{
  (
    expr = Expression()
    {
      exprList.add(expr);
    }
    ( <COMMA> expr = Expression()
      {
        exprList.add(expr);
      }
    )*
  )?
  {
    return exprList;
  }
}

RecordConstructor RecordConstructor() throws ParseException:
{
  Token startToken = null;
  FieldBinding fb = null;
  List<FieldBinding> fbList = new ArrayList<FieldBinding>();
}
{
  <LEFTBRACE> { startToken = token; }
  (
    fb = FieldBinding() { fbList.add(fb); }
    (<COMMA> fb = FieldBinding() { fbList.add(fb); })*
  )?
  <RIGHTBRACE>
  {
    RecordConstructor expr = new RecordConstructor(fbList);
    return addSourceLocation(expr, startToken);
  }
}

FieldBinding FieldBinding() throws ParseException:
{
  Expression left, right = null;
}
{
  left = Expression() ( <COLON> right = Expression() )?
  {
    if (right == null) {
        String generatedIdentifier = ExpressionToVariableUtil.getGeneratedIdentifier(left, false);
        if (generatedIdentifier == null) {
          throw new SqlppParseException(getSourceLocation(token), "Cannot infer field name");
        }
        String generatedName = SqlppVariableUtil.toUserDefinedName(generatedIdentifier);
        LiteralExpr generatedNameExpr = new LiteralExpr(new StringLiteral(generatedName));
        generatedNameExpr.setSourceLocation(left.getSourceLocation());
        return new FieldBinding(generatedNameExpr, left);
    } else {
      return new FieldBinding(left, right);
    }
  }
}

Expression FunctionCallExpr() throws ParseException:
{
  List<Expression> argList = new ArrayList<Expression>();
  Expression argExpr = null;
  FunctionName funcName = null;
  boolean star = false;
  boolean distinct = false;
  Expression filterExpr = null;
  WindowExpression windowExpr = null;
}
{
  funcName = FunctionName()
  <LEFTPAREN> (
    ( <DISTINCT> { distinct = true; } )?
    ( argExpr = Expression() | <MUL> { star = true; } )
    {
      if (star) {
        if (funcName.function.equalsIgnoreCase(BuiltinFunctions.SCALAR_COUNT.getName())) {
          argExpr = new LiteralExpr(new LongIntegerLiteral(1L));
        } else {
          throw new SqlppParseException(getSourceLocation(token),
            "The parameter * can only be used in " + BuiltinFunctions.SCALAR_COUNT.getName() + "().");
        }
      }
      argList.add(argExpr);
    }
  (<COMMA> argExpr = Expression()
    {
      argList.add(argExpr);
    }
  )*)? <RIGHTPAREN>

  {
    String name = funcName.function;
    if (distinct) {
      name += FunctionMapUtil.DISTINCT_AGGREGATE_SUFFIX;
    }
    String fqFunctionName = funcName.library == null ? name : funcName.library + "#" + name;
    int arity = argList.size();
    FunctionSignature signature = lookupFunctionSignature(funcName.dataverse, fqFunctionName, arity);
    if (signature == null) {
      signature = new FunctionSignature(funcName.dataverse, fqFunctionName, arity);
    }
  }

  ( <FILTER> <LEFTPAREN> <WHERE> filterExpr = Expression() <RIGHTPAREN> )?

  ( LOOKAHEAD(5) windowExpr = WindowExpr(signature, argList, filterExpr) )?

  {
    if (windowExpr != null) {
      return windowExpr;
    } else {
      CallExpr callExpr = new CallExpr(signature, argList, filterExpr);
      if (funcName.hintToken != null) {
        IExpressionAnnotation annotation = parseExpressionAnnotation(funcName.hintToken);
        if (annotation != null) {
          callExpr.addHint(annotation);
        }
      }
      FunctionMapUtil.normalizedListInputFunctions(callExpr);
      callExpr.setSourceLocation(funcName.sourceLoc);
      return callExpr;
    }
  }
}

WindowExpression WindowExpr(FunctionSignature signature, List<Expression> argList, Expression aggFilterExpr)
  throws ParseException:
{
  WindowExpression windowExpr = null;
  Boolean fromLast = null, ignoreNulls = null;
}
{
  (
    // FROM ( FIRST | LAST ) ( ( RESPECT | IGNORE ) NULLS )? OVER
    LOOKAHEAD(5, <FROM> <IDENTIFIER> ( <IDENTIFIER> <IDENTIFIER> )? <OVER>)
    <FROM> <IDENTIFIER>
    {
      if (isToken(FIRST)) {
        fromLast = false;
      } else if (isToken(LAST)) {
        fromLast = true;
      } else {
        throw createUnexpectedTokenError();
      }
    }
  )?
  (
    // ( RESPECT | IGNORE ) NULLS OVER
    LOOKAHEAD(3, <IDENTIFIER> <IDENTIFIER> <OVER>)
    <IDENTIFIER>
    {
      if (isToken(RESPECT)) {
        ignoreNulls = false;
      } else if (isToken(IGNORE)) {
        ignoreNulls = true;
      } else {
        throw createUnexpectedTokenError();
      }
    }
    <IDENTIFIER>
    {
      if (!isToken(NULLS)) {
        throw createUnexpectedTokenError();
      }
    }
  )?
  <OVER> windowExpr = OverClause(signature, argList, aggFilterExpr, token, fromLast, ignoreNulls)
  {
    return windowExpr;
  }
}

WindowExpression OverClause(FunctionSignature signature, List<Expression> argList, Expression aggFilterExpr,
    Token startToken, Boolean fromLast, Boolean ignoreNulls) throws ParseException:
{
  Expression partitionExpr = null;
  List<Expression> partitionExprs = new ArrayList<Expression>();
  OrderbyClause orderByClause = null;
  List<Expression> orderbyList = null;
  List<OrderbyClause.OrderModifier> orderbyModifierList = null;
  List<OrderbyClause.NullOrderModifier> orderbyNullModifierList = null;
  WindowExpression.FrameMode frameMode = null;
  Pair<WindowExpression.FrameBoundaryKind, Expression> frameStart = null, frameEnd = null;
  WindowExpression.FrameBoundaryKind frameStartKind = null, frameEndKind = null;
  Expression frameStartExpr = null, frameEndExpr = null;
  WindowExpression.FrameExclusionKind frameExclusionKind = null;
  Pair<VariableExpr, List<Pair<Expression, Identifier>>> windowVarWithFieldList = null;
  VariableExpr windowVar = null;
  List<Pair<Expression, Identifier>> windowFieldList = null;
}
{
  (
    windowVarWithFieldList = VariableWithFieldMap() <AS>
    {
      windowVar = windowVarWithFieldList.first;
      windowFieldList = windowVarWithFieldList.second;
    }
  )?
  <LEFTPAREN>
  (
    <IDENTIFIER> { expectToken(PARTITION); } <BY>
    partitionExpr = Expression() { partitionExprs.add(partitionExpr); }
    ( <COMMA> partitionExpr = Expression() { partitionExprs.add(partitionExpr); } )*
  )?
  (
    orderByClause = OrderbyClause()
    {
      orderbyList = orderByClause.getOrderbyList();
      orderbyModifierList = orderByClause.getModifierList();
      orderbyNullModifierList = orderByClause.getNullModifierList();
    }
    (
      frameMode = WindowFrameMode()
      (
        frameStart = WindowFrameBoundary() |
        ( <BETWEEN> frameStart = WindowFrameBoundary() <AND> frameEnd = WindowFrameBoundary() )
      )
      ( frameExclusionKind = WindowFrameExclusion() )?
      {
        frameStartKind = frameStart.first;
        frameStartExpr = frameStart.second;
        if (frameEnd == null) {
          frameEndKind = WindowExpression.FrameBoundaryKind.CURRENT_ROW;
        } else {
          frameEndKind = frameEnd.first;
          frameEndExpr = frameEnd.second;
        }
        if (frameExclusionKind == null) {
          frameExclusionKind = WindowExpression.FrameExclusionKind.NO_OTHERS;
        }
      }
    )?
  )?
  <RIGHTPAREN>
  {
    WindowExpression winExpr = new WindowExpression(signature, argList, aggFilterExpr, partitionExprs, orderbyList,
      orderbyModifierList, orderbyNullModifierList, frameMode, frameStartKind, frameStartExpr, frameEndKind,
      frameEndExpr, frameExclusionKind, windowVar, windowFieldList, ignoreNulls, fromLast);
    return addSourceLocation(winExpr, startToken);
  }
}

WindowExpression.FrameMode WindowFrameMode() throws ParseException:
{
}
{
  <IDENTIFIER>
  {
    if (isToken(RANGE)) {
      return WindowExpression.FrameMode.RANGE;
    } else if (isToken(ROWS)) {
      return WindowExpression.FrameMode.ROWS;
    } else if (isToken(GROUPS)) {
      return WindowExpression.FrameMode.GROUPS;
    } else {
      throw createUnexpectedTokenError();
    }
  }
}

Pair<WindowExpression.FrameBoundaryKind, Expression> WindowFrameBoundary() throws ParseException:
{
  boolean current = false;
  Expression expr = null;
}
{
  (
    LOOKAHEAD({ laIdentifier(CURRENT) || laIdentifier(UNBOUNDED) }) <IDENTIFIER> { current = isToken(CURRENT); }
    | expr = Expression()
  )
  <IDENTIFIER>
  {
    WindowExpression.FrameBoundaryKind kind;
    if (current && isToken(ROW)) {
      kind = WindowExpression.FrameBoundaryKind.CURRENT_ROW;
    } else if (!current && isToken(PRECEDING)) {
      kind = expr == null
        ? WindowExpression.FrameBoundaryKind.UNBOUNDED_PRECEDING
        : WindowExpression.FrameBoundaryKind.BOUNDED_PRECEDING;
    } else if (!current && isToken(FOLLOWING)) {
      kind = expr == null
        ? WindowExpression.FrameBoundaryKind.UNBOUNDED_FOLLOWING
        : WindowExpression.FrameBoundaryKind.BOUNDED_FOLLOWING;
    } else {
      throw createUnexpectedTokenError();
    }
    return new Pair<WindowExpression.FrameBoundaryKind, Expression>(kind, expr);
  }
}

WindowExpression.FrameExclusionKind WindowFrameExclusion() throws ParseException:
{
  boolean current = false, no = false;
}
{
  <IDENTIFIER>
  {
    expectToken(EXCLUDE);
  }
  (
    <GROUP>
    {
      return WindowExpression.FrameExclusionKind.GROUP;
    }
    |
    (
      <IDENTIFIER>
      {
        if (isToken(TIES)) {
          return WindowExpression.FrameExclusionKind.TIES;
        } else if (isToken(CURRENT)) {
          current = true;
        } else if (isToken(NO)) {
          no = true;
        } else {
          throw createUnexpectedTokenError();
        }
      }
      <IDENTIFIER>
      {
        if (current && isToken(ROW)) {
          return WindowExpression.FrameExclusionKind.CURRENT_ROW;
        } else if (no && isToken(OTHERS)) {
          return WindowExpression.FrameExclusionKind.NO_OTHERS;
        } else {
          throw createUnexpectedTokenError();
        }
      }
    )
  )
}

Expression ParenthesizedExpression() throws ParseException:
{
  Token startToken = null;
  Expression expr = null, expr2 = null;
  List<Expression> exprList = null;
}
{
    (
    LOOKAHEAD(2)
    <LEFTPAREN> { startToken = token; } expr = Expression()
    (
      <COMMA> expr2 = Expression()
      {
        if (exprList == null) {
          exprList = new ArrayList<Expression>();
          exprList.add(expr);
        }
        exprList.add(expr2);
      }
    )*
    <RIGHTPAREN>
    |
    expr = Subquery()
    )
    {
      if (exprList != null) {
        ListConstructor listExpr = new ListConstructor(ListConstructor.Type.ORDERED_LIST_CONSTRUCTOR, exprList);
        return addSourceLocation(listExpr, startToken);
      } else {
        return expr;
      }
    }
}

Expression CaseExpr() throws ParseException:
{
   Token startToken = null;
   Expression conditionExpr = null;
   List<Expression> whenExprs = new ArrayList<Expression>();
   List<Expression> thenExprs = new ArrayList<Expression>();
   Expression elseExpr = null;
   Expression whenExpr = null;
   Expression thenExpr = null;
}
{
   <CASE> { startToken = token; }
   ( conditionExpr = Expression() )?
   (
     <WHEN> whenExpr = Expression()
     {
        whenExprs.add(whenExpr);
     }
     <THEN> thenExpr = Expression()
     {
        thenExprs.add(thenExpr);
     }
   )*
   (<ELSE> elseExpr = Expression() )?
   <END>
   {
     if (conditionExpr == null) {
        LiteralExpr litExpr = new LiteralExpr(TrueLiteral.INSTANCE);
        conditionExpr = addSourceLocation(litExpr, startToken);
     }
     CaseExpression caseExpr = new CaseExpression(conditionExpr, whenExprs, thenExprs, elseExpr);
     return addSourceLocation(caseExpr, startToken);
   }
}

SelectExpression SelectExpression(boolean subquery) throws ParseException:
{
  List<LetClause> letClauses = new ArrayList<LetClause>();
  SelectSetOperation selectSetOperation;
  OrderbyClause orderbyClause = null;
  LimitClause limitClause = null;
  createNewScope();
}
{
    ( letClauses = LetClause() )?
    selectSetOperation = SelectSetOperation()
    (orderbyClause = OrderbyClause() {})?
    (limitClause = LimitClause() {})?
    {
      SelectExpression selectExpr =
        new SelectExpression(letClauses, selectSetOperation, orderbyClause, limitClause, subquery);
      selectExpr.setSourceLocation((!letClauses.isEmpty() ? letClauses.get(0) : selectSetOperation).getSourceLocation());
      return selectExpr;
    }
}

SelectSetOperation SelectSetOperation() throws ParseException:
{
  SetOperationInput setOperationInputLeft;
  List<SetOperationRight> setOperationRights = new ArrayList<SetOperationRight>();
}
{
  {
      SelectBlock selectBlockLeft = null;
      SelectExpression subqueryLeft = null;
      Expression expr = null;
  }
  selectBlockLeft = SelectBlock()
  {
     setOperationInputLeft = new SetOperationInput(selectBlockLeft, subqueryLeft);
  }
  (
    {
      SetOpType opType = SetOpType.UNION;
      boolean setSemantics = true;
      SelectBlock selectBlockRight = null;
      SelectExpression subqueryRight = null;
    }
    (<UNION> {opType = SetOpType.UNION;} |<INTERSECT> {opType = SetOpType.INTERSECT;} |<EXCEPT> {opType = SetOpType.EXCEPT;}) (<ALL> {setSemantics = false;} )?
    (selectBlockRight = SelectBlock()| subqueryRight = Subquery())
    {
        setOperationRights.add(new SetOperationRight(opType, setSemantics, new SetOperationInput(selectBlockRight, subqueryRight)));
    }
  )*
  {
    SelectSetOperation selectSetOp = new SelectSetOperation(setOperationInputLeft, setOperationRights);
    selectSetOp.setSourceLocation(selectBlockLeft.getSourceLocation());
    return selectSetOp;
  }
}

SelectExpression Subquery() throws ParseException:
{
   SelectExpression selectExpr = null;
}
{
  <LEFTPAREN> selectExpr = SelectExpression(true) {} <RIGHTPAREN>
  {
    return selectExpr;
  }
}

SelectBlock SelectBlock() throws ParseException:
{
  SelectClause selectClause = null;
  FromClause fromClause = null;
  List<LetClause> fromLetClauses = null;
  WhereClause whereClause = null;
  List<AbstractClause> fromLetWhereClauses = new ArrayList<AbstractClause>();
  GroupbyClause groupbyClause = null;
  List<LetClause> gbyLetClauses = null;
  HavingClause havingClause = null;
  List<AbstractClause> gbyLetHavingClauses = new ArrayList<AbstractClause>();
  SourceLocation startSrcLoc = null;
}
{
  (
    (
     selectClause = SelectClause() { startSrcLoc = selectClause.getSourceLocation(); }
     (
        (
          fromClause = FromClause()
          (
              fromLetClauses = LetClause()
          )?
          (whereClause = WhereClause())?
          (
            groupbyClause = GroupbyClause()
            (
                gbyLetClauses = LetClause()
            )?
            (havingClause = HavingClause())?
          )?
        )
        |
        (
          fromLetClauses = LetClause()
          {
            // LET without FROM -> create dummy FROM clause: FROM {{missing}} AS #0
            SourceLocation sourceLoc = getSourceLocation(token);
            LiteralExpr missingExpr = new LiteralExpr(MissingLiteral.INSTANCE);
            missingExpr.setSourceLocation(sourceLoc);
            List<Expression> list = new ArrayList<Expression>(1);
            list.add(missingExpr);
            ListConstructor listExpr = new ListConstructor(ListConstructor.Type.ORDERED_LIST_CONSTRUCTOR, list);
            listExpr.setSourceLocation(sourceLoc);
            List<FromTerm> fromTerms = new ArrayList<FromTerm>(1);
            VariableExpr fromVar = new VariableExpr(new VarIdentifier("#0"));
            fromVar.setSourceLocation(sourceLoc);
            fromTerms.add(new FromTerm(listExpr, fromVar, null, new ArrayList<AbstractBinaryCorrelateClause>()));
            fromClause = new FromClause(fromTerms);
          }
          (whereClause = WhereClause())?
        )
     )?
    )
    |
    (
     fromClause = FromClause() { startSrcLoc = fromClause.getSourceLocation(); }
     (
        fromLetClauses = LetClause()
     )?
     (whereClause = WhereClause())?
     (
        groupbyClause = GroupbyClause()
        (
            gbyLetClauses = LetClause()
        )?
        (havingClause = HavingClause())?
     )?
     selectClause = SelectClause()
    )
  )
  {
    if (fromLetClauses != null) {
      fromLetWhereClauses.addAll(fromLetClauses);
    }
    if (whereClause != null) {
      fromLetWhereClauses.add(whereClause);
    }
    if (gbyLetClauses != null) {
      gbyLetHavingClauses.addAll(gbyLetClauses);
    }
    if (havingClause != null) {
      gbyLetHavingClauses.add(havingClause);
    }
    SelectBlock selectBlock = new SelectBlock(selectClause, fromClause, fromLetWhereClauses, groupbyClause,
      gbyLetHavingClauses);
    selectBlock.setSourceLocation(startSrcLoc);
    return selectBlock;
  }
}

SelectClause SelectClause() throws ParseException:
{
  Token startToken = null;
  SelectRegular selectRegular = null;
  SelectElement selectElement = null;
  List<List<String>> fieldExclusions = new ArrayList<List<String>>();
  List<String> nestedField = new ArrayList<String>();
  String identifier;
  boolean distinct = false;
}
{
  <SELECT> { startToken = token; } (<ALL>|<DISTINCT> { distinct = true; } )?
  (
    (
      selectRegular = SelectRegular()
      ( LOOKAHEAD({laIdentifier(EXCLUDE)}) <IDENTIFIER>
        identifier = Identifier() { nestedField.add(identifier); }
        ( <DOT> identifier = Identifier() { nestedField.add(identifier); } )*
        {
          fieldExclusions.add(nestedField);
          nestedField = new ArrayList<String>();
        }
        ( LOOKAHEAD(1) // Force <COMMA> to be recognized for a nested field in our EXCLUDE list.
          <COMMA> identifier = Identifier() { nestedField.add(identifier); }
          ( <DOT> identifier = Identifier() { nestedField.add(identifier); } )*
          {
            fieldExclusions.add(nestedField);
            nestedField = new ArrayList<String>();
          }
        )*
      )?
    )
    |
    selectElement = SelectElement()
  )?
  {
    SourceLocation sourceLoc = getSourceLocation(startToken);
    if (selectRegular == null && selectElement == null){
        Projection projection = new Projection(Projection.Kind.STAR, null, null);
        projection.setSourceLocation(sourceLoc);
        List<Projection> projections = new ArrayList<Projection>();
        projections.add(projection);
        selectRegular = new SelectRegular(projections);
        selectRegular.setSourceLocation(sourceLoc);
    }
    SelectClause selectClause = new SelectClause(selectElement, selectRegular, fieldExclusions, distinct);
    selectClause.setSourceLocation(sourceLoc);
    return selectClause;
  }
}

SelectRegular SelectRegular() throws ParseException:
{
  SourceLocation startSrcLoc = null;
  List<Projection> projections = new ArrayList<Projection>();
  Projection projection = null;
}
{
  projection = Projection()
  {
    projections.add(projection);
    startSrcLoc = projection.getSourceLocation();
  }
  ( LOOKAHEAD(2) <COMMA> projection = Projection()
    {
      projections.add(projection);
    }
  )*
  {
    SelectRegular selectRegular = new SelectRegular(projections);
    selectRegular.setSourceLocation(startSrcLoc);
    return selectRegular;
  }
}

SelectElement SelectElement() throws ParseException:
{
  Token startToken = null;
  Expression expr = null;
  String name = null;
}
{
  (<RAW>|<ELEMENT>|<VALUE>) { startToken = token; } expr = Expression()
  {
    SelectElement selectElement = new SelectElement(expr);
    return addSourceLocation(selectElement, startToken);
  }
}

Projection Projection() throws ParseException :
{
  SourceLocation startSrcLoc = null;
  Expression expr = null;
  Identifier identifier = null;
  String name = null;
  Projection.Kind kind = null;
  boolean star = false;
  boolean varStar = false;
}
{
  (
    <MUL> { kind = Projection.Kind.STAR; startSrcLoc = getSourceLocation(token); }
    | LOOKAHEAD(3) expr = VariableRef() <DOT> <MUL> { kind = Projection.Kind.VAR_STAR; }
    | expr = Expression()
      ( // EXCLUDE is a soft-keyword-- we want to avoid mistaking EXCLUDE as an identifier here.
        LOOKAHEAD({ getToken(1).kind == AS || getToken(1).kind == QUOTED_STRING
                    || (getToken(1).kind == IDENTIFIER && !laIdentifier(1, EXCLUDE)) })
        (<AS>)? name = Identifier()
      )?
      {
        kind = Projection.Kind.NAMED_EXPR;
        if (name == null) {
          String generatedColumnIdentifier = ExpressionToVariableUtil.getGeneratedIdentifier(expr, false);
          if (generatedColumnIdentifier != null) {
            name = SqlppVariableUtil.toUserDefinedName(generatedColumnIdentifier);
          }
        }
      }
  )
  {
    Projection projection = new Projection(kind, expr, name);
    projection.setSourceLocation(expr != null ? expr.getSourceLocation() : startSrcLoc);
    return projection;
  }
}

FromClause FromClause() throws ParseException :
{
  Token startToken = null;
  List<FromTerm> fromTerms = new ArrayList<FromTerm>();
  extendCurrentScope();
}
{
  {
    FromTerm fromTerm = null;
  }
    <FROM> { startToken = token; } fromTerm = FromTerm() { fromTerms.add(fromTerm); }
    (LOOKAHEAD(2) <COMMA> fromTerm = FromTerm() { fromTerms.add(fromTerm); } )*
  {
    FromClause fromClause = new FromClause(fromTerms);
    return addSourceLocation(fromClause, startToken);
  }
}

FromTerm FromTerm() throws ParseException :
{
  Expression leftExpr = null;
  VariableExpr leftVar = null;
  VariableExpr posVar = null;
  AbstractBinaryCorrelateClause correlateClause = null;
  List<AbstractBinaryCorrelateClause> correlateClauses = new ArrayList<AbstractBinaryCorrelateClause>();
}
{
  leftExpr = Expression()
  {
    if (leftExpr.getKind() == Expression.Kind.VARIABLE_EXPRESSION) {
      Token hintToken = fetchHint(token, SqlppHint.SUBPATH_HINT);
      if (hintToken != null) {
        String subPath = hintToken.hintParams;
        ((VariableExpr) leftExpr).addHint(new ExternalSubpathAnnotation(subPath));
      }
    }
  } ((<AS>)? leftVar = Variable())? (<AT> posVar = Variable())?
  (
     (
      correlateClause = JoinOrUnnestClause(JoinType.INNER, UnnestType.INNER)
      | ( <INNER> correlateClause = JoinOrUnnestClause(JoinType.INNER, UnnestType.INNER) )
      | ( <LEFT> ( <OUTER> )? correlateClause = JoinOrUnnestClause(JoinType.LEFTOUTER, UnnestType.LEFTOUTER) )
      | ( <RIGHT> ( <OUTER> )? correlateClause = JoinClause(JoinType.RIGHTOUTER) )
      | ( <CROSS> correlateClause = CrossJoinClause() )
     )
     {
        correlateClauses.add(correlateClause);
     }
  )*
  {
    if (leftVar == null) {
        leftVar = ExpressionToVariableUtil.getGeneratedVariable(leftExpr, true);
    }
    FromTerm fromTerm = new FromTerm(leftExpr, leftVar, posVar, correlateClauses);
    fromTerm.setSourceLocation(leftExpr.getSourceLocation());
    return fromTerm;
  }
}

AbstractBinaryCorrelateClause JoinOrUnnestClause(JoinType joinType, UnnestType unnestType) throws ParseException :
{
  AbstractBinaryCorrelateClause correlateClause = null;
}
{
  ( correlateClause = JoinClause(joinType) | correlateClause = UnnestClause(unnestType) )
  {
    return correlateClause;
  }
}

JoinClause JoinClause(JoinType joinType) throws ParseException :
{
    Token startToken = null;
    Triple<Expression, VariableExpr, VariableExpr> rightInput = null;
    Expression conditionExpr = null;
}
{
  <JOIN> { startToken = token; } rightInput = JoinClauseRightInput() <ON> conditionExpr = Expression()
  {
    JoinClause joinClause = new JoinClause(joinType, rightInput.first, rightInput.second, rightInput.third,
      conditionExpr, joinType == JoinType.INNER ? null : Literal.Type.MISSING);
    return addSourceLocation(joinClause, startToken);
  }
}

JoinClause CrossJoinClause() throws ParseException :
{
    Token startToken = null;
    Triple<Expression, VariableExpr, VariableExpr> rightInput = null;
    Expression conditionExpr = null;
}
{
  <JOIN> { startToken = token; } rightInput = JoinClauseRightInput()
  {
    JoinClause joinClause = new JoinClause(JoinType.INNER, rightInput.first, rightInput.second, rightInput.third,
      new LiteralExpr(TrueLiteral.INSTANCE), null);
    return addSourceLocation(joinClause, startToken);
  }
}

Triple<Expression, VariableExpr, VariableExpr> JoinClauseRightInput() throws ParseException :
{
    Expression rightExpr = null;
    VariableExpr rightVar = null;
    VariableExpr posVar = null;
}
{
  rightExpr = Expression()
  {
    if (rightExpr.getKind() == Expression.Kind.VARIABLE_EXPRESSION) {
        Token hintToken = fetchHint(token, SqlppHint.SUBPATH_HINT);
        if (hintToken != null) {
          String subPath = hintToken.hintParams;
          ((VariableExpr) rightExpr).addHint(new ExternalSubpathAnnotation(subPath));
        }
    }
  } ((<AS>)? rightVar = Variable())? (<AT> posVar = Variable())?
  {
    if (rightVar == null) {
      rightVar = ExpressionToVariableUtil.getGeneratedVariable(rightExpr, true);
    }
    return new Triple<Expression, VariableExpr, VariableExpr>(rightExpr, rightVar, posVar);
  }
}

UnnestClause UnnestClause(UnnestType unnestType) throws ParseException :
{
    Token startToken = null;
    Expression rightExpr = null;
    VariableExpr rightVar = null;
    VariableExpr posVar = null;
}
{
  (<UNNEST>|<CORRELATE>|<FLATTEN>) { startToken = token; } rightExpr = Expression() ((<AS>)? rightVar = Variable())? (<AT> posVar = Variable())?
  {
    if (rightVar == null) {
      rightVar = ExpressionToVariableUtil.getGeneratedVariable(rightExpr, true);
    }
    UnnestClause unnestClause = new UnnestClause(unnestType, rightExpr, rightVar, posVar,
      unnestType == UnnestType.INNER ? null : Literal.Type.MISSING);
    return addSourceLocation(unnestClause, startToken);
  }
}

List<LetClause> LetClause() throws ParseException:
{
    List<LetClause> letList = new ArrayList<LetClause>();
    LetClause letClause;
}
{
    (
     (<LET>|<LETTING>) letClause = LetElement() { letList.add(letClause); } (LOOKAHEAD(1) <COMMA> letClause = LetElement() { letList.add(letClause); })*
     |
     <WITH> letClause = WithElement() { letList.add(letClause); } (LOOKAHEAD(1) <COMMA> letClause = WithElement() { letList.add(letClause); })*
    )
    {
      return letList;
    }
}

WhereClause WhereClause() throws ParseException :
{
  Token startToken = null;
  Expression whereExpr;
}
{
    <WHERE> { startToken = token; } whereExpr = Expression()
    {
      WhereClause wc = new WhereClause(whereExpr);
      return addSourceLocation(wc, startToken);
    }
}

OrderbyClause OrderbyClause() throws ParseException :
{
    Token startToken = null;
    OrderbyClause oc = new OrderbyClause();
    Triple<Expression, OrderbyClause.OrderModifier, OrderbyClause.NullOrderModifier> orderbyExpr = null;
    List<Expression> orderbyList = new ArrayList<Expression>();
    List<OrderbyClause.OrderModifier> modifierList = new ArrayList<OrderbyClause.OrderModifier>();
    List<OrderbyClause.NullOrderModifier> nullModifierList = new ArrayList<OrderbyClause.NullOrderModifier>();
}
{
  <ORDER>
  {
    startToken = token;
    Token hintToken = fetchHint(token, SqlppHint.INMEMORY_HINT, SqlppHint.RANGE_HINT);
    if (hintToken != null) {
      switch (hintToken.hint) {
        case INMEMORY_HINT:
          String[] splits = hintToken.hintParams.split("\\s+");
          int numFrames = Integer.parseInt(splits[0]);
          int numTuples = Integer.parseInt(splits[1]);
          oc.setNumFrames(numFrames);
          oc.setNumTuples(numTuples);
          break;
        case RANGE_HINT:
          try {
            Expression rangeExpr = parseExpression(hintToken.hintParams);
            RangeMap rangeMap = RangeMapBuilder.parseHint(rangeExpr);
            oc.setRangeMap(rangeMap);
          } catch (CompilationException e) {
            throw new SqlppParseException(getSourceLocation(hintToken), e.getMessage());
          }
          break;
      }
    }
  }
  <BY> orderbyExpr = OrderByExpression()
  {
    orderbyList.add(orderbyExpr.first);
    modifierList.add(orderbyExpr.second);
    nullModifierList.add(orderbyExpr.third);
  }
  (
    LOOKAHEAD(2) <COMMA> orderbyExpr = OrderByExpression()
    {
      orderbyList.add(orderbyExpr.first);
      modifierList.add(orderbyExpr.second);
      nullModifierList.add(orderbyExpr.third);
    }
  )*
  {
    oc.setOrderbyList(orderbyList);
    oc.setModifierList(modifierList);
    oc.setNullModifierList(nullModifierList);
    return addSourceLocation(oc, startToken);
  }
}

Triple<Expression, OrderbyClause.OrderModifier, OrderbyClause.NullOrderModifier> OrderByExpression()
  throws ParseException:
{
  Expression orderbyExpr = null;
  OrderbyClause.OrderModifier modif = OrderbyClause.OrderModifier.ASC;
  OrderbyClause.NullOrderModifier nullModif = null;
}
{
  orderbyExpr = Expression()
  (
    <ASC> { modif = OrderbyClause.OrderModifier.ASC; }
    |
    <DESC> { modif = OrderbyClause.OrderModifier.DESC; }
  )?
  (
    LOOKAHEAD({ laIdentifier(NULLS) }) <IDENTIFIER> { expectToken(NULLS); } <IDENTIFIER>
    {
      if (isToken(FIRST)) {
        nullModif = OrderbyClause.NullOrderModifier.FIRST;
      } else if (isToken(LAST)) {
        nullModif = OrderbyClause.NullOrderModifier.LAST;
      } else {
        throw createUnexpectedTokenError();
      }
    }
  )?
  {
    return new Triple<Expression, OrderbyClause.OrderModifier, OrderbyClause.NullOrderModifier>(orderbyExpr, modif,
      nullModif);
  }
}

GroupbyClause GroupbyClause()throws ParseException :
{
    Token startToken = null;
    GroupbyClause gbc = new GroupbyClause();
    List<List<GbyVariableExpressionPair>> gbyList = null;
    List<GroupingElement> groupingElementList = null;
    Pair<VariableExpr, List<Pair<Expression, Identifier>>> groupVarWithFieldList = null;
    VariableExpr groupVar = null;
    List<Pair<Expression, Identifier>> groupFieldList = null;
}
{
    {
      Scope newScope = extendCurrentScopeNoPush(true);
      // extendCurrentScope(true);
    }
    <GROUP>
    {
      startToken = token;
      Token hintToken = fetchHint(token, SqlppHint.HASH_GROUP_BY_HINT);
      if (hintToken != null) {
        gbc.setHashGroupByHint(true);
      }
    }
    <BY> groupingElementList = GroupingElementList()
    (
      <GROUP> <AS> groupVarWithFieldList = VariableWithFieldMap()
      {
        groupVar = groupVarWithFieldList.first;
        groupFieldList = groupVarWithFieldList.second;
      }
    )?
    {
      if (groupingSetsParser == null) {
        groupingSetsParser = new SqlppGroupingSetsParser();
      }
      SourceLocation sourceLoc = getSourceLocation(startToken);
      try {
        gbyList = groupingSetsParser.parse(groupingElementList, sourceLoc);
      } catch (CompilationException e) {
        throw new SqlppParseException(sourceLoc, e.getMessage());
      }
      gbc.setGbyPairList(gbyList);
      gbc.setDecorPairList(new ArrayList<GbyVariableExpressionPair>());
      gbc.setWithVarMap(new HashMap<Expression, VariableExpr>());
      gbc.setGroupVar(groupVar);
      gbc.setGroupFieldList(groupFieldList);
      replaceCurrentScope(newScope);
      return addSourceLocation(gbc, startToken);
    }
}

List<GroupingElement> GroupingElementList() throws ParseException:
{
  List<GroupingElement> groupingElementList = new ArrayList<GroupingElement>();
  GroupingElement groupingElement = null;
}
{
  groupingElement = GroupingElement() { groupingElementList.add(groupingElement); }
  ( LOOKAHEAD(1) <COMMA> groupingElement = GroupingElement() { groupingElementList.add(groupingElement); } )*
  {
    return groupingElementList;
  }
}

GroupingElement GroupingElement() throws ParseException:
{
  GroupingElement groupingElement = null;
  List<GroupingSet> groupingSets = null;
  List<GroupingElement> groupingElements = null;
}
{
  (
    LOOKAHEAD(2)
    <LEFTPAREN> <RIGHTPAREN>
    {
      groupingElement = GroupingSet.EMPTY;
    }
    |
    LOOKAHEAD({ laIdentifier(ROLLUP) && laToken(2, LEFTPAREN) })
    <IDENTIFIER> { expectToken(ROLLUP); }
    <LEFTPAREN> groupingSets = OrdinaryGroupingSetList() <RIGHTPAREN>
    {
      groupingElement = new RollupCube(groupingSets, false);
    }
    |
    LOOKAHEAD({ laIdentifier(CUBE) && laToken(2, LEFTPAREN) })
    <IDENTIFIER> { expectToken(CUBE); }
    <LEFTPAREN> groupingSets = OrdinaryGroupingSetList() <RIGHTPAREN>
    {
      groupingElement = new RollupCube(groupingSets, true);
    }
    |
    LOOKAHEAD({ laIdentifier(GROUPING) && laIdentifier(2, SETS) && laToken(3, LEFTPAREN) })
    <IDENTIFIER> { expectToken(GROUPING); } <IDENTIFIER> { expectToken(SETS); }
    <LEFTPAREN> groupingElements = GroupingElementList() <RIGHTPAREN>
    {
      groupingElement = new GroupingSets(groupingElements);
    }
    |
    groupingElement = OrdinaryGroupingSet()
  )
  {
    return groupingElement;
  }
}

GroupingSet OrdinaryGroupingSet() throws ParseException:
{
  GbyVariableExpressionPair gbyExprPair = null;
  List<GbyVariableExpressionPair> items = null;
}
{
  (
    LOOKAHEAD(1) <LEFTPAREN> items = GbyVariableExpressionPairList() <RIGHTPAREN>
    | gbyExprPair = GbyVariableExpressionPair() { items = Collections.singletonList(gbyExprPair); }
  )
  {
    return new GroupingSet(items);
  }
}

List<GroupingSet> OrdinaryGroupingSetList() throws ParseException:
{
  GroupingSet groupingSet = null;
  List<GroupingSet> items = new ArrayList<GroupingSet>();
}
{
  groupingSet = OrdinaryGroupingSet() { items.add(groupingSet); }
  ( LOOKAHEAD(1) <COMMA> groupingSet = OrdinaryGroupingSet() { items.add(groupingSet); } )*
  {
    return items;
  }
}

List<GbyVariableExpressionPair> GbyVariableExpressionPairList() throws ParseException:
{
  GbyVariableExpressionPair gbyExprPair = null;
  List<GbyVariableExpressionPair> items = new ArrayList<GbyVariableExpressionPair>();
}
{
  gbyExprPair = GbyVariableExpressionPair() { items.add(gbyExprPair); }
  ( LOOKAHEAD(1) <COMMA> gbyExprPair = GbyVariableExpressionPair() { items.add(gbyExprPair); } )*
  {
    return items;
  }
}

GbyVariableExpressionPair GbyVariableExpressionPair() throws ParseException:
{
  Expression expr = null;
  VariableExpr var = null;
}
{
  expr = Expression() ( (<AS>)? var = Variable() )?
  {
    return new GbyVariableExpressionPair(var, expr);
  }
}

HavingClause HavingClause() throws ParseException:
{
   Token startToken = null;
   Expression filterExpr = null;
}
{
    <HAVING> { startToken = token; } filterExpr = Expression()
    {
       HavingClause havingClause = new HavingClause(filterExpr);
       return addSourceLocation(havingClause, startToken);
    }
}

LimitClause LimitClause() throws ParseException:
{
    Token startToken = null;
    Expression limitExpr = null, offsetExpr = null;
}
{
  (
    (
      <LIMIT> { startToken = token; pushForbiddenScope(getCurrentScope()); } limitExpr = Expression()
      ( <OFFSET> offsetExpr = Expression() )?
      { popForbiddenScope(); }
    )
    |
    (
      <OFFSET> { startToken = token; pushForbiddenScope(getCurrentScope()); } offsetExpr = Expression()
      { popForbiddenScope(); }
    )
  )
  {
    LimitClause lc = new LimitClause(limitExpr, offsetExpr);
    return addSourceLocation(lc, startToken);
  }
}

QuantifiedExpression QuantifiedExpression()throws ParseException:
{
  Token startToken = null;
  QuantifiedExpression qc = new QuantifiedExpression();
  List<QuantifiedPair> quantifiedList = new ArrayList<QuantifiedPair>();
  Expression satisfiesExpr;
  VariableExpr var;
  Expression inExpr;
  QuantifiedPair pair;
}
{
  {
    createNewScope();
  }

     ( LOOKAHEAD(2)
       (<ANY>|<SOME>)<AND><EVERY> { startToken = token; qc.setQuantifier(QuantifiedExpression.Quantifier.SOME_AND_EVERY); }
       | (<ANY>|<SOME>) { startToken = token; qc.setQuantifier(QuantifiedExpression.Quantifier.SOME); }
       | <EVERY> {  startToken = token; qc.setQuantifier(QuantifiedExpression.Quantifier.EVERY); } )
    var = Variable() <IN> inExpr = Expression()
    {
      pair = new QuantifiedPair(var, inExpr);
      quantifiedList.add(pair);
    }
    (
    <COMMA> var = Variable() <IN> inExpr = Expression()
    {
      pair = new QuantifiedPair(var, inExpr);
      quantifiedList.add(pair);
    }
    )*
     <SATISFIES> satisfiesExpr = Expression() (<END>)?
     {
       qc.setSatisfiesExpr(satisfiesExpr);
       qc.setQuantifiedList(quantifiedList);
       removeCurrentScope();
       return addSourceLocation(qc, startToken);
     }
}

LetClause LetElement() throws ParseException:
{
    VariableExpr varExp;
    Expression beExp;
    extendCurrentScope();
}
{
    varExp = Variable() <EQ> beExp = Expression()
    {
      LetClause lc = new LetClause(varExp, beExp);
      lc.setSourceLocation(varExp.getSourceLocation());
      return lc;
    }
}

LetClause WithElement() throws ParseException:
{
    VariableExpr varExp;
    Expression beExp;
    extendCurrentScope();
}
{
    varExp = Variable() <AS> beExp = Expression()
    {
      LetClause lc = new LetClause(varExp, beExp);
      lc.setSourceLocation(varExp.getSourceLocation());
      return lc;
    }
}

TOKEN_MGR_DECLS:
{
    public int commentDepth = 0;
    public ArrayDeque<Integer> lexerStateStack = new ArrayDeque<Integer>();
    public Map<SourceLocation, String> hintCollector;

    public void pushState() {
      lexerStateStack.push( curLexState );
    }

    public void popState(String token) {
      if (lexerStateStack.size() > 0) {
         SwitchTo( lexerStateStack.pop() );
      } else {
         int errorLine = input_stream.getEndLine();
         int errorColumn = input_stream.getEndColumn();
         String msg = "Lexical error at line " + errorLine + ", column " + errorColumn + ". Encountered \"" + token
             + "\" but state stack is empty.";
         throw new TokenMgrError(msg, -1);
      }
    }

    void CommonTokenAction(Token token) {
      Token hintToken = token.specialToken;
      while (hintToken != null) { // make this a while loop
        hintToken.sourceLocation = new SourceLocation(hintToken.beginLine, hintToken.beginColumn);
        String text = hintToken.image.substring(1).trim();
        boolean hintFound = hintToken.parseHint(text);
        hintCollector.put(hintToken.sourceLocation, hintFound ? hintToken.hint.getIdentifier() : hintToken.hintParams);
        hintToken = hintToken.specialToken;
      }
    }
}

<DEFAULT,IN_DBL_BRACE>
TOKEN [IGNORE_CASE]:
{
  <ADAPTER: "adapter">
  | <ALL : "all">
  | <ANALYZE: "analyze">
  | <AND : "and">
  | <ANY : "any">
  | <APPLY : "apply">
  | <AS : "as">
  | <ASC : "asc">
  | <AT : "at">
  | <AUTOGENERATED : "autogenerated">
  | <BETWEEN : "between">
  | <BTREE : "btree">
  | <BY : "by">
  | <CASE : "case">
  | <CAST : "cast">
  | <CLOSED : "closed">
  | <CREATE : "create">
  | <CROSS : "cross">
  | <COMPACTION : "compaction"> // no longer used
  | <COMPACT : "compact">
  | <CONNECT : "connect">
  | <CORRELATE : "correlate">
  | <DATASET : "dataset">
  | <COLLECTION : "collection">
  | <DATAVERSE : "dataverse">
  | <DECLARE : "declare">
  | <DEFINITION : "definition">
  | <DELETE : "delete">
  | <DESC : "desc">
  | <DISCONNECT : "disconnect">
  | <DISTINCT : "distinct">
  | <DIV : "div">
  | <DROP : "drop">
  | <ELEMENT : "element">
  | <EXPLAIN : "explain">
  | <ELSE : "else">
  | <ENFORCED : "enforced">
  | <END : "end">
  | <EVERY : "every">
  | <EXCEPT : "except">
  | <EXISTS : "exists">
  | <EXTERNAL : "external">
  | <FALSE : "false">
  | <FEED : "feed">
  | <FILTER : "filter">
  | <FLATTEN : "flatten">
  | <FOR : "for">
  | <FROM : "from">
  | <FULL : "full">
  | <FULLTEXT : "fulltext">
  | <FUNCTION : "function">
  | <GROUP : "group">
  | <HAVING : "having">
  | <HINTS : "hints">
  | <IF : "if">
  | <INTO : "into">
  | <IN : "in">
  | <INDEX : "index">
  | <INGESTION : "ingestion">
  | <INNER : "inner">
  | <INSERT : "insert">
  | <INTERNAL : "internal">
  | <INTERSECT : "intersect">
  | <IS : "is">
  | <JOIN : "join">
  | <KEYWORD : "keyword">
  | <KEY : "key">
  | <KNOWN : "known">
  | <LEFT : "left">
  | <LETTING : "letting">
  | <LET : "let">
  | <LIKE : "like">
  | <LIMIT : "limit">
  | <LOAD : "load">
  | <MISSING : "missing">
  | <MOD : "mod">
  | <NODEGROUP : "nodegroup">
  | <NGRAM : "ngram">
  | <NOT : "not">
  | <NULL : "null">
  | <OFFSET : "offset">
  | <ON : "on">
  | <OPEN : "open">
  | <OR : "or">
  | <ORDER : "order">
  | <OUTER : "outer">
  | <OUTPUT : "output">
  | <OVER: "over">
  | <PATH : "path">
  | <POLICY : "policy">
  | <PRESORTED : "pre-sorted">
  | <PRIMARY : "primary">
  | <RAW : "raw">
  | <REFRESH : "refresh">
  | <RETURN : "return">
  | <RETURNING : "returning">
  | <RIGHT : "right">
  | <RTREE : "rtree">
  | <RUN : "run">
  | <SATISFIES : "satisfies">
  | <SECONDARY : "secondary">
  | <SELECT : "select">
  | <SET : "set">
  | <SOME : "some">
  | <START : "start">
  | <STOP : "stop">
  | <SYNONYM : "synonym">
  | <TEMPORARY : "temporary"> // intentionally not used but reserved for future usage
  | <THEN : "then">
  | <TO : "to">
  | <TRUE : "true">
  | <TYPE : "type">
  | <UNION : "union">
  | <UNKNOWN : "unknown">
  | <UNNEST : "unnest">
  | <UPDATE : "update">
  | <UPSERT : "upsert">
  | <USE : "use">
  | <USING : "using">
  | <VALUE : "value">
  | <VALUED : "valued">
  | <VIEW : "view">
  | <WHEN : "when">
  | <WHERE : "where">
  | <WITH : "with">
  | <WRITE : "write">
}

<DEFAULT,IN_DBL_BRACE>
TOKEN :
{
    <CARET : "^">
  | <CONCAT : "||">
  | <DIVIDE : "/">
  | <MINUS : "-">
  | <MUL : "*">
  | <PLUS : "+">

  | <LEFTPAREN : "(">
  | <RIGHTPAREN : ")">
  | <LEFTBRACKET : "[">
  | <RIGHTBRACKET : "]">

  | <ATT : "@">
  | <COLON : ":">
  | <COMMA : ",">
  | <DOT : ".">
  | <PERCENT: "%">
  | <QUES : "?">
  | <SEMICOLON : ";">
  | <SHARP : "#">

  | <LT : "<">
  | <GT : ">">
  | <LE : "<=">
  | <GE : ">=">
  | <EQ : "=">
  | <NE : "!=">
  | <LG : "<>">
  | <SIMILAR : "~=">
}

<DEFAULT,IN_DBL_BRACE>
TOKEN :
{
    <LEFTBRACE : "{"> { pushState(); } : DEFAULT
}

<DEFAULT>
TOKEN :
{
    <RIGHTBRACE : "}"> { popState("}"); }
}

<DEFAULT,IN_DBL_BRACE>
TOKEN :
{
    <LEFTDBLBRACE : "{{"> { pushState(); } : IN_DBL_BRACE
}

<IN_DBL_BRACE>
TOKEN :
{
    <RIGHTDBLBRACE : "}}"> { popState("}}"); }
}

<DEFAULT,IN_DBL_BRACE>
TOKEN :
{
    <#DIGIT : ["0" - "9"]>
}

<DEFAULT,IN_DBL_BRACE>
TOKEN:
{
    <INTEGER_LITERAL : <DIGITS> >
  | <DOUBLE_LITERAL: <DIGITS> ( "." <DIGITS> ) (("e"|"E") ("+"|"-")? <DIGITS>)?
                      | <DIGITS> (("e"|"E") ("+"|"-")? <DIGITS>)
                      | "." <DIGITS> (("e"|"E") ("+"|"-")? <DIGITS>)?
    >
  | <FLOAT_LITERAL:  <DIGITS> ( "f" | "F" )
                      | <DIGITS> ( "." <DIGITS> ( "f" | "F" ) )?
                      | "." <DIGITS> ( "f" | "F" )
    >
  | <#DIGITS : (<DIGIT>)+ >
}

<DEFAULT,IN_DBL_BRACE>
TOKEN :
{
    <#LETTER : ["A" - "Z", "a" - "z"]>
  | <#IDENTIFIER_START_SPECIALCHAR : ["_"]>
  | <#IDENTIFIER_REST_SPECIALCHAR : ["$"]>
  | <#IDENTIFIER_START : <LETTER> | <IDENTIFIER_START_SPECIALCHAR> >
  | <#IDENTIFIER_REST  : <LETTER> | <DIGIT> | <IDENTIFIER_START_SPECIALCHAR> | <IDENTIFIER_REST_SPECIALCHAR> >
  | <IDENTIFIER : <IDENTIFIER_START> (<IDENTIFIER_REST>)* >
}

<DEFAULT,IN_DBL_BRACE>
TOKEN :
{
    // backslash u + 4 hex digits escapes are handled in the underlying JavaCharStream
    <QUOTED_STRING : "`" (
          <EscapeQuot>
        | <EscapeBslash>
        | <EscapeSlash>
        | <EscapeBspace>
        | <EscapeFormf>
        | <EscapeNl>
        | <EscapeCr>
        | <EscapeTab>
        | ~["`","\\"])* "`">
  | <STRING_LITERAL : ( ("E")? "\"" (
          <EscapeQuot>
        | <EscapeBslash>
        | <EscapeSlash>
        | <EscapeBspace>
        | <EscapeFormf>
        | <EscapeNl>
        | <EscapeCr>
        | <EscapeTab>
        | ~["\"","\\"])* "\"")
      | ( ("E")? "\'" (
          <EscapeApos>
        | <EscapeBslash>
        | <EscapeSlash>
        | <EscapeBspace>
        | <EscapeFormf>
        | <EscapeNl>
        | <EscapeCr>
        | <EscapeTab>
        | ~["\'","\\"])* "\'")>
  | < #EscapeQuot: "\\\"" >
  | < #EscapeApos: "\\\'" >
  | < #EscapeBslash: "\\\\" >
  | < #EscapeSlash: "\\/" >
  | < #EscapeBspace: "\\b" >
  | < #EscapeFormf: "\\f" >
  | < #EscapeNl: "\\n" >
  | < #EscapeCr: "\\r" >
  | < #EscapeTab: "\\t" >
}

<DEFAULT,IN_DBL_BRACE>
TOKEN :
{
    <DOLLAR_INTEGER_LITERAL : "$" <INTEGER_LITERAL> >
  | <DOLLAR_IDENTIFIER : "$" <IDENTIFIER> >
  | <DOLLAR_QUOTED_STRING: "$" <QUOTED_STRING> >
}

<DEFAULT,IN_DBL_BRACE>
SKIP:
{
    " "
  | "\t"
  | "\r"
  | "\n"
}

<DEFAULT,IN_DBL_BRACE>
SKIP:
{
    <"//" (~["\n"])* "\n">
}

<DEFAULT,IN_DBL_BRACE>
SKIP:
{
    <"//" (~["\n","\r"])* ("\n"|"\r"|"\r\n")?>
}

<DEFAULT,IN_DBL_BRACE>
SKIP:
{
    <"--" (~["\n"])* "\n">
}


<DEFAULT,IN_DBL_BRACE>
SKIP:
{
    <"--" (~["\n","\r"])* ("\n"|"\r"|"\r\n")?>
}

<DEFAULT,IN_DBL_BRACE>
SKIP:
{
    <"/*"> { pushState(); } : INSIDE_COMMENT
}

<INSIDE_COMMENT>
SPECIAL_TOKEN:
{
    <"+"(" ")*(~["*"])*>
}

<INSIDE_COMMENT>
SKIP:
{
    <"/*"> { pushState(); }
}

<INSIDE_COMMENT>
SKIP:
{
    <"*/"> { popState("*/"); }
  | <~[]>
}
