blob: 53faff925774ab57e07340312b1b007bb6d7f2b3 [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 {
Dmitry Lychagine77cdac2019-08-05 11:37:47 -070020 COMMON_TOKEN_ACTION = true;
21 STATIC = false;
22 TOKEN_EXTENDS = "org.apache.asterix.lang.sqlpp.parser.SqlppToken";
Yingyi Bu391f09e2015-10-29 13:49:39 -070023}
24
Yingyi Bu391f09e2015-10-29 13:49:39 -070025PARSER_BEGIN(SQLPPParser)
26
27package org.apache.asterix.lang.sqlpp.parser;
28
29// For SQL++ ParserTokenManager
Till Westmanne9b2adf2016-10-15 12:39:01 -070030import java.util.ArrayDeque;
Yingyi Bu391f09e2015-10-29 13:49:39 -070031
32import java.io.BufferedReader;
33import java.io.File;
34import java.io.FileInputStream;
35import java.io.FileNotFoundException;
36import java.io.IOException;
37import java.io.InputStreamReader;
38import java.io.Reader;
39import java.io.StringReader;
40import java.util.ArrayList;
Dmitry Lychagin1f6a6e32019-07-02 11:59:53 -070041import java.util.Arrays;
42import java.util.Collection;
Yingyi Budaa549c2016-06-28 22:30:52 -070043import java.util.Collections;
Yingyi Bu391f09e2015-10-29 13:49:39 -070044import java.util.HashMap;
Dmitry Lychagin1f6a6e32019-07-02 11:59:53 -070045import java.util.HashSet;
Yingyi Bu391f09e2015-10-29 13:49:39 -070046import java.util.Iterator;
47import java.util.LinkedHashMap;
48import java.util.List;
49import java.util.Map;
50
51import org.apache.asterix.common.annotations.AutoDataGen;
52import org.apache.asterix.common.annotations.DateBetweenYearsDataGen;
53import org.apache.asterix.common.annotations.DatetimeAddRandHoursDataGen;
54import org.apache.asterix.common.annotations.DatetimeBetweenYearsDataGen;
55import org.apache.asterix.common.annotations.FieldIntervalDataGen;
56import org.apache.asterix.common.annotations.FieldValFileDataGen;
57import org.apache.asterix.common.annotations.FieldValFileSameIndexDataGen;
58import org.apache.asterix.common.annotations.IRecordFieldDataGen;
59import org.apache.asterix.common.annotations.InsertRandIntDataGen;
60import org.apache.asterix.common.annotations.ListDataGen;
61import org.apache.asterix.common.annotations.ListValFileDataGen;
62import org.apache.asterix.common.annotations.SkipSecondaryIndexSearchExpressionAnnotation;
63import org.apache.asterix.common.annotations.TypeDataGen;
64import org.apache.asterix.common.annotations.UndeclaredFieldsDataGen;
65import org.apache.asterix.common.config.DatasetConfig.DatasetType;
66import org.apache.asterix.common.config.DatasetConfig.IndexType;
Taewoo Kime65e6ca2017-01-14 17:53:28 -080067import org.apache.asterix.common.exceptions.CompilationException;
Dmitry Lychagin85142c02018-04-05 17:27:36 -070068import org.apache.asterix.common.exceptions.ErrorCode;
Dmitry Lychagin1f6a6e32019-07-02 11:59:53 -070069import org.apache.asterix.common.exceptions.WarningCollector;
70import org.apache.asterix.common.exceptions.WarningUtil;
Dmitry Lychagin7c53fcf2017-11-07 12:07:41 -080071import org.apache.asterix.common.functions.FunctionConstants;
Yingyi Bu391f09e2015-10-29 13:49:39 -070072import org.apache.asterix.common.functions.FunctionSignature;
Dmitry Lychagin54c06012019-11-13 15:54:20 -080073import org.apache.asterix.common.metadata.DataverseName;
Dmitry Lychagin276adf92019-01-15 13:16:40 -080074import org.apache.asterix.lang.common.base.AbstractClause;
Dmitry Lychaginee54cc02018-05-25 19:26:18 -070075import org.apache.asterix.lang.common.base.AbstractLangExpression;
76import org.apache.asterix.lang.common.base.AbstractStatement;
Yingyi Bu391f09e2015-10-29 13:49:39 -070077import org.apache.asterix.lang.common.base.Expression;
78import org.apache.asterix.lang.common.base.Literal;
79import org.apache.asterix.lang.common.base.IParser;
Dmitry Lychaginee54cc02018-05-25 19:26:18 -070080import org.apache.asterix.lang.common.base.ILangExpression;
Ali Alsuliman80225e22018-10-15 14:17:07 -070081import org.apache.asterix.lang.common.base.IParserFactory;
Yingyi Bu391f09e2015-10-29 13:49:39 -070082import org.apache.asterix.lang.common.base.Statement;
83import org.apache.asterix.lang.common.clause.GroupbyClause;
84import org.apache.asterix.lang.common.clause.LetClause;
85import org.apache.asterix.lang.common.clause.LimitClause;
86import org.apache.asterix.lang.common.clause.OrderbyClause;
87import org.apache.asterix.lang.common.clause.UpdateClause;
88import org.apache.asterix.lang.common.clause.WhereClause;
89import org.apache.asterix.lang.common.context.RootScopeFactory;
90import org.apache.asterix.lang.common.context.Scope;
91import org.apache.asterix.lang.common.expression.AbstractAccessor;
92import org.apache.asterix.lang.common.expression.CallExpr;
93import org.apache.asterix.lang.common.expression.FieldAccessor;
94import org.apache.asterix.lang.common.expression.FieldBinding;
95import org.apache.asterix.lang.common.expression.GbyVariableExpressionPair;
96import org.apache.asterix.lang.common.expression.IfExpr;
97import org.apache.asterix.lang.common.expression.IndexAccessor;
Dmitry Lychagin8ba59442017-06-16 14:19:45 -070098import org.apache.asterix.lang.common.expression.IndexedTypeExpression;
Yingyi Bu391f09e2015-10-29 13:49:39 -070099import org.apache.asterix.lang.common.expression.ListConstructor;
Hussain Towailebc5b5deb2018-12-15 18:48:48 +0300100import org.apache.asterix.lang.common.expression.ListSliceExpression;
Yingyi Bu391f09e2015-10-29 13:49:39 -0700101import org.apache.asterix.lang.common.expression.LiteralExpr;
102import org.apache.asterix.lang.common.expression.OperatorExpr;
103import org.apache.asterix.lang.common.expression.OrderedListTypeDefinition;
104import org.apache.asterix.lang.common.expression.QuantifiedExpression;
105import org.apache.asterix.lang.common.expression.RecordConstructor;
106import org.apache.asterix.lang.common.expression.RecordTypeDefinition;
107import org.apache.asterix.lang.common.expression.TypeExpression;
108import org.apache.asterix.lang.common.expression.TypeReferenceExpression;
109import org.apache.asterix.lang.common.expression.UnaryExpr;
Yingyi Bu391f09e2015-10-29 13:49:39 -0700110import org.apache.asterix.lang.common.expression.UnorderedListTypeDefinition;
111import org.apache.asterix.lang.common.expression.VariableExpr;
112import org.apache.asterix.lang.common.literal.DoubleLiteral;
113import org.apache.asterix.lang.common.literal.FalseLiteral;
114import org.apache.asterix.lang.common.literal.FloatLiteral;
115import org.apache.asterix.lang.common.literal.LongIntegerLiteral;
Yingyi Bu535d86b2016-05-23 16:44:25 -0700116import org.apache.asterix.lang.common.literal.MissingLiteral;
Yingyi Bu391f09e2015-10-29 13:49:39 -0700117import org.apache.asterix.lang.common.literal.NullLiteral;
118import org.apache.asterix.lang.common.literal.StringLiteral;
119import org.apache.asterix.lang.common.literal.TrueLiteral;
120import org.apache.asterix.lang.common.parser.ScopeChecker;
121import org.apache.asterix.lang.common.statement.CompactStatement;
122import org.apache.asterix.lang.common.statement.ConnectFeedStatement;
Abdullah Alamoudifff200c2017-02-18 20:32:14 -0800123import org.apache.asterix.lang.common.statement.StartFeedStatement;
124import org.apache.asterix.lang.common.statement.StopFeedStatement;
Ian Maxon38fe9402020-01-29 19:27:40 -0800125import org.apache.asterix.lang.common.statement.CreateAdapterStatement;
Yingyi Bu391f09e2015-10-29 13:49:39 -0700126import org.apache.asterix.lang.common.statement.CreateDataverseStatement;
127import org.apache.asterix.lang.common.statement.CreateFeedPolicyStatement;
128import org.apache.asterix.lang.common.statement.CreateFeedStatement;
129import org.apache.asterix.lang.common.statement.CreateFunctionStatement;
130import org.apache.asterix.lang.common.statement.CreateIndexStatement;
Dmitry Lychagin2a0848e2020-01-08 13:57:22 -0800131import org.apache.asterix.lang.common.statement.CreateSynonymStatement;
Yingyi Bu391f09e2015-10-29 13:49:39 -0700132import org.apache.asterix.lang.common.statement.DatasetDecl;
133import org.apache.asterix.lang.common.statement.DataverseDecl;
134import org.apache.asterix.lang.common.statement.DataverseDropStatement;
135import org.apache.asterix.lang.common.statement.DeleteStatement;
136import org.apache.asterix.lang.common.statement.DisconnectFeedStatement;
Yingyi Buab817482016-08-19 21:29:31 -0700137import org.apache.asterix.lang.common.statement.DropDatasetStatement;
Yingyi Bu391f09e2015-10-29 13:49:39 -0700138import org.apache.asterix.lang.common.statement.ExternalDetailsDecl;
139import org.apache.asterix.lang.common.statement.FeedDropStatement;
Abdullah Alamoudi5dc73ed2016-07-28 05:03:13 +0300140import org.apache.asterix.lang.common.statement.FeedPolicyDropStatement;
Yingyi Bu391f09e2015-10-29 13:49:39 -0700141import org.apache.asterix.lang.common.statement.FunctionDecl;
142import org.apache.asterix.lang.common.statement.FunctionDropStatement;
143import org.apache.asterix.lang.common.statement.IndexDropStatement;
144import org.apache.asterix.lang.common.statement.InsertStatement;
145import org.apache.asterix.lang.common.statement.InternalDetailsDecl;
146import org.apache.asterix.lang.common.statement.LoadStatement;
147import org.apache.asterix.lang.common.statement.NodeGroupDropStatement;
148import org.apache.asterix.lang.common.statement.NodegroupDecl;
149import org.apache.asterix.lang.common.statement.Query;
150import org.apache.asterix.lang.common.statement.RefreshExternalDatasetStatement;
Yingyi Bu391f09e2015-10-29 13:49:39 -0700151import org.apache.asterix.lang.common.statement.SetStatement;
Dmitry Lychagin2a0848e2020-01-08 13:57:22 -0800152import org.apache.asterix.lang.common.statement.SynonymDropStatement;
Yingyi Bu391f09e2015-10-29 13:49:39 -0700153import org.apache.asterix.lang.common.statement.TypeDecl;
154import org.apache.asterix.lang.common.statement.TypeDropStatement;
155import org.apache.asterix.lang.common.statement.UpdateStatement;
Yingyi Bucb5bf332017-01-02 22:19:50 -0800156import org.apache.asterix.lang.common.statement.UpsertStatement;
Yingyi Bu391f09e2015-10-29 13:49:39 -0700157import org.apache.asterix.lang.common.statement.WriteStatement;
158import org.apache.asterix.lang.common.struct.Identifier;
Dmitry Lychaginef1719e2017-12-15 08:33:07 -0800159import org.apache.asterix.lang.common.struct.OperatorType;
Yingyi Bu391f09e2015-10-29 13:49:39 -0700160import org.apache.asterix.lang.common.struct.QuantifiedPair;
161import org.apache.asterix.lang.common.struct.VarIdentifier;
Ali Alsuliman80225e22018-10-15 14:17:07 -0700162import org.apache.asterix.lang.common.util.RangeMapBuilder;
Yingyi Bu391f09e2015-10-29 13:49:39 -0700163import org.apache.asterix.lang.sqlpp.clause.AbstractBinaryCorrelateClause;
164import org.apache.asterix.lang.sqlpp.clause.FromClause;
165import org.apache.asterix.lang.sqlpp.clause.FromTerm;
166import org.apache.asterix.lang.sqlpp.clause.HavingClause;
167import org.apache.asterix.lang.sqlpp.clause.JoinClause;
Yingyi Bu391f09e2015-10-29 13:49:39 -0700168import org.apache.asterix.lang.sqlpp.clause.Projection;
169import org.apache.asterix.lang.sqlpp.clause.SelectBlock;
170import org.apache.asterix.lang.sqlpp.clause.SelectClause;
171import org.apache.asterix.lang.sqlpp.clause.SelectElement;
172import org.apache.asterix.lang.sqlpp.clause.SelectRegular;
173import org.apache.asterix.lang.sqlpp.clause.SelectSetOperation;
174import org.apache.asterix.lang.sqlpp.clause.UnnestClause;
Xikui Wangf6741682018-02-22 19:17:17 -0800175import org.apache.asterix.lang.common.clause.WhereClause;
Yingyi Buc8c067c2016-07-25 23:37:19 -0700176import org.apache.asterix.lang.sqlpp.expression.CaseExpression;
Yingyi Bu391f09e2015-10-29 13:49:39 -0700177import org.apache.asterix.lang.sqlpp.expression.SelectExpression;
Dmitry Lychaginfdedf622018-10-30 18:12:40 -0700178import org.apache.asterix.lang.sqlpp.expression.WindowExpression;
Yingyi Bu391f09e2015-10-29 13:49:39 -0700179import org.apache.asterix.lang.sqlpp.optype.JoinType;
180import org.apache.asterix.lang.sqlpp.optype.SetOpType;
Dmitry Lychaginac98f482020-03-31 12:26:40 -0700181import org.apache.asterix.lang.sqlpp.parser.SqlppGroupingSetsParser;
182import org.apache.asterix.lang.sqlpp.parser.SqlppGroupingSetsParser.GroupingElement;
183import org.apache.asterix.lang.sqlpp.parser.SqlppGroupingSetsParser.GroupingSet;
184import org.apache.asterix.lang.sqlpp.parser.SqlppGroupingSetsParser.GroupingSets;
185import org.apache.asterix.lang.sqlpp.parser.SqlppGroupingSetsParser.RollupCube;
Dmitry Lychagine77cdac2019-08-05 11:37:47 -0700186import org.apache.asterix.lang.sqlpp.parser.SqlppHint;
Yingyi Bu391f09e2015-10-29 13:49:39 -0700187import org.apache.asterix.lang.sqlpp.struct.SetOperationInput;
188import org.apache.asterix.lang.sqlpp.struct.SetOperationRight;
Yingyi Bu9e3f9be2016-07-01 10:07:37 -0700189import org.apache.asterix.lang.sqlpp.util.ExpressionToVariableUtil;
Xikui Wang96fd4022017-04-10 14:23:31 -0700190import org.apache.asterix.lang.sqlpp.util.FunctionMapUtil;
Yingyi Buacc12a92016-03-26 17:25:05 -0700191import org.apache.asterix.lang.sqlpp.util.SqlppVariableUtil;
Ian Maxon38fe9402020-01-29 19:27:40 -0800192import org.apache.asterix.external.dataset.adapter.AdapterIdentifier;
Dmitry Lychagin7c53fcf2017-11-07 12:07:41 -0800193import org.apache.asterix.om.functions.BuiltinFunctions;
Dmitry Lychagin75f19872019-10-03 17:56:35 -0700194import org.apache.asterix.om.types.BuiltinType;
Dmitry Lychagine77cdac2019-08-05 11:37:47 -0700195import org.apache.commons.lang3.ArrayUtils;
Dmitry Lychagin1f6a6e32019-07-02 11:59:53 -0700196import org.apache.commons.lang3.StringUtils;
Yingyi Bu391f09e2015-10-29 13:49:39 -0700197import org.apache.hyracks.algebricks.common.utils.Pair;
198import org.apache.hyracks.algebricks.common.utils.Triple;
Xikui Wang5a61b2a2018-01-02 14:14:03 -0800199import org.apache.hyracks.algebricks.common.exceptions.AlgebricksException;
Shiva2ea73232019-10-09 18:04:05 -0700200import org.apache.hyracks.algebricks.core.algebra.expressions.BroadcastExpressionAnnotation;
Yingyi Bu391f09e2015-10-29 13:49:39 -0700201import org.apache.hyracks.algebricks.core.algebra.expressions.IExpressionAnnotation;
202import org.apache.hyracks.algebricks.core.algebra.expressions.IndexedNLJoinExpressionAnnotation;
203import org.apache.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
Dmitry Lychaginee54cc02018-05-25 19:26:18 -0700204import org.apache.hyracks.api.exceptions.SourceLocation;
Dmitry Lychagin1f6a6e32019-07-02 11:59:53 -0700205import org.apache.hyracks.api.exceptions.Warning;
Ali Alsuliman587b7902019-01-21 14:33:50 -0800206import org.apache.hyracks.util.LogRedactionUtil;
Dmitry Lychagine77cdac2019-08-05 11:37:47 -0700207import org.apache.hyracks.util.StringUtil;
Yingyi Bu391f09e2015-10-29 13:49:39 -0700208
Yingyi Bucaea8f02015-11-16 15:12:15 -0800209class SQLPPParser extends ScopeChecker implements IParser {
Yingyi Bu391f09e2015-10-29 13:49:39 -0700210
Dmitry Lychaginf2c18aa2018-12-28 21:20:23 -0800211 // tokens parsed as identifiers
Dmitry Lychaginac98f482020-03-31 12:26:40 -0700212 private static final String CUBE = "CUBE";
Dmitry Lychaginf2c18aa2018-12-28 21:20:23 -0800213 private static final String CURRENT = "CURRENT";
214 private static final String EXCLUDE = "EXCLUDE";
Dmitry Lychagin5476f962019-05-31 16:03:11 -0700215 private static final String FIRST = "FIRST";
Dmitry Lychaginf2c18aa2018-12-28 21:20:23 -0800216 private static final String FOLLOWING = "FOLLOWING";
Dmitry Lychaginac98f482020-03-31 12:26:40 -0700217 private static final String GROUPING = "GROUPING";
Dmitry Lychaginf2c18aa2018-12-28 21:20:23 -0800218 private static final String GROUPS = "GROUPS";
Dmitry Lychagin3346cea2019-05-28 12:11:54 -0700219 private static final String IGNORE = "IGNORE";
Dmitry Lychagin5476f962019-05-31 16:03:11 -0700220 private static final String LAST = "LAST";
Dmitry Lychaginf2c18aa2018-12-28 21:20:23 -0800221 private static final String NO = "NO";
Dmitry Lychagin3346cea2019-05-28 12:11:54 -0700222 private static final String NULLS = "NULLS";
Dmitry Lychaginf2c18aa2018-12-28 21:20:23 -0800223 private static final String OTHERS = "OTHERS";
224 private static final String PARTITION = "PARTITION";
225 private static final String PRECEDING = "PRECEDING";
226 private static final String RANGE = "RANGE";
Dmitry Lychagin3346cea2019-05-28 12:11:54 -0700227 private static final String RESPECT = "RESPECT";
Dmitry Lychaginac98f482020-03-31 12:26:40 -0700228 private static final String ROLLUP = "ROLLUP";
Dmitry Lychaginf2c18aa2018-12-28 21:20:23 -0800229 private static final String ROW = "ROW";
230 private static final String ROWS = "ROWS";
Dmitry Lychaginac98f482020-03-31 12:26:40 -0700231 private static final String SETS = "SETS";
Dmitry Lychaginf2c18aa2018-12-28 21:20:23 -0800232 private static final String TIES = "TIES";
233 private static final String UNBOUNDED = "UNBOUNDED";
Ian Maxon38fe9402020-01-29 19:27:40 -0800234 private static final String ACTION = "ACTION";
235 private static final String LANGUAGE = "LANGUAGE";
236 private static final String CALL = "CALL";
237 private static final String DETERMINISTIC = "DETERMINISTIC";
238 private static final String RETURNS = "RETURNS";
239 private static final String INLINE = "INLINE";
240
Dmitry Lychaginf2c18aa2018-12-28 21:20:23 -0800241
Dmitry Lychagin75f19872019-10-03 17:56:35 -0700242 private static final String INT_TYPE_NAME = "int";
243
Till Westmann7199a562016-09-17 16:07:32 -0700244 // error configuration
245 protected static final boolean REPORT_EXPECTED_TOKENS = false;
246
Dmitry Lychagin1bdf8082018-06-13 14:48:23 -0700247 private int externalVarCounter;
248
Dmitry Lychagin54c06012019-11-13 15:54:20 -0800249 private DataverseName defaultDataverse;
250
Dmitry Lychaginac98f482020-03-31 12:26:40 -0700251 private SqlppGroupingSetsParser groupingSetsParser;
252
Dmitry Lychagin1f6a6e32019-07-02 11:59:53 -0700253 private final WarningCollector warningCollector = new WarningCollector();
254
Dmitry Lychagine77cdac2019-08-05 11:37:47 -0700255 private final Map<SourceLocation, String> hintCollector = new HashMap<SourceLocation, String>();
256
Yingyi Bu391f09e2015-10-29 13:49:39 -0700257 private static class IndexParams {
258 public IndexType type;
259 public int gramLength;
260
261 public IndexParams(IndexType type, int gramLength) {
262 this.type = type;
263 this.gramLength = gramLength;
264 }
265 };
266
267 private static class FunctionName {
Dmitry Lychagin54c06012019-11-13 15:54:20 -0800268 public DataverseName dataverse;
Dmitry Lychaginee54cc02018-05-25 19:26:18 -0700269 public String library;
270 public String function;
Dmitry Lychagine77cdac2019-08-05 11:37:47 -0700271 public SqlppHint hint;
Dmitry Lychaginee54cc02018-05-25 19:26:18 -0700272 public SourceLocation sourceLoc;
Yingyi Bu391f09e2015-10-29 13:49:39 -0700273 }
274
Dmitry Lychagine77cdac2019-08-05 11:37:47 -0700275 private IRecordFieldDataGen parseFieldDataGen(Token hintToken) throws ParseException {
276 String[] splits = hintToken.hintParams != null ? hintToken.hintParams.split("\\s+") : null;
277 switch (hintToken.hint) {
278 case VAL_FILE_HINT:
279 File[] valFiles = new File[splits.length];
280 for (int k=0; k<splits.length; k++) {
281 valFiles[k] = new File(splits[k]);
282 }
283 return new FieldValFileDataGen(valFiles);
284 case VAL_FILE_SAME_INDEX_HINT:
285 return new FieldValFileSameIndexDataGen(new File(splits[0]), splits[1]);
286 case LIST_VAL_FILE_HINT:
287 return new ListValFileDataGen(new File(splits[0]), Integer.parseInt(splits[1]), Integer.parseInt(splits[2]));
288 case LIST_HINT:
289 return new ListDataGen(Integer.parseInt(splits[0]), Integer.parseInt(splits[1]));
290 case INTERVAL_HINT:
291 FieldIntervalDataGen.ValueType vt;
292 switch (splits[0]) {
293 case "int":
294 vt = FieldIntervalDataGen.ValueType.INT;
295 break;
296 case "long":
297 vt = FieldIntervalDataGen.ValueType.LONG;
298 break;
299 case "float":
300 vt = FieldIntervalDataGen.ValueType.FLOAT;
301 break;
302 case "double":
303 vt = FieldIntervalDataGen.ValueType.DOUBLE;
304 break;
305 default:
306 throw new SqlppParseException(getSourceLocation(hintToken),
307 "Unknown type for interval data gen: " + splits[0]);
308 }
309 return new FieldIntervalDataGen(vt, splits[1], splits[2]);
310 case INSERT_RAND_INT_HINT:
311 return new InsertRandIntDataGen(splits[0], splits[1]);
312 case DATE_BETWEEN_YEARS_HINT:
313 return new DateBetweenYearsDataGen(Integer.parseInt(splits[0]), Integer.parseInt(splits[1]));
314 case DATETIME_BETWEEN_YEARS_HINT:
315 return new DatetimeBetweenYearsDataGen(Integer.parseInt(splits[0]), Integer.parseInt(splits[1]));
316 case DATETIME_ADD_RAND_HOURS_HINT:
317 return new DatetimeAddRandHoursDataGen(Integer.parseInt(splits[0]), Integer.parseInt(splits[1]), splits[2]);
318 case AUTO_HINT:
319 return new AutoDataGen(splits[0]);
320 default:
321 return null;
Yingyi Bu391f09e2015-10-29 13:49:39 -0700322 }
Yingyi Bu391f09e2015-10-29 13:49:39 -0700323 }
324
Till Westmann7199a562016-09-17 16:07:32 -0700325 public SQLPPParser(String s) {
Yingyi Bu391f09e2015-10-29 13:49:39 -0700326 this(new StringReader(s));
327 super.setInput(s);
Dmitry Lychagine77cdac2019-08-05 11:37:47 -0700328 token_source.hintCollector = hintCollector;
Yingyi Bu391f09e2015-10-29 13:49:39 -0700329 }
330
Taewoo Kime65e6ca2017-01-14 17:53:28 -0800331 public static void main(String args[]) throws ParseException, TokenMgrError, IOException, FileNotFoundException, CompilationException {
Yingyi Bu391f09e2015-10-29 13:49:39 -0700332 File file = new File(args[0]);
333 Reader fis = new BufferedReader(new InputStreamReader(new FileInputStream(file), "UTF-8"));
334 SQLPPParser parser = new SQLPPParser(fis);
335 List<Statement> st = parser.parse();
336 //st.accept(new SQLPPPrintVisitor(), 0);
337 }
338
Dmitry Lychagin45de2342020-02-03 12:01:28 -0800339 @Override
Taewoo Kime65e6ca2017-01-14 17:53:28 -0800340 public List<Statement> parse() throws CompilationException {
Dmitry Lychagin1227f022019-08-01 13:14:30 -0700341 return parseImpl(new ParseFunction<List<Statement>>() {
342 @Override
343 public List<Statement> parse() throws ParseException {
344 return SQLPPParser.this.Statement();
345 }
346 });
347 }
348
349 private Expression parseExpression() throws CompilationException {
350 return parseImpl(new ParseFunction<Expression>() {
351 @Override
352 public Expression parse() throws ParseException {
353 return SQLPPParser.this.Expression();
354 }
355 });
356 }
357
358 private static Expression parseExpression(String text) throws CompilationException {
359 return new SQLPPParser(text).parseExpression();
360 }
361
Dmitry Lychagin45de2342020-02-03 12:01:28 -0800362 @Override
Dmitry Lychagine74454b2020-02-06 13:44:21 -0800363 public FunctionDecl parseFunctionBody(FunctionSignature signature, List<String> paramNames)
Dmitry Lychagin45de2342020-02-03 12:01:28 -0800364 throws CompilationException {
Dmitry Lychagine74454b2020-02-06 13:44:21 -0800365 return parseImpl(new ParseFunction<FunctionDecl>() {
Dmitry Lychagin45de2342020-02-03 12:01:28 -0800366 @Override
Dmitry Lychagine74454b2020-02-06 13:44:21 -0800367 public FunctionDecl parse() throws ParseException {
Dmitry Lychagin45de2342020-02-03 12:01:28 -0800368 DataverseName dataverse = defaultDataverse;
369 defaultDataverse = signature.getDataverseName();
370 createNewScope();
Dmitry Lychagine74454b2020-02-06 13:44:21 -0800371 List<VarIdentifier> paramVars = new ArrayList<VarIdentifier>(paramNames.size());
372 for (String paramName : paramNames) {
373 paramVars.add(SqlppVariableUtil.toInternalVariableIdentifier(paramName));
374 }
Dmitry Lychagin45de2342020-02-03 12:01:28 -0800375 Expression functionBodyExpr = SQLPPParser.this.FunctionBody();
376 removeCurrentScope();
377 defaultDataverse = dataverse;
Dmitry Lychagine74454b2020-02-06 13:44:21 -0800378 return new FunctionDecl(signature, paramVars, functionBodyExpr);
Dmitry Lychagin45de2342020-02-03 12:01:28 -0800379 }
380 });
381 }
382
Dmitry Lychagin1227f022019-08-01 13:14:30 -0700383 private <T> T parseImpl(ParseFunction<T> parseFunction) throws CompilationException {
Dmitry Lychagin1f6a6e32019-07-02 11:59:53 -0700384 warningCollector.clear();
Dmitry Lychagine77cdac2019-08-05 11:37:47 -0700385 hintCollector.clear();
Yingyi Bu391f09e2015-10-29 13:49:39 -0700386 try {
Dmitry Lychagin1227f022019-08-01 13:14:30 -0700387 return parseFunction.parse();
Yingyi Bu391f09e2015-10-29 13:49:39 -0700388 } catch (Error e) {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -0700389 // 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 -0700390 // 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 -0700391 final String msg = e.getClass().getSimpleName() + (e.getMessage() != null ? ": " + e.getMessage() : "");
Ali Alsulimanfe901892019-03-19 01:40:35 -0700392 throw new CompilationException(ErrorCode.PARSE_ERROR, LogRedactionUtil.userData(msg));
Dmitry Lychaginee54cc02018-05-25 19:26:18 -0700393 } catch (SqlppParseException e) {
Ali Alsulimanfe901892019-03-19 01:40:35 -0700394 throw new CompilationException(ErrorCode.PARSE_ERROR, e.getSourceLocation(), LogRedactionUtil.userData(getMessage(e)));
Yingyi Bu391f09e2015-10-29 13:49:39 -0700395 } catch (ParseException e) {
Ali Alsulimanfe901892019-03-19 01:40:35 -0700396 throw new CompilationException(ErrorCode.PARSE_ERROR, LogRedactionUtil.userData(getMessage(e)));
Dmitry Lychagine77cdac2019-08-05 11:37:47 -0700397 } finally {
398 reportUnclaimedHints();
Yingyi Bu391f09e2015-10-29 13:49:39 -0700399 }
400 }
Till Westmann7199a562016-09-17 16:07:32 -0700401
Dmitry Lychagin1227f022019-08-01 13:14:30 -0700402 @FunctionalInterface
403 private interface ParseFunction<T> {
404 T parse() throws ParseException;
405 }
406
Dmitry Lychagin1f6a6e32019-07-02 11:59:53 -0700407 @Override
Ali Alsuliman6a9e2b02019-09-16 20:50:41 -0700408 public void getWarnings(Collection<? super Warning> outWarnings, long maxWarnings) {
409 warningCollector.getWarnings(outWarnings, maxWarnings);
410 }
411
412 @Override
413 public long getTotalWarningsCount() {
414 return warningCollector.getTotalWarningsCount();
Dmitry Lychagin1f6a6e32019-07-02 11:59:53 -0700415 }
416
Till Westmann7199a562016-09-17 16:07:32 -0700417 protected String getMessage(ParseException pe) {
418 Token currentToken = pe.currentToken;
419 if (currentToken == null) {
420 return pe.getMessage();
421 }
422 int[][] expectedTokenSequences = pe.expectedTokenSequences;
423 String[] tokenImage = pe.tokenImage;
424 String sep = REPORT_EXPECTED_TOKENS ? eol : " ";
425 StringBuilder expected = REPORT_EXPECTED_TOKENS ? new StringBuilder() : null;
426 int maxSize = appendExpected(expected, expectedTokenSequences, tokenImage);
427 Token tok = currentToken.next;
428 int line = tok.beginLine;
Dmitry Lychaginee54cc02018-05-25 19:26:18 -0700429 StringBuilder message = new StringBuilder(128);
430 message.append("In line ").append(line).append(" >>").append(getLine(line)).append("<<").append(sep).append("Encountered ");
Till Westmann7199a562016-09-17 16:07:32 -0700431 for (int i = 0; i < maxSize; i++) {
432 if (i != 0) {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -0700433 message.append(' ');
Till Westmann7199a562016-09-17 16:07:32 -0700434 }
435 if (tok.kind == 0) {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -0700436 message.append(fixQuotes(tokenImage[0]));
Till Westmann7199a562016-09-17 16:07:32 -0700437 break;
438 }
Till Westmanne3c9f272016-10-09 11:09:26 -0700439 final String fixedTokenImage = tokenImage[tok.kind];
440 if (! tok.image.equalsIgnoreCase(stripQuotes(fixedTokenImage))) {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -0700441 message.append(fixQuotes(fixedTokenImage)).append(' ');
Till Westmanne3c9f272016-10-09 11:09:26 -0700442 }
Dmitry Lychaginee54cc02018-05-25 19:26:18 -0700443 message.append(quot).append(addEscapes(tok.image)).append(quot);
Till Westmann7199a562016-09-17 16:07:32 -0700444 tok = tok.next;
445 }
Dmitry Lychaginee54cc02018-05-25 19:26:18 -0700446 message.append(" at column ").append(currentToken.next.beginColumn).append('.').append(sep);
Till Westmann7199a562016-09-17 16:07:32 -0700447 if (REPORT_EXPECTED_TOKENS) {
448 if (expectedTokenSequences.length == 1) {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -0700449 message.append("Was expecting:").append(sep).append(" ");
Till Westmann7199a562016-09-17 16:07:32 -0700450 } else {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -0700451 message.append("Was expecting one of:").append(sep).append(" ");
Till Westmann7199a562016-09-17 16:07:32 -0700452 }
Dmitry Lychaginee54cc02018-05-25 19:26:18 -0700453 message.append(expected);
Till Westmann7199a562016-09-17 16:07:32 -0700454 }
Dmitry Lychaginee54cc02018-05-25 19:26:18 -0700455 return message.toString();
Till Westmann7199a562016-09-17 16:07:32 -0700456 }
457
Dmitry Lychaginee54cc02018-05-25 19:26:18 -0700458 protected static SourceLocation getSourceLocation(Token token) {
Dmitry Lychagine77cdac2019-08-05 11:37:47 -0700459 return
460 token == null ? null :
461 token.sourceLocation != null ? token.sourceLocation :
462 new SourceLocation(token.beginLine, token.beginColumn);
Dmitry Lychaginee54cc02018-05-25 19:26:18 -0700463 }
464
Dmitry Lychagin5c26b422018-06-01 10:22:16 -0700465 protected static <T extends AbstractLangExpression> T addSourceLocation(T expr, Token token) {
466 expr.setSourceLocation(getSourceLocation(token));
467 return expr;
Dmitry Lychaginee54cc02018-05-25 19:26:18 -0700468 }
Dmitry Lychaginf2c18aa2018-12-28 21:20:23 -0800469
470 private boolean isToken(String image) {
471 return token.image.equalsIgnoreCase(image);
472 }
473
474 private void expectToken(String image) throws SqlppParseException {
475 if (!isToken(image)) {
476 throw createUnexpectedTokenError();
477 }
478 }
479
480 private SqlppParseException createUnexpectedTokenError() {
Dmitry Lychagin0d4c1b62020-02-07 17:10:16 -0800481 return createUnexpectedTokenError(null);
482 }
483
484 private SqlppParseException createUnexpectedTokenError(String expected) {
485 String message = "Unexpected token: " + LogRedactionUtil.userData(token.image) +
486 (expected == null ? "" : ". Expected: " + LogRedactionUtil.userData(expected));
487 return new SqlppParseException(getSourceLocation(token), message);
Dmitry Lychaginf2c18aa2018-12-28 21:20:23 -0800488 }
489
Dmitry Lychaginac98f482020-03-31 12:26:40 -0700490 private boolean laToken(int idx, int kind) {
491 Token t = getToken(idx);
492 return t.kind == kind;
493 }
494
Dmitry Lychaginf2c18aa2018-12-28 21:20:23 -0800495 private boolean laToken(int idx, int kind, String image) {
496 Token t = getToken(idx);
497 return t.kind == kind && t.image.equalsIgnoreCase(image);
498 }
499
500 private boolean laIdentifier(int idx, String image) {
501 return laToken(idx, IDENTIFIER, image);
502 }
503
504 private boolean laIdentifier(String image) {
505 return laIdentifier(1, image);
506 }
Dmitry Lychagin1f6a6e32019-07-02 11:59:53 -0700507
Dmitry Lychagine77cdac2019-08-05 11:37:47 -0700508 private Token fetchHint(Token token, SqlppHint... expectedHints) {
509 Token hintToken = token.specialToken;
510 if (hintToken == null) {
511 return null;
512 }
513 SourceLocation sourceLoc = getSourceLocation(hintToken);
514 hintCollector.remove(sourceLoc);
515 if (hintToken.hint == null) {
516 warnUnexpectedHint(hintToken.hintParams, sourceLoc, expectedHints);
517 return null;
518 } else if (!ArrayUtils.contains(expectedHints, hintToken.hint)) {
519 warnUnexpectedHint(hintToken.hint.getIdentifier(), sourceLoc, expectedHints);
520 return null;
521 } else {
522 return hintToken;
523 }
524 }
525
526 private void reportUnclaimedHints() {
527 for (Map.Entry<SourceLocation, String> me : hintCollector.entrySet()) {
528 warnUnexpectedHint(me.getValue(), me.getKey(), "None");
529 }
530 }
531
532 private void warnUnexpectedHint(String actualHint, SourceLocation sourceLoc, SqlppHint... expectedHints) {
533 warnUnexpectedHint(actualHint, sourceLoc, StringUtil.join(expectedHints, ", ", "\""));
534 }
535
536 private void warnUnexpectedHint(String actualHint, SourceLocation sourceLoc, String expectedHints) {
Ali Alsulimanaa118862019-09-10 20:55:45 -0700537 if (warningCollector.shouldWarn()) {
538 warningCollector.warn(WarningUtil.forAsterix(sourceLoc, ErrorCode.UNEXPECTED_HINT, actualHint, expectedHints));
539 }
Dmitry Lychagin1f6a6e32019-07-02 11:59:53 -0700540 }
Yingyi Bu391f09e2015-10-29 13:49:39 -0700541}
542
543PARSER_END(SQLPPParser)
544
Yingyi Bu391f09e2015-10-29 13:49:39 -0700545List<Statement> Statement() throws ParseException:
546{
547 scopeStack.push(RootScopeFactory.createRootScope(this));
548 List<Statement> decls = new ArrayList<Statement>();
549 Statement stmt = null;
550}
551{
Murtadha Hubaildc775222017-08-21 15:22:45 +0300552 (
Dmitry Lychaginaebd0312019-06-04 08:55:39 -0700553 (stmt = ExplainStatement()
Murtadha Hubaildc775222017-08-21 15:22:45 +0300554 {
555 decls.add(stmt);
556 }
557 )?
558 (<SEMICOLON>)+
Yingyi Bu391f09e2015-10-29 13:49:39 -0700559 )*
560 <EOF>
561 {
562 return decls;
563 }
564}
565
Dmitry Lychaginaebd0312019-06-04 08:55:39 -0700566Statement ExplainStatement() throws ParseException:
567{
568 Statement stmt = null;
569 Token explainToken = null;
570}
571{
572 ( <EXPLAIN> { explainToken = token; } )?
573 stmt = SingleStatement()
574 {
575 if (explainToken != null) {
576 if (stmt.getKind() == Statement.Kind.QUERY) {
577 ((Query)stmt).setExplain(true);
578 } else {
579 throw new SqlppParseException(getSourceLocation(explainToken),
580 "EXPLAIN is not supported for this kind of statement");
581 }
582 }
583 return stmt;
584 }
585}
586
Yingyi Bu391f09e2015-10-29 13:49:39 -0700587Statement SingleStatement() throws ParseException:
588{
589 Statement stmt = null;
590}
591{
592 (
593 stmt = DataverseDeclaration()
594 | stmt = FunctionDeclaration()
595 | stmt = CreateStatement()
596 | stmt = LoadStatement()
597 | stmt = DropStatement()
598 | stmt = WriteStatement()
599 | stmt = SetStatement()
600 | stmt = InsertStatement()
601 | stmt = DeleteStatement()
602 | stmt = UpdateStatement()
Yingyi Bucb5bf332017-01-02 22:19:50 -0800603 | stmt = UpsertStatement()
Yingyi Buab817482016-08-19 21:29:31 -0700604 | stmt = ConnectionStatement()
Yingyi Bu391f09e2015-10-29 13:49:39 -0700605 | stmt = CompactStatement()
Dmitry Lychaginaebd0312019-06-04 08:55:39 -0700606 | stmt = Query()
Yingyi Bu391f09e2015-10-29 13:49:39 -0700607 | stmt = RefreshExternalDatasetStatement()
Yingyi Bu391f09e2015-10-29 13:49:39 -0700608 )
609 {
610 return stmt;
611 }
612}
613
614DataverseDecl DataverseDeclaration() throws ParseException:
615{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -0700616 Token startToken = null;
Dmitry Lychagin54c06012019-11-13 15:54:20 -0800617 List<String> dvName = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -0700618}
619{
Dmitry Lychagin54c06012019-11-13 15:54:20 -0800620 <USE> { startToken = token; } dvName = MultipartIdentifier()
Yingyi Bu391f09e2015-10-29 13:49:39 -0700621 {
Dmitry Lychagin54c06012019-11-13 15:54:20 -0800622 defaultDataverse = DataverseName.create(dvName);
623 DataverseDecl dvDecl = new DataverseDecl(defaultDataverse);
Dmitry Lychagin5c26b422018-06-01 10:22:16 -0700624 return addSourceLocation(dvDecl, startToken);
Yingyi Bu391f09e2015-10-29 13:49:39 -0700625 }
626}
627
628Statement CreateStatement() throws ParseException:
629{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -0700630 Token startToken = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -0700631 Statement stmt = null;
632}
633{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -0700634 <CREATE> { startToken = token; }
Yingyi Bu391f09e2015-10-29 13:49:39 -0700635 (
Dmitry Lychagin314e2792019-11-26 14:35:42 -0800636 stmt = CreateTypeStatement(startToken)
637 | stmt = CreateNodegroupStatement(startToken)
638 | stmt = CreateDatasetStatement(startToken)
639 | stmt = CreateIndexStatement(startToken)
640 | stmt = CreateDataverseStatement(startToken)
641 | stmt = CreateFunctionStatement(startToken)
Ian Maxon38fe9402020-01-29 19:27:40 -0800642 | stmt = CreateAdapterStatement(startToken)
Dmitry Lychagin2a0848e2020-01-08 13:57:22 -0800643 | stmt = CreateSynonymStatement(startToken)
Dmitry Lychagin314e2792019-11-26 14:35:42 -0800644 | stmt = CreateFeedStatement(startToken)
645 | stmt = CreateFeedPolicyStatement(startToken)
Yingyi Bu391f09e2015-10-29 13:49:39 -0700646 )
647 {
648 return stmt;
649 }
650}
651
Dmitry Lychagin314e2792019-11-26 14:35:42 -0800652TypeDecl CreateTypeStatement(Token startStmtToken) throws ParseException:
653{
654 TypeDecl stmt = null;
655}
656{
657 <TYPE> stmt = TypeSpecification(startStmtToken)
658 {
659 return stmt;
660 }
661}
662
Dmitry Lychagine77cdac2019-08-05 11:37:47 -0700663TypeDecl TypeSpecification(Token startStmtToken) throws ParseException:
Yingyi Bu391f09e2015-10-29 13:49:39 -0700664{
Dmitry Lychagin54c06012019-11-13 15:54:20 -0800665 Pair<DataverseName,Identifier> nameComponents = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -0700666 boolean ifNotExists = false;
667 TypeExpression typeExpr = null;
668}
669{
Dmitry Lychagin314e2792019-11-26 14:35:42 -0800670 nameComponents = TypeName() ifNotExists = IfNotExists()
Till Westmannf6028272016-09-30 14:34:42 -0700671 <AS> typeExpr = RecordTypeDef()
Dmitry Lychagin314e2792019-11-26 14:35:42 -0800672 {
673 boolean dgen = false;
674 long numValues = -1;
675 String filename = null;
676 Token hintToken = fetchHint(startStmtToken, SqlppHint.DGEN_HINT);
677 if (hintToken != null) {
678 String hintParams = hintToken.hintParams;
679 String[] splits = hintParams != null ? hintParams.split("\\s+") : null;
680 if (splits == null || splits.length != 2) {
681 throw new SqlppParseException(getSourceLocation(hintToken),
682 "Expecting /*+ dgen <filename> <numberOfItems> */");
683 }
684 dgen = true;
685 filename = splits[0];
686 numValues = Long.parseLong(splits[1]);
Yingyi Bu391f09e2015-10-29 13:49:39 -0700687 }
Dmitry Lychagin314e2792019-11-26 14:35:42 -0800688 TypeDataGen tddg = new TypeDataGen(dgen, filename, numValues);
689 TypeDecl stmt = new TypeDecl(nameComponents.first, nameComponents.second, typeExpr, tddg, ifNotExists);
690 return addSourceLocation(stmt, startStmtToken);
691 }
692}
693
694NodegroupDecl CreateNodegroupStatement(Token startStmtToken) throws ParseException:
695{
696 NodegroupDecl stmt = null;
697}
698{
699 <NODEGROUP> stmt = NodegroupSpecification(startStmtToken)
700 {
701 return stmt;
702 }
Yingyi Bu391f09e2015-10-29 13:49:39 -0700703}
704
Dmitry Lychaginee54cc02018-05-25 19:26:18 -0700705NodegroupDecl NodegroupSpecification(Token startStmtToken) throws ParseException:
Yingyi Bu391f09e2015-10-29 13:49:39 -0700706{
707 String name = null;
708 String tmp = null;
709 boolean ifNotExists = false;
Dmitry Lychagin314e2792019-11-26 14:35:42 -0800710 List<Identifier> ncNames = new ArrayList<Identifier>();
Yingyi Bu391f09e2015-10-29 13:49:39 -0700711}
712{
Dmitry Lychagin314e2792019-11-26 14:35:42 -0800713 name = Identifier() ifNotExists = IfNotExists()
714 <ON> tmp = Identifier()
715 {
716 ncNames.add(new Identifier(tmp));
717 }
Yingyi Bu391f09e2015-10-29 13:49:39 -0700718 ( <COMMA> tmp = Identifier()
719 {
720 ncNames.add(new Identifier(tmp));
721 }
722 )*
Dmitry Lychagin314e2792019-11-26 14:35:42 -0800723 {
724 NodegroupDecl stmt = new NodegroupDecl(new Identifier(name), ncNames, ifNotExists);
725 return addSourceLocation(stmt, startStmtToken);
726 }
727}
728
729void Dataset() throws ParseException:
730{
731}
732{
733 (<DATASET>|<COLLECTION>)
734}
735
736DatasetDecl CreateDatasetStatement(Token startStmtToken) throws ParseException:
737{
738 DatasetDecl stmt = null;
739}
740{
741 (
742 (<INTERNAL>)? Dataset() stmt = DatasetSpecification(startStmtToken)
743 | <EXTERNAL> Dataset() stmt = ExternalDatasetSpecification(startStmtToken)
744 )
745 {
746 return stmt;
747 }
Yingyi Bu391f09e2015-10-29 13:49:39 -0700748}
749
Dmitry Lychaginee54cc02018-05-25 19:26:18 -0700750DatasetDecl DatasetSpecification(Token startStmtToken) throws ParseException:
Yingyi Bu391f09e2015-10-29 13:49:39 -0700751{
Dmitry Lychagin54c06012019-11-13 15:54:20 -0800752 Pair<DataverseName,Identifier> nameComponents = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -0700753 boolean ifNotExists = false;
Dmitry Lychagin54c06012019-11-13 15:54:20 -0800754 Pair<DataverseName,Identifier> typeComponents = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -0700755 String adapterName = null;
756 Map<String,String> properties = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -0700757 FunctionSignature appliedFunction = null;
Yingyi Buc9bfe252016-03-01 00:02:40 -0800758 Pair<List<Integer>, List<List<String>>> primaryKeyFields = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -0700759 String nodeGroupName = null;
760 Map<String,String> hints = new HashMap<String,String>();
Dmitry Lychaginee54cc02018-05-25 19:26:18 -0700761 DatasetDecl stmt = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -0700762 boolean autogenerated = false;
Yingyi Buc9bfe252016-03-01 00:02:40 -0800763 Pair<Integer, List<String>> filterField = null;
Dmitry Lychagin54c06012019-11-13 15:54:20 -0800764 Pair<DataverseName,Identifier> metaTypeComponents = new Pair<DataverseName, Identifier>(null, null);
Till Westmannf3aa19f2017-12-01 17:42:35 -0800765 RecordConstructor withRecord = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -0700766}
767{
Dmitry Lychagin314e2792019-11-26 14:35:42 -0800768 nameComponents = QualifiedName()
769 <LEFTPAREN> typeComponents = TypeName() <RIGHTPAREN>
Yingyi Bu391f09e2015-10-29 13:49:39 -0700770 (
Dmitry Lychagin314e2792019-11-26 14:35:42 -0800771 { String name; }
772 <WITH>
773 name = Identifier()
Yingyi Bu391f09e2015-10-29 13:49:39 -0700774 {
Dmitry Lychagin314e2792019-11-26 14:35:42 -0800775 if (!name.equalsIgnoreCase("meta")){
776 throw new SqlppParseException(getSourceLocation(startStmtToken),
777 "We can only support one additional associated field called \"meta\".");
778 }
Yingyi Bu391f09e2015-10-29 13:49:39 -0700779 }
Dmitry Lychagin314e2792019-11-26 14:35:42 -0800780 <LEFTPAREN> metaTypeComponents = TypeName() <RIGHTPAREN>
781 )?
782 ifNotExists = IfNotExists()
783 primaryKeyFields = PrimaryKey()
784 (<AUTOGENERATED> { autogenerated = true; } )?
785 (<ON> nodeGroupName = Identifier() )?
786 ( <HINTS> hints = Properties() )?
787 ( LOOKAHEAD(2) <WITH> <FILTER> <ON> filterField = NestedField() )?
788 ( <WITH> withRecord = RecordConstructor() )?
789 {
790 if(filterField!=null && filterField.first!=0){
791 throw new SqlppParseException(getSourceLocation(startStmtToken),
792 "A filter field can only be a field in the main record of the dataset.");
793 }
794 InternalDetailsDecl idd = new InternalDetailsDecl(primaryKeyFields.second, primaryKeyFields.first, autogenerated,
795 filterField == null? null : filterField.second);
796 try {
797 stmt = new DatasetDecl(nameComponents.first, nameComponents.second, typeComponents.first, typeComponents.second,
798 metaTypeComponents.first, metaTypeComponents.second,
799 nodeGroupName != null ? new Identifier(nodeGroupName) : null, hints, DatasetType.INTERNAL, idd, withRecord,
800 ifNotExists);
801 return addSourceLocation(stmt, startStmtToken);
802 } catch (CompilationException e) {
803 throw new SqlppParseException(getSourceLocation(startStmtToken), e.getMessage());
804 }
805 }
806}
807
808DatasetDecl ExternalDatasetSpecification(Token startStmtToken) throws ParseException:
809{
810 Pair<DataverseName,Identifier> nameComponents = null;
811 boolean ifNotExists = false;
812 Pair<DataverseName,Identifier> typeComponents = null;
813 String adapterName = null;
814 Map<String,String> properties = null;
815 String nodeGroupName = null;
816 Map<String,String> hints = new HashMap<String,String>();
817 DatasetDecl stmt = null;
818 Pair<DataverseName,Identifier> metaTypeComponents = new Pair<DataverseName, Identifier>(null, null);
819 RecordConstructor withRecord = null;
820}
821{
822 nameComponents = QualifiedName()
823 <LEFTPAREN> typeComponents = TypeName() <RIGHTPAREN>
824 ifNotExists = IfNotExists()
825 <USING> adapterName = AdapterName() properties = Configuration()
826 ( <ON> nodeGroupName = Identifier() )?
827 ( <HINTS> hints = Properties() )?
828 ( <WITH> withRecord = RecordConstructor() )?
829 {
830 ExternalDetailsDecl edd = new ExternalDetailsDecl();
831 edd.setAdapter(adapterName);
832 edd.setProperties(properties);
833 try {
834 stmt = new DatasetDecl(nameComponents.first, nameComponents.second, typeComponents.first, typeComponents.second,
835 metaTypeComponents.first, metaTypeComponents.second,
836 nodeGroupName != null? new Identifier(nodeGroupName): null, hints, DatasetType.EXTERNAL, edd, withRecord,
837 ifNotExists);
838 return addSourceLocation(stmt, startStmtToken);
839 } catch (CompilationException e) {
840 throw new SqlppParseException(getSourceLocation(startStmtToken), e.getMessage());
841 }
842 }
Yingyi Bu391f09e2015-10-29 13:49:39 -0700843}
844
845RefreshExternalDatasetStatement RefreshExternalDatasetStatement() throws ParseException:
846{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -0700847 Token startToken = null;
Dmitry Lychagin54c06012019-11-13 15:54:20 -0800848 Pair<DataverseName,Identifier> nameComponents = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -0700849 String datasetName = null;
850}
851{
Dmitry Lychagin314e2792019-11-26 14:35:42 -0800852 <REFRESH> { startToken = token; } <EXTERNAL> Dataset() nameComponents = QualifiedName()
853 {
854 RefreshExternalDatasetStatement stmt = new RefreshExternalDatasetStatement();
855 stmt.setDataverseName(nameComponents.first);
856 stmt.setDatasetName(nameComponents.second);
857 return addSourceLocation(stmt, startToken);
858 }
859}
860
861CreateIndexStatement CreateIndexStatement(Token startStmtToken) throws ParseException:
862{
863 CreateIndexStatement stmt = null;
864}
865{
866 (
867 <INDEX> stmt = IndexSpecification(startStmtToken)
868 | <PRIMARY> <INDEX> stmt = PrimaryIndexSpecification(startStmtToken)
869 )
870 {
871 return stmt;
872 }
Yingyi Bu391f09e2015-10-29 13:49:39 -0700873}
874
Dmitry Lychaginee54cc02018-05-25 19:26:18 -0700875CreateIndexStatement IndexSpecification(Token startStmtToken) throws ParseException:
Yingyi Bu391f09e2015-10-29 13:49:39 -0700876{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -0700877 CreateIndexStatement stmt = new CreateIndexStatement();
Yingyi Bu391f09e2015-10-29 13:49:39 -0700878 String indexName = null;
879 boolean ifNotExists = false;
Dmitry Lychagin54c06012019-11-13 15:54:20 -0800880 Pair<DataverseName,Identifier> nameComponents = null;
Dmitry Lychagin8ba59442017-06-16 14:19:45 -0700881 Pair<Integer, Pair<List<String>, IndexedTypeExpression>> fieldPair = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -0700882 IndexParams indexType = null;
883 boolean enforced = false;
884}
885{
Ali Alsuliman8351d252017-09-24 00:43:15 -0700886 (
Dmitry Lychagin314e2792019-11-26 14:35:42 -0800887 indexName = Identifier() ifNotExists = IfNotExists()
Ali Alsuliman8351d252017-09-24 00:43:15 -0700888 <ON> nameComponents = QualifiedName()
889 <LEFTPAREN> ( fieldPair = OpenField()
890 {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -0700891 stmt.addFieldExprPair(fieldPair.second);
892 stmt.addFieldIndexIndicator(fieldPair.first);
Yingyi Bu391f09e2015-10-29 13:49:39 -0700893 }
Ali Alsuliman8351d252017-09-24 00:43:15 -0700894 ) (<COMMA> fieldPair = OpenField()
895 {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -0700896 stmt.addFieldExprPair(fieldPair.second);
897 stmt.addFieldIndexIndicator(fieldPair.first);
Ali Alsuliman8351d252017-09-24 00:43:15 -0700898 }
Dmitry Lychagin314e2792019-11-26 14:35:42 -0800899 )* <RIGHTPAREN> ( <TYPE> indexType = IndexType() )? ( <ENFORCED> { enforced = true; } )?
Ali Alsuliman8351d252017-09-24 00:43:15 -0700900 )
901 {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -0700902 stmt.setIndexName(new Identifier(indexName));
903 stmt.setIfNotExists(ifNotExists);
904 stmt.setDataverseName(nameComponents.first);
905 stmt.setDatasetName(nameComponents.second);
Ali Alsuliman8351d252017-09-24 00:43:15 -0700906 if (indexType != null) {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -0700907 stmt.setIndexType(indexType.type);
908 stmt.setGramLength(indexType.gramLength);
Ali Alsuliman8351d252017-09-24 00:43:15 -0700909 }
Dmitry Lychaginee54cc02018-05-25 19:26:18 -0700910 stmt.setEnforced(enforced);
Dmitry Lychagin5c26b422018-06-01 10:22:16 -0700911 return addSourceLocation(stmt, startStmtToken);
Ali Alsuliman8351d252017-09-24 00:43:15 -0700912 }
Yingyi Bu391f09e2015-10-29 13:49:39 -0700913}
914
Dmitry Lychagin314e2792019-11-26 14:35:42 -0800915CreateIndexStatement PrimaryIndexSpecification(Token startStmtToken) throws ParseException:
916{
917 CreateIndexStatement stmt = new CreateIndexStatement();
918 String indexName = null;
919 boolean ifNotExists = false;
920 Pair<DataverseName,Identifier> nameComponents = null;
921}
922{
923 (indexName = Identifier())? ifNotExists = IfNotExists()
924 <ON> nameComponents = QualifiedName() (<TYPE> <BTREE>)?
925 {
926 if (indexName == null) {
927 indexName = "primary_idx_" + nameComponents.second;
928 }
929 stmt.setIndexName(new Identifier(indexName));
930 stmt.setIfNotExists(ifNotExists);
931 stmt.setDataverseName(nameComponents.first);
932 stmt.setDatasetName(nameComponents.second);
933 return addSourceLocation(stmt, startStmtToken);
934 }
935}
936
Yingyi Bu391f09e2015-10-29 13:49:39 -0700937String CompactionPolicy() throws ParseException :
938{
939 String compactionPolicy = null;
940}
941{
942 compactionPolicy = Identifier()
943 {
944 return compactionPolicy;
945 }
946}
947
948String FilterField() throws ParseException :
949{
950 String filterField = null;
951}
952{
953 filterField = Identifier()
954 {
955 return filterField;
956 }
957}
958
959IndexParams IndexType() throws ParseException:
960{
961 IndexType type = null;
962 int gramLength = 0;
963}
964{
965 (<BTREE>
966 {
967 type = IndexType.BTREE;
968 }
969 | <RTREE>
970 {
971 type = IndexType.RTREE;
972 }
973 | <KEYWORD>
974 {
975 type = IndexType.LENGTH_PARTITIONED_WORD_INVIX;
976 }
Taewoo Kimc49405a2017-01-04 00:30:43 -0800977 |<FULLTEXT>
978 {
979 type = IndexType.SINGLE_PARTITION_WORD_INVIX;
980 }
Yingyi Bu391f09e2015-10-29 13:49:39 -0700981 | <NGRAM> <LEFTPAREN> <INTEGER_LITERAL>
982 {
983 type = IndexType.LENGTH_PARTITIONED_NGRAM_INVIX;
984 gramLength = Integer.valueOf(token.image);
985 }
986 <RIGHTPAREN>)
987 {
988 return new IndexParams(type, gramLength);
989 }
990}
991
Dmitry Lychagin314e2792019-11-26 14:35:42 -0800992CreateDataverseStatement CreateDataverseStatement(Token startStmtToken) throws ParseException :
993{
994 CreateDataverseStatement stmt = null;
995}
996{
997 <DATAVERSE> stmt = DataverseSpecification(startStmtToken)
998 {
999 return stmt;
1000 }
1001}
1002
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07001003CreateDataverseStatement DataverseSpecification(Token startStmtToken) throws ParseException :
Yingyi Bu391f09e2015-10-29 13:49:39 -07001004{
Dmitry Lychagin54c06012019-11-13 15:54:20 -08001005 List<String> dvName = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07001006 boolean ifNotExists = false;
Yingyi Bu391f09e2015-10-29 13:49:39 -07001007}
1008{
Dmitry Lychagin314e2792019-11-26 14:35:42 -08001009 dvName = MultipartIdentifier() ifNotExists = IfNotExists()
1010 {
1011 CreateDataverseStatement stmt = new CreateDataverseStatement(DataverseName.create(dvName), null, ifNotExists);
1012 return addSourceLocation(stmt, startStmtToken);
1013 }
1014}
1015
1016CreateFunctionStatement CreateFunctionStatement(Token startStmtToken) throws ParseException:
1017{
1018 CreateFunctionStatement stmt = null;
1019}
1020{
1021 <FUNCTION> stmt = FunctionSpecification(startStmtToken)
1022 {
1023 return stmt;
1024 }
Yingyi Bu391f09e2015-10-29 13:49:39 -07001025}
1026
Ian Maxon38fe9402020-01-29 19:27:40 -08001027
1028CreateAdapterStatement CreateAdapterStatement(Token startStmtToken) throws ParseException:
1029{
1030 CreateAdapterStatement stmt = null;
1031}
1032{
1033 <ADAPTER> stmt = AdapterSpecification(startStmtToken)
1034 {
1035 return stmt;
1036 }
1037}
1038
1039CreateAdapterStatement AdapterSpecification(Token startStmtToken) throws ParseException:
1040{
1041 AdapterIdentifier signature = null;
1042 Token beginPos;
1043 Token endPos;
1044 Pair<DataverseName,Identifier> adaptName = null;
1045 DataverseName currentDataverse = defaultDataverse;
1046 String lang = null;
1047 String libName ="";
1048 String externalIdent = "";
1049 ListConstructor resources = null;
1050 boolean ifNotExists = false;
1051}
1052{
1053 adaptName = QualifiedName()
1054 <IDENTIFIER> {expectToken(LANGUAGE);} lang = Identifier() <AS> libName = ConstantString() <COMMA> externalIdent = ConstantString() ifNotExists = IfNotExists()
1055 {
1056 signature = new AdapterIdentifier(adaptName.getFirst(),adaptName.getSecond().getValue());
1057 CreateAdapterStatement stmt =
1058 new CreateAdapterStatement(signature, lang, libName, externalIdent, ifNotExists);
1059 return addSourceLocation(stmt, startStmtToken);
1060 }
1061
1062}
1063
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07001064CreateFunctionStatement FunctionSpecification(Token startStmtToken) throws ParseException:
Yingyi Bu391f09e2015-10-29 13:49:39 -07001065{
Ian Maxon38fe9402020-01-29 19:27:40 -08001066 FunctionSignature signature = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07001067 boolean ifNotExists = false;
Ian Maxon38fe9402020-01-29 19:27:40 -08001068 String functionBody = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07001069 VarIdentifier var = null;
Ian Maxon38fe9402020-01-29 19:27:40 -08001070 Expression functionBodyExpr = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07001071 Token beginPos;
1072 Token endPos;
1073 FunctionName fctName = null;
Dmitry Lychagin54c06012019-11-13 15:54:20 -08001074 DataverseName currentDataverse = defaultDataverse;
Ian Maxon38fe9402020-01-29 19:27:40 -08001075 IndexedTypeExpression returnType = null;
1076 boolean deterministic = false;
1077 boolean nullCall = false;
1078 String lang = null;
1079 String libName ="";
1080 String externalIdent = "";
Dmitry Lychagin74fac082020-03-05 11:28:18 -08001081 List<String> externalIdentList = null;
Dmitry Lychagin0d4c1b62020-02-07 17:10:16 -08001082 List<Pair<VarIdentifier,IndexedTypeExpression>> args = null;
Ian Maxon38fe9402020-01-29 19:27:40 -08001083 RecordConstructor resources = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07001084}
1085{
Dmitry Lychagin314e2792019-11-26 14:35:42 -08001086 fctName = FunctionName()
Steven Glenn Jacobs665e9fe2017-12-27 10:30:39 -08001087 {
1088 defaultDataverse = fctName.dataverse;
1089 }
Yingyi Bu391f09e2015-10-29 13:49:39 -07001090 ifNotExists = IfNotExists()
Ian Maxon38fe9402020-01-29 19:27:40 -08001091 args = FunctionParameters()
Dmitry Lychagin0d4c1b62020-02-07 17:10:16 -08001092 returnType = FunctionReturnType()
Ian Maxon38fe9402020-01-29 19:27:40 -08001093 (
1094 (
1095 <LEFTBRACE>
1096 {
1097 createNewScope();
1098 beginPos = token;
1099 }
Dmitry Lychagin45de2342020-02-03 12:01:28 -08001100 functionBodyExpr = FunctionBody()
Ian Maxon38fe9402020-01-29 19:27:40 -08001101 <RIGHTBRACE>{
1102 endPos = token;
1103 functionBody = extractFragment(beginPos.beginLine, beginPos.beginColumn, endPos.beginLine, endPos.beginColumn);
1104 signature = new FunctionSignature(fctName.dataverse, fctName.function, args.size());
1105 getCurrentScope().addFunctionDescriptor(signature, false);
1106 removeCurrentScope();
1107 defaultDataverse = currentDataverse;
1108 CreateFunctionStatement stmt = new CreateFunctionStatement(signature, args, returnType, functionBody, functionBodyExpr, ifNotExists);
1109 return addSourceLocation(stmt, startStmtToken);
1110 }
1111 )
1112 |
1113 <IDENTIFIER> {expectToken(LANGUAGE);}
1114 (
1115 LOOKAHEAD({laIdentifier(INLINE)})
1116 (
Dmitry Lychagin45de2342020-02-03 12:01:28 -08001117 <IDENTIFIER> <AS>
1118 {
Ian Maxon38fe9402020-01-29 19:27:40 -08001119 createNewScope();
1120 beginPos = token;
1121 }
Dmitry Lychagin45de2342020-02-03 12:01:28 -08001122 functionBodyExpr = FunctionBody()
Ian Maxon38fe9402020-01-29 19:27:40 -08001123 {
1124 endPos = token;
1125 functionBody = extractFragment(beginPos.endLine, beginPos.beginColumn+1, endPos.endLine, endPos.endColumn+1);
1126 signature = new FunctionSignature(fctName.dataverse, fctName.function, args.size());
1127 getCurrentScope().addFunctionDescriptor(signature, false);
1128 removeCurrentScope();
1129 defaultDataverse = currentDataverse;
1130 CreateFunctionStatement stmt = new CreateFunctionStatement(signature, args, returnType, functionBody, functionBodyExpr, ifNotExists);
1131 return addSourceLocation(stmt, startStmtToken);
1132 }
1133 )
1134 |
1135 (
1136 lang = Identifier()
1137 ( (<NOT> <IDENTIFIER> {expectToken(DETERMINISTIC); deterministic = false;}) | (<IDENTIFIER> {expectToken(DETERMINISTIC); deterministic = true;}) )?
1138 (<NULL> <IDENTIFIER> { expectToken(CALL); nullCall = true;})?
Dmitry Lychagin74fac082020-03-05 11:28:18 -08001139 <AS> libName = ConstantString()
1140 { externalIdentList = new ArrayList<String>(2); }
1141 ( <COMMA> externalIdent = ConstantString() { externalIdentList.add(externalIdent); } )+
Ian Maxon38fe9402020-01-29 19:27:40 -08001142 (<WITH> resources = RecordConstructor())?
1143 {
1144 signature = new FunctionSignature(fctName.dataverse, fctName.function, args.size());
1145 defaultDataverse = currentDataverse;
1146 CreateFunctionStatement stmt = null;
1147 try{
1148 stmt =
1149 new CreateFunctionStatement(signature, args, returnType, deterministic, nullCall,
Dmitry Lychagin74fac082020-03-05 11:28:18 -08001150 lang, libName, externalIdentList, resources, ifNotExists);
Ian Maxon38fe9402020-01-29 19:27:40 -08001151 } catch (AlgebricksException e) {
1152 throw new SqlppParseException(getSourceLocation(startStmtToken), e.getMessage());
1153 }
1154 return addSourceLocation(stmt, startStmtToken);
1155 }
1156 )
1157 )
1158 )
Dmitry Lychagin314e2792019-11-26 14:35:42 -08001159}
1160
Dmitry Lychagin0d4c1b62020-02-07 17:10:16 -08001161List<Pair<VarIdentifier,IndexedTypeExpression>> FunctionParameters() :
1162{
1163 List<Pair<VarIdentifier,IndexedTypeExpression>> paramList = Collections.<Pair<VarIdentifier,IndexedTypeExpression>>emptyList();
1164}
1165{
1166 <LEFTPAREN> (paramList = FunctionParameterList())? <RIGHTPAREN>
1167 {
1168 return paramList;
1169 }
1170}
1171
1172List<Pair<VarIdentifier,IndexedTypeExpression>> FunctionParameterList() :
1173{
1174 List<Pair<VarIdentifier,IndexedTypeExpression>> paramList = new ArrayList<Pair<VarIdentifier,IndexedTypeExpression>>();
1175 Pair<VarIdentifier,IndexedTypeExpression> varPair = new Pair<VarIdentifier,IndexedTypeExpression>(null,null);
1176 String var = null;
1177 IndexedTypeExpression type = null;
1178}
1179{
1180 var = VariableIdentifier() {
1181 varPair.setFirst(new VarIdentifier(var));
1182 paramList.add(varPair);
1183 } (LOOKAHEAD(3)(<COLON>)? type = IndexedTypeExpr() {varPair.setSecond(type);} )? (<COMMA> var = VariableIdentifier() {
1184 varPair = new Pair<VarIdentifier,IndexedTypeExpression>(null,null);
1185 varPair.setFirst(new VarIdentifier(var));
1186 paramList.add(varPair);
1187 } (LOOKAHEAD(3)(<COLON>)? type = IndexedTypeExpr() {varPair.setSecond(type);})?)*
1188 {
1189 return paramList;
1190 }
1191}
1192
1193IndexedTypeExpression FunctionReturnType() throws ParseException:
1194{
1195 IndexedTypeExpression returnType = null;
1196}
1197{
1198 ( LOOKAHEAD({laIdentifier(RETURNS)}) <IDENTIFIER> returnType = IndexedTypeExpr() )?
1199 {
1200 return returnType;
1201 }
1202}
1203
Dmitry Lychagin45de2342020-02-03 12:01:28 -08001204Expression FunctionBody() throws ParseException:
1205{
1206 Expression functionBodyExpr = null;
1207}
1208{
1209 ( functionBodyExpr = SelectExpression(true) | functionBodyExpr = Expression() )
1210 {
1211 return functionBodyExpr;
1212 }
1213}
1214
Dmitry Lychagin314e2792019-11-26 14:35:42 -08001215CreateFeedStatement CreateFeedStatement(Token startStmtToken) throws ParseException:
1216{
1217 CreateFeedStatement stmt = null;
1218}
1219{
1220 <FEED> stmt = FeedSpecification(startStmtToken)
1221 {
1222 return stmt;
1223 }
Yingyi Bu391f09e2015-10-29 13:49:39 -07001224}
1225
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07001226CreateFeedStatement FeedSpecification(Token startStmtToken) throws ParseException:
Yingyi Bu391f09e2015-10-29 13:49:39 -07001227{
Dmitry Lychagin54c06012019-11-13 15:54:20 -08001228 Pair<DataverseName,Identifier> nameComponents = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07001229 boolean ifNotExists = false;
1230 String adapterName = null;
1231 Map<String,String> properties = null;
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07001232 CreateFeedStatement stmt = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07001233 Pair<Identifier,Identifier> sourceNameComponents = null;
Xikui Wang5a61b2a2018-01-02 14:14:03 -08001234 RecordConstructor withRecord = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07001235}
1236{
Dmitry Lychagin314e2792019-11-26 14:35:42 -08001237 nameComponents = QualifiedName() ifNotExists = IfNotExists()
Xikui Wang5a61b2a2018-01-02 14:14:03 -08001238 <WITH> withRecord = RecordConstructor()
Abdullah Alamoudifff200c2017-02-18 20:32:14 -08001239 {
Xikui Wang5a61b2a2018-01-02 14:14:03 -08001240 try {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07001241 stmt = new CreateFeedStatement(nameComponents, withRecord, ifNotExists);
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07001242 return addSourceLocation(stmt, startStmtToken);
Xikui Wang5a61b2a2018-01-02 14:14:03 -08001243 } catch (AlgebricksException e) {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07001244 throw new SqlppParseException(getSourceLocation(startStmtToken), e.getMessage());
Xikui Wang5a61b2a2018-01-02 14:14:03 -08001245 }
Abdullah Alamoudifff200c2017-02-18 20:32:14 -08001246 }
Yingyi Bu391f09e2015-10-29 13:49:39 -07001247}
1248
Dmitry Lychagin314e2792019-11-26 14:35:42 -08001249CreateFeedPolicyStatement CreateFeedPolicyStatement(Token startStmtToken) throws ParseException:
1250{
1251 CreateFeedPolicyStatement stmt = null;
1252}
1253{
1254 <INGESTION> <POLICY> stmt = FeedPolicySpecification(startStmtToken)
1255 {
1256 return stmt;
1257 }
1258}
1259
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07001260CreateFeedPolicyStatement FeedPolicySpecification(Token startStmtToken) throws ParseException:
Yingyi Bu391f09e2015-10-29 13:49:39 -07001261{
Michael Blowd6cf6412016-06-30 02:44:35 -04001262 String policyName = null;
1263 String basePolicyName = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07001264 String sourcePolicyFile = null;
1265 String definition = null;
1266 boolean ifNotExists = false;
1267 Map<String,String> properties = null;
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07001268 CreateFeedPolicyStatement stmt = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07001269}
1270{
Dmitry Lychagin314e2792019-11-26 14:35:42 -08001271 policyName = Identifier() ifNotExists = IfNotExists()
1272 <FROM>
1273 (<POLICY> basePolicyName = Identifier() properties = Configuration() (<DEFINITION> definition = ConstantString())?
Yingyi Bu391f09e2015-10-29 13:49:39 -07001274 {
Dmitry Lychagin314e2792019-11-26 14:35:42 -08001275 stmt = new CreateFeedPolicyStatement(policyName, basePolicyName, properties, definition, ifNotExists);
Yingyi Bu391f09e2015-10-29 13:49:39 -07001276 }
Dmitry Lychagin314e2792019-11-26 14:35:42 -08001277 | <PATH> sourcePolicyFile = ConstantString() (<DEFINITION> definition = ConstantString())?
1278 {
1279 stmt = new CreateFeedPolicyStatement(policyName, sourcePolicyFile, definition, ifNotExists);
1280 }
1281 )
1282 {
1283 return addSourceLocation(stmt, startStmtToken);
1284 }
Yingyi Bu391f09e2015-10-29 13:49:39 -07001285}
1286
Yingyi Bu391f09e2015-10-29 13:49:39 -07001287
Dmitry Lychagin2a0848e2020-01-08 13:57:22 -08001288CreateSynonymStatement CreateSynonymStatement(Token startStmtToken) throws ParseException:
1289{
1290 CreateSynonymStatement stmt = null;
1291}
1292{
1293 <SYNONYM> stmt = SynonymSpecification(startStmtToken)
1294 {
1295 return stmt;
1296 }
1297}
1298
1299CreateSynonymStatement SynonymSpecification(Token startStmtToken) throws ParseException:
1300{
1301 Pair<DataverseName,Identifier> nameComponents = null;
1302 Pair<DataverseName,Identifier> objectNameComponents = null;
1303 boolean ifNotExists = false;
1304}
1305{
1306 nameComponents = QualifiedName() ifNotExists = IfNotExists()
1307 <FOR> objectNameComponents = QualifiedName()
1308 {
1309 CreateSynonymStatement stmt = new CreateSynonymStatement(nameComponents.first, nameComponents.second.getValue(),
1310 objectNameComponents.first, objectNameComponents.second.getValue(), ifNotExists);
1311 return addSourceLocation(stmt, startStmtToken);
1312 }
1313}
1314
Yingyi Bu391f09e2015-10-29 13:49:39 -07001315boolean IfNotExists() throws ParseException:
1316{
1317}
1318{
Yingyi Budaa549c2016-06-28 22:30:52 -07001319 ( LOOKAHEAD(1) <IF> <NOT> <EXISTS>
Yingyi Bu391f09e2015-10-29 13:49:39 -07001320 {
1321 return true;
1322 }
1323 )?
1324 {
1325 return false;
1326 }
1327}
1328
Xikui Wang9d63f622017-05-18 17:50:44 -07001329void ApplyFunction(List<FunctionSignature> funcSigs) throws ParseException:
Yingyi Bu391f09e2015-10-29 13:49:39 -07001330{
Dmitry Lychagin54c06012019-11-13 15:54:20 -08001331 FunctionName functionName = null;
Xikui Wang261dc6d2017-03-29 21:23:15 -07001332 String fqFunctionName = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07001333}
1334{
Dmitry Lychagin54c06012019-11-13 15:54:20 -08001335 <APPLY> <FUNCTION> functionName = FunctionName()
Dmitry Lychagin314e2792019-11-26 14:35:42 -08001336 {
1337 fqFunctionName = functionName.library == null ? functionName.function : functionName.library + "#" + functionName.function;
1338 funcSigs.add(new FunctionSignature(functionName.dataverse, fqFunctionName, 1));
1339 }
Xikui Wang261dc6d2017-03-29 21:23:15 -07001340 (
Dmitry Lychagin54c06012019-11-13 15:54:20 -08001341 <COMMA> functionName = FunctionName()
Xikui Wang261dc6d2017-03-29 21:23:15 -07001342 {
Dmitry Lychagin54c06012019-11-13 15:54:20 -08001343 fqFunctionName = functionName.library == null ? functionName.function : functionName.library + "#" + functionName.function;
1344 funcSigs.add(new FunctionSignature(functionName.dataverse, fqFunctionName, 1));
Xikui Wang261dc6d2017-03-29 21:23:15 -07001345 }
1346 )*
Yingyi Bu391f09e2015-10-29 13:49:39 -07001347}
1348
1349String GetPolicy() throws ParseException:
1350{
1351 String policy = null;
1352}
1353{
1354 <USING> <POLICY> policy = Identifier()
1355 {
1356 return policy;
1357 }
1358
1359}
1360
1361FunctionSignature FunctionSignature() throws ParseException:
1362{
1363 FunctionName fctName = null;
1364 int arity = 0;
1365}
1366{
1367 fctName = FunctionName() <ATT> <INTEGER_LITERAL>
1368 {
1369 arity = new Integer(token.image);
1370 if (arity < 0 && arity != FunctionIdentifier.VARARGS) {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07001371 throw new SqlppParseException(getSourceLocation(token), "Invalid arity:" + arity);
Yingyi Bu391f09e2015-10-29 13:49:39 -07001372 }
1373
1374 // TODO use fctName.library
1375 String fqFunctionName = fctName.library == null ? fctName.function : fctName.library + "#" + fctName.function;
1376 return new FunctionSignature(fctName.dataverse, fqFunctionName, arity);
1377 }
1378}
1379
Yingyi Buc9bfe252016-03-01 00:02:40 -08001380Pair<List<Integer>, List<List<String>>> PrimaryKey() throws ParseException:
Yingyi Bu391f09e2015-10-29 13:49:39 -07001381{
Yingyi Buc9bfe252016-03-01 00:02:40 -08001382 Pair<Integer, List<String>> tmp = null;
1383 List<Integer> keyFieldSourceIndicators = new ArrayList<Integer>();
Yingyi Bu391f09e2015-10-29 13:49:39 -07001384 List<List<String>> primaryKeyFields = new ArrayList<List<String>>();
1385}
1386{
1387 <PRIMARY> <KEY> tmp = NestedField()
1388 {
Yingyi Buc9bfe252016-03-01 00:02:40 -08001389 keyFieldSourceIndicators.add(tmp.first);
1390 primaryKeyFields.add(tmp.second);
Yingyi Bu391f09e2015-10-29 13:49:39 -07001391 }
1392 ( <COMMA> tmp = NestedField()
1393 {
Yingyi Buc9bfe252016-03-01 00:02:40 -08001394 keyFieldSourceIndicators.add(tmp.first);
1395 primaryKeyFields.add(tmp.second);
Yingyi Bu391f09e2015-10-29 13:49:39 -07001396 }
1397 )*
1398 {
Yingyi Buc9bfe252016-03-01 00:02:40 -08001399 return new Pair<List<Integer>, List<List<String>>> (keyFieldSourceIndicators, primaryKeyFields);
Yingyi Bu391f09e2015-10-29 13:49:39 -07001400 }
1401}
1402
1403Statement DropStatement() throws ParseException:
1404{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07001405 Token startToken = null;
Dmitry Lychagin314e2792019-11-26 14:35:42 -08001406 Statement stmt = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07001407}
1408{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07001409 <DROP> { startToken = token; }
Yingyi Bu391f09e2015-10-29 13:49:39 -07001410 (
Dmitry Lychagin314e2792019-11-26 14:35:42 -08001411 stmt = DropDatasetStatement(startToken)
1412 | stmt = DropIndexStatement(startToken)
1413 | stmt = DropNodeGroupStatement(startToken)
1414 | stmt = DropTypeStatement(startToken)
1415 | stmt = DropDataverseStatement(startToken)
1416 | stmt = DropFunctionStatement(startToken)
1417 | stmt = DropFeedStatement(startToken)
1418 | stmt = DropFeedPolicyStatement(startToken)
Dmitry Lychagin2a0848e2020-01-08 13:57:22 -08001419 | stmt = DropSynonymStatement(startToken)
Yingyi Bu391f09e2015-10-29 13:49:39 -07001420 )
1421 {
Dmitry Lychagin314e2792019-11-26 14:35:42 -08001422 return stmt;
1423 }
1424}
1425
1426DropDatasetStatement DropDatasetStatement(Token startStmtToken) throws ParseException:
1427{
1428 DropDatasetStatement stmt = null;
1429}
1430{
1431 Dataset() stmt = DropDatasetSpecification(startStmtToken)
1432 {
1433 return stmt;
1434 }
1435}
1436
1437DropDatasetStatement DropDatasetSpecification(Token startStmtToken) throws ParseException:
1438{
1439 Pair<DataverseName,Identifier> pairId = null;
1440 boolean ifExists = false;
1441}
1442{
1443 pairId = QualifiedName() ifExists = IfExists()
1444 {
1445 DropDatasetStatement stmt = new DropDatasetStatement(pairId.first, pairId.second, ifExists);
1446 return addSourceLocation(stmt, startStmtToken);
1447 }
1448}
1449
1450IndexDropStatement DropIndexStatement(Token startStmtToken) throws ParseException:
1451{
1452 IndexDropStatement stmt = null;
1453}
1454{
1455 <INDEX> stmt = DropIndexSpecification(startStmtToken)
1456 {
1457 return stmt;
1458 }
1459}
1460
1461IndexDropStatement DropIndexSpecification(Token startStmtToken) throws ParseException:
1462{
1463 Triple<DataverseName,Identifier,Identifier> tripleId = null;
1464 boolean ifExists = false;
1465}
1466{
1467 tripleId = DoubleQualifiedName() ifExists = IfExists()
1468 {
1469 IndexDropStatement stmt = new IndexDropStatement(tripleId.first, tripleId.second, tripleId.third, ifExists);
1470 return addSourceLocation(stmt, startStmtToken);
1471 }
1472}
1473
1474NodeGroupDropStatement DropNodeGroupStatement(Token startStmtToken) throws ParseException:
1475{
1476 NodeGroupDropStatement stmt = null;
1477}
1478{
1479 <NODEGROUP> stmt = DropNodeGroupSpecification(startStmtToken)
1480 {
1481 return stmt;
1482 }
1483}
1484
1485NodeGroupDropStatement DropNodeGroupSpecification(Token startStmtToken) throws ParseException:
1486{
1487 String id = null;
1488 boolean ifExists = false;
1489}
1490{
1491 id = Identifier() ifExists = IfExists()
1492 {
1493 NodeGroupDropStatement stmt = new NodeGroupDropStatement(new Identifier(id), ifExists);
1494 return addSourceLocation(stmt, startStmtToken);
1495 }
1496}
1497
1498TypeDropStatement DropTypeStatement(Token startStmtToken) throws ParseException:
1499{
1500 TypeDropStatement stmt = null;
1501}
1502{
1503 <TYPE> stmt = DropTypeSpecification(startStmtToken)
1504 {
1505 return stmt;
1506 }
1507}
1508
1509TypeDropStatement DropTypeSpecification(Token startStmtToken) throws ParseException:
1510{
1511 Pair<DataverseName,Identifier> pairId = null;
1512 boolean ifExists = false;
1513}
1514{
1515 pairId = TypeName() ifExists = IfExists()
1516 {
1517 TypeDropStatement stmt = new TypeDropStatement(pairId.first, pairId.second, ifExists);
1518 return addSourceLocation(stmt, startStmtToken);
1519 }
1520}
1521
1522DataverseDropStatement DropDataverseStatement(Token startStmtToken) throws ParseException:
1523{
1524 DataverseDropStatement stmt = null;
1525}
1526{
1527 <DATAVERSE> stmt = DropDataverseSpecification(startStmtToken)
1528 {
1529 return stmt;
1530 }
1531}
1532
1533DataverseDropStatement DropDataverseSpecification(Token startStmtToken) throws ParseException:
1534{
1535 List<String> multipartId = null;
1536 boolean ifExists = false;
1537}
1538{
1539 multipartId = MultipartIdentifier() ifExists = IfExists()
1540 {
1541 DataverseDropStatement stmt = new DataverseDropStatement(DataverseName.create(multipartId), ifExists);
1542 return addSourceLocation(stmt, startStmtToken);
1543 }
1544}
1545
1546FunctionDropStatement DropFunctionStatement(Token startStmtToken) throws ParseException:
1547{
1548 FunctionDropStatement stmt = null;
1549}
1550{
1551 <FUNCTION> stmt = DropFunctionSpecification(startStmtToken)
1552 {
1553 return stmt;
1554 }
1555}
1556
1557FunctionDropStatement DropFunctionSpecification(Token startStmtToken) throws ParseException:
1558{
1559 FunctionSignature funcSig = null;
1560 boolean ifExists = false;
1561}
1562{
1563 funcSig = FunctionSignature() ifExists = IfExists()
1564 {
1565 FunctionDropStatement stmt = new FunctionDropStatement(funcSig, ifExists);
1566 return addSourceLocation(stmt, startStmtToken);
1567 }
1568}
1569
1570FeedDropStatement DropFeedStatement(Token startStmtToken) throws ParseException:
1571{
1572 FeedDropStatement stmt = null;
1573}
1574{
1575 <FEED> stmt = DropFeedSpecification(startStmtToken)
1576 {
1577 return stmt;
1578 }
1579}
1580
1581FeedDropStatement DropFeedSpecification(Token startStmtToken) throws ParseException:
1582{
1583 Pair<DataverseName,Identifier> pairId = null;
1584 boolean ifExists = false;
1585}
1586{
1587 pairId = QualifiedName() ifExists = IfExists()
1588 {
1589 FeedDropStatement stmt = new FeedDropStatement(pairId.first, pairId.second, ifExists);
1590 return addSourceLocation(stmt, startStmtToken);
1591 }
1592}
1593
1594FeedPolicyDropStatement DropFeedPolicyStatement(Token startStmtToken) throws ParseException:
1595{
1596 FeedPolicyDropStatement stmt = null;
1597}
1598{
1599 <INGESTION> <POLICY> stmt = DropFeedPolicySpecification(startStmtToken)
1600 {
1601 return stmt;
1602 }
1603}
1604
1605FeedPolicyDropStatement DropFeedPolicySpecification(Token startStmtToken) throws ParseException:
1606{
1607 Pair<DataverseName,Identifier> pairId = null;
1608 boolean ifExists = false;
1609}
1610{
1611 pairId = QualifiedName() ifExists = IfExists()
1612 {
1613 FeedPolicyDropStatement stmt = new FeedPolicyDropStatement(pairId.first, pairId.second, ifExists);
1614 return addSourceLocation(stmt, startStmtToken);
Yingyi Bu391f09e2015-10-29 13:49:39 -07001615 }
1616}
1617
Dmitry Lychagin2a0848e2020-01-08 13:57:22 -08001618SynonymDropStatement DropSynonymStatement(Token startStmtToken) throws ParseException:
1619{
1620 SynonymDropStatement stmt = null;
1621}
1622{
1623 <SYNONYM> stmt = DropSynonymSpecification(startStmtToken)
1624 {
1625 return stmt;
1626 }
1627}
1628
1629SynonymDropStatement DropSynonymSpecification(Token startStmtToken) throws ParseException:
1630{
1631 Pair<DataverseName,Identifier> pairId = null;
1632 boolean ifExists = false;
1633}
1634{
1635 pairId = QualifiedName() ifExists = IfExists()
1636 {
1637 SynonymDropStatement stmt = new SynonymDropStatement(pairId.first, pairId.second.getValue(), ifExists);
1638 return addSourceLocation(stmt, startStmtToken);
1639 }
1640}
1641
Yingyi Bu391f09e2015-10-29 13:49:39 -07001642boolean IfExists() throws ParseException :
1643{
1644}
1645{
1646 ( LOOKAHEAD(1) <IF> <EXISTS>
1647 {
1648 return true;
1649 }
1650 )?
1651 {
1652 return false;
1653 }
1654}
1655
1656InsertStatement InsertStatement() throws ParseException:
1657{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07001658 Token startToken = null;
Dmitry Lychagin54c06012019-11-13 15:54:20 -08001659 Pair<DataverseName,Identifier> nameComponents = null;
Yingyi Bucb5bf332017-01-02 22:19:50 -08001660 VariableExpr var = null;
1661 Query query = null;
1662 Expression returnExpression = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07001663}
1664{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07001665 <INSERT> { startToken = token; } <INTO> nameComponents = QualifiedName() (<AS> var = Variable())?
Dmitry Lychaginaebd0312019-06-04 08:55:39 -07001666 query = Query()
Yingyi Bucb5bf332017-01-02 22:19:50 -08001667 ( <RETURNING> returnExpression = Expression())?
Yingyi Bu391f09e2015-10-29 13:49:39 -07001668 {
Dmitry Lychagin393215e2019-04-11 10:26:56 -07001669 if (var == null && returnExpression != null) {
1670 var = new VariableExpr(SqlppVariableUtil.toInternalVariableIdentifier(nameComponents.second.getValue()));
1671 addSourceLocation(var, startToken);
Yingyi Bucb5bf332017-01-02 22:19:50 -08001672 }
Yingyi Bucaea8f02015-11-16 15:12:15 -08001673 query.setTopLevel(true);
Dmitry Lychagin2a0848e2020-01-08 13:57:22 -08001674 InsertStatement stmt = new InsertStatement(nameComponents.first, nameComponents.second.getValue(), query,
1675 getVarCounter(), var, returnExpression);
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07001676 return addSourceLocation(stmt, startToken);
Yingyi Bucb5bf332017-01-02 22:19:50 -08001677 }
1678}
1679
1680UpsertStatement UpsertStatement() throws ParseException:
1681{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07001682 Token startToken = null;
Dmitry Lychagin54c06012019-11-13 15:54:20 -08001683 Pair<DataverseName,Identifier> nameComponents = null;
Yingyi Bucb5bf332017-01-02 22:19:50 -08001684 VariableExpr var = null;
1685 Query query = null;
1686 Expression returnExpression = null;
1687}
1688{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07001689 <UPSERT> { startToken = token; } <INTO> nameComponents = QualifiedName() (<AS> var = Variable())?
Dmitry Lychaginaebd0312019-06-04 08:55:39 -07001690 query = Query()
Yingyi Bucb5bf332017-01-02 22:19:50 -08001691 ( <RETURNING> returnExpression = Expression())?
1692 {
Dmitry Lychagin393215e2019-04-11 10:26:56 -07001693 if (var == null && returnExpression != null) {
1694 var = new VariableExpr(SqlppVariableUtil.toInternalVariableIdentifier(nameComponents.second.getValue()));
1695 addSourceLocation(var, startToken);
Yingyi Bucb5bf332017-01-02 22:19:50 -08001696 }
1697 query.setTopLevel(true);
Dmitry Lychagin2a0848e2020-01-08 13:57:22 -08001698 UpsertStatement stmt = new UpsertStatement(nameComponents.first, nameComponents.second.getValue(), query,
1699 getVarCounter(), var, returnExpression);
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07001700 return addSourceLocation(stmt, startToken);
Yingyi Bu391f09e2015-10-29 13:49:39 -07001701 }
1702}
1703
1704DeleteStatement DeleteStatement() throws ParseException:
1705{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07001706 Token startToken = null;
Dmitry Lychagin393215e2019-04-11 10:26:56 -07001707 VariableExpr var = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07001708 Expression condition = null;
Dmitry Lychagin54c06012019-11-13 15:54:20 -08001709 Pair<DataverseName, Identifier> nameComponents;
Yingyi Bu391f09e2015-10-29 13:49:39 -07001710}
1711{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07001712 <DELETE> { startToken = token; }
Dmitry Lychagin393215e2019-04-11 10:26:56 -07001713 <FROM> nameComponents = QualifiedName() ((<AS>)? var = Variable())?
Yingyi Bu391f09e2015-10-29 13:49:39 -07001714 (<WHERE> condition = Expression())?
Yingyi Bu20e085b2016-07-06 12:57:27 -07001715 {
Dmitry Lychagin393215e2019-04-11 10:26:56 -07001716 if (var == null) {
1717 var = new VariableExpr(SqlppVariableUtil.toInternalVariableIdentifier(nameComponents.second.getValue()));
1718 addSourceLocation(var, startToken);
Yingyi Bu20e085b2016-07-06 12:57:27 -07001719 }
Dmitry Lychagin2a0848e2020-01-08 13:57:22 -08001720 DeleteStatement stmt = new DeleteStatement(var, nameComponents.first, nameComponents.second.getValue(),
Abdullah Alamoudi6eb01752017-04-01 21:51:19 -07001721 condition, getVarCounter());
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07001722 return addSourceLocation(stmt, startToken);
Yingyi Bu20e085b2016-07-06 12:57:27 -07001723 }
Yingyi Bu391f09e2015-10-29 13:49:39 -07001724}
1725
1726UpdateStatement UpdateStatement() throws ParseException:
1727{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07001728 Token startToken = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07001729 VariableExpr vars;
1730 Expression target;
1731 Expression condition;
1732 UpdateClause uc;
1733 List<UpdateClause> ucs = new ArrayList<UpdateClause>();
1734}
1735{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07001736 <UPDATE> { startToken = token; } vars = Variable() <IN> target = Expression()
Yingyi Bu391f09e2015-10-29 13:49:39 -07001737 <WHERE> condition = Expression()
1738 <LEFTPAREN> (uc = UpdateClause()
1739 {
1740 ucs.add(uc);
1741 }
1742 (<COMMA> uc = UpdateClause()
1743 {
1744 ucs.add(uc);
1745 }
1746 )*) <RIGHTPAREN>
1747 {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07001748 UpdateStatement stmt = new UpdateStatement(vars, target, condition, ucs);
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07001749 return addSourceLocation(stmt, startToken);
Yingyi Bu391f09e2015-10-29 13:49:39 -07001750 }
1751}
1752
1753UpdateClause UpdateClause() throws ParseException:
1754{
1755 Expression target = null;
1756 Expression value = null ;
1757 InsertStatement is = null;
1758 DeleteStatement ds = null;
1759 UpdateStatement us = null;
1760 Expression condition = null;
1761 UpdateClause ifbranch = null;
1762 UpdateClause elsebranch = null;
1763}
1764{
1765 (<SET> target = Expression() <EQ> value = Expression()
1766 | is = InsertStatement()
1767 | ds = DeleteStatement()
1768 | us = UpdateStatement()
1769 | <IF> <LEFTPAREN> condition = Expression() <RIGHTPAREN>
1770 <THEN> ifbranch = UpdateClause()
1771 [LOOKAHEAD(1) <ELSE> elsebranch = UpdateClause()]
1772 {
1773 return new UpdateClause(target, value, is, ds, us, condition, ifbranch, elsebranch);
1774 }
1775 )
1776}
1777
1778Statement SetStatement() throws ParseException:
1779{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07001780 Token startToken = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07001781 String pn = null;
1782 String pv = null;
1783}
1784{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07001785 <SET> { startToken = token; } pn = Identifier() pv = ConstantString()
Yingyi Bu391f09e2015-10-29 13:49:39 -07001786 {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07001787 SetStatement stmt = new SetStatement(pn, pv);
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07001788 return addSourceLocation(stmt, startToken);
Yingyi Bu391f09e2015-10-29 13:49:39 -07001789 }
1790}
1791
1792Statement WriteStatement() throws ParseException:
1793{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07001794 Token startToken = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07001795 String nodeName = null;
1796 String fileName = null;
1797 Query query;
1798 String writerClass = null;
1799 Pair<Identifier,Identifier> nameComponents = null;
1800}
1801{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07001802 <WRITE> { startToken = token; } <OUTPUT> <TO> nodeName = Identifier() <COLON> fileName = ConstantString()
Yingyi Bu6d57e492016-06-06 21:24:42 -07001803 ( <USING> writerClass = ConstantString() )?
Yingyi Bu391f09e2015-10-29 13:49:39 -07001804 {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07001805 WriteStatement stmt = new WriteStatement(new Identifier(nodeName), fileName, writerClass);
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07001806 return addSourceLocation(stmt, startToken);
Yingyi Bu391f09e2015-10-29 13:49:39 -07001807 }
1808}
1809
1810LoadStatement LoadStatement() throws ParseException:
1811{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07001812 Token startToken = null;
Dmitry Lychagin54c06012019-11-13 15:54:20 -08001813 DataverseName dataverseName = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07001814 Identifier datasetName = null;
1815 boolean alreadySorted = false;
1816 String adapterName;
1817 Map<String,String> properties;
Dmitry Lychagin54c06012019-11-13 15:54:20 -08001818 Pair<DataverseName,Identifier> nameComponents = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07001819}
1820{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07001821 <LOAD> { startToken = token; } Dataset() nameComponents = QualifiedName()
Yingyi Bu391f09e2015-10-29 13:49:39 -07001822 {
1823 dataverseName = nameComponents.first;
1824 datasetName = nameComponents.second;
1825 }
1826 <USING> adapterName = AdapterName() properties = Configuration()
1827 (<PRESORTED>
1828 {
1829 alreadySorted = true;
1830 }
1831 )?
1832 {
Dmitry Lychagin2a0848e2020-01-08 13:57:22 -08001833 LoadStatement stmt = new LoadStatement(dataverseName, datasetName.getValue(), adapterName, properties,
1834 alreadySorted);
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07001835 return addSourceLocation(stmt, startToken);
Yingyi Bu391f09e2015-10-29 13:49:39 -07001836 }
1837}
1838
1839
1840String AdapterName() throws ParseException :
1841{
1842 String adapterName = null;
1843}
1844{
1845 adapterName = Identifier()
1846 {
1847 return adapterName;
1848 }
1849}
1850
1851Statement CompactStatement() throws ParseException:
1852{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07001853 Token startToken = null;
Dmitry Lychagin54c06012019-11-13 15:54:20 -08001854 Pair<DataverseName,Identifier> nameComponents = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07001855}
1856{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07001857 <COMPACT> { startToken = token; } Dataset() nameComponents = QualifiedName()
Yingyi Bu391f09e2015-10-29 13:49:39 -07001858 {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07001859 CompactStatement stmt = new CompactStatement(nameComponents.first, nameComponents.second);
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07001860 return addSourceLocation(stmt, startToken);
Yingyi Bu391f09e2015-10-29 13:49:39 -07001861 }
1862}
1863
Yingyi Buab817482016-08-19 21:29:31 -07001864Statement ConnectionStatement() throws ParseException:
Yingyi Bu391f09e2015-10-29 13:49:39 -07001865{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07001866 Token startToken = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07001867 Statement stmt = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07001868}
1869{
1870 (
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07001871 <CONNECT> { startToken = token; } stmt = ConnectStatement(startToken)
1872 | <DISCONNECT> { startToken = token; } stmt = DisconnectStatement(startToken)
1873 | <START> { startToken = token; } stmt = StartStatement(startToken)
1874 | <STOP> { startToken = token; } stmt = StopStatement(startToken)
Yingyi Buab817482016-08-19 21:29:31 -07001875 )
1876 {
1877 return stmt;
1878 }
1879}
1880
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07001881Statement StartStatement(Token startStmtToken) throws ParseException:
Abdullah Alamoudifff200c2017-02-18 20:32:14 -08001882{
Dmitry Lychagin54c06012019-11-13 15:54:20 -08001883 Pair<DataverseName,Identifier> feedNameComponents = null;
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07001884 AbstractStatement stmt = null;
Abdullah Alamoudifff200c2017-02-18 20:32:14 -08001885}
1886{
1887 <FEED> feedNameComponents = QualifiedName()
1888 {
1889 stmt = new StartFeedStatement (feedNameComponents);
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07001890 return addSourceLocation(stmt, startStmtToken);
Abdullah Alamoudifff200c2017-02-18 20:32:14 -08001891 }
1892}
1893
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07001894AbstractStatement StopStatement(Token startStmtToken) throws ParseException:
Abdullah Alamoudifff200c2017-02-18 20:32:14 -08001895{
Dmitry Lychagin54c06012019-11-13 15:54:20 -08001896 Pair<DataverseName,Identifier> feedNameComponents = null;
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07001897 AbstractStatement stmt = null;
Abdullah Alamoudifff200c2017-02-18 20:32:14 -08001898}
1899{
1900 <FEED> feedNameComponents = QualifiedName()
1901 {
1902 stmt = new StopFeedStatement (feedNameComponents);
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07001903 return addSourceLocation(stmt, startStmtToken);
Abdullah Alamoudifff200c2017-02-18 20:32:14 -08001904 }
1905}
1906
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07001907AbstractStatement DisconnectStatement(Token startStmtToken) throws ParseException:
Yingyi Buab817482016-08-19 21:29:31 -07001908{
Dmitry Lychagin54c06012019-11-13 15:54:20 -08001909 Pair<DataverseName,Identifier> feedNameComponents = null;
1910 Pair<DataverseName,Identifier> datasetNameComponents = null;
Yingyi Buab817482016-08-19 21:29:31 -07001911
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07001912 AbstractStatement stmt = null;
Yingyi Buab817482016-08-19 21:29:31 -07001913}
1914{
1915 (
1916 <FEED> feedNameComponents = QualifiedName() <FROM> Dataset() datasetNameComponents = QualifiedName()
Yingyi Bu391f09e2015-10-29 13:49:39 -07001917 {
1918 stmt = new DisconnectFeedStatement(feedNameComponents, datasetNameComponents);
1919 }
1920 )
Yingyi Buab817482016-08-19 21:29:31 -07001921 {
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07001922 return addSourceLocation(stmt, startStmtToken);
Yingyi Buab817482016-08-19 21:29:31 -07001923 }
1924}
1925
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07001926AbstractStatement ConnectStatement(Token startStmtToken) throws ParseException:
Yingyi Buab817482016-08-19 21:29:31 -07001927{
Dmitry Lychagin54c06012019-11-13 15:54:20 -08001928 Pair<DataverseName,Identifier> feedNameComponents = null;
1929 Pair<DataverseName,Identifier> datasetNameComponents = null;
Yingyi Buab817482016-08-19 21:29:31 -07001930
1931 Map<String,String> configuration = null;
Xikui Wang9d63f622017-05-18 17:50:44 -07001932 List<FunctionSignature> appliedFunctions = new ArrayList<FunctionSignature>();
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07001933 AbstractStatement stmt = null;
Yingyi Buab817482016-08-19 21:29:31 -07001934 String policy = null;
Xikui Wangf6741682018-02-22 19:17:17 -08001935 String whereClauseBody = null;
1936 WhereClause whereClause = null;
1937 Token beginPos = null;
1938 Token endPos = null;
Yingyi Buab817482016-08-19 21:29:31 -07001939}
1940{
1941 (
Abdullah Alamoudifff200c2017-02-18 20:32:14 -08001942 <FEED> feedNameComponents = QualifiedName() <TO> Dataset() datasetNameComponents = QualifiedName()
Xikui Wangf6741682018-02-22 19:17:17 -08001943 (ApplyFunction(appliedFunctions))?
1944 (policy = GetPolicy())?
1945 (
1946 <WHERE>
1947 {
1948 beginPos = token;
1949 whereClause = new WhereClause();
1950 Expression whereExpr;
1951 }
1952 whereExpr = Expression()
1953 {
1954 whereClause.setWhereExpr(whereExpr);
1955 }
1956 )?
1957 {
1958 if (whereClause != null) {
1959 endPos = token;
1960 whereClauseBody = extractFragment(beginPos.endLine, beginPos.endColumn, endPos.endLine, endPos.endColumn + 1);
1961 }
1962 }
Yingyi Buab817482016-08-19 21:29:31 -07001963 {
Xikui Wang261dc6d2017-03-29 21:23:15 -07001964 stmt = new ConnectFeedStatement(feedNameComponents, datasetNameComponents, appliedFunctions,
Xikui Wangf6741682018-02-22 19:17:17 -08001965 policy, whereClauseBody, getVarCounter());
Yingyi Buab817482016-08-19 21:29:31 -07001966 }
1967 )
1968 {
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07001969 return addSourceLocation(stmt, startStmtToken);
Yingyi Buab817482016-08-19 21:29:31 -07001970 }
Yingyi Bu391f09e2015-10-29 13:49:39 -07001971}
1972
1973Map<String,String> Configuration() throws ParseException :
1974{
1975 Map<String,String> configuration = new LinkedHashMap<String,String>();
1976 Pair<String, String> keyValuePair = null;
1977}
1978{
1979 <LEFTPAREN> ( keyValuePair = KeyValuePair()
1980 {
1981 configuration.put(keyValuePair.first, keyValuePair.second);
1982 }
1983 ( <COMMA> keyValuePair = KeyValuePair()
1984 {
1985 configuration.put(keyValuePair.first, keyValuePair.second);
1986 }
1987 )* )? <RIGHTPAREN>
1988 {
1989 return configuration;
1990 }
1991}
1992
1993Pair<String, String> KeyValuePair() throws ParseException:
1994{
1995 String key;
1996 String value;
1997}
1998{
Yingyi Bu6d57e492016-06-06 21:24:42 -07001999 <LEFTPAREN> key = ConstantString() <EQ> value = ConstantString() <RIGHTPAREN>
Yingyi Bu391f09e2015-10-29 13:49:39 -07002000 {
2001 return new Pair<String, String>(key, value);
2002 }
2003}
2004
2005Map<String,String> Properties() throws ParseException:
2006{
2007 Map<String,String> properties = new HashMap<String,String>();
2008 Pair<String, String> property;
2009}
2010{
2011 (LOOKAHEAD(1) <LEFTPAREN> property = Property()
2012 {
2013 properties.put(property.first, property.second);
2014 }
2015 ( <COMMA> property = Property()
2016 {
2017 properties.put(property.first, property.second);
2018 }
2019 )* <RIGHTPAREN> )?
2020 {
2021 return properties;
2022 }
2023}
2024
2025Pair<String, String> Property() throws ParseException:
2026{
Yingyi Bu6d57e492016-06-06 21:24:42 -07002027 String key = null;
2028 String value = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07002029}
2030{
Yingyi Bu6d57e492016-06-06 21:24:42 -07002031 (key = Identifier() | key = StringLiteral())
2032 <EQ>
2033 ( value = ConstantString() | <INTEGER_LITERAL>
Yingyi Bu391f09e2015-10-29 13:49:39 -07002034 {
2035 try {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002036 value = String.valueOf(Long.parseLong(token.image));
Yingyi Bu391f09e2015-10-29 13:49:39 -07002037 } catch (NumberFormatException nfe) {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002038 throw new SqlppParseException(getSourceLocation(token), "inapproriate value: " + token.image);
Yingyi Bu391f09e2015-10-29 13:49:39 -07002039 }
2040 }
2041 )
2042 {
2043 return new Pair<String, String>(key.toUpperCase(), value);
2044 }
2045}
2046
Dmitry Lychagin8ba59442017-06-16 14:19:45 -07002047IndexedTypeExpression IndexedTypeExpr() throws ParseException:
Yingyi Bu391f09e2015-10-29 13:49:39 -07002048{
2049 TypeExpression typeExpr = null;
Dmitry Lychagin8ba59442017-06-16 14:19:45 -07002050 boolean isUnknownable = false;
Yingyi Bu391f09e2015-10-29 13:49:39 -07002051}
2052{
2053 (
2054 typeExpr = TypeReference()
2055 | typeExpr = OrderedListTypeDef()
2056 | typeExpr = UnorderedListTypeDef()
2057 )
Dmitry Lychagin8ba59442017-06-16 14:19:45 -07002058 ( <QUES> { isUnknownable = true; } )?
Yingyi Bu391f09e2015-10-29 13:49:39 -07002059 {
Dmitry Lychagin8ba59442017-06-16 14:19:45 -07002060 return new IndexedTypeExpression(typeExpr, isUnknownable);
Yingyi Bu391f09e2015-10-29 13:49:39 -07002061 }
2062}
2063
2064TypeExpression TypeExpr() throws ParseException:
2065{
2066 TypeExpression typeExpr = null;
2067}
2068{
2069 (
2070 typeExpr = RecordTypeDef()
2071 | typeExpr = TypeReference()
2072 | typeExpr = OrderedListTypeDef()
2073 | typeExpr = UnorderedListTypeDef()
2074 )
2075 {
2076 return typeExpr;
2077 }
2078}
2079
2080RecordTypeDefinition RecordTypeDef() throws ParseException:
2081{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002082 Token startToken = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07002083 RecordTypeDefinition recType = new RecordTypeDefinition();
2084 RecordTypeDefinition.RecordKind recordKind = null;
2085}
2086{
2087 ( <CLOSED> { recordKind = RecordTypeDefinition.RecordKind.CLOSED; }
2088 | <OPEN> { recordKind = RecordTypeDefinition.RecordKind.OPEN; } )?
2089 <LEFTBRACE>
2090 {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002091 startToken = token;
Dmitry Lychagine77cdac2019-08-05 11:37:47 -07002092 Token hintToken = fetchHint(token, SqlppHint.GEN_FIELDS_HINT);
2093 if (hintToken != null) {
2094 String hintParams = hintToken.hintParams;
2095 String[] splits = hintParams != null ? hintParams.split("\\s+") : null;
2096 if (splits == null || splits.length != 4) {
2097 throw new SqlppParseException(getSourceLocation(hintToken),
2098 "Expecting: /*+ gen-fields <type> <min> <max> <prefix>*/");
Yingyi Bu391f09e2015-10-29 13:49:39 -07002099 }
Dmitry Lychagine77cdac2019-08-05 11:37:47 -07002100 if (!splits[0].equals("int")) {
2101 throw new SqlppParseException(getSourceLocation(hintToken),
2102 "The only supported type for gen-fields is int.");
2103 }
2104 UndeclaredFieldsDataGen ufdg = new UndeclaredFieldsDataGen(UndeclaredFieldsDataGen.Type.INT,
2105 Integer.parseInt(splits[1]), Integer.parseInt(splits[2]), splits[3]);
2106 recType.setUndeclaredFieldsDataGen(ufdg);
Yingyi Bu391f09e2015-10-29 13:49:39 -07002107 }
Yingyi Bu391f09e2015-10-29 13:49:39 -07002108 }
Dmitry Lychagine77cdac2019-08-05 11:37:47 -07002109 (
2110 RecordField(recType)
2111 ( <COMMA> RecordField(recType) )*
2112 )?
Yingyi Bu391f09e2015-10-29 13:49:39 -07002113 <RIGHTBRACE>
2114 {
2115 if (recordKind == null) {
2116 recordKind = RecordTypeDefinition.RecordKind.OPEN;
2117 }
2118 recType.setRecordKind(recordKind);
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07002119 return addSourceLocation(recType, startToken);
Yingyi Bu391f09e2015-10-29 13:49:39 -07002120 }
2121}
2122
2123void RecordField(RecordTypeDefinition recType) throws ParseException:
2124{
2125 String fieldName;
2126 TypeExpression type = null;
2127 boolean nullable = false;
2128}
2129{
2130 fieldName = Identifier()
2131 {
Dmitry Lychagine77cdac2019-08-05 11:37:47 -07002132 Token hintToken = fetchHint(token, SqlppHint.VAL_FILE_HINT, SqlppHint.VAL_FILE_SAME_INDEX_HINT,
2133 SqlppHint.LIST_VAL_FILE_HINT, SqlppHint.LIST_HINT, SqlppHint.INTERVAL_HINT, SqlppHint.INSERT_RAND_INT_HINT,
2134 SqlppHint.DATE_BETWEEN_YEARS_HINT, SqlppHint.DATETIME_ADD_RAND_HOURS_HINT, SqlppHint.AUTO_HINT);
2135 IRecordFieldDataGen rfdg = hintToken != null ? parseFieldDataGen(hintToken) : null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07002136 }
2137 <COLON> type = TypeExpr() (<QUES> { nullable = true; } )?
2138 {
2139 recType.addField(fieldName, type, nullable, rfdg);
2140 }
2141}
2142
2143TypeReferenceExpression TypeReference() throws ParseException:
2144{
Dmitry Lychagin54c06012019-11-13 15:54:20 -08002145 Pair<DataverseName,Identifier> id = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07002146}
2147{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002148 id = QualifiedName()
2149 {
Dmitry Lychagin75f19872019-10-03 17:56:35 -07002150 if (id.first == null && id.second.getValue().equalsIgnoreCase(INT_TYPE_NAME)) {
2151 id.second = new Identifier(BuiltinType.AINT64.getTypeName());
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002152 }
Yingyi Bu391f09e2015-10-29 13:49:39 -07002153
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002154 TypeReferenceExpression typeRef = new TypeReferenceExpression(id);
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07002155 return addSourceLocation(typeRef, token);
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002156 }
Yingyi Bu391f09e2015-10-29 13:49:39 -07002157}
2158
2159OrderedListTypeDefinition OrderedListTypeDef() throws ParseException:
2160{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002161 Token startToken = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07002162 TypeExpression type = null;
2163}
2164{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002165 <LEFTBRACKET> { startToken = token; }
2166 ( type = TypeExpr() )
Yingyi Bu391f09e2015-10-29 13:49:39 -07002167 <RIGHTBRACKET>
2168 {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002169 OrderedListTypeDefinition typeDef = new OrderedListTypeDefinition(type);
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07002170 return addSourceLocation(typeDef, startToken);
Yingyi Bu391f09e2015-10-29 13:49:39 -07002171 }
2172}
2173
Yingyi Bu391f09e2015-10-29 13:49:39 -07002174UnorderedListTypeDefinition UnorderedListTypeDef() throws ParseException:
2175{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002176 Token startToken = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07002177 TypeExpression type = null;
2178}
2179{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002180 <LEFTDBLBRACE> { startToken = token; }
Yingyi Bu391f09e2015-10-29 13:49:39 -07002181 ( type = TypeExpr() )
2182 <RIGHTDBLBRACE>
2183 {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002184 UnorderedListTypeDefinition typeDef = new UnorderedListTypeDefinition(type);
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07002185 return addSourceLocation(typeDef, startToken);
Yingyi Bu391f09e2015-10-29 13:49:39 -07002186 }
2187}
2188
2189FunctionName FunctionName() throws ParseException:
2190{
Dmitry Lychagin54c06012019-11-13 15:54:20 -08002191 Triple<List<String>, SourceLocation, SqlppHint> prefix = null;
2192 String suffix = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07002193}
2194{
Dmitry Lychagin54c06012019-11-13 15:54:20 -08002195 // Note: there's a copy of this production in PrimaryExpr() (LOOKAHEAD for FunctionCallExpr())
2196 // that copy must be kept in sync with this code
2197 prefix = MultipartIdentifierWithHints(SqlppHint.INDEXED_NESTED_LOOP_JOIN_HINT,
2198 SqlppHint.SKIP_SECONDARY_INDEX_SEARCH_HINT)
2199 (<SHARP> suffix = Identifier())?
Yingyi Bu391f09e2015-10-29 13:49:39 -07002200 {
2201 FunctionName result = new FunctionName();
Dmitry Lychagin54c06012019-11-13 15:54:20 -08002202 result.sourceLoc = prefix.second;
2203 result.hint = prefix.third;
2204 List<String> list = prefix.first;
2205 int ln = list.size();
2206 String last = list.get(ln - 1);
2207 if (suffix == null) {
2208 // prefix = (dv_part1.dv_part2...dv_partN.)?func_name
2209 // no library name
2210 result.function = last;
2211 } else {
2212 // prefix = (dv_part1.dv_part2...dv_partN.)?lib_name
2213 // suffix = func_name
2214 result.library = last;
2215 result.function = suffix;
Dmitry Lychagine77cdac2019-08-05 11:37:47 -07002216 }
Dmitry Lychagin54c06012019-11-13 15:54:20 -08002217 if (ln > 1) {
2218 result.dataverse = DataverseName.create(list, 0, ln - 1);
2219 } else {
2220 result.dataverse = defaultDataverse;
Yingyi Bu391f09e2015-10-29 13:49:39 -07002221 }
Yingyi Bu391f09e2015-10-29 13:49:39 -07002222
Dmitry Lychagin54c06012019-11-13 15:54:20 -08002223 if (result.function.equalsIgnoreCase(INT_TYPE_NAME)) {
2224 result.function = BuiltinType.AINT64.getTypeName();
Yingyi Bu391f09e2015-10-29 13:49:39 -07002225 }
Dmitry Lychagin54c06012019-11-13 15:54:20 -08002226 return result;
2227 }
Yingyi Bu391f09e2015-10-29 13:49:39 -07002228}
2229
Dmitry Lychagin54c06012019-11-13 15:54:20 -08002230Pair<DataverseName,Identifier> TypeName() throws ParseException:
Yingyi Bu391f09e2015-10-29 13:49:39 -07002231{
Dmitry Lychagin54c06012019-11-13 15:54:20 -08002232 Pair<DataverseName,Identifier> name = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07002233}
2234{
2235 name = QualifiedName()
2236 {
2237 if (name.first == null) {
Dmitry Lychagin54c06012019-11-13 15:54:20 -08002238 name.first = defaultDataverse;
Yingyi Bu391f09e2015-10-29 13:49:39 -07002239 }
2240 return name;
2241 }
2242}
2243
2244String Identifier() throws ParseException:
2245{
2246 String lit = null;
2247}
2248{
2249 (<IDENTIFIER>
2250 {
2251 return token.image;
2252 }
2253 | lit = QuotedString()
2254 {
2255 return lit;
2256 }
2257 )
2258}
2259
Dmitry Lychagin8ba59442017-06-16 14:19:45 -07002260Pair<Integer, Pair<List<String>, IndexedTypeExpression>> OpenField() throws ParseException:
Yingyi Bu391f09e2015-10-29 13:49:39 -07002261{
Dmitry Lychagin8ba59442017-06-16 14:19:45 -07002262 IndexedTypeExpression fieldType = null;
Yingyi Buc9bfe252016-03-01 00:02:40 -08002263 Pair<Integer, List<String>> fieldList = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07002264}
2265{
2266 fieldList = NestedField()
Dmitry Lychagin8ba59442017-06-16 14:19:45 -07002267 ( <COLON> fieldType = IndexedTypeExpr() )?
Yingyi Bu391f09e2015-10-29 13:49:39 -07002268 {
Dmitry Lychagin8ba59442017-06-16 14:19:45 -07002269 return new Pair<Integer, Pair<List<String>, IndexedTypeExpression>>
2270 (fieldList.first, new Pair<List<String>, IndexedTypeExpression>(fieldList.second, fieldType));
Yingyi Bu391f09e2015-10-29 13:49:39 -07002271 }
2272}
2273
Yingyi Buc9bfe252016-03-01 00:02:40 -08002274Pair<Integer, List<String>> NestedField() throws ParseException:
Yingyi Bu391f09e2015-10-29 13:49:39 -07002275{
2276 List<String> exprList = new ArrayList<String>();
2277 String lit = null;
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002278 Token litToken = null;
Yingyi Buc9bfe252016-03-01 00:02:40 -08002279 int source = 0;
Yingyi Bu391f09e2015-10-29 13:49:39 -07002280}
2281{
2282 lit = Identifier()
2283 {
Yingyi Bub9169b62016-02-26 21:21:49 -08002284 boolean meetParens = false;
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002285 litToken = token;
Yingyi Bub9169b62016-02-26 21:21:49 -08002286 }
2287 (
Yingyi Buc9bfe252016-03-01 00:02:40 -08002288 LOOKAHEAD(1)
Yingyi Bub9169b62016-02-26 21:21:49 -08002289 <LEFTPAREN><RIGHTPAREN>
2290 {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002291 if(!lit.equalsIgnoreCase("meta")){
2292 throw new SqlppParseException(getSourceLocation(litToken), "The string before () has to be \"meta\".");
Yingyi Bub9169b62016-02-26 21:21:49 -08002293 }
2294 meetParens = true;
Yingyi Buc9bfe252016-03-01 00:02:40 -08002295 source = 1;
Yingyi Bub9169b62016-02-26 21:21:49 -08002296 }
2297 )?
2298 {
2299 if(!meetParens){
2300 exprList.add(lit);
2301 }
Yingyi Bu391f09e2015-10-29 13:49:39 -07002302 }
2303 (<DOT>
2304 lit = Identifier()
2305 {
2306 exprList.add(lit);
2307 }
2308 )*
2309 {
Yingyi Buc9bfe252016-03-01 00:02:40 -08002310 return new Pair<Integer, List<String>>(source, exprList);
Yingyi Bu391f09e2015-10-29 13:49:39 -07002311 }
2312}
2313
Yingyi Bu6d57e492016-06-06 21:24:42 -07002314String ConstantString() throws ParseException:
2315{
2316 String value = null;
2317}
2318{
2319 (value = QuotedString() | value = StringLiteral())
2320 {
2321 return value;
2322 }
2323}
2324
Yingyi Bu391f09e2015-10-29 13:49:39 -07002325String QuotedString() throws ParseException:
2326{
2327}
2328{
2329 <QUOTED_STRING>
2330 {
2331 return removeQuotesAndEscapes(token.image);
2332 }
2333}
2334
Yingyi Bu391f09e2015-10-29 13:49:39 -07002335String StringLiteral() throws ParseException:
2336{
2337}
2338{
2339 <STRING_LITERAL>
2340 {
2341 return removeQuotesAndEscapes(token.image);
2342 }
2343}
2344
Dmitry Lychagin54c06012019-11-13 15:54:20 -08002345List<String> MultipartIdentifier() throws ParseException:
Yingyi Bu391f09e2015-10-29 13:49:39 -07002346{
Dmitry Lychagin54c06012019-11-13 15:54:20 -08002347 Triple<List<String>, SourceLocation, SqlppHint> result = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07002348}
2349{
Dmitry Lychagin54c06012019-11-13 15:54:20 -08002350 result = MultipartIdentifierWithHints(null)
Yingyi Bu391f09e2015-10-29 13:49:39 -07002351 {
Dmitry Lychagin54c06012019-11-13 15:54:20 -08002352 return result.first;
Yingyi Bu391f09e2015-10-29 13:49:39 -07002353 }
2354}
2355
Dmitry Lychagin54c06012019-11-13 15:54:20 -08002356Triple<List<String>, SourceLocation, SqlppHint> MultipartIdentifierWithHints(SqlppHint... expectedHints)
2357 throws ParseException:
Yingyi Bu391f09e2015-10-29 13:49:39 -07002358{
Dmitry Lychagin54c06012019-11-13 15:54:20 -08002359 List<String> list = new ArrayList<String>();
2360 SourceLocation sourceLoc = null;
2361 SqlppHint hint = null;
2362 String item = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07002363}
2364{
Dmitry Lychagin54c06012019-11-13 15:54:20 -08002365 item = Identifier()
Yingyi Bu391f09e2015-10-29 13:49:39 -07002366 {
Dmitry Lychagin54c06012019-11-13 15:54:20 -08002367 list.add(item);
2368 sourceLoc = getSourceLocation(token);
2369 if (expectedHints != null && expectedHints.length > 0) {
2370 Token hintToken = fetchHint(token, expectedHints);
2371 if (hintToken != null) {
2372 hint = hintToken.hint;
2373 }
Yingyi Bu391f09e2015-10-29 13:49:39 -07002374 }
Dmitry Lychagin54c06012019-11-13 15:54:20 -08002375 }
2376 (<DOT> item = Identifier() { list.add(item); } )*
2377 {
2378 return new Triple<List<String>, SourceLocation, SqlppHint>(list, sourceLoc, hint);
2379 }
2380}
2381
2382Pair<DataverseName,Identifier> QualifiedName() throws ParseException:
2383{
2384 List<String> list = null;
2385}
2386{
2387 list = MultipartIdentifier()
2388 {
2389 int len = list.size();
2390 DataverseName id1 = len > 1 ? DataverseName.create(list, 0, len - 1) : null;
2391 Identifier id2 = new Identifier(list.get(len - 1));
2392 return new Pair<DataverseName,Identifier>(id1, id2);
2393 }
2394}
2395
2396Triple<DataverseName, Identifier, Identifier> DoubleQualifiedName() throws ParseException:
2397{
2398 List<String> list = new ArrayList<String>();
2399 String item = null;
2400}
2401{
2402 item = Identifier() { list.add(item); }
2403 (<DOT> item = Identifier() { list.add(item); } )+
2404 {
2405 int len = list.size();
2406 DataverseName id1 = len > 2 ? DataverseName.create(list, 0, len - 2) : null;
2407 Identifier id2 = new Identifier(list.get(len - 2));
2408 Identifier id3 = new Identifier(list.get(len - 1));
2409 return new Triple<DataverseName,Identifier,Identifier>(id1, id2, id3);
Yingyi Bu391f09e2015-10-29 13:49:39 -07002410 }
2411}
2412
2413FunctionDecl FunctionDeclaration() throws ParseException:
2414{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002415 Token startToken = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07002416 String functionName;
Dmitry Lychagin0d4c1b62020-02-07 17:10:16 -08002417 List<Pair<VarIdentifier,IndexedTypeExpression>> paramList = Collections.<Pair<VarIdentifier,IndexedTypeExpression>>emptyList();;
Ian Maxon38fe9402020-01-29 19:27:40 -08002418 List<VarIdentifier> paramVarOnly = new ArrayList<VarIdentifier>();
Yingyi Bu391f09e2015-10-29 13:49:39 -07002419 Expression funcBody;
2420 createNewScope();
2421}
2422{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002423 <DECLARE> { startToken = token; } <FUNCTION>
Xikui Wang3de700a2018-03-15 16:32:55 -07002424 functionName = Identifier()
Ian Maxon38fe9402020-01-29 19:27:40 -08002425 paramList = FunctionParameters()
Xikui Wang3de700a2018-03-15 16:32:55 -07002426 <LEFTBRACE>
Dmitry Lychagin0d4c1b62020-02-07 17:10:16 -08002427 funcBody = FunctionBody()
Xikui Wang3de700a2018-03-15 16:32:55 -07002428 <RIGHTBRACE>
2429 {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002430 FunctionSignature signature = new FunctionSignature(defaultDataverse, functionName, paramList.size());
Xikui Wang3de700a2018-03-15 16:32:55 -07002431 getCurrentScope().addFunctionDescriptor(signature, false);
Ian Maxon38fe9402020-01-29 19:27:40 -08002432 for(Pair<VarIdentifier,IndexedTypeExpression> p: paramList){
2433 paramVarOnly.add(p.getFirst());
2434 }
2435 FunctionDecl stmt = new FunctionDecl(signature, paramVarOnly, funcBody);
Xikui Wang3de700a2018-03-15 16:32:55 -07002436 removeCurrentScope();
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07002437 return addSourceLocation(stmt, startToken);
Xikui Wang3de700a2018-03-15 16:32:55 -07002438 }
Yingyi Bu391f09e2015-10-29 13:49:39 -07002439}
2440
Dmitry Lychaginaebd0312019-06-04 08:55:39 -07002441Query Query() throws ParseException:
Yingyi Bu391f09e2015-10-29 13:49:39 -07002442{
Dmitry Lychaginaebd0312019-06-04 08:55:39 -07002443 Query query = new Query();
Yingyi Bu391f09e2015-10-29 13:49:39 -07002444 Expression expr;
2445}
2446{
2447 (
2448 expr = Expression()
2449 |
2450 expr = SelectExpression(false)
2451 )
2452 {
2453 query.setBody(expr);
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002454 query.setSourceLocation(expr.getSourceLocation());
Yingyi Bu391f09e2015-10-29 13:49:39 -07002455 return query;
2456 }
2457}
2458
2459
Yingyi Bu391f09e2015-10-29 13:49:39 -07002460Expression Expression():
2461{
2462 Expression expr = null;
2463 Expression exprP = null;
2464}
2465{
2466(
2467 LOOKAHEAD(2)
2468 expr = OperatorExpr()
Yingyi Bu391f09e2015-10-29 13:49:39 -07002469 | expr = QuantifiedExpression()
2470)
2471 {
2472 return (exprP==null) ? expr : exprP;
2473 }
2474}
2475
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002476Expression OperatorExpr() throws ParseException:
Yingyi Bu391f09e2015-10-29 13:49:39 -07002477{
2478 OperatorExpr op = null;
2479 Expression operand = null;
2480}
2481{
2482 operand = AndExpr()
2483 (
Yingyi Bu391f09e2015-10-29 13:49:39 -07002484 <OR>
2485 {
2486 if (op == null) {
2487 op = new OperatorExpr();
2488 op.addOperand(operand);
Xikui Wang3de700a2018-03-15 16:32:55 -07002489 op.setCurrentop(true);
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07002490 addSourceLocation(op, token);
Yingyi Bu391f09e2015-10-29 13:49:39 -07002491 }
Yingyi Bu196db5d2016-07-15 19:07:20 -07002492 try{
2493 op.addOperator(token.image.toLowerCase());
2494 } catch (Exception e){
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002495 throw new SqlppParseException(getSourceLocation(token), e.getMessage());
Yingyi Bu196db5d2016-07-15 19:07:20 -07002496 }
Xikui Wang3de700a2018-03-15 16:32:55 -07002497 }
Yingyi Bu391f09e2015-10-29 13:49:39 -07002498
Xikui Wang3de700a2018-03-15 16:32:55 -07002499 operand = AndExpr()
2500 {
2501 op.addOperand(operand);
2502 }
Yingyi Bu391f09e2015-10-29 13:49:39 -07002503
2504 )*
2505
2506 {
2507 return op==null? operand: op;
2508 }
2509}
2510
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002511Expression AndExpr() throws ParseException:
Yingyi Bu391f09e2015-10-29 13:49:39 -07002512{
2513 OperatorExpr op = null;
2514 Expression operand = null;
2515}
2516{
Yingyi Bu196db5d2016-07-15 19:07:20 -07002517 operand = NotExpr()
Yingyi Bu391f09e2015-10-29 13:49:39 -07002518 (
Yingyi Bu391f09e2015-10-29 13:49:39 -07002519 <AND>
2520 {
2521 if (op == null) {
2522 op = new OperatorExpr();
2523 op.addOperand(operand);
Yingyi Bu196db5d2016-07-15 19:07:20 -07002524 op.setCurrentop(true);
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07002525 addSourceLocation(op, token);
Yingyi Bu391f09e2015-10-29 13:49:39 -07002526 }
Yingyi Bu196db5d2016-07-15 19:07:20 -07002527 try{
2528 op.addOperator(token.image.toLowerCase());
Taewoo Kime65e6ca2017-01-14 17:53:28 -08002529 } catch (CompilationException e){
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002530 throw new SqlppParseException(getSourceLocation(token), e.getMessage());
Yingyi Bu196db5d2016-07-15 19:07:20 -07002531 }
Yingyi Bu391f09e2015-10-29 13:49:39 -07002532 }
2533
Yingyi Bu196db5d2016-07-15 19:07:20 -07002534 operand = NotExpr()
Yingyi Bu391f09e2015-10-29 13:49:39 -07002535 {
2536 op.addOperand(operand);
2537 }
2538
2539 )*
2540
2541 {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002542 return op==null ? operand: op;
Yingyi Bu391f09e2015-10-29 13:49:39 -07002543 }
2544}
2545
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002546Expression NotExpr() throws ParseException:
Yingyi Bu196db5d2016-07-15 19:07:20 -07002547{
2548 Expression inputExpr;
2549 boolean not = false;
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002550 Token startToken = null;
Yingyi Bu196db5d2016-07-15 19:07:20 -07002551}
2552{
Dmitry Lychagin5476f962019-05-31 16:03:11 -07002553 (LOOKAHEAD(2) <NOT> { not = true; startToken = token; } )? inputExpr = RelExpr()
Yingyi Bu196db5d2016-07-15 19:07:20 -07002554 {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002555 if(not) {
Dmitry Lychagin7c53fcf2017-11-07 12:07:41 -08002556 FunctionSignature signature = new FunctionSignature(BuiltinFunctions.NOT);
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002557 CallExpr callExpr = new CallExpr(signature, new ArrayList<Expression>(Collections.singletonList(inputExpr)));
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07002558 return addSourceLocation(callExpr, startToken);
Yingyi Bu196db5d2016-07-15 19:07:20 -07002559 } else {
2560 return inputExpr;
2561 }
2562 }
2563}
Yingyi Bu391f09e2015-10-29 13:49:39 -07002564
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002565Expression RelExpr() throws ParseException:
Yingyi Bu391f09e2015-10-29 13:49:39 -07002566{
Yingyi Bua8baf6d2016-07-05 21:40:44 -07002567 boolean not = false;
Yingyi Bu391f09e2015-10-29 13:49:39 -07002568 OperatorExpr op = null;
2569 Expression operand = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07002570 IExpressionAnnotation annotation = null;
2571}
2572{
Yingyi Bu6c638342016-09-02 17:54:34 -07002573 operand = BetweenExpr()
Yingyi Bu391f09e2015-10-29 13:49:39 -07002574
2575 (
Yingyi Bu6e6a80c2017-01-21 20:18:49 -08002576 LOOKAHEAD(2)( <LT> | <GT> | <LE> | <GE> | <EQ> | <NE> | <LG> |<SIMILAR> | (<NOT> { not = true; })? <IN>)
Yingyi Bu391f09e2015-10-29 13:49:39 -07002577 {
Dmitry Lychagine77cdac2019-08-05 11:37:47 -07002578 Token hintToken = fetchHint(token, SqlppHint.INDEXED_NESTED_LOOP_JOIN_HINT,
Shiva2ea73232019-10-09 18:04:05 -07002579 SqlppHint.SKIP_SECONDARY_INDEX_SEARCH_HINT, SqlppHint.HASH_BROADCAST_JOIN_HINT);
Dmitry Lychagine77cdac2019-08-05 11:37:47 -07002580 if (hintToken != null) {
2581 switch (hintToken.hint) {
2582 case INDEXED_NESTED_LOOP_JOIN_HINT:
Yingyi Bua8baf6d2016-07-05 21:40:44 -07002583 annotation = IndexedNLJoinExpressionAnnotation.INSTANCE;
Dmitry Lychagine77cdac2019-08-05 11:37:47 -07002584 break;
2585 case SKIP_SECONDARY_INDEX_SEARCH_HINT:
Yingyi Bua8baf6d2016-07-05 21:40:44 -07002586 annotation = SkipSecondaryIndexSearchExpressionAnnotation.INSTANCE;
Dmitry Lychagine77cdac2019-08-05 11:37:47 -07002587 break;
Shiva2ea73232019-10-09 18:04:05 -07002588 case HASH_BROADCAST_JOIN_HINT:
2589 annotation = new BroadcastExpressionAnnotation();
2590 annotation.setObject(BroadcastExpressionAnnotation.BroadcastSide.RIGHT);
Dmitry Lychagine77cdac2019-08-05 11:37:47 -07002591 break;
Yingyi Bua8baf6d2016-07-05 21:40:44 -07002592 }
Yingyi Bu391f09e2015-10-29 13:49:39 -07002593 }
Yingyi Buea4ec722016-11-04 01:26:16 -07002594
Yingyi Bua8baf6d2016-07-05 21:40:44 -07002595 String operator = token.image.toLowerCase();
Yingyi Bu4a4b8962016-09-16 12:09:11 -07002596 if (operator.equals("<>")){
2597 operator = "!=";
2598 }
2599 if (not) {
Yingyi Bua8baf6d2016-07-05 21:40:44 -07002600 operator = "not_" + operator;
2601 }
Yingyi Bu391f09e2015-10-29 13:49:39 -07002602 if (op == null) {
2603 op = new OperatorExpr();
Shiva2ea73232019-10-09 18:04:05 -07002604 op.addOperand(operand);
Yingyi Bua8baf6d2016-07-05 21:40:44 -07002605 op.setCurrentop(true);
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07002606 addSourceLocation(op, token);
Yingyi Bu391f09e2015-10-29 13:49:39 -07002607 }
Yingyi Bu196db5d2016-07-15 19:07:20 -07002608 try{
2609 op.addOperator(operator);
Taewoo Kime65e6ca2017-01-14 17:53:28 -08002610 } catch (CompilationException e){
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002611 throw new SqlppParseException(getSourceLocation(token), e.getMessage());
Yingyi Bu196db5d2016-07-15 19:07:20 -07002612 }
Yingyi Bua8baf6d2016-07-05 21:40:44 -07002613 }
Yingyi Bu391f09e2015-10-29 13:49:39 -07002614
Yingyi Bu6c638342016-09-02 17:54:34 -07002615 operand = BetweenExpr()
Yingyi Buea4ec722016-11-04 01:26:16 -07002616 {
Shiva2ea73232019-10-09 18:04:05 -07002617 op.addOperand(operand);
Yingyi Buea4ec722016-11-04 01:26:16 -07002618 }
Yingyi Bu391f09e2015-10-29 13:49:39 -07002619 )?
2620
2621 {
2622 if (annotation != null) {
2623 op.addHint(annotation);
2624 }
2625 return op==null? operand: op;
2626 }
2627}
2628
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002629Expression BetweenExpr() throws ParseException:
Yingyi Bu6c638342016-09-02 17:54:34 -07002630{
2631 boolean not = false;
2632 OperatorExpr op = null;
2633 Expression operand = null;
2634 IExpressionAnnotation annotation = null;
2635}
2636{
2637 operand = IsExpr()
2638 (
2639 LOOKAHEAD(2)
2640 (<NOT> { not = true; })? <BETWEEN>
2641 {
Dmitry Lychagine77cdac2019-08-05 11:37:47 -07002642 Token hintToken = fetchHint(token, SqlppHint.INDEXED_NESTED_LOOP_JOIN_HINT,
2643 SqlppHint.SKIP_SECONDARY_INDEX_SEARCH_HINT);
2644 if (hintToken != null) {
2645 switch (hintToken.hint) {
2646 case INDEXED_NESTED_LOOP_JOIN_HINT:
Yingyi Bu6c638342016-09-02 17:54:34 -07002647 annotation = IndexedNLJoinExpressionAnnotation.INSTANCE;
Dmitry Lychagine77cdac2019-08-05 11:37:47 -07002648 break;
2649 case SKIP_SECONDARY_INDEX_SEARCH_HINT:
Yingyi Bu6c638342016-09-02 17:54:34 -07002650 annotation = SkipSecondaryIndexSearchExpressionAnnotation.INSTANCE;
Dmitry Lychagine77cdac2019-08-05 11:37:47 -07002651 break;
Yingyi Bu6c638342016-09-02 17:54:34 -07002652 }
2653 }
2654 String operator = token.image.toLowerCase();
2655 if(not){
2656 operator = "not_" + operator;
2657 }
2658 if (op == null) {
2659 op = new OperatorExpr();
2660 op.addOperand(operand);
2661 op.setCurrentop(true);
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07002662 addSourceLocation(op, token);
Yingyi Bu6c638342016-09-02 17:54:34 -07002663 }
2664 try{
2665 op.addOperator(operator);
Taewoo Kime65e6ca2017-01-14 17:53:28 -08002666 } catch (CompilationException e){
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002667 throw new SqlppParseException(getSourceLocation(token), e.getMessage());
Yingyi Bu6c638342016-09-02 17:54:34 -07002668 }
2669 }
2670
2671 operand = IsExpr()
2672 {
2673 op.addOperand(operand);
2674 }
2675
2676 <AND>
2677 operand = IsExpr()
2678 {
Dmitry Lychaginef1719e2017-12-15 08:33:07 -08002679 op.addOperator(OperatorType.AND);
Yingyi Bu6c638342016-09-02 17:54:34 -07002680 op.addOperand(operand);
2681 }
2682 )?
2683
2684 {
2685 if (annotation != null) {
2686 op.addHint(annotation);
2687 }
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002688 return op==null ? operand: op;
Yingyi Bu6c638342016-09-02 17:54:34 -07002689 }
2690}
2691
Yingyi Budaa549c2016-06-28 22:30:52 -07002692Expression IsExpr() throws ParseException:
2693{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002694 Token notToken = null;
2695 CallExpr expr = null;
Yingyi Budaa549c2016-06-28 22:30:52 -07002696 Expression operand = null;
2697 boolean not = false;
Dmitry Lychagin7c53fcf2017-11-07 12:07:41 -08002698 FunctionIdentifier fn = null;
Yingyi Budaa549c2016-06-28 22:30:52 -07002699}
2700{
Yingyi Bu6e6a80c2017-01-21 20:18:49 -08002701 operand = LikeExpr()
Dmitry Lychagin7c53fcf2017-11-07 12:07:41 -08002702 ( <IS>
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002703 (<NOT> { not = true; notToken = token; })?
Dmitry Lychagin7c53fcf2017-11-07 12:07:41 -08002704 (
2705 <NULL> { fn = BuiltinFunctions.IS_NULL; } |
2706 <MISSING> { fn = BuiltinFunctions.IS_MISSING; } |
Dmitry Lychagin7d594a32018-01-15 14:31:03 -08002707 <UNKNOWN> { fn = BuiltinFunctions.IS_UNKNOWN; } |
Dmitry Lychagin1aa0dd42018-04-17 14:35:24 -07002708 (<KNOWN> | <VALUED>) { not = !not; fn = BuiltinFunctions.IS_UNKNOWN; }
Dmitry Lychagin7c53fcf2017-11-07 12:07:41 -08002709 )
Yingyi Budaa549c2016-06-28 22:30:52 -07002710 {
Dmitry Lychagin7c53fcf2017-11-07 12:07:41 -08002711 FunctionSignature signature = new FunctionSignature(fn);
Yingyi Budaa549c2016-06-28 22:30:52 -07002712 expr = new CallExpr(signature, new ArrayList<Expression>(Collections.singletonList(operand)));
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07002713 addSourceLocation(expr, token);
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002714 if (not) {
Dmitry Lychagin7c53fcf2017-11-07 12:07:41 -08002715 FunctionSignature notSignature = new FunctionSignature(BuiltinFunctions.NOT);
Yingyi Budaa549c2016-06-28 22:30:52 -07002716 expr = new CallExpr(notSignature, new ArrayList<Expression>(Collections.singletonList(expr)));
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07002717 addSourceLocation(expr, notToken);
Yingyi Budaa549c2016-06-28 22:30:52 -07002718 }
2719 }
2720 )?
2721 {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002722 return expr == null ? operand : expr;
Yingyi Budaa549c2016-06-28 22:30:52 -07002723 }
2724}
2725
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002726Expression LikeExpr() throws ParseException:
Yingyi Bu6e6a80c2017-01-21 20:18:49 -08002727{
2728 boolean not = false;
2729 OperatorExpr op = null;
2730 Expression operand = null;
2731}
2732{
2733 operand = ConcatExpr()
2734 (
2735 LOOKAHEAD(2)
2736 (<NOT> { not = true; })? <LIKE>
2737 {
2738 op = new OperatorExpr();
2739 op.addOperand(operand);
2740 op.setCurrentop(true);
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07002741 addSourceLocation(op, token);
Yingyi Bu6e6a80c2017-01-21 20:18:49 -08002742
2743 String operator = token.image.toLowerCase();
2744 if (not) {
2745 operator = "not_" + operator;
2746 }
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002747 try {
Yingyi Bu6e6a80c2017-01-21 20:18:49 -08002748 op.addOperator(operator);
2749 } catch (CompilationException e){
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002750 throw new SqlppParseException(getSourceLocation(token), e.getMessage());
Yingyi Bu6e6a80c2017-01-21 20:18:49 -08002751 }
2752 }
2753
2754 operand = ConcatExpr()
2755 {
2756 op.addOperand(operand);
2757 }
2758 )?
2759
2760 {
2761 return op == null ? operand : op;
2762 }
2763}
2764
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002765Expression ConcatExpr() throws ParseException:
Yingyi Bufdc71eb2016-08-24 22:41:57 -07002766{
2767 OperatorExpr op = null;
2768 Expression operand = null;
2769}
2770{
2771 operand = AddExpr()
2772 (
2773 LOOKAHEAD(1)
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002774 <CONCAT>
Yingyi Bufdc71eb2016-08-24 22:41:57 -07002775 {
2776 if (op == null) {
2777 op = new OperatorExpr();
2778 op.addOperand(operand);
2779 op.setCurrentop(true);
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07002780 addSourceLocation(op, token);
Yingyi Bufdc71eb2016-08-24 22:41:57 -07002781 }
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002782 op.addOperator(OperatorType.CONCAT);
Yingyi Bufdc71eb2016-08-24 22:41:57 -07002783 }
2784 operand = AddExpr()
2785 {
2786 op.addOperand(operand);
2787 }
2788 )*
2789
2790 {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002791 return op == null ? operand : op;
Yingyi Bufdc71eb2016-08-24 22:41:57 -07002792 }
2793}
Yingyi Budaa549c2016-06-28 22:30:52 -07002794
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002795Expression AddExpr() throws ParseException:
Yingyi Bu391f09e2015-10-29 13:49:39 -07002796{
2797 OperatorExpr op = null;
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002798 OperatorType opType = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07002799 Expression operand = null;
2800}
2801{
2802 operand = MultExpr()
Yingyi Budaa549c2016-06-28 22:30:52 -07002803 (
Yingyi Bufdc71eb2016-08-24 22:41:57 -07002804 LOOKAHEAD(1)
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002805 (<PLUS> { opType = OperatorType.PLUS; } | <MINUS> { opType = OperatorType.MINUS; } )
Yingyi Bu391f09e2015-10-29 13:49:39 -07002806 {
2807 if (op == null) {
2808 op = new OperatorExpr();
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002809 op.addOperand(operand);
2810 op.setCurrentop(true);
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07002811 addSourceLocation(op, token);
Yingyi Bu391f09e2015-10-29 13:49:39 -07002812 }
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002813 op.addOperator(opType);
Yingyi Bu391f09e2015-10-29 13:49:39 -07002814 }
2815
2816 operand = MultExpr()
2817 {
2818 op.addOperand(operand);
2819 }
2820 )*
2821
2822 {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002823 return op == null ? operand : op;
Yingyi Bu391f09e2015-10-29 13:49:39 -07002824 }
2825}
2826
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002827Expression MultExpr() throws ParseException:
Yingyi Bu391f09e2015-10-29 13:49:39 -07002828{
2829 OperatorExpr op = null;
Dmitry Lychaginbf48c492018-05-01 18:30:27 -07002830 OperatorType opType = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07002831 Expression operand = null;
2832}
2833{
Yingyi Bu79ccdac2016-07-26 23:49:24 -07002834 operand = ExponentExpr()
Yingyi Bu391f09e2015-10-29 13:49:39 -07002835
Dmitry Lychaginbf48c492018-05-01 18:30:27 -07002836 ( (
2837 <MUL> { opType = OperatorType.MUL; } |
2838 <DIVIDE> { opType = OperatorType.DIVIDE; } |
2839 <DIV> { opType = OperatorType.DIV; } |
2840 ( <MOD> | <PERCENT> ) { opType = OperatorType.MOD; }
2841 )
Yingyi Bu391f09e2015-10-29 13:49:39 -07002842 {
2843 if (op == null) {
2844 op = new OperatorExpr();
Yingyi Bu79ccdac2016-07-26 23:49:24 -07002845 op.addOperand(operand);
2846 op.setCurrentop(true);
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07002847 addSourceLocation(op, token);
Yingyi Bu79ccdac2016-07-26 23:49:24 -07002848 }
Dmitry Lychaginbf48c492018-05-01 18:30:27 -07002849 op.addOperator(opType);
Yingyi Bu79ccdac2016-07-26 23:49:24 -07002850 }
2851 operand = ExponentExpr()
2852 {
2853 op.addOperand(operand);
2854 }
2855 )*
2856
2857 {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002858 return op == null ? operand : op;
Yingyi Bu79ccdac2016-07-26 23:49:24 -07002859 }
2860}
2861
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002862Expression ExponentExpr() throws ParseException:
Yingyi Bu79ccdac2016-07-26 23:49:24 -07002863{
2864 OperatorExpr op = null;
2865 Expression operand = null;
2866}
2867{
2868 operand = UnaryExpr()
2869 (<CARET>
2870 {
2871 if (op == null) {
2872 op = new OperatorExpr();
2873 op.addOperand(operand);
2874 op.setCurrentop(true);
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07002875 addSourceLocation(op, token);
Yingyi Bu391f09e2015-10-29 13:49:39 -07002876 }
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002877 op.addOperator(OperatorType.CARET);
Yingyi Bu391f09e2015-10-29 13:49:39 -07002878 }
2879 operand = UnaryExpr()
2880 {
2881 op.addOperand(operand);
2882 }
Yingyi Bu79ccdac2016-07-26 23:49:24 -07002883 )?
2884 {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002885 return op == null ? operand : op;
Yingyi Bu79ccdac2016-07-26 23:49:24 -07002886 }
Yingyi Bu391f09e2015-10-29 13:49:39 -07002887}
2888
2889Expression UnaryExpr() throws ParseException:
2890{
Yingyi Bu196db5d2016-07-15 19:07:20 -07002891 boolean not = false;
2892 UnaryExpr uexpr = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07002893 Expression expr = null;
2894}
Yingyi Budaa549c2016-06-28 22:30:52 -07002895{
Yingyi Bu196db5d2016-07-15 19:07:20 -07002896 ( (<PLUS> | <MINUS> | (<NOT> { not = true; } )? <EXISTS> )
Yingyi Bu391f09e2015-10-29 13:49:39 -07002897 {
Yingyi Bu196db5d2016-07-15 19:07:20 -07002898 String exprType = token.image.toLowerCase();
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002899 if (not) {
Yingyi Bu196db5d2016-07-15 19:07:20 -07002900 exprType = "not_" + exprType;
2901 }
2902 uexpr = new UnaryExpr();
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07002903 addSourceLocation(uexpr, token);
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002904 try {
Yingyi Bu196db5d2016-07-15 19:07:20 -07002905 uexpr.setExprType(exprType);
Taewoo Kime65e6ca2017-01-14 17:53:28 -08002906 } catch (CompilationException e){
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002907 throw new SqlppParseException(getSourceLocation(token), e.getMessage());
Yingyi Budaa549c2016-06-28 22:30:52 -07002908 }
Yingyi Bu391f09e2015-10-29 13:49:39 -07002909 }
2910 )?
2911
2912 expr = ValueExpr()
2913 {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002914 if (uexpr == null) {
2915 return expr;
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07002916 } else {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002917 uexpr.setExpr(expr);
2918 return uexpr;
2919 }
Yingyi Bu391f09e2015-10-29 13:49:39 -07002920 }
2921}
2922
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002923Expression ValueExpr() throws ParseException:
Yingyi Bu391f09e2015-10-29 13:49:39 -07002924{
2925 Expression expr = null;
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002926 AbstractAccessor accessor = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07002927}
2928{
Hussain Towailebc5b5deb2018-12-15 18:48:48 +03002929 expr = PrimaryExpr()
2930 (
2931 accessor = FieldAccessor(accessor != null ? accessor : expr)
2932 |
2933 accessor = IndexAccessor(accessor != null ? accessor : expr)
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002934 )*
2935 {
2936 return accessor == null ? expr : accessor;
2937 }
Yingyi Bu391f09e2015-10-29 13:49:39 -07002938}
2939
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002940FieldAccessor FieldAccessor(Expression inputExpr) throws ParseException:
Yingyi Bu391f09e2015-10-29 13:49:39 -07002941{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002942 Token startToken = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07002943 String ident = null;
2944}
2945{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002946 <DOT> { startToken = token; } ident = Identifier()
Yingyi Bu391f09e2015-10-29 13:49:39 -07002947 {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002948 FieldAccessor fa = new FieldAccessor(inputExpr, new Identifier(ident));
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07002949 return addSourceLocation(fa, startToken);
Yingyi Bu391f09e2015-10-29 13:49:39 -07002950 }
2951}
2952
Hussain Towailebc5b5deb2018-12-15 18:48:48 +03002953AbstractAccessor IndexAccessor(Expression inputExpr) throws ParseException:
Yingyi Bu391f09e2015-10-29 13:49:39 -07002954{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002955 Token startToken = null;
Hussain Towailebc5b5deb2018-12-15 18:48:48 +03002956 boolean isListSliceExpression = false;
2957 AbstractAccessor resultExpression = null;
2958 Expression argumentExpression1 = null;
2959 Expression argumentExpression2 = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07002960}
2961{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002962 <LEFTBRACKET> { startToken = token; }
Hussain Towailebc5b5deb2018-12-15 18:48:48 +03002963 ( argumentExpression1 = Expression()
Yingyi Bu391f09e2015-10-29 13:49:39 -07002964 {
Hussain Towailebc5b5deb2018-12-15 18:48:48 +03002965 if (argumentExpression1.getKind() == Expression.Kind.LITERAL_EXPRESSION)
Yingyi Bu391f09e2015-10-29 13:49:39 -07002966 {
Hussain Towailebc5b5deb2018-12-15 18:48:48 +03002967 Literal lit = ((LiteralExpr)argumentExpression1).getValue();
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002968 if (lit.getLiteralType() != Literal.Type.INTEGER &&
2969 lit.getLiteralType() != Literal.Type.LONG) {
Hussain Towailebc5b5deb2018-12-15 18:48:48 +03002970 throw new SqlppParseException(argumentExpression1.getSourceLocation(), "Index should be an INTEGER");
Yingyi Bu391f09e2015-10-29 13:49:39 -07002971 }
2972 }
2973 }
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002974 )
Hussain Towailebc5b5deb2018-12-15 18:48:48 +03002975 (<COLON>
2976 {
2977 isListSliceExpression = true;
2978 }
2979 ( argumentExpression2 = Expression()
2980 {
2981 if (argumentExpression2.getKind() == Expression.Kind.LITERAL_EXPRESSION) {
2982 Literal lit = ((LiteralExpr)argumentExpression2).getValue();
2983 if (lit.getLiteralType() != Literal.Type.INTEGER &&
2984 lit.getLiteralType() != Literal.Type.LONG) {
2985 throw new SqlppParseException(argumentExpression2.getSourceLocation(), "Index should be an INTEGER");
2986 }
2987 }
2988 })?
2989 )?
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002990 <RIGHTBRACKET>
2991 {
Hussain Towailebc5b5deb2018-12-15 18:48:48 +03002992 if (!isListSliceExpression) {
2993 resultExpression = new IndexAccessor(inputExpr, argumentExpression1);
2994 } else {
2995 resultExpression = new ListSliceExpression(inputExpr, argumentExpression1, argumentExpression2);
2996 }
2997
2998 return addSourceLocation(resultExpression, startToken);
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002999 }
Yingyi Bu391f09e2015-10-29 13:49:39 -07003000}
3001
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07003002Expression PrimaryExpr() throws ParseException:
Yingyi Bu391f09e2015-10-29 13:49:39 -07003003{
3004 Expression expr = null;
3005}
3006{
Dmitry Lychagin54c06012019-11-13 15:54:20 -08003007 (
3008 LOOKAHEAD(Identifier() (<DOT> Identifier())* (<SHARP> Identifier())? <LEFTPAREN>) expr = FunctionCallExpr()
Dmitry Lychagin5fbd04b2018-04-19 16:54:28 -07003009 | expr = CaseExpr()
Yingyi Bu391f09e2015-10-29 13:49:39 -07003010 | expr = Literal()
3011 | expr = VariableRef()
Dmitry Lychagin1bdf8082018-06-13 14:48:23 -07003012 | expr = ExternalVariableRef()
Yingyi Bu391f09e2015-10-29 13:49:39 -07003013 | expr = ListConstructor()
3014 | expr = RecordConstructor()
3015 | expr = ParenthesizedExpression()
3016 )
3017 {
3018 return expr;
3019 }
3020}
3021
3022Expression Literal() throws ParseException:
3023{
3024 LiteralExpr lit = new LiteralExpr();
3025 String str = null;
3026}
3027{
3028 ( str = StringLiteral()
3029 {
3030 lit.setValue(new StringLiteral(str));
3031 }
3032 | <INTEGER_LITERAL>
3033 {
Till Westmann68c6a992016-09-30 00:19:12 -07003034 try {
3035 lit.setValue(new LongIntegerLiteral(Long.valueOf(token.image)));
3036 } catch (NumberFormatException e) {
Ali Alsuliman587b7902019-01-21 14:33:50 -08003037 throw new SqlppParseException(getSourceLocation(token), "Could not parse numeric literal \"" + LogRedactionUtil.userData(token.image) +'"');
Till Westmann68c6a992016-09-30 00:19:12 -07003038 }
Yingyi Bu391f09e2015-10-29 13:49:39 -07003039 }
3040 | <FLOAT_LITERAL>
3041 {
Till Westmann68c6a992016-09-30 00:19:12 -07003042 try {
3043 lit.setValue(new FloatLiteral(Float.valueOf(token.image)));
3044 } catch (NumberFormatException e) {
Ali Alsuliman587b7902019-01-21 14:33:50 -08003045 throw new SqlppParseException(getSourceLocation(token), "Could not parse numeric literal \"" + LogRedactionUtil.userData(token.image) +'"');
Till Westmann68c6a992016-09-30 00:19:12 -07003046 }
Yingyi Bu391f09e2015-10-29 13:49:39 -07003047 }
3048 | <DOUBLE_LITERAL>
3049 {
Till Westmann68c6a992016-09-30 00:19:12 -07003050 try {
3051 lit.setValue(new DoubleLiteral(Double.valueOf(token.image)));
3052 } catch (NumberFormatException e) {
Ali Alsuliman587b7902019-01-21 14:33:50 -08003053 throw new SqlppParseException(getSourceLocation(token), "Could not parse numeric literal \"" + LogRedactionUtil.userData(token.image) +'"');
Till Westmann68c6a992016-09-30 00:19:12 -07003054 }
Yingyi Bu391f09e2015-10-29 13:49:39 -07003055 }
Yingyi Bu535d86b2016-05-23 16:44:25 -07003056 | <MISSING>
3057 {
3058 lit.setValue(MissingLiteral.INSTANCE);
3059 }
Yingyi Bu391f09e2015-10-29 13:49:39 -07003060 | <NULL>
3061 {
3062 lit.setValue(NullLiteral.INSTANCE);
3063 }
3064 | <TRUE>
3065 {
3066 lit.setValue(TrueLiteral.INSTANCE);
3067 }
3068 | <FALSE>
3069 {
3070 lit.setValue(FalseLiteral.INSTANCE);
3071 }
3072 )
3073 {
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07003074 return addSourceLocation(lit, token);
Yingyi Bu391f09e2015-10-29 13:49:39 -07003075 }
3076}
3077
Yingyi Bu391f09e2015-10-29 13:49:39 -07003078VariableExpr VariableRef() throws ParseException:
3079{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07003080 String id = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07003081}
3082{
Dmitry Lychagin0d4c1b62020-02-07 17:10:16 -08003083 id = VariableIdentifier()
Yingyi Bu391f09e2015-10-29 13:49:39 -07003084 {
3085 Identifier ident = lookupSymbol(id);
3086 if (isInForbiddenScopes(id)) {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07003087 throw new SqlppParseException(getSourceLocation(token),
3088 "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 -07003089 }
Dmitry Lychagin75f19872019-10-03 17:56:35 -07003090 VariableExpr varExp;
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07003091 if (ident != null) { // exist such ident
Dmitry Lychagin75f19872019-10-03 17:56:35 -07003092 varExp = new VariableExpr((VarIdentifier)ident);
Yingyi Bu391f09e2015-10-29 13:49:39 -07003093 } else {
Dmitry Lychagin75f19872019-10-03 17:56:35 -07003094 varExp = new VariableExpr(new VarIdentifier(id));
Yingyi Buacc12a92016-03-26 17:25:05 -07003095 varExp.setIsNewVar(false);
Yingyi Bu391f09e2015-10-29 13:49:39 -07003096 }
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07003097 return addSourceLocation(varExp, token);
Yingyi Bu391f09e2015-10-29 13:49:39 -07003098 }
3099}
3100
Yingyi Bu391f09e2015-10-29 13:49:39 -07003101VariableExpr Variable() throws ParseException:
3102{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07003103 String id = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07003104}
3105{
Dmitry Lychagin0d4c1b62020-02-07 17:10:16 -08003106 id = VariableIdentifier()
Yingyi Bu391f09e2015-10-29 13:49:39 -07003107 {
3108 Identifier ident = lookupSymbol(id);
Dmitry Lychagin75f19872019-10-03 17:56:35 -07003109 VariableExpr varExp = new VariableExpr(new VarIdentifier(id));
3110 if (ident != null) { // exist such ident
Yingyi Bu391f09e2015-10-29 13:49:39 -07003111 varExp.setIsNewVar(false);
3112 }
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07003113 return addSourceLocation(varExp, token);
Yingyi Bu391f09e2015-10-29 13:49:39 -07003114 }
3115}
3116
Dmitry Lychagin0d4c1b62020-02-07 17:10:16 -08003117String VariableIdentifier() throws ParseException:
3118{
3119 String id = null;
3120}
3121{
3122 (<IDENTIFIER> { id = token.image; } | id = QuotedString())
3123 {
3124 return SqlppVariableUtil.toInternalVariableName(id); // prefix user-defined variables with "$".
3125 }
3126}
3127
Dmitry Lychaginf2c18aa2018-12-28 21:20:23 -08003128Pair<VariableExpr, List<Pair<Expression, Identifier>>> VariableWithFieldMap() throws ParseException:
3129{
3130 VariableExpr var = null;
3131 List<Pair<Expression, Identifier>> fieldList = new ArrayList<Pair<Expression, Identifier>>();
3132}
3133{
3134 var = Variable()
3135 ( LOOKAHEAD(1)
3136 {
3137 VariableExpr fieldVarExpr = null;
3138 String fieldIdentifierStr = null;
3139 }
3140 <LEFTPAREN>
3141 fieldVarExpr = VariableRef() <AS> fieldIdentifierStr = Identifier()
3142 {
3143 fieldList.add(new Pair<Expression, Identifier>(fieldVarExpr, new Identifier(fieldIdentifierStr)));
3144 }
3145 (<COMMA>
3146 fieldVarExpr = VariableRef() <AS> fieldIdentifierStr = Identifier()
3147 {
3148 fieldList.add(new Pair<Expression, Identifier>(fieldVarExpr, new Identifier(fieldIdentifierStr)));
3149 }
3150 )*
3151 <RIGHTPAREN>
3152 )?
3153 {
3154 return new Pair<VariableExpr, List<Pair<Expression, Identifier>>>(var, fieldList);
3155 }
3156}
3157
Dmitry Lychagin1bdf8082018-06-13 14:48:23 -07003158VariableExpr ExternalVariableRef() throws ParseException:
3159{
3160 String name = null;
3161}
3162{
3163 (
3164 (
3165 <DOLLAR>
3166 (
3167 <INTEGER_LITERAL> { name = token.image; } |
3168 <IDENTIFIER> { name = token.image; } |
3169 name = QuotedString()
3170 )
3171 )
3172 |
3173 (
3174 <QUES> { name = String.valueOf(++externalVarCounter); }
3175 )
3176 )
3177 {
3178 String idName = SqlppVariableUtil.toExternalVariableName(name);
3179 VarIdentifier id = new VarIdentifier(idName);
3180 VariableExpr varExp = new VariableExpr(id);
3181 return addSourceLocation(varExp, token);
3182 }
3183}
3184
Yingyi Bu391f09e2015-10-29 13:49:39 -07003185Expression ListConstructor() throws ParseException:
3186{
3187 Expression expr = null;
3188}
3189{
3190 (
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07003191 expr = OrderedListConstructor() |
3192 expr = UnorderedListConstructor()
Yingyi Bu391f09e2015-10-29 13:49:39 -07003193 )
Yingyi Bu391f09e2015-10-29 13:49:39 -07003194 {
3195 return expr;
3196 }
3197}
3198
Yingyi Bu391f09e2015-10-29 13:49:39 -07003199ListConstructor OrderedListConstructor() throws ParseException:
3200{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07003201 Token startToken = null;
3202 List<Expression> exprList = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07003203}
3204{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07003205 <LEFTBRACKET> { startToken = token; }
3206 exprList = ExpressionList()
3207 <RIGHTBRACKET>
3208 {
3209 ListConstructor expr = new ListConstructor(ListConstructor.Type.ORDERED_LIST_CONSTRUCTOR, exprList);
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07003210 return addSourceLocation(expr, startToken);
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07003211 }
Yingyi Bu391f09e2015-10-29 13:49:39 -07003212}
3213
3214ListConstructor UnorderedListConstructor() throws ParseException:
3215{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07003216 Token startToken = null;
3217 List<Expression> exprList = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07003218}
3219{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07003220 <LEFTDBLBRACE> { startToken = token; }
3221 exprList = ExpressionList()
3222 <RIGHTDBLBRACE>
3223 {
3224 ListConstructor expr = new ListConstructor(ListConstructor.Type.UNORDERED_LIST_CONSTRUCTOR, exprList);
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07003225 return addSourceLocation(expr, startToken);
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07003226 }
Yingyi Bu391f09e2015-10-29 13:49:39 -07003227}
3228
3229List<Expression> ExpressionList() throws ParseException:
3230{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07003231 Expression expr = null;
3232 List<Expression> exprList = new ArrayList<Expression>();
Yingyi Bu391f09e2015-10-29 13:49:39 -07003233}
3234{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07003235 (
3236 expr = Expression()
3237 {
3238 exprList.add(expr);
3239 }
3240 ( <COMMA> expr = Expression()
Till Westmann60f89982017-08-11 18:14:20 -07003241 {
3242 exprList.add(expr);
3243 }
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07003244 )*
3245 )?
3246 {
3247 return exprList;
3248 }
Yingyi Bu391f09e2015-10-29 13:49:39 -07003249}
3250
Yingyi Bu391f09e2015-10-29 13:49:39 -07003251RecordConstructor RecordConstructor() throws ParseException:
3252{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07003253 Token startToken = null;
3254 FieldBinding fb = null;
3255 List<FieldBinding> fbList = new ArrayList<FieldBinding>();
Yingyi Bu391f09e2015-10-29 13:49:39 -07003256}
3257{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07003258 <LEFTBRACE> { startToken = token; }
3259 (
3260 fb = FieldBinding() { fbList.add(fb); }
3261 (<COMMA> fb = FieldBinding() { fbList.add(fb); })*
3262 )?
3263 <RIGHTBRACE>
3264 {
3265 RecordConstructor expr = new RecordConstructor(fbList);
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07003266 return addSourceLocation(expr, startToken);
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07003267 }
Yingyi Bu391f09e2015-10-29 13:49:39 -07003268}
3269
3270FieldBinding FieldBinding() throws ParseException:
3271{
Dmitry Lychagincdcb9232019-06-04 13:27:03 -07003272 Expression left, right = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07003273}
3274{
Dmitry Lychagincdcb9232019-06-04 13:27:03 -07003275 left = Expression() ( <COLON> right = Expression() )?
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07003276 {
Dmitry Lychagincdcb9232019-06-04 13:27:03 -07003277 if (right == null) {
3278 String generatedIdentifier = ExpressionToVariableUtil.getGeneratedIdentifier(left, false);
3279 if (generatedIdentifier == null) {
3280 throw new SqlppParseException(getSourceLocation(token), "Cannot infer field name");
3281 }
3282 String generatedName = SqlppVariableUtil.toUserDefinedName(generatedIdentifier);
Ali Alsuliman5760e9e2019-08-22 16:37:36 -07003283 LiteralExpr generatedNameExpr = new LiteralExpr(new StringLiteral(generatedName));
3284 generatedNameExpr.setSourceLocation(left.getSourceLocation());
3285 return new FieldBinding(generatedNameExpr, left);
Dmitry Lychagincdcb9232019-06-04 13:27:03 -07003286 } else {
3287 return new FieldBinding(left, right);
3288 }
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07003289 }
Yingyi Bu391f09e2015-10-29 13:49:39 -07003290}
3291
Yingyi Bu391f09e2015-10-29 13:49:39 -07003292Expression FunctionCallExpr() throws ParseException:
3293{
Dmitry Lychaginfdedf622018-10-30 18:12:40 -07003294 Expression resultExpr;
Dmitry Lychaginf2c18aa2018-12-28 21:20:23 -08003295 CallExpr callExpr;
Yingyi Bu391f09e2015-10-29 13:49:39 -07003296 List<Expression> argList = new ArrayList<Expression>();
Yingyi Buf4d09842016-08-26 00:03:52 -07003297 Expression tmp = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07003298 int arity = 0;
3299 FunctionName funcName = null;
Yingyi Buf4d09842016-08-26 00:03:52 -07003300 boolean star = false;
Dmitry Lychagin7a4b5682017-09-11 18:53:07 -07003301 boolean distinct = false;
Yingyi Bu391f09e2015-10-29 13:49:39 -07003302}
3303{
3304 funcName = FunctionName()
Dmitry Lychagin7a4b5682017-09-11 18:53:07 -07003305 <LEFTPAREN> (
3306 ( <DISTINCT> { distinct = true; } )?
3307 ( tmp = Expression() | <MUL> { star = true; } )
Yingyi Bu391f09e2015-10-29 13:49:39 -07003308 {
Yingyi Buf4d09842016-08-26 00:03:52 -07003309 if(star){
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07003310 if(!funcName.function.equalsIgnoreCase("count")){
3311 throw new SqlppParseException(getSourceLocation(token), "The parameter * can only be used in COUNT().");
Yingyi Buf4d09842016-08-26 00:03:52 -07003312 }
3313 argList.add(new LiteralExpr(new LongIntegerLiteral(1L)));
3314 } else {
3315 argList.add(tmp);
3316 }
Yingyi Bu391f09e2015-10-29 13:49:39 -07003317 arity ++;
3318 }
3319 (<COMMA> tmp = Expression()
3320 {
3321 argList.add(tmp);
3322 arity++;
3323 }
3324 )*)? <RIGHTPAREN>
3325 {
Dmitry Lychagin7a4b5682017-09-11 18:53:07 -07003326 String name = funcName.function;
3327 if (distinct) {
Dmitry Lychagine5ea42d2019-03-15 11:38:09 -07003328 name += FunctionMapUtil.DISTINCT_AGGREGATE_SUFFIX;
Dmitry Lychagin7a4b5682017-09-11 18:53:07 -07003329 }
Yingyi Bu391f09e2015-10-29 13:49:39 -07003330 // TODO use funcName.library
Dmitry Lychagin7a4b5682017-09-11 18:53:07 -07003331 String fqFunctionName = funcName.library == null ? name : funcName.library + "#" + name;
Yingyi Bu391f09e2015-10-29 13:49:39 -07003332 FunctionSignature signature
3333 = lookupFunctionSignature(funcName.dataverse, fqFunctionName, arity);
3334 if (signature == null) {
3335 signature = new FunctionSignature(funcName.dataverse, fqFunctionName, arity);
3336 }
Dmitry Lychaginf2c18aa2018-12-28 21:20:23 -08003337 callExpr = FunctionMapUtil.normalizedListInputFunctions(new CallExpr(signature,argList));
Dmitry Lychagine77cdac2019-08-05 11:37:47 -07003338 if (funcName.hint != null) {
3339 switch (funcName.hint) {
3340 case INDEXED_NESTED_LOOP_JOIN_HINT:
3341 callExpr.addHint(IndexedNLJoinExpressionAnnotation.INSTANCE);
3342 break;
3343 case SKIP_SECONDARY_INDEX_SEARCH_HINT:
3344 callExpr.addHint(SkipSecondaryIndexSearchExpressionAnnotation.INSTANCE);
3345 break;
Yingyi Bu391f09e2015-10-29 13:49:39 -07003346 }
3347 }
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07003348 callExpr.setSourceLocation(funcName.sourceLoc);
Dmitry Lychaginfdedf622018-10-30 18:12:40 -07003349 resultExpr = callExpr;
Yingyi Bu391f09e2015-10-29 13:49:39 -07003350 }
Dmitry Lychaginfdedf622018-10-30 18:12:40 -07003351
Dmitry Lychagin5476f962019-05-31 16:03:11 -07003352 ( LOOKAHEAD(5) resultExpr = WindowExpr(callExpr.getFunctionSignature(), callExpr.getExprList()) )?
Dmitry Lychaginfdedf622018-10-30 18:12:40 -07003353
3354 {
3355 return resultExpr;
3356 }
Yingyi Bu391f09e2015-10-29 13:49:39 -07003357}
3358
Dmitry Lychagin5476f962019-05-31 16:03:11 -07003359WindowExpression WindowExpr(FunctionSignature signature, List<Expression> argList) throws ParseException:
3360{
3361 Boolean fromLast = null, ignoreNulls = null;
3362}
3363{
3364 (
3365 // FROM ( FIRST | LAST ) ( ( RESPECT | IGNORE ) NULLS )? OVER
3366 LOOKAHEAD(5, <FROM> <IDENTIFIER> ( <IDENTIFIER> <IDENTIFIER> )? <OVER>)
3367 <FROM> <IDENTIFIER>
3368 {
3369 if (isToken(FIRST)) {
3370 fromLast = false;
3371 } else if (isToken(LAST)) {
3372 fromLast = true;
3373 } else {
3374 throw createUnexpectedTokenError();
3375 }
3376 }
3377 )?
3378 (
3379 // ( RESPECT | IGNORE ) NULLS OVER
3380 LOOKAHEAD(3, <IDENTIFIER> <IDENTIFIER> <OVER>)
3381 <IDENTIFIER>
3382 {
3383 if (isToken(RESPECT)) {
3384 ignoreNulls = false;
3385 } else if (isToken(IGNORE)) {
3386 ignoreNulls = true;
3387 } else {
3388 throw createUnexpectedTokenError();
3389 }
3390 }
3391 <IDENTIFIER>
3392 {
3393 if (!isToken(NULLS)) {
3394 throw createUnexpectedTokenError();
3395 }
3396 }
3397 )?
3398 <OVER>
3399 {
3400 return OverClause(signature, argList, token, fromLast, ignoreNulls);
3401 }
3402}
3403
3404WindowExpression OverClause(FunctionSignature signature, List<Expression> argList, Token startToken, Boolean fromLast,
3405 Boolean ignoreNulls) throws ParseException:
Dmitry Lychaginf2c18aa2018-12-28 21:20:23 -08003406{
3407 Expression partitionExpr = null;
3408 List<Expression> partitionExprs = new ArrayList<Expression>();
3409 OrderbyClause orderByClause = null;
3410 List<Expression> orderbyList = null;
3411 List<OrderbyClause.OrderModifier> orderbyModifierList = null;
3412 WindowExpression.FrameMode frameMode = null;
3413 Pair<WindowExpression.FrameBoundaryKind, Expression> frameStart = null, frameEnd = null;
3414 WindowExpression.FrameBoundaryKind frameStartKind = null, frameEndKind = null;
3415 Expression frameStartExpr = null, frameEndExpr = null;
3416 WindowExpression.FrameExclusionKind frameExclusionKind = null;
3417 Pair<VariableExpr, List<Pair<Expression, Identifier>>> windowVarWithFieldList = null;
3418 VariableExpr windowVar = null;
3419 List<Pair<Expression, Identifier>> windowFieldList = null;
3420}
3421{
3422 (
3423 windowVarWithFieldList = VariableWithFieldMap() <AS>
3424 {
3425 windowVar = windowVarWithFieldList.first;
3426 windowFieldList = windowVarWithFieldList.second;
3427 }
3428 )?
3429 <LEFTPAREN>
3430 (
3431 <IDENTIFIER> { expectToken(PARTITION); } <BY>
3432 partitionExpr = Expression() { partitionExprs.add(partitionExpr); }
3433 ( <COMMA> partitionExpr = Expression() { partitionExprs.add(partitionExpr); } )*
3434 )?
3435 (
3436 orderByClause = OrderbyClause()
3437 {
3438 orderbyList = orderByClause.getOrderbyList();
3439 orderbyModifierList = orderByClause.getModifierList();
3440 }
3441 (
3442 frameMode = WindowFrameMode()
3443 (
3444 frameStart = WindowFrameBoundary() |
3445 ( <BETWEEN> frameStart = WindowFrameBoundary() <AND> frameEnd = WindowFrameBoundary() )
3446 )
3447 ( frameExclusionKind = WindowFrameExclusion() )?
3448 {
3449 frameStartKind = frameStart.first;
3450 frameStartExpr = frameStart.second;
3451 if (frameEnd == null) {
3452 frameEndKind = WindowExpression.FrameBoundaryKind.CURRENT_ROW;
3453 } else {
3454 frameEndKind = frameEnd.first;
3455 frameEndExpr = frameEnd.second;
3456 }
3457 if (frameExclusionKind == null) {
3458 frameExclusionKind = WindowExpression.FrameExclusionKind.NO_OTHERS;
3459 }
3460 }
3461 )?
3462 )?
3463 <RIGHTPAREN>
3464 {
3465 WindowExpression winExp = new WindowExpression(signature, argList, partitionExprs, orderbyList, orderbyModifierList,
3466 frameMode, frameStartKind, frameStartExpr, frameEndKind, frameEndExpr, frameExclusionKind, windowVar,
Dmitry Lychagin5476f962019-05-31 16:03:11 -07003467 windowFieldList, ignoreNulls, fromLast);
Dmitry Lychaginf2c18aa2018-12-28 21:20:23 -08003468 return addSourceLocation(winExp, startToken);
3469 }
3470}
3471
3472WindowExpression.FrameMode WindowFrameMode() throws ParseException:
3473{
3474}
3475{
3476 <IDENTIFIER>
3477 {
3478 if (isToken(RANGE)) {
3479 return WindowExpression.FrameMode.RANGE;
3480 } else if (isToken(ROWS)) {
3481 return WindowExpression.FrameMode.ROWS;
3482 } else if (isToken(GROUPS)) {
3483 return WindowExpression.FrameMode.GROUPS;
3484 } else {
3485 throw createUnexpectedTokenError();
3486 }
3487 }
3488}
3489
3490Pair<WindowExpression.FrameBoundaryKind, Expression> WindowFrameBoundary() throws ParseException:
3491{
3492 boolean current = false;
3493 Expression expr = null;
3494}
3495{
3496 (
Dmitry Lychagin5476f962019-05-31 16:03:11 -07003497 LOOKAHEAD({ laIdentifier(CURRENT) || laIdentifier(UNBOUNDED) }) <IDENTIFIER> { current = isToken(CURRENT); }
Dmitry Lychaginf2c18aa2018-12-28 21:20:23 -08003498 | expr = Expression()
3499 )
3500 <IDENTIFIER>
3501 {
3502 WindowExpression.FrameBoundaryKind kind;
3503 if (current && isToken(ROW)) {
3504 kind = WindowExpression.FrameBoundaryKind.CURRENT_ROW;
3505 } else if (!current && isToken(PRECEDING)) {
3506 kind = expr == null
3507 ? WindowExpression.FrameBoundaryKind.UNBOUNDED_PRECEDING
3508 : WindowExpression.FrameBoundaryKind.BOUNDED_PRECEDING;
3509 } else if (!current && isToken(FOLLOWING)) {
3510 kind = expr == null
3511 ? WindowExpression.FrameBoundaryKind.UNBOUNDED_FOLLOWING
3512 : WindowExpression.FrameBoundaryKind.BOUNDED_FOLLOWING;
3513 } else {
3514 throw createUnexpectedTokenError();
3515 }
3516 return new Pair<WindowExpression.FrameBoundaryKind, Expression>(kind, expr);
3517 }
3518}
3519
3520WindowExpression.FrameExclusionKind WindowFrameExclusion() throws ParseException:
3521{
3522 boolean current = false, no = false;
3523}
3524{
3525 <IDENTIFIER>
3526 {
3527 expectToken(EXCLUDE);
3528 }
3529 (
3530 <GROUP>
3531 {
3532 return WindowExpression.FrameExclusionKind.GROUP;
3533 }
3534 |
3535 (
3536 <IDENTIFIER>
3537 {
3538 if (isToken(TIES)) {
3539 return WindowExpression.FrameExclusionKind.TIES;
3540 } else if (isToken(CURRENT)) {
3541 current = true;
3542 } else if (isToken(NO)) {
3543 no = true;
3544 } else {
3545 throw createUnexpectedTokenError();
3546 }
3547 }
3548 <IDENTIFIER>
3549 {
3550 if (current && isToken(ROW)) {
3551 return WindowExpression.FrameExclusionKind.CURRENT_ROW;
3552 } else if (no && isToken(OTHERS)) {
3553 return WindowExpression.FrameExclusionKind.NO_OTHERS;
3554 } else {
3555 throw createUnexpectedTokenError();
3556 }
3557 }
3558 )
3559 )
3560}
3561
Yingyi Bu391f09e2015-10-29 13:49:39 -07003562Expression ParenthesizedExpression() throws ParseException:
3563{
3564 Expression expr;
3565}
3566{
3567 (
3568 LOOKAHEAD(2)
3569 <LEFTPAREN> expr = Expression() <RIGHTPAREN>
3570 |
3571 expr = Subquery()
3572 )
3573 {
3574 return expr;
3575 }
3576}
3577
Yingyi Buc8c067c2016-07-25 23:37:19 -07003578Expression CaseExpr() throws ParseException:
Yingyi Bu391f09e2015-10-29 13:49:39 -07003579{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07003580 Token startToken = null;
3581 Expression conditionExpr = null;
Yingyi Buc8c067c2016-07-25 23:37:19 -07003582 List<Expression> whenExprs = new ArrayList<Expression>();
3583 List<Expression> thenExprs = new ArrayList<Expression>();
3584 Expression elseExpr = null;
Yingyi Buc8c067c2016-07-25 23:37:19 -07003585 Expression whenExpr = null;
3586 Expression thenExpr = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07003587}
3588{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07003589 <CASE> { startToken = token; }
3590 ( conditionExpr = Expression() )?
Yingyi Buc8c067c2016-07-25 23:37:19 -07003591 (
3592 <WHEN> whenExpr = Expression()
3593 {
3594 whenExprs.add(whenExpr);
3595 }
3596 <THEN> thenExpr = Expression()
3597 {
3598 thenExprs.add(thenExpr);
3599 }
3600 )*
3601 (<ELSE> elseExpr = Expression() )?
3602 <END>
3603 {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07003604 if (conditionExpr == null) {
3605 LiteralExpr litExpr = new LiteralExpr(TrueLiteral.INSTANCE);
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07003606 conditionExpr = addSourceLocation(litExpr, startToken);
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07003607 }
3608 CaseExpression caseExpr = new CaseExpression(conditionExpr, whenExprs, thenExprs, elseExpr);
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07003609 return addSourceLocation(caseExpr, startToken);
Yingyi Buc8c067c2016-07-25 23:37:19 -07003610 }
Yingyi Bu391f09e2015-10-29 13:49:39 -07003611}
3612
Yingyi Buab817482016-08-19 21:29:31 -07003613SelectExpression SelectExpression(boolean subquery) throws ParseException:
3614{
Yingyi Bu391f09e2015-10-29 13:49:39 -07003615 List<LetClause> letClauses = new ArrayList<LetClause>();
3616 SelectSetOperation selectSetOperation;
3617 OrderbyClause orderbyClause = null;
3618 LimitClause limitClause = null;
3619 createNewScope();
Yingyi Buab817482016-08-19 21:29:31 -07003620}
3621{
Yingyi Bu391f09e2015-10-29 13:49:39 -07003622 ( letClauses = LetClause() )?
3623 selectSetOperation = SelectSetOperation()
3624 (orderbyClause = OrderbyClause() {})?
3625 (limitClause = LimitClause() {})?
3626 {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07003627 SelectExpression selectExpr =
3628 new SelectExpression(letClauses, selectSetOperation, orderbyClause, limitClause, subquery);
3629 selectExpr.setSourceLocation((!letClauses.isEmpty() ? letClauses.get(0) : selectSetOperation).getSourceLocation());
3630 return selectExpr;
Yingyi Bu391f09e2015-10-29 13:49:39 -07003631 }
3632}
3633
Yingyi Buab817482016-08-19 21:29:31 -07003634SelectSetOperation SelectSetOperation() throws ParseException:
3635{
Yingyi Bu391f09e2015-10-29 13:49:39 -07003636 SetOperationInput setOperationInputLeft;
3637 List<SetOperationRight> setOperationRights = new ArrayList<SetOperationRight>();
3638}
3639{
3640 {
3641 SelectBlock selectBlockLeft = null;
3642 SelectExpression subqueryLeft = null;
3643 Expression expr = null;
3644 }
3645 selectBlockLeft = SelectBlock()
3646 {
3647 setOperationInputLeft = new SetOperationInput(selectBlockLeft, subqueryLeft);
3648 }
3649 (
3650 {
3651 SetOpType opType = SetOpType.UNION;
3652 boolean setSemantics = true;
3653 SelectBlock selectBlockRight = null;
3654 SelectExpression subqueryRight = null;
3655 }
3656 (<UNION> {opType = SetOpType.UNION;} |<INTERSECT> {opType = SetOpType.INTERSECT;} |<EXCEPT> {opType = SetOpType.EXCEPT;}) (<ALL> {setSemantics = false;} )?
3657 (selectBlockRight = SelectBlock()| subqueryRight = Subquery())
3658 {
3659 setOperationRights.add(new SetOperationRight(opType, setSemantics, new SetOperationInput(selectBlockRight, subqueryRight)));
3660 }
3661 )*
3662 {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07003663 SelectSetOperation selectSetOp = new SelectSetOperation(setOperationInputLeft, setOperationRights);
3664 selectSetOp.setSourceLocation(selectBlockLeft.getSourceLocation());
3665 return selectSetOp;
Yingyi Bu391f09e2015-10-29 13:49:39 -07003666 }
3667}
3668
Yingyi Buab817482016-08-19 21:29:31 -07003669SelectExpression Subquery() throws ParseException:
3670{
Yingyi Bu391f09e2015-10-29 13:49:39 -07003671 SelectExpression selectExpr = null;
3672}
3673{
3674 <LEFTPAREN> selectExpr = SelectExpression(true) {} <RIGHTPAREN>
3675 {
3676 return selectExpr;
3677 }
3678}
3679
Yingyi Buab817482016-08-19 21:29:31 -07003680SelectBlock SelectBlock() throws ParseException:
3681{
Yingyi Bu391f09e2015-10-29 13:49:39 -07003682 SelectClause selectClause = null;
3683 FromClause fromClause = null;
3684 List<LetClause> fromLetClauses = null;
3685 WhereClause whereClause = null;
Dmitry Lychagin276adf92019-01-15 13:16:40 -08003686 List<AbstractClause> fromLetWhereClauses = new ArrayList<AbstractClause>();
Yingyi Bu391f09e2015-10-29 13:49:39 -07003687 GroupbyClause groupbyClause = null;
3688 List<LetClause> gbyLetClauses = null;
3689 HavingClause havingClause = null;
Dmitry Lychagin276adf92019-01-15 13:16:40 -08003690 List<AbstractClause> gbyLetHavingClauses = new ArrayList<AbstractClause>();
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07003691 SourceLocation startSrcLoc = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07003692}
3693{
3694 (
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07003695 selectClause = SelectClause() { startSrcLoc = selectClause.getSourceLocation(); }
Yingyi Bu391f09e2015-10-29 13:49:39 -07003696 (
Yingyi Bu391f09e2015-10-29 13:49:39 -07003697 (
Dmitry Lychagin368092d2019-06-06 14:39:38 -07003698 fromClause = FromClause()
3699 (
3700 fromLetClauses = LetClause()
3701 )?
3702 )
3703 |
3704 (
3705 fromLetClauses = LetClause()
3706 {
3707 // LET without FROM -> create dummy FROM clause: FROM {{missing}} AS #0
3708 SourceLocation sourceLoc = getSourceLocation(token);
3709 LiteralExpr missingExpr = new LiteralExpr(MissingLiteral.INSTANCE);
3710 missingExpr.setSourceLocation(sourceLoc);
3711 List<Expression> list = new ArrayList<Expression>(1);
3712 list.add(missingExpr);
3713 ListConstructor listExpr = new ListConstructor(ListConstructor.Type.ORDERED_LIST_CONSTRUCTOR, list);
3714 listExpr.setSourceLocation(sourceLoc);
3715 List<FromTerm> fromTerms = new ArrayList<FromTerm>(1);
3716 VariableExpr fromVar = new VariableExpr(new VarIdentifier("#0"));
3717 fromVar.setSourceLocation(sourceLoc);
3718 fromTerms.add(new FromTerm(listExpr, fromVar, null, new ArrayList<AbstractBinaryCorrelateClause>()));
3719 fromClause = new FromClause(fromTerms);
3720 }
3721 )
Yingyi Bu391f09e2015-10-29 13:49:39 -07003722 )?
3723 (whereClause = WhereClause())?
3724 (
3725 groupbyClause = GroupbyClause()
3726 (
Yingyi Bu391f09e2015-10-29 13:49:39 -07003727 gbyLetClauses = LetClause()
3728 )?
3729 (havingClause = HavingClause())?
3730 )?
3731 |
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07003732 fromClause = FromClause() { startSrcLoc = fromClause.getSourceLocation(); }
Yingyi Bu391f09e2015-10-29 13:49:39 -07003733 (
Yingyi Bu391f09e2015-10-29 13:49:39 -07003734 fromLetClauses = LetClause()
3735 )?
3736 (whereClause = WhereClause())?
3737 (
3738 groupbyClause = GroupbyClause()
3739 (
3740 gbyLetClauses = LetClause()
3741 )?
3742 (havingClause = HavingClause())?
3743 )?
3744 selectClause = SelectClause()
3745 )
3746 {
Dmitry Lychagin276adf92019-01-15 13:16:40 -08003747 if (fromLetClauses != null) {
3748 fromLetWhereClauses.addAll(fromLetClauses);
3749 }
3750 if (whereClause != null) {
3751 fromLetWhereClauses.add(whereClause);
3752 }
3753 if (gbyLetClauses != null) {
3754 gbyLetHavingClauses.addAll(gbyLetClauses);
3755 }
3756 if (havingClause != null) {
3757 gbyLetHavingClauses.add(havingClause);
3758 }
3759 SelectBlock selectBlock = new SelectBlock(selectClause, fromClause, fromLetWhereClauses, groupbyClause,
3760 gbyLetHavingClauses);
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07003761 selectBlock.setSourceLocation(startSrcLoc);
3762 return selectBlock;
Yingyi Bu391f09e2015-10-29 13:49:39 -07003763 }
3764}
3765
Yingyi Buab817482016-08-19 21:29:31 -07003766SelectClause SelectClause() throws ParseException:
3767{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07003768 Token startToken = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07003769 SelectRegular selectRegular = null;
3770 SelectElement selectElement = null;
3771 boolean distinct = false;
3772}
3773{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07003774 <SELECT> { startToken = token; } (<ALL>|<DISTINCT> { distinct = true; } )?
Yingyi Bu391f09e2015-10-29 13:49:39 -07003775 (
3776 selectRegular = SelectRegular()
Michael Blowd6cf6412016-06-30 02:44:35 -04003777 |
Yingyi Bu391f09e2015-10-29 13:49:39 -07003778 selectElement = SelectElement()
Yingyi Bua89fae62016-07-06 07:58:55 -07003779 )?
Yingyi Bu391f09e2015-10-29 13:49:39 -07003780 {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07003781 SourceLocation sourceLoc = getSourceLocation(startToken);
3782 if (selectRegular == null && selectElement == null){
Yingyi Bua89fae62016-07-06 07:58:55 -07003783 Projection projection = new Projection(null, null, true, false);
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07003784 projection.setSourceLocation(sourceLoc);
Yingyi Bua89fae62016-07-06 07:58:55 -07003785 List<Projection> projections = new ArrayList<Projection>();
3786 projections.add(projection);
3787 selectRegular = new SelectRegular(projections);
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07003788 selectRegular.setSourceLocation(sourceLoc);
Yingyi Bua89fae62016-07-06 07:58:55 -07003789 }
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07003790 SelectClause selectClause = new SelectClause(selectElement, selectRegular, distinct);
3791 selectClause.setSourceLocation(sourceLoc);
3792 return selectClause;
Yingyi Bu391f09e2015-10-29 13:49:39 -07003793 }
3794}
3795
Yingyi Buab817482016-08-19 21:29:31 -07003796SelectRegular SelectRegular() throws ParseException:
3797{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07003798 SourceLocation startSrcLoc = null;
Michael Blowd6cf6412016-06-30 02:44:35 -04003799 List<Projection> projections = new ArrayList<Projection>();
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07003800 Projection projection = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07003801}
3802{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07003803 projection = Projection()
Yingyi Bu391f09e2015-10-29 13:49:39 -07003804 {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07003805 projections.add(projection);
3806 startSrcLoc = projection.getSourceLocation();
3807 }
3808 ( LOOKAHEAD(2) <COMMA> projection = Projection()
3809 {
3810 projections.add(projection);
3811 }
3812 )*
3813 {
3814 SelectRegular selectRegular = new SelectRegular(projections);
3815 selectRegular.setSourceLocation(startSrcLoc);
3816 return selectRegular;
Yingyi Bu391f09e2015-10-29 13:49:39 -07003817 }
3818}
3819
Yingyi Buab817482016-08-19 21:29:31 -07003820SelectElement SelectElement() throws ParseException:
3821{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07003822 Token startToken = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07003823 Expression expr = null;
3824 String name = null;
3825}
3826{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07003827 (<RAW>|<ELEMENT>|<VALUE>) { startToken = token; } expr = Expression()
Yingyi Bu391f09e2015-10-29 13:49:39 -07003828 {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07003829 SelectElement selectElement = new SelectElement(expr);
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07003830 return addSourceLocation(selectElement, startToken);
Yingyi Bu391f09e2015-10-29 13:49:39 -07003831 }
3832}
3833
Yingyi Buab817482016-08-19 21:29:31 -07003834Projection Projection() throws ParseException :
3835{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07003836 SourceLocation startSrcLoc = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07003837 Expression expr = null;
3838 Identifier identifier = null;
3839 String name = null;
3840 boolean star = false;
Dmitry Lychagin5cdaa5d2018-02-21 11:11:26 -08003841 boolean varStar = false;
Yingyi Bu391f09e2015-10-29 13:49:39 -07003842}
3843{
3844 (
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07003845 <MUL> { star = true; startSrcLoc = getSourceLocation(token); }
3846 | LOOKAHEAD(3) expr = VariableRef() <DOT> <MUL> { varStar = true; }
Dmitry Lychagin5cdaa5d2018-02-21 11:11:26 -08003847 | expr = Expression() ((<AS>)? name = Identifier())?
3848 {
3849 if (name == null) {
3850 String generatedColumnIdentifier = ExpressionToVariableUtil.getGeneratedIdentifier(expr, false);
3851 if (generatedColumnIdentifier != null) {
3852 name = SqlppVariableUtil.toUserDefinedName(generatedColumnIdentifier);
3853 }
3854 }
3855 }
Yingyi Bu391f09e2015-10-29 13:49:39 -07003856 )
3857 {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07003858 Projection projection = new Projection(expr, name, star, varStar);
3859 projection.setSourceLocation(expr != null ? expr.getSourceLocation() : startSrcLoc);
3860 return projection;
Yingyi Bu391f09e2015-10-29 13:49:39 -07003861 }
3862}
3863
3864FromClause FromClause() throws ParseException :
3865{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07003866 Token startToken = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07003867 List<FromTerm> fromTerms = new ArrayList<FromTerm>();
3868 extendCurrentScope();
3869}
3870{
3871 {
3872 FromTerm fromTerm = null;
3873 }
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07003874 <FROM> { startToken = token; } fromTerm = FromTerm() { fromTerms.add(fromTerm); }
Yingyi Bu391f09e2015-10-29 13:49:39 -07003875 (LOOKAHEAD(2) <COMMA> fromTerm = FromTerm() { fromTerms.add(fromTerm); } )*
3876 {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07003877 FromClause fromClause = new FromClause(fromTerms);
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07003878 return addSourceLocation(fromClause, startToken);
Yingyi Bu391f09e2015-10-29 13:49:39 -07003879 }
3880}
3881
3882FromTerm FromTerm() throws ParseException :
3883{
3884 Expression leftExpr = null;
Michael Blowd6cf6412016-06-30 02:44:35 -04003885 VariableExpr leftVar = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07003886 VariableExpr posVar = null;
3887 List<AbstractBinaryCorrelateClause> correlateClauses = new ArrayList<AbstractBinaryCorrelateClause>();
3888}
3889{
Yingyi Bu9e3f9be2016-07-01 10:07:37 -07003890 leftExpr = Expression() ((<AS>)? leftVar = Variable())? (<AT> posVar = Variable())?
Yingyi Bu391f09e2015-10-29 13:49:39 -07003891 (
3892 {JoinType joinType = JoinType.INNER; }
3893 (joinType = JoinType())?
3894 {
3895 AbstractBinaryCorrelateClause correlateClause = null;
3896 }
3897 (correlateClause = JoinClause(joinType)
Yingyi Bu6d999ed2016-07-13 11:59:06 -07003898 | correlateClause = UnnestClause(joinType)
Yingyi Bu391f09e2015-10-29 13:49:39 -07003899 )
3900 {
3901 correlateClauses.add(correlateClause);
3902 }
3903 )*
3904 {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07003905 if (leftVar == null) {
Yingyi Bu5b2d4c82016-07-13 17:56:48 -07003906 leftVar = ExpressionToVariableUtil.getGeneratedVariable(leftExpr, true);
Yingyi Bu9e3f9be2016-07-01 10:07:37 -07003907 }
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07003908 FromTerm fromTerm = new FromTerm(leftExpr, leftVar, posVar, correlateClauses);
3909 fromTerm.setSourceLocation(leftExpr.getSourceLocation());
3910 return fromTerm;
Yingyi Bu391f09e2015-10-29 13:49:39 -07003911 }
3912}
3913
3914JoinClause JoinClause(JoinType joinType) throws ParseException :
3915{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07003916 Token startToken = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07003917 Expression rightExpr = null;
3918 VariableExpr rightVar = null;
3919 VariableExpr posVar = null;
3920 Expression conditionExpr = null;
3921}
3922{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07003923 <JOIN> { startToken = token; } rightExpr = Expression() ((<AS>)? rightVar = Variable())? (<AT> posVar = Variable())? <ON> conditionExpr = Expression()
Yingyi Bu391f09e2015-10-29 13:49:39 -07003924 {
Yingyi Bu9e3f9be2016-07-01 10:07:37 -07003925 if(rightVar==null){
Yingyi Bu5b2d4c82016-07-13 17:56:48 -07003926 rightVar = ExpressionToVariableUtil.getGeneratedVariable(rightExpr, true);
Yingyi Bu9e3f9be2016-07-01 10:07:37 -07003927 }
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07003928 JoinClause joinClause = new JoinClause(joinType, rightExpr, rightVar, posVar, conditionExpr);
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07003929 return addSourceLocation(joinClause, startToken);
Yingyi Bu391f09e2015-10-29 13:49:39 -07003930 }
3931}
3932
Yingyi Bu391f09e2015-10-29 13:49:39 -07003933UnnestClause UnnestClause(JoinType joinType) throws ParseException :
3934{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07003935 Token startToken = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07003936 Expression rightExpr;
3937 VariableExpr rightVar;
3938 VariableExpr posVar = null;
3939}
3940{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07003941 (<UNNEST>|<CORRELATE>|<FLATTEN>) { startToken = token; } rightExpr = Expression() ((<AS>)? rightVar = Variable()) (<AT> posVar = Variable())?
Yingyi Bu391f09e2015-10-29 13:49:39 -07003942 {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07003943 if (rightVar == null) {
3944 rightVar = ExpressionToVariableUtil.getGeneratedVariable(rightExpr, true);
Yingyi Bu9e3f9be2016-07-01 10:07:37 -07003945 }
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07003946 UnnestClause unnestClause = new UnnestClause(joinType, rightExpr, rightVar, posVar);
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07003947 return addSourceLocation(unnestClause, startToken);
Yingyi Bu391f09e2015-10-29 13:49:39 -07003948 }
3949}
3950
Yingyi Bu391f09e2015-10-29 13:49:39 -07003951JoinType JoinType() throws ParseException :
3952{
3953 JoinType joinType = JoinType.INNER;
3954}
3955{
3956 (<INNER>|<LEFT> (<OUTER>)? {joinType = JoinType.LEFTOUTER; })
3957 {
3958 return joinType;
3959 }
3960}
3961
3962List<LetClause> LetClause() throws ParseException:
3963{
3964 List<LetClause> letList = new ArrayList<LetClause>();
3965 LetClause letClause;
3966}
3967{
3968 (
3969 (<LET>|<LETTING>) letClause = LetElement() { letList.add(letClause); } (LOOKAHEAD(1) <COMMA> letClause = LetElement() { letList.add(letClause); })*
3970 |
3971 <WITH> letClause = WithElement() { letList.add(letClause); } (LOOKAHEAD(1) <COMMA> letClause = WithElement() { letList.add(letClause); })*
3972 )
3973 {
3974 return letList;
3975 }
3976}
3977
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07003978WhereClause WhereClause() throws ParseException :
Yingyi Bu391f09e2015-10-29 13:49:39 -07003979{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07003980 Token startToken = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07003981 Expression whereExpr;
3982}
3983{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07003984 <WHERE> { startToken = token; } whereExpr = Expression()
Yingyi Bu391f09e2015-10-29 13:49:39 -07003985 {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07003986 WhereClause wc = new WhereClause(whereExpr);
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07003987 return addSourceLocation(wc, startToken);
Yingyi Bu391f09e2015-10-29 13:49:39 -07003988 }
3989}
3990
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07003991OrderbyClause OrderbyClause() throws ParseException :
Yingyi Bu391f09e2015-10-29 13:49:39 -07003992{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07003993 Token startToken = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07003994 OrderbyClause oc = new OrderbyClause();
3995 Expression orderbyExpr;
3996 List<Expression> orderbyList = new ArrayList<Expression>();
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07003997 List<OrderbyClause.OrderModifier> modifierList = new ArrayList<OrderbyClause.OrderModifier>();
Yingyi Bu391f09e2015-10-29 13:49:39 -07003998 int numOfOrderby = 0;
3999}
4000{
4001 <ORDER>
4002 {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07004003 startToken = token;
Dmitry Lychagine77cdac2019-08-05 11:37:47 -07004004 Token hintToken = fetchHint(token, SqlppHint.INMEMORY_HINT, SqlppHint.RANGE_HINT);
4005 if (hintToken != null) {
4006 switch (hintToken.hint) {
4007 case INMEMORY_HINT:
4008 String[] splits = hintToken.hintParams.split("\\s+");
4009 int numFrames = Integer.parseInt(splits[0]);
4010 int numTuples = Integer.parseInt(splits[1]);
4011 oc.setNumFrames(numFrames);
4012 oc.setNumTuples(numTuples);
4013 break;
4014 case RANGE_HINT:
4015 try {
4016 oc.setRangeMap(RangeMapBuilder.parseHint(parseExpression(hintToken.hintParams)));
4017 } catch (CompilationException e) {
4018 throw new SqlppParseException(getSourceLocation(hintToken), e.getMessage());
4019 }
4020 break;
Ali Alsuliman80225e22018-10-15 14:17:07 -07004021 }
Yingyi Bu391f09e2015-10-29 13:49:39 -07004022 }
4023 }
4024 <BY> orderbyExpr = Expression()
4025 {
4026 orderbyList.add(orderbyExpr);
4027 OrderbyClause.OrderModifier modif = OrderbyClause.OrderModifier.ASC;
4028 }
4029 ( (<ASC> { modif = OrderbyClause.OrderModifier.ASC; })
4030 | (<DESC> { modif = OrderbyClause.OrderModifier.DESC; }))?
4031 {
4032 modifierList.add(modif);
4033 }
4034
4035 (LOOKAHEAD(2) <COMMA> orderbyExpr = Expression()
4036 {
4037 orderbyList.add(orderbyExpr);
4038 modif = OrderbyClause.OrderModifier.ASC;
4039 }
4040 ( (<ASC> { modif = OrderbyClause.OrderModifier.ASC; })
4041 | (<DESC> { modif = OrderbyClause.OrderModifier.DESC; }))?
4042 {
4043 modifierList.add(modif);
4044 }
4045 )*
4046
4047 {
4048 oc.setModifierList(modifierList);
4049 oc.setOrderbyList(orderbyList);
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07004050 return addSourceLocation(oc, startToken);
Yingyi Bu391f09e2015-10-29 13:49:39 -07004051 }
4052}
4053
4054GroupbyClause GroupbyClause()throws ParseException :
4055{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07004056 Token startToken = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07004057 GroupbyClause gbc = new GroupbyClause();
Dmitry Lychaginac98f482020-03-31 12:26:40 -07004058 List<List<GbyVariableExpressionPair>> gbyList = null;
4059 List<GroupingElement> groupingElementList = null;
Dmitry Lychaginf2c18aa2018-12-28 21:20:23 -08004060 Pair<VariableExpr, List<Pair<Expression, Identifier>>> groupVarWithFieldList = null;
Yingyi Buacc12a92016-03-26 17:25:05 -07004061 VariableExpr groupVar = null;
Dmitry Lychaginf2c18aa2018-12-28 21:20:23 -08004062 List<Pair<Expression, Identifier>> groupFieldList = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07004063}
4064{
Dmitry Lychaginac98f482020-03-31 12:26:40 -07004065 {
4066 Scope newScope = extendCurrentScopeNoPush(true);
4067 // extendCurrentScope(true);
4068 }
Yingyi Bu391f09e2015-10-29 13:49:39 -07004069 <GROUP>
Dmitry Lychaginac98f482020-03-31 12:26:40 -07004070 {
4071 startToken = token;
4072 Token hintToken = fetchHint(token, SqlppHint.HASH_GROUP_BY_HINT);
4073 if (hintToken != null) {
4074 gbc.setHashGroupByHint(true);
Yingyi Bu391f09e2015-10-29 13:49:39 -07004075 }
Dmitry Lychaginac98f482020-03-31 12:26:40 -07004076 }
4077 <BY> groupingElementList = GroupingElementList()
4078 (
4079 <GROUP> <AS> groupVarWithFieldList = VariableWithFieldMap()
Dmitry Lychaginf2c18aa2018-12-28 21:20:23 -08004080 {
4081 groupVar = groupVarWithFieldList.first;
4082 groupFieldList = groupVarWithFieldList.second;
4083 }
Yingyi Buacc12a92016-03-26 17:25:05 -07004084 )?
Yingyi Bu391f09e2015-10-29 13:49:39 -07004085 {
Dmitry Lychaginac98f482020-03-31 12:26:40 -07004086 if (groupingSetsParser == null) {
4087 groupingSetsParser = new SqlppGroupingSetsParser();
4088 }
4089 SourceLocation sourceLoc = getSourceLocation(startToken);
4090 try {
4091 gbyList = groupingSetsParser.parse(groupingElementList, sourceLoc);
4092 } catch (CompilationException e) {
4093 throw new SqlppParseException(sourceLoc, e.getMessage());
4094 }
4095 gbc.setGbyPairList(gbyList);
Yingyi Bu391f09e2015-10-29 13:49:39 -07004096 gbc.setDecorPairList(new ArrayList<GbyVariableExpressionPair>());
Yingyi Bu8671ddf2016-08-14 23:58:43 -07004097 gbc.setWithVarMap(new HashMap<Expression, VariableExpr>());
Yingyi Buacc12a92016-03-26 17:25:05 -07004098 gbc.setGroupVar(groupVar);
4099 gbc.setGroupFieldList(groupFieldList);
Yingyi Bu391f09e2015-10-29 13:49:39 -07004100 replaceCurrentScope(newScope);
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07004101 return addSourceLocation(gbc, startToken);
Yingyi Bu391f09e2015-10-29 13:49:39 -07004102 }
4103}
4104
Dmitry Lychaginac98f482020-03-31 12:26:40 -07004105List<GroupingElement> GroupingElementList() throws ParseException:
4106{
4107 List<GroupingElement> groupingElementList = new ArrayList<GroupingElement>();
4108 GroupingElement groupingElement = null;
4109}
4110{
4111 groupingElement = GroupingElement() { groupingElementList.add(groupingElement); }
4112 ( LOOKAHEAD(1) <COMMA> groupingElement = GroupingElement() { groupingElementList.add(groupingElement); } )*
4113 {
4114 return groupingElementList;
4115 }
4116}
4117
4118GroupingElement GroupingElement() throws ParseException:
4119{
4120 GroupingElement groupingElement = null;
4121 List<GroupingSet> groupingSets = null;
4122 List<GroupingElement> groupingElements = null;
4123}
4124{
4125 (
4126 LOOKAHEAD(2)
4127 <LEFTPAREN> <RIGHTPAREN>
4128 {
4129 groupingElement = GroupingSet.EMPTY;
4130 }
4131 |
4132 LOOKAHEAD({ laIdentifier(ROLLUP) && laToken(2, LEFTPAREN) })
4133 <IDENTIFIER> { expectToken(ROLLUP); }
4134 <LEFTPAREN> groupingSets = OrdinaryGroupingSetList() <RIGHTPAREN>
4135 {
4136 groupingElement = new RollupCube(groupingSets, false);
4137 }
4138 |
4139 LOOKAHEAD({ laIdentifier(CUBE) && laToken(2, LEFTPAREN) })
4140 <IDENTIFIER> { expectToken(CUBE); }
4141 <LEFTPAREN> groupingSets = OrdinaryGroupingSetList() <RIGHTPAREN>
4142 {
4143 groupingElement = new RollupCube(groupingSets, true);
4144 }
4145 |
4146 LOOKAHEAD({ laIdentifier(GROUPING) && laIdentifier(2, SETS) && laToken(3, LEFTPAREN) })
4147 <IDENTIFIER> { expectToken(GROUPING); } <IDENTIFIER> { expectToken(SETS); }
4148 <LEFTPAREN> groupingElements = GroupingElementList() <RIGHTPAREN>
4149 {
4150 groupingElement = new GroupingSets(groupingElements);
4151 }
4152 |
4153 groupingElement = OrdinaryGroupingSet()
4154 )
4155 {
4156 return groupingElement;
4157 }
4158}
4159
4160GroupingSet OrdinaryGroupingSet() throws ParseException:
4161{
4162 GbyVariableExpressionPair gbyExprPair = null;
4163 List<GbyVariableExpressionPair> items = null;
4164}
4165{
4166 (
4167 LOOKAHEAD(1) <LEFTPAREN> items = GbyVariableExpressionPairList() <RIGHTPAREN>
4168 | gbyExprPair = GbyVariableExpressionPair() { items = Collections.singletonList(gbyExprPair); }
4169 )
4170 {
4171 return new GroupingSet(items);
4172 }
4173}
4174
4175List<GroupingSet> OrdinaryGroupingSetList() throws ParseException:
4176{
4177 GroupingSet groupingSet = null;
4178 List<GroupingSet> items = new ArrayList<GroupingSet>();
4179}
4180{
4181 groupingSet = OrdinaryGroupingSet() { items.add(groupingSet); }
4182 ( LOOKAHEAD(1) <COMMA> groupingSet = OrdinaryGroupingSet() { items.add(groupingSet); } )*
4183 {
4184 return items;
4185 }
4186}
4187
4188List<GbyVariableExpressionPair> GbyVariableExpressionPairList() throws ParseException:
4189{
4190 GbyVariableExpressionPair gbyExprPair = null;
4191 List<GbyVariableExpressionPair> items = new ArrayList<GbyVariableExpressionPair>();
4192}
4193{
4194 gbyExprPair = GbyVariableExpressionPair() { items.add(gbyExprPair); }
4195 ( LOOKAHEAD(1) <COMMA> gbyExprPair = GbyVariableExpressionPair() { items.add(gbyExprPair); } )*
4196 {
4197 return items;
4198 }
4199}
4200
4201GbyVariableExpressionPair GbyVariableExpressionPair() throws ParseException:
4202{
4203 Expression expr = null;
4204 VariableExpr var = null;
4205}
4206{
4207 expr = Expression() ( (<AS>)? var = Variable() )?
4208 {
4209 return new GbyVariableExpressionPair(var, expr);
4210 }
4211}
4212
Yingyi Bu391f09e2015-10-29 13:49:39 -07004213HavingClause HavingClause() throws ParseException:
4214{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07004215 Token startToken = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07004216 Expression filterExpr = null;
4217}
4218{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07004219 <HAVING> { startToken = token; } filterExpr = Expression()
Yingyi Bu391f09e2015-10-29 13:49:39 -07004220 {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07004221 HavingClause havingClause = new HavingClause(filterExpr);
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07004222 return addSourceLocation(havingClause, startToken);
Yingyi Bu391f09e2015-10-29 13:49:39 -07004223 }
4224}
4225
4226LimitClause LimitClause() throws ParseException:
4227{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07004228 Token startToken = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07004229 LimitClause lc = new LimitClause();
4230 Expression expr;
4231 pushForbiddenScope(getCurrentScope());
4232}
4233{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07004234 <LIMIT> { startToken = token; } expr = Expression() { lc.setLimitExpr(expr); }
4235 (<OFFSET> expr = Expression() { lc.setOffset(expr); })?
Yingyi Bu391f09e2015-10-29 13:49:39 -07004236
4237 {
4238 popForbiddenScope();
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07004239 return addSourceLocation(lc, startToken);
Yingyi Bu391f09e2015-10-29 13:49:39 -07004240 }
4241}
4242
4243QuantifiedExpression QuantifiedExpression()throws ParseException:
4244{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07004245 Token startToken = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07004246 QuantifiedExpression qc = new QuantifiedExpression();
4247 List<QuantifiedPair> quantifiedList = new ArrayList<QuantifiedPair>();
4248 Expression satisfiesExpr;
4249 VariableExpr var;
4250 Expression inExpr;
4251 QuantifiedPair pair;
4252}
4253{
4254 {
4255 createNewScope();
4256 }
4257
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07004258 ( ((<ANY>|<SOME>) { startToken = token; qc.setQuantifier(QuantifiedExpression.Quantifier.SOME); })
4259 | (<EVERY> { startToken = token; qc.setQuantifier(QuantifiedExpression.Quantifier.EVERY); }))
Yingyi Bu391f09e2015-10-29 13:49:39 -07004260 var = Variable() <IN> inExpr = Expression()
4261 {
4262 pair = new QuantifiedPair(var, inExpr);
Yingyi Bu391f09e2015-10-29 13:49:39 -07004263 quantifiedList.add(pair);
4264 }
4265 (
4266 <COMMA> var = Variable() <IN> inExpr = Expression()
4267 {
4268 pair = new QuantifiedPair(var, inExpr);
Yingyi Bu391f09e2015-10-29 13:49:39 -07004269 quantifiedList.add(pair);
4270 }
4271 )*
Yingyi Bu858efae2016-10-13 17:31:57 -07004272 <SATISFIES> satisfiesExpr = Expression() (<END>)?
Yingyi Bu391f09e2015-10-29 13:49:39 -07004273 {
4274 qc.setSatisfiesExpr(satisfiesExpr);
4275 qc.setQuantifiedList(quantifiedList);
4276 removeCurrentScope();
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07004277 return addSourceLocation(qc, startToken);
Yingyi Bu391f09e2015-10-29 13:49:39 -07004278 }
4279}
4280
4281LetClause LetElement() throws ParseException:
4282{
Yingyi Bu391f09e2015-10-29 13:49:39 -07004283 VariableExpr varExp;
4284 Expression beExp;
4285 extendCurrentScope();
4286}
4287{
4288 varExp = Variable() <EQ> beExp = Expression()
4289 {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07004290 LetClause lc = new LetClause(varExp, beExp);
4291 lc.setSourceLocation(varExp.getSourceLocation());
Yingyi Bu391f09e2015-10-29 13:49:39 -07004292 return lc;
4293 }
4294}
4295
4296LetClause WithElement() throws ParseException:
4297{
Yingyi Bu391f09e2015-10-29 13:49:39 -07004298 VariableExpr varExp;
4299 Expression beExp;
4300 extendCurrentScope();
4301}
4302{
4303 varExp = Variable() <AS> beExp = Expression()
4304 {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07004305 LetClause lc = new LetClause(varExp, beExp);
4306 lc.setSourceLocation(varExp.getSourceLocation());
Yingyi Bu391f09e2015-10-29 13:49:39 -07004307 return lc;
4308 }
4309}
4310
4311TOKEN_MGR_DECLS:
4312{
4313 public int commentDepth = 0;
Till Westmanne9b2adf2016-10-15 12:39:01 -07004314 public ArrayDeque<Integer> lexerStateStack = new ArrayDeque<Integer>();
Dmitry Lychagine77cdac2019-08-05 11:37:47 -07004315 public Map<SourceLocation, String> hintCollector;
Yingyi Bu391f09e2015-10-29 13:49:39 -07004316
4317 public void pushState() {
4318 lexerStateStack.push( curLexState );
4319 }
4320
4321 public void popState(String token) {
4322 if (lexerStateStack.size() > 0) {
4323 SwitchTo( lexerStateStack.pop() );
4324 } else {
4325 int errorLine = input_stream.getEndLine();
4326 int errorColumn = input_stream.getEndColumn();
4327 String msg = "Lexical error at line " + errorLine + ", column " + errorColumn + ". Encountered \"" + token
4328 + "\" but state stack is empty.";
4329 throw new TokenMgrError(msg, -1);
4330 }
4331 }
Dmitry Lychagine77cdac2019-08-05 11:37:47 -07004332
4333 void CommonTokenAction(Token token) {
4334 Token hintToken = token.specialToken;
4335 if (hintToken != null) {
4336 hintToken.sourceLocation = new SourceLocation(hintToken.beginLine, hintToken.beginColumn);
4337 String text = hintToken.image.substring(1).trim();
4338 boolean hintFound = hintToken.parseHint(text);
4339 hintCollector.put(hintToken.sourceLocation, hintFound ? hintToken.hint.getIdentifier() : hintToken.hintParams);
4340 }
4341 }
Yingyi Bu391f09e2015-10-29 13:49:39 -07004342}
4343
4344<DEFAULT,IN_DBL_BRACE>
4345TOKEN [IGNORE_CASE]:
4346{
Ian Maxon38fe9402020-01-29 19:27:40 -08004347 <ADAPTER: "adapter">
4348 | <ALL : "all">
Yingyi Bu391f09e2015-10-29 13:49:39 -07004349 | <AND : "and">
Yingyi Bu8aac7242016-09-13 23:14:09 -07004350 | <ANY : "any">
Yingyi Bu391f09e2015-10-29 13:49:39 -07004351 | <APPLY : "apply">
4352 | <AS : "as">
4353 | <ASC : "asc">
4354 | <AT : "at">
4355 | <AUTOGENERATED : "autogenerated">
Yingyi Bua8baf6d2016-07-05 21:40:44 -07004356 | <BETWEEN : "between">
Yingyi Bu391f09e2015-10-29 13:49:39 -07004357 | <BTREE : "btree">
4358 | <BY : "by">
4359 | <CASE : "case">
4360 | <CLOSED : "closed">
4361 | <CREATE : "create">
4362 | <COMPACTION : "compaction">
4363 | <COMPACT : "compact">
4364 | <CONNECT : "connect">
4365 | <CORRELATE : "correlate">
Yingyi Bud56ff032016-08-01 10:26:57 -07004366 | <DATASET : "dataset">
Yingyi Bu1c0fff52016-03-25 20:23:30 -07004367 | <COLLECTION : "collection">
Yingyi Bud56ff032016-08-01 10:26:57 -07004368 | <DATAVERSE : "dataverse">
Yingyi Bu391f09e2015-10-29 13:49:39 -07004369 | <DECLARE : "declare">
4370 | <DEFINITION : "definition">
4371 | <DELETE : "delete">
4372 | <DESC : "desc">
4373 | <DISCONNECT : "disconnect">
4374 | <DISTINCT : "distinct">
Murtadha Hubail29f63912019-04-21 14:23:57 +03004375 | <DIV : "div">
Yingyi Bu391f09e2015-10-29 13:49:39 -07004376 | <DROP : "drop">
4377 | <ELEMENT : "element">
Till Westmann516d1a82016-08-02 14:45:53 -07004378 | <EXPLAIN : "explain">
Yingyi Bu391f09e2015-10-29 13:49:39 -07004379 | <ELSE : "else">
4380 | <ENFORCED : "enforced">
Yingyi Buc8c067c2016-07-25 23:37:19 -07004381 | <END : "end">
Yingyi Bu391f09e2015-10-29 13:49:39 -07004382 | <EVERY : "every">
4383 | <EXCEPT : "except">
4384 | <EXISTS : "exists">
4385 | <EXTERNAL : "external">
4386 | <FEED : "feed">
4387 | <FILTER : "filter">
4388 | <FLATTEN : "flatten">
4389 | <FOR : "for">
Yingyi Bu391f09e2015-10-29 13:49:39 -07004390 | <FROM : "from">
4391 | <FULL : "full">
Taewoo Kimc49405a2017-01-04 00:30:43 -08004392 | <FULLTEXT : "fulltext">
Yingyi Bu391f09e2015-10-29 13:49:39 -07004393 | <FUNCTION : "function">
4394 | <GROUP : "group">
4395 | <HAVING : "having">
4396 | <HINTS : "hints">
4397 | <IF : "if">
4398 | <INTO : "into">
4399 | <IN : "in">
4400 | <INDEX : "index">
4401 | <INGESTION : "ingestion">
4402 | <INNER : "inner">
4403 | <INSERT : "insert">
4404 | <INTERNAL : "internal">
4405 | <INTERSECT : "intersect">
Yingyi Budaa549c2016-06-28 22:30:52 -07004406 | <IS : "is">
Yingyi Bu391f09e2015-10-29 13:49:39 -07004407 | <JOIN : "join">
4408 | <KEYWORD : "keyword">
4409 | <KEY : "key">
Dmitry Lychagin1aa0dd42018-04-17 14:35:24 -07004410 | <KNOWN : "known">
Yingyi Bu391f09e2015-10-29 13:49:39 -07004411 | <LEFT : "left">
4412 | <LETTING : "letting">
4413 | <LET : "let">
Yingyi Bua8baf6d2016-07-05 21:40:44 -07004414 | <LIKE : "like">
Yingyi Bu391f09e2015-10-29 13:49:39 -07004415 | <LIMIT : "limit">
4416 | <LOAD : "load">
Murtadha Hubail29f63912019-04-21 14:23:57 +03004417 | <MOD : "mod">
Yingyi Bu391f09e2015-10-29 13:49:39 -07004418 | <NODEGROUP : "nodegroup">
4419 | <NGRAM : "ngram">
Yingyi Budaa549c2016-06-28 22:30:52 -07004420 | <NOT : "not">
Yingyi Bu391f09e2015-10-29 13:49:39 -07004421 | <OFFSET : "offset">
4422 | <ON : "on">
4423 | <OPEN : "open">
4424 | <OR : "or">
4425 | <ORDER : "order">
4426 | <OUTER : "outer">
4427 | <OUTPUT : "output">
Dmitry Lychaginfdedf622018-10-30 18:12:40 -07004428 | <OVER: "over">
Yingyi Bu391f09e2015-10-29 13:49:39 -07004429 | <PATH : "path">
4430 | <POLICY : "policy">
4431 | <PRESORTED : "pre-sorted">
4432 | <PRIMARY : "primary">
4433 | <RAW : "raw">
4434 | <REFRESH : "refresh">
4435 | <RETURN : "return">
Yingyi Bucb5bf332017-01-02 22:19:50 -08004436 | <RETURNING : "returning">
Yingyi Bu391f09e2015-10-29 13:49:39 -07004437 | <RTREE : "rtree">
4438 | <RUN : "run">
4439 | <SATISFIES : "satisfies">
4440 | <SECONDARY : "secondary">
4441 | <SELECT : "select">
4442 | <SET : "set">
4443 | <SOME : "some">
Abdullah Alamoudifff200c2017-02-18 20:32:14 -08004444 | <START : "start">
4445 | <STOP : "stop">
Dmitry Lychagin2a0848e2020-01-08 13:57:22 -08004446 | <SYNONYM : "synonym">
Murtadha Hubail2c04ae02017-11-21 15:58:01 +03004447 | <TEMPORARY : "temporary"> // intentionally not used but reserved for future usage
Yingyi Bu391f09e2015-10-29 13:49:39 -07004448 | <THEN : "then">
4449 | <TYPE : "type">
4450 | <TO : "to">
4451 | <UNION : "union">
Dmitry Lychagin8b6578a2017-11-08 15:04:35 -08004452 | <UNKNOWN : "unknown">
Yingyi Bu391f09e2015-10-29 13:49:39 -07004453 | <UNNEST : "unnest">
Yingyi Budaa549c2016-06-28 22:30:52 -07004454 | <UPDATE : "update">
Yingyi Bucb5bf332017-01-02 22:19:50 -08004455 | <UPSERT : "upsert">
Yingyi Budaa549c2016-06-28 22:30:52 -07004456 | <USE : "use">
4457 | <USING : "using">
Yingyi Bu391f09e2015-10-29 13:49:39 -07004458 | <VALUE : "value">
Dmitry Lychagin7d594a32018-01-15 14:31:03 -08004459 | <VALUED : "valued">
Yingyi Bu391f09e2015-10-29 13:49:39 -07004460 | <WHEN : "when">
4461 | <WHERE : "where">
4462 | <WITH : "with">
4463 | <WRITE : "write">
Yingyi Bu391f09e2015-10-29 13:49:39 -07004464}
4465
4466<DEFAULT,IN_DBL_BRACE>
4467TOKEN :
4468{
4469 <CARET : "^">
Yingyi Bufdc71eb2016-08-24 22:41:57 -07004470 | <CONCAT : "||">
Dmitry Lychaginbf48c492018-05-01 18:30:27 -07004471 | <DIVIDE : "/">
Yingyi Bu391f09e2015-10-29 13:49:39 -07004472 | <MINUS : "-">
Yingyi Bu391f09e2015-10-29 13:49:39 -07004473 | <MUL : "*">
4474 | <PLUS : "+">
4475
4476 | <LEFTPAREN : "(">
4477 | <RIGHTPAREN : ")">
4478 | <LEFTBRACKET : "[">
4479 | <RIGHTBRACKET : "]">
4480
4481 | <ATT : "@">
4482 | <COLON : ":">
4483 | <COMMA : ",">
Dmitry Lychagin1bdf8082018-06-13 14:48:23 -07004484 | <DOLLAR: "$">
Yingyi Bu391f09e2015-10-29 13:49:39 -07004485 | <DOT : ".">
Dmitry Lychaginbf48c492018-05-01 18:30:27 -07004486 | <PERCENT: "%">
Yingyi Bu391f09e2015-10-29 13:49:39 -07004487 | <QUES : "?">
4488 | <SEMICOLON : ";">
4489 | <SHARP : "#">
4490
4491 | <LT : "<">
4492 | <GT : ">">
4493 | <LE : "<=">
4494 | <GE : ">=">
4495 | <EQ : "=">
4496 | <NE : "!=">
Yingyi Bu4a4b8962016-09-16 12:09:11 -07004497 | <LG : "<>">
Yingyi Bu391f09e2015-10-29 13:49:39 -07004498 | <SIMILAR : "~=">
4499}
4500
4501<DEFAULT,IN_DBL_BRACE>
4502TOKEN :
4503{
4504 <LEFTBRACE : "{"> { pushState(); } : DEFAULT
4505}
4506
4507<DEFAULT>
4508TOKEN :
4509{
4510 <RIGHTBRACE : "}"> { popState("}"); }
4511}
4512
4513<DEFAULT,IN_DBL_BRACE>
4514TOKEN :
4515{
4516 <LEFTDBLBRACE : "{{"> { pushState(); } : IN_DBL_BRACE
4517}
4518
4519<IN_DBL_BRACE>
4520TOKEN :
4521{
4522 <RIGHTDBLBRACE : "}}"> { popState("}}"); }
4523}
4524
4525<DEFAULT,IN_DBL_BRACE>
4526TOKEN :
4527{
4528 <INTEGER_LITERAL : (<DIGIT>)+ >
4529}
4530
4531<DEFAULT,IN_DBL_BRACE>
Yingyi Bue311a632016-06-07 18:23:16 -07004532TOKEN [IGNORE_CASE]:
Yingyi Bu391f09e2015-10-29 13:49:39 -07004533{
Dmitry Lychagin1bdf8082018-06-13 14:48:23 -07004534 <MISSING : "missing">
4535 | <NULL : "null">
Yingyi Bu391f09e2015-10-29 13:49:39 -07004536 | <TRUE : "true">
4537 | <FALSE : "false">
4538}
4539
4540<DEFAULT,IN_DBL_BRACE>
4541TOKEN :
4542{
4543 <#DIGIT : ["0" - "9"]>
4544}
4545
4546<DEFAULT,IN_DBL_BRACE>
4547TOKEN:
4548{
Dmitry Lychaginee8526b2018-03-30 14:21:01 -07004549 < DOUBLE_LITERAL: <DIGITS> ( "." <DIGITS> ) (("e"|"E") ("+"|"-")? <DIGITS>)?
4550 | <DIGITS> (("e"|"E") ("+"|"-")? <DIGITS>)
4551 | "." <DIGITS> (("e"|"E") ("+"|"-")? <DIGITS>)?
Yingyi Bu391f09e2015-10-29 13:49:39 -07004552 >
Yingyi Bue4d919e2016-10-30 10:47:03 -07004553 | < FLOAT_LITERAL: <DIGITS> ( "f" | "F" )
4554 | <DIGITS> ( "." <DIGITS> ( "f" | "F" ) )?
4555 | "." <DIGITS> ( "f" | "F" )
Yingyi Bu391f09e2015-10-29 13:49:39 -07004556 >
4557 | <DIGITS : (<DIGIT>)+ >
4558}
4559
4560<DEFAULT,IN_DBL_BRACE>
4561TOKEN :
4562{
4563 <#LETTER : ["A" - "Z", "a" - "z"]>
Dmitry Lychagin9c83efb2018-01-16 14:31:58 -08004564 | <#IDENTIFIER_SPECIALCHARS_START : ["_"]>
4565 | <#IDENTIFIER_SPECIALCHARS_REST : ["$"]>
Yingyi Bu391f09e2015-10-29 13:49:39 -07004566}
4567
4568<DEFAULT,IN_DBL_BRACE>
4569TOKEN :
4570{
4571 // backslash u + 4 hex digits escapes are handled in the underlying JavaCharStream
Yingyi Bu6d57e492016-06-06 21:24:42 -07004572 <QUOTED_STRING : "`" (
Yingyi Bu391f09e2015-10-29 13:49:39 -07004573 <EscapeQuot>
4574 | <EscapeBslash>
4575 | <EscapeSlash>
4576 | <EscapeBspace>
4577 | <EscapeFormf>
4578 | <EscapeNl>
4579 | <EscapeCr>
4580 | <EscapeTab>
Yingyi Bu6d57e492016-06-06 21:24:42 -07004581 | ~["`","\\"])* "`">
4582 | <STRING_LITERAL : ("\"" (
Yingyi Bu391f09e2015-10-29 13:49:39 -07004583 <EscapeQuot>
Yingyi Bu391f09e2015-10-29 13:49:39 -07004584 | <EscapeBslash>
4585 | <EscapeSlash>
4586 | <EscapeBspace>
4587 | <EscapeFormf>
4588 | <EscapeNl>
4589 | <EscapeCr>
4590 | <EscapeTab>
Yingyi Bu6d57e492016-06-06 21:24:42 -07004591 | ~["\"","\\"])* "\"")
4592 | ("\'"(
4593 <EscapeApos>
4594 | <EscapeBslash>
4595 | <EscapeSlash>
4596 | <EscapeBspace>
4597 | <EscapeFormf>
4598 | <EscapeNl>
4599 | <EscapeCr>
4600 | <EscapeTab>
4601 | ~["\'","\\"])* "\'")>
Yingyi Bu391f09e2015-10-29 13:49:39 -07004602 | < #EscapeQuot: "\\\"" >
4603 | < #EscapeApos: "\\\'" >
4604 | < #EscapeBslash: "\\\\" >
4605 | < #EscapeSlash: "\\/" >
4606 | < #EscapeBspace: "\\b" >
4607 | < #EscapeFormf: "\\f" >
4608 | < #EscapeNl: "\\n" >
4609 | < #EscapeCr: "\\r" >
4610 | < #EscapeTab: "\\t" >
4611}
4612
4613<DEFAULT,IN_DBL_BRACE>
4614TOKEN :
4615{
Dmitry Lychagin9c83efb2018-01-16 14:31:58 -08004616 <IDENTIFIER : ( <LETTER> | <IDENTIFIER_SPECIALCHARS_START> )
4617 ( <LETTER> | <DIGIT> | <IDENTIFIER_SPECIALCHARS_START> | <IDENTIFIER_SPECIALCHARS_REST> )*>
Yingyi Bu391f09e2015-10-29 13:49:39 -07004618}
4619
4620<DEFAULT,IN_DBL_BRACE>
4621SKIP:
4622{
4623 " "
4624 | "\t"
4625 | "\r"
4626 | "\n"
4627}
4628
4629<DEFAULT,IN_DBL_BRACE>
4630SKIP:
4631{
4632 <"//" (~["\n"])* "\n">
4633}
4634
4635<DEFAULT,IN_DBL_BRACE>
4636SKIP:
4637{
4638 <"//" (~["\n","\r"])* ("\n"|"\r"|"\r\n")?>
4639}
4640
4641<DEFAULT,IN_DBL_BRACE>
4642SKIP:
4643{
Yingyi Bu93846a72016-09-13 16:30:39 -07004644 <"--" (~["\n"])* "\n">
4645}
4646
4647
4648<DEFAULT,IN_DBL_BRACE>
4649SKIP:
4650{
4651 <"--" (~["\n","\r"])* ("\n"|"\r"|"\r\n")?>
4652}
4653
4654<DEFAULT,IN_DBL_BRACE>
4655SKIP:
4656{
Yingyi Bu391f09e2015-10-29 13:49:39 -07004657 <"/*"> { pushState(); } : INSIDE_COMMENT
4658}
4659
4660<INSIDE_COMMENT>
4661SPECIAL_TOKEN:
4662{
4663 <"+"(" ")*(~["*"])*>
4664}
4665
4666<INSIDE_COMMENT>
4667SKIP:
4668{
4669 <"/*"> { pushState(); }
4670}
4671
4672<INSIDE_COMMENT>
4673SKIP:
4674{
4675 <"*/"> { popState("*/"); }
4676 | <~[]>
4677}