//
// 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.api.INamespaceResolver;
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.common.metadata.MetadataConstants;
import org.apache.asterix.common.metadata.MetadataUtil;
import org.apache.asterix.common.metadata.Namespace;
import org.apache.asterix.common.metadata.NamespaceResolver;
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.CreateDatabaseStatement;
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.DatabaseDropStatement;
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.TruncateDatasetStatement;
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.CopyFromStatement;
import org.apache.asterix.lang.common.statement.CopyToStatement;
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.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.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.ConfigurationUtil;
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.bootstrap.MetadataBuiltinEntities;
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 Namespace defaultNamespace;

    private String defaultDatabase;

    private DataverseName defaultDataverse;

    private SqlppGroupingSetsParser groupingSetsParser;

    private final WarningCollector warningCollector = new WarningCollector();

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

    private INamespaceResolver namespaceResolver;

    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 Namespace namespace;
       public String database;
       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, INamespaceResolver namespaceResolver) {
        this(new StringReader(s));
        super.setInput(s);
        this.namespaceResolver = namespaceResolver;
    }

    public SQLPPParser(Reader is, INamespaceResolver namespaceResolver) {
        this(is);
        this.namespaceResolver = namespaceResolver;
    }

    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);
        parser.namespaceResolver = new NamespaceResolver(false);
        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, INamespaceResolver nsr) throws CompilationException {
        return new SQLPPParser(text, nsr).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, INamespaceResolver nsr) throws CompilationException {
        return new SQLPPParser(text, nsr).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, INamespaceResolver nsr) throws CompilationException {
        return new SQLPPParser(text, nsr).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, INamespaceResolver nsr) throws CompilationException {
        return new SQLPPParser(text, nsr).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, INamespaceResolver nsr) throws CompilationException {
        return new SQLPPParser(text, nsr).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;
                String database = defaultDatabase;
                defaultDataverse = signature.getDataverseName();
                defaultDatabase = signature.getDatabaseName();
                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;
                defaultDatabase = database;
                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;
                String database = defaultDatabase;
                defaultDataverse = viewName.getDataverseName();
                defaultDatabase = viewName.getDatabaseName();
                createNewScope();
                Expression viewBodyExpr = SQLPPParser.this.ViewBody();
                removeCurrentScope();
                defaultDataverse = dataverse;
                defaultDatabase = database;
                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 List<Token> fetchHints(Token token, SqlppHint... expectedHints) {
          Token hintToken = token.specialToken;
          List<Token> hintTokenList = new ArrayList<Token>();
          while (hintToken != null) {
              SourceLocation sourceLoc = getSourceLocation(hintToken);
              hintCollector.remove(sourceLoc);
              if (hintToken.hint == null) {
                warnUnexpectedHint(hintToken.hintParams, sourceLoc, expectedHints);
              } else if (!ArrayUtils.contains(expectedHints, hintToken.hint)) {
                warnUnexpectedHint(hintToken.hint.getIdentifier(), sourceLoc, expectedHints);
              } else {
                hintTokenList.add(hintToken);
              }
              hintToken = hintToken.specialToken;
          }
          return hintTokenList;
        }


    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, this.namespaceResolver);
              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, this.namespaceResolver);
              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, this.namespaceResolver);
              return IndexedNLJoinExpressionAnnotation.newInstance(indexNames);
            }
          case RANGE_HINT:
            Expression rangeExpr = parseExpression(hintToken.hintParams, this.namespaceResolver);
            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, this.namespaceResolver);
              return SkipSecondaryIndexSearchExpressionAnnotation.newInstance(indexNames);
            }
          case SPATIAL_JOIN_HINT:
            List<Literal> hintValues = parseParenthesizedLiteralList(hintToken.hintParams, this.namespaceResolver);

            // 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, this.namespaceResolver);
              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;
      }
    }

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

    private Namespace createNamespace(List<String> parts, Token startToken) throws SqlppParseException {
      try {
        return namespaceResolver.resolve(parts);
      } catch (AsterixException e) {
        SqlppParseException pe = new SqlppParseException(getSourceLocation(startToken), e.getMessage());
        pe.initCause(e);
        throw pe;
      }
    }

    private void validatePKFields(Object primaryKeyFields, Token startToken) throws SqlppParseException {
      if (primaryKeyFields == null) {
        throw new SqlppParseException(getSourceLocation(startToken), "Invalid primary key specification.");
      }
    }

    private Map<String, String> getConfiguration(RecordConstructor withRecord) throws SqlppParseException {
      try {
        return ConfigurationUtil.toProperties(withRecord);
      } catch(AlgebricksException e) {
          throw new SqlppParseException(withRecord.getSourceLocation(), e.getMessage());
      }
    }
}

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 = CopyStatement()
    | stmt = DropStatement()
    | stmt = TruncateStatement()
    | stmt = SetStatement()
    | stmt = InsertStatement()
    | stmt = DeleteStatement()
    | stmt = UpdateStatement()
    | stmt = UpsertStatement()
    | stmt = ConnectionStatement()
    | stmt = CompactStatement()
    | stmt = AnalyzeStatement()
    | stmt = Query()
  )
  {
    return stmt;
  }
}

DataverseDecl DataverseDeclaration() throws ParseException:
{
  Token startToken = null;
  Namespace ns = null;
  Triple<List<String>, Token, Token> ident = null;
}
{
  <USE> { startToken = token; } ident = MultipartIdentifier()
    {
      ns = createNamespace(ident.first, ident.second);
      defaultDataverse = ns.getDataverseName();
      defaultDatabase = ns.getDatabaseName();
      defaultNamespace = ns;
      DataverseDecl dvDecl = new DataverseDecl(ns);
      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 = CreateDatabaseStatement(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<Namespace,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<Namespace,Identifier> nameComponents = null;
  boolean ifNotExists = false;
  TypeExpression typeExpr = null;
  TypeExpression metaTypeExpr = null;
  Pair<List<Integer>, List<List<String>>> primaryKeyFields = null;
  Triple<List<Integer>, List<List<String>>, List<TypeExpression>> primaryKeyFieldsWithTypes = null;
  Map<String,String> hints = new HashMap<String,String>();
  DatasetDecl stmt = null;
  boolean autogenerated = false;
  Pair<Integer, List<String>> filterField = null;
  RecordConstructor withRecord = null;
  SelectExpression selectExpr = null;
  Query query = null;
}
{
  nameComponents = QualifiedName()
  (typeExpr = DatasetTypeSpecification(RecordTypeDefinition.RecordKind.OPEN))?
  (
    { 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(RecordTypeDefinition.RecordKind.OPEN)
  )?
  ifNotExists = IfNotExists()
  (LOOKAHEAD(3) primaryKeyFieldsWithTypes = PrimaryKeyWithType()
    | primaryKeyFields = PrimaryKey())
  (<AUTOGENERATED> { autogenerated = true; } )?
  ( <HINTS> hints = Properties() )?
  ( LOOKAHEAD(2) <WITH> <FILTER> <ON>  filterField = NestedField() )?
  ( <WITH> withRecord = RecordConstructor() )?
  ( <AS> selectExpr = SelectExpression(false) )?
  {
    try {
      if (selectExpr != null) {
        query = new Query();
        query.setBody(selectExpr);
        query.setSourceLocation(selectExpr.getSourceLocation());
      }

      if (typeExpr == null) {
        validatePKFields(primaryKeyFieldsWithTypes, startStmtToken);
        InternalDetailsDecl idd = new InternalDetailsDecl(primaryKeyFieldsWithTypes.second,
          primaryKeyFieldsWithTypes.first, autogenerated, filterField == null? null : filterField.first,
          filterField == null? null : filterField.second, primaryKeyFieldsWithTypes.third);
        final TypeReferenceExpression anyObjectReference = new TypeReferenceExpression(
          new Pair(new Namespace(MetadataBuiltinEntities.ANY_OBJECT_DATATYPE.getDatabaseName(),
            MetadataBuiltinEntities.ANY_OBJECT_DATATYPE.getDataverseName()),
            new Identifier(MetadataBuiltinEntities.ANY_OBJECT_DATATYPE.getDatatypeName())));
        stmt = new DatasetDecl(nameComponents.first, nameComponents.second, anyObjectReference, null, hints,
          DatasetType.INTERNAL, idd, withRecord, ifNotExists, query);
        return addSourceLocation(stmt, startStmtToken);
      } else {
        validatePKFields(primaryKeyFields, startStmtToken);
        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, query);
        return addSourceLocation(stmt, startStmtToken);
      }
    } catch (CompilationException e) {
       throw new SqlppParseException(getSourceLocation(startStmtToken), e.getMessage());
    }
  }
}

DatasetDecl ExternalDatasetSpecification(Token startStmtToken) throws ParseException:
{
  Pair<Namespace,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(RecordTypeDefinition.RecordKind.OPEN)
  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(RecordTypeDefinition.RecordKind defaultRecordKind) throws ParseException:
{
  TypeExpression typeExpr = null;
}
{
  (
    LOOKAHEAD(3) typeExpr = DatasetRecordTypeSpecification(true, defaultRecordKind)
    | typeExpr = DatasetReferenceTypeSpecification()
  )
  {
    return typeExpr;
  }
}

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

RecordTypeDefinition DatasetRecordTypeSpecification(boolean allowRecordKindModifier, RecordTypeDefinition.RecordKind defaultRecordKind) 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 = defaultRecordKind;
     } 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);
  }
}

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<Namespace,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<Namespace,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);
    }
}

CreateDatabaseStatement CreateDatabaseStatement(Token startStmtToken) throws ParseException :
{
  CreateDatabaseStatement stmt = null;
}
{
  <DATABASE> stmt = DatabaseSpecification(startStmtToken)
  {
    return stmt;
  }
}

CreateDatabaseStatement DatabaseSpecification(Token startStmtToken) throws ParseException :
{
  String dbName = null;
  boolean ifNotExists = false;
}
{
  dbName = Identifier() ifNotExists = IfNotExists()
  {
    CreateDatabaseStatement stmt = new CreateDatabaseStatement(new Identifier(dbName), ifNotExists);
    return addSourceLocation(stmt, startStmtToken);
  }
}

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

CreateDataverseStatement DataverseSpecification(Token startStmtToken) throws ParseException :
{
  Namespace ns = null;
  boolean ifNotExists = false;
}
{
  ns = Namespace() ifNotExists = IfNotExists()
  {
    CreateDataverseStatement stmt = new CreateDataverseStatement(ns, 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<Namespace,Identifier> adapterName = null;
  Pair<Namespace,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<Namespace, 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<Namespace, Identifier> refNameComponents = null;
  List<CreateViewStatement.ForeignKeyDecl> foreignKeyDecls = null;
  DataverseName currentDataverse = defaultDataverse;
  String currentDatabase = defaultDatabase;
  Namespace currentNamespace = defaultNamespace;
}
{
  nameComponents = QualifiedName()
  (
      (
        typeExpr = DatasetTypeSpecification(RecordTypeDefinition.RecordKind.CLOSED)
        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) {
      defaultNamespace = nameComponents.first;
      defaultDataverse = nameComponents.first.getDataverseName();
      defaultDatabase = nameComponents.first.getDatabaseName();
    }
  }
  viewBodyExpr = ViewBody()
  {
    endPos = token;
    String viewBody = extractFragment(beginPos.beginLine, beginPos.beginColumn + 1, endPos.endLine,
      endPos.endColumn + 1);
    removeCurrentScope();
    defaultDataverse = currentDataverse;
    defaultDatabase = currentDatabase;
    defaultNamespace = currentNamespace;
    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;
}
{
  <TRANSFORM> <FUNCTION> stmt = FunctionSpecification(startStmtToken, orReplace, true)
  {
    return stmt;
  }
  |
  <FUNCTION> stmt = FunctionSpecification(startStmtToken, orReplace, false)
  {
    return stmt;
  }
}

CreateFunctionStatement FunctionSpecification(Token startStmtToken, boolean orReplace, boolean transform) 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<Namespace,Identifier> libraryName = null;
  List<String> externalIdentifier = null;
  RecordConstructor withOptions = null;
  boolean ifNotExists = false;
  CreateFunctionStatement stmt = null;
  DataverseName currentDataverse = defaultDataverse;
  String currentDatabase = defaultDatabase;
  Namespace currentNamespace = defaultNamespace;
}
{
  fctName = FunctionName()
  {
     defaultDataverse = fctName.dataverse;
     defaultDatabase = fctName.database;
     defaultNamespace = fctName.namespace;
  }
  paramsWithArity = FunctionParameters()
  {
    arity = paramsWithArity.first;
    params = paramsWithArity.second;
    signature = new FunctionSignature(fctName.database, 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, transform);
      }
    )
  |
    (
      <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;
    defaultDatabase = currentDatabase;
    defaultNamespace = currentNamespace;
    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<Namespace,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<Namespace,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<Namespace,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<Namespace,Identifier> nameComponents = null;
  Pair<Namespace,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.database, functionName.dataverse, fqFunctionName, 1));
  }
  (
      <COMMA> functionName = FunctionName()
      {
        fqFunctionName = functionName.library == null ? functionName.function : functionName.library + "#" + functionName.function;
        funcSigs.add(new FunctionSignature(functionName.database, 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.database, 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;
  }
}

Triple<List<Integer>, List<List<String>>, List<TypeExpression>> PrimaryKeyWithType() throws ParseException:
{
  Triple<List<Integer>, List<List<String>>, List<TypeExpression>> primaryKeyFieldsWithTypes = null;
}
{
  <PRIMARY> <KEY> <LEFTPAREN> primaryKeyFieldsWithTypes = PrimaryKeyFieldsWithType() <RIGHTPAREN>
  {
    return primaryKeyFieldsWithTypes;
  }
}

Triple<List<Integer>, List<List<String>>, List<TypeExpression>> PrimaryKeyFieldsWithType() throws ParseException:
{
  Pair<Integer, List<String>> tmp = null;
  List<Integer> keyFieldSourceIndicators = new ArrayList<Integer>();
  List<List<String>> primaryKeyFields = new ArrayList<List<String>>();
  List<TypeExpression> primaryKeyFieldTypes = new ArrayList<TypeExpression>();
  TypeExpression type = null;
}
{
  tmp = NestedField() <COLON> type = TypeReference()
    {
      keyFieldSourceIndicators.add(tmp.first);
      primaryKeyFields.add(tmp.second);
      primaryKeyFieldTypes.add(type);
    }
  ( <COMMA> tmp = NestedField() <COLON> type = TypeReference()
    {
      keyFieldSourceIndicators.add(tmp.first);
      primaryKeyFields.add(tmp.second);
      primaryKeyFieldTypes.add(type);
    }
  )*
    {
      return new Triple<List<Integer>, List<List<String>>, List<TypeExpression>> (keyFieldSourceIndicators,
        primaryKeyFields, primaryKeyFieldTypes);
    }
}

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 TruncateStatement() throws ParseException:
{
  Token startToken = null;
  Statement stmt = null;
}
{
  <TRUNCATE> { startToken = token; }
  (
    stmt = TruncateDatasetStatement(startToken)
  )
  {
    return stmt;
  }
}
TruncateDatasetStatement TruncateDatasetStatement(Token startStmtToken) throws ParseException:
{
  TruncateDatasetStatement stmt = null;
}
{
  DatasetToken() stmt = TruncateDatasetSpecification(startStmtToken)
  {
    return stmt;
  }
}

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

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 = DropDatabaseStatement(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<Namespace,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<Namespace,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<Namespace,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<Namespace,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<Namespace,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<Namespace,Identifier> pairId = null;
  boolean ifExists = false;
}
{
  pairId = TypeName() ifExists = IfExists()
  {
    TypeDropStatement stmt = new TypeDropStatement(pairId.first, pairId.second, ifExists);
    return addSourceLocation(stmt, startStmtToken);
  }
}

DatabaseDropStatement DropDatabaseStatement(Token startStmtToken) throws ParseException:
{
  DatabaseDropStatement stmt = null;
}
{
  <DATABASE> stmt = DropDatabaseSpecification(startStmtToken)
  {
    return stmt;
  }
}

DatabaseDropStatement DropDatabaseSpecification(Token startStmtToken) throws ParseException:
{
  String dbName = null;
  boolean ifExists = false;
}
{
  dbName = Identifier() ifExists = IfExists()
  {
    DatabaseDropStatement stmt = new DatabaseDropStatement(new Identifier(dbName), 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:
{
  Namespace ns = null;
  boolean ifExists = false;
}
{
  ns = Namespace() ifExists = IfExists()
  {
    DataverseDropStatement stmt = new DataverseDropStatement(ns, 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<Namespace,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<Namespace,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<Namespace,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<Namespace,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<Namespace,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<Namespace,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<Namespace, 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 CopyStatement() throws ParseException:
{
  Token startToken = null;
  Pair<Namespace,Identifier> nameComponents = null;
  Query query = null;
  Statement stmt = null;
  TypeExpression typeExpr = null;
  VariableExpr alias = null;
}
{
  <COPY>
  ( <INTO> { startToken = token; }
    nameComponents = QualifiedName()
    ((<AS>)? (typeExpr = DatasetTypeSpecification(RecordTypeDefinition.RecordKind.OPEN)))?
    stmt = CopyFromStatement(startToken, nameComponents, typeExpr)
  | <LEFTPAREN> { startToken = token; } query = Query() <RIGHTPAREN> (<AS>)? alias = Variable()  stmt = CopyToStatement(startToken, nameComponents, query, alias)
  | { startToken = token; } nameComponents = QualifiedName()
      (<AS>)? (typeExpr = DatasetTypeSpecification(RecordTypeDefinition.RecordKind.OPEN) | alias = Variable())?
      (stmt = CopyFromStatement(startToken, nameComponents, typeExpr) | stmt = CopyToStatement(startToken, nameComponents, query, alias))
  )
  {
    return stmt;
  }
}

CopyFromStatement CopyFromStatement(Token startToken, Pair<Namespace, Identifier> nameComponents, TypeExpression typeExpr) throws ParseException:
{
  Namespace namespace = nameComponents.first;
  Identifier datasetName = nameComponents.second;
  String adapterName;
  RecordConstructor withRecord;
  String sourcePath;
}
{
  <FROM> adapterName = AdapterName()
  <PATH> <LEFTPAREN> sourcePath = ConcatenatedStrings() <RIGHTPAREN>
  <WITH> withRecord = RecordConstructor()
    {
       ExternalDetailsDecl edd = new ExternalDetailsDecl();
       edd.setAdapter(adapterName);
       edd.setProperties(getConfiguration(withRecord));

       try {
         CopyFromStatement stmt = new CopyFromStatement(namespace, datasetName.getValue(), sourcePath, typeExpr, edd);
         return addSourceLocation(stmt, startToken);
       } catch (CompilationException e){
           throw new SqlppParseException(getSourceLocation(startToken), e.getMessage());
       }
    }
}

CopyToStatement CopyToStatement(Token startToken, Pair<Namespace, Identifier> nameComponents, Query query, VariableExpr alias) throws ParseException:
{
  VariableExpr usedAlias = alias;
  String adapterName;
  RecordConstructor withRecord;
  Namespace namespace = nameComponents == null ? null : nameComponents.first;
  String datasetName = nameComponents == null ? null : nameComponents.second.getValue();
  List<Expression> pathExprs;
  RecordTypeDefinition recordTypeDefinition = null;
  TypeExpression typeExpr = null;
  Boolean isRecordTypeDefinition = false;
  Map<String, String> formatConfigs = null;
  String propertyName = null, propertyValue = null;

  List<Expression> partitionExprs = new ArrayList<Expression>();
  Map<Integer, VariableExpr> partitionVarExprs = new HashMap<Integer, VariableExpr>();
  List<Expression> orderbyList = new ArrayList<Expression>();
  List<OrderbyClause.OrderModifier> orderbyModifierList = new ArrayList<OrderbyClause.OrderModifier>();
  List<OrderbyClause.NullOrderModifier> orderbyNullModifierList = new ArrayList<OrderbyClause.NullOrderModifier>();
}
{
  <TO> adapterName = AdapterName()
  <PATH> <LEFTPAREN> pathExprs = ExpressionList() <RIGHTPAREN>
  (CopyToOverClause(partitionExprs, partitionVarExprs, orderbyList, orderbyModifierList, orderbyNullModifierList))?
  (<TYPE> <LEFTPAREN>
    {
      recordTypeDefinition = RecordTypeDef();
      isRecordTypeDefinition = true;
    }
    <RIGHTPAREN>
  )?
  (<AS>
    {
      if (isRecordTypeDefinition == false) {
        typeExpr = DatasetRecordTypeSpecification(false, null);
      } else {
        throw new SqlppParseException(getSourceLocation(token), "Syntax error: Both 'TYPE()' and 'AS()' are provided. Please use either 'TYPE()' or 'AS()'.");
      }
    }
  )?
  (LOOKAHEAD(2) <IDENTIFIER> { propertyName = token.image.toLowerCase(); } propertyValue = StringLiteral()
    {
      if (formatConfigs == null) {
        formatConfigs = new HashMap<String, String>();
      }
      formatConfigs.put(propertyName, propertyValue);
    }
  )*
  <WITH> withRecord = RecordConstructor()
    {
       ExternalDetailsDecl edd = new ExternalDetailsDecl();
       edd.setAdapter(adapterName);
       edd.setProperties(getConfiguration(withRecord));

       if(namespace == null) {
          namespace = defaultNamespace;
       }

       if(usedAlias == null) {
          usedAlias = new VariableExpr(SqlppVariableUtil.toInternalVariableIdentifier(datasetName));
       }

       CopyToStatement stmt = new CopyToStatement(namespace, datasetName, query, usedAlias, edd, pathExprs, partitionExprs, partitionVarExprs, orderbyList, orderbyModifierList, orderbyNullModifierList, getVarCounter(), typeExpr, recordTypeDefinition, formatConfigs);
       return addSourceLocation(stmt, startToken);
    }
}

 void CopyToOverClause(List<Expression> partitionExprs,
                       Map<Integer, VariableExpr> partitionVarExprs,
                       List<Expression> orderbyList,
                       List<OrderbyClause.OrderModifier> orderbyModifierList,
                       List<OrderbyClause.NullOrderModifier> orderbyNullModifierList) throws ParseException:
{
  Expression partitionExpr = null;
  VariableExpr partitionVar = null;
  OrderbyClause orderByClause = null;
}
{
   <OVER> <LEFTPAREN>

   (<IDENTIFIER> {expectToken(PARTITION);} <BY>
   partitionExpr = Expression() { partitionExprs.add(partitionExpr);}
   ((<AS>)? partitionVar = Variable() { partitionVarExprs.put(0, partitionVar); })?
   (
     <COMMA> partitionExpr = Expression() { partitionExprs.add(partitionExpr); }
     ((<AS>)? partitionVar = Variable() { partitionVarExprs.put(partitionExprs.size() - 1, partitionVar); })?
   )*)?
   (
      orderByClause = OrderbyClause()
      {
        orderbyList.addAll(orderByClause.getOrderbyList());
        orderbyModifierList.addAll(orderByClause.getModifierList());
        orderbyNullModifierList.addAll(orderByClause.getNullModifierList());
      }
   )?
   <RIGHTPAREN>
   {
     if(partitionExprs.isEmpty() && orderbyList.isEmpty()) {
       throw new SqlppParseException(getSourceLocation(token), "OVER-clause cannot be empty");
     }
   }
}



LoadStatement LoadStatement() throws ParseException:
{
  Token startToken = null;
  Namespace namespace = null;
  Identifier datasetName = null;
  boolean alreadySorted = false;
  String adapterName;
  Map<String,String> properties;
  Pair<Namespace,Identifier> nameComponents = null;
}
{
  <LOAD> { startToken = token; } Dataset() nameComponents = QualifiedName()
    {
      namespace = nameComponents.first;
      datasetName = nameComponents.second;
    }
  <USING> adapterName = AdapterName() properties = Configuration()
  (<PRESORTED>
    {
      alreadySorted = true;
    }
  )?
    {
      LoadStatement stmt = new LoadStatement(namespace, 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<Namespace,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, Namespace namespace, Identifier identifier) throws ParseException:
{
  RecordConstructor withRecord = null;
}
{
  ( <WITH> withRecord = RecordConstructor() )?
  {
    try {
    AnalyzeStatement stmt = new AnalyzeStatement(namespace, identifier.getValue(), withRecord);
    return addSourceLocation(stmt, startToken);
    } catch (CompilationException e) {
       throw new SqlppParseException(getSourceLocation(startToken), e.getMessage());
    }
  }
}

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

Statement CompactStatement() throws ParseException:
{
  Token startToken = null;
  Pair<Namespace,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<Namespace,Identifier> feedNameComponents = null;
  AbstractStatement stmt = null;
}
{
  <FEED> feedNameComponents = QualifiedName()
  {
    stmt = new StartFeedStatement (feedNameComponents);
    return addSourceLocation(stmt, startStmtToken);
  }
}

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

AbstractStatement DisconnectStatement(Token startStmtToken) throws ParseException:
{
  Pair<Namespace,Identifier> feedNameComponents = null;
  Pair<Namespace,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<Namespace,Identifier> feedNameComponents = null;
  Pair<Namespace,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);
    }
}

String ConcatenatedStrings() throws ParseException:
{
  String stringVal;
  StringBuilder stringBuilder = new StringBuilder();
}
{
  stringVal = StringLiteral() { stringBuilder.append(stringVal); }
  (<COMMA> stringVal = StringLiteral() { stringBuilder.append(',').append(stringVal); })*
  {
    return stringBuilder.toString();
  }
}

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<Namespace,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.namespace = createNamespace(list, 0, ln - 1, startToken);
    } else {
      result.namespace = defaultNamespace;
    }
    result.dataverse = result.namespace == null ? null : result.namespace.getDataverseName();
    result.database = result.namespace == null ? null : result.namespace.getDatabaseName();

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

Pair<Namespace,Identifier> TypeName() throws ParseException:
{
  Pair<Namespace,Identifier> name = null;
}
{
  name = QualifiedName()
    {
      if (name.first == null) {
        name.first = defaultNamespace;
      }
      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);
  }
}

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

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<Namespace,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();
    Namespace id1 = len > 1 ? createNamespace(list, 0, len - 1, startToken) : null;
    Identifier id2 = new Identifier(list.get(len - 1));
    return new Pair<Namespace,Identifier>(id1, id2);
  }
}

Triple<Namespace, 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();
    Namespace id1 = len > 2 ? createNamespace(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<Namespace,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(defaultDatabase, 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;
          }
          List<Token> hintTokens = fetchHints(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
          );
          for (Token hintToken : hintTokens) {
            annotation = parseExpressionAnnotation(hintToken);
            if (annotation != null) {
                // annotation may be null if hints are malformed
                annotationList.add(annotation);
            }
          }
          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 (annotationList.size() > 0) {
         op.addHints(annotationList);
       }
       return op==null? operand: op;
     }
}

Expression BetweenExpr() throws ParseException:
{
  boolean not = false;
  OperatorExpr op = null;
  Expression operand = null;
  IExpressionAnnotation annotation = null;
  List<IExpressionAnnotation> annotationList = new ArrayList<IExpressionAnnotation>();
}
{
    operand = IsExpr()
    (
      LOOKAHEAD(2)
      (<NOT> { not = true; })? <BETWEEN>
        {
          List<Token> hintTokens = fetchHints(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
          );
          for (Token hintToken : hintTokens) {
             annotation = parseExpressionAnnotation(hintToken);
             if (annotation != null) {
                // annotation may be null if hints are malformed
                annotationList.add(annotation);
             }
          }

          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 (annotationList.size() > 0) {
         op.addHints(annotationList);
       }
       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;
  List<IExpressionAnnotation> annotationList = null;
}
{
    operand = ConcatExpr()
    (
        LOOKAHEAD(2)
        (<NOT> { not = true; })? <LIKE>
        {
          List<Token> hintTokens = fetchHints(token, SqlppHint.SINGLE_DATASET_PREDICATE_SELECTIVITY_HINT,
            SqlppHint.SKIP_SECONDARY_INDEX_SEARCH_HINT, SqlppHint.USE_SECONDARY_INDEX_SEARCH_HINT);
          if (hintTokens != null && !hintTokens.isEmpty()) {
            annotationList = new ArrayList<IExpressionAnnotation>();
          }
          for (Token hintToken : hintTokens) {
            annotation = parseExpressionAnnotation(hintToken);
            if (annotation != null) {
              // annotation may be null if hints are malformed
              annotationList.add(annotation);
            }
          }
          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 (annotationList != null && !annotationList.isEmpty()) {
            op.addHints(annotationList);
          }
        }

        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()
  (
    LOOKAHEAD(2)(
      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 (star) {
          resultAccessor = new IndexAccessor(inputExpr, IndexAccessor.IndexKind.STAR, null);
    } else if (slice || expr1 == null) {
      if (expr1 == null) {
        expr1 = new LiteralExpr(new LongIntegerLiteral(0L));
      }
      resultAccessor = new ListSliceExpression(inputExpr, expr1, expr2);
    } 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.database, funcName.dataverse, fqFunctionName, arity);
    if (signature == null) {
      signature = new FunctionSignature(funcName.database, 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(ValueExpr() <DOT> <MUL>) expr = ValueExpr() <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, this.namespaceResolver);
            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()
      ( <LIMIT> limitExpr = 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">
  | <DATABASE : "database">
  | <DATAVERSE : "dataverse">
  | <DECLARE : "declare">
  | <DEFINITION : "definition">
  | <DELETE : "delete">
  | <DESC : "desc">
  | <DISCONNECT : "disconnect">
  | <DISTINCT : "distinct">
  | <DIV : "div">
  | <DROP : "drop">
  | <TRUNCATE : "truncate">
  | <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">
  | <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">
  | <COPY : "copy">
  | <TRANSFORM : "transform">
}

<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>
        | <EscapeBTickWithBslash>
        | <EscapeBtickWithBtick>
        | ~["`","\\"])* "`">
  | <STRING_LITERAL : ( ("E")? "\"" (
          <EscapeQuot>
        | <EscapeBslash>
        | <EscapeSlash>
        | <EscapeBspace>
        | <EscapeFormf>
        | <EscapeNl>
        | <EscapeBTickWithBslash>
        | <EscapeCr>
        | <EscapeTab>
        | ~["\"","\\"])* "\"")
      | ( ("E")? "\'" (
          <EscapeApos>
        | <EscapeBslash>
        | <EscapeSlash>
        | <EscapeBspace>
        | <EscapeFormf>
        | <EscapeNl>
        | <EscapeBTickWithBslash>
        | <EscapeCr>
        | <EscapeTab>
        | ~["\'","\\"])* "\'")>
  | < #EscapeBTickWithBslash: "\\`" >
  | < #EscapeBtickWithBtick: "``" >
  | < #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("*/"); }
  | <~[]>
}
