blob: e19ee7a37820894cdb18b4cae99915298d7fc7eb [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;
Ali Alsuliman80225e22018-10-15 14:17:07 -070076import org.apache.asterix.lang.common.base.IParserFactory;
Yingyi Bu391f09e2015-10-29 13:49:39 -070077import org.apache.asterix.lang.common.base.Statement;
78import org.apache.asterix.lang.common.clause.GroupbyClause;
79import org.apache.asterix.lang.common.clause.LetClause;
80import org.apache.asterix.lang.common.clause.LimitClause;
81import org.apache.asterix.lang.common.clause.OrderbyClause;
82import org.apache.asterix.lang.common.clause.UpdateClause;
83import org.apache.asterix.lang.common.clause.WhereClause;
84import org.apache.asterix.lang.common.context.RootScopeFactory;
85import org.apache.asterix.lang.common.context.Scope;
86import org.apache.asterix.lang.common.expression.AbstractAccessor;
87import org.apache.asterix.lang.common.expression.CallExpr;
88import org.apache.asterix.lang.common.expression.FieldAccessor;
89import org.apache.asterix.lang.common.expression.FieldBinding;
90import org.apache.asterix.lang.common.expression.GbyVariableExpressionPair;
91import org.apache.asterix.lang.common.expression.IfExpr;
92import org.apache.asterix.lang.common.expression.IndexAccessor;
Dmitry Lychagin8ba59442017-06-16 14:19:45 -070093import org.apache.asterix.lang.common.expression.IndexedTypeExpression;
Yingyi Bu391f09e2015-10-29 13:49:39 -070094import org.apache.asterix.lang.common.expression.ListConstructor;
95import org.apache.asterix.lang.common.expression.LiteralExpr;
96import org.apache.asterix.lang.common.expression.OperatorExpr;
97import org.apache.asterix.lang.common.expression.OrderedListTypeDefinition;
98import org.apache.asterix.lang.common.expression.QuantifiedExpression;
99import org.apache.asterix.lang.common.expression.RecordConstructor;
100import org.apache.asterix.lang.common.expression.RecordTypeDefinition;
101import org.apache.asterix.lang.common.expression.TypeExpression;
102import org.apache.asterix.lang.common.expression.TypeReferenceExpression;
103import org.apache.asterix.lang.common.expression.UnaryExpr;
Yingyi Bu391f09e2015-10-29 13:49:39 -0700104import org.apache.asterix.lang.common.expression.UnorderedListTypeDefinition;
105import org.apache.asterix.lang.common.expression.VariableExpr;
106import org.apache.asterix.lang.common.literal.DoubleLiteral;
107import org.apache.asterix.lang.common.literal.FalseLiteral;
108import org.apache.asterix.lang.common.literal.FloatLiteral;
109import org.apache.asterix.lang.common.literal.LongIntegerLiteral;
Yingyi Bu535d86b2016-05-23 16:44:25 -0700110import org.apache.asterix.lang.common.literal.MissingLiteral;
Yingyi Bu391f09e2015-10-29 13:49:39 -0700111import org.apache.asterix.lang.common.literal.NullLiteral;
112import org.apache.asterix.lang.common.literal.StringLiteral;
113import org.apache.asterix.lang.common.literal.TrueLiteral;
114import org.apache.asterix.lang.common.parser.ScopeChecker;
115import org.apache.asterix.lang.common.statement.CompactStatement;
116import org.apache.asterix.lang.common.statement.ConnectFeedStatement;
Abdullah Alamoudifff200c2017-02-18 20:32:14 -0800117import org.apache.asterix.lang.common.statement.StartFeedStatement;
118import org.apache.asterix.lang.common.statement.StopFeedStatement;
Yingyi Bu391f09e2015-10-29 13:49:39 -0700119import org.apache.asterix.lang.common.statement.CreateDataverseStatement;
120import org.apache.asterix.lang.common.statement.CreateFeedPolicyStatement;
121import org.apache.asterix.lang.common.statement.CreateFeedStatement;
122import org.apache.asterix.lang.common.statement.CreateFunctionStatement;
123import org.apache.asterix.lang.common.statement.CreateIndexStatement;
Yingyi Bu391f09e2015-10-29 13:49:39 -0700124import org.apache.asterix.lang.common.statement.DatasetDecl;
125import org.apache.asterix.lang.common.statement.DataverseDecl;
126import org.apache.asterix.lang.common.statement.DataverseDropStatement;
127import org.apache.asterix.lang.common.statement.DeleteStatement;
128import org.apache.asterix.lang.common.statement.DisconnectFeedStatement;
Yingyi Buab817482016-08-19 21:29:31 -0700129import org.apache.asterix.lang.common.statement.DropDatasetStatement;
Yingyi Bu391f09e2015-10-29 13:49:39 -0700130import org.apache.asterix.lang.common.statement.ExternalDetailsDecl;
131import org.apache.asterix.lang.common.statement.FeedDropStatement;
Abdullah Alamoudi5dc73ed2016-07-28 05:03:13 +0300132import org.apache.asterix.lang.common.statement.FeedPolicyDropStatement;
Yingyi Bu391f09e2015-10-29 13:49:39 -0700133import org.apache.asterix.lang.common.statement.FunctionDecl;
134import org.apache.asterix.lang.common.statement.FunctionDropStatement;
135import org.apache.asterix.lang.common.statement.IndexDropStatement;
136import org.apache.asterix.lang.common.statement.InsertStatement;
137import org.apache.asterix.lang.common.statement.InternalDetailsDecl;
138import org.apache.asterix.lang.common.statement.LoadStatement;
139import org.apache.asterix.lang.common.statement.NodeGroupDropStatement;
140import org.apache.asterix.lang.common.statement.NodegroupDecl;
141import org.apache.asterix.lang.common.statement.Query;
142import org.apache.asterix.lang.common.statement.RefreshExternalDatasetStatement;
Yingyi Bu391f09e2015-10-29 13:49:39 -0700143import org.apache.asterix.lang.common.statement.SetStatement;
144import org.apache.asterix.lang.common.statement.TypeDecl;
145import org.apache.asterix.lang.common.statement.TypeDropStatement;
146import org.apache.asterix.lang.common.statement.UpdateStatement;
Yingyi Bucb5bf332017-01-02 22:19:50 -0800147import org.apache.asterix.lang.common.statement.UpsertStatement;
Yingyi Bu391f09e2015-10-29 13:49:39 -0700148import org.apache.asterix.lang.common.statement.WriteStatement;
149import org.apache.asterix.lang.common.struct.Identifier;
Dmitry Lychaginef1719e2017-12-15 08:33:07 -0800150import org.apache.asterix.lang.common.struct.OperatorType;
Yingyi Bu391f09e2015-10-29 13:49:39 -0700151import org.apache.asterix.lang.common.struct.QuantifiedPair;
152import org.apache.asterix.lang.common.struct.VarIdentifier;
Ali Alsuliman80225e22018-10-15 14:17:07 -0700153import org.apache.asterix.lang.common.util.RangeMapBuilder;
Yingyi Bu391f09e2015-10-29 13:49:39 -0700154import org.apache.asterix.lang.sqlpp.clause.AbstractBinaryCorrelateClause;
155import org.apache.asterix.lang.sqlpp.clause.FromClause;
156import org.apache.asterix.lang.sqlpp.clause.FromTerm;
157import org.apache.asterix.lang.sqlpp.clause.HavingClause;
158import org.apache.asterix.lang.sqlpp.clause.JoinClause;
Yingyi Bu391f09e2015-10-29 13:49:39 -0700159import org.apache.asterix.lang.sqlpp.clause.Projection;
160import org.apache.asterix.lang.sqlpp.clause.SelectBlock;
161import org.apache.asterix.lang.sqlpp.clause.SelectClause;
162import org.apache.asterix.lang.sqlpp.clause.SelectElement;
163import org.apache.asterix.lang.sqlpp.clause.SelectRegular;
164import org.apache.asterix.lang.sqlpp.clause.SelectSetOperation;
165import org.apache.asterix.lang.sqlpp.clause.UnnestClause;
Xikui Wangf6741682018-02-22 19:17:17 -0800166import org.apache.asterix.lang.common.clause.WhereClause;
Yingyi Buc8c067c2016-07-25 23:37:19 -0700167import org.apache.asterix.lang.sqlpp.expression.CaseExpression;
Yingyi Bu391f09e2015-10-29 13:49:39 -0700168import org.apache.asterix.lang.sqlpp.expression.SelectExpression;
Dmitry Lychaginfdedf622018-10-30 18:12:40 -0700169import org.apache.asterix.lang.sqlpp.expression.WindowExpression;
Yingyi Bu391f09e2015-10-29 13:49:39 -0700170import org.apache.asterix.lang.sqlpp.optype.JoinType;
171import org.apache.asterix.lang.sqlpp.optype.SetOpType;
172import org.apache.asterix.lang.sqlpp.struct.SetOperationInput;
173import org.apache.asterix.lang.sqlpp.struct.SetOperationRight;
Yingyi Bu9e3f9be2016-07-01 10:07:37 -0700174import org.apache.asterix.lang.sqlpp.util.ExpressionToVariableUtil;
Xikui Wang96fd4022017-04-10 14:23:31 -0700175import org.apache.asterix.lang.sqlpp.util.FunctionMapUtil;
Yingyi Buacc12a92016-03-26 17:25:05 -0700176import org.apache.asterix.lang.sqlpp.util.SqlppVariableUtil;
Dmitry Lychagin7c53fcf2017-11-07 12:07:41 -0800177import org.apache.asterix.om.functions.BuiltinFunctions;
Yingyi Bu391f09e2015-10-29 13:49:39 -0700178import org.apache.hyracks.algebricks.common.utils.Pair;
179import org.apache.hyracks.algebricks.common.utils.Triple;
Xikui Wang5a61b2a2018-01-02 14:14:03 -0800180import org.apache.hyracks.algebricks.common.exceptions.AlgebricksException;
Yingyi Bu391f09e2015-10-29 13:49:39 -0700181import org.apache.hyracks.algebricks.core.algebra.expressions.IExpressionAnnotation;
182import org.apache.hyracks.algebricks.core.algebra.expressions.IndexedNLJoinExpressionAnnotation;
183import org.apache.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
Dmitry Lychaginee54cc02018-05-25 19:26:18 -0700184import org.apache.hyracks.api.exceptions.SourceLocation;
Yingyi Bu391f09e2015-10-29 13:49:39 -0700185
Yingyi Bucaea8f02015-11-16 15:12:15 -0800186class SQLPPParser extends ScopeChecker implements IParser {
Yingyi Bu391f09e2015-10-29 13:49:39 -0700187
188 // optimizer hints
189 private static final String AUTO_HINT = "auto";
190 private static final String BROADCAST_JOIN_HINT = "bcast";
191 private static final String COMPOSE_VAL_FILES_HINT = "compose-val-files";
192 private static final String DATE_BETWEEN_YEARS_HINT = "date-between-years";
193 private static final String DATETIME_ADD_RAND_HOURS_HINT = "datetime-add-rand-hours";
194 private static final String DATETIME_BETWEEN_YEARS_HINT = "datetime-between-years";
195 private static final String HASH_GROUP_BY_HINT = "hash";
196 private static final String INDEXED_NESTED_LOOP_JOIN_HINT = "indexnl";
197 private static final String INMEMORY_HINT = "inmem";
198 private static final String INSERT_RAND_INT_HINT = "insert-rand-int";
199 private static final String INTERVAL_HINT = "interval";
200 private static final String LIST_HINT = "list";
201 private static final String LIST_VAL_FILE_HINT = "list-val-file";
202 private static final String RANGE_HINT = "range";
203 private static final String SKIP_SECONDARY_INDEX_SEARCH_HINT = "skip-index";
204 private static final String VAL_FILE_HINT = "val-files";
205 private static final String VAL_FILE_SAME_INDEX_HINT = "val-file-same-idx";
Yingyi Bu391f09e2015-10-29 13:49:39 -0700206 private static final String GEN_FIELDS_HINT = "gen-fields";
207
208 // data generator hints
209 private static final String DGEN_HINT = "dgen";
210
Till Westmann7199a562016-09-17 16:07:32 -0700211 // error configuration
212 protected static final boolean REPORT_EXPECTED_TOKENS = false;
213
Dmitry Lychagin1bdf8082018-06-13 14:48:23 -0700214 private int externalVarCounter;
215
Yingyi Bu391f09e2015-10-29 13:49:39 -0700216 private static class IndexParams {
217 public IndexType type;
218 public int gramLength;
219
220 public IndexParams(IndexType type, int gramLength) {
221 this.type = type;
222 this.gramLength = gramLength;
223 }
224 };
225
226 private static class FunctionName {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -0700227 public String dataverse;
228 public String library;
229 public String function;
230 public String hint;
231 public SourceLocation sourceLoc;
Yingyi Bu391f09e2015-10-29 13:49:39 -0700232 }
233
Dmitry Lychaginee54cc02018-05-25 19:26:18 -0700234 private String getHint(Token t) {
Yingyi Bu391f09e2015-10-29 13:49:39 -0700235 if (t.specialToken == null) {
236 return null;
237 }
238 String s = t.specialToken.image;
239 int n = s.length();
240 if (n < 2) {
241 return null;
242 }
243 return s.substring(1).trim();
244 }
245
Ali Alsuliman80225e22018-10-15 14:17:07 -0700246 private static IParser createNewParser(String statement) {
247 return new SQLPPParser(statement);
248 }
249
Dmitry Lychaginee54cc02018-05-25 19:26:18 -0700250 private Token getHintToken(Token t) {
251 return t.specialToken;
252 }
253
254 private IRecordFieldDataGen parseFieldDataGen(String hint, Token hintToken) throws ParseException {
Yingyi Bu391f09e2015-10-29 13:49:39 -0700255 IRecordFieldDataGen rfdg = null;
256 String splits[] = hint.split(" +");
257 if (splits[0].equals(VAL_FILE_HINT)) {
258 File[] valFiles = new File[splits.length - 1];
259 for (int k=1; k<splits.length; k++) {
260 valFiles[k-1] = new File(splits[k]);
261 }
262 rfdg = new FieldValFileDataGen(valFiles);
263 } else if (splits[0].equals(VAL_FILE_SAME_INDEX_HINT)) {
264 rfdg = new FieldValFileSameIndexDataGen(new File(splits[1]), splits[2]);
265 } else if (splits[0].equals(LIST_VAL_FILE_HINT)) {
266 rfdg = new ListValFileDataGen(new File(splits[1]), Integer.parseInt(splits[2]), Integer.parseInt(splits[3]));
267 } else if (splits[0].equals(LIST_HINT)) {
268 rfdg = new ListDataGen(Integer.parseInt(splits[1]), Integer.parseInt(splits[2]));
269 } else if (splits[0].equals(INTERVAL_HINT)) {
270 FieldIntervalDataGen.ValueType vt;
271 if (splits[1].equals("int")) {
272 vt = FieldIntervalDataGen.ValueType.INT;
273 } else if (splits[1].equals("long")) {
274 vt = FieldIntervalDataGen.ValueType.LONG;
275 } else if (splits[1].equals("float")) {
276 vt = FieldIntervalDataGen.ValueType.FLOAT;
277 } else if (splits[1].equals("double")) {
278 vt = FieldIntervalDataGen.ValueType.DOUBLE;
279 } else {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -0700280 throw new SqlppParseException(getSourceLocation(hintToken), "Unknown type for interval data gen: " + splits[1]);
Yingyi Bu391f09e2015-10-29 13:49:39 -0700281 }
282 rfdg = new FieldIntervalDataGen(vt, splits[2], splits[3]);
283 } else if (splits[0].equals(INSERT_RAND_INT_HINT)) {
284 rfdg = new InsertRandIntDataGen(splits[1], splits[2]);
285 } else if (splits[0].equals(DATE_BETWEEN_YEARS_HINT)) {
286 rfdg = new DateBetweenYearsDataGen(Integer.parseInt(splits[1]), Integer.parseInt(splits[2]));
287 } else if (splits[0].equals(DATETIME_BETWEEN_YEARS_HINT)) {
288 rfdg = new DatetimeBetweenYearsDataGen(Integer.parseInt(splits[1]), Integer.parseInt(splits[2]));
289 } else if (splits[0].equals(DATETIME_ADD_RAND_HOURS_HINT)) {
290 rfdg = new DatetimeAddRandHoursDataGen(Integer.parseInt(splits[1]), Integer.parseInt(splits[2]), splits[3]);
291 } else if (splits[0].equals(AUTO_HINT)) {
292 rfdg = new AutoDataGen(splits[1]);
293 }
294 return rfdg;
295 }
296
Till Westmann7199a562016-09-17 16:07:32 -0700297 public SQLPPParser(String s) {
Yingyi Bu391f09e2015-10-29 13:49:39 -0700298 this(new StringReader(s));
299 super.setInput(s);
300 }
301
Taewoo Kime65e6ca2017-01-14 17:53:28 -0800302 public static void main(String args[]) throws ParseException, TokenMgrError, IOException, FileNotFoundException, CompilationException {
Yingyi Bu391f09e2015-10-29 13:49:39 -0700303 File file = new File(args[0]);
304 Reader fis = new BufferedReader(new InputStreamReader(new FileInputStream(file), "UTF-8"));
305 SQLPPParser parser = new SQLPPParser(fis);
306 List<Statement> st = parser.parse();
307 //st.accept(new SQLPPPrintVisitor(), 0);
308 }
309
Taewoo Kime65e6ca2017-01-14 17:53:28 -0800310 public List<Statement> parse() throws CompilationException {
Yingyi Bu391f09e2015-10-29 13:49:39 -0700311 try {
312 return Statement();
313 } catch (Error e) {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -0700314 // 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 -0700315 // 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 -0700316 final String msg = e.getClass().getSimpleName() + (e.getMessage() != null ? ": " + e.getMessage() : "");
Dmitry Lychagin85142c02018-04-05 17:27:36 -0700317 throw new CompilationException(ErrorCode.PARSE_ERROR, msg);
Dmitry Lychaginee54cc02018-05-25 19:26:18 -0700318 } catch (SqlppParseException e) {
319 throw new CompilationException(ErrorCode.PARSE_ERROR, e.getSourceLocation(), getMessage(e));
Yingyi Bu391f09e2015-10-29 13:49:39 -0700320 } catch (ParseException e) {
Dmitry Lychagin85142c02018-04-05 17:27:36 -0700321 throw new CompilationException(ErrorCode.PARSE_ERROR, getMessage(e));
Yingyi Bu391f09e2015-10-29 13:49:39 -0700322 }
323 }
Till Westmann7199a562016-09-17 16:07:32 -0700324
325 protected String getMessage(ParseException pe) {
326 Token currentToken = pe.currentToken;
327 if (currentToken == null) {
328 return pe.getMessage();
329 }
330 int[][] expectedTokenSequences = pe.expectedTokenSequences;
331 String[] tokenImage = pe.tokenImage;
332 String sep = REPORT_EXPECTED_TOKENS ? eol : " ";
333 StringBuilder expected = REPORT_EXPECTED_TOKENS ? new StringBuilder() : null;
334 int maxSize = appendExpected(expected, expectedTokenSequences, tokenImage);
335 Token tok = currentToken.next;
336 int line = tok.beginLine;
Dmitry Lychaginee54cc02018-05-25 19:26:18 -0700337 StringBuilder message = new StringBuilder(128);
338 message.append("In line ").append(line).append(" >>").append(getLine(line)).append("<<").append(sep).append("Encountered ");
Till Westmann7199a562016-09-17 16:07:32 -0700339 for (int i = 0; i < maxSize; i++) {
340 if (i != 0) {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -0700341 message.append(' ');
Till Westmann7199a562016-09-17 16:07:32 -0700342 }
343 if (tok.kind == 0) {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -0700344 message.append(fixQuotes(tokenImage[0]));
Till Westmann7199a562016-09-17 16:07:32 -0700345 break;
346 }
Till Westmanne3c9f272016-10-09 11:09:26 -0700347 final String fixedTokenImage = tokenImage[tok.kind];
348 if (! tok.image.equalsIgnoreCase(stripQuotes(fixedTokenImage))) {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -0700349 message.append(fixQuotes(fixedTokenImage)).append(' ');
Till Westmanne3c9f272016-10-09 11:09:26 -0700350 }
Dmitry Lychaginee54cc02018-05-25 19:26:18 -0700351 message.append(quot).append(addEscapes(tok.image)).append(quot);
Till Westmann7199a562016-09-17 16:07:32 -0700352 tok = tok.next;
353 }
Dmitry Lychaginee54cc02018-05-25 19:26:18 -0700354 message.append(" at column ").append(currentToken.next.beginColumn).append('.').append(sep);
Till Westmann7199a562016-09-17 16:07:32 -0700355 if (REPORT_EXPECTED_TOKENS) {
356 if (expectedTokenSequences.length == 1) {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -0700357 message.append("Was expecting:").append(sep).append(" ");
Till Westmann7199a562016-09-17 16:07:32 -0700358 } else {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -0700359 message.append("Was expecting one of:").append(sep).append(" ");
Till Westmann7199a562016-09-17 16:07:32 -0700360 }
Dmitry Lychaginee54cc02018-05-25 19:26:18 -0700361 message.append(expected);
Till Westmann7199a562016-09-17 16:07:32 -0700362 }
Dmitry Lychaginee54cc02018-05-25 19:26:18 -0700363 return message.toString();
Till Westmann7199a562016-09-17 16:07:32 -0700364 }
365
Dmitry Lychaginee54cc02018-05-25 19:26:18 -0700366 protected static SourceLocation getSourceLocation(Token token) {
367 return token != null ? new SourceLocation(token.beginLine, token.beginColumn) : null;
368 }
369
Dmitry Lychagin5c26b422018-06-01 10:22:16 -0700370 protected static <T extends AbstractLangExpression> T addSourceLocation(T expr, Token token) {
371 expr.setSourceLocation(getSourceLocation(token));
372 return expr;
Dmitry Lychaginee54cc02018-05-25 19:26:18 -0700373 }
Yingyi Bu391f09e2015-10-29 13:49:39 -0700374}
375
376PARSER_END(SQLPPParser)
377
378
379List<Statement> Statement() throws ParseException:
380{
381 scopeStack.push(RootScopeFactory.createRootScope(this));
382 List<Statement> decls = new ArrayList<Statement>();
383 Statement stmt = null;
384}
385{
Murtadha Hubaildc775222017-08-21 15:22:45 +0300386 (
387 (stmt = SingleStatement()
388 {
389 decls.add(stmt);
390 }
391 )?
392 (<SEMICOLON>)+
Yingyi Bu391f09e2015-10-29 13:49:39 -0700393 )*
394 <EOF>
395 {
396 return decls;
397 }
398}
399
400Statement SingleStatement() throws ParseException:
401{
402 Statement stmt = null;
403}
404{
405 (
406 stmt = DataverseDeclaration()
407 | stmt = FunctionDeclaration()
408 | stmt = CreateStatement()
409 | stmt = LoadStatement()
410 | stmt = DropStatement()
411 | stmt = WriteStatement()
412 | stmt = SetStatement()
413 | stmt = InsertStatement()
414 | stmt = DeleteStatement()
415 | stmt = UpdateStatement()
Yingyi Bucb5bf332017-01-02 22:19:50 -0800416 | stmt = UpsertStatement()
Yingyi Buab817482016-08-19 21:29:31 -0700417 | stmt = ConnectionStatement()
Yingyi Bu391f09e2015-10-29 13:49:39 -0700418 | stmt = CompactStatement()
Till Westmannef3f0272016-07-27 18:34:01 -0700419 | stmt = ExplainStatement()
Murtadha Hubaildc775222017-08-21 15:22:45 +0300420 | stmt = Query(false)
Yingyi Bu391f09e2015-10-29 13:49:39 -0700421 | stmt = RefreshExternalDatasetStatement()
Yingyi Bu391f09e2015-10-29 13:49:39 -0700422 )
423 {
424 return stmt;
425 }
426}
427
428DataverseDecl DataverseDeclaration() throws ParseException:
429{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -0700430 Token startToken = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -0700431 String dvName = null;
432}
433{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -0700434 <USE> { startToken = token; } dvName = Identifier()
Yingyi Bu391f09e2015-10-29 13:49:39 -0700435 {
436 defaultDataverse = dvName;
Dmitry Lychaginee54cc02018-05-25 19:26:18 -0700437 DataverseDecl dvDecl = new DataverseDecl(new Identifier(dvName));
Dmitry Lychagin5c26b422018-06-01 10:22:16 -0700438 return addSourceLocation(dvDecl, startToken);
Yingyi Bu391f09e2015-10-29 13:49:39 -0700439 }
440}
441
442Statement CreateStatement() throws ParseException:
443{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -0700444 Token startToken = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -0700445 String hint = null;
Dmitry Lychaginee54cc02018-05-25 19:26:18 -0700446 Token hintToken = null;
447 boolean hintDGen = false;
Yingyi Bu391f09e2015-10-29 13:49:39 -0700448 Statement stmt = null;
449}
450{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -0700451 <CREATE> { startToken = token; }
Yingyi Bu391f09e2015-10-29 13:49:39 -0700452 (
453 {
454 hint = getHint(token);
Dmitry Lychaginee54cc02018-05-25 19:26:18 -0700455 if (hint != null) {
456 hintToken = getHintToken(token);
457 hintDGen = hint.startsWith(DGEN_HINT);
Yingyi Bu391f09e2015-10-29 13:49:39 -0700458 }
459 }
Dmitry Lychaginee54cc02018-05-25 19:26:18 -0700460 stmt = TypeSpecification(startToken, hint, hintDGen, hintToken)
461 | stmt = NodegroupSpecification(startToken)
462 | stmt = DatasetSpecification(startToken)
463 | stmt = IndexSpecification(startToken)
464 | stmt = DataverseSpecification(startToken)
465 | stmt = FunctionSpecification(startToken)
466 | stmt = FeedSpecification(startToken)
467 | stmt = FeedPolicySpecification(startToken)
Yingyi Bu391f09e2015-10-29 13:49:39 -0700468 )
469 {
470 return stmt;
471 }
472}
473
Dmitry Lychaginee54cc02018-05-25 19:26:18 -0700474TypeDecl TypeSpecification(Token startStmtToken, String hint, boolean dgen, Token hintToken) throws ParseException:
Yingyi Bu391f09e2015-10-29 13:49:39 -0700475{
476 Pair<Identifier,Identifier> nameComponents = null;
477 boolean ifNotExists = false;
478 TypeExpression typeExpr = null;
479}
480{
481 <TYPE> nameComponents = TypeName() ifNotExists = IfNotExists()
Till Westmannf6028272016-09-30 14:34:42 -0700482 <AS> typeExpr = RecordTypeDef()
Yingyi Bu391f09e2015-10-29 13:49:39 -0700483 {
484 long numValues = -1;
485 String filename = null;
486 if (dgen) {
487 String splits[] = hint.split(" +");
488 if (splits.length != 3) {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -0700489 throw new SqlppParseException(getSourceLocation(hintToken), "Expecting /*+ dgen <filename> <numberOfItems> */");
Yingyi Bu391f09e2015-10-29 13:49:39 -0700490 }
491 filename = splits[1];
492 numValues = Long.parseLong(splits[2]);
493 }
494 TypeDataGen tddg = new TypeDataGen(dgen, filename, numValues);
Dmitry Lychaginee54cc02018-05-25 19:26:18 -0700495 TypeDecl stmt = new TypeDecl(nameComponents.first, nameComponents.second, typeExpr, tddg, ifNotExists);
Dmitry Lychagin5c26b422018-06-01 10:22:16 -0700496 return addSourceLocation(stmt, startStmtToken);
Yingyi Bu391f09e2015-10-29 13:49:39 -0700497 }
498}
499
Dmitry Lychaginee54cc02018-05-25 19:26:18 -0700500NodegroupDecl NodegroupSpecification(Token startStmtToken) throws ParseException:
Yingyi Bu391f09e2015-10-29 13:49:39 -0700501{
502 String name = null;
503 String tmp = null;
504 boolean ifNotExists = false;
505 List<Identifier>ncNames = null;
506}
507{
508 <NODEGROUP> name = Identifier()
509 ifNotExists = IfNotExists() <ON> tmp = Identifier()
510 {
511 ncNames = new ArrayList<Identifier>();
512 ncNames.add(new Identifier(tmp));
513 }
514 ( <COMMA> tmp = Identifier()
515 {
516 ncNames.add(new Identifier(tmp));
517 }
518 )*
519 {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -0700520 NodegroupDecl stmt = new NodegroupDecl(new Identifier(name), ncNames, ifNotExists);
Dmitry Lychagin5c26b422018-06-01 10:22:16 -0700521 return addSourceLocation(stmt, startStmtToken);
Yingyi Bu391f09e2015-10-29 13:49:39 -0700522 }
523}
524
Dmitry Lychaginee54cc02018-05-25 19:26:18 -0700525DatasetDecl DatasetSpecification(Token startStmtToken) throws ParseException:
Yingyi Bu391f09e2015-10-29 13:49:39 -0700526{
527 Pair<Identifier,Identifier> nameComponents = null;
528 boolean ifNotExists = false;
Your Namedace5f22016-01-12 14:02:48 -0800529 Pair<Identifier,Identifier> typeComponents = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -0700530 String adapterName = null;
531 Map<String,String> properties = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -0700532 FunctionSignature appliedFunction = null;
Yingyi Buc9bfe252016-03-01 00:02:40 -0800533 Pair<List<Integer>, List<List<String>>> primaryKeyFields = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -0700534 String nodeGroupName = null;
535 Map<String,String> hints = new HashMap<String,String>();
Dmitry Lychaginee54cc02018-05-25 19:26:18 -0700536 DatasetDecl stmt = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -0700537 boolean autogenerated = false;
Yingyi Buc9bfe252016-03-01 00:02:40 -0800538 Pair<Integer, List<String>> filterField = null;
Yingyi Bub9169b62016-02-26 21:21:49 -0800539 Pair<Identifier,Identifier> metaTypeComponents = new Pair<Identifier, Identifier>(null, null);
Till Westmannf3aa19f2017-12-01 17:42:35 -0800540 RecordConstructor withRecord = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -0700541}
542{
543 (
Yingyi Bu1c0fff52016-03-25 20:23:30 -0700544 <EXTERNAL> Dataset() nameComponents = QualifiedName()
Your Namedace5f22016-01-12 14:02:48 -0800545 <LEFTPAREN> typeComponents = TypeName() <RIGHTPAREN>
Yingyi Bu391f09e2015-10-29 13:49:39 -0700546 ifNotExists = IfNotExists()
547 <USING> adapterName = AdapterName() properties = Configuration()
Till Westmannf3aa19f2017-12-01 17:42:35 -0800548 ( <ON> nodeGroupName = Identifier() )?
Yingyi Bu391f09e2015-10-29 13:49:39 -0700549 ( <HINTS> hints = Properties() )?
Till Westmannf3aa19f2017-12-01 17:42:35 -0800550 ( <WITH> withRecord = RecordConstructor() )?
Yingyi Bu391f09e2015-10-29 13:49:39 -0700551 {
552 ExternalDetailsDecl edd = new ExternalDetailsDecl();
553 edd.setAdapter(adapterName);
554 edd.setProperties(properties);
Till Westmannf3aa19f2017-12-01 17:42:35 -0800555 try{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -0700556 stmt = new DatasetDecl(nameComponents.first,
Yingyi Bu391f09e2015-10-29 13:49:39 -0700557 nameComponents.second,
Your Namedace5f22016-01-12 14:02:48 -0800558 typeComponents.first,
559 typeComponents.second,
Yingyi Bub9169b62016-02-26 21:21:49 -0800560 metaTypeComponents.first,
561 metaTypeComponents.second,
Yingyi Bu391f09e2015-10-29 13:49:39 -0700562 nodeGroupName != null? new Identifier(nodeGroupName): null,
Yingyi Bu391f09e2015-10-29 13:49:39 -0700563 hints,
564 DatasetType.EXTERNAL,
565 edd,
Till Westmannf3aa19f2017-12-01 17:42:35 -0800566 withRecord,
Yingyi Bu391f09e2015-10-29 13:49:39 -0700567 ifNotExists);
Till Westmannf3aa19f2017-12-01 17:42:35 -0800568 } catch (CompilationException e){
Dmitry Lychaginee54cc02018-05-25 19:26:18 -0700569 throw new SqlppParseException(getSourceLocation(startStmtToken), e.getMessage());
Till Westmannf3aa19f2017-12-01 17:42:35 -0800570 }
Yingyi Bu391f09e2015-10-29 13:49:39 -0700571 }
572
Murtadha Hubail2c04ae02017-11-21 15:58:01 +0300573 | ( <INTERNAL> )?
Yingyi Bu1c0fff52016-03-25 20:23:30 -0700574 Dataset() nameComponents = QualifiedName()
Your Namedace5f22016-01-12 14:02:48 -0800575 <LEFTPAREN> typeComponents = TypeName() <RIGHTPAREN>
Yingyi Bub9169b62016-02-26 21:21:49 -0800576 (
577 { String name; }
578 <WITH>
579 name = Identifier()
580 {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -0700581 if (!name.equalsIgnoreCase("meta")){
582 throw new SqlppParseException(getSourceLocation(startStmtToken),
583 "We can only support one additional associated field called \"meta\".");
Yingyi Bub9169b62016-02-26 21:21:49 -0800584 }
585 }
586 <LEFTPAREN> metaTypeComponents = TypeName() <RIGHTPAREN>
587 )?
Yingyi Bu391f09e2015-10-29 13:49:39 -0700588 ifNotExists = IfNotExists()
589 primaryKeyFields = PrimaryKey()
590 (<AUTOGENERATED> { autogenerated = true; } )?
591 (<ON> nodeGroupName = Identifier() )?
592 ( <HINTS> hints = Properties() )?
Yingyi Bu391f09e2015-10-29 13:49:39 -0700593 ( LOOKAHEAD(2) <WITH> <FILTER> <ON> filterField = NestedField() )?
Till Westmannf3aa19f2017-12-01 17:42:35 -0800594 ( <WITH> withRecord = RecordConstructor() )?
Yingyi Bu391f09e2015-10-29 13:49:39 -0700595 {
Yingyi Buc9bfe252016-03-01 00:02:40 -0800596 if(filterField!=null && filterField.first!=0){
Dmitry Lychaginee54cc02018-05-25 19:26:18 -0700597 throw new SqlppParseException(getSourceLocation(startStmtToken),
598 "A filter field can only be a field in the main record of the dataset.");
Yingyi Buc9bfe252016-03-01 00:02:40 -0800599 }
600 InternalDetailsDecl idd = new InternalDetailsDecl(primaryKeyFields.second,
601 primaryKeyFields.first,
Yingyi Bu391f09e2015-10-29 13:49:39 -0700602 autogenerated,
Murtadha Hubail2c04ae02017-11-21 15:58:01 +0300603 filterField == null? null : filterField.second);
Till Westmannf3aa19f2017-12-01 17:42:35 -0800604 try{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -0700605 stmt = new DatasetDecl(nameComponents.first,
Yingyi Bu391f09e2015-10-29 13:49:39 -0700606 nameComponents.second,
Your Namedace5f22016-01-12 14:02:48 -0800607 typeComponents.first,
608 typeComponents.second,
Yingyi Bub9169b62016-02-26 21:21:49 -0800609 metaTypeComponents.first,
610 metaTypeComponents.second,
Yingyi Bu391f09e2015-10-29 13:49:39 -0700611 nodeGroupName != null ? new Identifier(nodeGroupName) : null,
Yingyi Bu391f09e2015-10-29 13:49:39 -0700612 hints,
613 DatasetType.INTERNAL,
614 idd,
Till Westmannf3aa19f2017-12-01 17:42:35 -0800615 withRecord,
Yingyi Bu391f09e2015-10-29 13:49:39 -0700616 ifNotExists);
Till Westmannf3aa19f2017-12-01 17:42:35 -0800617 } catch (CompilationException e){
Dmitry Lychaginee54cc02018-05-25 19:26:18 -0700618 throw new SqlppParseException(getSourceLocation(startStmtToken), e.getMessage());
Till Westmannf3aa19f2017-12-01 17:42:35 -0800619 }
Yingyi Bu391f09e2015-10-29 13:49:39 -0700620 }
621 )
622 {
Dmitry Lychagin5c26b422018-06-01 10:22:16 -0700623 return addSourceLocation(stmt, startStmtToken);
Yingyi Bu391f09e2015-10-29 13:49:39 -0700624 }
625}
626
627RefreshExternalDatasetStatement RefreshExternalDatasetStatement() throws ParseException:
628{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -0700629 Token startToken = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -0700630 Pair<Identifier,Identifier> nameComponents = null;
631 String datasetName = null;
632}
633{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -0700634 <REFRESH> { startToken = token; } <EXTERNAL> Dataset() nameComponents = QualifiedName()
Yingyi Bu391f09e2015-10-29 13:49:39 -0700635 {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -0700636 RefreshExternalDatasetStatement stmt = new RefreshExternalDatasetStatement();
637 stmt.setDataverseName(nameComponents.first);
638 stmt.setDatasetName(nameComponents.second);
Dmitry Lychagin5c26b422018-06-01 10:22:16 -0700639 return addSourceLocation(stmt, startToken);
Yingyi Bu391f09e2015-10-29 13:49:39 -0700640 }
641}
642
Dmitry Lychaginee54cc02018-05-25 19:26:18 -0700643CreateIndexStatement IndexSpecification(Token startStmtToken) throws ParseException:
Yingyi Bu391f09e2015-10-29 13:49:39 -0700644{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -0700645 CreateIndexStatement stmt = new CreateIndexStatement();
Yingyi Bu391f09e2015-10-29 13:49:39 -0700646 String indexName = null;
647 boolean ifNotExists = false;
648 Pair<Identifier,Identifier> nameComponents = null;
Dmitry Lychagin8ba59442017-06-16 14:19:45 -0700649 Pair<Integer, Pair<List<String>, IndexedTypeExpression>> fieldPair = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -0700650 IndexParams indexType = null;
651 boolean enforced = false;
Ali Alsuliman8351d252017-09-24 00:43:15 -0700652 boolean isPrimaryIdx = false;
Yingyi Bu391f09e2015-10-29 13:49:39 -0700653}
654{
Ali Alsuliman8351d252017-09-24 00:43:15 -0700655 (
656 (<INDEX> indexName = Identifier()
657 ifNotExists = IfNotExists()
658 <ON> nameComponents = QualifiedName()
659 <LEFTPAREN> ( fieldPair = OpenField()
660 {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -0700661 stmt.addFieldExprPair(fieldPair.second);
662 stmt.addFieldIndexIndicator(fieldPair.first);
Yingyi Bu391f09e2015-10-29 13:49:39 -0700663 }
Ali Alsuliman8351d252017-09-24 00:43:15 -0700664 ) (<COMMA> fieldPair = OpenField()
665 {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -0700666 stmt.addFieldExprPair(fieldPair.second);
667 stmt.addFieldIndexIndicator(fieldPair.first);
Ali Alsuliman8351d252017-09-24 00:43:15 -0700668 }
669 )* <RIGHTPAREN> ( <TYPE> indexType = IndexType() )? ( <ENFORCED> { enforced = true; } )?)
670 |
671 (<PRIMARY> <INDEX> {isPrimaryIdx = true;}
672 (
673 (indexName = Identifier())? ifNotExists = IfNotExists()
674 )
675 <ON> nameComponents = QualifiedName() (<TYPE> <BTREE>)?
676 )
677 )
678 {
679 if (isPrimaryIdx && indexName == null) {
680 indexName = "primary_idx_" + nameComponents.second;
Yingyi Bu391f09e2015-10-29 13:49:39 -0700681 }
Dmitry Lychaginee54cc02018-05-25 19:26:18 -0700682 stmt.setIndexName(new Identifier(indexName));
683 stmt.setIfNotExists(ifNotExists);
684 stmt.setDataverseName(nameComponents.first);
685 stmt.setDatasetName(nameComponents.second);
Ali Alsuliman8351d252017-09-24 00:43:15 -0700686 if (indexType != null) {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -0700687 stmt.setIndexType(indexType.type);
688 stmt.setGramLength(indexType.gramLength);
Ali Alsuliman8351d252017-09-24 00:43:15 -0700689 }
Dmitry Lychaginee54cc02018-05-25 19:26:18 -0700690 stmt.setEnforced(enforced);
Dmitry Lychagin5c26b422018-06-01 10:22:16 -0700691 return addSourceLocation(stmt, startStmtToken);
Ali Alsuliman8351d252017-09-24 00:43:15 -0700692 }
Yingyi Bu391f09e2015-10-29 13:49:39 -0700693}
694
695String CompactionPolicy() throws ParseException :
696{
697 String compactionPolicy = null;
698}
699{
700 compactionPolicy = Identifier()
701 {
702 return compactionPolicy;
703 }
704}
705
706String FilterField() throws ParseException :
707{
708 String filterField = null;
709}
710{
711 filterField = Identifier()
712 {
713 return filterField;
714 }
715}
716
717IndexParams IndexType() throws ParseException:
718{
719 IndexType type = null;
720 int gramLength = 0;
721}
722{
723 (<BTREE>
724 {
725 type = IndexType.BTREE;
726 }
727 | <RTREE>
728 {
729 type = IndexType.RTREE;
730 }
731 | <KEYWORD>
732 {
733 type = IndexType.LENGTH_PARTITIONED_WORD_INVIX;
734 }
Taewoo Kimc49405a2017-01-04 00:30:43 -0800735 |<FULLTEXT>
736 {
737 type = IndexType.SINGLE_PARTITION_WORD_INVIX;
738 }
Yingyi Bu391f09e2015-10-29 13:49:39 -0700739 | <NGRAM> <LEFTPAREN> <INTEGER_LITERAL>
740 {
741 type = IndexType.LENGTH_PARTITIONED_NGRAM_INVIX;
742 gramLength = Integer.valueOf(token.image);
743 }
744 <RIGHTPAREN>)
745 {
746 return new IndexParams(type, gramLength);
747 }
748}
749
Dmitry Lychaginee54cc02018-05-25 19:26:18 -0700750CreateDataverseStatement DataverseSpecification(Token startStmtToken) throws ParseException :
Yingyi Bu391f09e2015-10-29 13:49:39 -0700751{
752 String dvName = null;
753 boolean ifNotExists = false;
Yingyi Bu391f09e2015-10-29 13:49:39 -0700754}
755{
756 <DATAVERSE> dvName = Identifier()
757 ifNotExists = IfNotExists()
Yingyi Bu391f09e2015-10-29 13:49:39 -0700758 {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -0700759 CreateDataverseStatement stmt = new CreateDataverseStatement(new Identifier(dvName), null, ifNotExists);
Dmitry Lychagin5c26b422018-06-01 10:22:16 -0700760 return addSourceLocation(stmt, startStmtToken);
Yingyi Bu391f09e2015-10-29 13:49:39 -0700761 }
762}
763
Dmitry Lychaginee54cc02018-05-25 19:26:18 -0700764CreateFunctionStatement FunctionSpecification(Token startStmtToken) throws ParseException:
Yingyi Bu391f09e2015-10-29 13:49:39 -0700765{
766 FunctionSignature signature;
767 boolean ifNotExists = false;
768 List<VarIdentifier> paramList = new ArrayList<VarIdentifier>();
769 String functionBody;
770 VarIdentifier var = null;
771 Expression functionBodyExpr;
772 Token beginPos;
773 Token endPos;
774 FunctionName fctName = null;
Steven Glenn Jacobs665e9fe2017-12-27 10:30:39 -0800775 String currentDataverse = defaultDataverse;
Yingyi Bu391f09e2015-10-29 13:49:39 -0700776
777 createNewScope();
778}
779{
780 <FUNCTION> fctName = FunctionName()
Steven Glenn Jacobs665e9fe2017-12-27 10:30:39 -0800781 {
782 defaultDataverse = fctName.dataverse;
783 }
Yingyi Bu391f09e2015-10-29 13:49:39 -0700784 ifNotExists = IfNotExists()
785 paramList = ParameterList()
786 <LEFTBRACE>
787 {
788 beginPos = token;
789 }
Xikui Wang3de700a2018-03-15 16:32:55 -0700790 (functionBodyExpr = SelectExpression(true) | functionBodyExpr = Expression())
791 <RIGHTBRACE>
Yingyi Bu391f09e2015-10-29 13:49:39 -0700792 {
793 endPos = token;
794 functionBody = extractFragment(beginPos.beginLine, beginPos.beginColumn, endPos.beginLine, endPos.beginColumn);
795 // TODO use fctName.library
796 signature = new FunctionSignature(fctName.dataverse, fctName.function, paramList.size());
797 getCurrentScope().addFunctionDescriptor(signature, false);
798 removeCurrentScope();
Steven Glenn Jacobs665e9fe2017-12-27 10:30:39 -0800799 defaultDataverse = currentDataverse;
Dmitry Lychaginee54cc02018-05-25 19:26:18 -0700800 CreateFunctionStatement stmt = new CreateFunctionStatement(signature, paramList, functionBody, functionBodyExpr, ifNotExists);
Dmitry Lychagin5c26b422018-06-01 10:22:16 -0700801 return addSourceLocation(stmt, startStmtToken);
Yingyi Bu391f09e2015-10-29 13:49:39 -0700802 }
803}
804
Dmitry Lychaginee54cc02018-05-25 19:26:18 -0700805CreateFeedStatement FeedSpecification(Token startStmtToken) throws ParseException:
Yingyi Bu391f09e2015-10-29 13:49:39 -0700806{
807 Pair<Identifier,Identifier> nameComponents = null;
808 boolean ifNotExists = false;
809 String adapterName = null;
810 Map<String,String> properties = null;
Dmitry Lychaginee54cc02018-05-25 19:26:18 -0700811 CreateFeedStatement stmt = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -0700812 Pair<Identifier,Identifier> sourceNameComponents = null;
Xikui Wang5a61b2a2018-01-02 14:14:03 -0800813 RecordConstructor withRecord = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -0700814}
815{
Abdullah Alamoudifff200c2017-02-18 20:32:14 -0800816 <FEED> nameComponents = QualifiedName() ifNotExists = IfNotExists()
Xikui Wang5a61b2a2018-01-02 14:14:03 -0800817 <WITH> withRecord = RecordConstructor()
Abdullah Alamoudifff200c2017-02-18 20:32:14 -0800818 {
Xikui Wang5a61b2a2018-01-02 14:14:03 -0800819 try {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -0700820 stmt = new CreateFeedStatement(nameComponents, withRecord, ifNotExists);
Dmitry Lychagin5c26b422018-06-01 10:22:16 -0700821 return addSourceLocation(stmt, startStmtToken);
Xikui Wang5a61b2a2018-01-02 14:14:03 -0800822 } catch (AlgebricksException e) {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -0700823 throw new SqlppParseException(getSourceLocation(startStmtToken), e.getMessage());
Xikui Wang5a61b2a2018-01-02 14:14:03 -0800824 }
Abdullah Alamoudifff200c2017-02-18 20:32:14 -0800825 }
Yingyi Bu391f09e2015-10-29 13:49:39 -0700826}
827
Dmitry Lychaginee54cc02018-05-25 19:26:18 -0700828CreateFeedPolicyStatement FeedPolicySpecification(Token startStmtToken) throws ParseException:
Yingyi Bu391f09e2015-10-29 13:49:39 -0700829{
Michael Blowd6cf6412016-06-30 02:44:35 -0400830 String policyName = null;
831 String basePolicyName = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -0700832 String sourcePolicyFile = null;
833 String definition = null;
834 boolean ifNotExists = false;
835 Map<String,String> properties = null;
Dmitry Lychaginee54cc02018-05-25 19:26:18 -0700836 CreateFeedPolicyStatement stmt = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -0700837}
838{
839 (
840 <INGESTION> <POLICY> policyName = Identifier() ifNotExists = IfNotExists()
Yingyi Bu6d57e492016-06-06 21:24:42 -0700841 <FROM>
842 (<POLICY> basePolicyName = Identifier() properties = Configuration() (<DEFINITION> definition = ConstantString())?
Yingyi Bu391f09e2015-10-29 13:49:39 -0700843 {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -0700844 stmt = new CreateFeedPolicyStatement(policyName,
Yingyi Bu391f09e2015-10-29 13:49:39 -0700845 basePolicyName, properties, definition, ifNotExists);
846 }
Abdullah Alamoudi5dc73ed2016-07-28 05:03:13 +0300847 | <PATH> sourcePolicyFile = ConstantString() (<DEFINITION> definition = ConstantString())?
Yingyi Bu391f09e2015-10-29 13:49:39 -0700848 {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -0700849 stmt = new CreateFeedPolicyStatement(policyName, sourcePolicyFile, definition, ifNotExists);
Yingyi Bu391f09e2015-10-29 13:49:39 -0700850 }
Yingyi Bu6d57e492016-06-06 21:24:42 -0700851 )
Yingyi Bu391f09e2015-10-29 13:49:39 -0700852 )
853 {
Dmitry Lychagin5c26b422018-06-01 10:22:16 -0700854 return addSourceLocation(stmt, startStmtToken);
Yingyi Bu391f09e2015-10-29 13:49:39 -0700855 }
856}
857
Yingyi Bu391f09e2015-10-29 13:49:39 -0700858List<VarIdentifier> ParameterList() throws ParseException:
859{
860 List<VarIdentifier> paramList = new ArrayList<VarIdentifier>();
861 VarIdentifier var = null;
862}
863{
864 <LEFTPAREN> (<IDENTIFIER>
865 {
Yingyi Buacc12a92016-03-26 17:25:05 -0700866 var = SqlppVariableUtil.toInternalVariableIdentifier(token.image);
Yingyi Bu391f09e2015-10-29 13:49:39 -0700867 paramList.add(var);
Yingyi Bu391f09e2015-10-29 13:49:39 -0700868 }
869 (<COMMA> <IDENTIFIER>
870 {
Yingyi Buacc12a92016-03-26 17:25:05 -0700871 var = SqlppVariableUtil.toInternalVariableIdentifier(token.image);
Yingyi Bu391f09e2015-10-29 13:49:39 -0700872 paramList.add(var);
Yingyi Bu391f09e2015-10-29 13:49:39 -0700873 }
874 )*)? <RIGHTPAREN>
875 {
876 return paramList;
877 }
878}
879
880boolean IfNotExists() throws ParseException:
881{
882}
883{
Yingyi Budaa549c2016-06-28 22:30:52 -0700884 ( LOOKAHEAD(1) <IF> <NOT> <EXISTS>
Yingyi Bu391f09e2015-10-29 13:49:39 -0700885 {
886 return true;
887 }
888 )?
889 {
890 return false;
891 }
892}
893
Xikui Wang9d63f622017-05-18 17:50:44 -0700894void ApplyFunction(List<FunctionSignature> funcSigs) throws ParseException:
Yingyi Bu391f09e2015-10-29 13:49:39 -0700895{
896 FunctionName functioName = null;
Xikui Wang261dc6d2017-03-29 21:23:15 -0700897 String fqFunctionName = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -0700898}
899{
900 <APPLY> <FUNCTION> functioName = FunctionName()
901 {
Xikui Wang261dc6d2017-03-29 21:23:15 -0700902 fqFunctionName = functioName.library == null ? functioName.function : functioName.library + "#" + functioName.function;
903 funcSigs.add(new FunctionSignature(functioName.dataverse, fqFunctionName, 1));
904 }
905 (
906 <COMMA> functioName = FunctionName()
907 {
908 fqFunctionName = functioName.library == null ? functioName.function : functioName.library + "#" + functioName.function;
909 funcSigs.add(new FunctionSignature(functioName.dataverse, fqFunctionName, 1));
910 }
911 )*
Yingyi Bu391f09e2015-10-29 13:49:39 -0700912}
913
914String GetPolicy() throws ParseException:
915{
916 String policy = null;
917}
918{
919 <USING> <POLICY> policy = Identifier()
920 {
921 return policy;
922 }
923
924}
925
926FunctionSignature FunctionSignature() throws ParseException:
927{
928 FunctionName fctName = null;
929 int arity = 0;
930}
931{
932 fctName = FunctionName() <ATT> <INTEGER_LITERAL>
933 {
934 arity = new Integer(token.image);
935 if (arity < 0 && arity != FunctionIdentifier.VARARGS) {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -0700936 throw new SqlppParseException(getSourceLocation(token), "Invalid arity:" + arity);
Yingyi Bu391f09e2015-10-29 13:49:39 -0700937 }
938
939 // TODO use fctName.library
940 String fqFunctionName = fctName.library == null ? fctName.function : fctName.library + "#" + fctName.function;
941 return new FunctionSignature(fctName.dataverse, fqFunctionName, arity);
942 }
943}
944
Yingyi Buc9bfe252016-03-01 00:02:40 -0800945Pair<List<Integer>, List<List<String>>> PrimaryKey() throws ParseException:
Yingyi Bu391f09e2015-10-29 13:49:39 -0700946{
Yingyi Buc9bfe252016-03-01 00:02:40 -0800947 Pair<Integer, List<String>> tmp = null;
948 List<Integer> keyFieldSourceIndicators = new ArrayList<Integer>();
Yingyi Bu391f09e2015-10-29 13:49:39 -0700949 List<List<String>> primaryKeyFields = new ArrayList<List<String>>();
950}
951{
952 <PRIMARY> <KEY> tmp = NestedField()
953 {
Yingyi Buc9bfe252016-03-01 00:02:40 -0800954 keyFieldSourceIndicators.add(tmp.first);
955 primaryKeyFields.add(tmp.second);
Yingyi Bu391f09e2015-10-29 13:49:39 -0700956 }
957 ( <COMMA> tmp = NestedField()
958 {
Yingyi Buc9bfe252016-03-01 00:02:40 -0800959 keyFieldSourceIndicators.add(tmp.first);
960 primaryKeyFields.add(tmp.second);
Yingyi Bu391f09e2015-10-29 13:49:39 -0700961 }
962 )*
963 {
Yingyi Buc9bfe252016-03-01 00:02:40 -0800964 return new Pair<List<Integer>, List<List<String>>> (keyFieldSourceIndicators, primaryKeyFields);
Yingyi Bu391f09e2015-10-29 13:49:39 -0700965 }
966}
967
968Statement DropStatement() throws ParseException:
969{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -0700970 Token startToken = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -0700971 String id = null;
972 Pair<Identifier,Identifier> pairId = null;
973 Triple<Identifier,Identifier,Identifier> tripleId = null;
974 FunctionSignature funcSig = null;
975 boolean ifExists = false;
Dmitry Lychaginee54cc02018-05-25 19:26:18 -0700976 AbstractStatement stmt = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -0700977}
978{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -0700979 <DROP> { startToken = token; }
Yingyi Bu391f09e2015-10-29 13:49:39 -0700980 (
Yingyi Bu1c0fff52016-03-25 20:23:30 -0700981 Dataset() pairId = QualifiedName() ifExists = IfExists()
Yingyi Bu391f09e2015-10-29 13:49:39 -0700982 {
Yingyi Buab817482016-08-19 21:29:31 -0700983 stmt = new DropDatasetStatement(pairId.first, pairId.second, ifExists);
Yingyi Bu391f09e2015-10-29 13:49:39 -0700984 }
985 | <INDEX> tripleId = DoubleQualifiedName() ifExists = IfExists()
986 {
987 stmt = new IndexDropStatement(tripleId.first, tripleId.second, tripleId.third, ifExists);
988 }
989 | <NODEGROUP> id = Identifier() ifExists = IfExists()
990 {
991 stmt = new NodeGroupDropStatement(new Identifier(id), ifExists);
992 }
993 | <TYPE> pairId = TypeName() ifExists = IfExists()
994 {
995 stmt = new TypeDropStatement(pairId.first, pairId.second, ifExists);
996 }
997 | <DATAVERSE> id = Identifier() ifExists = IfExists()
998 {
999 stmt = new DataverseDropStatement(new Identifier(id), ifExists);
1000 }
1001 | <FUNCTION> funcSig = FunctionSignature() ifExists = IfExists()
1002 {
1003 stmt = new FunctionDropStatement(funcSig, ifExists);
1004 }
1005 | <FEED> pairId = QualifiedName() ifExists = IfExists()
1006 {
1007 stmt = new FeedDropStatement(pairId.first, pairId.second, ifExists);
1008 }
Abdullah Alamoudi5dc73ed2016-07-28 05:03:13 +03001009 | <INGESTION> <POLICY> pairId = QualifiedName() ifExists = IfExists()
1010 {
1011 stmt = new FeedPolicyDropStatement(pairId.first, pairId.second, ifExists);
1012 }
Yingyi Bu391f09e2015-10-29 13:49:39 -07001013 )
1014 {
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07001015 return addSourceLocation(stmt, startToken);
Yingyi Bu391f09e2015-10-29 13:49:39 -07001016 }
1017}
1018
1019boolean IfExists() throws ParseException :
1020{
1021}
1022{
1023 ( LOOKAHEAD(1) <IF> <EXISTS>
1024 {
1025 return true;
1026 }
1027 )?
1028 {
1029 return false;
1030 }
1031}
1032
1033InsertStatement InsertStatement() throws ParseException:
1034{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07001035 Token startToken = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07001036 Pair<Identifier,Identifier> nameComponents = null;
Yingyi Bucb5bf332017-01-02 22:19:50 -08001037 VariableExpr var = null;
1038 Query query = null;
1039 Expression returnExpression = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07001040}
1041{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07001042 <INSERT> { startToken = token; } <INTO> nameComponents = QualifiedName() (<AS> var = Variable())?
Yingyi Bucb5bf332017-01-02 22:19:50 -08001043 query = Query(false)
1044 ( <RETURNING> returnExpression = Expression())?
Yingyi Bu391f09e2015-10-29 13:49:39 -07001045 {
Yingyi Bucb5bf332017-01-02 22:19:50 -08001046 if (returnExpression != null && var == null) {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07001047 var = ExpressionToVariableUtil.getGeneratedVariable(query.getBody(), true);
Yingyi Bucb5bf332017-01-02 22:19:50 -08001048 }
Yingyi Bucaea8f02015-11-16 15:12:15 -08001049 query.setTopLevel(true);
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07001050 InsertStatement stmt = new InsertStatement(nameComponents.first, nameComponents.second, query, getVarCounter(),
1051 var, returnExpression);
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07001052 return addSourceLocation(stmt, startToken);
Yingyi Bucb5bf332017-01-02 22:19:50 -08001053 }
1054}
1055
1056UpsertStatement UpsertStatement() throws ParseException:
1057{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07001058 Token startToken = null;
Yingyi Bucb5bf332017-01-02 22:19:50 -08001059 Pair<Identifier,Identifier> nameComponents = null;
1060 VariableExpr var = null;
1061 Query query = null;
1062 Expression returnExpression = null;
1063}
1064{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07001065 <UPSERT> { startToken = token; } <INTO> nameComponents = QualifiedName() (<AS> var = Variable())?
Yingyi Bucb5bf332017-01-02 22:19:50 -08001066 query = Query(false)
1067 ( <RETURNING> returnExpression = Expression())?
1068 {
1069 if (returnExpression != null && var == null) {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07001070 var = ExpressionToVariableUtil.getGeneratedVariable(query.getBody(), true);
Yingyi Bucb5bf332017-01-02 22:19:50 -08001071 }
1072 query.setTopLevel(true);
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07001073 UpsertStatement stmt = new UpsertStatement(nameComponents.first, nameComponents.second, query, getVarCounter(),
1074 var, returnExpression);
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07001075 return addSourceLocation(stmt, startToken);
Yingyi Bu391f09e2015-10-29 13:49:39 -07001076 }
1077}
1078
1079DeleteStatement DeleteStatement() throws ParseException:
1080{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07001081 Token startToken = null;
Yingyi Bu20e085b2016-07-06 12:57:27 -07001082 VariableExpr varExpr = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07001083 Expression condition = null;
1084 Pair<Identifier, Identifier> nameComponents;
Yingyi Bu391f09e2015-10-29 13:49:39 -07001085}
1086{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07001087 <DELETE> { startToken = token; }
Yingyi Bu391f09e2015-10-29 13:49:39 -07001088 <FROM> nameComponents = QualifiedName()
Yingyi Bu20e085b2016-07-06 12:57:27 -07001089 ((<AS>)? varExpr = Variable())?
Yingyi Bu391f09e2015-10-29 13:49:39 -07001090 (<WHERE> condition = Expression())?
Yingyi Bu20e085b2016-07-06 12:57:27 -07001091 {
Yingyi Bu20e085b2016-07-06 12:57:27 -07001092 if(varExpr == null){
1093 varExpr = new VariableExpr();
1094 VarIdentifier var = SqlppVariableUtil.toInternalVariableIdentifier(nameComponents.second.getValue());
1095 varExpr.setVar(var);
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07001096 addSourceLocation(varExpr, startToken);
Yingyi Bu20e085b2016-07-06 12:57:27 -07001097 }
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07001098 DeleteStatement stmt = new DeleteStatement(varExpr, nameComponents.first, nameComponents.second,
Abdullah Alamoudi6eb01752017-04-01 21:51:19 -07001099 condition, getVarCounter());
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07001100 return addSourceLocation(stmt, startToken);
Yingyi Bu20e085b2016-07-06 12:57:27 -07001101 }
Yingyi Bu391f09e2015-10-29 13:49:39 -07001102}
1103
1104UpdateStatement UpdateStatement() throws ParseException:
1105{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07001106 Token startToken = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07001107 VariableExpr vars;
1108 Expression target;
1109 Expression condition;
1110 UpdateClause uc;
1111 List<UpdateClause> ucs = new ArrayList<UpdateClause>();
1112}
1113{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07001114 <UPDATE> { startToken = token; } vars = Variable() <IN> target = Expression()
Yingyi Bu391f09e2015-10-29 13:49:39 -07001115 <WHERE> condition = Expression()
1116 <LEFTPAREN> (uc = UpdateClause()
1117 {
1118 ucs.add(uc);
1119 }
1120 (<COMMA> uc = UpdateClause()
1121 {
1122 ucs.add(uc);
1123 }
1124 )*) <RIGHTPAREN>
1125 {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07001126 UpdateStatement stmt = new UpdateStatement(vars, target, condition, ucs);
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07001127 return addSourceLocation(stmt, startToken);
Yingyi Bu391f09e2015-10-29 13:49:39 -07001128 }
1129}
1130
1131UpdateClause UpdateClause() throws ParseException:
1132{
1133 Expression target = null;
1134 Expression value = null ;
1135 InsertStatement is = null;
1136 DeleteStatement ds = null;
1137 UpdateStatement us = null;
1138 Expression condition = null;
1139 UpdateClause ifbranch = null;
1140 UpdateClause elsebranch = null;
1141}
1142{
1143 (<SET> target = Expression() <EQ> value = Expression()
1144 | is = InsertStatement()
1145 | ds = DeleteStatement()
1146 | us = UpdateStatement()
1147 | <IF> <LEFTPAREN> condition = Expression() <RIGHTPAREN>
1148 <THEN> ifbranch = UpdateClause()
1149 [LOOKAHEAD(1) <ELSE> elsebranch = UpdateClause()]
1150 {
1151 return new UpdateClause(target, value, is, ds, us, condition, ifbranch, elsebranch);
1152 }
1153 )
1154}
1155
1156Statement SetStatement() throws ParseException:
1157{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07001158 Token startToken = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07001159 String pn = null;
1160 String pv = null;
1161}
1162{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07001163 <SET> { startToken = token; } pn = Identifier() pv = ConstantString()
Yingyi Bu391f09e2015-10-29 13:49:39 -07001164 {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07001165 SetStatement stmt = new SetStatement(pn, pv);
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07001166 return addSourceLocation(stmt, startToken);
Yingyi Bu391f09e2015-10-29 13:49:39 -07001167 }
1168}
1169
1170Statement WriteStatement() throws ParseException:
1171{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07001172 Token startToken = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07001173 String nodeName = null;
1174 String fileName = null;
1175 Query query;
1176 String writerClass = null;
1177 Pair<Identifier,Identifier> nameComponents = null;
1178}
1179{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07001180 <WRITE> { startToken = token; } <OUTPUT> <TO> nodeName = Identifier() <COLON> fileName = ConstantString()
Yingyi Bu6d57e492016-06-06 21:24:42 -07001181 ( <USING> writerClass = ConstantString() )?
Yingyi Bu391f09e2015-10-29 13:49:39 -07001182 {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07001183 WriteStatement stmt = new WriteStatement(new Identifier(nodeName), fileName, writerClass);
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07001184 return addSourceLocation(stmt, startToken);
Yingyi Bu391f09e2015-10-29 13:49:39 -07001185 }
1186}
1187
1188LoadStatement LoadStatement() throws ParseException:
1189{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07001190 Token startToken = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07001191 Identifier dataverseName = null;
1192 Identifier datasetName = null;
1193 boolean alreadySorted = false;
1194 String adapterName;
1195 Map<String,String> properties;
1196 Pair<Identifier,Identifier> nameComponents = null;
1197}
1198{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07001199 <LOAD> { startToken = token; } Dataset() nameComponents = QualifiedName()
Yingyi Bu391f09e2015-10-29 13:49:39 -07001200 {
1201 dataverseName = nameComponents.first;
1202 datasetName = nameComponents.second;
1203 }
1204 <USING> adapterName = AdapterName() properties = Configuration()
1205 (<PRESORTED>
1206 {
1207 alreadySorted = true;
1208 }
1209 )?
1210 {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07001211 LoadStatement stmt = new LoadStatement(dataverseName, datasetName, adapterName, properties, alreadySorted);
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07001212 return addSourceLocation(stmt, startToken);
Yingyi Bu391f09e2015-10-29 13:49:39 -07001213 }
1214}
1215
1216
1217String AdapterName() throws ParseException :
1218{
1219 String adapterName = null;
1220}
1221{
1222 adapterName = Identifier()
1223 {
1224 return adapterName;
1225 }
1226}
1227
1228Statement CompactStatement() throws ParseException:
1229{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07001230 Token startToken = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07001231 Pair<Identifier,Identifier> nameComponents = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07001232}
1233{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07001234 <COMPACT> { startToken = token; } Dataset() nameComponents = QualifiedName()
Yingyi Bu391f09e2015-10-29 13:49:39 -07001235 {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07001236 CompactStatement stmt = new CompactStatement(nameComponents.first, nameComponents.second);
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07001237 return addSourceLocation(stmt, startToken);
Yingyi Bu391f09e2015-10-29 13:49:39 -07001238 }
1239}
1240
Yingyi Buab817482016-08-19 21:29:31 -07001241Statement ConnectionStatement() throws ParseException:
Yingyi Bu391f09e2015-10-29 13:49:39 -07001242{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07001243 Token startToken = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07001244 Statement stmt = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07001245}
1246{
1247 (
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07001248 <CONNECT> { startToken = token; } stmt = ConnectStatement(startToken)
1249 | <DISCONNECT> { startToken = token; } stmt = DisconnectStatement(startToken)
1250 | <START> { startToken = token; } stmt = StartStatement(startToken)
1251 | <STOP> { startToken = token; } stmt = StopStatement(startToken)
Yingyi Buab817482016-08-19 21:29:31 -07001252 )
1253 {
1254 return stmt;
1255 }
1256}
1257
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07001258Statement StartStatement(Token startStmtToken) throws ParseException:
Abdullah Alamoudifff200c2017-02-18 20:32:14 -08001259{
1260 Pair<Identifier,Identifier> feedNameComponents = null;
1261
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07001262 AbstractStatement stmt = null;
Abdullah Alamoudifff200c2017-02-18 20:32:14 -08001263}
1264{
1265 <FEED> feedNameComponents = QualifiedName()
1266 {
1267 stmt = new StartFeedStatement (feedNameComponents);
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07001268 return addSourceLocation(stmt, startStmtToken);
Abdullah Alamoudifff200c2017-02-18 20:32:14 -08001269 }
1270}
1271
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07001272AbstractStatement StopStatement(Token startStmtToken) throws ParseException:
Abdullah Alamoudifff200c2017-02-18 20:32:14 -08001273{
1274 Pair<Identifier,Identifier> feedNameComponents = null;
1275
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07001276 AbstractStatement stmt = null;
Abdullah Alamoudifff200c2017-02-18 20:32:14 -08001277}
1278{
1279 <FEED> feedNameComponents = QualifiedName()
1280 {
1281 stmt = new StopFeedStatement (feedNameComponents);
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07001282 return addSourceLocation(stmt, startStmtToken);
Abdullah Alamoudifff200c2017-02-18 20:32:14 -08001283 }
1284}
1285
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07001286AbstractStatement DisconnectStatement(Token startStmtToken) throws ParseException:
Yingyi Buab817482016-08-19 21:29:31 -07001287{
1288 Pair<Identifier,Identifier> feedNameComponents = null;
1289 Pair<Identifier,Identifier> datasetNameComponents = null;
1290
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07001291 AbstractStatement stmt = null;
Yingyi Buab817482016-08-19 21:29:31 -07001292}
1293{
1294 (
1295 <FEED> feedNameComponents = QualifiedName() <FROM> Dataset() datasetNameComponents = QualifiedName()
Yingyi Bu391f09e2015-10-29 13:49:39 -07001296 {
1297 stmt = new DisconnectFeedStatement(feedNameComponents, datasetNameComponents);
1298 }
1299 )
Yingyi Buab817482016-08-19 21:29:31 -07001300 {
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07001301 return addSourceLocation(stmt, startStmtToken);
Yingyi Buab817482016-08-19 21:29:31 -07001302 }
1303}
1304
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07001305AbstractStatement ConnectStatement(Token startStmtToken) throws ParseException:
Yingyi Buab817482016-08-19 21:29:31 -07001306{
1307 Pair<Identifier,Identifier> feedNameComponents = null;
1308 Pair<Identifier,Identifier> datasetNameComponents = null;
1309
1310 Map<String,String> configuration = null;
Xikui Wang9d63f622017-05-18 17:50:44 -07001311 List<FunctionSignature> appliedFunctions = new ArrayList<FunctionSignature>();
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07001312 AbstractStatement stmt = null;
Yingyi Buab817482016-08-19 21:29:31 -07001313 String policy = null;
Xikui Wangf6741682018-02-22 19:17:17 -08001314 String whereClauseBody = null;
1315 WhereClause whereClause = null;
1316 Token beginPos = null;
1317 Token endPos = null;
Yingyi Buab817482016-08-19 21:29:31 -07001318}
1319{
1320 (
Abdullah Alamoudifff200c2017-02-18 20:32:14 -08001321 <FEED> feedNameComponents = QualifiedName() <TO> Dataset() datasetNameComponents = QualifiedName()
Xikui Wangf6741682018-02-22 19:17:17 -08001322 (ApplyFunction(appliedFunctions))?
1323 (policy = GetPolicy())?
1324 (
1325 <WHERE>
1326 {
1327 beginPos = token;
1328 whereClause = new WhereClause();
1329 Expression whereExpr;
1330 }
1331 whereExpr = Expression()
1332 {
1333 whereClause.setWhereExpr(whereExpr);
1334 }
1335 )?
1336 {
1337 if (whereClause != null) {
1338 endPos = token;
1339 whereClauseBody = extractFragment(beginPos.endLine, beginPos.endColumn, endPos.endLine, endPos.endColumn + 1);
1340 }
1341 }
Yingyi Buab817482016-08-19 21:29:31 -07001342 {
Xikui Wang261dc6d2017-03-29 21:23:15 -07001343 stmt = new ConnectFeedStatement(feedNameComponents, datasetNameComponents, appliedFunctions,
Xikui Wangf6741682018-02-22 19:17:17 -08001344 policy, whereClauseBody, getVarCounter());
Yingyi Buab817482016-08-19 21:29:31 -07001345 }
1346 )
1347 {
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07001348 return addSourceLocation(stmt, startStmtToken);
Yingyi Buab817482016-08-19 21:29:31 -07001349 }
Yingyi Bu391f09e2015-10-29 13:49:39 -07001350}
1351
1352Map<String,String> Configuration() throws ParseException :
1353{
1354 Map<String,String> configuration = new LinkedHashMap<String,String>();
1355 Pair<String, String> keyValuePair = null;
1356}
1357{
1358 <LEFTPAREN> ( keyValuePair = KeyValuePair()
1359 {
1360 configuration.put(keyValuePair.first, keyValuePair.second);
1361 }
1362 ( <COMMA> keyValuePair = KeyValuePair()
1363 {
1364 configuration.put(keyValuePair.first, keyValuePair.second);
1365 }
1366 )* )? <RIGHTPAREN>
1367 {
1368 return configuration;
1369 }
1370}
1371
1372Pair<String, String> KeyValuePair() throws ParseException:
1373{
1374 String key;
1375 String value;
1376}
1377{
Yingyi Bu6d57e492016-06-06 21:24:42 -07001378 <LEFTPAREN> key = ConstantString() <EQ> value = ConstantString() <RIGHTPAREN>
Yingyi Bu391f09e2015-10-29 13:49:39 -07001379 {
1380 return new Pair<String, String>(key, value);
1381 }
1382}
1383
1384Map<String,String> Properties() throws ParseException:
1385{
1386 Map<String,String> properties = new HashMap<String,String>();
1387 Pair<String, String> property;
1388}
1389{
1390 (LOOKAHEAD(1) <LEFTPAREN> property = Property()
1391 {
1392 properties.put(property.first, property.second);
1393 }
1394 ( <COMMA> property = Property()
1395 {
1396 properties.put(property.first, property.second);
1397 }
1398 )* <RIGHTPAREN> )?
1399 {
1400 return properties;
1401 }
1402}
1403
1404Pair<String, String> Property() throws ParseException:
1405{
Yingyi Bu6d57e492016-06-06 21:24:42 -07001406 String key = null;
1407 String value = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07001408}
1409{
Yingyi Bu6d57e492016-06-06 21:24:42 -07001410 (key = Identifier() | key = StringLiteral())
1411 <EQ>
1412 ( value = ConstantString() | <INTEGER_LITERAL>
Yingyi Bu391f09e2015-10-29 13:49:39 -07001413 {
1414 try {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07001415 value = String.valueOf(Long.parseLong(token.image));
Yingyi Bu391f09e2015-10-29 13:49:39 -07001416 } catch (NumberFormatException nfe) {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07001417 throw new SqlppParseException(getSourceLocation(token), "inapproriate value: " + token.image);
Yingyi Bu391f09e2015-10-29 13:49:39 -07001418 }
1419 }
1420 )
1421 {
1422 return new Pair<String, String>(key.toUpperCase(), value);
1423 }
1424}
1425
Dmitry Lychagin8ba59442017-06-16 14:19:45 -07001426IndexedTypeExpression IndexedTypeExpr() throws ParseException:
Yingyi Bu391f09e2015-10-29 13:49:39 -07001427{
1428 TypeExpression typeExpr = null;
Dmitry Lychagin8ba59442017-06-16 14:19:45 -07001429 boolean isUnknownable = false;
Yingyi Bu391f09e2015-10-29 13:49:39 -07001430}
1431{
1432 (
1433 typeExpr = TypeReference()
1434 | typeExpr = OrderedListTypeDef()
1435 | typeExpr = UnorderedListTypeDef()
1436 )
Dmitry Lychagin8ba59442017-06-16 14:19:45 -07001437 ( <QUES> { isUnknownable = true; } )?
Yingyi Bu391f09e2015-10-29 13:49:39 -07001438 {
Dmitry Lychagin8ba59442017-06-16 14:19:45 -07001439 return new IndexedTypeExpression(typeExpr, isUnknownable);
Yingyi Bu391f09e2015-10-29 13:49:39 -07001440 }
1441}
1442
1443TypeExpression TypeExpr() throws ParseException:
1444{
1445 TypeExpression typeExpr = null;
1446}
1447{
1448 (
1449 typeExpr = RecordTypeDef()
1450 | typeExpr = TypeReference()
1451 | typeExpr = OrderedListTypeDef()
1452 | typeExpr = UnorderedListTypeDef()
1453 )
1454 {
1455 return typeExpr;
1456 }
1457}
1458
1459RecordTypeDefinition RecordTypeDef() throws ParseException:
1460{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07001461 Token startToken = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07001462 RecordTypeDefinition recType = new RecordTypeDefinition();
1463 RecordTypeDefinition.RecordKind recordKind = null;
1464}
1465{
1466 ( <CLOSED> { recordKind = RecordTypeDefinition.RecordKind.CLOSED; }
1467 | <OPEN> { recordKind = RecordTypeDefinition.RecordKind.OPEN; } )?
1468 <LEFTBRACE>
1469 {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07001470 startToken = token;
Yingyi Bu391f09e2015-10-29 13:49:39 -07001471 String hint = getHint(token);
1472 if (hint != null) {
1473 String splits[] = hint.split(" +");
1474 if (splits[0].equals(GEN_FIELDS_HINT)) {
1475 if (splits.length != 5) {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07001476 throw new SqlppParseException(getSourceLocation(getHintToken(token)),
1477 "Expecting: /*+ gen-fields <type> <min> <max> <prefix>*/");
Yingyi Bu391f09e2015-10-29 13:49:39 -07001478 }
1479 if (!splits[1].equals("int")) {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07001480 throw new SqlppParseException(getSourceLocation(getHintToken(token)),
1481 "The only supported type for gen-fields is int.");
Yingyi Bu391f09e2015-10-29 13:49:39 -07001482 }
1483 UndeclaredFieldsDataGen ufdg = new UndeclaredFieldsDataGen(UndeclaredFieldsDataGen.Type.INT,
1484 Integer.parseInt(splits[2]), Integer.parseInt(splits[3]), splits[4]);
1485 recType.setUndeclaredFieldsDataGen(ufdg);
1486 }
1487 }
1488
1489 }
1490 (
1491 RecordField(recType)
1492 ( <COMMA> RecordField(recType) )*
1493 )?
1494 <RIGHTBRACE>
1495 {
1496 if (recordKind == null) {
1497 recordKind = RecordTypeDefinition.RecordKind.OPEN;
1498 }
1499 recType.setRecordKind(recordKind);
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07001500 return addSourceLocation(recType, startToken);
Yingyi Bu391f09e2015-10-29 13:49:39 -07001501 }
1502}
1503
1504void RecordField(RecordTypeDefinition recType) throws ParseException:
1505{
1506 String fieldName;
1507 TypeExpression type = null;
1508 boolean nullable = false;
1509}
1510{
1511 fieldName = Identifier()
1512 {
1513 String hint = getHint(token);
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07001514 IRecordFieldDataGen rfdg = hint != null ? parseFieldDataGen(hint, token.specialToken) : null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07001515 }
1516 <COLON> type = TypeExpr() (<QUES> { nullable = true; } )?
1517 {
1518 recType.addField(fieldName, type, nullable, rfdg);
1519 }
1520}
1521
1522TypeReferenceExpression TypeReference() throws ParseException:
1523{
Abdullah Alamoudie4b318f2016-09-19 13:31:25 +03001524 Pair<Identifier,Identifier> id = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07001525}
1526{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07001527 id = QualifiedName()
1528 {
1529 if (id.first == null && id.second.getValue().equalsIgnoreCase("int")) {
1530 id.second.setValue("int64");
1531 }
Yingyi Bu391f09e2015-10-29 13:49:39 -07001532
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07001533 TypeReferenceExpression typeRef = new TypeReferenceExpression(id);
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07001534 return addSourceLocation(typeRef, token);
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07001535 }
Yingyi Bu391f09e2015-10-29 13:49:39 -07001536}
1537
1538OrderedListTypeDefinition OrderedListTypeDef() throws ParseException:
1539{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07001540 Token startToken = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07001541 TypeExpression type = null;
1542}
1543{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07001544 <LEFTBRACKET> { startToken = token; }
1545 ( type = TypeExpr() )
Yingyi Bu391f09e2015-10-29 13:49:39 -07001546 <RIGHTBRACKET>
1547 {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07001548 OrderedListTypeDefinition typeDef = new OrderedListTypeDefinition(type);
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07001549 return addSourceLocation(typeDef, startToken);
Yingyi Bu391f09e2015-10-29 13:49:39 -07001550 }
1551}
1552
Yingyi Bu391f09e2015-10-29 13:49:39 -07001553UnorderedListTypeDefinition UnorderedListTypeDef() throws ParseException:
1554{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07001555 Token startToken = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07001556 TypeExpression type = null;
1557}
1558{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07001559 <LEFTDBLBRACE> { startToken = token; }
Yingyi Bu391f09e2015-10-29 13:49:39 -07001560 ( type = TypeExpr() )
1561 <RIGHTDBLBRACE>
1562 {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07001563 UnorderedListTypeDefinition typeDef = new UnorderedListTypeDefinition(type);
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07001564 return addSourceLocation(typeDef, startToken);
Yingyi Bu391f09e2015-10-29 13:49:39 -07001565 }
1566}
1567
1568FunctionName FunctionName() throws ParseException:
1569{
1570 String first = null;
1571 String second = null;
1572 String third = null;
1573 boolean secondAfterDot = false;
1574}
1575{
Michael Blowd6cf6412016-06-30 02:44:35 -04001576 first = Identifier()
Yingyi Bu391f09e2015-10-29 13:49:39 -07001577 {
1578 FunctionName result = new FunctionName();
1579 result.hint = getHint(token);
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07001580 result.sourceLoc = getSourceLocation(token);
Michael Blowd6cf6412016-06-30 02:44:35 -04001581 }
Yingyi Bu391f09e2015-10-29 13:49:39 -07001582 ( <DOT> second = Identifier()
1583 {
1584 secondAfterDot = true;
1585 }
1586 (<SHARP> third = Identifier())? | <SHARP> second = Identifier() )?
1587 {
1588 if (second == null) {
1589 result.dataverse = defaultDataverse;
1590 result.library = null;
1591 result.function = first;
1592 } else if (third == null) {
1593 if (secondAfterDot) {
1594 result.dataverse = first;
1595 result.library = null;
1596 result.function = second;
1597 } else {
1598 result.dataverse = defaultDataverse;
1599 result.library = first;
1600 result.function = second;
1601 }
1602 } else {
1603 result.dataverse = first;
1604 result.library = second;
1605 result.function = third;
1606 }
1607
1608 if (result.function.equalsIgnoreCase("int")) {
1609 result.function = "int64";
1610 }
1611 return result;
1612 }
1613}
1614
1615Pair<Identifier,Identifier> TypeName() throws ParseException:
1616{
1617 Pair<Identifier,Identifier> name = null;
1618}
1619{
1620 name = QualifiedName()
1621 {
1622 if (name.first == null) {
1623 name.first = new Identifier(defaultDataverse);
1624 }
1625 return name;
1626 }
1627}
1628
1629String Identifier() throws ParseException:
1630{
1631 String lit = null;
1632}
1633{
1634 (<IDENTIFIER>
1635 {
1636 return token.image;
1637 }
1638 | lit = QuotedString()
1639 {
1640 return lit;
1641 }
1642 )
1643}
1644
Yingyi Bu1c0fff52016-03-25 20:23:30 -07001645void Dataset() throws ParseException:
1646{
1647}
1648{
1649 (<DATASET>|<COLLECTION>)
1650}
1651
Dmitry Lychagin8ba59442017-06-16 14:19:45 -07001652Pair<Integer, Pair<List<String>, IndexedTypeExpression>> OpenField() throws ParseException:
Yingyi Bu391f09e2015-10-29 13:49:39 -07001653{
Dmitry Lychagin8ba59442017-06-16 14:19:45 -07001654 IndexedTypeExpression fieldType = null;
Yingyi Buc9bfe252016-03-01 00:02:40 -08001655 Pair<Integer, List<String>> fieldList = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07001656}
1657{
1658 fieldList = NestedField()
Dmitry Lychagin8ba59442017-06-16 14:19:45 -07001659 ( <COLON> fieldType = IndexedTypeExpr() )?
Yingyi Bu391f09e2015-10-29 13:49:39 -07001660 {
Dmitry Lychagin8ba59442017-06-16 14:19:45 -07001661 return new Pair<Integer, Pair<List<String>, IndexedTypeExpression>>
1662 (fieldList.first, new Pair<List<String>, IndexedTypeExpression>(fieldList.second, fieldType));
Yingyi Bu391f09e2015-10-29 13:49:39 -07001663 }
1664}
1665
Yingyi Buc9bfe252016-03-01 00:02:40 -08001666Pair<Integer, List<String>> NestedField() throws ParseException:
Yingyi Bu391f09e2015-10-29 13:49:39 -07001667{
1668 List<String> exprList = new ArrayList<String>();
1669 String lit = null;
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07001670 Token litToken = null;
Yingyi Buc9bfe252016-03-01 00:02:40 -08001671 int source = 0;
Yingyi Bu391f09e2015-10-29 13:49:39 -07001672}
1673{
1674 lit = Identifier()
1675 {
Yingyi Bub9169b62016-02-26 21:21:49 -08001676 boolean meetParens = false;
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07001677 litToken = token;
Yingyi Bub9169b62016-02-26 21:21:49 -08001678 }
1679 (
Yingyi Buc9bfe252016-03-01 00:02:40 -08001680 LOOKAHEAD(1)
Yingyi Bub9169b62016-02-26 21:21:49 -08001681 <LEFTPAREN><RIGHTPAREN>
1682 {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07001683 if(!lit.equalsIgnoreCase("meta")){
1684 throw new SqlppParseException(getSourceLocation(litToken), "The string before () has to be \"meta\".");
Yingyi Bub9169b62016-02-26 21:21:49 -08001685 }
1686 meetParens = true;
Yingyi Buc9bfe252016-03-01 00:02:40 -08001687 source = 1;
Yingyi Bub9169b62016-02-26 21:21:49 -08001688 }
1689 )?
1690 {
1691 if(!meetParens){
1692 exprList.add(lit);
1693 }
Yingyi Bu391f09e2015-10-29 13:49:39 -07001694 }
1695 (<DOT>
1696 lit = Identifier()
1697 {
1698 exprList.add(lit);
1699 }
1700 )*
1701 {
Yingyi Buc9bfe252016-03-01 00:02:40 -08001702 return new Pair<Integer, List<String>>(source, exprList);
Yingyi Bu391f09e2015-10-29 13:49:39 -07001703 }
1704}
1705
Yingyi Bu6d57e492016-06-06 21:24:42 -07001706String ConstantString() throws ParseException:
1707{
1708 String value = null;
1709}
1710{
1711 (value = QuotedString() | value = StringLiteral())
1712 {
1713 return value;
1714 }
1715}
1716
Yingyi Bu391f09e2015-10-29 13:49:39 -07001717String QuotedString() throws ParseException:
1718{
1719}
1720{
1721 <QUOTED_STRING>
1722 {
1723 return removeQuotesAndEscapes(token.image);
1724 }
1725}
1726
Yingyi Bu391f09e2015-10-29 13:49:39 -07001727String StringLiteral() throws ParseException:
1728{
1729}
1730{
1731 <STRING_LITERAL>
1732 {
1733 return removeQuotesAndEscapes(token.image);
1734 }
1735}
1736
1737Pair<Identifier,Identifier> QualifiedName() throws ParseException:
1738{
1739 String first = null;
1740 String second = null;
1741}
1742{
1743 first = Identifier() (<DOT> second = Identifier())?
1744 {
1745 Identifier id1 = null;
1746 Identifier id2 = null;
1747 if (second == null) {
1748 id2 = new Identifier(first);
1749 } else
1750 {
1751 id1 = new Identifier(first);
1752 id2 = new Identifier(second);
1753 }
1754 return new Pair<Identifier,Identifier>(id1, id2);
1755 }
1756}
1757
1758Triple<Identifier,Identifier,Identifier> DoubleQualifiedName() throws ParseException:
1759{
1760 String first = null;
1761 String second = null;
1762 String third = null;
1763}
1764{
1765 first = Identifier() <DOT> second = Identifier() (<DOT> third = Identifier())?
1766 {
1767 Identifier id1 = null;
1768 Identifier id2 = null;
1769 Identifier id3 = null;
1770 if (third == null) {
1771 id2 = new Identifier(first);
1772 id3 = new Identifier(second);
1773 } else {
1774 id1 = new Identifier(first);
1775 id2 = new Identifier(second);
1776 id3 = new Identifier(third);
1777 }
1778 return new Triple<Identifier,Identifier,Identifier>(id1, id2, id3);
1779 }
1780}
1781
1782FunctionDecl FunctionDeclaration() throws ParseException:
1783{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07001784 Token startToken = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07001785 String functionName;
1786 List<VarIdentifier> paramList = new ArrayList<VarIdentifier>();
1787 Expression funcBody;
1788 createNewScope();
1789}
1790{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07001791 <DECLARE> { startToken = token; } <FUNCTION>
Xikui Wang3de700a2018-03-15 16:32:55 -07001792 functionName = Identifier()
1793 paramList = ParameterList()
1794 <LEFTBRACE>
1795 (funcBody = SelectExpression(true) | funcBody = Expression())
1796 <RIGHTBRACE>
1797 {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07001798 FunctionSignature signature = new FunctionSignature(defaultDataverse, functionName, paramList.size());
Xikui Wang3de700a2018-03-15 16:32:55 -07001799 getCurrentScope().addFunctionDescriptor(signature, false);
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07001800 FunctionDecl stmt = new FunctionDecl(signature, paramList, funcBody);
Xikui Wang3de700a2018-03-15 16:32:55 -07001801 removeCurrentScope();
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07001802 return addSourceLocation(stmt, startToken);
Xikui Wang3de700a2018-03-15 16:32:55 -07001803 }
Yingyi Bu391f09e2015-10-29 13:49:39 -07001804}
1805
Till Westmannef3f0272016-07-27 18:34:01 -07001806Query ExplainStatement() throws ParseException:
Yingyi Bu391f09e2015-10-29 13:49:39 -07001807{
Till Westmannef3f0272016-07-27 18:34:01 -07001808 Query query;
1809}
1810{
Till Westmann516d1a82016-08-02 14:45:53 -07001811 <EXPLAIN> query = Query(true)
Till Westmannef3f0272016-07-27 18:34:01 -07001812 {
1813 return query;
1814 }
1815}
1816
1817Query Query(boolean explain) throws ParseException:
1818{
1819 Query query = new Query(explain);
Yingyi Bu391f09e2015-10-29 13:49:39 -07001820 Expression expr;
1821}
1822{
1823 (
1824 expr = Expression()
1825 |
1826 expr = SelectExpression(false)
1827 )
1828 {
1829 query.setBody(expr);
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07001830 query.setSourceLocation(expr.getSourceLocation());
Yingyi Bu391f09e2015-10-29 13:49:39 -07001831 return query;
1832 }
1833}
1834
1835
Yingyi Bu391f09e2015-10-29 13:49:39 -07001836Expression Expression():
1837{
1838 Expression expr = null;
1839 Expression exprP = null;
1840}
1841{
1842(
1843 LOOKAHEAD(2)
1844 expr = OperatorExpr()
Yingyi Bu391f09e2015-10-29 13:49:39 -07001845 | expr = QuantifiedExpression()
1846)
1847 {
1848 return (exprP==null) ? expr : exprP;
1849 }
1850}
1851
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07001852Expression OperatorExpr() throws ParseException:
Yingyi Bu391f09e2015-10-29 13:49:39 -07001853{
1854 OperatorExpr op = null;
1855 Expression operand = null;
1856}
1857{
1858 operand = AndExpr()
1859 (
Yingyi Bu391f09e2015-10-29 13:49:39 -07001860 <OR>
1861 {
1862 if (op == null) {
1863 op = new OperatorExpr();
1864 op.addOperand(operand);
Xikui Wang3de700a2018-03-15 16:32:55 -07001865 op.setCurrentop(true);
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07001866 addSourceLocation(op, token);
Yingyi Bu391f09e2015-10-29 13:49:39 -07001867 }
Yingyi Bu196db5d2016-07-15 19:07:20 -07001868 try{
1869 op.addOperator(token.image.toLowerCase());
1870 } catch (Exception e){
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07001871 throw new SqlppParseException(getSourceLocation(token), e.getMessage());
Yingyi Bu196db5d2016-07-15 19:07:20 -07001872 }
Xikui Wang3de700a2018-03-15 16:32:55 -07001873 }
Yingyi Bu391f09e2015-10-29 13:49:39 -07001874
Xikui Wang3de700a2018-03-15 16:32:55 -07001875 operand = AndExpr()
1876 {
1877 op.addOperand(operand);
1878 }
Yingyi Bu391f09e2015-10-29 13:49:39 -07001879
1880 )*
1881
1882 {
1883 return op==null? operand: op;
1884 }
1885}
1886
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07001887Expression AndExpr() throws ParseException:
Yingyi Bu391f09e2015-10-29 13:49:39 -07001888{
1889 OperatorExpr op = null;
1890 Expression operand = null;
1891}
1892{
Yingyi Bu196db5d2016-07-15 19:07:20 -07001893 operand = NotExpr()
Yingyi Bu391f09e2015-10-29 13:49:39 -07001894 (
Yingyi Bu391f09e2015-10-29 13:49:39 -07001895 <AND>
1896 {
1897 if (op == null) {
1898 op = new OperatorExpr();
1899 op.addOperand(operand);
Yingyi Bu196db5d2016-07-15 19:07:20 -07001900 op.setCurrentop(true);
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07001901 addSourceLocation(op, token);
Yingyi Bu391f09e2015-10-29 13:49:39 -07001902 }
Yingyi Bu196db5d2016-07-15 19:07:20 -07001903 try{
1904 op.addOperator(token.image.toLowerCase());
Taewoo Kime65e6ca2017-01-14 17:53:28 -08001905 } catch (CompilationException e){
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07001906 throw new SqlppParseException(getSourceLocation(token), e.getMessage());
Yingyi Bu196db5d2016-07-15 19:07:20 -07001907 }
Yingyi Bu391f09e2015-10-29 13:49:39 -07001908 }
1909
Yingyi Bu196db5d2016-07-15 19:07:20 -07001910 operand = NotExpr()
Yingyi Bu391f09e2015-10-29 13:49:39 -07001911 {
1912 op.addOperand(operand);
1913 }
1914
1915 )*
1916
1917 {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07001918 return op==null ? operand: op;
Yingyi Bu391f09e2015-10-29 13:49:39 -07001919 }
1920}
1921
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07001922Expression NotExpr() throws ParseException:
Yingyi Bu196db5d2016-07-15 19:07:20 -07001923{
1924 Expression inputExpr;
1925 boolean not = false;
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07001926 Token startToken = null;
Yingyi Bu196db5d2016-07-15 19:07:20 -07001927}
1928{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07001929 (<NOT> { not = true; startToken = token; } )? inputExpr = RelExpr()
Yingyi Bu196db5d2016-07-15 19:07:20 -07001930 {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07001931 if(not) {
Dmitry Lychagin7c53fcf2017-11-07 12:07:41 -08001932 FunctionSignature signature = new FunctionSignature(BuiltinFunctions.NOT);
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07001933 CallExpr callExpr = new CallExpr(signature, new ArrayList<Expression>(Collections.singletonList(inputExpr)));
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07001934 return addSourceLocation(callExpr, startToken);
Yingyi Bu196db5d2016-07-15 19:07:20 -07001935 } else {
1936 return inputExpr;
1937 }
1938 }
1939}
Yingyi Bu391f09e2015-10-29 13:49:39 -07001940
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07001941Expression RelExpr() throws ParseException:
Yingyi Bu391f09e2015-10-29 13:49:39 -07001942{
Yingyi Bua8baf6d2016-07-05 21:40:44 -07001943 boolean not = false;
Yingyi Bu391f09e2015-10-29 13:49:39 -07001944 OperatorExpr op = null;
1945 Expression operand = null;
1946 boolean broadcast = false;
1947 IExpressionAnnotation annotation = null;
1948}
1949{
Yingyi Bu6c638342016-09-02 17:54:34 -07001950 operand = BetweenExpr()
Yingyi Bu391f09e2015-10-29 13:49:39 -07001951
1952 (
Yingyi Bu6e6a80c2017-01-21 20:18:49 -08001953 LOOKAHEAD(2)( <LT> | <GT> | <LE> | <GE> | <EQ> | <NE> | <LG> |<SIMILAR> | (<NOT> { not = true; })? <IN>)
Yingyi Bu391f09e2015-10-29 13:49:39 -07001954 {
1955 String mhint = getHint(token);
1956 if (mhint != null) {
1957 if (mhint.equals(INDEXED_NESTED_LOOP_JOIN_HINT)) {
Yingyi Bua8baf6d2016-07-05 21:40:44 -07001958 annotation = IndexedNLJoinExpressionAnnotation.INSTANCE;
1959 } else if (mhint.equals(SKIP_SECONDARY_INDEX_SEARCH_HINT)) {
1960 annotation = SkipSecondaryIndexSearchExpressionAnnotation.INSTANCE;
Yingyi Buea4ec722016-11-04 01:26:16 -07001961 } else if (mhint.equals(BROADCAST_JOIN_HINT)) {
1962 broadcast = true;
Yingyi Bua8baf6d2016-07-05 21:40:44 -07001963 }
Yingyi Bu391f09e2015-10-29 13:49:39 -07001964 }
Yingyi Buea4ec722016-11-04 01:26:16 -07001965
Yingyi Bua8baf6d2016-07-05 21:40:44 -07001966 String operator = token.image.toLowerCase();
Yingyi Bu4a4b8962016-09-16 12:09:11 -07001967 if (operator.equals("<>")){
1968 operator = "!=";
1969 }
1970 if (not) {
Yingyi Bua8baf6d2016-07-05 21:40:44 -07001971 operator = "not_" + operator;
1972 }
Yingyi Bu391f09e2015-10-29 13:49:39 -07001973 if (op == null) {
1974 op = new OperatorExpr();
Yingyi Buea4ec722016-11-04 01:26:16 -07001975 op.addOperand(operand, false); // broadcast is always for the right branch
Yingyi Bua8baf6d2016-07-05 21:40:44 -07001976 op.setCurrentop(true);
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07001977 addSourceLocation(op, token);
Yingyi Bu391f09e2015-10-29 13:49:39 -07001978 }
Yingyi Bu196db5d2016-07-15 19:07:20 -07001979 try{
1980 op.addOperator(operator);
Taewoo Kime65e6ca2017-01-14 17:53:28 -08001981 } catch (CompilationException e){
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07001982 throw new SqlppParseException(getSourceLocation(token), e.getMessage());
Yingyi Bu196db5d2016-07-15 19:07:20 -07001983 }
Yingyi Bua8baf6d2016-07-05 21:40:44 -07001984 }
Yingyi Bu391f09e2015-10-29 13:49:39 -07001985
Yingyi Bu6c638342016-09-02 17:54:34 -07001986 operand = BetweenExpr()
Yingyi Buea4ec722016-11-04 01:26:16 -07001987 {
Yingyi Bu391f09e2015-10-29 13:49:39 -07001988 op.addOperand(operand, broadcast);
Yingyi Buea4ec722016-11-04 01:26:16 -07001989 }
Yingyi Bu391f09e2015-10-29 13:49:39 -07001990 )?
1991
1992 {
1993 if (annotation != null) {
1994 op.addHint(annotation);
1995 }
1996 return op==null? operand: op;
1997 }
1998}
1999
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002000Expression BetweenExpr() throws ParseException:
Yingyi Bu6c638342016-09-02 17:54:34 -07002001{
2002 boolean not = false;
2003 OperatorExpr op = null;
2004 Expression operand = null;
2005 IExpressionAnnotation annotation = null;
2006}
2007{
2008 operand = IsExpr()
2009 (
2010 LOOKAHEAD(2)
2011 (<NOT> { not = true; })? <BETWEEN>
2012 {
2013 String mhint = getHint(token);
2014 if (mhint != null) {
2015 if (mhint.equals(INDEXED_NESTED_LOOP_JOIN_HINT)) {
2016 annotation = IndexedNLJoinExpressionAnnotation.INSTANCE;
2017 } else if (mhint.equals(SKIP_SECONDARY_INDEX_SEARCH_HINT)) {
2018 annotation = SkipSecondaryIndexSearchExpressionAnnotation.INSTANCE;
2019 }
2020 }
2021 String operator = token.image.toLowerCase();
2022 if(not){
2023 operator = "not_" + operator;
2024 }
2025 if (op == null) {
2026 op = new OperatorExpr();
2027 op.addOperand(operand);
2028 op.setCurrentop(true);
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07002029 addSourceLocation(op, token);
Yingyi Bu6c638342016-09-02 17:54:34 -07002030 }
2031 try{
2032 op.addOperator(operator);
Taewoo Kime65e6ca2017-01-14 17:53:28 -08002033 } catch (CompilationException e){
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002034 throw new SqlppParseException(getSourceLocation(token), e.getMessage());
Yingyi Bu6c638342016-09-02 17:54:34 -07002035 }
2036 }
2037
2038 operand = IsExpr()
2039 {
2040 op.addOperand(operand);
2041 }
2042
2043 <AND>
2044 operand = IsExpr()
2045 {
Dmitry Lychaginef1719e2017-12-15 08:33:07 -08002046 op.addOperator(OperatorType.AND);
Yingyi Bu6c638342016-09-02 17:54:34 -07002047 op.addOperand(operand);
2048 }
2049 )?
2050
2051 {
2052 if (annotation != null) {
2053 op.addHint(annotation);
2054 }
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002055 return op==null ? operand: op;
Yingyi Bu6c638342016-09-02 17:54:34 -07002056 }
2057}
2058
Yingyi Budaa549c2016-06-28 22:30:52 -07002059Expression IsExpr() throws ParseException:
2060{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002061 Token notToken = null;
2062 CallExpr expr = null;
Yingyi Budaa549c2016-06-28 22:30:52 -07002063 Expression operand = null;
2064 boolean not = false;
Dmitry Lychagin7c53fcf2017-11-07 12:07:41 -08002065 FunctionIdentifier fn = null;
Yingyi Budaa549c2016-06-28 22:30:52 -07002066}
2067{
Yingyi Bu6e6a80c2017-01-21 20:18:49 -08002068 operand = LikeExpr()
Dmitry Lychagin7c53fcf2017-11-07 12:07:41 -08002069 ( <IS>
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002070 (<NOT> { not = true; notToken = token; })?
Dmitry Lychagin7c53fcf2017-11-07 12:07:41 -08002071 (
2072 <NULL> { fn = BuiltinFunctions.IS_NULL; } |
2073 <MISSING> { fn = BuiltinFunctions.IS_MISSING; } |
Dmitry Lychagin7d594a32018-01-15 14:31:03 -08002074 <UNKNOWN> { fn = BuiltinFunctions.IS_UNKNOWN; } |
Dmitry Lychagin1aa0dd42018-04-17 14:35:24 -07002075 (<KNOWN> | <VALUED>) { not = !not; fn = BuiltinFunctions.IS_UNKNOWN; }
Dmitry Lychagin7c53fcf2017-11-07 12:07:41 -08002076 )
Yingyi Budaa549c2016-06-28 22:30:52 -07002077 {
Dmitry Lychagin7c53fcf2017-11-07 12:07:41 -08002078 FunctionSignature signature = new FunctionSignature(fn);
Yingyi Budaa549c2016-06-28 22:30:52 -07002079 expr = new CallExpr(signature, new ArrayList<Expression>(Collections.singletonList(operand)));
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07002080 addSourceLocation(expr, token);
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002081 if (not) {
Dmitry Lychagin7c53fcf2017-11-07 12:07:41 -08002082 FunctionSignature notSignature = new FunctionSignature(BuiltinFunctions.NOT);
Yingyi Budaa549c2016-06-28 22:30:52 -07002083 expr = new CallExpr(notSignature, new ArrayList<Expression>(Collections.singletonList(expr)));
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07002084 addSourceLocation(expr, notToken);
Yingyi Budaa549c2016-06-28 22:30:52 -07002085 }
2086 }
2087 )?
2088 {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002089 return expr == null ? operand : expr;
Yingyi Budaa549c2016-06-28 22:30:52 -07002090 }
2091}
2092
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002093Expression LikeExpr() throws ParseException:
Yingyi Bu6e6a80c2017-01-21 20:18:49 -08002094{
2095 boolean not = false;
2096 OperatorExpr op = null;
2097 Expression operand = null;
2098}
2099{
2100 operand = ConcatExpr()
2101 (
2102 LOOKAHEAD(2)
2103 (<NOT> { not = true; })? <LIKE>
2104 {
2105 op = new OperatorExpr();
2106 op.addOperand(operand);
2107 op.setCurrentop(true);
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07002108 addSourceLocation(op, token);
Yingyi Bu6e6a80c2017-01-21 20:18:49 -08002109
2110 String operator = token.image.toLowerCase();
2111 if (not) {
2112 operator = "not_" + operator;
2113 }
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002114 try {
Yingyi Bu6e6a80c2017-01-21 20:18:49 -08002115 op.addOperator(operator);
2116 } catch (CompilationException e){
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002117 throw new SqlppParseException(getSourceLocation(token), e.getMessage());
Yingyi Bu6e6a80c2017-01-21 20:18:49 -08002118 }
2119 }
2120
2121 operand = ConcatExpr()
2122 {
2123 op.addOperand(operand);
2124 }
2125 )?
2126
2127 {
2128 return op == null ? operand : op;
2129 }
2130}
2131
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002132Expression ConcatExpr() throws ParseException:
Yingyi Bufdc71eb2016-08-24 22:41:57 -07002133{
2134 OperatorExpr op = null;
2135 Expression operand = null;
2136}
2137{
2138 operand = AddExpr()
2139 (
2140 LOOKAHEAD(1)
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002141 <CONCAT>
Yingyi Bufdc71eb2016-08-24 22:41:57 -07002142 {
2143 if (op == null) {
2144 op = new OperatorExpr();
2145 op.addOperand(operand);
2146 op.setCurrentop(true);
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07002147 addSourceLocation(op, token);
Yingyi Bufdc71eb2016-08-24 22:41:57 -07002148 }
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002149 op.addOperator(OperatorType.CONCAT);
Yingyi Bufdc71eb2016-08-24 22:41:57 -07002150 }
2151 operand = AddExpr()
2152 {
2153 op.addOperand(operand);
2154 }
2155 )*
2156
2157 {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002158 return op == null ? operand : op;
Yingyi Bufdc71eb2016-08-24 22:41:57 -07002159 }
2160}
Yingyi Budaa549c2016-06-28 22:30:52 -07002161
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002162Expression AddExpr() throws ParseException:
Yingyi Bu391f09e2015-10-29 13:49:39 -07002163{
2164 OperatorExpr op = null;
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002165 OperatorType opType = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07002166 Expression operand = null;
2167}
2168{
2169 operand = MultExpr()
Yingyi Budaa549c2016-06-28 22:30:52 -07002170 (
Yingyi Bufdc71eb2016-08-24 22:41:57 -07002171 LOOKAHEAD(1)
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002172 (<PLUS> { opType = OperatorType.PLUS; } | <MINUS> { opType = OperatorType.MINUS; } )
Yingyi Bu391f09e2015-10-29 13:49:39 -07002173 {
2174 if (op == null) {
2175 op = new OperatorExpr();
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002176 op.addOperand(operand);
2177 op.setCurrentop(true);
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07002178 addSourceLocation(op, token);
Yingyi Bu391f09e2015-10-29 13:49:39 -07002179 }
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002180 op.addOperator(opType);
Yingyi Bu391f09e2015-10-29 13:49:39 -07002181 }
2182
2183 operand = MultExpr()
2184 {
2185 op.addOperand(operand);
2186 }
2187 )*
2188
2189 {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002190 return op == null ? operand : op;
Yingyi Bu391f09e2015-10-29 13:49:39 -07002191 }
2192}
2193
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002194Expression MultExpr() throws ParseException:
Yingyi Bu391f09e2015-10-29 13:49:39 -07002195{
2196 OperatorExpr op = null;
Dmitry Lychaginbf48c492018-05-01 18:30:27 -07002197 OperatorType opType = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07002198 Expression operand = null;
2199}
2200{
Yingyi Bu79ccdac2016-07-26 23:49:24 -07002201 operand = ExponentExpr()
Yingyi Bu391f09e2015-10-29 13:49:39 -07002202
Dmitry Lychaginbf48c492018-05-01 18:30:27 -07002203 ( (
2204 <MUL> { opType = OperatorType.MUL; } |
2205 <DIVIDE> { opType = OperatorType.DIVIDE; } |
2206 <DIV> { opType = OperatorType.DIV; } |
2207 ( <MOD> | <PERCENT> ) { opType = OperatorType.MOD; }
2208 )
Yingyi Bu391f09e2015-10-29 13:49:39 -07002209 {
2210 if (op == null) {
2211 op = new OperatorExpr();
Yingyi Bu79ccdac2016-07-26 23:49:24 -07002212 op.addOperand(operand);
2213 op.setCurrentop(true);
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07002214 addSourceLocation(op, token);
Yingyi Bu79ccdac2016-07-26 23:49:24 -07002215 }
Dmitry Lychaginbf48c492018-05-01 18:30:27 -07002216 op.addOperator(opType);
Yingyi Bu79ccdac2016-07-26 23:49:24 -07002217 }
2218 operand = ExponentExpr()
2219 {
2220 op.addOperand(operand);
2221 }
2222 )*
2223
2224 {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002225 return op == null ? operand : op;
Yingyi Bu79ccdac2016-07-26 23:49:24 -07002226 }
2227}
2228
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002229Expression ExponentExpr() throws ParseException:
Yingyi Bu79ccdac2016-07-26 23:49:24 -07002230{
2231 OperatorExpr op = null;
2232 Expression operand = null;
2233}
2234{
2235 operand = UnaryExpr()
2236 (<CARET>
2237 {
2238 if (op == null) {
2239 op = new OperatorExpr();
2240 op.addOperand(operand);
2241 op.setCurrentop(true);
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07002242 addSourceLocation(op, token);
Yingyi Bu391f09e2015-10-29 13:49:39 -07002243 }
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002244 op.addOperator(OperatorType.CARET);
Yingyi Bu391f09e2015-10-29 13:49:39 -07002245 }
2246 operand = UnaryExpr()
2247 {
2248 op.addOperand(operand);
2249 }
Yingyi Bu79ccdac2016-07-26 23:49:24 -07002250 )?
2251 {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002252 return op == null ? operand : op;
Yingyi Bu79ccdac2016-07-26 23:49:24 -07002253 }
Yingyi Bu391f09e2015-10-29 13:49:39 -07002254}
2255
2256Expression UnaryExpr() throws ParseException:
2257{
Yingyi Bu196db5d2016-07-15 19:07:20 -07002258 boolean not = false;
2259 UnaryExpr uexpr = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07002260 Expression expr = null;
2261}
Yingyi Budaa549c2016-06-28 22:30:52 -07002262{
Yingyi Bu196db5d2016-07-15 19:07:20 -07002263 ( (<PLUS> | <MINUS> | (<NOT> { not = true; } )? <EXISTS> )
Yingyi Bu391f09e2015-10-29 13:49:39 -07002264 {
Yingyi Bu196db5d2016-07-15 19:07:20 -07002265 String exprType = token.image.toLowerCase();
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002266 if (not) {
Yingyi Bu196db5d2016-07-15 19:07:20 -07002267 exprType = "not_" + exprType;
2268 }
2269 uexpr = new UnaryExpr();
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07002270 addSourceLocation(uexpr, token);
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002271 try {
Yingyi Bu196db5d2016-07-15 19:07:20 -07002272 uexpr.setExprType(exprType);
Taewoo Kime65e6ca2017-01-14 17:53:28 -08002273 } catch (CompilationException e){
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002274 throw new SqlppParseException(getSourceLocation(token), e.getMessage());
Yingyi Budaa549c2016-06-28 22:30:52 -07002275 }
Yingyi Bu391f09e2015-10-29 13:49:39 -07002276 }
2277 )?
2278
2279 expr = ValueExpr()
2280 {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002281 if (uexpr == null) {
2282 return expr;
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07002283 } else {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002284 uexpr.setExpr(expr);
2285 return uexpr;
2286 }
Yingyi Bu391f09e2015-10-29 13:49:39 -07002287 }
2288}
2289
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002290Expression ValueExpr() throws ParseException:
Yingyi Bu391f09e2015-10-29 13:49:39 -07002291{
2292 Expression expr = null;
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002293 AbstractAccessor accessor = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07002294}
2295{
2296 expr = PrimaryExpr() (
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002297 accessor = FieldAccessor(accessor != null ? accessor : expr)
2298 | accessor = IndexAccessor(accessor != null ? accessor : expr)
2299 )*
2300 {
2301 return accessor == null ? expr : accessor;
2302 }
Yingyi Bu391f09e2015-10-29 13:49:39 -07002303}
2304
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002305FieldAccessor FieldAccessor(Expression inputExpr) throws ParseException:
Yingyi Bu391f09e2015-10-29 13:49:39 -07002306{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002307 Token startToken = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07002308 String ident = null;
2309}
2310{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002311 <DOT> { startToken = token; } ident = Identifier()
Yingyi Bu391f09e2015-10-29 13:49:39 -07002312 {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002313 FieldAccessor fa = new FieldAccessor(inputExpr, new Identifier(ident));
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07002314 return addSourceLocation(fa, startToken);
Yingyi Bu391f09e2015-10-29 13:49:39 -07002315 }
2316}
2317
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002318IndexAccessor IndexAccessor(Expression inputExpr) throws ParseException:
Yingyi Bu391f09e2015-10-29 13:49:39 -07002319{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002320 Token startToken = null;
2321 Expression expr = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07002322}
2323{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002324 <LEFTBRACKET> { startToken = token; }
2325 ( expr = Expression()
Yingyi Bu391f09e2015-10-29 13:49:39 -07002326 {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002327 if (expr.getKind() == Expression.Kind.LITERAL_EXPRESSION)
Yingyi Bu391f09e2015-10-29 13:49:39 -07002328 {
2329 Literal lit = ((LiteralExpr)expr).getValue();
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002330 if (lit.getLiteralType() != Literal.Type.INTEGER &&
2331 lit.getLiteralType() != Literal.Type.LONG) {
2332 throw new SqlppParseException(expr.getSourceLocation(), "Index should be an INTEGER");
Yingyi Bu391f09e2015-10-29 13:49:39 -07002333 }
2334 }
2335 }
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002336 )
Yingyi Bu391f09e2015-10-29 13:49:39 -07002337
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002338 <RIGHTBRACKET>
2339 {
2340 IndexAccessor ia = new IndexAccessor(inputExpr, expr);
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07002341 return addSourceLocation(ia, startToken);
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002342 }
Yingyi Bu391f09e2015-10-29 13:49:39 -07002343}
2344
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002345Expression PrimaryExpr() throws ParseException:
Yingyi Bu391f09e2015-10-29 13:49:39 -07002346{
2347 Expression expr = null;
2348}
2349{
2350 ( LOOKAHEAD(4)
2351 expr = FunctionCallExpr()
Dmitry Lychagin5fbd04b2018-04-19 16:54:28 -07002352 | expr = CaseExpr()
Yingyi Bu391f09e2015-10-29 13:49:39 -07002353 | expr = Literal()
2354 | expr = VariableRef()
Dmitry Lychagin1bdf8082018-06-13 14:48:23 -07002355 | expr = ExternalVariableRef()
Yingyi Bu391f09e2015-10-29 13:49:39 -07002356 | expr = ListConstructor()
2357 | expr = RecordConstructor()
2358 | expr = ParenthesizedExpression()
2359 )
2360 {
2361 return expr;
2362 }
2363}
2364
2365Expression Literal() throws ParseException:
2366{
2367 LiteralExpr lit = new LiteralExpr();
2368 String str = null;
2369}
2370{
2371 ( str = StringLiteral()
2372 {
2373 lit.setValue(new StringLiteral(str));
2374 }
2375 | <INTEGER_LITERAL>
2376 {
Till Westmann68c6a992016-09-30 00:19:12 -07002377 try {
2378 lit.setValue(new LongIntegerLiteral(Long.valueOf(token.image)));
2379 } catch (NumberFormatException e) {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002380 throw new SqlppParseException(getSourceLocation(token), "Could not parse numeric literal \"" + token.image +'"');
Till Westmann68c6a992016-09-30 00:19:12 -07002381 }
Yingyi Bu391f09e2015-10-29 13:49:39 -07002382 }
2383 | <FLOAT_LITERAL>
2384 {
Till Westmann68c6a992016-09-30 00:19:12 -07002385 try {
2386 lit.setValue(new FloatLiteral(Float.valueOf(token.image)));
2387 } catch (NumberFormatException e) {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002388 throw new SqlppParseException(getSourceLocation(token), "Could not parse numeric literal \"" + token.image +'"');
Till Westmann68c6a992016-09-30 00:19:12 -07002389 }
Yingyi Bu391f09e2015-10-29 13:49:39 -07002390 }
2391 | <DOUBLE_LITERAL>
2392 {
Till Westmann68c6a992016-09-30 00:19:12 -07002393 try {
2394 lit.setValue(new DoubleLiteral(Double.valueOf(token.image)));
2395 } catch (NumberFormatException e) {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002396 throw new SqlppParseException(getSourceLocation(token), "Could not parse numeric literal \"" + token.image +'"');
Till Westmann68c6a992016-09-30 00:19:12 -07002397 }
Yingyi Bu391f09e2015-10-29 13:49:39 -07002398 }
Yingyi Bu535d86b2016-05-23 16:44:25 -07002399 | <MISSING>
2400 {
2401 lit.setValue(MissingLiteral.INSTANCE);
2402 }
Yingyi Bu391f09e2015-10-29 13:49:39 -07002403 | <NULL>
2404 {
2405 lit.setValue(NullLiteral.INSTANCE);
2406 }
2407 | <TRUE>
2408 {
2409 lit.setValue(TrueLiteral.INSTANCE);
2410 }
2411 | <FALSE>
2412 {
2413 lit.setValue(FalseLiteral.INSTANCE);
2414 }
2415 )
2416 {
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07002417 return addSourceLocation(lit, token);
Yingyi Bu391f09e2015-10-29 13:49:39 -07002418 }
2419}
2420
Yingyi Bu391f09e2015-10-29 13:49:39 -07002421VariableExpr VariableRef() throws ParseException:
2422{
Yingyi Bu391f09e2015-10-29 13:49:39 -07002423 VarIdentifier var = new VarIdentifier();
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002424 String id = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07002425}
2426{
Yingyi Bu391f09e2015-10-29 13:49:39 -07002427 (<IDENTIFIER> { id = token.image; } | id = QuotedString())
2428 {
Yingyi Buacc12a92016-03-26 17:25:05 -07002429 id = SqlppVariableUtil.toInternalVariableName(id); // Prefix user-defined variables with "$"
Yingyi Bu391f09e2015-10-29 13:49:39 -07002430 Identifier ident = lookupSymbol(id);
2431 if (isInForbiddenScopes(id)) {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002432 throw new SqlppParseException(getSourceLocation(token),
2433 "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 -07002434 }
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002435 VariableExpr varExp = new VariableExpr();
2436 if (ident != null) { // exist such ident
Yingyi Bu391f09e2015-10-29 13:49:39 -07002437 varExp.setVar((VarIdentifier)ident);
2438 } else {
2439 varExp.setVar(var);
Yingyi Buacc12a92016-03-26 17:25:05 -07002440 varExp.setIsNewVar(false);
2441 var.setValue(id);
Yingyi Bu391f09e2015-10-29 13:49:39 -07002442 }
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07002443 return addSourceLocation(varExp, token);
Yingyi Bu391f09e2015-10-29 13:49:39 -07002444 }
2445}
2446
Yingyi Bu391f09e2015-10-29 13:49:39 -07002447VariableExpr Variable() throws ParseException:
2448{
Yingyi Bu391f09e2015-10-29 13:49:39 -07002449 VarIdentifier var = new VarIdentifier();
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002450 String id = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07002451}
2452{
Yingyi Bu391f09e2015-10-29 13:49:39 -07002453 (<IDENTIFIER> { id = token.image; } | id = QuotedString())
2454 {
Yingyi Buacc12a92016-03-26 17:25:05 -07002455 id = SqlppVariableUtil.toInternalVariableName(id); // prefix user-defined variables with "$".
Yingyi Bu391f09e2015-10-29 13:49:39 -07002456 Identifier ident = lookupSymbol(id);
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002457 VariableExpr varExp = new VariableExpr();
Yingyi Bu391f09e2015-10-29 13:49:39 -07002458 if(ident != null) { // exist such ident
2459 varExp.setIsNewVar(false);
2460 }
2461 varExp.setVar(var);
Yingyi Bucaea8f02015-11-16 15:12:15 -08002462 var.setValue(id);
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07002463 return addSourceLocation(varExp, token);
Yingyi Bu391f09e2015-10-29 13:49:39 -07002464 }
2465}
2466
Dmitry Lychagin1bdf8082018-06-13 14:48:23 -07002467VariableExpr ExternalVariableRef() throws ParseException:
2468{
2469 String name = null;
2470}
2471{
2472 (
2473 (
2474 <DOLLAR>
2475 (
2476 <INTEGER_LITERAL> { name = token.image; } |
2477 <IDENTIFIER> { name = token.image; } |
2478 name = QuotedString()
2479 )
2480 )
2481 |
2482 (
2483 <QUES> { name = String.valueOf(++externalVarCounter); }
2484 )
2485 )
2486 {
2487 String idName = SqlppVariableUtil.toExternalVariableName(name);
2488 VarIdentifier id = new VarIdentifier(idName);
2489 VariableExpr varExp = new VariableExpr(id);
2490 return addSourceLocation(varExp, token);
2491 }
2492}
2493
Yingyi Bu391f09e2015-10-29 13:49:39 -07002494Expression ListConstructor() throws ParseException:
2495{
2496 Expression expr = null;
2497}
2498{
2499 (
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002500 expr = OrderedListConstructor() |
2501 expr = UnorderedListConstructor()
Yingyi Bu391f09e2015-10-29 13:49:39 -07002502 )
Yingyi Bu391f09e2015-10-29 13:49:39 -07002503 {
2504 return expr;
2505 }
2506}
2507
Yingyi Bu391f09e2015-10-29 13:49:39 -07002508ListConstructor OrderedListConstructor() throws ParseException:
2509{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002510 Token startToken = null;
2511 List<Expression> exprList = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07002512}
2513{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002514 <LEFTBRACKET> { startToken = token; }
2515 exprList = ExpressionList()
2516 <RIGHTBRACKET>
2517 {
2518 ListConstructor expr = new ListConstructor(ListConstructor.Type.ORDERED_LIST_CONSTRUCTOR, exprList);
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07002519 return addSourceLocation(expr, startToken);
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002520 }
Yingyi Bu391f09e2015-10-29 13:49:39 -07002521}
2522
2523ListConstructor UnorderedListConstructor() throws ParseException:
2524{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002525 Token startToken = null;
2526 List<Expression> exprList = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07002527}
2528{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002529 <LEFTDBLBRACE> { startToken = token; }
2530 exprList = ExpressionList()
2531 <RIGHTDBLBRACE>
2532 {
2533 ListConstructor expr = new ListConstructor(ListConstructor.Type.UNORDERED_LIST_CONSTRUCTOR, exprList);
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07002534 return addSourceLocation(expr, startToken);
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002535 }
Yingyi Bu391f09e2015-10-29 13:49:39 -07002536}
2537
2538List<Expression> ExpressionList() throws ParseException:
2539{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002540 Expression expr = null;
2541 List<Expression> exprList = new ArrayList<Expression>();
Yingyi Bu391f09e2015-10-29 13:49:39 -07002542}
2543{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002544 (
2545 expr = Expression()
2546 {
2547 exprList.add(expr);
2548 }
2549 ( <COMMA> expr = Expression()
Till Westmann60f89982017-08-11 18:14:20 -07002550 {
2551 exprList.add(expr);
2552 }
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002553 )*
2554 )?
2555 {
2556 return exprList;
2557 }
Yingyi Bu391f09e2015-10-29 13:49:39 -07002558}
2559
Yingyi Bu391f09e2015-10-29 13:49:39 -07002560RecordConstructor RecordConstructor() throws ParseException:
2561{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002562 Token startToken = null;
2563 FieldBinding fb = null;
2564 List<FieldBinding> fbList = new ArrayList<FieldBinding>();
Yingyi Bu391f09e2015-10-29 13:49:39 -07002565}
2566{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002567 <LEFTBRACE> { startToken = token; }
2568 (
2569 fb = FieldBinding() { fbList.add(fb); }
2570 (<COMMA> fb = FieldBinding() { fbList.add(fb); })*
2571 )?
2572 <RIGHTBRACE>
2573 {
2574 RecordConstructor expr = new RecordConstructor(fbList);
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07002575 return addSourceLocation(expr, startToken);
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002576 }
Yingyi Bu391f09e2015-10-29 13:49:39 -07002577}
2578
2579FieldBinding FieldBinding() throws ParseException:
2580{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002581 Expression left, right;
Yingyi Bu391f09e2015-10-29 13:49:39 -07002582}
2583{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002584 left = Expression() <COLON> right = Expression()
2585 {
2586 return new FieldBinding(left, right);
2587 }
Yingyi Bu391f09e2015-10-29 13:49:39 -07002588}
2589
Yingyi Bu391f09e2015-10-29 13:49:39 -07002590Expression FunctionCallExpr() throws ParseException:
2591{
Dmitry Lychaginfdedf622018-10-30 18:12:40 -07002592 Expression resultExpr;
Yingyi Bu391f09e2015-10-29 13:49:39 -07002593 List<Expression> argList = new ArrayList<Expression>();
Yingyi Buf4d09842016-08-26 00:03:52 -07002594 Expression tmp = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07002595 int arity = 0;
2596 FunctionName funcName = null;
2597 String hint = null;
Yingyi Buf4d09842016-08-26 00:03:52 -07002598 boolean star = false;
Dmitry Lychagin7a4b5682017-09-11 18:53:07 -07002599 boolean distinct = false;
Dmitry Lychaginfdedf622018-10-30 18:12:40 -07002600 Token overToken = null;
2601 Expression partitionExpr = null;
2602 List<Expression> partitionExprs = new ArrayList<Expression>();
2603 OrderbyClause orderByClause = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07002604}
2605{
2606 funcName = FunctionName()
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002607 {
2608 hint = funcName.hint;
2609 }
Dmitry Lychagin7a4b5682017-09-11 18:53:07 -07002610 <LEFTPAREN> (
2611 ( <DISTINCT> { distinct = true; } )?
2612 ( tmp = Expression() | <MUL> { star = true; } )
Yingyi Bu391f09e2015-10-29 13:49:39 -07002613 {
Yingyi Buf4d09842016-08-26 00:03:52 -07002614 if(star){
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002615 if(!funcName.function.equalsIgnoreCase("count")){
2616 throw new SqlppParseException(getSourceLocation(token), "The parameter * can only be used in COUNT().");
Yingyi Buf4d09842016-08-26 00:03:52 -07002617 }
2618 argList.add(new LiteralExpr(new LongIntegerLiteral(1L)));
2619 } else {
2620 argList.add(tmp);
2621 }
Yingyi Bu391f09e2015-10-29 13:49:39 -07002622 arity ++;
2623 }
2624 (<COMMA> tmp = Expression()
2625 {
2626 argList.add(tmp);
2627 arity++;
2628 }
2629 )*)? <RIGHTPAREN>
2630 {
Dmitry Lychagin7a4b5682017-09-11 18:53:07 -07002631 String name = funcName.function;
2632 if (distinct) {
2633 name += "-distinct";
2634 }
Yingyi Bu391f09e2015-10-29 13:49:39 -07002635 // TODO use funcName.library
Dmitry Lychagin7a4b5682017-09-11 18:53:07 -07002636 String fqFunctionName = funcName.library == null ? name : funcName.library + "#" + name;
Yingyi Bu391f09e2015-10-29 13:49:39 -07002637 FunctionSignature signature
2638 = lookupFunctionSignature(funcName.dataverse, fqFunctionName, arity);
2639 if (signature == null) {
2640 signature = new FunctionSignature(funcName.dataverse, fqFunctionName, arity);
2641 }
Dmitry Lychaginfdedf622018-10-30 18:12:40 -07002642 CallExpr callExpr = FunctionMapUtil.normalizedListInputFunctions(new CallExpr(signature,argList));
Yingyi Bu391f09e2015-10-29 13:49:39 -07002643 if (hint != null) {
2644 if (hint.startsWith(INDEXED_NESTED_LOOP_JOIN_HINT)) {
2645 callExpr.addHint(IndexedNLJoinExpressionAnnotation.INSTANCE);
2646 } else if (hint.startsWith(SKIP_SECONDARY_INDEX_SEARCH_HINT)) {
2647 callExpr.addHint(SkipSecondaryIndexSearchExpressionAnnotation.INSTANCE);
2648 }
2649 }
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002650 callExpr.setSourceLocation(funcName.sourceLoc);
Dmitry Lychaginfdedf622018-10-30 18:12:40 -07002651 resultExpr = callExpr;
Yingyi Bu391f09e2015-10-29 13:49:39 -07002652 }
Dmitry Lychaginfdedf622018-10-30 18:12:40 -07002653
2654 (
2655 <OVER> { overToken = token; }
2656 <LEFTPAREN>
2657 (
2658 <PARTITION> <BY>
2659 partitionExpr = Expression() { partitionExprs.add(partitionExpr); }
2660 ( <COMMA> partitionExpr = Expression() { partitionExprs.add(partitionExpr); } )*
2661 )?
2662 orderByClause = OrderbyClause()
2663 <RIGHTPAREN>
2664 {
2665 WindowExpression winExp = new WindowExpression(callExpr, partitionExprs, orderByClause.getOrderbyList(),
2666 orderByClause.getModifierList());
2667 resultExpr = addSourceLocation(winExp, overToken);
2668 }
2669 )?
2670
2671 {
2672 return resultExpr;
2673 }
Yingyi Bu391f09e2015-10-29 13:49:39 -07002674}
2675
2676Expression ParenthesizedExpression() throws ParseException:
2677{
2678 Expression expr;
2679}
2680{
2681 (
2682 LOOKAHEAD(2)
2683 <LEFTPAREN> expr = Expression() <RIGHTPAREN>
2684 |
2685 expr = Subquery()
2686 )
2687 {
2688 return expr;
2689 }
2690}
2691
Yingyi Buc8c067c2016-07-25 23:37:19 -07002692Expression CaseExpr() throws ParseException:
Yingyi Bu391f09e2015-10-29 13:49:39 -07002693{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002694 Token startToken = null;
2695 Expression conditionExpr = null;
Yingyi Buc8c067c2016-07-25 23:37:19 -07002696 List<Expression> whenExprs = new ArrayList<Expression>();
2697 List<Expression> thenExprs = new ArrayList<Expression>();
2698 Expression elseExpr = null;
Yingyi Buc8c067c2016-07-25 23:37:19 -07002699 Expression whenExpr = null;
2700 Expression thenExpr = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07002701}
2702{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002703 <CASE> { startToken = token; }
2704 ( conditionExpr = Expression() )?
Yingyi Buc8c067c2016-07-25 23:37:19 -07002705 (
2706 <WHEN> whenExpr = Expression()
2707 {
2708 whenExprs.add(whenExpr);
2709 }
2710 <THEN> thenExpr = Expression()
2711 {
2712 thenExprs.add(thenExpr);
2713 }
2714 )*
2715 (<ELSE> elseExpr = Expression() )?
2716 <END>
2717 {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002718 if (conditionExpr == null) {
2719 LiteralExpr litExpr = new LiteralExpr(TrueLiteral.INSTANCE);
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07002720 conditionExpr = addSourceLocation(litExpr, startToken);
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002721 }
2722 CaseExpression caseExpr = new CaseExpression(conditionExpr, whenExprs, thenExprs, elseExpr);
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07002723 return addSourceLocation(caseExpr, startToken);
Yingyi Buc8c067c2016-07-25 23:37:19 -07002724 }
Yingyi Bu391f09e2015-10-29 13:49:39 -07002725}
2726
Yingyi Buab817482016-08-19 21:29:31 -07002727SelectExpression SelectExpression(boolean subquery) throws ParseException:
2728{
Yingyi Bu391f09e2015-10-29 13:49:39 -07002729 List<LetClause> letClauses = new ArrayList<LetClause>();
2730 SelectSetOperation selectSetOperation;
2731 OrderbyClause orderbyClause = null;
2732 LimitClause limitClause = null;
2733 createNewScope();
Yingyi Buab817482016-08-19 21:29:31 -07002734}
2735{
Yingyi Bu391f09e2015-10-29 13:49:39 -07002736 ( letClauses = LetClause() )?
2737 selectSetOperation = SelectSetOperation()
2738 (orderbyClause = OrderbyClause() {})?
2739 (limitClause = LimitClause() {})?
2740 {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002741 SelectExpression selectExpr =
2742 new SelectExpression(letClauses, selectSetOperation, orderbyClause, limitClause, subquery);
2743 selectExpr.setSourceLocation((!letClauses.isEmpty() ? letClauses.get(0) : selectSetOperation).getSourceLocation());
2744 return selectExpr;
Yingyi Bu391f09e2015-10-29 13:49:39 -07002745 }
2746}
2747
Yingyi Buab817482016-08-19 21:29:31 -07002748SelectSetOperation SelectSetOperation() throws ParseException:
2749{
Yingyi Bu391f09e2015-10-29 13:49:39 -07002750 SetOperationInput setOperationInputLeft;
2751 List<SetOperationRight> setOperationRights = new ArrayList<SetOperationRight>();
2752}
2753{
2754 {
2755 SelectBlock selectBlockLeft = null;
2756 SelectExpression subqueryLeft = null;
2757 Expression expr = null;
2758 }
2759 selectBlockLeft = SelectBlock()
2760 {
2761 setOperationInputLeft = new SetOperationInput(selectBlockLeft, subqueryLeft);
2762 }
2763 (
2764 {
2765 SetOpType opType = SetOpType.UNION;
2766 boolean setSemantics = true;
2767 SelectBlock selectBlockRight = null;
2768 SelectExpression subqueryRight = null;
2769 }
2770 (<UNION> {opType = SetOpType.UNION;} |<INTERSECT> {opType = SetOpType.INTERSECT;} |<EXCEPT> {opType = SetOpType.EXCEPT;}) (<ALL> {setSemantics = false;} )?
2771 (selectBlockRight = SelectBlock()| subqueryRight = Subquery())
2772 {
2773 setOperationRights.add(new SetOperationRight(opType, setSemantics, new SetOperationInput(selectBlockRight, subqueryRight)));
2774 }
2775 )*
2776 {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002777 SelectSetOperation selectSetOp = new SelectSetOperation(setOperationInputLeft, setOperationRights);
2778 selectSetOp.setSourceLocation(selectBlockLeft.getSourceLocation());
2779 return selectSetOp;
Yingyi Bu391f09e2015-10-29 13:49:39 -07002780 }
2781}
2782
Yingyi Buab817482016-08-19 21:29:31 -07002783SelectExpression Subquery() throws ParseException:
2784{
Yingyi Bu391f09e2015-10-29 13:49:39 -07002785 SelectExpression selectExpr = null;
2786}
2787{
2788 <LEFTPAREN> selectExpr = SelectExpression(true) {} <RIGHTPAREN>
2789 {
2790 return selectExpr;
2791 }
2792}
2793
Yingyi Buab817482016-08-19 21:29:31 -07002794SelectBlock SelectBlock() throws ParseException:
2795{
Yingyi Bu391f09e2015-10-29 13:49:39 -07002796 SelectClause selectClause = null;
2797 FromClause fromClause = null;
2798 List<LetClause> fromLetClauses = null;
2799 WhereClause whereClause = null;
2800 GroupbyClause groupbyClause = null;
2801 List<LetClause> gbyLetClauses = null;
2802 HavingClause havingClause = null;
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002803 SourceLocation startSrcLoc = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07002804}
2805{
2806 (
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002807 selectClause = SelectClause() { startSrcLoc = selectClause.getSourceLocation(); }
Yingyi Bu391f09e2015-10-29 13:49:39 -07002808 (
2809 LOOKAHEAD(1)
2810 fromClause = FromClause()
2811 (
2812 LOOKAHEAD(1)
2813 fromLetClauses = LetClause()
2814 )?
2815 )?
2816 (whereClause = WhereClause())?
2817 (
2818 groupbyClause = GroupbyClause()
2819 (
2820 LOOKAHEAD(1)
2821 gbyLetClauses = LetClause()
2822 )?
2823 (havingClause = HavingClause())?
2824 )?
2825 |
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002826 fromClause = FromClause() { startSrcLoc = fromClause.getSourceLocation(); }
Yingyi Bu391f09e2015-10-29 13:49:39 -07002827 (
2828 LOOKAHEAD(1)
2829 fromLetClauses = LetClause()
2830 )?
2831 (whereClause = WhereClause())?
2832 (
2833 groupbyClause = GroupbyClause()
2834 (
2835 gbyLetClauses = LetClause()
2836 )?
2837 (havingClause = HavingClause())?
2838 )?
2839 selectClause = SelectClause()
2840 )
2841 {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002842 SelectBlock selectBlock = new SelectBlock(selectClause, fromClause, fromLetClauses, whereClause, groupbyClause,
2843 gbyLetClauses, havingClause);
2844 selectBlock.setSourceLocation(startSrcLoc);
2845 return selectBlock;
Yingyi Bu391f09e2015-10-29 13:49:39 -07002846 }
2847}
2848
Yingyi Buab817482016-08-19 21:29:31 -07002849SelectClause SelectClause() throws ParseException:
2850{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002851 Token startToken = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07002852 SelectRegular selectRegular = null;
2853 SelectElement selectElement = null;
2854 boolean distinct = false;
2855}
2856{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002857 <SELECT> { startToken = token; } (<ALL>|<DISTINCT> { distinct = true; } )?
Yingyi Bu391f09e2015-10-29 13:49:39 -07002858 (
2859 selectRegular = SelectRegular()
Michael Blowd6cf6412016-06-30 02:44:35 -04002860 |
Yingyi Bu391f09e2015-10-29 13:49:39 -07002861 selectElement = SelectElement()
Yingyi Bua89fae62016-07-06 07:58:55 -07002862 )?
Yingyi Bu391f09e2015-10-29 13:49:39 -07002863 {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002864 SourceLocation sourceLoc = getSourceLocation(startToken);
2865 if (selectRegular == null && selectElement == null){
Yingyi Bua89fae62016-07-06 07:58:55 -07002866 Projection projection = new Projection(null, null, true, false);
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002867 projection.setSourceLocation(sourceLoc);
Yingyi Bua89fae62016-07-06 07:58:55 -07002868 List<Projection> projections = new ArrayList<Projection>();
2869 projections.add(projection);
2870 selectRegular = new SelectRegular(projections);
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002871 selectRegular.setSourceLocation(sourceLoc);
Yingyi Bua89fae62016-07-06 07:58:55 -07002872 }
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002873 SelectClause selectClause = new SelectClause(selectElement, selectRegular, distinct);
2874 selectClause.setSourceLocation(sourceLoc);
2875 return selectClause;
Yingyi Bu391f09e2015-10-29 13:49:39 -07002876 }
2877}
2878
Yingyi Buab817482016-08-19 21:29:31 -07002879SelectRegular SelectRegular() throws ParseException:
2880{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002881 SourceLocation startSrcLoc = null;
Michael Blowd6cf6412016-06-30 02:44:35 -04002882 List<Projection> projections = new ArrayList<Projection>();
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002883 Projection projection = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07002884}
2885{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002886 projection = Projection()
Yingyi Bu391f09e2015-10-29 13:49:39 -07002887 {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002888 projections.add(projection);
2889 startSrcLoc = projection.getSourceLocation();
2890 }
2891 ( LOOKAHEAD(2) <COMMA> projection = Projection()
2892 {
2893 projections.add(projection);
2894 }
2895 )*
2896 {
2897 SelectRegular selectRegular = new SelectRegular(projections);
2898 selectRegular.setSourceLocation(startSrcLoc);
2899 return selectRegular;
Yingyi Bu391f09e2015-10-29 13:49:39 -07002900 }
2901}
2902
Yingyi Buab817482016-08-19 21:29:31 -07002903SelectElement SelectElement() throws ParseException:
2904{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002905 Token startToken = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07002906 Expression expr = null;
2907 String name = null;
2908}
2909{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002910 (<RAW>|<ELEMENT>|<VALUE>) { startToken = token; } expr = Expression()
Yingyi Bu391f09e2015-10-29 13:49:39 -07002911 {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002912 SelectElement selectElement = new SelectElement(expr);
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07002913 return addSourceLocation(selectElement, startToken);
Yingyi Bu391f09e2015-10-29 13:49:39 -07002914 }
2915}
2916
Yingyi Buab817482016-08-19 21:29:31 -07002917Projection Projection() throws ParseException :
2918{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002919 SourceLocation startSrcLoc = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07002920 Expression expr = null;
2921 Identifier identifier = null;
2922 String name = null;
2923 boolean star = false;
Dmitry Lychagin5cdaa5d2018-02-21 11:11:26 -08002924 boolean varStar = false;
Yingyi Bu391f09e2015-10-29 13:49:39 -07002925}
2926{
2927 (
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002928 <MUL> { star = true; startSrcLoc = getSourceLocation(token); }
2929 | LOOKAHEAD(3) expr = VariableRef() <DOT> <MUL> { varStar = true; }
Dmitry Lychagin5cdaa5d2018-02-21 11:11:26 -08002930 | expr = Expression() ((<AS>)? name = Identifier())?
2931 {
2932 if (name == null) {
2933 String generatedColumnIdentifier = ExpressionToVariableUtil.getGeneratedIdentifier(expr, false);
2934 if (generatedColumnIdentifier != null) {
2935 name = SqlppVariableUtil.toUserDefinedName(generatedColumnIdentifier);
2936 }
2937 }
2938 }
Yingyi Bu391f09e2015-10-29 13:49:39 -07002939 )
2940 {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002941 Projection projection = new Projection(expr, name, star, varStar);
2942 projection.setSourceLocation(expr != null ? expr.getSourceLocation() : startSrcLoc);
2943 return projection;
Yingyi Bu391f09e2015-10-29 13:49:39 -07002944 }
2945}
2946
2947FromClause FromClause() throws ParseException :
2948{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002949 Token startToken = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07002950 List<FromTerm> fromTerms = new ArrayList<FromTerm>();
2951 extendCurrentScope();
2952}
2953{
2954 {
2955 FromTerm fromTerm = null;
2956 }
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002957 <FROM> { startToken = token; } fromTerm = FromTerm() { fromTerms.add(fromTerm); }
Yingyi Bu391f09e2015-10-29 13:49:39 -07002958 (LOOKAHEAD(2) <COMMA> fromTerm = FromTerm() { fromTerms.add(fromTerm); } )*
2959 {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002960 FromClause fromClause = new FromClause(fromTerms);
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07002961 return addSourceLocation(fromClause, startToken);
Yingyi Bu391f09e2015-10-29 13:49:39 -07002962 }
2963}
2964
2965FromTerm FromTerm() throws ParseException :
2966{
2967 Expression leftExpr = null;
Michael Blowd6cf6412016-06-30 02:44:35 -04002968 VariableExpr leftVar = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07002969 VariableExpr posVar = null;
2970 List<AbstractBinaryCorrelateClause> correlateClauses = new ArrayList<AbstractBinaryCorrelateClause>();
2971}
2972{
Yingyi Bu9e3f9be2016-07-01 10:07:37 -07002973 leftExpr = Expression() ((<AS>)? leftVar = Variable())? (<AT> posVar = Variable())?
Yingyi Bu391f09e2015-10-29 13:49:39 -07002974 (
2975 {JoinType joinType = JoinType.INNER; }
2976 (joinType = JoinType())?
2977 {
2978 AbstractBinaryCorrelateClause correlateClause = null;
2979 }
2980 (correlateClause = JoinClause(joinType)
Yingyi Bu6d999ed2016-07-13 11:59:06 -07002981 | correlateClause = UnnestClause(joinType)
Yingyi Bu391f09e2015-10-29 13:49:39 -07002982 )
2983 {
2984 correlateClauses.add(correlateClause);
2985 }
2986 )*
2987 {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002988 if (leftVar == null) {
Yingyi Bu5b2d4c82016-07-13 17:56:48 -07002989 leftVar = ExpressionToVariableUtil.getGeneratedVariable(leftExpr, true);
Yingyi Bu9e3f9be2016-07-01 10:07:37 -07002990 }
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002991 FromTerm fromTerm = new FromTerm(leftExpr, leftVar, posVar, correlateClauses);
2992 fromTerm.setSourceLocation(leftExpr.getSourceLocation());
2993 return fromTerm;
Yingyi Bu391f09e2015-10-29 13:49:39 -07002994 }
2995}
2996
2997JoinClause JoinClause(JoinType joinType) throws ParseException :
2998{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002999 Token startToken = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07003000 Expression rightExpr = null;
3001 VariableExpr rightVar = null;
3002 VariableExpr posVar = null;
3003 Expression conditionExpr = null;
3004}
3005{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07003006 <JOIN> { startToken = token; } rightExpr = Expression() ((<AS>)? rightVar = Variable())? (<AT> posVar = Variable())? <ON> conditionExpr = Expression()
Yingyi Bu391f09e2015-10-29 13:49:39 -07003007 {
Yingyi Bu9e3f9be2016-07-01 10:07:37 -07003008 if(rightVar==null){
Yingyi Bu5b2d4c82016-07-13 17:56:48 -07003009 rightVar = ExpressionToVariableUtil.getGeneratedVariable(rightExpr, true);
Yingyi Bu9e3f9be2016-07-01 10:07:37 -07003010 }
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07003011 JoinClause joinClause = new JoinClause(joinType, rightExpr, rightVar, posVar, conditionExpr);
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07003012 return addSourceLocation(joinClause, startToken);
Yingyi Bu391f09e2015-10-29 13:49:39 -07003013 }
3014}
3015
Yingyi Bu391f09e2015-10-29 13:49:39 -07003016UnnestClause UnnestClause(JoinType joinType) throws ParseException :
3017{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07003018 Token startToken = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07003019 Expression rightExpr;
3020 VariableExpr rightVar;
3021 VariableExpr posVar = null;
3022}
3023{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07003024 (<UNNEST>|<CORRELATE>|<FLATTEN>) { startToken = token; } rightExpr = Expression() ((<AS>)? rightVar = Variable()) (<AT> posVar = Variable())?
Yingyi Bu391f09e2015-10-29 13:49:39 -07003025 {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07003026 if (rightVar == null) {
3027 rightVar = ExpressionToVariableUtil.getGeneratedVariable(rightExpr, true);
Yingyi Bu9e3f9be2016-07-01 10:07:37 -07003028 }
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07003029 UnnestClause unnestClause = new UnnestClause(joinType, rightExpr, rightVar, posVar);
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07003030 return addSourceLocation(unnestClause, startToken);
Yingyi Bu391f09e2015-10-29 13:49:39 -07003031 }
3032}
3033
Yingyi Bu391f09e2015-10-29 13:49:39 -07003034JoinType JoinType() throws ParseException :
3035{
3036 JoinType joinType = JoinType.INNER;
3037}
3038{
3039 (<INNER>|<LEFT> (<OUTER>)? {joinType = JoinType.LEFTOUTER; })
3040 {
3041 return joinType;
3042 }
3043}
3044
3045List<LetClause> LetClause() throws ParseException:
3046{
3047 List<LetClause> letList = new ArrayList<LetClause>();
3048 LetClause letClause;
3049}
3050{
3051 (
3052 (<LET>|<LETTING>) letClause = LetElement() { letList.add(letClause); } (LOOKAHEAD(1) <COMMA> letClause = LetElement() { letList.add(letClause); })*
3053 |
3054 <WITH> letClause = WithElement() { letList.add(letClause); } (LOOKAHEAD(1) <COMMA> letClause = WithElement() { letList.add(letClause); })*
3055 )
3056 {
3057 return letList;
3058 }
3059}
3060
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07003061WhereClause WhereClause() throws ParseException :
Yingyi Bu391f09e2015-10-29 13:49:39 -07003062{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07003063 Token startToken = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07003064 Expression whereExpr;
3065}
3066{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07003067 <WHERE> { startToken = token; } whereExpr = Expression()
Yingyi Bu391f09e2015-10-29 13:49:39 -07003068 {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07003069 WhereClause wc = new WhereClause(whereExpr);
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07003070 return addSourceLocation(wc, startToken);
Yingyi Bu391f09e2015-10-29 13:49:39 -07003071 }
3072}
3073
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07003074OrderbyClause OrderbyClause() throws ParseException :
Yingyi Bu391f09e2015-10-29 13:49:39 -07003075{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07003076 Token startToken = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07003077 OrderbyClause oc = new OrderbyClause();
3078 Expression orderbyExpr;
3079 List<Expression> orderbyList = new ArrayList<Expression>();
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07003080 List<OrderbyClause.OrderModifier> modifierList = new ArrayList<OrderbyClause.OrderModifier>();
Yingyi Bu391f09e2015-10-29 13:49:39 -07003081 int numOfOrderby = 0;
3082}
3083{
3084 <ORDER>
3085 {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07003086 startToken = token;
Yingyi Bu391f09e2015-10-29 13:49:39 -07003087 String hint = getHint(token);
3088 if (hint != null) {
3089 if (hint.startsWith(INMEMORY_HINT)) {
3090 String splits[] = hint.split(" +");
3091 int numFrames = Integer.parseInt(splits[1]);
3092 int numTuples = Integer.parseInt(splits[2]);
3093 oc.setNumFrames(numFrames);
3094 oc.setNumTuples(numTuples);
3095 }
Ali Alsuliman80225e22018-10-15 14:17:07 -07003096 if (hint.startsWith(RANGE_HINT)) {
3097 try {
3098 oc.setRangeMap(RangeMapBuilder.parseHint(createNewParser(hint.substring(RANGE_HINT.length()))));
3099 } catch (CompilationException e) {
3100 throw new SqlppParseException(getSourceLocation(getHintToken(token)), e.getMessage());
3101 }
3102 }
Yingyi Bu391f09e2015-10-29 13:49:39 -07003103 }
3104 }
3105 <BY> orderbyExpr = Expression()
3106 {
3107 orderbyList.add(orderbyExpr);
3108 OrderbyClause.OrderModifier modif = OrderbyClause.OrderModifier.ASC;
3109 }
3110 ( (<ASC> { modif = OrderbyClause.OrderModifier.ASC; })
3111 | (<DESC> { modif = OrderbyClause.OrderModifier.DESC; }))?
3112 {
3113 modifierList.add(modif);
3114 }
3115
3116 (LOOKAHEAD(2) <COMMA> orderbyExpr = Expression()
3117 {
3118 orderbyList.add(orderbyExpr);
3119 modif = OrderbyClause.OrderModifier.ASC;
3120 }
3121 ( (<ASC> { modif = OrderbyClause.OrderModifier.ASC; })
3122 | (<DESC> { modif = OrderbyClause.OrderModifier.DESC; }))?
3123 {
3124 modifierList.add(modif);
3125 }
3126 )*
3127
3128 {
3129 oc.setModifierList(modifierList);
3130 oc.setOrderbyList(orderbyList);
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07003131 return addSourceLocation(oc, startToken);
Yingyi Bu391f09e2015-10-29 13:49:39 -07003132 }
3133}
3134
3135GroupbyClause GroupbyClause()throws ParseException :
3136{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07003137 Token startToken = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07003138 GroupbyClause gbc = new GroupbyClause();
3139 List<GbyVariableExpressionPair> vePairList = new ArrayList<GbyVariableExpressionPair>();
3140 VariableExpr var = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07003141 Expression expr = null;
3142 VariableExpr decorVar = null;
3143 Expression decorExpr = null;
Yingyi Buacc12a92016-03-26 17:25:05 -07003144
3145 VariableExpr groupVar = null;
3146 List<Pair<Expression, Identifier>> groupFieldList = new ArrayList<Pair<Expression, Identifier>>();
Yingyi Bu391f09e2015-10-29 13:49:39 -07003147}
3148{
3149 {
3150 Scope newScope = extendCurrentScopeNoPush(true);
3151 // extendCurrentScope(true);
3152 }
3153 <GROUP>
3154 {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07003155 startToken = token;
Yingyi Bu391f09e2015-10-29 13:49:39 -07003156 String hint = getHint(token);
3157 if (hint != null && hint.equals(HASH_GROUP_BY_HINT)) {
3158 gbc.setHashGroupByHint(true);
3159 }
3160 }
3161 <BY> (
3162 expr = Expression()
3163 (LOOKAHEAD(1) (<AS>)?
3164 var = Variable()
Yingyi Bucaea8f02015-11-16 15:12:15 -08003165 )?
Yingyi Bu391f09e2015-10-29 13:49:39 -07003166 {
Yingyi Bu9e3f9be2016-07-01 10:07:37 -07003167 if(var==null){
Yingyi Bu5b2d4c82016-07-13 17:56:48 -07003168 var = ExpressionToVariableUtil.getGeneratedVariable(expr, false);
Yingyi Bu9e3f9be2016-07-01 10:07:37 -07003169 }
Yingyi Bu391f09e2015-10-29 13:49:39 -07003170 GbyVariableExpressionPair pair1 = new GbyVariableExpressionPair(var, expr);
3171 vePairList.add(pair1);
3172 }
3173 ( LOOKAHEAD(1) <COMMA>
Yingyi Bu9e3f9be2016-07-01 10:07:37 -07003174 {
3175 var = null;
3176 }
Yingyi Bu391f09e2015-10-29 13:49:39 -07003177 expr = Expression()
3178 (LOOKAHEAD(1) (<AS>)?
3179 var = Variable()
Yingyi Bucaea8f02015-11-16 15:12:15 -08003180 )?
Yingyi Bu391f09e2015-10-29 13:49:39 -07003181 {
Yingyi Bu9e3f9be2016-07-01 10:07:37 -07003182 if(var==null){
Yingyi Bu5b2d4c82016-07-13 17:56:48 -07003183 var = ExpressionToVariableUtil.getGeneratedVariable(expr, false);
Yingyi Bu9e3f9be2016-07-01 10:07:37 -07003184 }
Yingyi Bu391f09e2015-10-29 13:49:39 -07003185 GbyVariableExpressionPair pair2 = new GbyVariableExpressionPair(var, expr);
3186 vePairList.add(pair2);
3187 }
3188 )*
3189 )
Yingyi Buacc12a92016-03-26 17:25:05 -07003190 (<GROUP> <AS> groupVar = Variable()
3191 ( LOOKAHEAD(1)
3192 {
3193 VariableExpr fieldVarExpr = null;
3194 String fieldIdentifierStr = null;
3195 }
3196 <LEFTPAREN>
3197 fieldVarExpr = VariableRef() <AS> fieldIdentifierStr = Identifier()
3198 {
3199 groupFieldList.add(new Pair<Expression, Identifier>(fieldVarExpr, new Identifier(fieldIdentifierStr)));
3200 }
3201 (<COMMA>
3202 fieldVarExpr = VariableRef() <AS> fieldIdentifierStr = Identifier()
3203 {
3204 groupFieldList.add(new Pair<Expression, Identifier>(fieldVarExpr, new Identifier(fieldIdentifierStr)));
3205 }
3206 )*
3207 <RIGHTPAREN>
3208 )?
3209 )?
Yingyi Bu391f09e2015-10-29 13:49:39 -07003210 {
3211 gbc.setGbyPairList(vePairList);
3212 gbc.setDecorPairList(new ArrayList<GbyVariableExpressionPair>());
Yingyi Bu8671ddf2016-08-14 23:58:43 -07003213 gbc.setWithVarMap(new HashMap<Expression, VariableExpr>());
Yingyi Buacc12a92016-03-26 17:25:05 -07003214 gbc.setGroupVar(groupVar);
3215 gbc.setGroupFieldList(groupFieldList);
Yingyi Bu391f09e2015-10-29 13:49:39 -07003216 replaceCurrentScope(newScope);
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07003217 return addSourceLocation(gbc, startToken);
Yingyi Bu391f09e2015-10-29 13:49:39 -07003218 }
3219}
3220
3221HavingClause HavingClause() throws ParseException:
3222{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07003223 Token startToken = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07003224 Expression filterExpr = null;
3225}
3226{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07003227 <HAVING> { startToken = token; } filterExpr = Expression()
Yingyi Bu391f09e2015-10-29 13:49:39 -07003228 {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07003229 HavingClause havingClause = new HavingClause(filterExpr);
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07003230 return addSourceLocation(havingClause, startToken);
Yingyi Bu391f09e2015-10-29 13:49:39 -07003231 }
3232}
3233
3234LimitClause LimitClause() throws ParseException:
3235{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07003236 Token startToken = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07003237 LimitClause lc = new LimitClause();
3238 Expression expr;
3239 pushForbiddenScope(getCurrentScope());
3240}
3241{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07003242 <LIMIT> { startToken = token; } expr = Expression() { lc.setLimitExpr(expr); }
3243 (<OFFSET> expr = Expression() { lc.setOffset(expr); })?
Yingyi Bu391f09e2015-10-29 13:49:39 -07003244
3245 {
3246 popForbiddenScope();
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07003247 return addSourceLocation(lc, startToken);
Yingyi Bu391f09e2015-10-29 13:49:39 -07003248 }
3249}
3250
3251QuantifiedExpression QuantifiedExpression()throws ParseException:
3252{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07003253 Token startToken = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07003254 QuantifiedExpression qc = new QuantifiedExpression();
3255 List<QuantifiedPair> quantifiedList = new ArrayList<QuantifiedPair>();
3256 Expression satisfiesExpr;
3257 VariableExpr var;
3258 Expression inExpr;
3259 QuantifiedPair pair;
3260}
3261{
3262 {
3263 createNewScope();
3264 }
3265
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07003266 ( ((<ANY>|<SOME>) { startToken = token; qc.setQuantifier(QuantifiedExpression.Quantifier.SOME); })
3267 | (<EVERY> { startToken = token; qc.setQuantifier(QuantifiedExpression.Quantifier.EVERY); }))
Yingyi Bu391f09e2015-10-29 13:49:39 -07003268 var = Variable() <IN> inExpr = Expression()
3269 {
3270 pair = new QuantifiedPair(var, inExpr);
Yingyi Bu391f09e2015-10-29 13:49:39 -07003271 quantifiedList.add(pair);
3272 }
3273 (
3274 <COMMA> var = Variable() <IN> inExpr = Expression()
3275 {
3276 pair = new QuantifiedPair(var, inExpr);
Yingyi Bu391f09e2015-10-29 13:49:39 -07003277 quantifiedList.add(pair);
3278 }
3279 )*
Yingyi Bu858efae2016-10-13 17:31:57 -07003280 <SATISFIES> satisfiesExpr = Expression() (<END>)?
Yingyi Bu391f09e2015-10-29 13:49:39 -07003281 {
3282 qc.setSatisfiesExpr(satisfiesExpr);
3283 qc.setQuantifiedList(quantifiedList);
3284 removeCurrentScope();
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07003285 return addSourceLocation(qc, startToken);
Yingyi Bu391f09e2015-10-29 13:49:39 -07003286 }
3287}
3288
3289LetClause LetElement() throws ParseException:
3290{
Yingyi Bu391f09e2015-10-29 13:49:39 -07003291 VariableExpr varExp;
3292 Expression beExp;
3293 extendCurrentScope();
3294}
3295{
3296 varExp = Variable() <EQ> beExp = Expression()
3297 {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07003298 LetClause lc = new LetClause(varExp, beExp);
3299 lc.setSourceLocation(varExp.getSourceLocation());
Yingyi Bu391f09e2015-10-29 13:49:39 -07003300 return lc;
3301 }
3302}
3303
3304LetClause WithElement() throws ParseException:
3305{
Yingyi Bu391f09e2015-10-29 13:49:39 -07003306 VariableExpr varExp;
3307 Expression beExp;
3308 extendCurrentScope();
3309}
3310{
3311 varExp = Variable() <AS> beExp = Expression()
3312 {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07003313 LetClause lc = new LetClause(varExp, beExp);
3314 lc.setSourceLocation(varExp.getSourceLocation());
Yingyi Bu391f09e2015-10-29 13:49:39 -07003315 return lc;
3316 }
3317}
3318
3319TOKEN_MGR_DECLS:
3320{
3321 public int commentDepth = 0;
Till Westmanne9b2adf2016-10-15 12:39:01 -07003322 public ArrayDeque<Integer> lexerStateStack = new ArrayDeque<Integer>();
Yingyi Bu391f09e2015-10-29 13:49:39 -07003323
3324 public void pushState() {
3325 lexerStateStack.push( curLexState );
3326 }
3327
3328 public void popState(String token) {
3329 if (lexerStateStack.size() > 0) {
3330 SwitchTo( lexerStateStack.pop() );
3331 } else {
3332 int errorLine = input_stream.getEndLine();
3333 int errorColumn = input_stream.getEndColumn();
3334 String msg = "Lexical error at line " + errorLine + ", column " + errorColumn + ". Encountered \"" + token
3335 + "\" but state stack is empty.";
3336 throw new TokenMgrError(msg, -1);
3337 }
3338 }
3339}
3340
3341<DEFAULT,IN_DBL_BRACE>
3342TOKEN [IGNORE_CASE]:
3343{
3344 <ALL : "all">
3345 | <AND : "and">
Yingyi Bu8aac7242016-09-13 23:14:09 -07003346 | <ANY : "any">
Yingyi Bu391f09e2015-10-29 13:49:39 -07003347 | <APPLY : "apply">
3348 | <AS : "as">
3349 | <ASC : "asc">
3350 | <AT : "at">
3351 | <AUTOGENERATED : "autogenerated">
Yingyi Bua8baf6d2016-07-05 21:40:44 -07003352 | <BETWEEN : "between">
Yingyi Bu391f09e2015-10-29 13:49:39 -07003353 | <BTREE : "btree">
3354 | <BY : "by">
3355 | <CASE : "case">
3356 | <CLOSED : "closed">
3357 | <CREATE : "create">
3358 | <COMPACTION : "compaction">
3359 | <COMPACT : "compact">
3360 | <CONNECT : "connect">
3361 | <CORRELATE : "correlate">
Yingyi Bud56ff032016-08-01 10:26:57 -07003362 | <DATASET : "dataset">
Yingyi Bu1c0fff52016-03-25 20:23:30 -07003363 | <COLLECTION : "collection">
Yingyi Bud56ff032016-08-01 10:26:57 -07003364 | <DATAVERSE : "dataverse">
Yingyi Bu391f09e2015-10-29 13:49:39 -07003365 | <DECLARE : "declare">
3366 | <DEFINITION : "definition">
3367 | <DELETE : "delete">
3368 | <DESC : "desc">
3369 | <DISCONNECT : "disconnect">
3370 | <DISTINCT : "distinct">
3371 | <DROP : "drop">
3372 | <ELEMENT : "element">
Till Westmann516d1a82016-08-02 14:45:53 -07003373 | <EXPLAIN : "explain">
Yingyi Bu391f09e2015-10-29 13:49:39 -07003374 | <ELSE : "else">
3375 | <ENFORCED : "enforced">
Yingyi Buc8c067c2016-07-25 23:37:19 -07003376 | <END : "end">
Yingyi Bu391f09e2015-10-29 13:49:39 -07003377 | <EVERY : "every">
3378 | <EXCEPT : "except">
3379 | <EXISTS : "exists">
3380 | <EXTERNAL : "external">
3381 | <FEED : "feed">
3382 | <FILTER : "filter">
3383 | <FLATTEN : "flatten">
3384 | <FOR : "for">
Yingyi Bu391f09e2015-10-29 13:49:39 -07003385 | <FROM : "from">
3386 | <FULL : "full">
Taewoo Kimc49405a2017-01-04 00:30:43 -08003387 | <FULLTEXT : "fulltext">
Yingyi Bu391f09e2015-10-29 13:49:39 -07003388 | <FUNCTION : "function">
3389 | <GROUP : "group">
3390 | <HAVING : "having">
3391 | <HINTS : "hints">
3392 | <IF : "if">
3393 | <INTO : "into">
3394 | <IN : "in">
3395 | <INDEX : "index">
3396 | <INGESTION : "ingestion">
3397 | <INNER : "inner">
3398 | <INSERT : "insert">
3399 | <INTERNAL : "internal">
3400 | <INTERSECT : "intersect">
Yingyi Budaa549c2016-06-28 22:30:52 -07003401 | <IS : "is">
Yingyi Bu391f09e2015-10-29 13:49:39 -07003402 | <JOIN : "join">
3403 | <KEYWORD : "keyword">
3404 | <KEY : "key">
Dmitry Lychagin1aa0dd42018-04-17 14:35:24 -07003405 | <KNOWN : "known">
Yingyi Bu391f09e2015-10-29 13:49:39 -07003406 | <LEFT : "left">
3407 | <LETTING : "letting">
3408 | <LET : "let">
Yingyi Bua8baf6d2016-07-05 21:40:44 -07003409 | <LIKE : "like">
Yingyi Bu391f09e2015-10-29 13:49:39 -07003410 | <LIMIT : "limit">
3411 | <LOAD : "load">
Yingyi Bu391f09e2015-10-29 13:49:39 -07003412 | <NODEGROUP : "nodegroup">
3413 | <NGRAM : "ngram">
Yingyi Budaa549c2016-06-28 22:30:52 -07003414 | <NOT : "not">
Yingyi Bu391f09e2015-10-29 13:49:39 -07003415 | <OFFSET : "offset">
3416 | <ON : "on">
3417 | <OPEN : "open">
3418 | <OR : "or">
3419 | <ORDER : "order">
3420 | <OUTER : "outer">
3421 | <OUTPUT : "output">
Dmitry Lychaginfdedf622018-10-30 18:12:40 -07003422 | <OVER: "over">
Yingyi Bu391f09e2015-10-29 13:49:39 -07003423 | <PATH : "path">
Dmitry Lychaginfdedf622018-10-30 18:12:40 -07003424 | <PARTITION : "partition">
Yingyi Bu391f09e2015-10-29 13:49:39 -07003425 | <POLICY : "policy">
3426 | <PRESORTED : "pre-sorted">
3427 | <PRIMARY : "primary">
3428 | <RAW : "raw">
3429 | <REFRESH : "refresh">
3430 | <RETURN : "return">
Yingyi Bucb5bf332017-01-02 22:19:50 -08003431 | <RETURNING : "returning">
Yingyi Bu391f09e2015-10-29 13:49:39 -07003432 | <RTREE : "rtree">
3433 | <RUN : "run">
3434 | <SATISFIES : "satisfies">
3435 | <SECONDARY : "secondary">
3436 | <SELECT : "select">
3437 | <SET : "set">
3438 | <SOME : "some">
Abdullah Alamoudifff200c2017-02-18 20:32:14 -08003439 | <START : "start">
3440 | <STOP : "stop">
Murtadha Hubail2c04ae02017-11-21 15:58:01 +03003441 | <TEMPORARY : "temporary"> // intentionally not used but reserved for future usage
Yingyi Bu391f09e2015-10-29 13:49:39 -07003442 | <THEN : "then">
3443 | <TYPE : "type">
3444 | <TO : "to">
3445 | <UNION : "union">
Dmitry Lychagin8b6578a2017-11-08 15:04:35 -08003446 | <UNKNOWN : "unknown">
Yingyi Bu391f09e2015-10-29 13:49:39 -07003447 | <UNNEST : "unnest">
Yingyi Budaa549c2016-06-28 22:30:52 -07003448 | <UPDATE : "update">
Yingyi Bucb5bf332017-01-02 22:19:50 -08003449 | <UPSERT : "upsert">
Yingyi Budaa549c2016-06-28 22:30:52 -07003450 | <USE : "use">
3451 | <USING : "using">
Yingyi Bu391f09e2015-10-29 13:49:39 -07003452 | <VALUE : "value">
Dmitry Lychagin7d594a32018-01-15 14:31:03 -08003453 | <VALUED : "valued">
Yingyi Bu391f09e2015-10-29 13:49:39 -07003454 | <WHEN : "when">
3455 | <WHERE : "where">
3456 | <WITH : "with">
3457 | <WRITE : "write">
Yingyi Bu391f09e2015-10-29 13:49:39 -07003458}
3459
3460<DEFAULT,IN_DBL_BRACE>
3461TOKEN :
3462{
3463 <CARET : "^">
Yingyi Bufdc71eb2016-08-24 22:41:57 -07003464 | <CONCAT : "||">
Dmitry Lychaginbf48c492018-05-01 18:30:27 -07003465 | <DIVIDE : "/">
3466 | <DIV : "div">
Yingyi Bu391f09e2015-10-29 13:49:39 -07003467 | <MINUS : "-">
Dmitry Lychaginbf48c492018-05-01 18:30:27 -07003468 | <MOD : "mod">
Yingyi Bu391f09e2015-10-29 13:49:39 -07003469 | <MUL : "*">
3470 | <PLUS : "+">
3471
3472 | <LEFTPAREN : "(">
3473 | <RIGHTPAREN : ")">
3474 | <LEFTBRACKET : "[">
3475 | <RIGHTBRACKET : "]">
3476
3477 | <ATT : "@">
3478 | <COLON : ":">
3479 | <COMMA : ",">
Dmitry Lychagin1bdf8082018-06-13 14:48:23 -07003480 | <DOLLAR: "$">
Yingyi Bu391f09e2015-10-29 13:49:39 -07003481 | <DOT : ".">
Dmitry Lychaginbf48c492018-05-01 18:30:27 -07003482 | <PERCENT: "%">
Yingyi Bu391f09e2015-10-29 13:49:39 -07003483 | <QUES : "?">
3484 | <SEMICOLON : ";">
3485 | <SHARP : "#">
3486
3487 | <LT : "<">
3488 | <GT : ">">
3489 | <LE : "<=">
3490 | <GE : ">=">
3491 | <EQ : "=">
3492 | <NE : "!=">
Yingyi Bu4a4b8962016-09-16 12:09:11 -07003493 | <LG : "<>">
Yingyi Bu391f09e2015-10-29 13:49:39 -07003494 | <SIMILAR : "~=">
3495}
3496
3497<DEFAULT,IN_DBL_BRACE>
3498TOKEN :
3499{
3500 <LEFTBRACE : "{"> { pushState(); } : DEFAULT
3501}
3502
3503<DEFAULT>
3504TOKEN :
3505{
3506 <RIGHTBRACE : "}"> { popState("}"); }
3507}
3508
3509<DEFAULT,IN_DBL_BRACE>
3510TOKEN :
3511{
3512 <LEFTDBLBRACE : "{{"> { pushState(); } : IN_DBL_BRACE
3513}
3514
3515<IN_DBL_BRACE>
3516TOKEN :
3517{
3518 <RIGHTDBLBRACE : "}}"> { popState("}}"); }
3519}
3520
3521<DEFAULT,IN_DBL_BRACE>
3522TOKEN :
3523{
3524 <INTEGER_LITERAL : (<DIGIT>)+ >
3525}
3526
3527<DEFAULT,IN_DBL_BRACE>
Yingyi Bue311a632016-06-07 18:23:16 -07003528TOKEN [IGNORE_CASE]:
Yingyi Bu391f09e2015-10-29 13:49:39 -07003529{
Dmitry Lychagin1bdf8082018-06-13 14:48:23 -07003530 <MISSING : "missing">
3531 | <NULL : "null">
Yingyi Bu391f09e2015-10-29 13:49:39 -07003532 | <TRUE : "true">
3533 | <FALSE : "false">
3534}
3535
3536<DEFAULT,IN_DBL_BRACE>
3537TOKEN :
3538{
3539 <#DIGIT : ["0" - "9"]>
3540}
3541
3542<DEFAULT,IN_DBL_BRACE>
3543TOKEN:
3544{
Dmitry Lychaginee8526b2018-03-30 14:21:01 -07003545 < DOUBLE_LITERAL: <DIGITS> ( "." <DIGITS> ) (("e"|"E") ("+"|"-")? <DIGITS>)?
3546 | <DIGITS> (("e"|"E") ("+"|"-")? <DIGITS>)
3547 | "." <DIGITS> (("e"|"E") ("+"|"-")? <DIGITS>)?
Yingyi Bu391f09e2015-10-29 13:49:39 -07003548 >
Yingyi Bue4d919e2016-10-30 10:47:03 -07003549 | < FLOAT_LITERAL: <DIGITS> ( "f" | "F" )
3550 | <DIGITS> ( "." <DIGITS> ( "f" | "F" ) )?
3551 | "." <DIGITS> ( "f" | "F" )
Yingyi Bu391f09e2015-10-29 13:49:39 -07003552 >
3553 | <DIGITS : (<DIGIT>)+ >
3554}
3555
3556<DEFAULT,IN_DBL_BRACE>
3557TOKEN :
3558{
3559 <#LETTER : ["A" - "Z", "a" - "z"]>
Dmitry Lychagin9c83efb2018-01-16 14:31:58 -08003560 | <#IDENTIFIER_SPECIALCHARS_START : ["_"]>
3561 | <#IDENTIFIER_SPECIALCHARS_REST : ["$"]>
Yingyi Bu391f09e2015-10-29 13:49:39 -07003562}
3563
3564<DEFAULT,IN_DBL_BRACE>
3565TOKEN :
3566{
3567 // backslash u + 4 hex digits escapes are handled in the underlying JavaCharStream
Yingyi Bu6d57e492016-06-06 21:24:42 -07003568 <QUOTED_STRING : "`" (
Yingyi Bu391f09e2015-10-29 13:49:39 -07003569 <EscapeQuot>
3570 | <EscapeBslash>
3571 | <EscapeSlash>
3572 | <EscapeBspace>
3573 | <EscapeFormf>
3574 | <EscapeNl>
3575 | <EscapeCr>
3576 | <EscapeTab>
Yingyi Bu6d57e492016-06-06 21:24:42 -07003577 | ~["`","\\"])* "`">
3578 | <STRING_LITERAL : ("\"" (
Yingyi Bu391f09e2015-10-29 13:49:39 -07003579 <EscapeQuot>
Yingyi Bu391f09e2015-10-29 13:49:39 -07003580 | <EscapeBslash>
3581 | <EscapeSlash>
3582 | <EscapeBspace>
3583 | <EscapeFormf>
3584 | <EscapeNl>
3585 | <EscapeCr>
3586 | <EscapeTab>
Yingyi Bu6d57e492016-06-06 21:24:42 -07003587 | ~["\"","\\"])* "\"")
3588 | ("\'"(
3589 <EscapeApos>
3590 | <EscapeBslash>
3591 | <EscapeSlash>
3592 | <EscapeBspace>
3593 | <EscapeFormf>
3594 | <EscapeNl>
3595 | <EscapeCr>
3596 | <EscapeTab>
3597 | ~["\'","\\"])* "\'")>
Yingyi Bu391f09e2015-10-29 13:49:39 -07003598 | < #EscapeQuot: "\\\"" >
3599 | < #EscapeApos: "\\\'" >
3600 | < #EscapeBslash: "\\\\" >
3601 | < #EscapeSlash: "\\/" >
3602 | < #EscapeBspace: "\\b" >
3603 | < #EscapeFormf: "\\f" >
3604 | < #EscapeNl: "\\n" >
3605 | < #EscapeCr: "\\r" >
3606 | < #EscapeTab: "\\t" >
3607}
3608
3609<DEFAULT,IN_DBL_BRACE>
3610TOKEN :
3611{
Dmitry Lychagin9c83efb2018-01-16 14:31:58 -08003612 <IDENTIFIER : ( <LETTER> | <IDENTIFIER_SPECIALCHARS_START> )
3613 ( <LETTER> | <DIGIT> | <IDENTIFIER_SPECIALCHARS_START> | <IDENTIFIER_SPECIALCHARS_REST> )*>
Yingyi Bu391f09e2015-10-29 13:49:39 -07003614}
3615
3616<DEFAULT,IN_DBL_BRACE>
3617SKIP:
3618{
3619 " "
3620 | "\t"
3621 | "\r"
3622 | "\n"
3623}
3624
3625<DEFAULT,IN_DBL_BRACE>
3626SKIP:
3627{
3628 <"//" (~["\n"])* "\n">
3629}
3630
3631<DEFAULT,IN_DBL_BRACE>
3632SKIP:
3633{
3634 <"//" (~["\n","\r"])* ("\n"|"\r"|"\r\n")?>
3635}
3636
3637<DEFAULT,IN_DBL_BRACE>
3638SKIP:
3639{
Yingyi Bu93846a72016-09-13 16:30:39 -07003640 <"--" (~["\n"])* "\n">
3641}
3642
3643
3644<DEFAULT,IN_DBL_BRACE>
3645SKIP:
3646{
3647 <"--" (~["\n","\r"])* ("\n"|"\r"|"\r\n")?>
3648}
3649
3650<DEFAULT,IN_DBL_BRACE>
3651SKIP:
3652{
Yingyi Bu391f09e2015-10-29 13:49:39 -07003653 <"/*"> { pushState(); } : INSIDE_COMMENT
3654}
3655
3656<INSIDE_COMMENT>
3657SPECIAL_TOKEN:
3658{
3659 <"+"(" ")*(~["*"])*>
3660}
3661
3662<INSIDE_COMMENT>
3663SKIP:
3664{
3665 <"/*"> { pushState(); }
3666}
3667
3668<INSIDE_COMMENT>
3669SKIP:
3670{
3671 <"*/"> { popState("*/"); }
3672 | <~[]>
3673}