blob: e2a8759854e18d8053aee0ce367978ad250eb957 [file] [log] [blame]
Michael Blow82464fb2017-03-28 18:48:13 -04001//
2// Licensed to the Apache Software Foundation (ASF) under one
3// or more contributor license agreements. See the NOTICE file
4// distributed with this work for additional information
5// regarding copyright ownership. The ASF licenses this file
6// to you under the Apache License, Version 2.0 (the
7// "License"); you may not use this file except in compliance
8// with the License. You may obtain a copy of the License at
9//
10// http://www.apache.org/licenses/LICENSE-2.0
11//
12// Unless required by applicable law or agreed to in writing,
13// software distributed under the License is distributed on an
14// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15// KIND, either express or implied. See the License for the
16// specific language governing permissions and limitations
17// under the License.
18//
Yingyi Bu391f09e2015-10-29 13:49:39 -070019options {
20
21
22 STATIC = false;
23
24}
25
26
27PARSER_BEGIN(SQLPPParser)
28
29package org.apache.asterix.lang.sqlpp.parser;
30
31// For SQL++ ParserTokenManager
Till Westmanne9b2adf2016-10-15 12:39:01 -070032import java.util.ArrayDeque;
Yingyi Bu391f09e2015-10-29 13:49:39 -070033
34import java.io.BufferedReader;
35import java.io.File;
36import java.io.FileInputStream;
37import java.io.FileNotFoundException;
38import java.io.IOException;
39import java.io.InputStreamReader;
40import java.io.Reader;
41import java.io.StringReader;
42import java.util.ArrayList;
Yingyi Budaa549c2016-06-28 22:30:52 -070043import java.util.Collections;
Yingyi Bu391f09e2015-10-29 13:49:39 -070044import java.util.HashMap;
45import java.util.Iterator;
46import java.util.LinkedHashMap;
47import java.util.List;
48import java.util.Map;
49
50import org.apache.asterix.common.annotations.AutoDataGen;
51import org.apache.asterix.common.annotations.DateBetweenYearsDataGen;
52import org.apache.asterix.common.annotations.DatetimeAddRandHoursDataGen;
53import org.apache.asterix.common.annotations.DatetimeBetweenYearsDataGen;
54import org.apache.asterix.common.annotations.FieldIntervalDataGen;
55import org.apache.asterix.common.annotations.FieldValFileDataGen;
56import org.apache.asterix.common.annotations.FieldValFileSameIndexDataGen;
57import org.apache.asterix.common.annotations.IRecordFieldDataGen;
58import org.apache.asterix.common.annotations.InsertRandIntDataGen;
59import org.apache.asterix.common.annotations.ListDataGen;
60import org.apache.asterix.common.annotations.ListValFileDataGen;
61import org.apache.asterix.common.annotations.SkipSecondaryIndexSearchExpressionAnnotation;
62import org.apache.asterix.common.annotations.TypeDataGen;
63import org.apache.asterix.common.annotations.UndeclaredFieldsDataGen;
64import org.apache.asterix.common.config.DatasetConfig.DatasetType;
65import org.apache.asterix.common.config.DatasetConfig.IndexType;
Taewoo Kime65e6ca2017-01-14 17:53:28 -080066import org.apache.asterix.common.exceptions.CompilationException;
Dmitry Lychagin85142c02018-04-05 17:27:36 -070067import org.apache.asterix.common.exceptions.ErrorCode;
Dmitry Lychagin7c53fcf2017-11-07 12:07:41 -080068import org.apache.asterix.common.functions.FunctionConstants;
Yingyi Bu391f09e2015-10-29 13:49:39 -070069import org.apache.asterix.common.functions.FunctionSignature;
Dmitry Lychaginee54cc02018-05-25 19:26:18 -070070import org.apache.asterix.lang.common.base.AbstractLangExpression;
71import org.apache.asterix.lang.common.base.AbstractStatement;
Yingyi Bu391f09e2015-10-29 13:49:39 -070072import org.apache.asterix.lang.common.base.Expression;
73import org.apache.asterix.lang.common.base.Literal;
74import org.apache.asterix.lang.common.base.IParser;
Dmitry Lychaginee54cc02018-05-25 19:26:18 -070075import org.apache.asterix.lang.common.base.ILangExpression;
Yingyi Bu391f09e2015-10-29 13:49:39 -070076import org.apache.asterix.lang.common.base.Statement;
77import org.apache.asterix.lang.common.clause.GroupbyClause;
78import org.apache.asterix.lang.common.clause.LetClause;
79import org.apache.asterix.lang.common.clause.LimitClause;
80import org.apache.asterix.lang.common.clause.OrderbyClause;
81import org.apache.asterix.lang.common.clause.UpdateClause;
82import org.apache.asterix.lang.common.clause.WhereClause;
83import org.apache.asterix.lang.common.context.RootScopeFactory;
84import org.apache.asterix.lang.common.context.Scope;
85import org.apache.asterix.lang.common.expression.AbstractAccessor;
86import org.apache.asterix.lang.common.expression.CallExpr;
87import org.apache.asterix.lang.common.expression.FieldAccessor;
88import org.apache.asterix.lang.common.expression.FieldBinding;
89import org.apache.asterix.lang.common.expression.GbyVariableExpressionPair;
90import org.apache.asterix.lang.common.expression.IfExpr;
91import org.apache.asterix.lang.common.expression.IndexAccessor;
Dmitry Lychagin8ba59442017-06-16 14:19:45 -070092import org.apache.asterix.lang.common.expression.IndexedTypeExpression;
Yingyi Bu391f09e2015-10-29 13:49:39 -070093import org.apache.asterix.lang.common.expression.ListConstructor;
94import org.apache.asterix.lang.common.expression.LiteralExpr;
95import org.apache.asterix.lang.common.expression.OperatorExpr;
96import org.apache.asterix.lang.common.expression.OrderedListTypeDefinition;
97import org.apache.asterix.lang.common.expression.QuantifiedExpression;
98import org.apache.asterix.lang.common.expression.RecordConstructor;
99import org.apache.asterix.lang.common.expression.RecordTypeDefinition;
100import org.apache.asterix.lang.common.expression.TypeExpression;
101import org.apache.asterix.lang.common.expression.TypeReferenceExpression;
102import org.apache.asterix.lang.common.expression.UnaryExpr;
Yingyi Bu391f09e2015-10-29 13:49:39 -0700103import org.apache.asterix.lang.common.expression.UnorderedListTypeDefinition;
104import org.apache.asterix.lang.common.expression.VariableExpr;
105import org.apache.asterix.lang.common.literal.DoubleLiteral;
106import org.apache.asterix.lang.common.literal.FalseLiteral;
107import org.apache.asterix.lang.common.literal.FloatLiteral;
108import org.apache.asterix.lang.common.literal.LongIntegerLiteral;
Yingyi Bu535d86b2016-05-23 16:44:25 -0700109import org.apache.asterix.lang.common.literal.MissingLiteral;
Yingyi Bu391f09e2015-10-29 13:49:39 -0700110import org.apache.asterix.lang.common.literal.NullLiteral;
111import org.apache.asterix.lang.common.literal.StringLiteral;
112import org.apache.asterix.lang.common.literal.TrueLiteral;
113import org.apache.asterix.lang.common.parser.ScopeChecker;
114import org.apache.asterix.lang.common.statement.CompactStatement;
115import org.apache.asterix.lang.common.statement.ConnectFeedStatement;
Abdullah Alamoudifff200c2017-02-18 20:32:14 -0800116import org.apache.asterix.lang.common.statement.StartFeedStatement;
117import org.apache.asterix.lang.common.statement.StopFeedStatement;
Yingyi Bu391f09e2015-10-29 13:49:39 -0700118import org.apache.asterix.lang.common.statement.CreateDataverseStatement;
119import org.apache.asterix.lang.common.statement.CreateFeedPolicyStatement;
120import org.apache.asterix.lang.common.statement.CreateFeedStatement;
121import org.apache.asterix.lang.common.statement.CreateFunctionStatement;
122import org.apache.asterix.lang.common.statement.CreateIndexStatement;
Yingyi Bu391f09e2015-10-29 13:49:39 -0700123import org.apache.asterix.lang.common.statement.DatasetDecl;
124import org.apache.asterix.lang.common.statement.DataverseDecl;
125import org.apache.asterix.lang.common.statement.DataverseDropStatement;
126import org.apache.asterix.lang.common.statement.DeleteStatement;
127import org.apache.asterix.lang.common.statement.DisconnectFeedStatement;
Yingyi Buab817482016-08-19 21:29:31 -0700128import org.apache.asterix.lang.common.statement.DropDatasetStatement;
Yingyi Bu391f09e2015-10-29 13:49:39 -0700129import org.apache.asterix.lang.common.statement.ExternalDetailsDecl;
130import org.apache.asterix.lang.common.statement.FeedDropStatement;
Abdullah Alamoudi5dc73ed2016-07-28 05:03:13 +0300131import org.apache.asterix.lang.common.statement.FeedPolicyDropStatement;
Yingyi Bu391f09e2015-10-29 13:49:39 -0700132import org.apache.asterix.lang.common.statement.FunctionDecl;
133import org.apache.asterix.lang.common.statement.FunctionDropStatement;
134import org.apache.asterix.lang.common.statement.IndexDropStatement;
135import org.apache.asterix.lang.common.statement.InsertStatement;
136import org.apache.asterix.lang.common.statement.InternalDetailsDecl;
137import org.apache.asterix.lang.common.statement.LoadStatement;
138import org.apache.asterix.lang.common.statement.NodeGroupDropStatement;
139import org.apache.asterix.lang.common.statement.NodegroupDecl;
140import org.apache.asterix.lang.common.statement.Query;
141import org.apache.asterix.lang.common.statement.RefreshExternalDatasetStatement;
Yingyi Bu391f09e2015-10-29 13:49:39 -0700142import org.apache.asterix.lang.common.statement.SetStatement;
143import org.apache.asterix.lang.common.statement.TypeDecl;
144import org.apache.asterix.lang.common.statement.TypeDropStatement;
145import org.apache.asterix.lang.common.statement.UpdateStatement;
Yingyi Bucb5bf332017-01-02 22:19:50 -0800146import org.apache.asterix.lang.common.statement.UpsertStatement;
Yingyi Bu391f09e2015-10-29 13:49:39 -0700147import org.apache.asterix.lang.common.statement.WriteStatement;
148import org.apache.asterix.lang.common.struct.Identifier;
Dmitry Lychaginef1719e2017-12-15 08:33:07 -0800149import org.apache.asterix.lang.common.struct.OperatorType;
Yingyi Bu391f09e2015-10-29 13:49:39 -0700150import org.apache.asterix.lang.common.struct.QuantifiedPair;
151import org.apache.asterix.lang.common.struct.VarIdentifier;
152import org.apache.asterix.lang.sqlpp.clause.AbstractBinaryCorrelateClause;
153import org.apache.asterix.lang.sqlpp.clause.FromClause;
154import org.apache.asterix.lang.sqlpp.clause.FromTerm;
155import org.apache.asterix.lang.sqlpp.clause.HavingClause;
156import org.apache.asterix.lang.sqlpp.clause.JoinClause;
Yingyi Bu391f09e2015-10-29 13:49:39 -0700157import org.apache.asterix.lang.sqlpp.clause.Projection;
158import org.apache.asterix.lang.sqlpp.clause.SelectBlock;
159import org.apache.asterix.lang.sqlpp.clause.SelectClause;
160import org.apache.asterix.lang.sqlpp.clause.SelectElement;
161import org.apache.asterix.lang.sqlpp.clause.SelectRegular;
162import org.apache.asterix.lang.sqlpp.clause.SelectSetOperation;
163import org.apache.asterix.lang.sqlpp.clause.UnnestClause;
Xikui Wangf6741682018-02-22 19:17:17 -0800164import org.apache.asterix.lang.common.clause.WhereClause;
Yingyi Buc8c067c2016-07-25 23:37:19 -0700165import org.apache.asterix.lang.sqlpp.expression.CaseExpression;
Yingyi Bu391f09e2015-10-29 13:49:39 -0700166import org.apache.asterix.lang.sqlpp.expression.SelectExpression;
167import org.apache.asterix.lang.sqlpp.optype.JoinType;
168import org.apache.asterix.lang.sqlpp.optype.SetOpType;
169import org.apache.asterix.lang.sqlpp.struct.SetOperationInput;
170import org.apache.asterix.lang.sqlpp.struct.SetOperationRight;
Yingyi Bu9e3f9be2016-07-01 10:07:37 -0700171import org.apache.asterix.lang.sqlpp.util.ExpressionToVariableUtil;
Xikui Wang96fd4022017-04-10 14:23:31 -0700172import org.apache.asterix.lang.sqlpp.util.FunctionMapUtil;
Yingyi Buacc12a92016-03-26 17:25:05 -0700173import org.apache.asterix.lang.sqlpp.util.SqlppVariableUtil;
Dmitry Lychagin7c53fcf2017-11-07 12:07:41 -0800174import org.apache.asterix.om.functions.BuiltinFunctions;
Yingyi Bu391f09e2015-10-29 13:49:39 -0700175import org.apache.hyracks.algebricks.common.utils.Pair;
176import org.apache.hyracks.algebricks.common.utils.Triple;
Xikui Wang5a61b2a2018-01-02 14:14:03 -0800177import org.apache.hyracks.algebricks.common.exceptions.AlgebricksException;
Yingyi Bu391f09e2015-10-29 13:49:39 -0700178import org.apache.hyracks.algebricks.core.algebra.expressions.IExpressionAnnotation;
179import org.apache.hyracks.algebricks.core.algebra.expressions.IndexedNLJoinExpressionAnnotation;
180import org.apache.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
Dmitry Lychaginee54cc02018-05-25 19:26:18 -0700181import org.apache.hyracks.api.exceptions.SourceLocation;
Yingyi Bu391f09e2015-10-29 13:49:39 -0700182
Yingyi Bucaea8f02015-11-16 15:12:15 -0800183class SQLPPParser extends ScopeChecker implements IParser {
Yingyi Bu391f09e2015-10-29 13:49:39 -0700184
185 // optimizer hints
186 private static final String AUTO_HINT = "auto";
187 private static final String BROADCAST_JOIN_HINT = "bcast";
188 private static final String COMPOSE_VAL_FILES_HINT = "compose-val-files";
189 private static final String DATE_BETWEEN_YEARS_HINT = "date-between-years";
190 private static final String DATETIME_ADD_RAND_HOURS_HINT = "datetime-add-rand-hours";
191 private static final String DATETIME_BETWEEN_YEARS_HINT = "datetime-between-years";
192 private static final String HASH_GROUP_BY_HINT = "hash";
193 private static final String INDEXED_NESTED_LOOP_JOIN_HINT = "indexnl";
194 private static final String INMEMORY_HINT = "inmem";
195 private static final String INSERT_RAND_INT_HINT = "insert-rand-int";
196 private static final String INTERVAL_HINT = "interval";
197 private static final String LIST_HINT = "list";
198 private static final String LIST_VAL_FILE_HINT = "list-val-file";
199 private static final String RANGE_HINT = "range";
200 private static final String SKIP_SECONDARY_INDEX_SEARCH_HINT = "skip-index";
201 private static final String VAL_FILE_HINT = "val-files";
202 private static final String VAL_FILE_SAME_INDEX_HINT = "val-file-same-idx";
203
204 private static final String GEN_FIELDS_HINT = "gen-fields";
205
206 // data generator hints
207 private static final String DGEN_HINT = "dgen";
208
Till Westmann7199a562016-09-17 16:07:32 -0700209 // error configuration
210 protected static final boolean REPORT_EXPECTED_TOKENS = false;
211
Dmitry Lychagin1bdf8082018-06-13 14:48:23 -0700212 private int externalVarCounter;
213
Yingyi Bu391f09e2015-10-29 13:49:39 -0700214 private static class IndexParams {
215 public IndexType type;
216 public int gramLength;
217
218 public IndexParams(IndexType type, int gramLength) {
219 this.type = type;
220 this.gramLength = gramLength;
221 }
222 };
223
224 private static class FunctionName {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -0700225 public String dataverse;
226 public String library;
227 public String function;
228 public String hint;
229 public SourceLocation sourceLoc;
Yingyi Bu391f09e2015-10-29 13:49:39 -0700230 }
231
Dmitry Lychaginee54cc02018-05-25 19:26:18 -0700232 private String getHint(Token t) {
Yingyi Bu391f09e2015-10-29 13:49:39 -0700233 if (t.specialToken == null) {
234 return null;
235 }
236 String s = t.specialToken.image;
237 int n = s.length();
238 if (n < 2) {
239 return null;
240 }
241 return s.substring(1).trim();
242 }
243
Dmitry Lychaginee54cc02018-05-25 19:26:18 -0700244 private Token getHintToken(Token t) {
245 return t.specialToken;
246 }
247
248 private IRecordFieldDataGen parseFieldDataGen(String hint, Token hintToken) throws ParseException {
Yingyi Bu391f09e2015-10-29 13:49:39 -0700249 IRecordFieldDataGen rfdg = null;
250 String splits[] = hint.split(" +");
251 if (splits[0].equals(VAL_FILE_HINT)) {
252 File[] valFiles = new File[splits.length - 1];
253 for (int k=1; k<splits.length; k++) {
254 valFiles[k-1] = new File(splits[k]);
255 }
256 rfdg = new FieldValFileDataGen(valFiles);
257 } else if (splits[0].equals(VAL_FILE_SAME_INDEX_HINT)) {
258 rfdg = new FieldValFileSameIndexDataGen(new File(splits[1]), splits[2]);
259 } else if (splits[0].equals(LIST_VAL_FILE_HINT)) {
260 rfdg = new ListValFileDataGen(new File(splits[1]), Integer.parseInt(splits[2]), Integer.parseInt(splits[3]));
261 } else if (splits[0].equals(LIST_HINT)) {
262 rfdg = new ListDataGen(Integer.parseInt(splits[1]), Integer.parseInt(splits[2]));
263 } else if (splits[0].equals(INTERVAL_HINT)) {
264 FieldIntervalDataGen.ValueType vt;
265 if (splits[1].equals("int")) {
266 vt = FieldIntervalDataGen.ValueType.INT;
267 } else if (splits[1].equals("long")) {
268 vt = FieldIntervalDataGen.ValueType.LONG;
269 } else if (splits[1].equals("float")) {
270 vt = FieldIntervalDataGen.ValueType.FLOAT;
271 } else if (splits[1].equals("double")) {
272 vt = FieldIntervalDataGen.ValueType.DOUBLE;
273 } else {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -0700274 throw new SqlppParseException(getSourceLocation(hintToken), "Unknown type for interval data gen: " + splits[1]);
Yingyi Bu391f09e2015-10-29 13:49:39 -0700275 }
276 rfdg = new FieldIntervalDataGen(vt, splits[2], splits[3]);
277 } else if (splits[0].equals(INSERT_RAND_INT_HINT)) {
278 rfdg = new InsertRandIntDataGen(splits[1], splits[2]);
279 } else if (splits[0].equals(DATE_BETWEEN_YEARS_HINT)) {
280 rfdg = new DateBetweenYearsDataGen(Integer.parseInt(splits[1]), Integer.parseInt(splits[2]));
281 } else if (splits[0].equals(DATETIME_BETWEEN_YEARS_HINT)) {
282 rfdg = new DatetimeBetweenYearsDataGen(Integer.parseInt(splits[1]), Integer.parseInt(splits[2]));
283 } else if (splits[0].equals(DATETIME_ADD_RAND_HOURS_HINT)) {
284 rfdg = new DatetimeAddRandHoursDataGen(Integer.parseInt(splits[1]), Integer.parseInt(splits[2]), splits[3]);
285 } else if (splits[0].equals(AUTO_HINT)) {
286 rfdg = new AutoDataGen(splits[1]);
287 }
288 return rfdg;
289 }
290
Till Westmann7199a562016-09-17 16:07:32 -0700291 public SQLPPParser(String s) {
Yingyi Bu391f09e2015-10-29 13:49:39 -0700292 this(new StringReader(s));
293 super.setInput(s);
294 }
295
Taewoo Kime65e6ca2017-01-14 17:53:28 -0800296 public static void main(String args[]) throws ParseException, TokenMgrError, IOException, FileNotFoundException, CompilationException {
Yingyi Bu391f09e2015-10-29 13:49:39 -0700297 File file = new File(args[0]);
298 Reader fis = new BufferedReader(new InputStreamReader(new FileInputStream(file), "UTF-8"));
299 SQLPPParser parser = new SQLPPParser(fis);
300 List<Statement> st = parser.parse();
301 //st.accept(new SQLPPPrintVisitor(), 0);
302 }
303
Taewoo Kime65e6ca2017-01-14 17:53:28 -0800304 public List<Statement> parse() throws CompilationException {
Yingyi Bu391f09e2015-10-29 13:49:39 -0700305 try {
306 return Statement();
307 } catch (Error e) {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -0700308 // this is here as the JavaCharStream that's below the lexer sometimes throws Errors that are not handled
Yingyi Bu391f09e2015-10-29 13:49:39 -0700309 // by the ANTLR-generated lexer or parser (e.g it does this for invalid backslash u + 4 hex digits escapes)
Till Westmann60f89982017-08-11 18:14:20 -0700310 final String msg = e.getClass().getSimpleName() + (e.getMessage() != null ? ": " + e.getMessage() : "");
Dmitry Lychagin85142c02018-04-05 17:27:36 -0700311 throw new CompilationException(ErrorCode.PARSE_ERROR, msg);
Dmitry Lychaginee54cc02018-05-25 19:26:18 -0700312 } catch (SqlppParseException e) {
313 throw new CompilationException(ErrorCode.PARSE_ERROR, e.getSourceLocation(), getMessage(e));
Yingyi Bu391f09e2015-10-29 13:49:39 -0700314 } catch (ParseException e) {
Dmitry Lychagin85142c02018-04-05 17:27:36 -0700315 throw new CompilationException(ErrorCode.PARSE_ERROR, getMessage(e));
Yingyi Bu391f09e2015-10-29 13:49:39 -0700316 }
317 }
Till Westmann7199a562016-09-17 16:07:32 -0700318
319 protected String getMessage(ParseException pe) {
320 Token currentToken = pe.currentToken;
321 if (currentToken == null) {
322 return pe.getMessage();
323 }
324 int[][] expectedTokenSequences = pe.expectedTokenSequences;
325 String[] tokenImage = pe.tokenImage;
326 String sep = REPORT_EXPECTED_TOKENS ? eol : " ";
327 StringBuilder expected = REPORT_EXPECTED_TOKENS ? new StringBuilder() : null;
328 int maxSize = appendExpected(expected, expectedTokenSequences, tokenImage);
329 Token tok = currentToken.next;
330 int line = tok.beginLine;
Dmitry Lychaginee54cc02018-05-25 19:26:18 -0700331 StringBuilder message = new StringBuilder(128);
332 message.append("In line ").append(line).append(" >>").append(getLine(line)).append("<<").append(sep).append("Encountered ");
Till Westmann7199a562016-09-17 16:07:32 -0700333 for (int i = 0; i < maxSize; i++) {
334 if (i != 0) {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -0700335 message.append(' ');
Till Westmann7199a562016-09-17 16:07:32 -0700336 }
337 if (tok.kind == 0) {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -0700338 message.append(fixQuotes(tokenImage[0]));
Till Westmann7199a562016-09-17 16:07:32 -0700339 break;
340 }
Till Westmanne3c9f272016-10-09 11:09:26 -0700341 final String fixedTokenImage = tokenImage[tok.kind];
342 if (! tok.image.equalsIgnoreCase(stripQuotes(fixedTokenImage))) {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -0700343 message.append(fixQuotes(fixedTokenImage)).append(' ');
Till Westmanne3c9f272016-10-09 11:09:26 -0700344 }
Dmitry Lychaginee54cc02018-05-25 19:26:18 -0700345 message.append(quot).append(addEscapes(tok.image)).append(quot);
Till Westmann7199a562016-09-17 16:07:32 -0700346 tok = tok.next;
347 }
Dmitry Lychaginee54cc02018-05-25 19:26:18 -0700348 message.append(" at column ").append(currentToken.next.beginColumn).append('.').append(sep);
Till Westmann7199a562016-09-17 16:07:32 -0700349 if (REPORT_EXPECTED_TOKENS) {
350 if (expectedTokenSequences.length == 1) {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -0700351 message.append("Was expecting:").append(sep).append(" ");
Till Westmann7199a562016-09-17 16:07:32 -0700352 } else {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -0700353 message.append("Was expecting one of:").append(sep).append(" ");
Till Westmann7199a562016-09-17 16:07:32 -0700354 }
Dmitry Lychaginee54cc02018-05-25 19:26:18 -0700355 message.append(expected);
Till Westmann7199a562016-09-17 16:07:32 -0700356 }
Dmitry Lychaginee54cc02018-05-25 19:26:18 -0700357 return message.toString();
Till Westmann7199a562016-09-17 16:07:32 -0700358 }
359
Dmitry Lychaginee54cc02018-05-25 19:26:18 -0700360 protected static SourceLocation getSourceLocation(Token token) {
361 return token != null ? new SourceLocation(token.beginLine, token.beginColumn) : null;
362 }
363
Dmitry Lychagin5c26b422018-06-01 10:22:16 -0700364 protected static <T extends AbstractLangExpression> T addSourceLocation(T expr, Token token) {
365 expr.setSourceLocation(getSourceLocation(token));
366 return expr;
Dmitry Lychaginee54cc02018-05-25 19:26:18 -0700367 }
Yingyi Bu391f09e2015-10-29 13:49:39 -0700368}
369
370PARSER_END(SQLPPParser)
371
372
373List<Statement> Statement() throws ParseException:
374{
375 scopeStack.push(RootScopeFactory.createRootScope(this));
376 List<Statement> decls = new ArrayList<Statement>();
377 Statement stmt = null;
378}
379{
Murtadha Hubaildc775222017-08-21 15:22:45 +0300380 (
381 (stmt = SingleStatement()
382 {
383 decls.add(stmt);
384 }
385 )?
386 (<SEMICOLON>)+
Yingyi Bu391f09e2015-10-29 13:49:39 -0700387 )*
388 <EOF>
389 {
390 return decls;
391 }
392}
393
394Statement SingleStatement() throws ParseException:
395{
396 Statement stmt = null;
397}
398{
399 (
400 stmt = DataverseDeclaration()
401 | stmt = FunctionDeclaration()
402 | stmt = CreateStatement()
403 | stmt = LoadStatement()
404 | stmt = DropStatement()
405 | stmt = WriteStatement()
406 | stmt = SetStatement()
407 | stmt = InsertStatement()
408 | stmt = DeleteStatement()
409 | stmt = UpdateStatement()
Yingyi Bucb5bf332017-01-02 22:19:50 -0800410 | stmt = UpsertStatement()
Yingyi Buab817482016-08-19 21:29:31 -0700411 | stmt = ConnectionStatement()
Yingyi Bu391f09e2015-10-29 13:49:39 -0700412 | stmt = CompactStatement()
Till Westmannef3f0272016-07-27 18:34:01 -0700413 | stmt = ExplainStatement()
Murtadha Hubaildc775222017-08-21 15:22:45 +0300414 | stmt = Query(false)
Yingyi Bu391f09e2015-10-29 13:49:39 -0700415 | stmt = RefreshExternalDatasetStatement()
Yingyi Bu391f09e2015-10-29 13:49:39 -0700416 )
417 {
418 return stmt;
419 }
420}
421
422DataverseDecl DataverseDeclaration() throws ParseException:
423{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -0700424 Token startToken = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -0700425 String dvName = null;
426}
427{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -0700428 <USE> { startToken = token; } dvName = Identifier()
Yingyi Bu391f09e2015-10-29 13:49:39 -0700429 {
430 defaultDataverse = dvName;
Dmitry Lychaginee54cc02018-05-25 19:26:18 -0700431 DataverseDecl dvDecl = new DataverseDecl(new Identifier(dvName));
Dmitry Lychagin5c26b422018-06-01 10:22:16 -0700432 return addSourceLocation(dvDecl, startToken);
Yingyi Bu391f09e2015-10-29 13:49:39 -0700433 }
434}
435
436Statement CreateStatement() throws ParseException:
437{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -0700438 Token startToken = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -0700439 String hint = null;
Dmitry Lychaginee54cc02018-05-25 19:26:18 -0700440 Token hintToken = null;
441 boolean hintDGen = false;
Yingyi Bu391f09e2015-10-29 13:49:39 -0700442 Statement stmt = null;
443}
444{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -0700445 <CREATE> { startToken = token; }
Yingyi Bu391f09e2015-10-29 13:49:39 -0700446 (
447 {
448 hint = getHint(token);
Dmitry Lychaginee54cc02018-05-25 19:26:18 -0700449 if (hint != null) {
450 hintToken = getHintToken(token);
451 hintDGen = hint.startsWith(DGEN_HINT);
Yingyi Bu391f09e2015-10-29 13:49:39 -0700452 }
453 }
Dmitry Lychaginee54cc02018-05-25 19:26:18 -0700454 stmt = TypeSpecification(startToken, hint, hintDGen, hintToken)
455 | stmt = NodegroupSpecification(startToken)
456 | stmt = DatasetSpecification(startToken)
457 | stmt = IndexSpecification(startToken)
458 | stmt = DataverseSpecification(startToken)
459 | stmt = FunctionSpecification(startToken)
460 | stmt = FeedSpecification(startToken)
461 | stmt = FeedPolicySpecification(startToken)
Yingyi Bu391f09e2015-10-29 13:49:39 -0700462 )
463 {
464 return stmt;
465 }
466}
467
Dmitry Lychaginee54cc02018-05-25 19:26:18 -0700468TypeDecl TypeSpecification(Token startStmtToken, String hint, boolean dgen, Token hintToken) throws ParseException:
Yingyi Bu391f09e2015-10-29 13:49:39 -0700469{
470 Pair<Identifier,Identifier> nameComponents = null;
471 boolean ifNotExists = false;
472 TypeExpression typeExpr = null;
473}
474{
475 <TYPE> nameComponents = TypeName() ifNotExists = IfNotExists()
Till Westmannf6028272016-09-30 14:34:42 -0700476 <AS> typeExpr = RecordTypeDef()
Yingyi Bu391f09e2015-10-29 13:49:39 -0700477 {
478 long numValues = -1;
479 String filename = null;
480 if (dgen) {
481 String splits[] = hint.split(" +");
482 if (splits.length != 3) {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -0700483 throw new SqlppParseException(getSourceLocation(hintToken), "Expecting /*+ dgen <filename> <numberOfItems> */");
Yingyi Bu391f09e2015-10-29 13:49:39 -0700484 }
485 filename = splits[1];
486 numValues = Long.parseLong(splits[2]);
487 }
488 TypeDataGen tddg = new TypeDataGen(dgen, filename, numValues);
Dmitry Lychaginee54cc02018-05-25 19:26:18 -0700489 TypeDecl stmt = new TypeDecl(nameComponents.first, nameComponents.second, typeExpr, tddg, ifNotExists);
Dmitry Lychagin5c26b422018-06-01 10:22:16 -0700490 return addSourceLocation(stmt, startStmtToken);
Yingyi Bu391f09e2015-10-29 13:49:39 -0700491 }
492}
493
Dmitry Lychaginee54cc02018-05-25 19:26:18 -0700494NodegroupDecl NodegroupSpecification(Token startStmtToken) throws ParseException:
Yingyi Bu391f09e2015-10-29 13:49:39 -0700495{
496 String name = null;
497 String tmp = null;
498 boolean ifNotExists = false;
499 List<Identifier>ncNames = null;
500}
501{
502 <NODEGROUP> name = Identifier()
503 ifNotExists = IfNotExists() <ON> tmp = Identifier()
504 {
505 ncNames = new ArrayList<Identifier>();
506 ncNames.add(new Identifier(tmp));
507 }
508 ( <COMMA> tmp = Identifier()
509 {
510 ncNames.add(new Identifier(tmp));
511 }
512 )*
513 {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -0700514 NodegroupDecl stmt = new NodegroupDecl(new Identifier(name), ncNames, ifNotExists);
Dmitry Lychagin5c26b422018-06-01 10:22:16 -0700515 return addSourceLocation(stmt, startStmtToken);
Yingyi Bu391f09e2015-10-29 13:49:39 -0700516 }
517}
518
Dmitry Lychaginee54cc02018-05-25 19:26:18 -0700519DatasetDecl DatasetSpecification(Token startStmtToken) throws ParseException:
Yingyi Bu391f09e2015-10-29 13:49:39 -0700520{
521 Pair<Identifier,Identifier> nameComponents = null;
522 boolean ifNotExists = false;
Your Namedace5f22016-01-12 14:02:48 -0800523 Pair<Identifier,Identifier> typeComponents = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -0700524 String adapterName = null;
525 Map<String,String> properties = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -0700526 FunctionSignature appliedFunction = null;
Yingyi Buc9bfe252016-03-01 00:02:40 -0800527 Pair<List<Integer>, List<List<String>>> primaryKeyFields = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -0700528 String nodeGroupName = null;
529 Map<String,String> hints = new HashMap<String,String>();
Dmitry Lychaginee54cc02018-05-25 19:26:18 -0700530 DatasetDecl stmt = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -0700531 boolean autogenerated = false;
Yingyi Buc9bfe252016-03-01 00:02:40 -0800532 Pair<Integer, List<String>> filterField = null;
Yingyi Bub9169b62016-02-26 21:21:49 -0800533 Pair<Identifier,Identifier> metaTypeComponents = new Pair<Identifier, Identifier>(null, null);
Till Westmannf3aa19f2017-12-01 17:42:35 -0800534 RecordConstructor withRecord = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -0700535}
536{
537 (
Yingyi Bu1c0fff52016-03-25 20:23:30 -0700538 <EXTERNAL> Dataset() nameComponents = QualifiedName()
Your Namedace5f22016-01-12 14:02:48 -0800539 <LEFTPAREN> typeComponents = TypeName() <RIGHTPAREN>
Yingyi Bu391f09e2015-10-29 13:49:39 -0700540 ifNotExists = IfNotExists()
541 <USING> adapterName = AdapterName() properties = Configuration()
Till Westmannf3aa19f2017-12-01 17:42:35 -0800542 ( <ON> nodeGroupName = Identifier() )?
Yingyi Bu391f09e2015-10-29 13:49:39 -0700543 ( <HINTS> hints = Properties() )?
Till Westmannf3aa19f2017-12-01 17:42:35 -0800544 ( <WITH> withRecord = RecordConstructor() )?
Yingyi Bu391f09e2015-10-29 13:49:39 -0700545 {
546 ExternalDetailsDecl edd = new ExternalDetailsDecl();
547 edd.setAdapter(adapterName);
548 edd.setProperties(properties);
Till Westmannf3aa19f2017-12-01 17:42:35 -0800549 try{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -0700550 stmt = new DatasetDecl(nameComponents.first,
Yingyi Bu391f09e2015-10-29 13:49:39 -0700551 nameComponents.second,
Your Namedace5f22016-01-12 14:02:48 -0800552 typeComponents.first,
553 typeComponents.second,
Yingyi Bub9169b62016-02-26 21:21:49 -0800554 metaTypeComponents.first,
555 metaTypeComponents.second,
Yingyi Bu391f09e2015-10-29 13:49:39 -0700556 nodeGroupName != null? new Identifier(nodeGroupName): null,
Yingyi Bu391f09e2015-10-29 13:49:39 -0700557 hints,
558 DatasetType.EXTERNAL,
559 edd,
Till Westmannf3aa19f2017-12-01 17:42:35 -0800560 withRecord,
Yingyi Bu391f09e2015-10-29 13:49:39 -0700561 ifNotExists);
Till Westmannf3aa19f2017-12-01 17:42:35 -0800562 } catch (CompilationException e){
Dmitry Lychaginee54cc02018-05-25 19:26:18 -0700563 throw new SqlppParseException(getSourceLocation(startStmtToken), e.getMessage());
Till Westmannf3aa19f2017-12-01 17:42:35 -0800564 }
Yingyi Bu391f09e2015-10-29 13:49:39 -0700565 }
566
Murtadha Hubail2c04ae02017-11-21 15:58:01 +0300567 | ( <INTERNAL> )?
Yingyi Bu1c0fff52016-03-25 20:23:30 -0700568 Dataset() nameComponents = QualifiedName()
Your Namedace5f22016-01-12 14:02:48 -0800569 <LEFTPAREN> typeComponents = TypeName() <RIGHTPAREN>
Yingyi Bub9169b62016-02-26 21:21:49 -0800570 (
571 { String name; }
572 <WITH>
573 name = Identifier()
574 {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -0700575 if (!name.equalsIgnoreCase("meta")){
576 throw new SqlppParseException(getSourceLocation(startStmtToken),
577 "We can only support one additional associated field called \"meta\".");
Yingyi Bub9169b62016-02-26 21:21:49 -0800578 }
579 }
580 <LEFTPAREN> metaTypeComponents = TypeName() <RIGHTPAREN>
581 )?
Yingyi Bu391f09e2015-10-29 13:49:39 -0700582 ifNotExists = IfNotExists()
583 primaryKeyFields = PrimaryKey()
584 (<AUTOGENERATED> { autogenerated = true; } )?
585 (<ON> nodeGroupName = Identifier() )?
586 ( <HINTS> hints = Properties() )?
Yingyi Bu391f09e2015-10-29 13:49:39 -0700587 ( LOOKAHEAD(2) <WITH> <FILTER> <ON> filterField = NestedField() )?
Till Westmannf3aa19f2017-12-01 17:42:35 -0800588 ( <WITH> withRecord = RecordConstructor() )?
Yingyi Bu391f09e2015-10-29 13:49:39 -0700589 {
Yingyi Buc9bfe252016-03-01 00:02:40 -0800590 if(filterField!=null && filterField.first!=0){
Dmitry Lychaginee54cc02018-05-25 19:26:18 -0700591 throw new SqlppParseException(getSourceLocation(startStmtToken),
592 "A filter field can only be a field in the main record of the dataset.");
Yingyi Buc9bfe252016-03-01 00:02:40 -0800593 }
594 InternalDetailsDecl idd = new InternalDetailsDecl(primaryKeyFields.second,
595 primaryKeyFields.first,
Yingyi Bu391f09e2015-10-29 13:49:39 -0700596 autogenerated,
Murtadha Hubail2c04ae02017-11-21 15:58:01 +0300597 filterField == null? null : filterField.second);
Till Westmannf3aa19f2017-12-01 17:42:35 -0800598 try{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -0700599 stmt = new DatasetDecl(nameComponents.first,
Yingyi Bu391f09e2015-10-29 13:49:39 -0700600 nameComponents.second,
Your Namedace5f22016-01-12 14:02:48 -0800601 typeComponents.first,
602 typeComponents.second,
Yingyi Bub9169b62016-02-26 21:21:49 -0800603 metaTypeComponents.first,
604 metaTypeComponents.second,
Yingyi Bu391f09e2015-10-29 13:49:39 -0700605 nodeGroupName != null ? new Identifier(nodeGroupName) : null,
Yingyi Bu391f09e2015-10-29 13:49:39 -0700606 hints,
607 DatasetType.INTERNAL,
608 idd,
Till Westmannf3aa19f2017-12-01 17:42:35 -0800609 withRecord,
Yingyi Bu391f09e2015-10-29 13:49:39 -0700610 ifNotExists);
Till Westmannf3aa19f2017-12-01 17:42:35 -0800611 } catch (CompilationException e){
Dmitry Lychaginee54cc02018-05-25 19:26:18 -0700612 throw new SqlppParseException(getSourceLocation(startStmtToken), e.getMessage());
Till Westmannf3aa19f2017-12-01 17:42:35 -0800613 }
Yingyi Bu391f09e2015-10-29 13:49:39 -0700614 }
615 )
616 {
Dmitry Lychagin5c26b422018-06-01 10:22:16 -0700617 return addSourceLocation(stmt, startStmtToken);
Yingyi Bu391f09e2015-10-29 13:49:39 -0700618 }
619}
620
621RefreshExternalDatasetStatement RefreshExternalDatasetStatement() throws ParseException:
622{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -0700623 Token startToken = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -0700624 Pair<Identifier,Identifier> nameComponents = null;
625 String datasetName = null;
626}
627{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -0700628 <REFRESH> { startToken = token; } <EXTERNAL> Dataset() nameComponents = QualifiedName()
Yingyi Bu391f09e2015-10-29 13:49:39 -0700629 {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -0700630 RefreshExternalDatasetStatement stmt = new RefreshExternalDatasetStatement();
631 stmt.setDataverseName(nameComponents.first);
632 stmt.setDatasetName(nameComponents.second);
Dmitry Lychagin5c26b422018-06-01 10:22:16 -0700633 return addSourceLocation(stmt, startToken);
Yingyi Bu391f09e2015-10-29 13:49:39 -0700634 }
635}
636
Dmitry Lychaginee54cc02018-05-25 19:26:18 -0700637CreateIndexStatement IndexSpecification(Token startStmtToken) throws ParseException:
Yingyi Bu391f09e2015-10-29 13:49:39 -0700638{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -0700639 CreateIndexStatement stmt = new CreateIndexStatement();
Yingyi Bu391f09e2015-10-29 13:49:39 -0700640 String indexName = null;
641 boolean ifNotExists = false;
642 Pair<Identifier,Identifier> nameComponents = null;
Dmitry Lychagin8ba59442017-06-16 14:19:45 -0700643 Pair<Integer, Pair<List<String>, IndexedTypeExpression>> fieldPair = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -0700644 IndexParams indexType = null;
645 boolean enforced = false;
Ali Alsuliman8351d252017-09-24 00:43:15 -0700646 boolean isPrimaryIdx = false;
Yingyi Bu391f09e2015-10-29 13:49:39 -0700647}
648{
Ali Alsuliman8351d252017-09-24 00:43:15 -0700649 (
650 (<INDEX> indexName = Identifier()
651 ifNotExists = IfNotExists()
652 <ON> nameComponents = QualifiedName()
653 <LEFTPAREN> ( fieldPair = OpenField()
654 {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -0700655 stmt.addFieldExprPair(fieldPair.second);
656 stmt.addFieldIndexIndicator(fieldPair.first);
Yingyi Bu391f09e2015-10-29 13:49:39 -0700657 }
Ali Alsuliman8351d252017-09-24 00:43:15 -0700658 ) (<COMMA> fieldPair = OpenField()
659 {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -0700660 stmt.addFieldExprPair(fieldPair.second);
661 stmt.addFieldIndexIndicator(fieldPair.first);
Ali Alsuliman8351d252017-09-24 00:43:15 -0700662 }
663 )* <RIGHTPAREN> ( <TYPE> indexType = IndexType() )? ( <ENFORCED> { enforced = true; } )?)
664 |
665 (<PRIMARY> <INDEX> {isPrimaryIdx = true;}
666 (
667 (indexName = Identifier())? ifNotExists = IfNotExists()
668 )
669 <ON> nameComponents = QualifiedName() (<TYPE> <BTREE>)?
670 )
671 )
672 {
673 if (isPrimaryIdx && indexName == null) {
674 indexName = "primary_idx_" + nameComponents.second;
Yingyi Bu391f09e2015-10-29 13:49:39 -0700675 }
Dmitry Lychaginee54cc02018-05-25 19:26:18 -0700676 stmt.setIndexName(new Identifier(indexName));
677 stmt.setIfNotExists(ifNotExists);
678 stmt.setDataverseName(nameComponents.first);
679 stmt.setDatasetName(nameComponents.second);
Ali Alsuliman8351d252017-09-24 00:43:15 -0700680 if (indexType != null) {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -0700681 stmt.setIndexType(indexType.type);
682 stmt.setGramLength(indexType.gramLength);
Ali Alsuliman8351d252017-09-24 00:43:15 -0700683 }
Dmitry Lychaginee54cc02018-05-25 19:26:18 -0700684 stmt.setEnforced(enforced);
Dmitry Lychagin5c26b422018-06-01 10:22:16 -0700685 return addSourceLocation(stmt, startStmtToken);
Ali Alsuliman8351d252017-09-24 00:43:15 -0700686 }
Yingyi Bu391f09e2015-10-29 13:49:39 -0700687}
688
689String CompactionPolicy() throws ParseException :
690{
691 String compactionPolicy = null;
692}
693{
694 compactionPolicy = Identifier()
695 {
696 return compactionPolicy;
697 }
698}
699
700String FilterField() throws ParseException :
701{
702 String filterField = null;
703}
704{
705 filterField = Identifier()
706 {
707 return filterField;
708 }
709}
710
711IndexParams IndexType() throws ParseException:
712{
713 IndexType type = null;
714 int gramLength = 0;
715}
716{
717 (<BTREE>
718 {
719 type = IndexType.BTREE;
720 }
721 | <RTREE>
722 {
723 type = IndexType.RTREE;
724 }
725 | <KEYWORD>
726 {
727 type = IndexType.LENGTH_PARTITIONED_WORD_INVIX;
728 }
Taewoo Kimc49405a2017-01-04 00:30:43 -0800729 |<FULLTEXT>
730 {
731 type = IndexType.SINGLE_PARTITION_WORD_INVIX;
732 }
Yingyi Bu391f09e2015-10-29 13:49:39 -0700733 | <NGRAM> <LEFTPAREN> <INTEGER_LITERAL>
734 {
735 type = IndexType.LENGTH_PARTITIONED_NGRAM_INVIX;
736 gramLength = Integer.valueOf(token.image);
737 }
738 <RIGHTPAREN>)
739 {
740 return new IndexParams(type, gramLength);
741 }
742}
743
Dmitry Lychaginee54cc02018-05-25 19:26:18 -0700744CreateDataverseStatement DataverseSpecification(Token startStmtToken) throws ParseException :
Yingyi Bu391f09e2015-10-29 13:49:39 -0700745{
746 String dvName = null;
747 boolean ifNotExists = false;
Yingyi Bu391f09e2015-10-29 13:49:39 -0700748}
749{
750 <DATAVERSE> dvName = Identifier()
751 ifNotExists = IfNotExists()
Yingyi Bu391f09e2015-10-29 13:49:39 -0700752 {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -0700753 CreateDataverseStatement stmt = new CreateDataverseStatement(new Identifier(dvName), null, ifNotExists);
Dmitry Lychagin5c26b422018-06-01 10:22:16 -0700754 return addSourceLocation(stmt, startStmtToken);
Yingyi Bu391f09e2015-10-29 13:49:39 -0700755 }
756}
757
Dmitry Lychaginee54cc02018-05-25 19:26:18 -0700758CreateFunctionStatement FunctionSpecification(Token startStmtToken) throws ParseException:
Yingyi Bu391f09e2015-10-29 13:49:39 -0700759{
760 FunctionSignature signature;
761 boolean ifNotExists = false;
762 List<VarIdentifier> paramList = new ArrayList<VarIdentifier>();
763 String functionBody;
764 VarIdentifier var = null;
765 Expression functionBodyExpr;
766 Token beginPos;
767 Token endPos;
768 FunctionName fctName = null;
Steven Glenn Jacobs665e9fe2017-12-27 10:30:39 -0800769 String currentDataverse = defaultDataverse;
Yingyi Bu391f09e2015-10-29 13:49:39 -0700770
771 createNewScope();
772}
773{
774 <FUNCTION> fctName = FunctionName()
Steven Glenn Jacobs665e9fe2017-12-27 10:30:39 -0800775 {
776 defaultDataverse = fctName.dataverse;
777 }
Yingyi Bu391f09e2015-10-29 13:49:39 -0700778 ifNotExists = IfNotExists()
779 paramList = ParameterList()
780 <LEFTBRACE>
781 {
782 beginPos = token;
783 }
Xikui Wang3de700a2018-03-15 16:32:55 -0700784 (functionBodyExpr = SelectExpression(true) | functionBodyExpr = Expression())
785 <RIGHTBRACE>
Yingyi Bu391f09e2015-10-29 13:49:39 -0700786 {
787 endPos = token;
788 functionBody = extractFragment(beginPos.beginLine, beginPos.beginColumn, endPos.beginLine, endPos.beginColumn);
789 // TODO use fctName.library
790 signature = new FunctionSignature(fctName.dataverse, fctName.function, paramList.size());
791 getCurrentScope().addFunctionDescriptor(signature, false);
792 removeCurrentScope();
Steven Glenn Jacobs665e9fe2017-12-27 10:30:39 -0800793 defaultDataverse = currentDataverse;
Dmitry Lychaginee54cc02018-05-25 19:26:18 -0700794 CreateFunctionStatement stmt = new CreateFunctionStatement(signature, paramList, functionBody, functionBodyExpr, ifNotExists);
Dmitry Lychagin5c26b422018-06-01 10:22:16 -0700795 return addSourceLocation(stmt, startStmtToken);
Yingyi Bu391f09e2015-10-29 13:49:39 -0700796 }
797}
798
Dmitry Lychaginee54cc02018-05-25 19:26:18 -0700799CreateFeedStatement FeedSpecification(Token startStmtToken) throws ParseException:
Yingyi Bu391f09e2015-10-29 13:49:39 -0700800{
801 Pair<Identifier,Identifier> nameComponents = null;
802 boolean ifNotExists = false;
803 String adapterName = null;
804 Map<String,String> properties = null;
Dmitry Lychaginee54cc02018-05-25 19:26:18 -0700805 CreateFeedStatement stmt = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -0700806 Pair<Identifier,Identifier> sourceNameComponents = null;
Xikui Wang5a61b2a2018-01-02 14:14:03 -0800807 RecordConstructor withRecord = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -0700808}
809{
Abdullah Alamoudifff200c2017-02-18 20:32:14 -0800810 <FEED> nameComponents = QualifiedName() ifNotExists = IfNotExists()
Xikui Wang5a61b2a2018-01-02 14:14:03 -0800811 <WITH> withRecord = RecordConstructor()
Abdullah Alamoudifff200c2017-02-18 20:32:14 -0800812 {
Xikui Wang5a61b2a2018-01-02 14:14:03 -0800813 try {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -0700814 stmt = new CreateFeedStatement(nameComponents, withRecord, ifNotExists);
Dmitry Lychagin5c26b422018-06-01 10:22:16 -0700815 return addSourceLocation(stmt, startStmtToken);
Xikui Wang5a61b2a2018-01-02 14:14:03 -0800816 } catch (AlgebricksException e) {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -0700817 throw new SqlppParseException(getSourceLocation(startStmtToken), e.getMessage());
Xikui Wang5a61b2a2018-01-02 14:14:03 -0800818 }
Abdullah Alamoudifff200c2017-02-18 20:32:14 -0800819 }
Yingyi Bu391f09e2015-10-29 13:49:39 -0700820}
821
Dmitry Lychaginee54cc02018-05-25 19:26:18 -0700822CreateFeedPolicyStatement FeedPolicySpecification(Token startStmtToken) throws ParseException:
Yingyi Bu391f09e2015-10-29 13:49:39 -0700823{
Michael Blowd6cf6412016-06-30 02:44:35 -0400824 String policyName = null;
825 String basePolicyName = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -0700826 String sourcePolicyFile = null;
827 String definition = null;
828 boolean ifNotExists = false;
829 Map<String,String> properties = null;
Dmitry Lychaginee54cc02018-05-25 19:26:18 -0700830 CreateFeedPolicyStatement stmt = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -0700831}
832{
833 (
834 <INGESTION> <POLICY> policyName = Identifier() ifNotExists = IfNotExists()
Yingyi Bu6d57e492016-06-06 21:24:42 -0700835 <FROM>
836 (<POLICY> basePolicyName = Identifier() properties = Configuration() (<DEFINITION> definition = ConstantString())?
Yingyi Bu391f09e2015-10-29 13:49:39 -0700837 {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -0700838 stmt = new CreateFeedPolicyStatement(policyName,
Yingyi Bu391f09e2015-10-29 13:49:39 -0700839 basePolicyName, properties, definition, ifNotExists);
840 }
Abdullah Alamoudi5dc73ed2016-07-28 05:03:13 +0300841 | <PATH> sourcePolicyFile = ConstantString() (<DEFINITION> definition = ConstantString())?
Yingyi Bu391f09e2015-10-29 13:49:39 -0700842 {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -0700843 stmt = new CreateFeedPolicyStatement(policyName, sourcePolicyFile, definition, ifNotExists);
Yingyi Bu391f09e2015-10-29 13:49:39 -0700844 }
Yingyi Bu6d57e492016-06-06 21:24:42 -0700845 )
Yingyi Bu391f09e2015-10-29 13:49:39 -0700846 )
847 {
Dmitry Lychagin5c26b422018-06-01 10:22:16 -0700848 return addSourceLocation(stmt, startStmtToken);
Yingyi Bu391f09e2015-10-29 13:49:39 -0700849 }
850}
851
Yingyi Bu391f09e2015-10-29 13:49:39 -0700852List<VarIdentifier> ParameterList() throws ParseException:
853{
854 List<VarIdentifier> paramList = new ArrayList<VarIdentifier>();
855 VarIdentifier var = null;
856}
857{
858 <LEFTPAREN> (<IDENTIFIER>
859 {
Yingyi Buacc12a92016-03-26 17:25:05 -0700860 var = SqlppVariableUtil.toInternalVariableIdentifier(token.image);
Yingyi Bu391f09e2015-10-29 13:49:39 -0700861 paramList.add(var);
Yingyi Bu391f09e2015-10-29 13:49:39 -0700862 }
863 (<COMMA> <IDENTIFIER>
864 {
Yingyi Buacc12a92016-03-26 17:25:05 -0700865 var = SqlppVariableUtil.toInternalVariableIdentifier(token.image);
Yingyi Bu391f09e2015-10-29 13:49:39 -0700866 paramList.add(var);
Yingyi Bu391f09e2015-10-29 13:49:39 -0700867 }
868 )*)? <RIGHTPAREN>
869 {
870 return paramList;
871 }
872}
873
874boolean IfNotExists() throws ParseException:
875{
876}
877{
Yingyi Budaa549c2016-06-28 22:30:52 -0700878 ( LOOKAHEAD(1) <IF> <NOT> <EXISTS>
Yingyi Bu391f09e2015-10-29 13:49:39 -0700879 {
880 return true;
881 }
882 )?
883 {
884 return false;
885 }
886}
887
Xikui Wang9d63f622017-05-18 17:50:44 -0700888void ApplyFunction(List<FunctionSignature> funcSigs) throws ParseException:
Yingyi Bu391f09e2015-10-29 13:49:39 -0700889{
890 FunctionName functioName = null;
Xikui Wang261dc6d2017-03-29 21:23:15 -0700891 String fqFunctionName = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -0700892}
893{
894 <APPLY> <FUNCTION> functioName = FunctionName()
895 {
Xikui Wang261dc6d2017-03-29 21:23:15 -0700896 fqFunctionName = functioName.library == null ? functioName.function : functioName.library + "#" + functioName.function;
897 funcSigs.add(new FunctionSignature(functioName.dataverse, fqFunctionName, 1));
898 }
899 (
900 <COMMA> functioName = FunctionName()
901 {
902 fqFunctionName = functioName.library == null ? functioName.function : functioName.library + "#" + functioName.function;
903 funcSigs.add(new FunctionSignature(functioName.dataverse, fqFunctionName, 1));
904 }
905 )*
Yingyi Bu391f09e2015-10-29 13:49:39 -0700906}
907
908String GetPolicy() throws ParseException:
909{
910 String policy = null;
911}
912{
913 <USING> <POLICY> policy = Identifier()
914 {
915 return policy;
916 }
917
918}
919
920FunctionSignature FunctionSignature() throws ParseException:
921{
922 FunctionName fctName = null;
923 int arity = 0;
924}
925{
926 fctName = FunctionName() <ATT> <INTEGER_LITERAL>
927 {
928 arity = new Integer(token.image);
929 if (arity < 0 && arity != FunctionIdentifier.VARARGS) {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -0700930 throw new SqlppParseException(getSourceLocation(token), "Invalid arity:" + arity);
Yingyi Bu391f09e2015-10-29 13:49:39 -0700931 }
932
933 // TODO use fctName.library
934 String fqFunctionName = fctName.library == null ? fctName.function : fctName.library + "#" + fctName.function;
935 return new FunctionSignature(fctName.dataverse, fqFunctionName, arity);
936 }
937}
938
Yingyi Buc9bfe252016-03-01 00:02:40 -0800939Pair<List<Integer>, List<List<String>>> PrimaryKey() throws ParseException:
Yingyi Bu391f09e2015-10-29 13:49:39 -0700940{
Yingyi Buc9bfe252016-03-01 00:02:40 -0800941 Pair<Integer, List<String>> tmp = null;
942 List<Integer> keyFieldSourceIndicators = new ArrayList<Integer>();
Yingyi Bu391f09e2015-10-29 13:49:39 -0700943 List<List<String>> primaryKeyFields = new ArrayList<List<String>>();
944}
945{
946 <PRIMARY> <KEY> tmp = NestedField()
947 {
Yingyi Buc9bfe252016-03-01 00:02:40 -0800948 keyFieldSourceIndicators.add(tmp.first);
949 primaryKeyFields.add(tmp.second);
Yingyi Bu391f09e2015-10-29 13:49:39 -0700950 }
951 ( <COMMA> tmp = NestedField()
952 {
Yingyi Buc9bfe252016-03-01 00:02:40 -0800953 keyFieldSourceIndicators.add(tmp.first);
954 primaryKeyFields.add(tmp.second);
Yingyi Bu391f09e2015-10-29 13:49:39 -0700955 }
956 )*
957 {
Yingyi Buc9bfe252016-03-01 00:02:40 -0800958 return new Pair<List<Integer>, List<List<String>>> (keyFieldSourceIndicators, primaryKeyFields);
Yingyi Bu391f09e2015-10-29 13:49:39 -0700959 }
960}
961
962Statement DropStatement() throws ParseException:
963{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -0700964 Token startToken = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -0700965 String id = null;
966 Pair<Identifier,Identifier> pairId = null;
967 Triple<Identifier,Identifier,Identifier> tripleId = null;
968 FunctionSignature funcSig = null;
969 boolean ifExists = false;
Dmitry Lychaginee54cc02018-05-25 19:26:18 -0700970 AbstractStatement stmt = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -0700971}
972{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -0700973 <DROP> { startToken = token; }
Yingyi Bu391f09e2015-10-29 13:49:39 -0700974 (
Yingyi Bu1c0fff52016-03-25 20:23:30 -0700975 Dataset() pairId = QualifiedName() ifExists = IfExists()
Yingyi Bu391f09e2015-10-29 13:49:39 -0700976 {
Yingyi Buab817482016-08-19 21:29:31 -0700977 stmt = new DropDatasetStatement(pairId.first, pairId.second, ifExists);
Yingyi Bu391f09e2015-10-29 13:49:39 -0700978 }
979 | <INDEX> tripleId = DoubleQualifiedName() ifExists = IfExists()
980 {
981 stmt = new IndexDropStatement(tripleId.first, tripleId.second, tripleId.third, ifExists);
982 }
983 | <NODEGROUP> id = Identifier() ifExists = IfExists()
984 {
985 stmt = new NodeGroupDropStatement(new Identifier(id), ifExists);
986 }
987 | <TYPE> pairId = TypeName() ifExists = IfExists()
988 {
989 stmt = new TypeDropStatement(pairId.first, pairId.second, ifExists);
990 }
991 | <DATAVERSE> id = Identifier() ifExists = IfExists()
992 {
993 stmt = new DataverseDropStatement(new Identifier(id), ifExists);
994 }
995 | <FUNCTION> funcSig = FunctionSignature() ifExists = IfExists()
996 {
997 stmt = new FunctionDropStatement(funcSig, ifExists);
998 }
999 | <FEED> pairId = QualifiedName() ifExists = IfExists()
1000 {
1001 stmt = new FeedDropStatement(pairId.first, pairId.second, ifExists);
1002 }
Abdullah Alamoudi5dc73ed2016-07-28 05:03:13 +03001003 | <INGESTION> <POLICY> pairId = QualifiedName() ifExists = IfExists()
1004 {
1005 stmt = new FeedPolicyDropStatement(pairId.first, pairId.second, ifExists);
1006 }
Yingyi Bu391f09e2015-10-29 13:49:39 -07001007 )
1008 {
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07001009 return addSourceLocation(stmt, startToken);
Yingyi Bu391f09e2015-10-29 13:49:39 -07001010 }
1011}
1012
1013boolean IfExists() throws ParseException :
1014{
1015}
1016{
1017 ( LOOKAHEAD(1) <IF> <EXISTS>
1018 {
1019 return true;
1020 }
1021 )?
1022 {
1023 return false;
1024 }
1025}
1026
1027InsertStatement InsertStatement() throws ParseException:
1028{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07001029 Token startToken = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07001030 Pair<Identifier,Identifier> nameComponents = null;
Yingyi Bucb5bf332017-01-02 22:19:50 -08001031 VariableExpr var = null;
1032 Query query = null;
1033 Expression returnExpression = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07001034}
1035{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07001036 <INSERT> { startToken = token; } <INTO> nameComponents = QualifiedName() (<AS> var = Variable())?
Yingyi Bucb5bf332017-01-02 22:19:50 -08001037 query = Query(false)
1038 ( <RETURNING> returnExpression = Expression())?
Yingyi Bu391f09e2015-10-29 13:49:39 -07001039 {
Yingyi Bucb5bf332017-01-02 22:19:50 -08001040 if (returnExpression != null && var == null) {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07001041 var = ExpressionToVariableUtil.getGeneratedVariable(query.getBody(), true);
Yingyi Bucb5bf332017-01-02 22:19:50 -08001042 }
Yingyi Bucaea8f02015-11-16 15:12:15 -08001043 query.setTopLevel(true);
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07001044 InsertStatement stmt = new InsertStatement(nameComponents.first, nameComponents.second, query, getVarCounter(),
1045 var, returnExpression);
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07001046 return addSourceLocation(stmt, startToken);
Yingyi Bucb5bf332017-01-02 22:19:50 -08001047 }
1048}
1049
1050UpsertStatement UpsertStatement() throws ParseException:
1051{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07001052 Token startToken = null;
Yingyi Bucb5bf332017-01-02 22:19:50 -08001053 Pair<Identifier,Identifier> nameComponents = null;
1054 VariableExpr var = null;
1055 Query query = null;
1056 Expression returnExpression = null;
1057}
1058{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07001059 <UPSERT> { startToken = token; } <INTO> nameComponents = QualifiedName() (<AS> var = Variable())?
Yingyi Bucb5bf332017-01-02 22:19:50 -08001060 query = Query(false)
1061 ( <RETURNING> returnExpression = Expression())?
1062 {
1063 if (returnExpression != null && var == null) {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07001064 var = ExpressionToVariableUtil.getGeneratedVariable(query.getBody(), true);
Yingyi Bucb5bf332017-01-02 22:19:50 -08001065 }
1066 query.setTopLevel(true);
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07001067 UpsertStatement stmt = new UpsertStatement(nameComponents.first, nameComponents.second, query, getVarCounter(),
1068 var, returnExpression);
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07001069 return addSourceLocation(stmt, startToken);
Yingyi Bu391f09e2015-10-29 13:49:39 -07001070 }
1071}
1072
1073DeleteStatement DeleteStatement() throws ParseException:
1074{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07001075 Token startToken = null;
Yingyi Bu20e085b2016-07-06 12:57:27 -07001076 VariableExpr varExpr = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07001077 Expression condition = null;
1078 Pair<Identifier, Identifier> nameComponents;
Yingyi Bu391f09e2015-10-29 13:49:39 -07001079}
1080{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07001081 <DELETE> { startToken = token; }
Yingyi Bu391f09e2015-10-29 13:49:39 -07001082 <FROM> nameComponents = QualifiedName()
Yingyi Bu20e085b2016-07-06 12:57:27 -07001083 ((<AS>)? varExpr = Variable())?
Yingyi Bu391f09e2015-10-29 13:49:39 -07001084 (<WHERE> condition = Expression())?
Yingyi Bu20e085b2016-07-06 12:57:27 -07001085 {
Yingyi Bu20e085b2016-07-06 12:57:27 -07001086 if(varExpr == null){
1087 varExpr = new VariableExpr();
1088 VarIdentifier var = SqlppVariableUtil.toInternalVariableIdentifier(nameComponents.second.getValue());
1089 varExpr.setVar(var);
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07001090 addSourceLocation(varExpr, startToken);
Yingyi Bu20e085b2016-07-06 12:57:27 -07001091 }
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07001092 DeleteStatement stmt = new DeleteStatement(varExpr, nameComponents.first, nameComponents.second,
Abdullah Alamoudi6eb01752017-04-01 21:51:19 -07001093 condition, getVarCounter());
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07001094 return addSourceLocation(stmt, startToken);
Yingyi Bu20e085b2016-07-06 12:57:27 -07001095 }
Yingyi Bu391f09e2015-10-29 13:49:39 -07001096}
1097
1098UpdateStatement UpdateStatement() throws ParseException:
1099{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07001100 Token startToken = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07001101 VariableExpr vars;
1102 Expression target;
1103 Expression condition;
1104 UpdateClause uc;
1105 List<UpdateClause> ucs = new ArrayList<UpdateClause>();
1106}
1107{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07001108 <UPDATE> { startToken = token; } vars = Variable() <IN> target = Expression()
Yingyi Bu391f09e2015-10-29 13:49:39 -07001109 <WHERE> condition = Expression()
1110 <LEFTPAREN> (uc = UpdateClause()
1111 {
1112 ucs.add(uc);
1113 }
1114 (<COMMA> uc = UpdateClause()
1115 {
1116 ucs.add(uc);
1117 }
1118 )*) <RIGHTPAREN>
1119 {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07001120 UpdateStatement stmt = new UpdateStatement(vars, target, condition, ucs);
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07001121 return addSourceLocation(stmt, startToken);
Yingyi Bu391f09e2015-10-29 13:49:39 -07001122 }
1123}
1124
1125UpdateClause UpdateClause() throws ParseException:
1126{
1127 Expression target = null;
1128 Expression value = null ;
1129 InsertStatement is = null;
1130 DeleteStatement ds = null;
1131 UpdateStatement us = null;
1132 Expression condition = null;
1133 UpdateClause ifbranch = null;
1134 UpdateClause elsebranch = null;
1135}
1136{
1137 (<SET> target = Expression() <EQ> value = Expression()
1138 | is = InsertStatement()
1139 | ds = DeleteStatement()
1140 | us = UpdateStatement()
1141 | <IF> <LEFTPAREN> condition = Expression() <RIGHTPAREN>
1142 <THEN> ifbranch = UpdateClause()
1143 [LOOKAHEAD(1) <ELSE> elsebranch = UpdateClause()]
1144 {
1145 return new UpdateClause(target, value, is, ds, us, condition, ifbranch, elsebranch);
1146 }
1147 )
1148}
1149
1150Statement SetStatement() throws ParseException:
1151{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07001152 Token startToken = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07001153 String pn = null;
1154 String pv = null;
1155}
1156{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07001157 <SET> { startToken = token; } pn = Identifier() pv = ConstantString()
Yingyi Bu391f09e2015-10-29 13:49:39 -07001158 {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07001159 SetStatement stmt = new SetStatement(pn, pv);
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07001160 return addSourceLocation(stmt, startToken);
Yingyi Bu391f09e2015-10-29 13:49:39 -07001161 }
1162}
1163
1164Statement WriteStatement() throws ParseException:
1165{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07001166 Token startToken = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07001167 String nodeName = null;
1168 String fileName = null;
1169 Query query;
1170 String writerClass = null;
1171 Pair<Identifier,Identifier> nameComponents = null;
1172}
1173{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07001174 <WRITE> { startToken = token; } <OUTPUT> <TO> nodeName = Identifier() <COLON> fileName = ConstantString()
Yingyi Bu6d57e492016-06-06 21:24:42 -07001175 ( <USING> writerClass = ConstantString() )?
Yingyi Bu391f09e2015-10-29 13:49:39 -07001176 {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07001177 WriteStatement stmt = new WriteStatement(new Identifier(nodeName), fileName, writerClass);
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07001178 return addSourceLocation(stmt, startToken);
Yingyi Bu391f09e2015-10-29 13:49:39 -07001179 }
1180}
1181
1182LoadStatement LoadStatement() throws ParseException:
1183{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07001184 Token startToken = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07001185 Identifier dataverseName = null;
1186 Identifier datasetName = null;
1187 boolean alreadySorted = false;
1188 String adapterName;
1189 Map<String,String> properties;
1190 Pair<Identifier,Identifier> nameComponents = null;
1191}
1192{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07001193 <LOAD> { startToken = token; } Dataset() nameComponents = QualifiedName()
Yingyi Bu391f09e2015-10-29 13:49:39 -07001194 {
1195 dataverseName = nameComponents.first;
1196 datasetName = nameComponents.second;
1197 }
1198 <USING> adapterName = AdapterName() properties = Configuration()
1199 (<PRESORTED>
1200 {
1201 alreadySorted = true;
1202 }
1203 )?
1204 {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07001205 LoadStatement stmt = new LoadStatement(dataverseName, datasetName, adapterName, properties, alreadySorted);
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07001206 return addSourceLocation(stmt, startToken);
Yingyi Bu391f09e2015-10-29 13:49:39 -07001207 }
1208}
1209
1210
1211String AdapterName() throws ParseException :
1212{
1213 String adapterName = null;
1214}
1215{
1216 adapterName = Identifier()
1217 {
1218 return adapterName;
1219 }
1220}
1221
1222Statement CompactStatement() throws ParseException:
1223{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07001224 Token startToken = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07001225 Pair<Identifier,Identifier> nameComponents = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07001226}
1227{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07001228 <COMPACT> { startToken = token; } Dataset() nameComponents = QualifiedName()
Yingyi Bu391f09e2015-10-29 13:49:39 -07001229 {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07001230 CompactStatement stmt = new CompactStatement(nameComponents.first, nameComponents.second);
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07001231 return addSourceLocation(stmt, startToken);
Yingyi Bu391f09e2015-10-29 13:49:39 -07001232 }
1233}
1234
Yingyi Buab817482016-08-19 21:29:31 -07001235Statement ConnectionStatement() throws ParseException:
Yingyi Bu391f09e2015-10-29 13:49:39 -07001236{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07001237 Token startToken = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07001238 Statement stmt = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07001239}
1240{
1241 (
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07001242 <CONNECT> { startToken = token; } stmt = ConnectStatement(startToken)
1243 | <DISCONNECT> { startToken = token; } stmt = DisconnectStatement(startToken)
1244 | <START> { startToken = token; } stmt = StartStatement(startToken)
1245 | <STOP> { startToken = token; } stmt = StopStatement(startToken)
Yingyi Buab817482016-08-19 21:29:31 -07001246 )
1247 {
1248 return stmt;
1249 }
1250}
1251
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07001252Statement StartStatement(Token startStmtToken) throws ParseException:
Abdullah Alamoudifff200c2017-02-18 20:32:14 -08001253{
1254 Pair<Identifier,Identifier> feedNameComponents = null;
1255
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07001256 AbstractStatement stmt = null;
Abdullah Alamoudifff200c2017-02-18 20:32:14 -08001257}
1258{
1259 <FEED> feedNameComponents = QualifiedName()
1260 {
1261 stmt = new StartFeedStatement (feedNameComponents);
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07001262 return addSourceLocation(stmt, startStmtToken);
Abdullah Alamoudifff200c2017-02-18 20:32:14 -08001263 }
1264}
1265
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07001266AbstractStatement StopStatement(Token startStmtToken) throws ParseException:
Abdullah Alamoudifff200c2017-02-18 20:32:14 -08001267{
1268 Pair<Identifier,Identifier> feedNameComponents = null;
1269
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07001270 AbstractStatement stmt = null;
Abdullah Alamoudifff200c2017-02-18 20:32:14 -08001271}
1272{
1273 <FEED> feedNameComponents = QualifiedName()
1274 {
1275 stmt = new StopFeedStatement (feedNameComponents);
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07001276 return addSourceLocation(stmt, startStmtToken);
Abdullah Alamoudifff200c2017-02-18 20:32:14 -08001277 }
1278}
1279
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07001280AbstractStatement DisconnectStatement(Token startStmtToken) throws ParseException:
Yingyi Buab817482016-08-19 21:29:31 -07001281{
1282 Pair<Identifier,Identifier> feedNameComponents = null;
1283 Pair<Identifier,Identifier> datasetNameComponents = null;
1284
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07001285 AbstractStatement stmt = null;
Yingyi Buab817482016-08-19 21:29:31 -07001286}
1287{
1288 (
1289 <FEED> feedNameComponents = QualifiedName() <FROM> Dataset() datasetNameComponents = QualifiedName()
Yingyi Bu391f09e2015-10-29 13:49:39 -07001290 {
1291 stmt = new DisconnectFeedStatement(feedNameComponents, datasetNameComponents);
1292 }
1293 )
Yingyi Buab817482016-08-19 21:29:31 -07001294 {
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07001295 return addSourceLocation(stmt, startStmtToken);
Yingyi Buab817482016-08-19 21:29:31 -07001296 }
1297}
1298
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07001299AbstractStatement ConnectStatement(Token startStmtToken) throws ParseException:
Yingyi Buab817482016-08-19 21:29:31 -07001300{
1301 Pair<Identifier,Identifier> feedNameComponents = null;
1302 Pair<Identifier,Identifier> datasetNameComponents = null;
1303
1304 Map<String,String> configuration = null;
Xikui Wang9d63f622017-05-18 17:50:44 -07001305 List<FunctionSignature> appliedFunctions = new ArrayList<FunctionSignature>();
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07001306 AbstractStatement stmt = null;
Yingyi Buab817482016-08-19 21:29:31 -07001307 String policy = null;
Xikui Wangf6741682018-02-22 19:17:17 -08001308 String whereClauseBody = null;
1309 WhereClause whereClause = null;
1310 Token beginPos = null;
1311 Token endPos = null;
Yingyi Buab817482016-08-19 21:29:31 -07001312}
1313{
1314 (
Abdullah Alamoudifff200c2017-02-18 20:32:14 -08001315 <FEED> feedNameComponents = QualifiedName() <TO> Dataset() datasetNameComponents = QualifiedName()
Xikui Wangf6741682018-02-22 19:17:17 -08001316 (ApplyFunction(appliedFunctions))?
1317 (policy = GetPolicy())?
1318 (
1319 <WHERE>
1320 {
1321 beginPos = token;
1322 whereClause = new WhereClause();
1323 Expression whereExpr;
1324 }
1325 whereExpr = Expression()
1326 {
1327 whereClause.setWhereExpr(whereExpr);
1328 }
1329 )?
1330 {
1331 if (whereClause != null) {
1332 endPos = token;
1333 whereClauseBody = extractFragment(beginPos.endLine, beginPos.endColumn, endPos.endLine, endPos.endColumn + 1);
1334 }
1335 }
Yingyi Buab817482016-08-19 21:29:31 -07001336 {
Xikui Wang261dc6d2017-03-29 21:23:15 -07001337 stmt = new ConnectFeedStatement(feedNameComponents, datasetNameComponents, appliedFunctions,
Xikui Wangf6741682018-02-22 19:17:17 -08001338 policy, whereClauseBody, getVarCounter());
Yingyi Buab817482016-08-19 21:29:31 -07001339 }
1340 )
1341 {
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07001342 return addSourceLocation(stmt, startStmtToken);
Yingyi Buab817482016-08-19 21:29:31 -07001343 }
Yingyi Bu391f09e2015-10-29 13:49:39 -07001344}
1345
1346Map<String,String> Configuration() throws ParseException :
1347{
1348 Map<String,String> configuration = new LinkedHashMap<String,String>();
1349 Pair<String, String> keyValuePair = null;
1350}
1351{
1352 <LEFTPAREN> ( keyValuePair = KeyValuePair()
1353 {
1354 configuration.put(keyValuePair.first, keyValuePair.second);
1355 }
1356 ( <COMMA> keyValuePair = KeyValuePair()
1357 {
1358 configuration.put(keyValuePair.first, keyValuePair.second);
1359 }
1360 )* )? <RIGHTPAREN>
1361 {
1362 return configuration;
1363 }
1364}
1365
1366Pair<String, String> KeyValuePair() throws ParseException:
1367{
1368 String key;
1369 String value;
1370}
1371{
Yingyi Bu6d57e492016-06-06 21:24:42 -07001372 <LEFTPAREN> key = ConstantString() <EQ> value = ConstantString() <RIGHTPAREN>
Yingyi Bu391f09e2015-10-29 13:49:39 -07001373 {
1374 return new Pair<String, String>(key, value);
1375 }
1376}
1377
1378Map<String,String> Properties() throws ParseException:
1379{
1380 Map<String,String> properties = new HashMap<String,String>();
1381 Pair<String, String> property;
1382}
1383{
1384 (LOOKAHEAD(1) <LEFTPAREN> property = Property()
1385 {
1386 properties.put(property.first, property.second);
1387 }
1388 ( <COMMA> property = Property()
1389 {
1390 properties.put(property.first, property.second);
1391 }
1392 )* <RIGHTPAREN> )?
1393 {
1394 return properties;
1395 }
1396}
1397
1398Pair<String, String> Property() throws ParseException:
1399{
Yingyi Bu6d57e492016-06-06 21:24:42 -07001400 String key = null;
1401 String value = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07001402}
1403{
Yingyi Bu6d57e492016-06-06 21:24:42 -07001404 (key = Identifier() | key = StringLiteral())
1405 <EQ>
1406 ( value = ConstantString() | <INTEGER_LITERAL>
Yingyi Bu391f09e2015-10-29 13:49:39 -07001407 {
1408 try {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07001409 value = String.valueOf(Long.parseLong(token.image));
Yingyi Bu391f09e2015-10-29 13:49:39 -07001410 } catch (NumberFormatException nfe) {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07001411 throw new SqlppParseException(getSourceLocation(token), "inapproriate value: " + token.image);
Yingyi Bu391f09e2015-10-29 13:49:39 -07001412 }
1413 }
1414 )
1415 {
1416 return new Pair<String, String>(key.toUpperCase(), value);
1417 }
1418}
1419
Dmitry Lychagin8ba59442017-06-16 14:19:45 -07001420IndexedTypeExpression IndexedTypeExpr() throws ParseException:
Yingyi Bu391f09e2015-10-29 13:49:39 -07001421{
1422 TypeExpression typeExpr = null;
Dmitry Lychagin8ba59442017-06-16 14:19:45 -07001423 boolean isUnknownable = false;
Yingyi Bu391f09e2015-10-29 13:49:39 -07001424}
1425{
1426 (
1427 typeExpr = TypeReference()
1428 | typeExpr = OrderedListTypeDef()
1429 | typeExpr = UnorderedListTypeDef()
1430 )
Dmitry Lychagin8ba59442017-06-16 14:19:45 -07001431 ( <QUES> { isUnknownable = true; } )?
Yingyi Bu391f09e2015-10-29 13:49:39 -07001432 {
Dmitry Lychagin8ba59442017-06-16 14:19:45 -07001433 return new IndexedTypeExpression(typeExpr, isUnknownable);
Yingyi Bu391f09e2015-10-29 13:49:39 -07001434 }
1435}
1436
1437TypeExpression TypeExpr() throws ParseException:
1438{
1439 TypeExpression typeExpr = null;
1440}
1441{
1442 (
1443 typeExpr = RecordTypeDef()
1444 | typeExpr = TypeReference()
1445 | typeExpr = OrderedListTypeDef()
1446 | typeExpr = UnorderedListTypeDef()
1447 )
1448 {
1449 return typeExpr;
1450 }
1451}
1452
1453RecordTypeDefinition RecordTypeDef() throws ParseException:
1454{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07001455 Token startToken = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07001456 RecordTypeDefinition recType = new RecordTypeDefinition();
1457 RecordTypeDefinition.RecordKind recordKind = null;
1458}
1459{
1460 ( <CLOSED> { recordKind = RecordTypeDefinition.RecordKind.CLOSED; }
1461 | <OPEN> { recordKind = RecordTypeDefinition.RecordKind.OPEN; } )?
1462 <LEFTBRACE>
1463 {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07001464 startToken = token;
Yingyi Bu391f09e2015-10-29 13:49:39 -07001465 String hint = getHint(token);
1466 if (hint != null) {
1467 String splits[] = hint.split(" +");
1468 if (splits[0].equals(GEN_FIELDS_HINT)) {
1469 if (splits.length != 5) {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07001470 throw new SqlppParseException(getSourceLocation(getHintToken(token)),
1471 "Expecting: /*+ gen-fields <type> <min> <max> <prefix>*/");
Yingyi Bu391f09e2015-10-29 13:49:39 -07001472 }
1473 if (!splits[1].equals("int")) {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07001474 throw new SqlppParseException(getSourceLocation(getHintToken(token)),
1475 "The only supported type for gen-fields is int.");
Yingyi Bu391f09e2015-10-29 13:49:39 -07001476 }
1477 UndeclaredFieldsDataGen ufdg = new UndeclaredFieldsDataGen(UndeclaredFieldsDataGen.Type.INT,
1478 Integer.parseInt(splits[2]), Integer.parseInt(splits[3]), splits[4]);
1479 recType.setUndeclaredFieldsDataGen(ufdg);
1480 }
1481 }
1482
1483 }
1484 (
1485 RecordField(recType)
1486 ( <COMMA> RecordField(recType) )*
1487 )?
1488 <RIGHTBRACE>
1489 {
1490 if (recordKind == null) {
1491 recordKind = RecordTypeDefinition.RecordKind.OPEN;
1492 }
1493 recType.setRecordKind(recordKind);
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07001494 return addSourceLocation(recType, startToken);
Yingyi Bu391f09e2015-10-29 13:49:39 -07001495 }
1496}
1497
1498void RecordField(RecordTypeDefinition recType) throws ParseException:
1499{
1500 String fieldName;
1501 TypeExpression type = null;
1502 boolean nullable = false;
1503}
1504{
1505 fieldName = Identifier()
1506 {
1507 String hint = getHint(token);
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07001508 IRecordFieldDataGen rfdg = hint != null ? parseFieldDataGen(hint, token.specialToken) : null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07001509 }
1510 <COLON> type = TypeExpr() (<QUES> { nullable = true; } )?
1511 {
1512 recType.addField(fieldName, type, nullable, rfdg);
1513 }
1514}
1515
1516TypeReferenceExpression TypeReference() throws ParseException:
1517{
Abdullah Alamoudie4b318f2016-09-19 13:31:25 +03001518 Pair<Identifier,Identifier> id = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07001519}
1520{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07001521 id = QualifiedName()
1522 {
1523 if (id.first == null && id.second.getValue().equalsIgnoreCase("int")) {
1524 id.second.setValue("int64");
1525 }
Yingyi Bu391f09e2015-10-29 13:49:39 -07001526
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07001527 TypeReferenceExpression typeRef = new TypeReferenceExpression(id);
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07001528 return addSourceLocation(typeRef, token);
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07001529 }
Yingyi Bu391f09e2015-10-29 13:49:39 -07001530}
1531
1532OrderedListTypeDefinition OrderedListTypeDef() throws ParseException:
1533{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07001534 Token startToken = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07001535 TypeExpression type = null;
1536}
1537{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07001538 <LEFTBRACKET> { startToken = token; }
1539 ( type = TypeExpr() )
Yingyi Bu391f09e2015-10-29 13:49:39 -07001540 <RIGHTBRACKET>
1541 {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07001542 OrderedListTypeDefinition typeDef = new OrderedListTypeDefinition(type);
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07001543 return addSourceLocation(typeDef, startToken);
Yingyi Bu391f09e2015-10-29 13:49:39 -07001544 }
1545}
1546
Yingyi Bu391f09e2015-10-29 13:49:39 -07001547UnorderedListTypeDefinition UnorderedListTypeDef() throws ParseException:
1548{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07001549 Token startToken = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07001550 TypeExpression type = null;
1551}
1552{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07001553 <LEFTDBLBRACE> { startToken = token; }
Yingyi Bu391f09e2015-10-29 13:49:39 -07001554 ( type = TypeExpr() )
1555 <RIGHTDBLBRACE>
1556 {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07001557 UnorderedListTypeDefinition typeDef = new UnorderedListTypeDefinition(type);
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07001558 return addSourceLocation(typeDef, startToken);
Yingyi Bu391f09e2015-10-29 13:49:39 -07001559 }
1560}
1561
1562FunctionName FunctionName() throws ParseException:
1563{
1564 String first = null;
1565 String second = null;
1566 String third = null;
1567 boolean secondAfterDot = false;
1568}
1569{
Michael Blowd6cf6412016-06-30 02:44:35 -04001570 first = Identifier()
Yingyi Bu391f09e2015-10-29 13:49:39 -07001571 {
1572 FunctionName result = new FunctionName();
1573 result.hint = getHint(token);
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07001574 result.sourceLoc = getSourceLocation(token);
Michael Blowd6cf6412016-06-30 02:44:35 -04001575 }
Yingyi Bu391f09e2015-10-29 13:49:39 -07001576 ( <DOT> second = Identifier()
1577 {
1578 secondAfterDot = true;
1579 }
1580 (<SHARP> third = Identifier())? | <SHARP> second = Identifier() )?
1581 {
1582 if (second == null) {
1583 result.dataverse = defaultDataverse;
1584 result.library = null;
1585 result.function = first;
1586 } else if (third == null) {
1587 if (secondAfterDot) {
1588 result.dataverse = first;
1589 result.library = null;
1590 result.function = second;
1591 } else {
1592 result.dataverse = defaultDataverse;
1593 result.library = first;
1594 result.function = second;
1595 }
1596 } else {
1597 result.dataverse = first;
1598 result.library = second;
1599 result.function = third;
1600 }
1601
1602 if (result.function.equalsIgnoreCase("int")) {
1603 result.function = "int64";
1604 }
1605 return result;
1606 }
1607}
1608
1609Pair<Identifier,Identifier> TypeName() throws ParseException:
1610{
1611 Pair<Identifier,Identifier> name = null;
1612}
1613{
1614 name = QualifiedName()
1615 {
1616 if (name.first == null) {
1617 name.first = new Identifier(defaultDataverse);
1618 }
1619 return name;
1620 }
1621}
1622
1623String Identifier() throws ParseException:
1624{
1625 String lit = null;
1626}
1627{
1628 (<IDENTIFIER>
1629 {
1630 return token.image;
1631 }
1632 | lit = QuotedString()
1633 {
1634 return lit;
1635 }
1636 )
1637}
1638
Yingyi Bu1c0fff52016-03-25 20:23:30 -07001639void Dataset() throws ParseException:
1640{
1641}
1642{
1643 (<DATASET>|<COLLECTION>)
1644}
1645
Dmitry Lychagin8ba59442017-06-16 14:19:45 -07001646Pair<Integer, Pair<List<String>, IndexedTypeExpression>> OpenField() throws ParseException:
Yingyi Bu391f09e2015-10-29 13:49:39 -07001647{
Dmitry Lychagin8ba59442017-06-16 14:19:45 -07001648 IndexedTypeExpression fieldType = null;
Yingyi Buc9bfe252016-03-01 00:02:40 -08001649 Pair<Integer, List<String>> fieldList = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07001650}
1651{
1652 fieldList = NestedField()
Dmitry Lychagin8ba59442017-06-16 14:19:45 -07001653 ( <COLON> fieldType = IndexedTypeExpr() )?
Yingyi Bu391f09e2015-10-29 13:49:39 -07001654 {
Dmitry Lychagin8ba59442017-06-16 14:19:45 -07001655 return new Pair<Integer, Pair<List<String>, IndexedTypeExpression>>
1656 (fieldList.first, new Pair<List<String>, IndexedTypeExpression>(fieldList.second, fieldType));
Yingyi Bu391f09e2015-10-29 13:49:39 -07001657 }
1658}
1659
Yingyi Buc9bfe252016-03-01 00:02:40 -08001660Pair<Integer, List<String>> NestedField() throws ParseException:
Yingyi Bu391f09e2015-10-29 13:49:39 -07001661{
1662 List<String> exprList = new ArrayList<String>();
1663 String lit = null;
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07001664 Token litToken = null;
Yingyi Buc9bfe252016-03-01 00:02:40 -08001665 int source = 0;
Yingyi Bu391f09e2015-10-29 13:49:39 -07001666}
1667{
1668 lit = Identifier()
1669 {
Yingyi Bub9169b62016-02-26 21:21:49 -08001670 boolean meetParens = false;
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07001671 litToken = token;
Yingyi Bub9169b62016-02-26 21:21:49 -08001672 }
1673 (
Yingyi Buc9bfe252016-03-01 00:02:40 -08001674 LOOKAHEAD(1)
Yingyi Bub9169b62016-02-26 21:21:49 -08001675 <LEFTPAREN><RIGHTPAREN>
1676 {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07001677 if(!lit.equalsIgnoreCase("meta")){
1678 throw new SqlppParseException(getSourceLocation(litToken), "The string before () has to be \"meta\".");
Yingyi Bub9169b62016-02-26 21:21:49 -08001679 }
1680 meetParens = true;
Yingyi Buc9bfe252016-03-01 00:02:40 -08001681 source = 1;
Yingyi Bub9169b62016-02-26 21:21:49 -08001682 }
1683 )?
1684 {
1685 if(!meetParens){
1686 exprList.add(lit);
1687 }
Yingyi Bu391f09e2015-10-29 13:49:39 -07001688 }
1689 (<DOT>
1690 lit = Identifier()
1691 {
1692 exprList.add(lit);
1693 }
1694 )*
1695 {
Yingyi Buc9bfe252016-03-01 00:02:40 -08001696 return new Pair<Integer, List<String>>(source, exprList);
Yingyi Bu391f09e2015-10-29 13:49:39 -07001697 }
1698}
1699
Yingyi Bu6d57e492016-06-06 21:24:42 -07001700String ConstantString() throws ParseException:
1701{
1702 String value = null;
1703}
1704{
1705 (value = QuotedString() | value = StringLiteral())
1706 {
1707 return value;
1708 }
1709}
1710
Yingyi Bu391f09e2015-10-29 13:49:39 -07001711String QuotedString() throws ParseException:
1712{
1713}
1714{
1715 <QUOTED_STRING>
1716 {
1717 return removeQuotesAndEscapes(token.image);
1718 }
1719}
1720
Yingyi Bu391f09e2015-10-29 13:49:39 -07001721String StringLiteral() throws ParseException:
1722{
1723}
1724{
1725 <STRING_LITERAL>
1726 {
1727 return removeQuotesAndEscapes(token.image);
1728 }
1729}
1730
1731Pair<Identifier,Identifier> QualifiedName() throws ParseException:
1732{
1733 String first = null;
1734 String second = null;
1735}
1736{
1737 first = Identifier() (<DOT> second = Identifier())?
1738 {
1739 Identifier id1 = null;
1740 Identifier id2 = null;
1741 if (second == null) {
1742 id2 = new Identifier(first);
1743 } else
1744 {
1745 id1 = new Identifier(first);
1746 id2 = new Identifier(second);
1747 }
1748 return new Pair<Identifier,Identifier>(id1, id2);
1749 }
1750}
1751
1752Triple<Identifier,Identifier,Identifier> DoubleQualifiedName() throws ParseException:
1753{
1754 String first = null;
1755 String second = null;
1756 String third = null;
1757}
1758{
1759 first = Identifier() <DOT> second = Identifier() (<DOT> third = Identifier())?
1760 {
1761 Identifier id1 = null;
1762 Identifier id2 = null;
1763 Identifier id3 = null;
1764 if (third == null) {
1765 id2 = new Identifier(first);
1766 id3 = new Identifier(second);
1767 } else {
1768 id1 = new Identifier(first);
1769 id2 = new Identifier(second);
1770 id3 = new Identifier(third);
1771 }
1772 return new Triple<Identifier,Identifier,Identifier>(id1, id2, id3);
1773 }
1774}
1775
1776FunctionDecl FunctionDeclaration() throws ParseException:
1777{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07001778 Token startToken = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07001779 String functionName;
1780 List<VarIdentifier> paramList = new ArrayList<VarIdentifier>();
1781 Expression funcBody;
1782 createNewScope();
1783}
1784{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07001785 <DECLARE> { startToken = token; } <FUNCTION>
Xikui Wang3de700a2018-03-15 16:32:55 -07001786 functionName = Identifier()
1787 paramList = ParameterList()
1788 <LEFTBRACE>
1789 (funcBody = SelectExpression(true) | funcBody = Expression())
1790 <RIGHTBRACE>
1791 {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07001792 FunctionSignature signature = new FunctionSignature(defaultDataverse, functionName, paramList.size());
Xikui Wang3de700a2018-03-15 16:32:55 -07001793 getCurrentScope().addFunctionDescriptor(signature, false);
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07001794 FunctionDecl stmt = new FunctionDecl(signature, paramList, funcBody);
Xikui Wang3de700a2018-03-15 16:32:55 -07001795 removeCurrentScope();
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07001796 return addSourceLocation(stmt, startToken);
Xikui Wang3de700a2018-03-15 16:32:55 -07001797 }
Yingyi Bu391f09e2015-10-29 13:49:39 -07001798}
1799
Till Westmannef3f0272016-07-27 18:34:01 -07001800Query ExplainStatement() throws ParseException:
Yingyi Bu391f09e2015-10-29 13:49:39 -07001801{
Till Westmannef3f0272016-07-27 18:34:01 -07001802 Query query;
1803}
1804{
Till Westmann516d1a82016-08-02 14:45:53 -07001805 <EXPLAIN> query = Query(true)
Till Westmannef3f0272016-07-27 18:34:01 -07001806 {
1807 return query;
1808 }
1809}
1810
1811Query Query(boolean explain) throws ParseException:
1812{
1813 Query query = new Query(explain);
Yingyi Bu391f09e2015-10-29 13:49:39 -07001814 Expression expr;
1815}
1816{
1817 (
1818 expr = Expression()
1819 |
1820 expr = SelectExpression(false)
1821 )
1822 {
1823 query.setBody(expr);
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07001824 query.setSourceLocation(expr.getSourceLocation());
Yingyi Bu391f09e2015-10-29 13:49:39 -07001825 return query;
1826 }
1827}
1828
1829
Yingyi Bu391f09e2015-10-29 13:49:39 -07001830Expression Expression():
1831{
1832 Expression expr = null;
1833 Expression exprP = null;
1834}
1835{
1836(
1837 LOOKAHEAD(2)
1838 expr = OperatorExpr()
Yingyi Bu391f09e2015-10-29 13:49:39 -07001839 | expr = QuantifiedExpression()
1840)
1841 {
1842 return (exprP==null) ? expr : exprP;
1843 }
1844}
1845
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07001846Expression OperatorExpr() throws ParseException:
Yingyi Bu391f09e2015-10-29 13:49:39 -07001847{
1848 OperatorExpr op = null;
1849 Expression operand = null;
1850}
1851{
1852 operand = AndExpr()
1853 (
Yingyi Bu391f09e2015-10-29 13:49:39 -07001854 <OR>
1855 {
1856 if (op == null) {
1857 op = new OperatorExpr();
1858 op.addOperand(operand);
Xikui Wang3de700a2018-03-15 16:32:55 -07001859 op.setCurrentop(true);
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07001860 addSourceLocation(op, token);
Yingyi Bu391f09e2015-10-29 13:49:39 -07001861 }
Yingyi Bu196db5d2016-07-15 19:07:20 -07001862 try{
1863 op.addOperator(token.image.toLowerCase());
1864 } catch (Exception e){
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07001865 throw new SqlppParseException(getSourceLocation(token), e.getMessage());
Yingyi Bu196db5d2016-07-15 19:07:20 -07001866 }
Xikui Wang3de700a2018-03-15 16:32:55 -07001867 }
Yingyi Bu391f09e2015-10-29 13:49:39 -07001868
Xikui Wang3de700a2018-03-15 16:32:55 -07001869 operand = AndExpr()
1870 {
1871 op.addOperand(operand);
1872 }
Yingyi Bu391f09e2015-10-29 13:49:39 -07001873
1874 )*
1875
1876 {
1877 return op==null? operand: op;
1878 }
1879}
1880
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07001881Expression AndExpr() throws ParseException:
Yingyi Bu391f09e2015-10-29 13:49:39 -07001882{
1883 OperatorExpr op = null;
1884 Expression operand = null;
1885}
1886{
Yingyi Bu196db5d2016-07-15 19:07:20 -07001887 operand = NotExpr()
Yingyi Bu391f09e2015-10-29 13:49:39 -07001888 (
Yingyi Bu391f09e2015-10-29 13:49:39 -07001889 <AND>
1890 {
1891 if (op == null) {
1892 op = new OperatorExpr();
1893 op.addOperand(operand);
Yingyi Bu196db5d2016-07-15 19:07:20 -07001894 op.setCurrentop(true);
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07001895 addSourceLocation(op, token);
Yingyi Bu391f09e2015-10-29 13:49:39 -07001896 }
Yingyi Bu196db5d2016-07-15 19:07:20 -07001897 try{
1898 op.addOperator(token.image.toLowerCase());
Taewoo Kime65e6ca2017-01-14 17:53:28 -08001899 } catch (CompilationException e){
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07001900 throw new SqlppParseException(getSourceLocation(token), e.getMessage());
Yingyi Bu196db5d2016-07-15 19:07:20 -07001901 }
Yingyi Bu391f09e2015-10-29 13:49:39 -07001902 }
1903
Yingyi Bu196db5d2016-07-15 19:07:20 -07001904 operand = NotExpr()
Yingyi Bu391f09e2015-10-29 13:49:39 -07001905 {
1906 op.addOperand(operand);
1907 }
1908
1909 )*
1910
1911 {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07001912 return op==null ? operand: op;
Yingyi Bu391f09e2015-10-29 13:49:39 -07001913 }
1914}
1915
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07001916Expression NotExpr() throws ParseException:
Yingyi Bu196db5d2016-07-15 19:07:20 -07001917{
1918 Expression inputExpr;
1919 boolean not = false;
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07001920 Token startToken = null;
Yingyi Bu196db5d2016-07-15 19:07:20 -07001921}
1922{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07001923 (<NOT> { not = true; startToken = token; } )? inputExpr = RelExpr()
Yingyi Bu196db5d2016-07-15 19:07:20 -07001924 {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07001925 if(not) {
Dmitry Lychagin7c53fcf2017-11-07 12:07:41 -08001926 FunctionSignature signature = new FunctionSignature(BuiltinFunctions.NOT);
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07001927 CallExpr callExpr = new CallExpr(signature, new ArrayList<Expression>(Collections.singletonList(inputExpr)));
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07001928 return addSourceLocation(callExpr, startToken);
Yingyi Bu196db5d2016-07-15 19:07:20 -07001929 } else {
1930 return inputExpr;
1931 }
1932 }
1933}
Yingyi Bu391f09e2015-10-29 13:49:39 -07001934
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07001935Expression RelExpr() throws ParseException:
Yingyi Bu391f09e2015-10-29 13:49:39 -07001936{
Yingyi Bua8baf6d2016-07-05 21:40:44 -07001937 boolean not = false;
Yingyi Bu391f09e2015-10-29 13:49:39 -07001938 OperatorExpr op = null;
1939 Expression operand = null;
1940 boolean broadcast = false;
1941 IExpressionAnnotation annotation = null;
1942}
1943{
Yingyi Bu6c638342016-09-02 17:54:34 -07001944 operand = BetweenExpr()
Yingyi Bu391f09e2015-10-29 13:49:39 -07001945
1946 (
Yingyi Bu6e6a80c2017-01-21 20:18:49 -08001947 LOOKAHEAD(2)( <LT> | <GT> | <LE> | <GE> | <EQ> | <NE> | <LG> |<SIMILAR> | (<NOT> { not = true; })? <IN>)
Yingyi Bu391f09e2015-10-29 13:49:39 -07001948 {
1949 String mhint = getHint(token);
1950 if (mhint != null) {
1951 if (mhint.equals(INDEXED_NESTED_LOOP_JOIN_HINT)) {
Yingyi Bua8baf6d2016-07-05 21:40:44 -07001952 annotation = IndexedNLJoinExpressionAnnotation.INSTANCE;
1953 } else if (mhint.equals(SKIP_SECONDARY_INDEX_SEARCH_HINT)) {
1954 annotation = SkipSecondaryIndexSearchExpressionAnnotation.INSTANCE;
Yingyi Buea4ec722016-11-04 01:26:16 -07001955 } else if (mhint.equals(BROADCAST_JOIN_HINT)) {
1956 broadcast = true;
Yingyi Bua8baf6d2016-07-05 21:40:44 -07001957 }
Yingyi Bu391f09e2015-10-29 13:49:39 -07001958 }
Yingyi Buea4ec722016-11-04 01:26:16 -07001959
Yingyi Bua8baf6d2016-07-05 21:40:44 -07001960 String operator = token.image.toLowerCase();
Yingyi Bu4a4b8962016-09-16 12:09:11 -07001961 if (operator.equals("<>")){
1962 operator = "!=";
1963 }
1964 if (not) {
Yingyi Bua8baf6d2016-07-05 21:40:44 -07001965 operator = "not_" + operator;
1966 }
Yingyi Bu391f09e2015-10-29 13:49:39 -07001967 if (op == null) {
1968 op = new OperatorExpr();
Yingyi Buea4ec722016-11-04 01:26:16 -07001969 op.addOperand(operand, false); // broadcast is always for the right branch
Yingyi Bua8baf6d2016-07-05 21:40:44 -07001970 op.setCurrentop(true);
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07001971 addSourceLocation(op, token);
Yingyi Bu391f09e2015-10-29 13:49:39 -07001972 }
Yingyi Bu196db5d2016-07-15 19:07:20 -07001973 try{
1974 op.addOperator(operator);
Taewoo Kime65e6ca2017-01-14 17:53:28 -08001975 } catch (CompilationException e){
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07001976 throw new SqlppParseException(getSourceLocation(token), e.getMessage());
Yingyi Bu196db5d2016-07-15 19:07:20 -07001977 }
Yingyi Bua8baf6d2016-07-05 21:40:44 -07001978 }
Yingyi Bu391f09e2015-10-29 13:49:39 -07001979
Yingyi Bu6c638342016-09-02 17:54:34 -07001980 operand = BetweenExpr()
Yingyi Buea4ec722016-11-04 01:26:16 -07001981 {
Yingyi Bu391f09e2015-10-29 13:49:39 -07001982 op.addOperand(operand, broadcast);
Yingyi Buea4ec722016-11-04 01:26:16 -07001983 }
Yingyi Bu391f09e2015-10-29 13:49:39 -07001984 )?
1985
1986 {
1987 if (annotation != null) {
1988 op.addHint(annotation);
1989 }
1990 return op==null? operand: op;
1991 }
1992}
1993
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07001994Expression BetweenExpr() throws ParseException:
Yingyi Bu6c638342016-09-02 17:54:34 -07001995{
1996 boolean not = false;
1997 OperatorExpr op = null;
1998 Expression operand = null;
1999 IExpressionAnnotation annotation = null;
2000}
2001{
2002 operand = IsExpr()
2003 (
2004 LOOKAHEAD(2)
2005 (<NOT> { not = true; })? <BETWEEN>
2006 {
2007 String mhint = getHint(token);
2008 if (mhint != null) {
2009 if (mhint.equals(INDEXED_NESTED_LOOP_JOIN_HINT)) {
2010 annotation = IndexedNLJoinExpressionAnnotation.INSTANCE;
2011 } else if (mhint.equals(SKIP_SECONDARY_INDEX_SEARCH_HINT)) {
2012 annotation = SkipSecondaryIndexSearchExpressionAnnotation.INSTANCE;
2013 }
2014 }
2015 String operator = token.image.toLowerCase();
2016 if(not){
2017 operator = "not_" + operator;
2018 }
2019 if (op == null) {
2020 op = new OperatorExpr();
2021 op.addOperand(operand);
2022 op.setCurrentop(true);
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07002023 addSourceLocation(op, token);
Yingyi Bu6c638342016-09-02 17:54:34 -07002024 }
2025 try{
2026 op.addOperator(operator);
Taewoo Kime65e6ca2017-01-14 17:53:28 -08002027 } catch (CompilationException e){
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002028 throw new SqlppParseException(getSourceLocation(token), e.getMessage());
Yingyi Bu6c638342016-09-02 17:54:34 -07002029 }
2030 }
2031
2032 operand = IsExpr()
2033 {
2034 op.addOperand(operand);
2035 }
2036
2037 <AND>
2038 operand = IsExpr()
2039 {
Dmitry Lychaginef1719e2017-12-15 08:33:07 -08002040 op.addOperator(OperatorType.AND);
Yingyi Bu6c638342016-09-02 17:54:34 -07002041 op.addOperand(operand);
2042 }
2043 )?
2044
2045 {
2046 if (annotation != null) {
2047 op.addHint(annotation);
2048 }
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002049 return op==null ? operand: op;
Yingyi Bu6c638342016-09-02 17:54:34 -07002050 }
2051}
2052
Yingyi Budaa549c2016-06-28 22:30:52 -07002053Expression IsExpr() throws ParseException:
2054{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002055 Token notToken = null;
2056 CallExpr expr = null;
Yingyi Budaa549c2016-06-28 22:30:52 -07002057 Expression operand = null;
2058 boolean not = false;
Dmitry Lychagin7c53fcf2017-11-07 12:07:41 -08002059 FunctionIdentifier fn = null;
Yingyi Budaa549c2016-06-28 22:30:52 -07002060}
2061{
Yingyi Bu6e6a80c2017-01-21 20:18:49 -08002062 operand = LikeExpr()
Dmitry Lychagin7c53fcf2017-11-07 12:07:41 -08002063 ( <IS>
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002064 (<NOT> { not = true; notToken = token; })?
Dmitry Lychagin7c53fcf2017-11-07 12:07:41 -08002065 (
2066 <NULL> { fn = BuiltinFunctions.IS_NULL; } |
2067 <MISSING> { fn = BuiltinFunctions.IS_MISSING; } |
Dmitry Lychagin7d594a32018-01-15 14:31:03 -08002068 <UNKNOWN> { fn = BuiltinFunctions.IS_UNKNOWN; } |
Dmitry Lychagin1aa0dd42018-04-17 14:35:24 -07002069 (<KNOWN> | <VALUED>) { not = !not; fn = BuiltinFunctions.IS_UNKNOWN; }
Dmitry Lychagin7c53fcf2017-11-07 12:07:41 -08002070 )
Yingyi Budaa549c2016-06-28 22:30:52 -07002071 {
Dmitry Lychagin7c53fcf2017-11-07 12:07:41 -08002072 FunctionSignature signature = new FunctionSignature(fn);
Yingyi Budaa549c2016-06-28 22:30:52 -07002073 expr = new CallExpr(signature, new ArrayList<Expression>(Collections.singletonList(operand)));
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07002074 addSourceLocation(expr, token);
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002075 if (not) {
Dmitry Lychagin7c53fcf2017-11-07 12:07:41 -08002076 FunctionSignature notSignature = new FunctionSignature(BuiltinFunctions.NOT);
Yingyi Budaa549c2016-06-28 22:30:52 -07002077 expr = new CallExpr(notSignature, new ArrayList<Expression>(Collections.singletonList(expr)));
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07002078 addSourceLocation(expr, notToken);
Yingyi Budaa549c2016-06-28 22:30:52 -07002079 }
2080 }
2081 )?
2082 {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002083 return expr == null ? operand : expr;
Yingyi Budaa549c2016-06-28 22:30:52 -07002084 }
2085}
2086
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002087Expression LikeExpr() throws ParseException:
Yingyi Bu6e6a80c2017-01-21 20:18:49 -08002088{
2089 boolean not = false;
2090 OperatorExpr op = null;
2091 Expression operand = null;
2092}
2093{
2094 operand = ConcatExpr()
2095 (
2096 LOOKAHEAD(2)
2097 (<NOT> { not = true; })? <LIKE>
2098 {
2099 op = new OperatorExpr();
2100 op.addOperand(operand);
2101 op.setCurrentop(true);
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07002102 addSourceLocation(op, token);
Yingyi Bu6e6a80c2017-01-21 20:18:49 -08002103
2104 String operator = token.image.toLowerCase();
2105 if (not) {
2106 operator = "not_" + operator;
2107 }
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002108 try {
Yingyi Bu6e6a80c2017-01-21 20:18:49 -08002109 op.addOperator(operator);
2110 } catch (CompilationException e){
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002111 throw new SqlppParseException(getSourceLocation(token), e.getMessage());
Yingyi Bu6e6a80c2017-01-21 20:18:49 -08002112 }
2113 }
2114
2115 operand = ConcatExpr()
2116 {
2117 op.addOperand(operand);
2118 }
2119 )?
2120
2121 {
2122 return op == null ? operand : op;
2123 }
2124}
2125
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002126Expression ConcatExpr() throws ParseException:
Yingyi Bufdc71eb2016-08-24 22:41:57 -07002127{
2128 OperatorExpr op = null;
2129 Expression operand = null;
2130}
2131{
2132 operand = AddExpr()
2133 (
2134 LOOKAHEAD(1)
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002135 <CONCAT>
Yingyi Bufdc71eb2016-08-24 22:41:57 -07002136 {
2137 if (op == null) {
2138 op = new OperatorExpr();
2139 op.addOperand(operand);
2140 op.setCurrentop(true);
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07002141 addSourceLocation(op, token);
Yingyi Bufdc71eb2016-08-24 22:41:57 -07002142 }
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002143 op.addOperator(OperatorType.CONCAT);
Yingyi Bufdc71eb2016-08-24 22:41:57 -07002144 }
2145 operand = AddExpr()
2146 {
2147 op.addOperand(operand);
2148 }
2149 )*
2150
2151 {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002152 return op == null ? operand : op;
Yingyi Bufdc71eb2016-08-24 22:41:57 -07002153 }
2154}
Yingyi Budaa549c2016-06-28 22:30:52 -07002155
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002156Expression AddExpr() throws ParseException:
Yingyi Bu391f09e2015-10-29 13:49:39 -07002157{
2158 OperatorExpr op = null;
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002159 OperatorType opType = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07002160 Expression operand = null;
2161}
2162{
2163 operand = MultExpr()
Yingyi Budaa549c2016-06-28 22:30:52 -07002164 (
Yingyi Bufdc71eb2016-08-24 22:41:57 -07002165 LOOKAHEAD(1)
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002166 (<PLUS> { opType = OperatorType.PLUS; } | <MINUS> { opType = OperatorType.MINUS; } )
Yingyi Bu391f09e2015-10-29 13:49:39 -07002167 {
2168 if (op == null) {
2169 op = new OperatorExpr();
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002170 op.addOperand(operand);
2171 op.setCurrentop(true);
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07002172 addSourceLocation(op, token);
Yingyi Bu391f09e2015-10-29 13:49:39 -07002173 }
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002174 op.addOperator(opType);
Yingyi Bu391f09e2015-10-29 13:49:39 -07002175 }
2176
2177 operand = MultExpr()
2178 {
2179 op.addOperand(operand);
2180 }
2181 )*
2182
2183 {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002184 return op == null ? operand : op;
Yingyi Bu391f09e2015-10-29 13:49:39 -07002185 }
2186}
2187
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002188Expression MultExpr() throws ParseException:
Yingyi Bu391f09e2015-10-29 13:49:39 -07002189{
2190 OperatorExpr op = null;
Dmitry Lychaginbf48c492018-05-01 18:30:27 -07002191 OperatorType opType = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07002192 Expression operand = null;
2193}
2194{
Yingyi Bu79ccdac2016-07-26 23:49:24 -07002195 operand = ExponentExpr()
Yingyi Bu391f09e2015-10-29 13:49:39 -07002196
Dmitry Lychaginbf48c492018-05-01 18:30:27 -07002197 ( (
2198 <MUL> { opType = OperatorType.MUL; } |
2199 <DIVIDE> { opType = OperatorType.DIVIDE; } |
2200 <DIV> { opType = OperatorType.DIV; } |
2201 ( <MOD> | <PERCENT> ) { opType = OperatorType.MOD; }
2202 )
Yingyi Bu391f09e2015-10-29 13:49:39 -07002203 {
2204 if (op == null) {
2205 op = new OperatorExpr();
Yingyi Bu79ccdac2016-07-26 23:49:24 -07002206 op.addOperand(operand);
2207 op.setCurrentop(true);
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07002208 addSourceLocation(op, token);
Yingyi Bu79ccdac2016-07-26 23:49:24 -07002209 }
Dmitry Lychaginbf48c492018-05-01 18:30:27 -07002210 op.addOperator(opType);
Yingyi Bu79ccdac2016-07-26 23:49:24 -07002211 }
2212 operand = ExponentExpr()
2213 {
2214 op.addOperand(operand);
2215 }
2216 )*
2217
2218 {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002219 return op == null ? operand : op;
Yingyi Bu79ccdac2016-07-26 23:49:24 -07002220 }
2221}
2222
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002223Expression ExponentExpr() throws ParseException:
Yingyi Bu79ccdac2016-07-26 23:49:24 -07002224{
2225 OperatorExpr op = null;
2226 Expression operand = null;
2227}
2228{
2229 operand = UnaryExpr()
2230 (<CARET>
2231 {
2232 if (op == null) {
2233 op = new OperatorExpr();
2234 op.addOperand(operand);
2235 op.setCurrentop(true);
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07002236 addSourceLocation(op, token);
Yingyi Bu391f09e2015-10-29 13:49:39 -07002237 }
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002238 op.addOperator(OperatorType.CARET);
Yingyi Bu391f09e2015-10-29 13:49:39 -07002239 }
2240 operand = UnaryExpr()
2241 {
2242 op.addOperand(operand);
2243 }
Yingyi Bu79ccdac2016-07-26 23:49:24 -07002244 )?
2245 {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002246 return op == null ? operand : op;
Yingyi Bu79ccdac2016-07-26 23:49:24 -07002247 }
Yingyi Bu391f09e2015-10-29 13:49:39 -07002248}
2249
2250Expression UnaryExpr() throws ParseException:
2251{
Yingyi Bu196db5d2016-07-15 19:07:20 -07002252 boolean not = false;
2253 UnaryExpr uexpr = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07002254 Expression expr = null;
2255}
Yingyi Budaa549c2016-06-28 22:30:52 -07002256{
Yingyi Bu196db5d2016-07-15 19:07:20 -07002257 ( (<PLUS> | <MINUS> | (<NOT> { not = true; } )? <EXISTS> )
Yingyi Bu391f09e2015-10-29 13:49:39 -07002258 {
Yingyi Bu196db5d2016-07-15 19:07:20 -07002259 String exprType = token.image.toLowerCase();
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002260 if (not) {
Yingyi Bu196db5d2016-07-15 19:07:20 -07002261 exprType = "not_" + exprType;
2262 }
2263 uexpr = new UnaryExpr();
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07002264 addSourceLocation(uexpr, token);
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002265 try {
Yingyi Bu196db5d2016-07-15 19:07:20 -07002266 uexpr.setExprType(exprType);
Taewoo Kime65e6ca2017-01-14 17:53:28 -08002267 } catch (CompilationException e){
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002268 throw new SqlppParseException(getSourceLocation(token), e.getMessage());
Yingyi Budaa549c2016-06-28 22:30:52 -07002269 }
Yingyi Bu391f09e2015-10-29 13:49:39 -07002270 }
2271 )?
2272
2273 expr = ValueExpr()
2274 {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002275 if (uexpr == null) {
2276 return expr;
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07002277 } else {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002278 uexpr.setExpr(expr);
2279 return uexpr;
2280 }
Yingyi Bu391f09e2015-10-29 13:49:39 -07002281 }
2282}
2283
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002284Expression ValueExpr() throws ParseException:
Yingyi Bu391f09e2015-10-29 13:49:39 -07002285{
2286 Expression expr = null;
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002287 AbstractAccessor accessor = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07002288}
2289{
2290 expr = PrimaryExpr() (
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002291 accessor = FieldAccessor(accessor != null ? accessor : expr)
2292 | accessor = IndexAccessor(accessor != null ? accessor : expr)
2293 )*
2294 {
2295 return accessor == null ? expr : accessor;
2296 }
Yingyi Bu391f09e2015-10-29 13:49:39 -07002297}
2298
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002299FieldAccessor FieldAccessor(Expression inputExpr) throws ParseException:
Yingyi Bu391f09e2015-10-29 13:49:39 -07002300{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002301 Token startToken = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07002302 String ident = null;
2303}
2304{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002305 <DOT> { startToken = token; } ident = Identifier()
Yingyi Bu391f09e2015-10-29 13:49:39 -07002306 {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002307 FieldAccessor fa = new FieldAccessor(inputExpr, new Identifier(ident));
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07002308 return addSourceLocation(fa, startToken);
Yingyi Bu391f09e2015-10-29 13:49:39 -07002309 }
2310}
2311
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002312IndexAccessor IndexAccessor(Expression inputExpr) throws ParseException:
Yingyi Bu391f09e2015-10-29 13:49:39 -07002313{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002314 Token startToken = null;
2315 Expression expr = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07002316}
2317{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002318 <LEFTBRACKET> { startToken = token; }
2319 ( expr = Expression()
Yingyi Bu391f09e2015-10-29 13:49:39 -07002320 {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002321 if (expr.getKind() == Expression.Kind.LITERAL_EXPRESSION)
Yingyi Bu391f09e2015-10-29 13:49:39 -07002322 {
2323 Literal lit = ((LiteralExpr)expr).getValue();
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002324 if (lit.getLiteralType() != Literal.Type.INTEGER &&
2325 lit.getLiteralType() != Literal.Type.LONG) {
2326 throw new SqlppParseException(expr.getSourceLocation(), "Index should be an INTEGER");
Yingyi Bu391f09e2015-10-29 13:49:39 -07002327 }
2328 }
2329 }
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002330 )
Yingyi Bu391f09e2015-10-29 13:49:39 -07002331
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002332 <RIGHTBRACKET>
2333 {
2334 IndexAccessor ia = new IndexAccessor(inputExpr, expr);
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07002335 return addSourceLocation(ia, startToken);
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002336 }
Yingyi Bu391f09e2015-10-29 13:49:39 -07002337}
2338
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002339Expression PrimaryExpr() throws ParseException:
Yingyi Bu391f09e2015-10-29 13:49:39 -07002340{
2341 Expression expr = null;
2342}
2343{
2344 ( LOOKAHEAD(4)
2345 expr = FunctionCallExpr()
Dmitry Lychagin5fbd04b2018-04-19 16:54:28 -07002346 | expr = CaseExpr()
Yingyi Bu391f09e2015-10-29 13:49:39 -07002347 | expr = Literal()
2348 | expr = VariableRef()
Dmitry Lychagin1bdf8082018-06-13 14:48:23 -07002349 | expr = ExternalVariableRef()
Yingyi Bu391f09e2015-10-29 13:49:39 -07002350 | expr = ListConstructor()
2351 | expr = RecordConstructor()
2352 | expr = ParenthesizedExpression()
2353 )
2354 {
2355 return expr;
2356 }
2357}
2358
2359Expression Literal() throws ParseException:
2360{
2361 LiteralExpr lit = new LiteralExpr();
2362 String str = null;
2363}
2364{
2365 ( str = StringLiteral()
2366 {
2367 lit.setValue(new StringLiteral(str));
2368 }
2369 | <INTEGER_LITERAL>
2370 {
Till Westmann68c6a992016-09-30 00:19:12 -07002371 try {
2372 lit.setValue(new LongIntegerLiteral(Long.valueOf(token.image)));
2373 } catch (NumberFormatException e) {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002374 throw new SqlppParseException(getSourceLocation(token), "Could not parse numeric literal \"" + token.image +'"');
Till Westmann68c6a992016-09-30 00:19:12 -07002375 }
Yingyi Bu391f09e2015-10-29 13:49:39 -07002376 }
2377 | <FLOAT_LITERAL>
2378 {
Till Westmann68c6a992016-09-30 00:19:12 -07002379 try {
2380 lit.setValue(new FloatLiteral(Float.valueOf(token.image)));
2381 } catch (NumberFormatException e) {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002382 throw new SqlppParseException(getSourceLocation(token), "Could not parse numeric literal \"" + token.image +'"');
Till Westmann68c6a992016-09-30 00:19:12 -07002383 }
Yingyi Bu391f09e2015-10-29 13:49:39 -07002384 }
2385 | <DOUBLE_LITERAL>
2386 {
Till Westmann68c6a992016-09-30 00:19:12 -07002387 try {
2388 lit.setValue(new DoubleLiteral(Double.valueOf(token.image)));
2389 } catch (NumberFormatException e) {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002390 throw new SqlppParseException(getSourceLocation(token), "Could not parse numeric literal \"" + token.image +'"');
Till Westmann68c6a992016-09-30 00:19:12 -07002391 }
Yingyi Bu391f09e2015-10-29 13:49:39 -07002392 }
Yingyi Bu535d86b2016-05-23 16:44:25 -07002393 | <MISSING>
2394 {
2395 lit.setValue(MissingLiteral.INSTANCE);
2396 }
Yingyi Bu391f09e2015-10-29 13:49:39 -07002397 | <NULL>
2398 {
2399 lit.setValue(NullLiteral.INSTANCE);
2400 }
2401 | <TRUE>
2402 {
2403 lit.setValue(TrueLiteral.INSTANCE);
2404 }
2405 | <FALSE>
2406 {
2407 lit.setValue(FalseLiteral.INSTANCE);
2408 }
2409 )
2410 {
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07002411 return addSourceLocation(lit, token);
Yingyi Bu391f09e2015-10-29 13:49:39 -07002412 }
2413}
2414
Yingyi Bu391f09e2015-10-29 13:49:39 -07002415VariableExpr VariableRef() throws ParseException:
2416{
Yingyi Bu391f09e2015-10-29 13:49:39 -07002417 VarIdentifier var = new VarIdentifier();
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002418 String id = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07002419}
2420{
Yingyi Bu391f09e2015-10-29 13:49:39 -07002421 (<IDENTIFIER> { id = token.image; } | id = QuotedString())
2422 {
Yingyi Buacc12a92016-03-26 17:25:05 -07002423 id = SqlppVariableUtil.toInternalVariableName(id); // Prefix user-defined variables with "$"
Yingyi Bu391f09e2015-10-29 13:49:39 -07002424 Identifier ident = lookupSymbol(id);
2425 if (isInForbiddenScopes(id)) {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002426 throw new SqlppParseException(getSourceLocation(token),
2427 "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.");
Yingyi Bu391f09e2015-10-29 13:49:39 -07002428 }
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002429 VariableExpr varExp = new VariableExpr();
2430 if (ident != null) { // exist such ident
Yingyi Bu391f09e2015-10-29 13:49:39 -07002431 varExp.setVar((VarIdentifier)ident);
2432 } else {
2433 varExp.setVar(var);
Yingyi Buacc12a92016-03-26 17:25:05 -07002434 varExp.setIsNewVar(false);
2435 var.setValue(id);
Yingyi Bu391f09e2015-10-29 13:49:39 -07002436 }
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07002437 return addSourceLocation(varExp, token);
Yingyi Bu391f09e2015-10-29 13:49:39 -07002438 }
2439}
2440
Yingyi Bu391f09e2015-10-29 13:49:39 -07002441VariableExpr Variable() throws ParseException:
2442{
Yingyi Bu391f09e2015-10-29 13:49:39 -07002443 VarIdentifier var = new VarIdentifier();
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002444 String id = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07002445}
2446{
Yingyi Bu391f09e2015-10-29 13:49:39 -07002447 (<IDENTIFIER> { id = token.image; } | id = QuotedString())
2448 {
Yingyi Buacc12a92016-03-26 17:25:05 -07002449 id = SqlppVariableUtil.toInternalVariableName(id); // prefix user-defined variables with "$".
Yingyi Bu391f09e2015-10-29 13:49:39 -07002450 Identifier ident = lookupSymbol(id);
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002451 VariableExpr varExp = new VariableExpr();
Yingyi Bu391f09e2015-10-29 13:49:39 -07002452 if(ident != null) { // exist such ident
2453 varExp.setIsNewVar(false);
2454 }
2455 varExp.setVar(var);
Yingyi Bucaea8f02015-11-16 15:12:15 -08002456 var.setValue(id);
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07002457 return addSourceLocation(varExp, token);
Yingyi Bu391f09e2015-10-29 13:49:39 -07002458 }
2459}
2460
Dmitry Lychagin1bdf8082018-06-13 14:48:23 -07002461VariableExpr ExternalVariableRef() throws ParseException:
2462{
2463 String name = null;
2464}
2465{
2466 (
2467 (
2468 <DOLLAR>
2469 (
2470 <INTEGER_LITERAL> { name = token.image; } |
2471 <IDENTIFIER> { name = token.image; } |
2472 name = QuotedString()
2473 )
2474 )
2475 |
2476 (
2477 <QUES> { name = String.valueOf(++externalVarCounter); }
2478 )
2479 )
2480 {
2481 String idName = SqlppVariableUtil.toExternalVariableName(name);
2482 VarIdentifier id = new VarIdentifier(idName);
2483 VariableExpr varExp = new VariableExpr(id);
2484 return addSourceLocation(varExp, token);
2485 }
2486}
2487
Yingyi Bu391f09e2015-10-29 13:49:39 -07002488Expression ListConstructor() throws ParseException:
2489{
2490 Expression expr = null;
2491}
2492{
2493 (
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002494 expr = OrderedListConstructor() |
2495 expr = UnorderedListConstructor()
Yingyi Bu391f09e2015-10-29 13:49:39 -07002496 )
Yingyi Bu391f09e2015-10-29 13:49:39 -07002497 {
2498 return expr;
2499 }
2500}
2501
Yingyi Bu391f09e2015-10-29 13:49:39 -07002502ListConstructor OrderedListConstructor() throws ParseException:
2503{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002504 Token startToken = null;
2505 List<Expression> exprList = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07002506}
2507{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002508 <LEFTBRACKET> { startToken = token; }
2509 exprList = ExpressionList()
2510 <RIGHTBRACKET>
2511 {
2512 ListConstructor expr = new ListConstructor(ListConstructor.Type.ORDERED_LIST_CONSTRUCTOR, exprList);
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07002513 return addSourceLocation(expr, startToken);
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002514 }
Yingyi Bu391f09e2015-10-29 13:49:39 -07002515}
2516
2517ListConstructor UnorderedListConstructor() throws ParseException:
2518{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002519 Token startToken = null;
2520 List<Expression> exprList = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07002521}
2522{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002523 <LEFTDBLBRACE> { startToken = token; }
2524 exprList = ExpressionList()
2525 <RIGHTDBLBRACE>
2526 {
2527 ListConstructor expr = new ListConstructor(ListConstructor.Type.UNORDERED_LIST_CONSTRUCTOR, exprList);
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07002528 return addSourceLocation(expr, startToken);
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002529 }
Yingyi Bu391f09e2015-10-29 13:49:39 -07002530}
2531
2532List<Expression> ExpressionList() throws ParseException:
2533{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002534 Expression expr = null;
2535 List<Expression> exprList = new ArrayList<Expression>();
Yingyi Bu391f09e2015-10-29 13:49:39 -07002536}
2537{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002538 (
2539 expr = Expression()
2540 {
2541 exprList.add(expr);
2542 }
2543 ( <COMMA> expr = Expression()
Till Westmann60f89982017-08-11 18:14:20 -07002544 {
2545 exprList.add(expr);
2546 }
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002547 )*
2548 )?
2549 {
2550 return exprList;
2551 }
Yingyi Bu391f09e2015-10-29 13:49:39 -07002552}
2553
Yingyi Bu391f09e2015-10-29 13:49:39 -07002554RecordConstructor RecordConstructor() throws ParseException:
2555{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002556 Token startToken = null;
2557 FieldBinding fb = null;
2558 List<FieldBinding> fbList = new ArrayList<FieldBinding>();
Yingyi Bu391f09e2015-10-29 13:49:39 -07002559}
2560{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002561 <LEFTBRACE> { startToken = token; }
2562 (
2563 fb = FieldBinding() { fbList.add(fb); }
2564 (<COMMA> fb = FieldBinding() { fbList.add(fb); })*
2565 )?
2566 <RIGHTBRACE>
2567 {
2568 RecordConstructor expr = new RecordConstructor(fbList);
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07002569 return addSourceLocation(expr, startToken);
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002570 }
Yingyi Bu391f09e2015-10-29 13:49:39 -07002571}
2572
2573FieldBinding FieldBinding() throws ParseException:
2574{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002575 Expression left, right;
Yingyi Bu391f09e2015-10-29 13:49:39 -07002576}
2577{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002578 left = Expression() <COLON> right = Expression()
2579 {
2580 return new FieldBinding(left, right);
2581 }
Yingyi Bu391f09e2015-10-29 13:49:39 -07002582}
2583
Yingyi Bu391f09e2015-10-29 13:49:39 -07002584Expression FunctionCallExpr() throws ParseException:
2585{
2586 CallExpr callExpr;
2587 List<Expression> argList = new ArrayList<Expression>();
Yingyi Buf4d09842016-08-26 00:03:52 -07002588 Expression tmp = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07002589 int arity = 0;
2590 FunctionName funcName = null;
2591 String hint = null;
Yingyi Buf4d09842016-08-26 00:03:52 -07002592 boolean star = false;
Dmitry Lychagin7a4b5682017-09-11 18:53:07 -07002593 boolean distinct = false;
Yingyi Bu391f09e2015-10-29 13:49:39 -07002594}
2595{
2596 funcName = FunctionName()
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002597 {
2598 hint = funcName.hint;
2599 }
Dmitry Lychagin7a4b5682017-09-11 18:53:07 -07002600 <LEFTPAREN> (
2601 ( <DISTINCT> { distinct = true; } )?
2602 ( tmp = Expression() | <MUL> { star = true; } )
Yingyi Bu391f09e2015-10-29 13:49:39 -07002603 {
Yingyi Buf4d09842016-08-26 00:03:52 -07002604 if(star){
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002605 if(!funcName.function.equalsIgnoreCase("count")){
2606 throw new SqlppParseException(getSourceLocation(token), "The parameter * can only be used in COUNT().");
Yingyi Buf4d09842016-08-26 00:03:52 -07002607 }
2608 argList.add(new LiteralExpr(new LongIntegerLiteral(1L)));
2609 } else {
2610 argList.add(tmp);
2611 }
Yingyi Bu391f09e2015-10-29 13:49:39 -07002612 arity ++;
2613 }
2614 (<COMMA> tmp = Expression()
2615 {
2616 argList.add(tmp);
2617 arity++;
2618 }
2619 )*)? <RIGHTPAREN>
2620 {
Dmitry Lychagin7a4b5682017-09-11 18:53:07 -07002621 String name = funcName.function;
2622 if (distinct) {
2623 name += "-distinct";
2624 }
Yingyi Bu391f09e2015-10-29 13:49:39 -07002625 // TODO use funcName.library
Dmitry Lychagin7a4b5682017-09-11 18:53:07 -07002626 String fqFunctionName = funcName.library == null ? name : funcName.library + "#" + name;
Yingyi Bu391f09e2015-10-29 13:49:39 -07002627 FunctionSignature signature
2628 = lookupFunctionSignature(funcName.dataverse, fqFunctionName, arity);
2629 if (signature == null) {
2630 signature = new FunctionSignature(funcName.dataverse, fqFunctionName, arity);
2631 }
Xikui Wang96fd4022017-04-10 14:23:31 -07002632 callExpr = FunctionMapUtil.normalizedListInputFunctions(new CallExpr(signature,argList));
Yingyi Bu391f09e2015-10-29 13:49:39 -07002633 if (hint != null) {
2634 if (hint.startsWith(INDEXED_NESTED_LOOP_JOIN_HINT)) {
2635 callExpr.addHint(IndexedNLJoinExpressionAnnotation.INSTANCE);
2636 } else if (hint.startsWith(SKIP_SECONDARY_INDEX_SEARCH_HINT)) {
2637 callExpr.addHint(SkipSecondaryIndexSearchExpressionAnnotation.INSTANCE);
2638 }
2639 }
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002640 callExpr.setSourceLocation(funcName.sourceLoc);
Yingyi Bu391f09e2015-10-29 13:49:39 -07002641 return callExpr;
2642 }
2643}
2644
2645Expression ParenthesizedExpression() throws ParseException:
2646{
2647 Expression expr;
2648}
2649{
2650 (
2651 LOOKAHEAD(2)
2652 <LEFTPAREN> expr = Expression() <RIGHTPAREN>
2653 |
2654 expr = Subquery()
2655 )
2656 {
2657 return expr;
2658 }
2659}
2660
Yingyi Buc8c067c2016-07-25 23:37:19 -07002661Expression CaseExpr() throws ParseException:
Yingyi Bu391f09e2015-10-29 13:49:39 -07002662{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002663 Token startToken = null;
2664 Expression conditionExpr = null;
Yingyi Buc8c067c2016-07-25 23:37:19 -07002665 List<Expression> whenExprs = new ArrayList<Expression>();
2666 List<Expression> thenExprs = new ArrayList<Expression>();
2667 Expression elseExpr = null;
Yingyi Buc8c067c2016-07-25 23:37:19 -07002668 Expression whenExpr = null;
2669 Expression thenExpr = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07002670}
2671{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002672 <CASE> { startToken = token; }
2673 ( conditionExpr = Expression() )?
Yingyi Buc8c067c2016-07-25 23:37:19 -07002674 (
2675 <WHEN> whenExpr = Expression()
2676 {
2677 whenExprs.add(whenExpr);
2678 }
2679 <THEN> thenExpr = Expression()
2680 {
2681 thenExprs.add(thenExpr);
2682 }
2683 )*
2684 (<ELSE> elseExpr = Expression() )?
2685 <END>
2686 {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002687 if (conditionExpr == null) {
2688 LiteralExpr litExpr = new LiteralExpr(TrueLiteral.INSTANCE);
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07002689 conditionExpr = addSourceLocation(litExpr, startToken);
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002690 }
2691 CaseExpression caseExpr = new CaseExpression(conditionExpr, whenExprs, thenExprs, elseExpr);
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07002692 return addSourceLocation(caseExpr, startToken);
Yingyi Buc8c067c2016-07-25 23:37:19 -07002693 }
Yingyi Bu391f09e2015-10-29 13:49:39 -07002694}
2695
Yingyi Buab817482016-08-19 21:29:31 -07002696SelectExpression SelectExpression(boolean subquery) throws ParseException:
2697{
Yingyi Bu391f09e2015-10-29 13:49:39 -07002698 List<LetClause> letClauses = new ArrayList<LetClause>();
2699 SelectSetOperation selectSetOperation;
2700 OrderbyClause orderbyClause = null;
2701 LimitClause limitClause = null;
2702 createNewScope();
Yingyi Buab817482016-08-19 21:29:31 -07002703}
2704{
Yingyi Bu391f09e2015-10-29 13:49:39 -07002705 ( letClauses = LetClause() )?
2706 selectSetOperation = SelectSetOperation()
2707 (orderbyClause = OrderbyClause() {})?
2708 (limitClause = LimitClause() {})?
2709 {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002710 SelectExpression selectExpr =
2711 new SelectExpression(letClauses, selectSetOperation, orderbyClause, limitClause, subquery);
2712 selectExpr.setSourceLocation((!letClauses.isEmpty() ? letClauses.get(0) : selectSetOperation).getSourceLocation());
2713 return selectExpr;
Yingyi Bu391f09e2015-10-29 13:49:39 -07002714 }
2715}
2716
Yingyi Buab817482016-08-19 21:29:31 -07002717SelectSetOperation SelectSetOperation() throws ParseException:
2718{
Yingyi Bu391f09e2015-10-29 13:49:39 -07002719 SetOperationInput setOperationInputLeft;
2720 List<SetOperationRight> setOperationRights = new ArrayList<SetOperationRight>();
2721}
2722{
2723 {
2724 SelectBlock selectBlockLeft = null;
2725 SelectExpression subqueryLeft = null;
2726 Expression expr = null;
2727 }
2728 selectBlockLeft = SelectBlock()
2729 {
2730 setOperationInputLeft = new SetOperationInput(selectBlockLeft, subqueryLeft);
2731 }
2732 (
2733 {
2734 SetOpType opType = SetOpType.UNION;
2735 boolean setSemantics = true;
2736 SelectBlock selectBlockRight = null;
2737 SelectExpression subqueryRight = null;
2738 }
2739 (<UNION> {opType = SetOpType.UNION;} |<INTERSECT> {opType = SetOpType.INTERSECT;} |<EXCEPT> {opType = SetOpType.EXCEPT;}) (<ALL> {setSemantics = false;} )?
2740 (selectBlockRight = SelectBlock()| subqueryRight = Subquery())
2741 {
2742 setOperationRights.add(new SetOperationRight(opType, setSemantics, new SetOperationInput(selectBlockRight, subqueryRight)));
2743 }
2744 )*
2745 {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002746 SelectSetOperation selectSetOp = new SelectSetOperation(setOperationInputLeft, setOperationRights);
2747 selectSetOp.setSourceLocation(selectBlockLeft.getSourceLocation());
2748 return selectSetOp;
Yingyi Bu391f09e2015-10-29 13:49:39 -07002749 }
2750}
2751
Yingyi Buab817482016-08-19 21:29:31 -07002752SelectExpression Subquery() throws ParseException:
2753{
Yingyi Bu391f09e2015-10-29 13:49:39 -07002754 SelectExpression selectExpr = null;
2755}
2756{
2757 <LEFTPAREN> selectExpr = SelectExpression(true) {} <RIGHTPAREN>
2758 {
2759 return selectExpr;
2760 }
2761}
2762
Yingyi Buab817482016-08-19 21:29:31 -07002763SelectBlock SelectBlock() throws ParseException:
2764{
Yingyi Bu391f09e2015-10-29 13:49:39 -07002765 SelectClause selectClause = null;
2766 FromClause fromClause = null;
2767 List<LetClause> fromLetClauses = null;
2768 WhereClause whereClause = null;
2769 GroupbyClause groupbyClause = null;
2770 List<LetClause> gbyLetClauses = null;
2771 HavingClause havingClause = null;
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002772 SourceLocation startSrcLoc = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07002773}
2774{
2775 (
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002776 selectClause = SelectClause() { startSrcLoc = selectClause.getSourceLocation(); }
Yingyi Bu391f09e2015-10-29 13:49:39 -07002777 (
2778 LOOKAHEAD(1)
2779 fromClause = FromClause()
2780 (
2781 LOOKAHEAD(1)
2782 fromLetClauses = LetClause()
2783 )?
2784 )?
2785 (whereClause = WhereClause())?
2786 (
2787 groupbyClause = GroupbyClause()
2788 (
2789 LOOKAHEAD(1)
2790 gbyLetClauses = LetClause()
2791 )?
2792 (havingClause = HavingClause())?
2793 )?
2794 |
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002795 fromClause = FromClause() { startSrcLoc = fromClause.getSourceLocation(); }
Yingyi Bu391f09e2015-10-29 13:49:39 -07002796 (
2797 LOOKAHEAD(1)
2798 fromLetClauses = LetClause()
2799 )?
2800 (whereClause = WhereClause())?
2801 (
2802 groupbyClause = GroupbyClause()
2803 (
2804 gbyLetClauses = LetClause()
2805 )?
2806 (havingClause = HavingClause())?
2807 )?
2808 selectClause = SelectClause()
2809 )
2810 {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002811 SelectBlock selectBlock = new SelectBlock(selectClause, fromClause, fromLetClauses, whereClause, groupbyClause,
2812 gbyLetClauses, havingClause);
2813 selectBlock.setSourceLocation(startSrcLoc);
2814 return selectBlock;
Yingyi Bu391f09e2015-10-29 13:49:39 -07002815 }
2816}
2817
Yingyi Buab817482016-08-19 21:29:31 -07002818SelectClause SelectClause() throws ParseException:
2819{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002820 Token startToken = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07002821 SelectRegular selectRegular = null;
2822 SelectElement selectElement = null;
2823 boolean distinct = false;
2824}
2825{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002826 <SELECT> { startToken = token; } (<ALL>|<DISTINCT> { distinct = true; } )?
Yingyi Bu391f09e2015-10-29 13:49:39 -07002827 (
2828 selectRegular = SelectRegular()
Michael Blowd6cf6412016-06-30 02:44:35 -04002829 |
Yingyi Bu391f09e2015-10-29 13:49:39 -07002830 selectElement = SelectElement()
Yingyi Bua89fae62016-07-06 07:58:55 -07002831 )?
Yingyi Bu391f09e2015-10-29 13:49:39 -07002832 {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002833 SourceLocation sourceLoc = getSourceLocation(startToken);
2834 if (selectRegular == null && selectElement == null){
Yingyi Bua89fae62016-07-06 07:58:55 -07002835 Projection projection = new Projection(null, null, true, false);
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002836 projection.setSourceLocation(sourceLoc);
Yingyi Bua89fae62016-07-06 07:58:55 -07002837 List<Projection> projections = new ArrayList<Projection>();
2838 projections.add(projection);
2839 selectRegular = new SelectRegular(projections);
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002840 selectRegular.setSourceLocation(sourceLoc);
Yingyi Bua89fae62016-07-06 07:58:55 -07002841 }
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002842 SelectClause selectClause = new SelectClause(selectElement, selectRegular, distinct);
2843 selectClause.setSourceLocation(sourceLoc);
2844 return selectClause;
Yingyi Bu391f09e2015-10-29 13:49:39 -07002845 }
2846}
2847
Yingyi Buab817482016-08-19 21:29:31 -07002848SelectRegular SelectRegular() throws ParseException:
2849{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002850 SourceLocation startSrcLoc = null;
Michael Blowd6cf6412016-06-30 02:44:35 -04002851 List<Projection> projections = new ArrayList<Projection>();
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002852 Projection projection = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07002853}
2854{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002855 projection = Projection()
Yingyi Bu391f09e2015-10-29 13:49:39 -07002856 {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002857 projections.add(projection);
2858 startSrcLoc = projection.getSourceLocation();
2859 }
2860 ( LOOKAHEAD(2) <COMMA> projection = Projection()
2861 {
2862 projections.add(projection);
2863 }
2864 )*
2865 {
2866 SelectRegular selectRegular = new SelectRegular(projections);
2867 selectRegular.setSourceLocation(startSrcLoc);
2868 return selectRegular;
Yingyi Bu391f09e2015-10-29 13:49:39 -07002869 }
2870}
2871
Yingyi Buab817482016-08-19 21:29:31 -07002872SelectElement SelectElement() throws ParseException:
2873{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002874 Token startToken = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07002875 Expression expr = null;
2876 String name = null;
2877}
2878{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002879 (<RAW>|<ELEMENT>|<VALUE>) { startToken = token; } expr = Expression()
Yingyi Bu391f09e2015-10-29 13:49:39 -07002880 {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002881 SelectElement selectElement = new SelectElement(expr);
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07002882 return addSourceLocation(selectElement, startToken);
Yingyi Bu391f09e2015-10-29 13:49:39 -07002883 }
2884}
2885
Yingyi Buab817482016-08-19 21:29:31 -07002886Projection Projection() throws ParseException :
2887{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002888 SourceLocation startSrcLoc = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07002889 Expression expr = null;
2890 Identifier identifier = null;
2891 String name = null;
2892 boolean star = false;
Dmitry Lychagin5cdaa5d2018-02-21 11:11:26 -08002893 boolean varStar = false;
Yingyi Bu391f09e2015-10-29 13:49:39 -07002894}
2895{
2896 (
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002897 <MUL> { star = true; startSrcLoc = getSourceLocation(token); }
2898 | LOOKAHEAD(3) expr = VariableRef() <DOT> <MUL> { varStar = true; }
Dmitry Lychagin5cdaa5d2018-02-21 11:11:26 -08002899 | expr = Expression() ((<AS>)? name = Identifier())?
2900 {
2901 if (name == null) {
2902 String generatedColumnIdentifier = ExpressionToVariableUtil.getGeneratedIdentifier(expr, false);
2903 if (generatedColumnIdentifier != null) {
2904 name = SqlppVariableUtil.toUserDefinedName(generatedColumnIdentifier);
2905 }
2906 }
2907 }
Yingyi Bu391f09e2015-10-29 13:49:39 -07002908 )
2909 {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002910 Projection projection = new Projection(expr, name, star, varStar);
2911 projection.setSourceLocation(expr != null ? expr.getSourceLocation() : startSrcLoc);
2912 return projection;
Yingyi Bu391f09e2015-10-29 13:49:39 -07002913 }
2914}
2915
2916FromClause FromClause() throws ParseException :
2917{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002918 Token startToken = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07002919 List<FromTerm> fromTerms = new ArrayList<FromTerm>();
2920 extendCurrentScope();
2921}
2922{
2923 {
2924 FromTerm fromTerm = null;
2925 }
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002926 <FROM> { startToken = token; } fromTerm = FromTerm() { fromTerms.add(fromTerm); }
Yingyi Bu391f09e2015-10-29 13:49:39 -07002927 (LOOKAHEAD(2) <COMMA> fromTerm = FromTerm() { fromTerms.add(fromTerm); } )*
2928 {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002929 FromClause fromClause = new FromClause(fromTerms);
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07002930 return addSourceLocation(fromClause, startToken);
Yingyi Bu391f09e2015-10-29 13:49:39 -07002931 }
2932}
2933
2934FromTerm FromTerm() throws ParseException :
2935{
2936 Expression leftExpr = null;
Michael Blowd6cf6412016-06-30 02:44:35 -04002937 VariableExpr leftVar = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07002938 VariableExpr posVar = null;
2939 List<AbstractBinaryCorrelateClause> correlateClauses = new ArrayList<AbstractBinaryCorrelateClause>();
2940}
2941{
Yingyi Bu9e3f9be2016-07-01 10:07:37 -07002942 leftExpr = Expression() ((<AS>)? leftVar = Variable())? (<AT> posVar = Variable())?
Yingyi Bu391f09e2015-10-29 13:49:39 -07002943 (
2944 {JoinType joinType = JoinType.INNER; }
2945 (joinType = JoinType())?
2946 {
2947 AbstractBinaryCorrelateClause correlateClause = null;
2948 }
2949 (correlateClause = JoinClause(joinType)
Yingyi Bu6d999ed2016-07-13 11:59:06 -07002950 | correlateClause = UnnestClause(joinType)
Yingyi Bu391f09e2015-10-29 13:49:39 -07002951 )
2952 {
2953 correlateClauses.add(correlateClause);
2954 }
2955 )*
2956 {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002957 if (leftVar == null) {
Yingyi Bu5b2d4c82016-07-13 17:56:48 -07002958 leftVar = ExpressionToVariableUtil.getGeneratedVariable(leftExpr, true);
Yingyi Bu9e3f9be2016-07-01 10:07:37 -07002959 }
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002960 FromTerm fromTerm = new FromTerm(leftExpr, leftVar, posVar, correlateClauses);
2961 fromTerm.setSourceLocation(leftExpr.getSourceLocation());
2962 return fromTerm;
Yingyi Bu391f09e2015-10-29 13:49:39 -07002963 }
2964}
2965
2966JoinClause JoinClause(JoinType joinType) throws ParseException :
2967{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002968 Token startToken = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07002969 Expression rightExpr = null;
2970 VariableExpr rightVar = null;
2971 VariableExpr posVar = null;
2972 Expression conditionExpr = null;
2973}
2974{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002975 <JOIN> { startToken = token; } rightExpr = Expression() ((<AS>)? rightVar = Variable())? (<AT> posVar = Variable())? <ON> conditionExpr = Expression()
Yingyi Bu391f09e2015-10-29 13:49:39 -07002976 {
Yingyi Bu9e3f9be2016-07-01 10:07:37 -07002977 if(rightVar==null){
Yingyi Bu5b2d4c82016-07-13 17:56:48 -07002978 rightVar = ExpressionToVariableUtil.getGeneratedVariable(rightExpr, true);
Yingyi Bu9e3f9be2016-07-01 10:07:37 -07002979 }
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002980 JoinClause joinClause = new JoinClause(joinType, rightExpr, rightVar, posVar, conditionExpr);
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07002981 return addSourceLocation(joinClause, startToken);
Yingyi Bu391f09e2015-10-29 13:49:39 -07002982 }
2983}
2984
Yingyi Bu391f09e2015-10-29 13:49:39 -07002985UnnestClause UnnestClause(JoinType joinType) throws ParseException :
2986{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002987 Token startToken = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07002988 Expression rightExpr;
2989 VariableExpr rightVar;
2990 VariableExpr posVar = null;
2991}
2992{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002993 (<UNNEST>|<CORRELATE>|<FLATTEN>) { startToken = token; } rightExpr = Expression() ((<AS>)? rightVar = Variable()) (<AT> posVar = Variable())?
Yingyi Bu391f09e2015-10-29 13:49:39 -07002994 {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002995 if (rightVar == null) {
2996 rightVar = ExpressionToVariableUtil.getGeneratedVariable(rightExpr, true);
Yingyi Bu9e3f9be2016-07-01 10:07:37 -07002997 }
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002998 UnnestClause unnestClause = new UnnestClause(joinType, rightExpr, rightVar, posVar);
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07002999 return addSourceLocation(unnestClause, startToken);
Yingyi Bu391f09e2015-10-29 13:49:39 -07003000 }
3001}
3002
Yingyi Bu391f09e2015-10-29 13:49:39 -07003003JoinType JoinType() throws ParseException :
3004{
3005 JoinType joinType = JoinType.INNER;
3006}
3007{
3008 (<INNER>|<LEFT> (<OUTER>)? {joinType = JoinType.LEFTOUTER; })
3009 {
3010 return joinType;
3011 }
3012}
3013
3014List<LetClause> LetClause() throws ParseException:
3015{
3016 List<LetClause> letList = new ArrayList<LetClause>();
3017 LetClause letClause;
3018}
3019{
3020 (
3021 (<LET>|<LETTING>) letClause = LetElement() { letList.add(letClause); } (LOOKAHEAD(1) <COMMA> letClause = LetElement() { letList.add(letClause); })*
3022 |
3023 <WITH> letClause = WithElement() { letList.add(letClause); } (LOOKAHEAD(1) <COMMA> letClause = WithElement() { letList.add(letClause); })*
3024 )
3025 {
3026 return letList;
3027 }
3028}
3029
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07003030WhereClause WhereClause() throws ParseException :
Yingyi Bu391f09e2015-10-29 13:49:39 -07003031{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07003032 Token startToken = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07003033 Expression whereExpr;
3034}
3035{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07003036 <WHERE> { startToken = token; } whereExpr = Expression()
Yingyi Bu391f09e2015-10-29 13:49:39 -07003037 {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07003038 WhereClause wc = new WhereClause(whereExpr);
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07003039 return addSourceLocation(wc, startToken);
Yingyi Bu391f09e2015-10-29 13:49:39 -07003040 }
3041}
3042
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07003043OrderbyClause OrderbyClause() throws ParseException :
Yingyi Bu391f09e2015-10-29 13:49:39 -07003044{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07003045 Token startToken = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07003046 OrderbyClause oc = new OrderbyClause();
3047 Expression orderbyExpr;
3048 List<Expression> orderbyList = new ArrayList<Expression>();
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07003049 List<OrderbyClause.OrderModifier> modifierList = new ArrayList<OrderbyClause.OrderModifier>();
Yingyi Bu391f09e2015-10-29 13:49:39 -07003050 int numOfOrderby = 0;
3051}
3052{
3053 <ORDER>
3054 {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07003055 startToken = token;
Yingyi Bu391f09e2015-10-29 13:49:39 -07003056 String hint = getHint(token);
3057 if (hint != null) {
3058 if (hint.startsWith(INMEMORY_HINT)) {
3059 String splits[] = hint.split(" +");
3060 int numFrames = Integer.parseInt(splits[1]);
3061 int numTuples = Integer.parseInt(splits[2]);
3062 oc.setNumFrames(numFrames);
3063 oc.setNumTuples(numTuples);
3064 }
3065 }
3066 }
3067 <BY> orderbyExpr = Expression()
3068 {
3069 orderbyList.add(orderbyExpr);
3070 OrderbyClause.OrderModifier modif = OrderbyClause.OrderModifier.ASC;
3071 }
3072 ( (<ASC> { modif = OrderbyClause.OrderModifier.ASC; })
3073 | (<DESC> { modif = OrderbyClause.OrderModifier.DESC; }))?
3074 {
3075 modifierList.add(modif);
3076 }
3077
3078 (LOOKAHEAD(2) <COMMA> orderbyExpr = Expression()
3079 {
3080 orderbyList.add(orderbyExpr);
3081 modif = OrderbyClause.OrderModifier.ASC;
3082 }
3083 ( (<ASC> { modif = OrderbyClause.OrderModifier.ASC; })
3084 | (<DESC> { modif = OrderbyClause.OrderModifier.DESC; }))?
3085 {
3086 modifierList.add(modif);
3087 }
3088 )*
3089
3090 {
3091 oc.setModifierList(modifierList);
3092 oc.setOrderbyList(orderbyList);
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07003093 return addSourceLocation(oc, startToken);
Yingyi Bu391f09e2015-10-29 13:49:39 -07003094 }
3095}
3096
3097GroupbyClause GroupbyClause()throws ParseException :
3098{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07003099 Token startToken = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07003100 GroupbyClause gbc = new GroupbyClause();
3101 List<GbyVariableExpressionPair> vePairList = new ArrayList<GbyVariableExpressionPair>();
3102 VariableExpr var = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07003103 Expression expr = null;
3104 VariableExpr decorVar = null;
3105 Expression decorExpr = null;
Yingyi Buacc12a92016-03-26 17:25:05 -07003106
3107 VariableExpr groupVar = null;
3108 List<Pair<Expression, Identifier>> groupFieldList = new ArrayList<Pair<Expression, Identifier>>();
Yingyi Bu391f09e2015-10-29 13:49:39 -07003109}
3110{
3111 {
3112 Scope newScope = extendCurrentScopeNoPush(true);
3113 // extendCurrentScope(true);
3114 }
3115 <GROUP>
3116 {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07003117 startToken = token;
Yingyi Bu391f09e2015-10-29 13:49:39 -07003118 String hint = getHint(token);
3119 if (hint != null && hint.equals(HASH_GROUP_BY_HINT)) {
3120 gbc.setHashGroupByHint(true);
3121 }
3122 }
3123 <BY> (
3124 expr = Expression()
3125 (LOOKAHEAD(1) (<AS>)?
3126 var = Variable()
Yingyi Bucaea8f02015-11-16 15:12:15 -08003127 )?
Yingyi Bu391f09e2015-10-29 13:49:39 -07003128 {
Yingyi Bu9e3f9be2016-07-01 10:07:37 -07003129 if(var==null){
Yingyi Bu5b2d4c82016-07-13 17:56:48 -07003130 var = ExpressionToVariableUtil.getGeneratedVariable(expr, false);
Yingyi Bu9e3f9be2016-07-01 10:07:37 -07003131 }
Yingyi Bu391f09e2015-10-29 13:49:39 -07003132 GbyVariableExpressionPair pair1 = new GbyVariableExpressionPair(var, expr);
3133 vePairList.add(pair1);
3134 }
3135 ( LOOKAHEAD(1) <COMMA>
Yingyi Bu9e3f9be2016-07-01 10:07:37 -07003136 {
3137 var = null;
3138 }
Yingyi Bu391f09e2015-10-29 13:49:39 -07003139 expr = Expression()
3140 (LOOKAHEAD(1) (<AS>)?
3141 var = Variable()
Yingyi Bucaea8f02015-11-16 15:12:15 -08003142 )?
Yingyi Bu391f09e2015-10-29 13:49:39 -07003143 {
Yingyi Bu9e3f9be2016-07-01 10:07:37 -07003144 if(var==null){
Yingyi Bu5b2d4c82016-07-13 17:56:48 -07003145 var = ExpressionToVariableUtil.getGeneratedVariable(expr, false);
Yingyi Bu9e3f9be2016-07-01 10:07:37 -07003146 }
Yingyi Bu391f09e2015-10-29 13:49:39 -07003147 GbyVariableExpressionPair pair2 = new GbyVariableExpressionPair(var, expr);
3148 vePairList.add(pair2);
3149 }
3150 )*
3151 )
Yingyi Buacc12a92016-03-26 17:25:05 -07003152 (<GROUP> <AS> groupVar = Variable()
3153 ( LOOKAHEAD(1)
3154 {
3155 VariableExpr fieldVarExpr = null;
3156 String fieldIdentifierStr = null;
3157 }
3158 <LEFTPAREN>
3159 fieldVarExpr = VariableRef() <AS> fieldIdentifierStr = Identifier()
3160 {
3161 groupFieldList.add(new Pair<Expression, Identifier>(fieldVarExpr, new Identifier(fieldIdentifierStr)));
3162 }
3163 (<COMMA>
3164 fieldVarExpr = VariableRef() <AS> fieldIdentifierStr = Identifier()
3165 {
3166 groupFieldList.add(new Pair<Expression, Identifier>(fieldVarExpr, new Identifier(fieldIdentifierStr)));
3167 }
3168 )*
3169 <RIGHTPAREN>
3170 )?
3171 )?
Yingyi Bu391f09e2015-10-29 13:49:39 -07003172 {
3173 gbc.setGbyPairList(vePairList);
3174 gbc.setDecorPairList(new ArrayList<GbyVariableExpressionPair>());
Yingyi Bu8671ddf2016-08-14 23:58:43 -07003175 gbc.setWithVarMap(new HashMap<Expression, VariableExpr>());
Yingyi Buacc12a92016-03-26 17:25:05 -07003176 gbc.setGroupVar(groupVar);
3177 gbc.setGroupFieldList(groupFieldList);
Yingyi Bu391f09e2015-10-29 13:49:39 -07003178 replaceCurrentScope(newScope);
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07003179 return addSourceLocation(gbc, startToken);
Yingyi Bu391f09e2015-10-29 13:49:39 -07003180 }
3181}
3182
3183HavingClause HavingClause() throws ParseException:
3184{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07003185 Token startToken = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07003186 Expression filterExpr = null;
3187}
3188{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07003189 <HAVING> { startToken = token; } filterExpr = Expression()
Yingyi Bu391f09e2015-10-29 13:49:39 -07003190 {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07003191 HavingClause havingClause = new HavingClause(filterExpr);
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07003192 return addSourceLocation(havingClause, startToken);
Yingyi Bu391f09e2015-10-29 13:49:39 -07003193 }
3194}
3195
3196LimitClause LimitClause() throws ParseException:
3197{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07003198 Token startToken = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07003199 LimitClause lc = new LimitClause();
3200 Expression expr;
3201 pushForbiddenScope(getCurrentScope());
3202}
3203{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07003204 <LIMIT> { startToken = token; } expr = Expression() { lc.setLimitExpr(expr); }
3205 (<OFFSET> expr = Expression() { lc.setOffset(expr); })?
Yingyi Bu391f09e2015-10-29 13:49:39 -07003206
3207 {
3208 popForbiddenScope();
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07003209 return addSourceLocation(lc, startToken);
Yingyi Bu391f09e2015-10-29 13:49:39 -07003210 }
3211}
3212
3213QuantifiedExpression QuantifiedExpression()throws ParseException:
3214{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07003215 Token startToken = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07003216 QuantifiedExpression qc = new QuantifiedExpression();
3217 List<QuantifiedPair> quantifiedList = new ArrayList<QuantifiedPair>();
3218 Expression satisfiesExpr;
3219 VariableExpr var;
3220 Expression inExpr;
3221 QuantifiedPair pair;
3222}
3223{
3224 {
3225 createNewScope();
3226 }
3227
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07003228 ( ((<ANY>|<SOME>) { startToken = token; qc.setQuantifier(QuantifiedExpression.Quantifier.SOME); })
3229 | (<EVERY> { startToken = token; qc.setQuantifier(QuantifiedExpression.Quantifier.EVERY); }))
Yingyi Bu391f09e2015-10-29 13:49:39 -07003230 var = Variable() <IN> inExpr = Expression()
3231 {
3232 pair = new QuantifiedPair(var, inExpr);
Yingyi Bu391f09e2015-10-29 13:49:39 -07003233 quantifiedList.add(pair);
3234 }
3235 (
3236 <COMMA> var = Variable() <IN> inExpr = Expression()
3237 {
3238 pair = new QuantifiedPair(var, inExpr);
Yingyi Bu391f09e2015-10-29 13:49:39 -07003239 quantifiedList.add(pair);
3240 }
3241 )*
Yingyi Bu858efae2016-10-13 17:31:57 -07003242 <SATISFIES> satisfiesExpr = Expression() (<END>)?
Yingyi Bu391f09e2015-10-29 13:49:39 -07003243 {
3244 qc.setSatisfiesExpr(satisfiesExpr);
3245 qc.setQuantifiedList(quantifiedList);
3246 removeCurrentScope();
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07003247 return addSourceLocation(qc, startToken);
Yingyi Bu391f09e2015-10-29 13:49:39 -07003248 }
3249}
3250
3251LetClause LetElement() throws ParseException:
3252{
Yingyi Bu391f09e2015-10-29 13:49:39 -07003253 VariableExpr varExp;
3254 Expression beExp;
3255 extendCurrentScope();
3256}
3257{
3258 varExp = Variable() <EQ> beExp = Expression()
3259 {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07003260 LetClause lc = new LetClause(varExp, beExp);
3261 lc.setSourceLocation(varExp.getSourceLocation());
Yingyi Bu391f09e2015-10-29 13:49:39 -07003262 return lc;
3263 }
3264}
3265
3266LetClause WithElement() throws ParseException:
3267{
Yingyi Bu391f09e2015-10-29 13:49:39 -07003268 VariableExpr varExp;
3269 Expression beExp;
3270 extendCurrentScope();
3271}
3272{
3273 varExp = Variable() <AS> beExp = Expression()
3274 {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07003275 LetClause lc = new LetClause(varExp, beExp);
3276 lc.setSourceLocation(varExp.getSourceLocation());
Yingyi Bu391f09e2015-10-29 13:49:39 -07003277 return lc;
3278 }
3279}
3280
3281TOKEN_MGR_DECLS:
3282{
3283 public int commentDepth = 0;
Till Westmanne9b2adf2016-10-15 12:39:01 -07003284 public ArrayDeque<Integer> lexerStateStack = new ArrayDeque<Integer>();
Yingyi Bu391f09e2015-10-29 13:49:39 -07003285
3286 public void pushState() {
3287 lexerStateStack.push( curLexState );
3288 }
3289
3290 public void popState(String token) {
3291 if (lexerStateStack.size() > 0) {
3292 SwitchTo( lexerStateStack.pop() );
3293 } else {
3294 int errorLine = input_stream.getEndLine();
3295 int errorColumn = input_stream.getEndColumn();
3296 String msg = "Lexical error at line " + errorLine + ", column " + errorColumn + ". Encountered \"" + token
3297 + "\" but state stack is empty.";
3298 throw new TokenMgrError(msg, -1);
3299 }
3300 }
3301}
3302
3303<DEFAULT,IN_DBL_BRACE>
3304TOKEN [IGNORE_CASE]:
3305{
3306 <ALL : "all">
3307 | <AND : "and">
Yingyi Bu8aac7242016-09-13 23:14:09 -07003308 | <ANY : "any">
Yingyi Bu391f09e2015-10-29 13:49:39 -07003309 | <APPLY : "apply">
3310 | <AS : "as">
3311 | <ASC : "asc">
3312 | <AT : "at">
3313 | <AUTOGENERATED : "autogenerated">
Yingyi Bua8baf6d2016-07-05 21:40:44 -07003314 | <BETWEEN : "between">
Yingyi Bu391f09e2015-10-29 13:49:39 -07003315 | <BTREE : "btree">
3316 | <BY : "by">
3317 | <CASE : "case">
3318 | <CLOSED : "closed">
3319 | <CREATE : "create">
3320 | <COMPACTION : "compaction">
3321 | <COMPACT : "compact">
3322 | <CONNECT : "connect">
3323 | <CORRELATE : "correlate">
Yingyi Bud56ff032016-08-01 10:26:57 -07003324 | <DATASET : "dataset">
Yingyi Bu1c0fff52016-03-25 20:23:30 -07003325 | <COLLECTION : "collection">
Yingyi Bud56ff032016-08-01 10:26:57 -07003326 | <DATAVERSE : "dataverse">
Yingyi Bu391f09e2015-10-29 13:49:39 -07003327 | <DECLARE : "declare">
3328 | <DEFINITION : "definition">
3329 | <DELETE : "delete">
3330 | <DESC : "desc">
3331 | <DISCONNECT : "disconnect">
3332 | <DISTINCT : "distinct">
3333 | <DROP : "drop">
3334 | <ELEMENT : "element">
Till Westmann516d1a82016-08-02 14:45:53 -07003335 | <EXPLAIN : "explain">
Yingyi Bu391f09e2015-10-29 13:49:39 -07003336 | <ELSE : "else">
3337 | <ENFORCED : "enforced">
Yingyi Buc8c067c2016-07-25 23:37:19 -07003338 | <END : "end">
Yingyi Bu391f09e2015-10-29 13:49:39 -07003339 | <EVERY : "every">
3340 | <EXCEPT : "except">
3341 | <EXISTS : "exists">
3342 | <EXTERNAL : "external">
3343 | <FEED : "feed">
3344 | <FILTER : "filter">
3345 | <FLATTEN : "flatten">
3346 | <FOR : "for">
Yingyi Bu391f09e2015-10-29 13:49:39 -07003347 | <FROM : "from">
3348 | <FULL : "full">
Taewoo Kimc49405a2017-01-04 00:30:43 -08003349 | <FULLTEXT : "fulltext">
Yingyi Bu391f09e2015-10-29 13:49:39 -07003350 | <FUNCTION : "function">
3351 | <GROUP : "group">
3352 | <HAVING : "having">
3353 | <HINTS : "hints">
3354 | <IF : "if">
3355 | <INTO : "into">
3356 | <IN : "in">
3357 | <INDEX : "index">
3358 | <INGESTION : "ingestion">
3359 | <INNER : "inner">
3360 | <INSERT : "insert">
3361 | <INTERNAL : "internal">
3362 | <INTERSECT : "intersect">
Yingyi Budaa549c2016-06-28 22:30:52 -07003363 | <IS : "is">
Yingyi Bu391f09e2015-10-29 13:49:39 -07003364 | <JOIN : "join">
3365 | <KEYWORD : "keyword">
3366 | <KEY : "key">
Dmitry Lychagin1aa0dd42018-04-17 14:35:24 -07003367 | <KNOWN : "known">
Yingyi Bu391f09e2015-10-29 13:49:39 -07003368 | <LEFT : "left">
3369 | <LETTING : "letting">
3370 | <LET : "let">
Yingyi Bua8baf6d2016-07-05 21:40:44 -07003371 | <LIKE : "like">
Yingyi Bu391f09e2015-10-29 13:49:39 -07003372 | <LIMIT : "limit">
3373 | <LOAD : "load">
Yingyi Bu391f09e2015-10-29 13:49:39 -07003374 | <NODEGROUP : "nodegroup">
3375 | <NGRAM : "ngram">
Yingyi Budaa549c2016-06-28 22:30:52 -07003376 | <NOT : "not">
Yingyi Bu391f09e2015-10-29 13:49:39 -07003377 | <OFFSET : "offset">
3378 | <ON : "on">
3379 | <OPEN : "open">
3380 | <OR : "or">
3381 | <ORDER : "order">
3382 | <OUTER : "outer">
3383 | <OUTPUT : "output">
3384 | <PATH : "path">
3385 | <POLICY : "policy">
3386 | <PRESORTED : "pre-sorted">
3387 | <PRIMARY : "primary">
3388 | <RAW : "raw">
3389 | <REFRESH : "refresh">
3390 | <RETURN : "return">
Yingyi Bucb5bf332017-01-02 22:19:50 -08003391 | <RETURNING : "returning">
Yingyi Bu391f09e2015-10-29 13:49:39 -07003392 | <RTREE : "rtree">
3393 | <RUN : "run">
3394 | <SATISFIES : "satisfies">
3395 | <SECONDARY : "secondary">
3396 | <SELECT : "select">
3397 | <SET : "set">
3398 | <SOME : "some">
Abdullah Alamoudifff200c2017-02-18 20:32:14 -08003399 | <START : "start">
3400 | <STOP : "stop">
Murtadha Hubail2c04ae02017-11-21 15:58:01 +03003401 | <TEMPORARY : "temporary"> // intentionally not used but reserved for future usage
Yingyi Bu391f09e2015-10-29 13:49:39 -07003402 | <THEN : "then">
3403 | <TYPE : "type">
3404 | <TO : "to">
3405 | <UNION : "union">
Dmitry Lychagin8b6578a2017-11-08 15:04:35 -08003406 | <UNKNOWN : "unknown">
Yingyi Bu391f09e2015-10-29 13:49:39 -07003407 | <UNNEST : "unnest">
Yingyi Budaa549c2016-06-28 22:30:52 -07003408 | <UPDATE : "update">
Yingyi Bucb5bf332017-01-02 22:19:50 -08003409 | <UPSERT : "upsert">
Yingyi Budaa549c2016-06-28 22:30:52 -07003410 | <USE : "use">
3411 | <USING : "using">
Yingyi Bu391f09e2015-10-29 13:49:39 -07003412 | <VALUE : "value">
Dmitry Lychagin7d594a32018-01-15 14:31:03 -08003413 | <VALUED : "valued">
Yingyi Bu391f09e2015-10-29 13:49:39 -07003414 | <WHEN : "when">
3415 | <WHERE : "where">
3416 | <WITH : "with">
3417 | <WRITE : "write">
Yingyi Bu391f09e2015-10-29 13:49:39 -07003418}
3419
3420<DEFAULT,IN_DBL_BRACE>
3421TOKEN :
3422{
3423 <CARET : "^">
Yingyi Bufdc71eb2016-08-24 22:41:57 -07003424 | <CONCAT : "||">
Dmitry Lychaginbf48c492018-05-01 18:30:27 -07003425 | <DIVIDE : "/">
3426 | <DIV : "div">
Yingyi Bu391f09e2015-10-29 13:49:39 -07003427 | <MINUS : "-">
Dmitry Lychaginbf48c492018-05-01 18:30:27 -07003428 | <MOD : "mod">
Yingyi Bu391f09e2015-10-29 13:49:39 -07003429 | <MUL : "*">
3430 | <PLUS : "+">
3431
3432 | <LEFTPAREN : "(">
3433 | <RIGHTPAREN : ")">
3434 | <LEFTBRACKET : "[">
3435 | <RIGHTBRACKET : "]">
3436
3437 | <ATT : "@">
3438 | <COLON : ":">
3439 | <COMMA : ",">
Dmitry Lychagin1bdf8082018-06-13 14:48:23 -07003440 | <DOLLAR: "$">
Yingyi Bu391f09e2015-10-29 13:49:39 -07003441 | <DOT : ".">
Dmitry Lychaginbf48c492018-05-01 18:30:27 -07003442 | <PERCENT: "%">
Yingyi Bu391f09e2015-10-29 13:49:39 -07003443 | <QUES : "?">
3444 | <SEMICOLON : ";">
3445 | <SHARP : "#">
3446
3447 | <LT : "<">
3448 | <GT : ">">
3449 | <LE : "<=">
3450 | <GE : ">=">
3451 | <EQ : "=">
3452 | <NE : "!=">
Yingyi Bu4a4b8962016-09-16 12:09:11 -07003453 | <LG : "<>">
Yingyi Bu391f09e2015-10-29 13:49:39 -07003454 | <SIMILAR : "~=">
3455}
3456
3457<DEFAULT,IN_DBL_BRACE>
3458TOKEN :
3459{
3460 <LEFTBRACE : "{"> { pushState(); } : DEFAULT
3461}
3462
3463<DEFAULT>
3464TOKEN :
3465{
3466 <RIGHTBRACE : "}"> { popState("}"); }
3467}
3468
3469<DEFAULT,IN_DBL_BRACE>
3470TOKEN :
3471{
3472 <LEFTDBLBRACE : "{{"> { pushState(); } : IN_DBL_BRACE
3473}
3474
3475<IN_DBL_BRACE>
3476TOKEN :
3477{
3478 <RIGHTDBLBRACE : "}}"> { popState("}}"); }
3479}
3480
3481<DEFAULT,IN_DBL_BRACE>
3482TOKEN :
3483{
3484 <INTEGER_LITERAL : (<DIGIT>)+ >
3485}
3486
3487<DEFAULT,IN_DBL_BRACE>
Yingyi Bue311a632016-06-07 18:23:16 -07003488TOKEN [IGNORE_CASE]:
Yingyi Bu391f09e2015-10-29 13:49:39 -07003489{
Dmitry Lychagin1bdf8082018-06-13 14:48:23 -07003490 <MISSING : "missing">
3491 | <NULL : "null">
Yingyi Bu391f09e2015-10-29 13:49:39 -07003492 | <TRUE : "true">
3493 | <FALSE : "false">
3494}
3495
3496<DEFAULT,IN_DBL_BRACE>
3497TOKEN :
3498{
3499 <#DIGIT : ["0" - "9"]>
3500}
3501
3502<DEFAULT,IN_DBL_BRACE>
3503TOKEN:
3504{
Dmitry Lychaginee8526b2018-03-30 14:21:01 -07003505 < DOUBLE_LITERAL: <DIGITS> ( "." <DIGITS> ) (("e"|"E") ("+"|"-")? <DIGITS>)?
3506 | <DIGITS> (("e"|"E") ("+"|"-")? <DIGITS>)
3507 | "." <DIGITS> (("e"|"E") ("+"|"-")? <DIGITS>)?
Yingyi Bu391f09e2015-10-29 13:49:39 -07003508 >
Yingyi Bue4d919e2016-10-30 10:47:03 -07003509 | < FLOAT_LITERAL: <DIGITS> ( "f" | "F" )
3510 | <DIGITS> ( "." <DIGITS> ( "f" | "F" ) )?
3511 | "." <DIGITS> ( "f" | "F" )
Yingyi Bu391f09e2015-10-29 13:49:39 -07003512 >
3513 | <DIGITS : (<DIGIT>)+ >
3514}
3515
3516<DEFAULT,IN_DBL_BRACE>
3517TOKEN :
3518{
3519 <#LETTER : ["A" - "Z", "a" - "z"]>
Dmitry Lychagin9c83efb2018-01-16 14:31:58 -08003520 | <#IDENTIFIER_SPECIALCHARS_START : ["_"]>
3521 | <#IDENTIFIER_SPECIALCHARS_REST : ["$"]>
Yingyi Bu391f09e2015-10-29 13:49:39 -07003522}
3523
3524<DEFAULT,IN_DBL_BRACE>
3525TOKEN :
3526{
3527 // backslash u + 4 hex digits escapes are handled in the underlying JavaCharStream
Yingyi Bu6d57e492016-06-06 21:24:42 -07003528 <QUOTED_STRING : "`" (
Yingyi Bu391f09e2015-10-29 13:49:39 -07003529 <EscapeQuot>
3530 | <EscapeBslash>
3531 | <EscapeSlash>
3532 | <EscapeBspace>
3533 | <EscapeFormf>
3534 | <EscapeNl>
3535 | <EscapeCr>
3536 | <EscapeTab>
Yingyi Bu6d57e492016-06-06 21:24:42 -07003537 | ~["`","\\"])* "`">
3538 | <STRING_LITERAL : ("\"" (
Yingyi Bu391f09e2015-10-29 13:49:39 -07003539 <EscapeQuot>
Yingyi Bu391f09e2015-10-29 13:49:39 -07003540 | <EscapeBslash>
3541 | <EscapeSlash>
3542 | <EscapeBspace>
3543 | <EscapeFormf>
3544 | <EscapeNl>
3545 | <EscapeCr>
3546 | <EscapeTab>
Yingyi Bu6d57e492016-06-06 21:24:42 -07003547 | ~["\"","\\"])* "\"")
3548 | ("\'"(
3549 <EscapeApos>
3550 | <EscapeBslash>
3551 | <EscapeSlash>
3552 | <EscapeBspace>
3553 | <EscapeFormf>
3554 | <EscapeNl>
3555 | <EscapeCr>
3556 | <EscapeTab>
3557 | ~["\'","\\"])* "\'")>
Yingyi Bu391f09e2015-10-29 13:49:39 -07003558 | < #EscapeQuot: "\\\"" >
3559 | < #EscapeApos: "\\\'" >
3560 | < #EscapeBslash: "\\\\" >
3561 | < #EscapeSlash: "\\/" >
3562 | < #EscapeBspace: "\\b" >
3563 | < #EscapeFormf: "\\f" >
3564 | < #EscapeNl: "\\n" >
3565 | < #EscapeCr: "\\r" >
3566 | < #EscapeTab: "\\t" >
3567}
3568
3569<DEFAULT,IN_DBL_BRACE>
3570TOKEN :
3571{
Dmitry Lychagin9c83efb2018-01-16 14:31:58 -08003572 <IDENTIFIER : ( <LETTER> | <IDENTIFIER_SPECIALCHARS_START> )
3573 ( <LETTER> | <DIGIT> | <IDENTIFIER_SPECIALCHARS_START> | <IDENTIFIER_SPECIALCHARS_REST> )*>
Yingyi Bu391f09e2015-10-29 13:49:39 -07003574}
3575
3576<DEFAULT,IN_DBL_BRACE>
3577SKIP:
3578{
3579 " "
3580 | "\t"
3581 | "\r"
3582 | "\n"
3583}
3584
3585<DEFAULT,IN_DBL_BRACE>
3586SKIP:
3587{
3588 <"//" (~["\n"])* "\n">
3589}
3590
3591<DEFAULT,IN_DBL_BRACE>
3592SKIP:
3593{
3594 <"//" (~["\n","\r"])* ("\n"|"\r"|"\r\n")?>
3595}
3596
3597<DEFAULT,IN_DBL_BRACE>
3598SKIP:
3599{
Yingyi Bu93846a72016-09-13 16:30:39 -07003600 <"--" (~["\n"])* "\n">
3601}
3602
3603
3604<DEFAULT,IN_DBL_BRACE>
3605SKIP:
3606{
3607 <"--" (~["\n","\r"])* ("\n"|"\r"|"\r\n")?>
3608}
3609
3610<DEFAULT,IN_DBL_BRACE>
3611SKIP:
3612{
Yingyi Bu391f09e2015-10-29 13:49:39 -07003613 <"/*"> { pushState(); } : INSIDE_COMMENT
3614}
3615
3616<INSIDE_COMMENT>
3617SPECIAL_TOKEN:
3618{
3619 <"+"(" ")*(~["*"])*>
3620}
3621
3622<INSIDE_COMMENT>
3623SKIP:
3624{
3625 <"/*"> { pushState(); }
3626}
3627
3628<INSIDE_COMMENT>
3629SKIP:
3630{
3631 <"*/"> { popState("*/"); }
3632 | <~[]>
3633}