blob: 4e64944f0a4504b88a2faa242132fd03230df1a5 [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;
Dmitry Lychagin6fd8ab32020-12-03 09:04:14 -080059import org.apache.asterix.common.annotations.IndexedNLJoinExpressionAnnotation;
Yingyi Bu391f09e2015-10-29 13:49:39 -070060import org.apache.asterix.common.annotations.InsertRandIntDataGen;
61import org.apache.asterix.common.annotations.ListDataGen;
62import org.apache.asterix.common.annotations.ListValFileDataGen;
Caleb Herbel8d9c57a2020-08-14 20:41:13 -060063import org.apache.asterix.common.annotations.RangeAnnotation;
Dmitry Lychagin6fd8ab32020-12-03 09:04:14 -080064import org.apache.asterix.common.annotations.SecondaryIndexSearchPreferenceAnnotation;
Yingyi Bu391f09e2015-10-29 13:49:39 -070065import org.apache.asterix.common.annotations.SkipSecondaryIndexSearchExpressionAnnotation;
Tin Vu4f1090d2021-09-21 02:06:32 -070066import org.apache.asterix.common.annotations.SpatialJoinAnnotation;
Yingyi Bu391f09e2015-10-29 13:49:39 -070067import org.apache.asterix.common.annotations.TypeDataGen;
68import org.apache.asterix.common.annotations.UndeclaredFieldsDataGen;
69import org.apache.asterix.common.config.DatasetConfig.DatasetType;
70import org.apache.asterix.common.config.DatasetConfig.IndexType;
Dmitry Lychagin13a40e12021-04-08 18:22:57 -070071import org.apache.asterix.common.exceptions.AsterixException;
Taewoo Kime65e6ca2017-01-14 17:53:28 -080072import org.apache.asterix.common.exceptions.CompilationException;
Dmitry Lychagin85142c02018-04-05 17:27:36 -070073import org.apache.asterix.common.exceptions.ErrorCode;
Dmitry Lychagin1f6a6e32019-07-02 11:59:53 -070074import org.apache.asterix.common.exceptions.WarningCollector;
Dmitry Lychagin7c53fcf2017-11-07 12:07:41 -080075import org.apache.asterix.common.functions.FunctionConstants;
Yingyi Bu391f09e2015-10-29 13:49:39 -070076import org.apache.asterix.common.functions.FunctionSignature;
Dmitry Lychagin54c06012019-11-13 15:54:20 -080077import org.apache.asterix.common.metadata.DataverseName;
Dmitry Lychagin793c39e2021-04-21 16:52:10 -070078import org.apache.asterix.common.metadata.DatasetFullyQualifiedName;
Dmitry Lychagin276adf92019-01-15 13:16:40 -080079import org.apache.asterix.lang.common.base.AbstractClause;
Dmitry Lychaginee54cc02018-05-25 19:26:18 -070080import org.apache.asterix.lang.common.base.AbstractLangExpression;
81import org.apache.asterix.lang.common.base.AbstractStatement;
Yingyi Bu391f09e2015-10-29 13:49:39 -070082import org.apache.asterix.lang.common.base.Expression;
83import org.apache.asterix.lang.common.base.Literal;
84import org.apache.asterix.lang.common.base.IParser;
Dmitry Lychaginee54cc02018-05-25 19:26:18 -070085import org.apache.asterix.lang.common.base.ILangExpression;
Ali Alsuliman80225e22018-10-15 14:17:07 -070086import org.apache.asterix.lang.common.base.IParserFactory;
Yingyi Bu391f09e2015-10-29 13:49:39 -070087import org.apache.asterix.lang.common.base.Statement;
88import org.apache.asterix.lang.common.clause.GroupbyClause;
89import org.apache.asterix.lang.common.clause.LetClause;
90import org.apache.asterix.lang.common.clause.LimitClause;
91import org.apache.asterix.lang.common.clause.OrderbyClause;
92import org.apache.asterix.lang.common.clause.UpdateClause;
93import org.apache.asterix.lang.common.clause.WhereClause;
94import org.apache.asterix.lang.common.context.RootScopeFactory;
95import org.apache.asterix.lang.common.context.Scope;
96import org.apache.asterix.lang.common.expression.AbstractAccessor;
97import org.apache.asterix.lang.common.expression.CallExpr;
98import org.apache.asterix.lang.common.expression.FieldAccessor;
99import org.apache.asterix.lang.common.expression.FieldBinding;
100import org.apache.asterix.lang.common.expression.GbyVariableExpressionPair;
101import org.apache.asterix.lang.common.expression.IfExpr;
102import org.apache.asterix.lang.common.expression.IndexAccessor;
Dmitry Lychagin8ba59442017-06-16 14:19:45 -0700103import org.apache.asterix.lang.common.expression.IndexedTypeExpression;
Yingyi Bu391f09e2015-10-29 13:49:39 -0700104import org.apache.asterix.lang.common.expression.ListConstructor;
Hussain Towailebc5b5deb2018-12-15 18:48:48 +0300105import org.apache.asterix.lang.common.expression.ListSliceExpression;
Yingyi Bu391f09e2015-10-29 13:49:39 -0700106import org.apache.asterix.lang.common.expression.LiteralExpr;
107import org.apache.asterix.lang.common.expression.OperatorExpr;
108import org.apache.asterix.lang.common.expression.OrderedListTypeDefinition;
109import org.apache.asterix.lang.common.expression.QuantifiedExpression;
110import org.apache.asterix.lang.common.expression.RecordConstructor;
111import org.apache.asterix.lang.common.expression.RecordTypeDefinition;
112import org.apache.asterix.lang.common.expression.TypeExpression;
113import org.apache.asterix.lang.common.expression.TypeReferenceExpression;
114import org.apache.asterix.lang.common.expression.UnaryExpr;
Yingyi Bu391f09e2015-10-29 13:49:39 -0700115import org.apache.asterix.lang.common.expression.UnorderedListTypeDefinition;
116import org.apache.asterix.lang.common.expression.VariableExpr;
117import org.apache.asterix.lang.common.literal.DoubleLiteral;
118import org.apache.asterix.lang.common.literal.FalseLiteral;
119import org.apache.asterix.lang.common.literal.FloatLiteral;
120import org.apache.asterix.lang.common.literal.LongIntegerLiteral;
Yingyi Bu535d86b2016-05-23 16:44:25 -0700121import org.apache.asterix.lang.common.literal.MissingLiteral;
Yingyi Bu391f09e2015-10-29 13:49:39 -0700122import org.apache.asterix.lang.common.literal.NullLiteral;
123import org.apache.asterix.lang.common.literal.StringLiteral;
124import org.apache.asterix.lang.common.literal.TrueLiteral;
125import org.apache.asterix.lang.common.parser.ScopeChecker;
Dmitry Lychagin20905cd2020-08-06 20:34:55 -0700126import org.apache.asterix.lang.common.statement.AdapterDropStatement;
Yingyi Bu391f09e2015-10-29 13:49:39 -0700127import org.apache.asterix.lang.common.statement.CompactStatement;
128import org.apache.asterix.lang.common.statement.ConnectFeedStatement;
Abdullah Alamoudifff200c2017-02-18 20:32:14 -0800129import org.apache.asterix.lang.common.statement.StartFeedStatement;
130import org.apache.asterix.lang.common.statement.StopFeedStatement;
Ian Maxon38fe9402020-01-29 19:27:40 -0800131import org.apache.asterix.lang.common.statement.CreateAdapterStatement;
Yingyi Bu391f09e2015-10-29 13:49:39 -0700132import org.apache.asterix.lang.common.statement.CreateDataverseStatement;
133import org.apache.asterix.lang.common.statement.CreateFeedPolicyStatement;
134import org.apache.asterix.lang.common.statement.CreateFeedStatement;
135import org.apache.asterix.lang.common.statement.CreateFunctionStatement;
136import org.apache.asterix.lang.common.statement.CreateIndexStatement;
Dmitry Lychagin2a0848e2020-01-08 13:57:22 -0800137import org.apache.asterix.lang.common.statement.CreateSynonymStatement;
Rui Guoe6986dd2020-11-25 19:50:06 -0800138import org.apache.asterix.lang.common.statement.CreateFullTextFilterStatement;
139import org.apache.asterix.lang.common.statement.CreateFullTextConfigStatement;
Dmitry Lychagin793c39e2021-04-21 16:52:10 -0700140import org.apache.asterix.lang.common.statement.CreateViewStatement;
Yingyi Bu391f09e2015-10-29 13:49:39 -0700141import org.apache.asterix.lang.common.statement.DatasetDecl;
142import org.apache.asterix.lang.common.statement.DataverseDecl;
143import org.apache.asterix.lang.common.statement.DataverseDropStatement;
144import org.apache.asterix.lang.common.statement.DeleteStatement;
145import org.apache.asterix.lang.common.statement.DisconnectFeedStatement;
Yingyi Buab817482016-08-19 21:29:31 -0700146import org.apache.asterix.lang.common.statement.DropDatasetStatement;
Yingyi Bu391f09e2015-10-29 13:49:39 -0700147import org.apache.asterix.lang.common.statement.ExternalDetailsDecl;
148import org.apache.asterix.lang.common.statement.FeedDropStatement;
Abdullah Alamoudi5dc73ed2016-07-28 05:03:13 +0300149import org.apache.asterix.lang.common.statement.FeedPolicyDropStatement;
Yingyi Bu391f09e2015-10-29 13:49:39 -0700150import org.apache.asterix.lang.common.statement.FunctionDecl;
151import org.apache.asterix.lang.common.statement.FunctionDropStatement;
152import org.apache.asterix.lang.common.statement.IndexDropStatement;
Rui Guoe6986dd2020-11-25 19:50:06 -0800153import org.apache.asterix.lang.common.statement.FullTextFilterDropStatement;
154import org.apache.asterix.lang.common.statement.FullTextConfigDropStatement;
Yingyi Bu391f09e2015-10-29 13:49:39 -0700155import org.apache.asterix.lang.common.statement.InsertStatement;
156import org.apache.asterix.lang.common.statement.InternalDetailsDecl;
157import org.apache.asterix.lang.common.statement.LoadStatement;
158import org.apache.asterix.lang.common.statement.NodeGroupDropStatement;
159import org.apache.asterix.lang.common.statement.NodegroupDecl;
160import org.apache.asterix.lang.common.statement.Query;
161import org.apache.asterix.lang.common.statement.RefreshExternalDatasetStatement;
Yingyi Bu391f09e2015-10-29 13:49:39 -0700162import org.apache.asterix.lang.common.statement.SetStatement;
Dmitry Lychagin2a0848e2020-01-08 13:57:22 -0800163import org.apache.asterix.lang.common.statement.SynonymDropStatement;
Yingyi Bu391f09e2015-10-29 13:49:39 -0700164import org.apache.asterix.lang.common.statement.TypeDecl;
165import org.apache.asterix.lang.common.statement.TypeDropStatement;
166import org.apache.asterix.lang.common.statement.UpdateStatement;
Yingyi Bucb5bf332017-01-02 22:19:50 -0800167import org.apache.asterix.lang.common.statement.UpsertStatement;
Dmitry Lychagin793c39e2021-04-21 16:52:10 -0700168import org.apache.asterix.lang.common.statement.ViewDecl;
169import org.apache.asterix.lang.common.statement.ViewDropStatement;
Yingyi Bu391f09e2015-10-29 13:49:39 -0700170import org.apache.asterix.lang.common.statement.WriteStatement;
171import org.apache.asterix.lang.common.struct.Identifier;
Dmitry Lychaginef1719e2017-12-15 08:33:07 -0800172import org.apache.asterix.lang.common.struct.OperatorType;
Yingyi Bu391f09e2015-10-29 13:49:39 -0700173import org.apache.asterix.lang.common.struct.QuantifiedPair;
174import org.apache.asterix.lang.common.struct.VarIdentifier;
Dmitry Lychagin4fb583d2021-11-10 17:25:28 -0800175import org.apache.asterix.lang.common.util.DatasetDeclParametersUtil;
Tin Vu4f1090d2021-09-21 02:06:32 -0700176import org.apache.asterix.lang.common.util.ExpressionUtils;
Ali Alsuliman80225e22018-10-15 14:17:07 -0700177import org.apache.asterix.lang.common.util.RangeMapBuilder;
Yingyi Bu391f09e2015-10-29 13:49:39 -0700178import org.apache.asterix.lang.sqlpp.clause.AbstractBinaryCorrelateClause;
179import org.apache.asterix.lang.sqlpp.clause.FromClause;
180import org.apache.asterix.lang.sqlpp.clause.FromTerm;
181import org.apache.asterix.lang.sqlpp.clause.HavingClause;
182import org.apache.asterix.lang.sqlpp.clause.JoinClause;
Yingyi Bu391f09e2015-10-29 13:49:39 -0700183import org.apache.asterix.lang.sqlpp.clause.Projection;
184import org.apache.asterix.lang.sqlpp.clause.SelectBlock;
185import org.apache.asterix.lang.sqlpp.clause.SelectClause;
186import org.apache.asterix.lang.sqlpp.clause.SelectElement;
187import org.apache.asterix.lang.sqlpp.clause.SelectRegular;
188import org.apache.asterix.lang.sqlpp.clause.SelectSetOperation;
189import org.apache.asterix.lang.sqlpp.clause.UnnestClause;
Xikui Wangf6741682018-02-22 19:17:17 -0800190import org.apache.asterix.lang.common.clause.WhereClause;
Yingyi Buc8c067c2016-07-25 23:37:19 -0700191import org.apache.asterix.lang.sqlpp.expression.CaseExpression;
Yingyi Bu391f09e2015-10-29 13:49:39 -0700192import org.apache.asterix.lang.sqlpp.expression.SelectExpression;
Dmitry Lychaginfdedf622018-10-30 18:12:40 -0700193import org.apache.asterix.lang.sqlpp.expression.WindowExpression;
Yingyi Bu391f09e2015-10-29 13:49:39 -0700194import org.apache.asterix.lang.sqlpp.optype.JoinType;
195import org.apache.asterix.lang.sqlpp.optype.SetOpType;
Dmitry Lychagind4ce84c2020-10-13 16:24:37 -0700196import org.apache.asterix.lang.sqlpp.optype.UnnestType;
Dmitry Lychaginac98f482020-03-31 12:26:40 -0700197import org.apache.asterix.lang.sqlpp.parser.SqlppGroupingSetsParser;
198import org.apache.asterix.lang.sqlpp.parser.SqlppGroupingSetsParser.GroupingElement;
199import org.apache.asterix.lang.sqlpp.parser.SqlppGroupingSetsParser.GroupingSet;
200import org.apache.asterix.lang.sqlpp.parser.SqlppGroupingSetsParser.GroupingSets;
201import org.apache.asterix.lang.sqlpp.parser.SqlppGroupingSetsParser.RollupCube;
Dmitry Lychagine77cdac2019-08-05 11:37:47 -0700202import org.apache.asterix.lang.sqlpp.parser.SqlppHint;
Yingyi Bu391f09e2015-10-29 13:49:39 -0700203import org.apache.asterix.lang.sqlpp.struct.SetOperationInput;
204import org.apache.asterix.lang.sqlpp.struct.SetOperationRight;
Yingyi Bu9e3f9be2016-07-01 10:07:37 -0700205import org.apache.asterix.lang.sqlpp.util.ExpressionToVariableUtil;
Xikui Wang96fd4022017-04-10 14:23:31 -0700206import org.apache.asterix.lang.sqlpp.util.FunctionMapUtil;
Yingyi Buacc12a92016-03-26 17:25:05 -0700207import org.apache.asterix.lang.sqlpp.util.SqlppVariableUtil;
Ian Maxon38fe9402020-01-29 19:27:40 -0800208import org.apache.asterix.external.dataset.adapter.AdapterIdentifier;
Tin Vu4f1090d2021-09-21 02:06:32 -0700209import org.apache.asterix.om.exceptions.TypeMismatchException;
Dmitry Lychagin7c53fcf2017-11-07 12:07:41 -0800210import org.apache.asterix.om.functions.BuiltinFunctions;
Dmitry Lychagin75f19872019-10-03 17:56:35 -0700211import org.apache.asterix.om.types.BuiltinType;
Dmitry Lychagine77cdac2019-08-05 11:37:47 -0700212import org.apache.commons.lang3.ArrayUtils;
Dmitry Lychagin1f6a6e32019-07-02 11:59:53 -0700213import org.apache.commons.lang3.StringUtils;
Yingyi Bu391f09e2015-10-29 13:49:39 -0700214import org.apache.hyracks.algebricks.common.utils.Pair;
215import org.apache.hyracks.algebricks.common.utils.Triple;
Xikui Wang5a61b2a2018-01-02 14:14:03 -0800216import org.apache.hyracks.algebricks.common.exceptions.AlgebricksException;
Shiva2ea73232019-10-09 18:04:05 -0700217import org.apache.hyracks.algebricks.core.algebra.expressions.BroadcastExpressionAnnotation;
Yingyi Bu391f09e2015-10-29 13:49:39 -0700218import org.apache.hyracks.algebricks.core.algebra.expressions.IExpressionAnnotation;
Yingyi Bu391f09e2015-10-29 13:49:39 -0700219import org.apache.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
Dmitry Lychagin67714e22021-01-29 11:18:58 -0800220import org.apache.hyracks.api.exceptions.IWarningCollector;
Dmitry Lychaginee54cc02018-05-25 19:26:18 -0700221import org.apache.hyracks.api.exceptions.SourceLocation;
Dmitry Lychagin1f6a6e32019-07-02 11:59:53 -0700222import org.apache.hyracks.api.exceptions.Warning;
Dmitry Lychagin70bf47a2020-10-22 13:25:57 -0700223import org.apache.hyracks.dataflow.common.data.partition.range.RangeMap;
Ali Alsuliman587b7902019-01-21 14:33:50 -0800224import org.apache.hyracks.util.LogRedactionUtil;
Dmitry Lychagine77cdac2019-08-05 11:37:47 -0700225import org.apache.hyracks.util.StringUtil;
Yingyi Bu391f09e2015-10-29 13:49:39 -0700226
Yingyi Bucaea8f02015-11-16 15:12:15 -0800227class SQLPPParser extends ScopeChecker implements IParser {
Yingyi Bu391f09e2015-10-29 13:49:39 -0700228
Dmitry Lychaginf2c18aa2018-12-28 21:20:23 -0800229 // tokens parsed as identifiers
Dmitry Lychaginac98f482020-03-31 12:26:40 -0700230 private static final String CUBE = "CUBE";
Dmitry Lychaginf2c18aa2018-12-28 21:20:23 -0800231 private static final String CURRENT = "CURRENT";
Dmitry Lychagin33c77f92021-07-21 15:59:04 -0700232 private static final String DEFAULT = "DEFAULT";
Dmitry Lychaginf2c18aa2018-12-28 21:20:23 -0800233 private static final String EXCLUDE = "EXCLUDE";
Ali Alsuliman931e7382021-08-08 21:55:59 +0300234 private static final String INCLUDE = "INCLUDE";
Dmitry Lychagin5476f962019-05-31 16:03:11 -0700235 private static final String FIRST = "FIRST";
Dmitry Lychaginf2c18aa2018-12-28 21:20:23 -0800236 private static final String FOLLOWING = "FOLLOWING";
Dmitry Lychagin914983f2021-09-30 15:11:11 -0700237 private static final String FOREIGN = "FOREIGN";
Dmitry Lychaginac98f482020-03-31 12:26:40 -0700238 private static final String GROUPING = "GROUPING";
Dmitry Lychaginf2c18aa2018-12-28 21:20:23 -0800239 private static final String GROUPS = "GROUPS";
Dmitry Lychagin3346cea2019-05-28 12:11:54 -0700240 private static final String IGNORE = "IGNORE";
Dmitry Lychagin5476f962019-05-31 16:03:11 -0700241 private static final String LAST = "LAST";
Glenn67fd1f32021-02-25 16:04:49 -0800242 private static final String META = "META";
Dmitry Lychaginf2c18aa2018-12-28 21:20:23 -0800243 private static final String NO = "NO";
Dmitry Lychagin3346cea2019-05-28 12:11:54 -0700244 private static final String NULLS = "NULLS";
Dmitry Lychaginf2c18aa2018-12-28 21:20:23 -0800245 private static final String OTHERS = "OTHERS";
246 private static final String PARTITION = "PARTITION";
247 private static final String PRECEDING = "PRECEDING";
248 private static final String RANGE = "RANGE";
Dmitry Lychagin914983f2021-09-30 15:11:11 -0700249 private static final String REFERENCES = "REFERENCES";
Dmitry Lychagin3346cea2019-05-28 12:11:54 -0700250 private static final String RESPECT = "RESPECT";
Dmitry Lychaginac98f482020-03-31 12:26:40 -0700251 private static final String ROLLUP = "ROLLUP";
Dmitry Lychaginf2c18aa2018-12-28 21:20:23 -0800252 private static final String ROW = "ROW";
253 private static final String ROWS = "ROWS";
Dmitry Lychaginac98f482020-03-31 12:26:40 -0700254 private static final String SETS = "SETS";
Dmitry Lychaginf2c18aa2018-12-28 21:20:23 -0800255 private static final String TIES = "TIES";
256 private static final String UNBOUNDED = "UNBOUNDED";
Dmitry Lychagindcb4ad22020-08-26 15:49:09 -0700257 private static final String REPLACE = "REPLACE";
Ian Maxon38fe9402020-01-29 19:27:40 -0800258 private static final String RETURNS = "RETURNS";
Rui Guoe6986dd2020-11-25 19:50:06 -0800259 private static final String CONFIG = "CONFIG";
260
Dmitry Lychaginf2c18aa2018-12-28 21:20:23 -0800261
Dmitry Lychagin75f19872019-10-03 17:56:35 -0700262 private static final String INT_TYPE_NAME = "int";
Dmitry Lychagin541652082020-11-09 14:04:53 -0800263 private static final String UDF_VARARGS_PARAM_NAME = "args"; // Note: this value is stored in the function metadata
Dmitry Lychagin75f19872019-10-03 17:56:35 -0700264
Till Westmann7199a562016-09-17 16:07:32 -0700265 // error configuration
266 protected static final boolean REPORT_EXPECTED_TOKENS = false;
267
Dmitry Lychagin1bdf8082018-06-13 14:48:23 -0700268 private int externalVarCounter;
269
Dmitry Lychagin54c06012019-11-13 15:54:20 -0800270 private DataverseName defaultDataverse;
271
Dmitry Lychaginac98f482020-03-31 12:26:40 -0700272 private SqlppGroupingSetsParser groupingSetsParser;
273
Dmitry Lychagin1f6a6e32019-07-02 11:59:53 -0700274 private final WarningCollector warningCollector = new WarningCollector();
275
Dmitry Lychagine77cdac2019-08-05 11:37:47 -0700276 private final Map<SourceLocation, String> hintCollector = new HashMap<SourceLocation, String>();
277
Yingyi Bu391f09e2015-10-29 13:49:39 -0700278 private static class IndexParams {
279 public IndexType type;
280 public int gramLength;
Rui Guoe6986dd2020-11-25 19:50:06 -0800281 public String fullTextConfig;
Yingyi Bu391f09e2015-10-29 13:49:39 -0700282
Rui Guoe6986dd2020-11-25 19:50:06 -0800283 public IndexParams(IndexType type, int gramLength, String fullTextConfig) {
Yingyi Bu391f09e2015-10-29 13:49:39 -0700284 this.type = type;
285 this.gramLength = gramLength;
Rui Guoe6986dd2020-11-25 19:50:06 -0800286 this.fullTextConfig = fullTextConfig;
Yingyi Bu391f09e2015-10-29 13:49:39 -0700287 }
Ali Alsuliman69ce7d82021-11-01 15:00:16 -0700288 }
Yingyi Bu391f09e2015-10-29 13:49:39 -0700289
290 private static class FunctionName {
Dmitry Lychagin54c06012019-11-13 15:54:20 -0800291 public DataverseName dataverse;
Dmitry Lychaginee54cc02018-05-25 19:26:18 -0700292 public String library;
293 public String function;
Caleb Herbel8d9c57a2020-08-14 20:41:13 -0600294 public Token hintToken;
Dmitry Lychaginee54cc02018-05-25 19:26:18 -0700295 public SourceLocation sourceLoc;
Yingyi Bu391f09e2015-10-29 13:49:39 -0700296 }
297
Dmitry Lychagine77cdac2019-08-05 11:37:47 -0700298 private IRecordFieldDataGen parseFieldDataGen(Token hintToken) throws ParseException {
299 String[] splits = hintToken.hintParams != null ? hintToken.hintParams.split("\\s+") : null;
300 switch (hintToken.hint) {
301 case VAL_FILE_HINT:
302 File[] valFiles = new File[splits.length];
303 for (int k=0; k<splits.length; k++) {
304 valFiles[k] = new File(splits[k]);
305 }
306 return new FieldValFileDataGen(valFiles);
307 case VAL_FILE_SAME_INDEX_HINT:
308 return new FieldValFileSameIndexDataGen(new File(splits[0]), splits[1]);
309 case LIST_VAL_FILE_HINT:
310 return new ListValFileDataGen(new File(splits[0]), Integer.parseInt(splits[1]), Integer.parseInt(splits[2]));
311 case LIST_HINT:
312 return new ListDataGen(Integer.parseInt(splits[0]), Integer.parseInt(splits[1]));
313 case INTERVAL_HINT:
314 FieldIntervalDataGen.ValueType vt;
315 switch (splits[0]) {
316 case "int":
317 vt = FieldIntervalDataGen.ValueType.INT;
318 break;
319 case "long":
320 vt = FieldIntervalDataGen.ValueType.LONG;
321 break;
322 case "float":
323 vt = FieldIntervalDataGen.ValueType.FLOAT;
324 break;
325 case "double":
326 vt = FieldIntervalDataGen.ValueType.DOUBLE;
327 break;
328 default:
329 throw new SqlppParseException(getSourceLocation(hintToken),
330 "Unknown type for interval data gen: " + splits[0]);
331 }
332 return new FieldIntervalDataGen(vt, splits[1], splits[2]);
333 case INSERT_RAND_INT_HINT:
334 return new InsertRandIntDataGen(splits[0], splits[1]);
335 case DATE_BETWEEN_YEARS_HINT:
336 return new DateBetweenYearsDataGen(Integer.parseInt(splits[0]), Integer.parseInt(splits[1]));
337 case DATETIME_BETWEEN_YEARS_HINT:
338 return new DatetimeBetweenYearsDataGen(Integer.parseInt(splits[0]), Integer.parseInt(splits[1]));
339 case DATETIME_ADD_RAND_HOURS_HINT:
340 return new DatetimeAddRandHoursDataGen(Integer.parseInt(splits[0]), Integer.parseInt(splits[1]), splits[2]);
341 case AUTO_HINT:
342 return new AutoDataGen(splits[0]);
343 default:
344 return null;
Yingyi Bu391f09e2015-10-29 13:49:39 -0700345 }
Yingyi Bu391f09e2015-10-29 13:49:39 -0700346 }
347
Till Westmann7199a562016-09-17 16:07:32 -0700348 public SQLPPParser(String s) {
Yingyi Bu391f09e2015-10-29 13:49:39 -0700349 this(new StringReader(s));
350 super.setInput(s);
351 }
352
Ali Alsuliman69ce7d82021-11-01 15:00:16 -0700353 public static void main(String[] args) throws ParseException, TokenMgrError, IOException, FileNotFoundException, CompilationException {
Yingyi Bu391f09e2015-10-29 13:49:39 -0700354 File file = new File(args[0]);
355 Reader fis = new BufferedReader(new InputStreamReader(new FileInputStream(file), "UTF-8"));
356 SQLPPParser parser = new SQLPPParser(fis);
357 List<Statement> st = parser.parse();
358 //st.accept(new SQLPPPrintVisitor(), 0);
359 }
360
Dmitry Lychagin45de2342020-02-03 12:01:28 -0800361 @Override
Taewoo Kime65e6ca2017-01-14 17:53:28 -0800362 public List<Statement> parse() throws CompilationException {
Dmitry Lychagin1227f022019-08-01 13:14:30 -0700363 return parseImpl(new ParseFunction<List<Statement>>() {
364 @Override
365 public List<Statement> parse() throws ParseException {
366 return SQLPPParser.this.Statement();
367 }
368 });
369 }
370
Dmitry Lychagin62f0beb2020-09-08 11:44:19 -0700371 @Override
372 public Expression parseExpression() throws CompilationException {
Dmitry Lychagin1227f022019-08-01 13:14:30 -0700373 return parseImpl(new ParseFunction<Expression>() {
374 @Override
375 public Expression parse() throws ParseException {
376 return SQLPPParser.this.Expression();
377 }
378 });
379 }
380
381 private static Expression parseExpression(String text) throws CompilationException {
382 return new SQLPPParser(text).parseExpression();
383 }
384
Dmitry Lychagin45de2342020-02-03 12:01:28 -0800385 @Override
Dmitry Lychaginef680d7d2020-10-15 13:10:41 -0700386 public List<String> parseMultipartIdentifier() throws CompilationException {
387 return parseImpl(new ParseFunction<List<String>>() {
388 @Override
389 public List<String> parse() throws ParseException {
Dmitry Lychagin13a40e12021-04-08 18:22:57 -0700390 return SQLPPParser.this.MultipartIdentifier().first;
Dmitry Lychaginef680d7d2020-10-15 13:10:41 -0700391 }
392 });
393 }
394
Dmitry Lychagin6fd8ab32020-12-03 09:04:14 -0800395 private List<String> parseParenthesizedIdentifierList() throws CompilationException {
396 return parseImpl(new ParseFunction<List<String>>() {
397 @Override
398 public List<String> parse() throws ParseException {
399 return SQLPPParser.this.ParenthesizedIdentifierList();
400 }
401 });
402 }
403
404 private static List<String> parseParenthesizedIdentifierList(String text) throws CompilationException {
405 return new SQLPPParser(text).parseParenthesizedIdentifierList();
406 }
407
Tin Vu4f1090d2021-09-21 02:06:32 -0700408 private List<Literal> parseParenthesizedLiteralList() throws CompilationException {
409 return parseImpl(new ParseFunction<List<Literal>>() {
410 @Override
411 public List<Literal> parse() throws ParseException {
412 return SQLPPParser.this.ParenthesizedLiteralList();
413 }
414 });
415 }
416
417 private static List<Literal> parseParenthesizedLiteralList(String text) throws CompilationException {
418 return new SQLPPParser(text).parseParenthesizedLiteralList();
419 }
420
Dmitry Lychaginef680d7d2020-10-15 13:10:41 -0700421 @Override
Dmitry Lychagin9ba74872021-04-05 14:38:20 -0700422 public FunctionDecl parseFunctionBody(FunctionSignature signature, List<String> paramNames, boolean isStored)
Dmitry Lychagin45de2342020-02-03 12:01:28 -0800423 throws CompilationException {
Dmitry Lychagine74454b2020-02-06 13:44:21 -0800424 return parseImpl(new ParseFunction<FunctionDecl>() {
Dmitry Lychagin45de2342020-02-03 12:01:28 -0800425 @Override
Dmitry Lychagine74454b2020-02-06 13:44:21 -0800426 public FunctionDecl parse() throws ParseException {
Dmitry Lychagin45de2342020-02-03 12:01:28 -0800427 DataverseName dataverse = defaultDataverse;
428 defaultDataverse = signature.getDataverseName();
429 createNewScope();
Dmitry Lychagine74454b2020-02-06 13:44:21 -0800430 List<VarIdentifier> paramVars = new ArrayList<VarIdentifier>(paramNames.size());
431 for (String paramName : paramNames) {
432 paramVars.add(SqlppVariableUtil.toInternalVariableIdentifier(paramName));
433 }
Dmitry Lychagin45de2342020-02-03 12:01:28 -0800434 Expression functionBodyExpr = SQLPPParser.this.FunctionBody();
435 removeCurrentScope();
436 defaultDataverse = dataverse;
Dmitry Lychagin9ba74872021-04-05 14:38:20 -0700437 return new FunctionDecl(signature, paramVars, functionBodyExpr, isStored);
Dmitry Lychagin45de2342020-02-03 12:01:28 -0800438 }
439 });
440 }
441
Dmitry Lychagin793c39e2021-04-21 16:52:10 -0700442 @Override
443 public ViewDecl parseViewBody(DatasetFullyQualifiedName viewName) throws CompilationException {
444 return parseImpl(new ParseFunction<ViewDecl>() {
445 @Override
446 public ViewDecl parse() throws ParseException {
447 DataverseName dataverse = defaultDataverse;
448 defaultDataverse = viewName.getDataverseName();
449 createNewScope();
450 Expression viewBodyExpr = SQLPPParser.this.ViewBody();
451 removeCurrentScope();
452 defaultDataverse = dataverse;
453 return new ViewDecl(viewName, viewBodyExpr);
454 }
455 });
456 }
457
Dmitry Lychagin1227f022019-08-01 13:14:30 -0700458 private <T> T parseImpl(ParseFunction<T> parseFunction) throws CompilationException {
Dmitry Lychagin1f6a6e32019-07-02 11:59:53 -0700459 warningCollector.clear();
Dmitry Lychagine77cdac2019-08-05 11:37:47 -0700460 hintCollector.clear();
Dmitry Lychagin67714e22021-01-29 11:18:58 -0800461 token_source.hintCollector = hintCollector;
Yingyi Bu391f09e2015-10-29 13:49:39 -0700462 try {
Dmitry Lychagin1227f022019-08-01 13:14:30 -0700463 return parseFunction.parse();
Dmitry Lychagin3e2623c2020-04-01 11:20:04 -0700464 } catch (SqlppParseException e) {
Dmitry Lychagin13a40e12021-04-08 18:22:57 -0700465 if (e.getCause() instanceof AlgebricksException) {
466 AlgebricksException cause = (AlgebricksException) e.getCause();
467 if (cause.getError().isPresent() && cause.getError().get() instanceof ErrorCode) {
468 throw new CompilationException((ErrorCode) cause.getError().get(), e.getSourceLocation(),
469 cause.getParams());
470 }
471 }
472 throw new CompilationException(ErrorCode.PARSE_ERROR, e.getSourceLocation(),
473 LogRedactionUtil.userData(getMessage(e)));
Dmitry Lychagin3e2623c2020-04-01 11:20:04 -0700474 } catch (ParseException e) {
475 throw new CompilationException(ErrorCode.PARSE_ERROR, LogRedactionUtil.userData(getMessage(e)));
Yingyi Bu391f09e2015-10-29 13:49:39 -0700476 } catch (Error e) {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -0700477 // this is here as the JavaCharStream that's below the lexer sometimes throws Errors that are not handled
Dmitry Lychagind4ce84c2020-10-13 16:24:37 -0700478 // by the generated lexer or parser (e.g it does this for invalid backslash u + 4 hex digits escapes)
Till Westmann60f89982017-08-11 18:14:20 -0700479 final String msg = e.getClass().getSimpleName() + (e.getMessage() != null ? ": " + e.getMessage() : "");
Ali Alsulimanfe901892019-03-19 01:40:35 -0700480 throw new CompilationException(ErrorCode.PARSE_ERROR, LogRedactionUtil.userData(msg));
Dmitry Lychagine77cdac2019-08-05 11:37:47 -0700481 } finally {
482 reportUnclaimedHints();
Yingyi Bu391f09e2015-10-29 13:49:39 -0700483 }
484 }
Till Westmann7199a562016-09-17 16:07:32 -0700485
Dmitry Lychagin1227f022019-08-01 13:14:30 -0700486 @FunctionalInterface
487 private interface ParseFunction<T> {
488 T parse() throws ParseException;
489 }
490
Dmitry Lychagin1f6a6e32019-07-02 11:59:53 -0700491 @Override
Dmitry Lychagin67714e22021-01-29 11:18:58 -0800492 public void getWarnings(IWarningCollector outWarningCollector) {
493 warningCollector.getWarnings(outWarningCollector);
494 }
495
496 @Override
Ali Alsuliman6a9e2b02019-09-16 20:50:41 -0700497 public void getWarnings(Collection<? super Warning> outWarnings, long maxWarnings) {
498 warningCollector.getWarnings(outWarnings, maxWarnings);
499 }
500
501 @Override
502 public long getTotalWarningsCount() {
503 return warningCollector.getTotalWarningsCount();
Dmitry Lychagin1f6a6e32019-07-02 11:59:53 -0700504 }
505
Till Westmann7199a562016-09-17 16:07:32 -0700506 protected String getMessage(ParseException pe) {
507 Token currentToken = pe.currentToken;
508 if (currentToken == null) {
509 return pe.getMessage();
510 }
511 int[][] expectedTokenSequences = pe.expectedTokenSequences;
512 String[] tokenImage = pe.tokenImage;
513 String sep = REPORT_EXPECTED_TOKENS ? eol : " ";
514 StringBuilder expected = REPORT_EXPECTED_TOKENS ? new StringBuilder() : null;
515 int maxSize = appendExpected(expected, expectedTokenSequences, tokenImage);
516 Token tok = currentToken.next;
517 int line = tok.beginLine;
Dmitry Lychaginee54cc02018-05-25 19:26:18 -0700518 StringBuilder message = new StringBuilder(128);
519 message.append("In line ").append(line).append(" >>").append(getLine(line)).append("<<").append(sep).append("Encountered ");
Till Westmann7199a562016-09-17 16:07:32 -0700520 for (int i = 0; i < maxSize; i++) {
521 if (i != 0) {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -0700522 message.append(' ');
Till Westmann7199a562016-09-17 16:07:32 -0700523 }
524 if (tok.kind == 0) {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -0700525 message.append(fixQuotes(tokenImage[0]));
Till Westmann7199a562016-09-17 16:07:32 -0700526 break;
527 }
Till Westmanne3c9f272016-10-09 11:09:26 -0700528 final String fixedTokenImage = tokenImage[tok.kind];
529 if (! tok.image.equalsIgnoreCase(stripQuotes(fixedTokenImage))) {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -0700530 message.append(fixQuotes(fixedTokenImage)).append(' ');
Till Westmanne3c9f272016-10-09 11:09:26 -0700531 }
Dmitry Lychaginee54cc02018-05-25 19:26:18 -0700532 message.append(quot).append(addEscapes(tok.image)).append(quot);
Till Westmann7199a562016-09-17 16:07:32 -0700533 tok = tok.next;
534 }
Dmitry Lychaginee54cc02018-05-25 19:26:18 -0700535 message.append(" at column ").append(currentToken.next.beginColumn).append('.').append(sep);
Till Westmann7199a562016-09-17 16:07:32 -0700536 if (REPORT_EXPECTED_TOKENS) {
537 if (expectedTokenSequences.length == 1) {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -0700538 message.append("Was expecting:").append(sep).append(" ");
Till Westmann7199a562016-09-17 16:07:32 -0700539 } else {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -0700540 message.append("Was expecting one of:").append(sep).append(" ");
Till Westmann7199a562016-09-17 16:07:32 -0700541 }
Dmitry Lychaginee54cc02018-05-25 19:26:18 -0700542 message.append(expected);
Till Westmann7199a562016-09-17 16:07:32 -0700543 }
Dmitry Lychaginee54cc02018-05-25 19:26:18 -0700544 return message.toString();
Till Westmann7199a562016-09-17 16:07:32 -0700545 }
546
Dmitry Lychaginee54cc02018-05-25 19:26:18 -0700547 protected static SourceLocation getSourceLocation(Token token) {
Dmitry Lychagine77cdac2019-08-05 11:37:47 -0700548 return
549 token == null ? null :
550 token.sourceLocation != null ? token.sourceLocation :
551 new SourceLocation(token.beginLine, token.beginColumn);
Dmitry Lychaginee54cc02018-05-25 19:26:18 -0700552 }
553
Dmitry Lychagin5c26b422018-06-01 10:22:16 -0700554 protected static <T extends AbstractLangExpression> T addSourceLocation(T expr, Token token) {
555 expr.setSourceLocation(getSourceLocation(token));
556 return expr;
Dmitry Lychaginee54cc02018-05-25 19:26:18 -0700557 }
Dmitry Lychaginf2c18aa2018-12-28 21:20:23 -0800558
559 private boolean isToken(String image) {
Dmitry Lychagindcb4ad22020-08-26 15:49:09 -0700560 return isToken(token, image);
561 }
562
563 private static boolean isToken(Token token, String image) {
Dmitry Lychaginf2c18aa2018-12-28 21:20:23 -0800564 return token.image.equalsIgnoreCase(image);
565 }
566
567 private void expectToken(String image) throws SqlppParseException {
Dmitry Lychagindcb4ad22020-08-26 15:49:09 -0700568 expectToken(token, image);
569 }
570
571 private static void expectToken(Token token, String image) throws SqlppParseException {
572 if (!isToken(token, image)) {
573 throw createUnexpectedTokenError(token);
Dmitry Lychaginf2c18aa2018-12-28 21:20:23 -0800574 }
575 }
576
577 private SqlppParseException createUnexpectedTokenError() {
Dmitry Lychagin5cc254a2020-05-08 17:12:47 -0700578 return createUnexpectedTokenError(token, null);
Dmitry Lychagin3e2623c2020-04-01 11:20:04 -0700579 }
580
Dmitry Lychagindcb4ad22020-08-26 15:49:09 -0700581 private static SqlppParseException createUnexpectedTokenError(Token t) {
Dmitry Lychagin5cc254a2020-05-08 17:12:47 -0700582 return createUnexpectedTokenError(t, null);
Dmitry Lychagin0d4c1b62020-02-07 17:10:16 -0800583 }
584
585 private SqlppParseException createUnexpectedTokenError(String expected) {
Dmitry Lychagin5cc254a2020-05-08 17:12:47 -0700586 return createUnexpectedTokenError(token, expected);
587 }
588
Dmitry Lychagindcb4ad22020-08-26 15:49:09 -0700589 private static SqlppParseException createUnexpectedTokenError(Token t, String expected) {
Dmitry Lychagin5cc254a2020-05-08 17:12:47 -0700590 String message = "Unexpected token: " + LogRedactionUtil.userData(t.image) +
Dmitry Lychagin0d4c1b62020-02-07 17:10:16 -0800591 (expected == null ? "" : ". Expected: " + LogRedactionUtil.userData(expected));
Dmitry Lychagin5cc254a2020-05-08 17:12:47 -0700592 return new SqlppParseException(getSourceLocation(t), message);
Dmitry Lychaginf2c18aa2018-12-28 21:20:23 -0800593 }
594
Dmitry Lychaginac98f482020-03-31 12:26:40 -0700595 private boolean laToken(int idx, int kind) {
596 Token t = getToken(idx);
597 return t.kind == kind;
598 }
599
Dmitry Lychaginf2c18aa2018-12-28 21:20:23 -0800600 private boolean laToken(int idx, int kind, String image) {
601 Token t = getToken(idx);
602 return t.kind == kind && t.image.equalsIgnoreCase(image);
603 }
604
605 private boolean laIdentifier(int idx, String image) {
606 return laToken(idx, IDENTIFIER, image);
607 }
608
609 private boolean laIdentifier(String image) {
610 return laIdentifier(1, image);
611 }
Dmitry Lychagin1f6a6e32019-07-02 11:59:53 -0700612
Dmitry Lychagine77cdac2019-08-05 11:37:47 -0700613 private Token fetchHint(Token token, SqlppHint... expectedHints) {
614 Token hintToken = token.specialToken;
615 if (hintToken == null) {
616 return null;
617 }
618 SourceLocation sourceLoc = getSourceLocation(hintToken);
619 hintCollector.remove(sourceLoc);
620 if (hintToken.hint == null) {
621 warnUnexpectedHint(hintToken.hintParams, sourceLoc, expectedHints);
622 return null;
623 } else if (!ArrayUtils.contains(expectedHints, hintToken.hint)) {
624 warnUnexpectedHint(hintToken.hint.getIdentifier(), sourceLoc, expectedHints);
625 return null;
626 } else {
627 return hintToken;
628 }
629 }
630
631 private void reportUnclaimedHints() {
632 for (Map.Entry<SourceLocation, String> me : hintCollector.entrySet()) {
633 warnUnexpectedHint(me.getValue(), me.getKey(), "None");
634 }
635 }
636
637 private void warnUnexpectedHint(String actualHint, SourceLocation sourceLoc, SqlppHint... expectedHints) {
638 warnUnexpectedHint(actualHint, sourceLoc, StringUtil.join(expectedHints, ", ", "\""));
639 }
640
641 private void warnUnexpectedHint(String actualHint, SourceLocation sourceLoc, String expectedHints) {
Ali Alsulimanaa118862019-09-10 20:55:45 -0700642 if (warningCollector.shouldWarn()) {
Michael Blow7c838de2021-02-23 16:12:48 -0500643 warningCollector.warn(Warning.of(sourceLoc, ErrorCode.UNEXPECTED_HINT, actualHint, expectedHints));
Ali Alsulimanaa118862019-09-10 20:55:45 -0700644 }
Dmitry Lychagin1f6a6e32019-07-02 11:59:53 -0700645 }
Dmitry Lychaginf7bc6c12020-06-01 18:19:44 -0700646
Dmitry Lychagin7c624522020-12-04 18:01:45 -0800647 private IExpressionAnnotation parseExpressionAnnotation(Token hintToken) {
648 // placeholder for the annotation that should be returned if this hint's parameters cannot be parsed
649 IExpressionAnnotation onParseErrorReturn = null;
Dmitry Lychagin6fd8ab32020-12-03 09:04:14 -0800650 try {
651 switch (hintToken.hint) {
652 case HASH_BROADCAST_JOIN_HINT:
653 return new BroadcastExpressionAnnotation(BroadcastExpressionAnnotation.BroadcastSide.RIGHT);
654 case INDEXED_NESTED_LOOP_JOIN_HINT:
655 if (hintToken.hintParams == null) {
656 return IndexedNLJoinExpressionAnnotation.INSTANCE_ANY_INDEX;
657 } else {
Dmitry Lychagin7c624522020-12-04 18:01:45 -0800658 // if parameter parsing fails then return hint annotation without parameters
659 onParseErrorReturn = IndexedNLJoinExpressionAnnotation.INSTANCE_ANY_INDEX;
Dmitry Lychagin6fd8ab32020-12-03 09:04:14 -0800660 List<String> indexNames = parseParenthesizedIdentifierList(hintToken.hintParams);
661 return IndexedNLJoinExpressionAnnotation.newInstance(indexNames);
662 }
663 case RANGE_HINT:
664 Expression rangeExpr = parseExpression(hintToken.hintParams);
665 RangeMap rangeMap = RangeMapBuilder.parseHint(rangeExpr);
666 return new RangeAnnotation(rangeMap);
667 case SKIP_SECONDARY_INDEX_SEARCH_HINT:
668 if (hintToken.hintParams == null) {
669 return SkipSecondaryIndexSearchExpressionAnnotation.INSTANCE_ANY_INDEX;
670 } else {
Dmitry Lychagin7c624522020-12-04 18:01:45 -0800671 // if parameter parsing fails then ignore this hint
Dmitry Lychagin6fd8ab32020-12-03 09:04:14 -0800672 List<String> indexNames = parseParenthesizedIdentifierList(hintToken.hintParams);
673 return SkipSecondaryIndexSearchExpressionAnnotation.newInstance(indexNames);
674 }
Tin Vu4f1090d2021-09-21 02:06:32 -0700675 case SPATIAL_JOIN_HINT:
676 List<Literal> hintValues = parseParenthesizedLiteralList(hintToken.hintParams);
677
678 // Handle exceptions
679 if (hintValues.size() != 6) {
680 throw new SqlppParseException(getSourceLocation(hintToken), String.format("Unexpected hint: %s. 6 arguments are required.",
681 hintToken.hint.toString()));
682 }
683
684 for (int i = 0; i < 4; i++) {
685 Literal lit = hintValues.get(i);
686 if ((lit.getLiteralType() != Literal.Type.DOUBLE)
687 && (lit.getLiteralType() != Literal.Type.FLOAT)
688 && (lit.getLiteralType() != Literal.Type.LONG)
689 && (lit.getLiteralType() != Literal.Type.INTEGER)){
690 throw new SqlppParseException(getSourceLocation(hintToken), String.format("Unexpected hint: %s. Numeric value is required for first 4 arguments.",
691 hintToken.hint.toString()));
692 }
693 }
694
695 for (int i = 4; i < 6; i++) {
696 Literal lit = hintValues.get(i);
697 if ((lit.getLiteralType() != Literal.Type.LONG)
698 && (lit.getLiteralType() != Literal.Type.INTEGER)) {
699 throw new SqlppParseException(getSourceLocation(hintToken), String.format("Unexpected hint: %s. Long/int is required for last 2 arguments.",
700 hintToken.hint.toString()));
701 }
702 }
703
704 try {
705 double minX = ExpressionUtils.getDoubleValue(hintValues.get(0));
706 double minY = ExpressionUtils.getDoubleValue(hintValues.get(1));
707 double maxX = ExpressionUtils.getDoubleValue(hintValues.get(2));
708 double maxY = ExpressionUtils.getDoubleValue(hintValues.get(3));
709 int numRows = (int) ExpressionUtils.getLongValue(hintValues.get(4));
710 int numColumns = (int) ExpressionUtils.getLongValue(hintValues.get(5));
711 SpatialJoinAnnotation spatialJoinAnn = new SpatialJoinAnnotation(minX, minY, maxX, maxY, numRows, numColumns);
712 return spatialJoinAnn;
713 } catch (TypeMismatchException e) {
714 throw new SqlppParseException(getSourceLocation(hintToken), e.getMessage());
715 }
Dmitry Lychagin6fd8ab32020-12-03 09:04:14 -0800716 case USE_SECONDARY_INDEX_SEARCH_HINT:
717 if (hintToken.hintParams == null) {
Dmitry Lychagin7c624522020-12-04 18:01:45 -0800718 throw new SqlppParseException(getSourceLocation(hintToken), "Expected index name(s)");
Dmitry Lychagin6fd8ab32020-12-03 09:04:14 -0800719 } else {
Dmitry Lychagin7c624522020-12-04 18:01:45 -0800720 // if parameter parsing fails then ignore this hint
Dmitry Lychagin6fd8ab32020-12-03 09:04:14 -0800721 List<String> indexNames = parseParenthesizedIdentifierList(hintToken.hintParams);
722 return SecondaryIndexSearchPreferenceAnnotation.newInstance(indexNames);
723 }
724 default:
Dmitry Lychagin7c624522020-12-04 18:01:45 -0800725 throw new SqlppParseException(getSourceLocation(hintToken), "Unexpected hint");
Dmitry Lychagin6fd8ab32020-12-03 09:04:14 -0800726 }
Dmitry Lychagin7c624522020-12-04 18:01:45 -0800727 } catch (SqlppParseException e) {
728 if (warningCollector.shouldWarn()) {
Michael Blow7c838de2021-02-23 16:12:48 -0500729 warningCollector.warn(Warning.of(getSourceLocation(hintToken), ErrorCode.INVALID_HINT,
Dmitry Lychagin7c624522020-12-04 18:01:45 -0800730 hintToken.hint.toString(), e.getMessage()));
731 }
732 return onParseErrorReturn;
Dmitry Lychagin6fd8ab32020-12-03 09:04:14 -0800733 } catch (CompilationException e) {
Dmitry Lychagin7c624522020-12-04 18:01:45 -0800734 if (warningCollector.shouldWarn()) {
Michael Blow7c838de2021-02-23 16:12:48 -0500735 warningCollector.warn(Warning.of(getSourceLocation(hintToken), ErrorCode.INVALID_HINT,
Dmitry Lychagin7c624522020-12-04 18:01:45 -0800736 hintToken.hint.toString(), e.getMessage()));
737 }
738 return onParseErrorReturn;
Dmitry Lychagin6fd8ab32020-12-03 09:04:14 -0800739 }
740 }
741
Dmitry Lychaginf7bc6c12020-06-01 18:19:44 -0700742 private void ensureNoTypeDeclsInFunction(String fnName, List<Pair<VarIdentifier, TypeExpression>> paramList,
743 TypeExpression returnType, Token startToken) throws SqlppParseException {
744 for (Pair<VarIdentifier, TypeExpression> p : paramList) {
745 if (p.second != null) {
746 String paramName = SqlppVariableUtil.toUserDefinedName(p.first.getValue());
747 throw new SqlppParseException(getSourceLocation(startToken),
748 "Unexpected type declaration for parameter " + paramName + " in function " + fnName);
749 }
750 }
751 if (returnType != null) {
752 throw new SqlppParseException(getSourceLocation(startToken),
753 "Unexpected return type declaration for function " + fnName);
754 }
755 }
Dmitry Lychagin0a722532020-08-27 18:39:25 -0700756
757 private void ensureIntegerLiteral(LiteralExpr expr, String errorPrefix) throws SqlppParseException {
758 Literal lit = expr.getValue();
759 if (lit.getLiteralType() != Literal.Type.INTEGER && lit.getLiteralType() != Literal.Type.LONG) {
760 throw new SqlppParseException(expr.getSourceLocation(), errorPrefix + " should be an INTEGER");
761 }
762 }
Dmitry Lychagin13a40e12021-04-08 18:22:57 -0700763
764 private DataverseName createDataverseName(List<String> parts, int fromIndex, int toIndex, Token startToken)
765 throws SqlppParseException {
766 try {
767 return DataverseName.create(parts, fromIndex, toIndex);
768 } catch (AsterixException e) {
769 SqlppParseException pe = new SqlppParseException(getSourceLocation(startToken), e.getMessage());
770 pe.initCause(e);
771 throw pe;
772 }
773 }
Yingyi Bu391f09e2015-10-29 13:49:39 -0700774}
775
776PARSER_END(SQLPPParser)
777
Yingyi Bu391f09e2015-10-29 13:49:39 -0700778List<Statement> Statement() throws ParseException:
779{
780 scopeStack.push(RootScopeFactory.createRootScope(this));
781 List<Statement> decls = new ArrayList<Statement>();
782 Statement stmt = null;
783}
784{
Murtadha Hubaildc775222017-08-21 15:22:45 +0300785 (
Dmitry Lychaginaebd0312019-06-04 08:55:39 -0700786 (stmt = ExplainStatement()
Murtadha Hubaildc775222017-08-21 15:22:45 +0300787 {
788 decls.add(stmt);
789 }
790 )?
791 (<SEMICOLON>)+
Yingyi Bu391f09e2015-10-29 13:49:39 -0700792 )*
793 <EOF>
794 {
795 return decls;
796 }
797}
798
Dmitry Lychaginaebd0312019-06-04 08:55:39 -0700799Statement ExplainStatement() throws ParseException:
800{
801 Statement stmt = null;
802 Token explainToken = null;
803}
804{
805 ( <EXPLAIN> { explainToken = token; } )?
806 stmt = SingleStatement()
807 {
808 if (explainToken != null) {
809 if (stmt.getKind() == Statement.Kind.QUERY) {
810 ((Query)stmt).setExplain(true);
811 } else {
812 throw new SqlppParseException(getSourceLocation(explainToken),
813 "EXPLAIN is not supported for this kind of statement");
814 }
815 }
816 return stmt;
817 }
818}
819
Yingyi Bu391f09e2015-10-29 13:49:39 -0700820Statement SingleStatement() throws ParseException:
821{
822 Statement stmt = null;
823}
824{
825 (
826 stmt = DataverseDeclaration()
827 | stmt = FunctionDeclaration()
828 | stmt = CreateStatement()
829 | stmt = LoadStatement()
830 | stmt = DropStatement()
831 | stmt = WriteStatement()
832 | stmt = SetStatement()
833 | stmt = InsertStatement()
834 | stmt = DeleteStatement()
835 | stmt = UpdateStatement()
Yingyi Bucb5bf332017-01-02 22:19:50 -0800836 | stmt = UpsertStatement()
Yingyi Buab817482016-08-19 21:29:31 -0700837 | stmt = ConnectionStatement()
Yingyi Bu391f09e2015-10-29 13:49:39 -0700838 | stmt = CompactStatement()
Dmitry Lychaginaebd0312019-06-04 08:55:39 -0700839 | stmt = Query()
Yingyi Bu391f09e2015-10-29 13:49:39 -0700840 | stmt = RefreshExternalDatasetStatement()
Yingyi Bu391f09e2015-10-29 13:49:39 -0700841 )
842 {
843 return stmt;
844 }
845}
846
847DataverseDecl DataverseDeclaration() throws ParseException:
848{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -0700849 Token startToken = null;
Dmitry Lychagin13a40e12021-04-08 18:22:57 -0700850 DataverseName dvName = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -0700851}
852{
Dmitry Lychagin13a40e12021-04-08 18:22:57 -0700853 <USE> { startToken = token; } dvName = DataverseName()
Yingyi Bu391f09e2015-10-29 13:49:39 -0700854 {
Dmitry Lychagin13a40e12021-04-08 18:22:57 -0700855 defaultDataverse = dvName;
Dmitry Lychagin54c06012019-11-13 15:54:20 -0800856 DataverseDecl dvDecl = new DataverseDecl(defaultDataverse);
Dmitry Lychagin5c26b422018-06-01 10:22:16 -0700857 return addSourceLocation(dvDecl, startToken);
Yingyi Bu391f09e2015-10-29 13:49:39 -0700858 }
859}
860
861Statement CreateStatement() throws ParseException:
862{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -0700863 Token startToken = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -0700864 Statement stmt = null;
865}
866{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -0700867 <CREATE> { startToken = token; }
Yingyi Bu391f09e2015-10-29 13:49:39 -0700868 (
Dmitry Lychagindcb4ad22020-08-26 15:49:09 -0700869 stmt = CreateOrReplaceStatement(startToken)
870 | stmt = CreateTypeStatement(startToken)
Dmitry Lychagin314e2792019-11-26 14:35:42 -0800871 | stmt = CreateNodegroupStatement(startToken)
872 | stmt = CreateDatasetStatement(startToken)
873 | stmt = CreateIndexStatement(startToken)
874 | stmt = CreateDataverseStatement(startToken)
Dmitry Lychagindcb4ad22020-08-26 15:49:09 -0700875 | stmt = CreateFunctionStatement(startToken, false)
Ian Maxon38fe9402020-01-29 19:27:40 -0800876 | stmt = CreateAdapterStatement(startToken)
Dmitry Lychagin2a0848e2020-01-08 13:57:22 -0800877 | stmt = CreateSynonymStatement(startToken)
Dmitry Lychagin314e2792019-11-26 14:35:42 -0800878 | stmt = CreateFeedStatement(startToken)
879 | stmt = CreateFeedPolicyStatement(startToken)
Rui Guoe6986dd2020-11-25 19:50:06 -0800880 | stmt = CreateFullTextStatement(startToken)
Dmitry Lychagin793c39e2021-04-21 16:52:10 -0700881 | stmt = CreateViewStatement(startToken, false)
Yingyi Bu391f09e2015-10-29 13:49:39 -0700882 )
883 {
884 return stmt;
885 }
886}
887
Dmitry Lychagindcb4ad22020-08-26 15:49:09 -0700888Statement CreateOrReplaceStatement(Token startStmtToken) throws ParseException:
889{
890 Statement stmt = null;
891 Token replaceToken = null;
892}
893{
894 <OR> <IDENTIFIER> { replaceToken = token; }
895 (
896 stmt = CreateFunctionStatement(startStmtToken, true)
Dmitry Lychagin793c39e2021-04-21 16:52:10 -0700897 | stmt = CreateViewStatement(startStmtToken, true)
Dmitry Lychagindcb4ad22020-08-26 15:49:09 -0700898 )
899 {
900 // check expected token here to make the grammar extension plugin happy
901 expectToken(replaceToken, REPLACE);
902 return stmt;
903 }
904}
905
Dmitry Lychagin314e2792019-11-26 14:35:42 -0800906TypeDecl CreateTypeStatement(Token startStmtToken) throws ParseException:
907{
908 TypeDecl stmt = null;
909}
910{
911 <TYPE> stmt = TypeSpecification(startStmtToken)
912 {
913 return stmt;
914 }
915}
916
Dmitry Lychagine77cdac2019-08-05 11:37:47 -0700917TypeDecl TypeSpecification(Token startStmtToken) throws ParseException:
Yingyi Bu391f09e2015-10-29 13:49:39 -0700918{
Dmitry Lychagin54c06012019-11-13 15:54:20 -0800919 Pair<DataverseName,Identifier> nameComponents = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -0700920 boolean ifNotExists = false;
921 TypeExpression typeExpr = null;
922}
923{
Dmitry Lychagin314e2792019-11-26 14:35:42 -0800924 nameComponents = TypeName() ifNotExists = IfNotExists()
Till Westmannf6028272016-09-30 14:34:42 -0700925 <AS> typeExpr = RecordTypeDef()
Dmitry Lychagin314e2792019-11-26 14:35:42 -0800926 {
927 boolean dgen = false;
928 long numValues = -1;
929 String filename = null;
930 Token hintToken = fetchHint(startStmtToken, SqlppHint.DGEN_HINT);
931 if (hintToken != null) {
932 String hintParams = hintToken.hintParams;
933 String[] splits = hintParams != null ? hintParams.split("\\s+") : null;
934 if (splits == null || splits.length != 2) {
935 throw new SqlppParseException(getSourceLocation(hintToken),
936 "Expecting /*+ dgen <filename> <numberOfItems> */");
937 }
938 dgen = true;
939 filename = splits[0];
940 numValues = Long.parseLong(splits[1]);
Yingyi Bu391f09e2015-10-29 13:49:39 -0700941 }
Dmitry Lychagin314e2792019-11-26 14:35:42 -0800942 TypeDataGen tddg = new TypeDataGen(dgen, filename, numValues);
943 TypeDecl stmt = new TypeDecl(nameComponents.first, nameComponents.second, typeExpr, tddg, ifNotExists);
944 return addSourceLocation(stmt, startStmtToken);
945 }
946}
947
948NodegroupDecl CreateNodegroupStatement(Token startStmtToken) throws ParseException:
949{
950 NodegroupDecl stmt = null;
951}
952{
953 <NODEGROUP> stmt = NodegroupSpecification(startStmtToken)
954 {
955 return stmt;
956 }
Yingyi Bu391f09e2015-10-29 13:49:39 -0700957}
958
Dmitry Lychaginee54cc02018-05-25 19:26:18 -0700959NodegroupDecl NodegroupSpecification(Token startStmtToken) throws ParseException:
Yingyi Bu391f09e2015-10-29 13:49:39 -0700960{
961 String name = null;
962 String tmp = null;
963 boolean ifNotExists = false;
Dmitry Lychagin314e2792019-11-26 14:35:42 -0800964 List<Identifier> ncNames = new ArrayList<Identifier>();
Yingyi Bu391f09e2015-10-29 13:49:39 -0700965}
966{
Dmitry Lychagin314e2792019-11-26 14:35:42 -0800967 name = Identifier() ifNotExists = IfNotExists()
968 <ON> tmp = Identifier()
969 {
970 ncNames.add(new Identifier(tmp));
971 }
Yingyi Bu391f09e2015-10-29 13:49:39 -0700972 ( <COMMA> tmp = Identifier()
973 {
974 ncNames.add(new Identifier(tmp));
975 }
976 )*
Dmitry Lychagin314e2792019-11-26 14:35:42 -0800977 {
978 NodegroupDecl stmt = new NodegroupDecl(new Identifier(name), ncNames, ifNotExists);
979 return addSourceLocation(stmt, startStmtToken);
980 }
981}
982
983void Dataset() throws ParseException:
984{
985}
986{
987 (<DATASET>|<COLLECTION>)
988}
989
990DatasetDecl CreateDatasetStatement(Token startStmtToken) throws ParseException:
991{
992 DatasetDecl stmt = null;
993}
994{
995 (
996 (<INTERNAL>)? Dataset() stmt = DatasetSpecification(startStmtToken)
997 | <EXTERNAL> Dataset() stmt = ExternalDatasetSpecification(startStmtToken)
998 )
999 {
1000 return stmt;
1001 }
Yingyi Bu391f09e2015-10-29 13:49:39 -07001002}
1003
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07001004DatasetDecl DatasetSpecification(Token startStmtToken) throws ParseException:
Yingyi Bu391f09e2015-10-29 13:49:39 -07001005{
Dmitry Lychagin54c06012019-11-13 15:54:20 -08001006 Pair<DataverseName,Identifier> nameComponents = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07001007 boolean ifNotExists = false;
Dmitry Lychagin3e2623c2020-04-01 11:20:04 -07001008 TypeExpression typeExpr = null;
1009 TypeExpression metaTypeExpr = null;
Yingyi Buc9bfe252016-03-01 00:02:40 -08001010 Pair<List<Integer>, List<List<String>>> primaryKeyFields = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07001011 Map<String,String> hints = new HashMap<String,String>();
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07001012 DatasetDecl stmt = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07001013 boolean autogenerated = false;
Yingyi Buc9bfe252016-03-01 00:02:40 -08001014 Pair<Integer, List<String>> filterField = null;
Till Westmannf3aa19f2017-12-01 17:42:35 -08001015 RecordConstructor withRecord = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07001016}
1017{
Dmitry Lychagin314e2792019-11-26 14:35:42 -08001018 nameComponents = QualifiedName()
Dmitry Lychagin5cc254a2020-05-08 17:12:47 -07001019 typeExpr = DatasetTypeSpecification()
Yingyi Bu391f09e2015-10-29 13:49:39 -07001020 (
Dmitry Lychagin314e2792019-11-26 14:35:42 -08001021 { String name; }
1022 <WITH>
1023 name = Identifier()
Yingyi Bu391f09e2015-10-29 13:49:39 -07001024 {
Dmitry Lychagin314e2792019-11-26 14:35:42 -08001025 if (!name.equalsIgnoreCase("meta")){
1026 throw new SqlppParseException(getSourceLocation(startStmtToken),
1027 "We can only support one additional associated field called \"meta\".");
1028 }
Yingyi Bu391f09e2015-10-29 13:49:39 -07001029 }
Dmitry Lychagin5cc254a2020-05-08 17:12:47 -07001030 metaTypeExpr = DatasetTypeSpecification()
Dmitry Lychagin314e2792019-11-26 14:35:42 -08001031 )?
1032 ifNotExists = IfNotExists()
1033 primaryKeyFields = PrimaryKey()
1034 (<AUTOGENERATED> { autogenerated = true; } )?
Dmitry Lychagin314e2792019-11-26 14:35:42 -08001035 ( <HINTS> hints = Properties() )?
1036 ( LOOKAHEAD(2) <WITH> <FILTER> <ON> filterField = NestedField() )?
1037 ( <WITH> withRecord = RecordConstructor() )?
1038 {
Dmitry Lychagin314e2792019-11-26 14:35:42 -08001039 try {
Xikui Wangca7927f2020-09-03 11:27:57 -07001040 InternalDetailsDecl idd = new InternalDetailsDecl(primaryKeyFields.second, primaryKeyFields.first, autogenerated,
1041 filterField == null? null : filterField.first, filterField == null? null : filterField.second);
Dmitry Lychagin4fb583d2021-11-10 17:25:28 -08001042 DatasetDeclParametersUtil.adjustInlineTypeDecl(typeExpr, primaryKeyFields.second, primaryKeyFields.first, false);
1043 if (metaTypeExpr != null) {
1044 DatasetDeclParametersUtil.adjustInlineTypeDecl(metaTypeExpr, primaryKeyFields.second, primaryKeyFields.first,
1045 true);
1046 }
Murtadha Hubail353e95f2020-08-24 22:18:04 +03001047 stmt = new DatasetDecl(nameComponents.first, nameComponents.second, typeExpr, metaTypeExpr, hints,
1048 DatasetType.INTERNAL, idd, withRecord, ifNotExists);
Dmitry Lychagin314e2792019-11-26 14:35:42 -08001049 return addSourceLocation(stmt, startStmtToken);
1050 } catch (CompilationException e) {
1051 throw new SqlppParseException(getSourceLocation(startStmtToken), e.getMessage());
1052 }
1053 }
1054}
1055
1056DatasetDecl ExternalDatasetSpecification(Token startStmtToken) throws ParseException:
1057{
1058 Pair<DataverseName,Identifier> nameComponents = null;
Dmitry Lychagin5cc254a2020-05-08 17:12:47 -07001059 TypeExpression typeExpr = null;
Dmitry Lychagin314e2792019-11-26 14:35:42 -08001060 boolean ifNotExists = false;
Dmitry Lychagin314e2792019-11-26 14:35:42 -08001061 String adapterName = null;
1062 Map<String,String> properties = null;
Dmitry Lychagin314e2792019-11-26 14:35:42 -08001063 Map<String,String> hints = new HashMap<String,String>();
1064 DatasetDecl stmt = null;
Dmitry Lychagin314e2792019-11-26 14:35:42 -08001065 RecordConstructor withRecord = null;
1066}
1067{
1068 nameComponents = QualifiedName()
Dmitry Lychagin5cc254a2020-05-08 17:12:47 -07001069 typeExpr = DatasetTypeSpecification()
Dmitry Lychagin314e2792019-11-26 14:35:42 -08001070 ifNotExists = IfNotExists()
1071 <USING> adapterName = AdapterName() properties = Configuration()
Dmitry Lychagin314e2792019-11-26 14:35:42 -08001072 ( <HINTS> hints = Properties() )?
1073 ( <WITH> withRecord = RecordConstructor() )?
1074 {
1075 ExternalDetailsDecl edd = new ExternalDetailsDecl();
1076 edd.setAdapter(adapterName);
1077 edd.setProperties(properties);
1078 try {
Murtadha Hubail353e95f2020-08-24 22:18:04 +03001079 stmt = new DatasetDecl(nameComponents.first, nameComponents.second, typeExpr, null, hints, DatasetType.EXTERNAL,
1080 edd, withRecord, ifNotExists);
Dmitry Lychagin314e2792019-11-26 14:35:42 -08001081 return addSourceLocation(stmt, startStmtToken);
1082 } catch (CompilationException e) {
1083 throw new SqlppParseException(getSourceLocation(startStmtToken), e.getMessage());
1084 }
1085 }
Yingyi Bu391f09e2015-10-29 13:49:39 -07001086}
1087
Dmitry Lychagin3e2623c2020-04-01 11:20:04 -07001088TypeExpression DatasetTypeSpecification() throws ParseException:
1089{
1090 TypeExpression typeExpr = null;
1091}
1092{
1093 (
1094 LOOKAHEAD(3) typeExpr = DatasetRecordTypeSpecification(true)
1095 | typeExpr = DatasetReferenceTypeSpecification()
1096 )
1097 {
1098 return typeExpr;
1099 }
1100}
1101
1102TypeExpression DatasetReferenceTypeSpecification() throws ParseException:
1103{
1104 TypeExpression typeExpr = null;
1105}
1106{
1107 <LEFTPAREN> typeExpr = TypeReference() <RIGHTPAREN>
1108 {
1109 return typeExpr;
1110 }
1111}
1112
Dmitry Lychagin33c77f92021-07-21 15:59:04 -07001113RecordTypeDefinition DatasetRecordTypeSpecification(boolean allowRecordKindModifier) throws ParseException:
Dmitry Lychagin3e2623c2020-04-01 11:20:04 -07001114{
1115 RecordTypeDefinition recordTypeDef = null;
1116 RecordTypeDefinition.RecordKind recordKind = null;
Dmitry Lychagin6c239e72020-06-19 19:46:27 -07001117 Token startToken = null, recordKindToken = null;
Dmitry Lychagin3e2623c2020-04-01 11:20:04 -07001118}
1119{
Dmitry Lychagin6c239e72020-06-19 19:46:27 -07001120 <LEFTPAREN> { startToken = token; } recordTypeDef = DatasetRecordTypeDef() <RIGHTPAREN>
Dmitry Lychagin3e2623c2020-04-01 11:20:04 -07001121 ( recordKind = RecordTypeKind() { recordKindToken = token; } <TYPE> )?
1122 {
1123 if (recordKind == null) {
1124 recordKind = RecordTypeDefinition.RecordKind.CLOSED;
1125 } else if (!allowRecordKindModifier) {
1126 throw createUnexpectedTokenError(recordKindToken);
1127 }
1128 recordTypeDef.setRecordKind(recordKind);
Dmitry Lychagin6c239e72020-06-19 19:46:27 -07001129 return addSourceLocation(recordTypeDef, startToken);
Dmitry Lychagin3e2623c2020-04-01 11:20:04 -07001130 }
1131}
1132
1133RecordTypeDefinition DatasetRecordTypeDef() throws ParseException:
1134{
1135 RecordTypeDefinition recType = new RecordTypeDefinition();
1136}
1137{
1138 DatasetRecordField(recType) ( <COMMA> DatasetRecordField(recType) )*
1139 {
1140 return recType;
1141 }
1142}
1143
1144void DatasetRecordField(RecordTypeDefinition recType) throws ParseException:
1145{
1146 String fieldName;
1147 TypeExpression type = null;
Dmitry Lychagin3a628022020-05-12 18:09:02 -07001148 boolean nullable = true, missable = true;
Dmitry Lychagin3e2623c2020-04-01 11:20:04 -07001149}
1150{
1151 fieldName = Identifier()
Dmitry Lychagin3a628022020-05-12 18:09:02 -07001152 type = TypeReference() ( <NOT> <UNKNOWN> { nullable = false; missable = false; } )?
Dmitry Lychagin3e2623c2020-04-01 11:20:04 -07001153 {
Dmitry Lychagin3a628022020-05-12 18:09:02 -07001154 recType.addField(fieldName, type, nullable, missable);
Dmitry Lychagin3e2623c2020-04-01 11:20:04 -07001155 }
1156}
1157
Yingyi Bu391f09e2015-10-29 13:49:39 -07001158RefreshExternalDatasetStatement RefreshExternalDatasetStatement() throws ParseException:
1159{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07001160 Token startToken = null;
Dmitry Lychagin54c06012019-11-13 15:54:20 -08001161 Pair<DataverseName,Identifier> nameComponents = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07001162 String datasetName = null;
1163}
1164{
Dmitry Lychagin314e2792019-11-26 14:35:42 -08001165 <REFRESH> { startToken = token; } <EXTERNAL> Dataset() nameComponents = QualifiedName()
1166 {
1167 RefreshExternalDatasetStatement stmt = new RefreshExternalDatasetStatement();
1168 stmt.setDataverseName(nameComponents.first);
1169 stmt.setDatasetName(nameComponents.second);
1170 return addSourceLocation(stmt, startToken);
1171 }
1172}
1173
1174CreateIndexStatement CreateIndexStatement(Token startStmtToken) throws ParseException:
1175{
1176 CreateIndexStatement stmt = null;
1177}
1178{
1179 (
1180 <INDEX> stmt = IndexSpecification(startStmtToken)
1181 | <PRIMARY> <INDEX> stmt = PrimaryIndexSpecification(startStmtToken)
1182 )
1183 {
1184 return stmt;
1185 }
Yingyi Bu391f09e2015-10-29 13:49:39 -07001186}
1187
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07001188CreateIndexStatement IndexSpecification(Token startStmtToken) throws ParseException:
Yingyi Bu391f09e2015-10-29 13:49:39 -07001189{
Dmitry Lychagin54c06012019-11-13 15:54:20 -08001190 Pair<DataverseName,Identifier> nameComponents = null;
Glenn67fd1f32021-02-25 16:04:49 -08001191 String indexName = null;
1192 IndexParams indexParams = null;
1193 CreateIndexStatement.IndexedElement indexedElement = null;
1194 List<CreateIndexStatement.IndexedElement> indexedElementList = new ArrayList<CreateIndexStatement.IndexedElement>();
Yingyi Bu391f09e2015-10-29 13:49:39 -07001195 boolean enforced = false;
Glenn67fd1f32021-02-25 16:04:49 -08001196 boolean ifNotExists = false;
1197 boolean hasUnnest = false;
1198 String fullTextConfigName = null;
1199 Token startElementToken = null;
Ali Alsuliman931e7382021-08-08 21:55:59 +03001200 Boolean excludeUnknown = null;
Ali Alsuliman465a7282021-11-24 12:51:32 -08001201 Pair<Map<String, String>, Boolean> castConfigDefaultNull;
Ali Alsuliman69ce7d82021-11-01 15:00:16 -07001202 Boolean castDefaultNull = null;
Ali Alsuliman465a7282021-11-24 12:51:32 -08001203 Map<String, String> castConfig = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07001204}
1205{
Ali Alsuliman8351d252017-09-24 00:43:15 -07001206 (
Dmitry Lychagin314e2792019-11-26 14:35:42 -08001207 indexName = Identifier() ifNotExists = IfNotExists()
Ali Alsuliman8351d252017-09-24 00:43:15 -07001208 <ON> nameComponents = QualifiedName()
Glenn67fd1f32021-02-25 16:04:49 -08001209 <LEFTPAREN> { startElementToken = token; }
1210 indexedElement = IndexedElement(startElementToken) {
1211 indexedElementList.add(indexedElement);
1212 hasUnnest |= indexedElement.hasUnnest();
Yingyi Bu391f09e2015-10-29 13:49:39 -07001213 }
Glenn67fd1f32021-02-25 16:04:49 -08001214 (<COMMA> { startElementToken = token; }
1215 indexedElement = IndexedElement(startElementToken) {
1216 indexedElementList.add(indexedElement);
1217 hasUnnest |= indexedElement.hasUnnest();
1218 }
1219 )*
1220 <RIGHTPAREN>
1221 ( <TYPE> indexParams = IndexType() )? ( <ENFORCED> { enforced = true; } )?
Ali Alsuliman69ce7d82021-11-01 15:00:16 -07001222 ( LOOKAHEAD({laIdentifier(EXCLUDE) || laIdentifier(INCLUDE)}) <IDENTIFIER>
1223 {
1224 if (isToken(EXCLUDE)) {
1225 excludeUnknown = true;
1226 } else if (isToken(INCLUDE)) {
1227 excludeUnknown = false;
1228 } else {
1229 throw createUnexpectedTokenError();
1230 }
1231 } <UNKNOWN> <KEY>
Ali Alsuliman931e7382021-08-08 21:55:59 +03001232 )?
Ali Alsuliman69ce7d82021-11-01 15:00:16 -07001233
Ali Alsuliman465a7282021-11-24 12:51:32 -08001234 ( <CAST><LEFTPAREN> castConfigDefaultNull = CastDefaultNull() <RIGHTPAREN>
1235 {
1236 castConfig = castConfigDefaultNull.first;
1237 castDefaultNull = castConfigDefaultNull.second;
1238 }
1239 )?
Ali Alsuliman8351d252017-09-24 00:43:15 -07001240 )
1241 {
Glenn67fd1f32021-02-25 16:04:49 -08001242 IndexType indexType;
1243 int gramLength;
1244 if (indexParams != null) {
1245 indexType = indexParams.type;
1246 gramLength = indexParams.gramLength;
1247 fullTextConfigName = indexParams.fullTextConfig;
1248 } else {
1249 indexType = hasUnnest ? IndexType.ARRAY : IndexType.BTREE;
1250 gramLength = -1;
1251 fullTextConfigName = null;
Ali Alsuliman8351d252017-09-24 00:43:15 -07001252 }
Glenn67fd1f32021-02-25 16:04:49 -08001253 CreateIndexStatement stmt = new CreateIndexStatement(nameComponents.first, nameComponents.second,
Ali Alsuliman931e7382021-08-08 21:55:59 +03001254 new Identifier(indexName), indexType, indexedElementList, enforced, gramLength, fullTextConfigName, ifNotExists,
Ali Alsuliman465a7282021-11-24 12:51:32 -08001255 excludeUnknown, castDefaultNull, castConfig);
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07001256 return addSourceLocation(stmt, startStmtToken);
Ali Alsuliman8351d252017-09-24 00:43:15 -07001257 }
Yingyi Bu391f09e2015-10-29 13:49:39 -07001258}
1259
Glenn67fd1f32021-02-25 16:04:49 -08001260CreateIndexStatement.IndexedElement IndexedElement(Token startElementToken) throws ParseException:
1261{
1262 Triple<Integer, List<List<String>>, List<Pair<List<String>, IndexedTypeExpression>>> element = null;
1263 Pair<List<String>, IndexedTypeExpression> elementSimple = null;
1264 int elementSimpleSource = 0;
1265}
1266{
1267 (
1268 element = IndexedElementUnnestSelect()
1269 | (
1270 LOOKAHEAD({ laIdentifier(META) && laToken(2, LEFTPAREN) && laToken(3, RIGHTPAREN) })
1271 <IDENTIFIER> { expectToken(META); } <LEFTPAREN> <RIGHTPAREN>
1272 <DOT> elementSimple = IndexedField()
1273 { elementSimpleSource = 1; }
1274 )
1275 | elementSimple = IndexedField()
1276 | <LEFTPAREN> ( element = IndexedElementUnnestSelect() | elementSimple = IndexedField() ) <RIGHTPAREN>
1277 )
1278 {
1279 int source;
1280 List<List<String>> unnestList;
1281 List<Pair<List<String>, IndexedTypeExpression>> projectList;
1282 if (elementSimple != null) {
1283 source = elementSimpleSource;
1284 unnestList = null;
1285 projectList = Collections.singletonList(elementSimple);
1286 } else {
1287 source = element.first;
1288 unnestList = element.second;
1289 projectList = element.third;
1290 }
1291 CreateIndexStatement.IndexedElement ie = new CreateIndexStatement.IndexedElement(source, unnestList, projectList);
1292 ie.setSourceLocation(getSourceLocation(startElementToken));
1293 return ie;
1294 }
1295}
1296
1297Triple<Integer, List<List<String>>, List<Pair<List<String>, IndexedTypeExpression>>> IndexedElementUnnestSelect()
1298 throws ParseException:
1299{
1300 int source = 0;
1301 Pair<List<List<String>>, List<Pair<List<String>, IndexedTypeExpression>>> element = null;
1302}
1303{
1304 <UNNEST>
1305 (
1306 (
1307 LOOKAHEAD({ laIdentifier(META) && laToken(2, LEFTPAREN) && laToken(3, RIGHTPAREN) })
1308 <IDENTIFIER> { expectToken(META); } <LEFTPAREN> <RIGHTPAREN>
1309 <DOT> element = IndexedElementUnnestSelectBody() { source = 1; }
1310 ) | element = IndexedElementUnnestSelectBody()
1311 )
1312 {
1313 return new Triple<Integer, List<List<String>>, List<Pair<List<String>, IndexedTypeExpression>>>(
1314 source, element.first, element.second
1315 );
1316 }
1317}
1318
1319Pair<List<List<String>>, List<Pair<List<String>, IndexedTypeExpression>>> IndexedElementUnnestSelectBody()
1320 throws ParseException:
1321{
Dmitry Lychaginb9393132021-04-12 17:21:22 -07001322 Triple<List<String>, Token, Token> path = null;
Glenn67fd1f32021-02-25 16:04:49 -08001323 IndexedTypeExpression type = null;
1324 List<List<String>> unnestList = new ArrayList();
Glenn67fd1f32021-02-25 16:04:49 -08001325 List<Pair<List<String>, IndexedTypeExpression>> projectList = new ArrayList();
1326}
1327{
Dmitry Lychaginb9393132021-04-12 17:21:22 -07001328 path = MultipartIdentifier() { unnestList.add(path.first); }
1329 ( <UNNEST> path = MultipartIdentifier() { unnestList.add(path.first); })*
Glenn67fd1f32021-02-25 16:04:49 -08001330 (
Glenn58329202021-04-09 12:03:46 -07001331 ( <COLON> type = IndexedTypeExpr(false)
Glenn67fd1f32021-02-25 16:04:49 -08001332 {
1333 projectList.add(new Pair<List<String>, IndexedTypeExpression>(null, type));
1334 }
1335 ) |
1336 (
Glenn58329202021-04-09 12:03:46 -07001337 <SELECT> path = MultipartIdentifier() ( <COLON> type = IndexedTypeExpr(false) )?
1338 {
Dmitry Lychaginb9393132021-04-12 17:21:22 -07001339 projectList.add(new Pair<List<String>, IndexedTypeExpression>(path.first, type));
Glenn58329202021-04-09 12:03:46 -07001340 }
1341 ( <COMMA> path = MultipartIdentifier() ( <COLON> type = IndexedTypeExpr(false) )?
1342 {
Dmitry Lychaginb9393132021-04-12 17:21:22 -07001343 projectList.add(new Pair<List<String>, IndexedTypeExpression>(path.first, type));
Glenn58329202021-04-09 12:03:46 -07001344 }
1345 )*
Glenn67fd1f32021-02-25 16:04:49 -08001346 )
1347 )?
1348 {
1349 if (projectList.isEmpty()) {
1350 // To support the case (<UNNEST> IDENTIFIER)* IDENTIFIER w/o any type specification.
1351 projectList.add(new Pair<List<String>, IndexedTypeExpression>(null, null));
1352 }
1353
1354 return new Pair<List<List<String>>, List<Pair<List<String>, IndexedTypeExpression>>>(unnestList, projectList);
1355 }
1356}
1357
1358Pair<List<String>, IndexedTypeExpression> IndexedField() throws ParseException:
1359{
Dmitry Lychaginb9393132021-04-12 17:21:22 -07001360 Triple<List<String>, Token, Token> path = null;
Glenn67fd1f32021-02-25 16:04:49 -08001361 IndexedTypeExpression type = null;
1362}
1363{
Glenn58329202021-04-09 12:03:46 -07001364 path = MultipartIdentifier() ( <COLON> type = IndexedTypeExpr(true) )?
Glenn67fd1f32021-02-25 16:04:49 -08001365 {
Dmitry Lychaginb9393132021-04-12 17:21:22 -07001366 return new Pair<List<String>, IndexedTypeExpression>(path.first, type);
Glenn67fd1f32021-02-25 16:04:49 -08001367 }
1368}
1369
Dmitry Lychagin314e2792019-11-26 14:35:42 -08001370CreateIndexStatement PrimaryIndexSpecification(Token startStmtToken) throws ParseException:
1371{
Glenn67fd1f32021-02-25 16:04:49 -08001372 Pair<DataverseName,Identifier> nameComponents = null;
Dmitry Lychagin314e2792019-11-26 14:35:42 -08001373 String indexName = null;
1374 boolean ifNotExists = false;
Dmitry Lychagin314e2792019-11-26 14:35:42 -08001375}
1376{
1377 (indexName = Identifier())? ifNotExists = IfNotExists()
1378 <ON> nameComponents = QualifiedName() (<TYPE> <BTREE>)?
1379 {
1380 if (indexName == null) {
1381 indexName = "primary_idx_" + nameComponents.second;
1382 }
Glenn67fd1f32021-02-25 16:04:49 -08001383 CreateIndexStatement stmt = new CreateIndexStatement(nameComponents.first, nameComponents.second,
Ali Alsuliman465a7282021-11-24 12:51:32 -08001384 new Identifier(indexName), IndexType.BTREE, Collections.emptyList(), false, -1, null, ifNotExists, null, null,
1385 Collections.emptyMap());
Dmitry Lychagin314e2792019-11-26 14:35:42 -08001386 return addSourceLocation(stmt, startStmtToken);
1387 }
1388}
1389
Yingyi Bu391f09e2015-10-29 13:49:39 -07001390String FilterField() throws ParseException :
1391{
1392 String filterField = null;
1393}
1394{
1395 filterField = Identifier()
1396 {
1397 return filterField;
1398 }
1399}
1400
1401IndexParams IndexType() throws ParseException:
1402{
1403 IndexType type = null;
1404 int gramLength = 0;
Rui Guoe6986dd2020-11-25 19:50:06 -08001405 String fullTextConfig = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07001406}
1407{
1408 (<BTREE>
1409 {
1410 type = IndexType.BTREE;
1411 }
1412 | <RTREE>
1413 {
1414 type = IndexType.RTREE;
1415 }
1416 | <KEYWORD>
1417 {
1418 type = IndexType.LENGTH_PARTITIONED_WORD_INVIX;
1419 }
Rui Guoe6986dd2020-11-25 19:50:06 -08001420 | <FULLTEXT>
Taewoo Kimc49405a2017-01-04 00:30:43 -08001421 {
1422 type = IndexType.SINGLE_PARTITION_WORD_INVIX;
1423 }
Rui Guoe6986dd2020-11-25 19:50:06 -08001424 // For now we don't allow inverted index creation using a full-text config in another data verse.
1425 // We may want to support corss-dataverse full-text config access later
1426 // If so, replace the Identifier() with QualifiedName() to get the dataverse name
1427 ( <USING> Identifier()
1428 {
1429 fullTextConfig = token.image;
1430 }
1431 )?
Yingyi Bu391f09e2015-10-29 13:49:39 -07001432 | <NGRAM> <LEFTPAREN> <INTEGER_LITERAL>
1433 {
1434 type = IndexType.LENGTH_PARTITIONED_NGRAM_INVIX;
1435 gramLength = Integer.valueOf(token.image);
1436 }
1437 <RIGHTPAREN>)
1438 {
Rui Guoe6986dd2020-11-25 19:50:06 -08001439 return new IndexParams(type, gramLength, fullTextConfig);
Yingyi Bu391f09e2015-10-29 13:49:39 -07001440 }
1441}
1442
Dmitry Lychagin314e2792019-11-26 14:35:42 -08001443CreateDataverseStatement CreateDataverseStatement(Token startStmtToken) throws ParseException :
1444{
1445 CreateDataverseStatement stmt = null;
1446}
1447{
1448 <DATAVERSE> stmt = DataverseSpecification(startStmtToken)
1449 {
1450 return stmt;
1451 }
1452}
1453
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07001454CreateDataverseStatement DataverseSpecification(Token startStmtToken) throws ParseException :
Yingyi Bu391f09e2015-10-29 13:49:39 -07001455{
Dmitry Lychagin13a40e12021-04-08 18:22:57 -07001456 DataverseName dvName = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07001457 boolean ifNotExists = false;
Yingyi Bu391f09e2015-10-29 13:49:39 -07001458}
1459{
Dmitry Lychagin13a40e12021-04-08 18:22:57 -07001460 dvName = DataverseName() ifNotExists = IfNotExists()
Dmitry Lychagin314e2792019-11-26 14:35:42 -08001461 {
Dmitry Lychagin13a40e12021-04-08 18:22:57 -07001462 CreateDataverseStatement stmt = new CreateDataverseStatement(dvName, null, ifNotExists);
Dmitry Lychagin314e2792019-11-26 14:35:42 -08001463 return addSourceLocation(stmt, startStmtToken);
1464 }
1465}
1466
Ian Maxon38fe9402020-01-29 19:27:40 -08001467CreateAdapterStatement CreateAdapterStatement(Token startStmtToken) throws ParseException:
1468{
1469 CreateAdapterStatement stmt = null;
1470}
1471{
1472 <ADAPTER> stmt = AdapterSpecification(startStmtToken)
1473 {
1474 return stmt;
1475 }
1476}
1477
1478CreateAdapterStatement AdapterSpecification(Token startStmtToken) throws ParseException:
1479{
Dmitry Lychagin20905cd2020-08-06 20:34:55 -07001480 Pair<DataverseName,Identifier> adapterName = null;
1481 Pair<DataverseName,Identifier> libraryName = null;
1482 List<String> externalIdentifier = null;
Ian Maxon38fe9402020-01-29 19:27:40 -08001483 boolean ifNotExists = false;
1484}
1485{
Dmitry Lychagin20905cd2020-08-06 20:34:55 -07001486 adapterName = QualifiedName()
1487 ifNotExists = IfNotExists()
1488 <AS> externalIdentifier = FunctionExternalIdentifier()
1489 <AT> libraryName = QualifiedName()
1490 {
1491 CreateAdapterStatement stmt = new CreateAdapterStatement(adapterName.first, adapterName.second.getValue(),
1492 libraryName.first, libraryName.second.getValue(), externalIdentifier, ifNotExists);
1493 return addSourceLocation(stmt, startStmtToken);
1494 }
1495}
Ian Maxon38fe9402020-01-29 19:27:40 -08001496
Dmitry Lychagin793c39e2021-04-21 16:52:10 -07001497CreateViewStatement CreateViewStatement(Token startStmtToken, boolean orReplace) throws ParseException:
1498{
1499 CreateViewStatement stmt = null;
1500}
1501{
1502 <VIEW> stmt = ViewSpecification(startStmtToken, orReplace)
1503 {
1504 return stmt;
1505 }
1506}
1507
1508CreateViewStatement ViewSpecification(Token startStmtToken, boolean orReplace) throws ParseException:
1509{
1510 Pair<DataverseName, Identifier> nameComponents = null;
Dmitry Lychagin33c77f92021-07-21 15:59:04 -07001511 TypeExpression typeExpr = null;
Dmitry Lychagin793c39e2021-04-21 16:52:10 -07001512 boolean ifNotExists = false;
1513 Token beginPos = null, endPos = null;
1514 Expression viewBodyExpr = null;
Ali Alsuliman465a7282021-11-24 12:51:32 -08001515 Pair<Map<String, String>, Boolean> viewConfigDefaultNull;
Dmitry Lychagin33c77f92021-07-21 15:59:04 -07001516 Boolean defaultNull = null;
Dmitry Lychagin1f6f24e2021-08-19 21:41:57 -07001517 Map<String, String> viewConfig = null;
Dmitry Lychagin81578f92021-08-24 11:57:07 -07001518 Pair<List<Integer>, List<List<String>>> primaryKeyFields = null;
Dmitry Lychagin914983f2021-09-30 15:11:11 -07001519 Pair<List<Integer>, List<List<String>>> foreignKeyFields = null;
1520 Pair<DataverseName, Identifier> refNameComponents = null;
1521 List<CreateViewStatement.ForeignKeyDecl> foreignKeyDecls = null;
Dmitry Lychagin793c39e2021-04-21 16:52:10 -07001522 DataverseName currentDataverse = defaultDataverse;
1523}
1524{
1525 nameComponents = QualifiedName()
Dmitry Lychagin33c77f92021-07-21 15:59:04 -07001526 (
Dmitry Lychagin1f6f24e2021-08-19 21:41:57 -07001527 (
1528 typeExpr = DatasetTypeSpecification()
1529 ifNotExists = IfNotExists()
Ali Alsuliman465a7282021-11-24 12:51:32 -08001530 viewConfigDefaultNull = CastDefaultNull()
1531 {
1532 viewConfig = viewConfigDefaultNull.first;
1533 defaultNull = viewConfigDefaultNull.second;
1534 }
Dmitry Lychagin914983f2021-09-30 15:11:11 -07001535 (
1536 <PRIMARY> <KEY> <LEFTPAREN> primaryKeyFields = PrimaryKeyFields() <RIGHTPAREN>
1537 <NOT> <ENFORCED>
1538 )?
1539 (
1540 <IDENTIFIER> { expectToken(FOREIGN); } <KEY> <LEFTPAREN> foreignKeyFields = PrimaryKeyFields() <RIGHTPAREN>
1541 <IDENTIFIER> { expectToken(REFERENCES); } refNameComponents = QualifiedName()
1542 <NOT> <ENFORCED>
1543 {
1544 if (foreignKeyDecls == null) {
1545 foreignKeyDecls = new ArrayList<CreateViewStatement.ForeignKeyDecl>();
1546 }
1547 foreignKeyDecls.add(new CreateViewStatement.ForeignKeyDecl(foreignKeyFields.second,
1548 foreignKeyFields.first, refNameComponents.first, refNameComponents.second));
1549 }
1550 )*
Dmitry Lychagin1f6f24e2021-08-19 21:41:57 -07001551 )
1552 |
1553 ( ifNotExists = IfNotExists() )
Dmitry Lychagin33c77f92021-07-21 15:59:04 -07001554 )
Dmitry Lychagin793c39e2021-04-21 16:52:10 -07001555 {
1556 if (orReplace && ifNotExists) {
Dmitry Lychagin33c77f92021-07-21 15:59:04 -07001557 throw new SqlppParseException(getSourceLocation(startStmtToken), "Unexpected IF NOT EXISTS");
Dmitry Lychagin793c39e2021-04-21 16:52:10 -07001558 }
1559 }
1560 <AS>
1561 {
1562 beginPos = token;
1563 createNewScope();
1564 if (nameComponents.first != null) {
1565 defaultDataverse = nameComponents.first;
1566 }
1567 }
1568 viewBodyExpr = ViewBody()
1569 {
1570 endPos = token;
1571 String viewBody = extractFragment(beginPos.beginLine, beginPos.beginColumn + 1, endPos.endLine,
1572 endPos.endColumn + 1);
1573 removeCurrentScope();
1574 defaultDataverse = currentDataverse;
Dmitry Lychagin4fb583d2021-11-10 17:25:28 -08001575 if (typeExpr != null && primaryKeyFields != null) {
1576 DatasetDeclParametersUtil.adjustInlineTypeDecl(typeExpr, primaryKeyFields.second, primaryKeyFields.first, false);
1577 }
Dmitry Lychagin914983f2021-09-30 15:11:11 -07001578 CreateViewStatement.KeyDecl primaryKeyDecl = primaryKeyFields != null ?
1579 new CreateViewStatement.KeyDecl(primaryKeyFields.second, primaryKeyFields.first) : null;
1580 CreateViewStatement stmt = new CreateViewStatement(nameComponents.first, nameComponents.second.getValue(),
1581 typeExpr, viewBody, viewBodyExpr, defaultNull, viewConfig, primaryKeyDecl, foreignKeyDecls, orReplace,
1582 ifNotExists);
Dmitry Lychagin793c39e2021-04-21 16:52:10 -07001583 return addSourceLocation(stmt, startStmtToken);
1584 }
1585}
1586
1587Expression ViewBody() throws ParseException:
1588{
1589 Expression viewBodyExpr = null;
1590}
1591{
Dmitry Lychagin33c77f92021-07-21 15:59:04 -07001592 (
1593 ( viewBodyExpr = VariableRef() ( viewBodyExpr = FieldAccessor(viewBodyExpr) )* )
1594 | viewBodyExpr = SelectExpression(true)
1595 )
Dmitry Lychagin793c39e2021-04-21 16:52:10 -07001596 {
1597 return viewBodyExpr;
1598 }
1599}
1600
Ali Alsuliman465a7282021-11-24 12:51:32 -08001601Pair<Map<String, String>, Boolean> CastDefaultNull() throws ParseException:
1602{
1603 Map<String, String> castConfig = null;
1604 Boolean defaultNull = null;
1605 String propertyName = null, propertyValue = null;
1606}
1607{
1608 <IDENTIFIER> { expectToken(DEFAULT); } <NULL> { defaultNull = true; }
1609 (
1610 LOOKAHEAD(2) <IDENTIFIER> { propertyName = token.image.toLowerCase(); } propertyValue = StringLiteral()
1611 {
1612 if (castConfig == null) {
1613 castConfig = new HashMap<String, String>();
1614 }
1615 castConfig.put(propertyName, propertyValue);
1616 }
1617 )*
1618 {
1619 return new Pair<Map<String, String>, Boolean>(castConfig, defaultNull);
1620 }
1621}
1622
Dmitry Lychagindcb4ad22020-08-26 15:49:09 -07001623CreateFunctionStatement CreateFunctionStatement(Token startStmtToken, boolean orReplace) throws ParseException:
Dmitry Lychagin20905cd2020-08-06 20:34:55 -07001624{
1625 CreateFunctionStatement stmt = null;
1626}
1627{
Dmitry Lychagindcb4ad22020-08-26 15:49:09 -07001628 <FUNCTION> stmt = FunctionSpecification(startStmtToken, orReplace)
Dmitry Lychagin20905cd2020-08-06 20:34:55 -07001629 {
1630 return stmt;
1631 }
Ian Maxon38fe9402020-01-29 19:27:40 -08001632}
1633
Dmitry Lychagindcb4ad22020-08-26 15:49:09 -07001634CreateFunctionStatement FunctionSpecification(Token startStmtToken, boolean orReplace) throws ParseException:
Yingyi Bu391f09e2015-10-29 13:49:39 -07001635{
Ian Maxon38fe9402020-01-29 19:27:40 -08001636 FunctionSignature signature = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07001637 FunctionName fctName = null;
Dmitry Lychagin541652082020-11-09 14:04:53 -08001638 Pair<Integer, List<Pair<VarIdentifier,TypeExpression>>> paramsWithArity = null;
Dmitry Lychaginf7bc6c12020-06-01 18:19:44 -07001639 List<Pair<VarIdentifier,TypeExpression>> params = null;
Dmitry Lychagin541652082020-11-09 14:04:53 -08001640 int arity = 0;
Dmitry Lychagin20905cd2020-08-06 20:34:55 -07001641 TypeExpression returnType = null;
1642 Token beginPos = null, endPos = null;
1643 Expression functionBodyExpr = null;
1644 Pair<DataverseName,Identifier> libraryName = null;
1645 List<String> externalIdentifier = null;
1646 RecordConstructor withOptions = null;
1647 boolean ifNotExists = false;
1648 CreateFunctionStatement stmt = null;
1649 DataverseName currentDataverse = defaultDataverse;
Yingyi Bu391f09e2015-10-29 13:49:39 -07001650}
1651{
Dmitry Lychagin314e2792019-11-26 14:35:42 -08001652 fctName = FunctionName()
Steven Glenn Jacobs665e9fe2017-12-27 10:30:39 -08001653 {
1654 defaultDataverse = fctName.dataverse;
1655 }
Dmitry Lychagin541652082020-11-09 14:04:53 -08001656 paramsWithArity = FunctionParameters()
1657 {
1658 arity = paramsWithArity.first;
1659 params = paramsWithArity.second;
Dmitry Lychagin265e3ce2021-03-02 12:22:38 -08001660 signature = new FunctionSignature(fctName.dataverse, fctName.function, arity);
Dmitry Lychagin541652082020-11-09 14:04:53 -08001661 }
Dmitry Lychagin265e3ce2021-03-02 12:22:38 -08001662 ifNotExists = IfNotExists()
Dmitry Lychagin793c39e2021-04-21 16:52:10 -07001663 {
1664 if (orReplace && ifNotExists) {
1665 throw new SqlppParseException(getSourceLocation(token), "Unexpected IF NOT EXISTS");
1666 }
1667 }
Dmitry Lychagin0d4c1b62020-02-07 17:10:16 -08001668 returnType = FunctionReturnType()
Ian Maxon38fe9402020-01-29 19:27:40 -08001669 (
1670 (
1671 <LEFTBRACE>
1672 {
Dmitry Lychagin20905cd2020-08-06 20:34:55 -07001673 beginPos = token;
1674 createNewScope();
Ian Maxon38fe9402020-01-29 19:27:40 -08001675 }
Dmitry Lychagin45de2342020-02-03 12:01:28 -08001676 functionBodyExpr = FunctionBody()
Dmitry Lychagin20905cd2020-08-06 20:34:55 -07001677 <RIGHTBRACE>
1678 {
1679 endPos = token;
1680 String functionBody = extractFragment(beginPos.beginLine, beginPos.beginColumn, endPos.beginLine,
1681 endPos.beginColumn);
Dmitry Lychagin20905cd2020-08-06 20:34:55 -07001682 getCurrentScope().addFunctionDescriptor(signature, false);
1683 removeCurrentScope();
Dmitry Lychagin20905cd2020-08-06 20:34:55 -07001684 ensureNoTypeDeclsInFunction(fctName.function, params, returnType, startStmtToken);
Dmitry Lychagindcb4ad22020-08-26 15:49:09 -07001685 stmt = new CreateFunctionStatement(signature, params, functionBody, functionBodyExpr, orReplace, ifNotExists);
Dmitry Lychagin20905cd2020-08-06 20:34:55 -07001686 }
Ian Maxon38fe9402020-01-29 19:27:40 -08001687 )
1688 |
Dmitry Lychagin20905cd2020-08-06 20:34:55 -07001689 (
1690 <AS> externalIdentifier = FunctionExternalIdentifier()
1691 <AT> libraryName = QualifiedName()
1692 (<WITH> withOptions = RecordConstructor())?
1693 {
Dmitry Lychagin20905cd2020-08-06 20:34:55 -07001694 try {
1695 stmt = new CreateFunctionStatement(signature, params, returnType, libraryName.first,
Dmitry Lychagindcb4ad22020-08-26 15:49:09 -07001696 libraryName.second.getValue(), externalIdentifier, withOptions, orReplace, ifNotExists);
Dmitry Lychagin20905cd2020-08-06 20:34:55 -07001697 } catch (AlgebricksException e) {
1698 throw new SqlppParseException(getSourceLocation(startStmtToken), e.getMessage());
1699 }
Dmitry Lychagin20905cd2020-08-06 20:34:55 -07001700 }
1701 )
Ian Maxon38fe9402020-01-29 19:27:40 -08001702 )
Dmitry Lychagin265e3ce2021-03-02 12:22:38 -08001703 {
Dmitry Lychagin265e3ce2021-03-02 12:22:38 -08001704 defaultDataverse = currentDataverse;
1705 return addSourceLocation(stmt, startStmtToken);
1706 }
Dmitry Lychagin314e2792019-11-26 14:35:42 -08001707}
1708
Dmitry Lychagin541652082020-11-09 14:04:53 -08001709Pair<Integer, List<Pair<VarIdentifier, TypeExpression>>> FunctionParameters() :
Dmitry Lychagin0d4c1b62020-02-07 17:10:16 -08001710{
Dmitry Lychagin541652082020-11-09 14:04:53 -08001711 Pair<Integer, List<Pair<VarIdentifier, TypeExpression>>> params = null;
Dmitry Lychagin0d4c1b62020-02-07 17:10:16 -08001712}
1713{
Dmitry Lychagin541652082020-11-09 14:04:53 -08001714 <LEFTPAREN> (params = FunctionParameterList())? <RIGHTPAREN>
Dmitry Lychagin0d4c1b62020-02-07 17:10:16 -08001715 {
Dmitry Lychagin541652082020-11-09 14:04:53 -08001716 if (params == null) {
1717 params = new Pair<Integer, List<Pair<VarIdentifier, TypeExpression>>>(
1718 0, Collections.<Pair<VarIdentifier, TypeExpression>>emptyList()
1719 );
1720 }
1721 return params;
Dmitry Lychagin0d4c1b62020-02-07 17:10:16 -08001722 }
1723}
1724
Dmitry Lychagin541652082020-11-09 14:04:53 -08001725Pair<Integer, List<Pair<VarIdentifier, TypeExpression>>> FunctionParameterList() :
Dmitry Lychagin0d4c1b62020-02-07 17:10:16 -08001726{
Dmitry Lychagin541652082020-11-09 14:04:53 -08001727 List<Pair<VarIdentifier, TypeExpression>> paramList = null;
1728 Pair<VarIdentifier, TypeExpression> param = null;
1729 int arity = 0;
Dmitry Lychagin0d4c1b62020-02-07 17:10:16 -08001730}
1731{
Dmitry Lychagin541652082020-11-09 14:04:53 -08001732 (
1733 (
1734 <DOT> <DOT> <DOT>
1735 {
1736 param = new Pair<VarIdentifier, TypeExpression>(
1737 SqlppVariableUtil.toInternalVariableIdentifier(UDF_VARARGS_PARAM_NAME), null
1738 );
1739 paramList = Collections.<Pair<VarIdentifier, TypeExpression>>singletonList(param);
1740 arity = FunctionIdentifier.VARARGS;
1741 }
1742 )
1743 |
1744 (
1745 param = FunctionParameter()
1746 {
1747 paramList = new ArrayList<Pair<VarIdentifier, TypeExpression>>();
1748 paramList.add(param);
1749 }
1750 ( <COMMA> param = FunctionParameter() { paramList.add(param); } )*
1751 {
1752 arity = paramList.size();
1753 }
1754 )
1755 )
Dmitry Lychaginf7bc6c12020-06-01 18:19:44 -07001756 {
Dmitry Lychagin541652082020-11-09 14:04:53 -08001757 return new Pair<Integer, List<Pair<VarIdentifier, TypeExpression>>>(arity, paramList);
Dmitry Lychaginf7bc6c12020-06-01 18:19:44 -07001758 }
Dmitry Lychagin0d4c1b62020-02-07 17:10:16 -08001759}
1760
Dmitry Lychaginf7bc6c12020-06-01 18:19:44 -07001761Pair<VarIdentifier,TypeExpression> FunctionParameter() throws ParseException:
Dmitry Lychagin0d4c1b62020-02-07 17:10:16 -08001762{
Dmitry Lychaginf7bc6c12020-06-01 18:19:44 -07001763 String name = null;
1764 TypeExpression type = null;
Dmitry Lychagin0d4c1b62020-02-07 17:10:16 -08001765}
1766{
Dmitry Lychaginf7bc6c12020-06-01 18:19:44 -07001767 name = VariableIdentifier()
1768 ( LOOKAHEAD(3) (<COLON>)? type = TypeExpr(false) )?
1769 {
1770 return new Pair<VarIdentifier,TypeExpression>(new VarIdentifier(name), type);
1771 }
1772}
1773
1774TypeExpression FunctionReturnType() throws ParseException:
1775{
1776 TypeExpression returnType = null;
1777}
1778{
1779 ( LOOKAHEAD({laIdentifier(RETURNS)}) <IDENTIFIER> returnType = TypeExpr(false) )?
Dmitry Lychagin0d4c1b62020-02-07 17:10:16 -08001780 {
1781 return returnType;
1782 }
1783}
1784
Dmitry Lychagin45de2342020-02-03 12:01:28 -08001785Expression FunctionBody() throws ParseException:
1786{
1787 Expression functionBodyExpr = null;
1788}
1789{
1790 ( functionBodyExpr = SelectExpression(true) | functionBodyExpr = Expression() )
1791 {
1792 return functionBodyExpr;
1793 }
1794}
1795
Dmitry Lychagin20905cd2020-08-06 20:34:55 -07001796List<String> FunctionExternalIdentifier() throws ParseException:
1797{
1798 String ident = null;
1799 List<String> identList = new ArrayList(2);
1800}
1801{
1802 ident = StringLiteral() { identList.add(ident.trim()); }
1803 ( <COMMA> ident = StringLiteral() { identList.add(ident.trim()); } )*
1804 {
1805 return identList;
1806 }
1807}
1808
Dmitry Lychagin314e2792019-11-26 14:35:42 -08001809CreateFeedStatement CreateFeedStatement(Token startStmtToken) throws ParseException:
1810{
1811 CreateFeedStatement stmt = null;
1812}
1813{
1814 <FEED> stmt = FeedSpecification(startStmtToken)
1815 {
1816 return stmt;
1817 }
Yingyi Bu391f09e2015-10-29 13:49:39 -07001818}
1819
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07001820CreateFeedStatement FeedSpecification(Token startStmtToken) throws ParseException:
Yingyi Bu391f09e2015-10-29 13:49:39 -07001821{
Dmitry Lychagin54c06012019-11-13 15:54:20 -08001822 Pair<DataverseName,Identifier> nameComponents = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07001823 boolean ifNotExists = false;
1824 String adapterName = null;
1825 Map<String,String> properties = null;
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07001826 CreateFeedStatement stmt = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07001827 Pair<Identifier,Identifier> sourceNameComponents = null;
Xikui Wang5a61b2a2018-01-02 14:14:03 -08001828 RecordConstructor withRecord = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07001829}
1830{
Dmitry Lychagin314e2792019-11-26 14:35:42 -08001831 nameComponents = QualifiedName() ifNotExists = IfNotExists()
Xikui Wang5a61b2a2018-01-02 14:14:03 -08001832 <WITH> withRecord = RecordConstructor()
Abdullah Alamoudifff200c2017-02-18 20:32:14 -08001833 {
Xikui Wang5a61b2a2018-01-02 14:14:03 -08001834 try {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07001835 stmt = new CreateFeedStatement(nameComponents, withRecord, ifNotExists);
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07001836 return addSourceLocation(stmt, startStmtToken);
Xikui Wang5a61b2a2018-01-02 14:14:03 -08001837 } catch (AlgebricksException e) {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07001838 throw new SqlppParseException(getSourceLocation(startStmtToken), e.getMessage());
Xikui Wang5a61b2a2018-01-02 14:14:03 -08001839 }
Abdullah Alamoudifff200c2017-02-18 20:32:14 -08001840 }
Yingyi Bu391f09e2015-10-29 13:49:39 -07001841}
1842
Dmitry Lychagin314e2792019-11-26 14:35:42 -08001843CreateFeedPolicyStatement CreateFeedPolicyStatement(Token startStmtToken) throws ParseException:
1844{
1845 CreateFeedPolicyStatement stmt = null;
1846}
1847{
1848 <INGESTION> <POLICY> stmt = FeedPolicySpecification(startStmtToken)
1849 {
1850 return stmt;
1851 }
1852}
1853
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07001854CreateFeedPolicyStatement FeedPolicySpecification(Token startStmtToken) throws ParseException:
Yingyi Bu391f09e2015-10-29 13:49:39 -07001855{
Michael Blowd6cf6412016-06-30 02:44:35 -04001856 String policyName = null;
1857 String basePolicyName = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07001858 String sourcePolicyFile = null;
1859 String definition = null;
1860 boolean ifNotExists = false;
1861 Map<String,String> properties = null;
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07001862 CreateFeedPolicyStatement stmt = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07001863}
1864{
Dmitry Lychagin314e2792019-11-26 14:35:42 -08001865 policyName = Identifier() ifNotExists = IfNotExists()
1866 <FROM>
1867 (<POLICY> basePolicyName = Identifier() properties = Configuration() (<DEFINITION> definition = ConstantString())?
Yingyi Bu391f09e2015-10-29 13:49:39 -07001868 {
Dmitry Lychagin314e2792019-11-26 14:35:42 -08001869 stmt = new CreateFeedPolicyStatement(policyName, basePolicyName, properties, definition, ifNotExists);
Yingyi Bu391f09e2015-10-29 13:49:39 -07001870 }
Dmitry Lychagin314e2792019-11-26 14:35:42 -08001871 | <PATH> sourcePolicyFile = ConstantString() (<DEFINITION> definition = ConstantString())?
1872 {
1873 stmt = new CreateFeedPolicyStatement(policyName, sourcePolicyFile, definition, ifNotExists);
1874 }
1875 )
1876 {
1877 return addSourceLocation(stmt, startStmtToken);
1878 }
Yingyi Bu391f09e2015-10-29 13:49:39 -07001879}
1880
Rui Guoe6986dd2020-11-25 19:50:06 -08001881Statement CreateFullTextStatement(Token startStmtToken) throws ParseException:
1882{
1883 Statement stmt = null;
1884}
1885{
1886 (
1887 <FULLTEXT>
1888 (
1889 <FILTER> stmt = CreateFullTextFilterSpec(startStmtToken)
1890 | (<IDENTIFIER> { expectToken(CONFIG); } stmt = CreateFullTextConfigSpec(startStmtToken))
1891 )
1892 )
1893 {
1894 return stmt;
1895 }
1896}
1897
1898CreateFullTextFilterStatement CreateFullTextFilterSpec(Token startStmtToken) throws ParseException:
1899{
1900 CreateFullTextFilterStatement stmt = null;
1901 Pair<DataverseName,Identifier> nameComponents = null;
1902 boolean ifNotExists = false;
1903 RecordConstructor expr = null;
1904}
1905{
1906 (
1907 nameComponents = QualifiedName() ifNotExists = IfNotExists()
1908 <AS>
1909 expr = RecordConstructor()
1910 )
1911 {
1912 try {
1913 stmt = new CreateFullTextFilterStatement(nameComponents.first, nameComponents.second.getValue(), ifNotExists, expr);
1914 return addSourceLocation(stmt, startStmtToken);
1915 } catch (CompilationException e) {
1916 throw new SqlppParseException(getSourceLocation(startStmtToken), e.getMessage());
1917 }
1918 }
1919}
1920
1921CreateFullTextConfigStatement CreateFullTextConfigSpec(Token startStmtToken) throws ParseException:
1922{
1923 CreateFullTextConfigStatement stmt = null;
1924 Pair<DataverseName,Identifier> nameComponents = null;
1925 boolean ifNotExists = false;
1926 RecordConstructor expr = null;
1927}
1928{
1929 (
1930 nameComponents = QualifiedName() ifNotExists = IfNotExists()
1931 <AS>
1932 expr = RecordConstructor()
1933 )
1934 {
1935 try {
1936 stmt = new CreateFullTextConfigStatement(nameComponents.first, nameComponents.second.getValue(), ifNotExists, expr);
1937 return addSourceLocation(stmt, startStmtToken);
1938 } catch (CompilationException e) {
1939 throw new SqlppParseException(getSourceLocation(startStmtToken), e.getMessage());
1940 }
1941 }
1942}
1943
Dmitry Lychagin2a0848e2020-01-08 13:57:22 -08001944CreateSynonymStatement CreateSynonymStatement(Token startStmtToken) throws ParseException:
1945{
1946 CreateSynonymStatement stmt = null;
1947}
1948{
1949 <SYNONYM> stmt = SynonymSpecification(startStmtToken)
1950 {
1951 return stmt;
1952 }
1953}
1954
1955CreateSynonymStatement SynonymSpecification(Token startStmtToken) throws ParseException:
1956{
1957 Pair<DataverseName,Identifier> nameComponents = null;
1958 Pair<DataverseName,Identifier> objectNameComponents = null;
1959 boolean ifNotExists = false;
1960}
1961{
1962 nameComponents = QualifiedName() ifNotExists = IfNotExists()
1963 <FOR> objectNameComponents = QualifiedName()
1964 {
1965 CreateSynonymStatement stmt = new CreateSynonymStatement(nameComponents.first, nameComponents.second.getValue(),
1966 objectNameComponents.first, objectNameComponents.second.getValue(), ifNotExists);
1967 return addSourceLocation(stmt, startStmtToken);
1968 }
1969}
1970
Yingyi Bu391f09e2015-10-29 13:49:39 -07001971boolean IfNotExists() throws ParseException:
1972{
1973}
1974{
Yingyi Budaa549c2016-06-28 22:30:52 -07001975 ( LOOKAHEAD(1) <IF> <NOT> <EXISTS>
Yingyi Bu391f09e2015-10-29 13:49:39 -07001976 {
1977 return true;
1978 }
1979 )?
1980 {
1981 return false;
1982 }
1983}
1984
Xikui Wang9d63f622017-05-18 17:50:44 -07001985void ApplyFunction(List<FunctionSignature> funcSigs) throws ParseException:
Yingyi Bu391f09e2015-10-29 13:49:39 -07001986{
Dmitry Lychagin54c06012019-11-13 15:54:20 -08001987 FunctionName functionName = null;
Xikui Wang261dc6d2017-03-29 21:23:15 -07001988 String fqFunctionName = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07001989}
1990{
Dmitry Lychagin54c06012019-11-13 15:54:20 -08001991 <APPLY> <FUNCTION> functionName = FunctionName()
Dmitry Lychagin314e2792019-11-26 14:35:42 -08001992 {
1993 fqFunctionName = functionName.library == null ? functionName.function : functionName.library + "#" + functionName.function;
1994 funcSigs.add(new FunctionSignature(functionName.dataverse, fqFunctionName, 1));
1995 }
Xikui Wang261dc6d2017-03-29 21:23:15 -07001996 (
Dmitry Lychagin54c06012019-11-13 15:54:20 -08001997 <COMMA> functionName = FunctionName()
Xikui Wang261dc6d2017-03-29 21:23:15 -07001998 {
Dmitry Lychagin54c06012019-11-13 15:54:20 -08001999 fqFunctionName = functionName.library == null ? functionName.function : functionName.library + "#" + functionName.function;
2000 funcSigs.add(new FunctionSignature(functionName.dataverse, fqFunctionName, 1));
Xikui Wang261dc6d2017-03-29 21:23:15 -07002001 }
2002 )*
Yingyi Bu391f09e2015-10-29 13:49:39 -07002003}
2004
2005String GetPolicy() throws ParseException:
2006{
2007 String policy = null;
2008}
2009{
2010 <USING> <POLICY> policy = Identifier()
2011 {
2012 return policy;
2013 }
2014
2015}
2016
2017FunctionSignature FunctionSignature() throws ParseException:
2018{
2019 FunctionName fctName = null;
Dmitry Lychagin541652082020-11-09 14:04:53 -08002020 Pair<Integer, List<Pair<VarIdentifier,TypeExpression>>> params = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07002021 int arity = 0;
2022}
2023{
Dmitry Lychagindcb4ad22020-08-26 15:49:09 -07002024 fctName = FunctionName()
2025 (
Dmitry Lychagin541652082020-11-09 14:04:53 -08002026 LOOKAHEAD(2) params = FunctionParameters() { arity = params.first; }
Dmitry Lychagindcb4ad22020-08-26 15:49:09 -07002027 | ( <LEFTPAREN> arity = FunctionArity() <RIGHTPAREN> )
2028 | ( <ATT> arity = FunctionArity() ) // back-compat
2029 )
2030 {
2031 return new FunctionSignature(fctName.dataverse, fctName.function, arity);
2032 }
2033}
Yingyi Bu391f09e2015-10-29 13:49:39 -07002034
Dmitry Lychagindcb4ad22020-08-26 15:49:09 -07002035int FunctionArity() throws ParseException:
2036{
2037 int arity;
2038}
2039{
2040 <INTEGER_LITERAL>
2041 {
2042 try {
2043 arity = Integer.parseInt(token.image);
2044 } catch (NumberFormatException e) {
2045 throw new SqlppParseException(getSourceLocation(token), "Invalid arity: " + token.image);
Yingyi Bu391f09e2015-10-29 13:49:39 -07002046 }
Dmitry Lychagindcb4ad22020-08-26 15:49:09 -07002047 if (arity < 0 && arity != FunctionIdentifier.VARARGS) {
2048 throw new SqlppParseException(getSourceLocation(token), "Invalid arity: " + arity);
2049 }
2050 return arity;
2051 }
Yingyi Bu391f09e2015-10-29 13:49:39 -07002052}
2053
Yingyi Buc9bfe252016-03-01 00:02:40 -08002054Pair<List<Integer>, List<List<String>>> PrimaryKey() throws ParseException:
Yingyi Bu391f09e2015-10-29 13:49:39 -07002055{
Dmitry Lychagin81578f92021-08-24 11:57:07 -07002056 Pair<List<Integer>, List<List<String>>> primaryKeyFields = null;
2057}
2058{
2059 <PRIMARY> <KEY> primaryKeyFields = PrimaryKeyFields()
2060 {
2061 return primaryKeyFields;
2062 }
2063}
2064
2065Pair<List<Integer>, List<List<String>>> PrimaryKeyFields() throws ParseException:
2066{
Yingyi Buc9bfe252016-03-01 00:02:40 -08002067 Pair<Integer, List<String>> tmp = null;
2068 List<Integer> keyFieldSourceIndicators = new ArrayList<Integer>();
Yingyi Bu391f09e2015-10-29 13:49:39 -07002069 List<List<String>> primaryKeyFields = new ArrayList<List<String>>();
2070}
2071{
Dmitry Lychagin81578f92021-08-24 11:57:07 -07002072 tmp = NestedField()
Yingyi Bu391f09e2015-10-29 13:49:39 -07002073 {
Yingyi Buc9bfe252016-03-01 00:02:40 -08002074 keyFieldSourceIndicators.add(tmp.first);
2075 primaryKeyFields.add(tmp.second);
Yingyi Bu391f09e2015-10-29 13:49:39 -07002076 }
2077 ( <COMMA> tmp = NestedField()
2078 {
Yingyi Buc9bfe252016-03-01 00:02:40 -08002079 keyFieldSourceIndicators.add(tmp.first);
2080 primaryKeyFields.add(tmp.second);
Yingyi Bu391f09e2015-10-29 13:49:39 -07002081 }
2082 )*
2083 {
Yingyi Buc9bfe252016-03-01 00:02:40 -08002084 return new Pair<List<Integer>, List<List<String>>> (keyFieldSourceIndicators, primaryKeyFields);
Yingyi Bu391f09e2015-10-29 13:49:39 -07002085 }
2086}
2087
2088Statement DropStatement() throws ParseException:
2089{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002090 Token startToken = null;
Dmitry Lychagin314e2792019-11-26 14:35:42 -08002091 Statement stmt = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07002092}
2093{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002094 <DROP> { startToken = token; }
Yingyi Bu391f09e2015-10-29 13:49:39 -07002095 (
Dmitry Lychagin314e2792019-11-26 14:35:42 -08002096 stmt = DropDatasetStatement(startToken)
2097 | stmt = DropIndexStatement(startToken)
2098 | stmt = DropNodeGroupStatement(startToken)
2099 | stmt = DropTypeStatement(startToken)
2100 | stmt = DropDataverseStatement(startToken)
Dmitry Lychagin20905cd2020-08-06 20:34:55 -07002101 | stmt = DropAdapterStatement(startToken)
Dmitry Lychagin314e2792019-11-26 14:35:42 -08002102 | stmt = DropFunctionStatement(startToken)
2103 | stmt = DropFeedStatement(startToken)
2104 | stmt = DropFeedPolicyStatement(startToken)
Dmitry Lychagin2a0848e2020-01-08 13:57:22 -08002105 | stmt = DropSynonymStatement(startToken)
Rui Guoe6986dd2020-11-25 19:50:06 -08002106 | stmt = DropFullTextStatement(startToken)
Dmitry Lychagin793c39e2021-04-21 16:52:10 -07002107 | stmt = DropViewStatement(startToken)
Yingyi Bu391f09e2015-10-29 13:49:39 -07002108 )
2109 {
Dmitry Lychagin314e2792019-11-26 14:35:42 -08002110 return stmt;
2111 }
2112}
2113
2114DropDatasetStatement DropDatasetStatement(Token startStmtToken) throws ParseException:
2115{
2116 DropDatasetStatement stmt = null;
2117}
2118{
2119 Dataset() stmt = DropDatasetSpecification(startStmtToken)
2120 {
2121 return stmt;
2122 }
2123}
2124
2125DropDatasetStatement DropDatasetSpecification(Token startStmtToken) throws ParseException:
2126{
2127 Pair<DataverseName,Identifier> pairId = null;
2128 boolean ifExists = false;
2129}
2130{
2131 pairId = QualifiedName() ifExists = IfExists()
2132 {
2133 DropDatasetStatement stmt = new DropDatasetStatement(pairId.first, pairId.second, ifExists);
2134 return addSourceLocation(stmt, startStmtToken);
2135 }
2136}
2137
Dmitry Lychagin793c39e2021-04-21 16:52:10 -07002138ViewDropStatement DropViewStatement(Token startStmtToken) throws ParseException:
2139{
2140 ViewDropStatement stmt = null;
2141}
2142{
2143 <VIEW> stmt = DropViewSpecification(startStmtToken)
2144 {
2145 return stmt;
2146 }
2147}
2148
2149ViewDropStatement DropViewSpecification(Token startStmtToken) throws ParseException:
2150{
2151 Pair<DataverseName,Identifier> pairId = null;
2152 boolean ifExists = false;
2153}
2154{
2155 pairId = QualifiedName() ifExists = IfExists()
2156 {
2157 ViewDropStatement stmt = new ViewDropStatement(pairId.first, pairId.second, ifExists);
2158 return addSourceLocation(stmt, startStmtToken);
2159 }
2160}
2161
Dmitry Lychagin314e2792019-11-26 14:35:42 -08002162IndexDropStatement DropIndexStatement(Token startStmtToken) throws ParseException:
2163{
2164 IndexDropStatement stmt = null;
2165}
2166{
2167 <INDEX> stmt = DropIndexSpecification(startStmtToken)
2168 {
2169 return stmt;
2170 }
2171}
2172
2173IndexDropStatement DropIndexSpecification(Token startStmtToken) throws ParseException:
2174{
2175 Triple<DataverseName,Identifier,Identifier> tripleId = null;
2176 boolean ifExists = false;
2177}
2178{
2179 tripleId = DoubleQualifiedName() ifExists = IfExists()
2180 {
2181 IndexDropStatement stmt = new IndexDropStatement(tripleId.first, tripleId.second, tripleId.third, ifExists);
2182 return addSourceLocation(stmt, startStmtToken);
2183 }
2184}
2185
Rui Guoe6986dd2020-11-25 19:50:06 -08002186Statement DropFullTextStatement(Token startStmtToken) throws ParseException:
2187{
2188 Statement stmt = null;
2189}
2190{
2191 <FULLTEXT>
2192 (
2193 <FILTER> stmt = DropFullTextFilterSpec(startStmtToken)
2194 | (<IDENTIFIER> { expectToken(CONFIG); } stmt = DropFullTextConfigSpec(startStmtToken))
2195 )
2196 {
2197 return stmt;
2198 }
2199}
2200
2201FullTextFilterDropStatement DropFullTextFilterSpec(Token startStmtToken) throws ParseException:
2202{
2203 FullTextFilterDropStatement stmt = null;
2204 Pair<DataverseName,Identifier> nameComponents = null;
2205 boolean ifExists = false;
2206}
2207{
2208 nameComponents = QualifiedName() ifExists = IfExists()
2209 {
2210 stmt = new FullTextFilterDropStatement(nameComponents.first, nameComponents.second.getValue(), ifExists);
2211 return addSourceLocation(stmt, startStmtToken);
2212 }
2213}
2214
2215FullTextConfigDropStatement DropFullTextConfigSpec(Token startStmtToken) throws ParseException:
2216{
2217 FullTextConfigDropStatement stmt = null;
2218 Pair<DataverseName,Identifier> nameComponents = null;
2219 boolean ifExists = false;
2220}
2221{
2222 nameComponents = QualifiedName() ifExists = IfExists()
2223 {
2224 stmt = new FullTextConfigDropStatement(nameComponents.first, nameComponents.second.getValue(), ifExists);
2225 return addSourceLocation(stmt, startStmtToken);
2226 }
2227}
2228
2229
Dmitry Lychagin314e2792019-11-26 14:35:42 -08002230NodeGroupDropStatement DropNodeGroupStatement(Token startStmtToken) throws ParseException:
2231{
2232 NodeGroupDropStatement stmt = null;
2233}
2234{
2235 <NODEGROUP> stmt = DropNodeGroupSpecification(startStmtToken)
2236 {
2237 return stmt;
2238 }
2239}
2240
2241NodeGroupDropStatement DropNodeGroupSpecification(Token startStmtToken) throws ParseException:
2242{
2243 String id = null;
2244 boolean ifExists = false;
2245}
2246{
2247 id = Identifier() ifExists = IfExists()
2248 {
2249 NodeGroupDropStatement stmt = new NodeGroupDropStatement(new Identifier(id), ifExists);
2250 return addSourceLocation(stmt, startStmtToken);
2251 }
2252}
2253
2254TypeDropStatement DropTypeStatement(Token startStmtToken) throws ParseException:
2255{
2256 TypeDropStatement stmt = null;
2257}
2258{
2259 <TYPE> stmt = DropTypeSpecification(startStmtToken)
2260 {
2261 return stmt;
2262 }
2263}
2264
2265TypeDropStatement DropTypeSpecification(Token startStmtToken) throws ParseException:
2266{
2267 Pair<DataverseName,Identifier> pairId = null;
2268 boolean ifExists = false;
2269}
2270{
2271 pairId = TypeName() ifExists = IfExists()
2272 {
2273 TypeDropStatement stmt = new TypeDropStatement(pairId.first, pairId.second, ifExists);
2274 return addSourceLocation(stmt, startStmtToken);
2275 }
2276}
2277
2278DataverseDropStatement DropDataverseStatement(Token startStmtToken) throws ParseException:
2279{
2280 DataverseDropStatement stmt = null;
2281}
2282{
2283 <DATAVERSE> stmt = DropDataverseSpecification(startStmtToken)
2284 {
2285 return stmt;
2286 }
2287}
2288
2289DataverseDropStatement DropDataverseSpecification(Token startStmtToken) throws ParseException:
2290{
Dmitry Lychagin13a40e12021-04-08 18:22:57 -07002291 DataverseName dvName = null;
Dmitry Lychagin314e2792019-11-26 14:35:42 -08002292 boolean ifExists = false;
2293}
2294{
Dmitry Lychagin13a40e12021-04-08 18:22:57 -07002295 dvName = DataverseName() ifExists = IfExists()
Dmitry Lychagin314e2792019-11-26 14:35:42 -08002296 {
Dmitry Lychagin13a40e12021-04-08 18:22:57 -07002297 DataverseDropStatement stmt = new DataverseDropStatement(dvName, ifExists);
Dmitry Lychagin314e2792019-11-26 14:35:42 -08002298 return addSourceLocation(stmt, startStmtToken);
2299 }
2300}
2301
Dmitry Lychagin20905cd2020-08-06 20:34:55 -07002302AdapterDropStatement DropAdapterStatement(Token startStmtToken) throws ParseException:
2303{
2304 AdapterDropStatement stmt = null;
2305}
2306{
2307 <ADAPTER> stmt = DropAdapterSpecification(startStmtToken)
2308 {
2309 return stmt;
2310 }
2311}
2312
2313AdapterDropStatement DropAdapterSpecification(Token startStmtToken) throws ParseException:
2314{
2315 Pair<DataverseName,Identifier> adapterName = null;
2316 boolean ifExists = false;
2317}
2318{
2319 adapterName = QualifiedName() ifExists = IfExists()
2320 {
2321 AdapterDropStatement stmt = new AdapterDropStatement(adapterName.first, adapterName.second.getValue(), ifExists);
2322 return addSourceLocation(stmt, startStmtToken);
2323 }
2324}
2325
Dmitry Lychagin314e2792019-11-26 14:35:42 -08002326FunctionDropStatement DropFunctionStatement(Token startStmtToken) throws ParseException:
2327{
2328 FunctionDropStatement stmt = null;
2329}
2330{
2331 <FUNCTION> stmt = DropFunctionSpecification(startStmtToken)
2332 {
2333 return stmt;
2334 }
2335}
2336
2337FunctionDropStatement DropFunctionSpecification(Token startStmtToken) throws ParseException:
2338{
2339 FunctionSignature funcSig = null;
2340 boolean ifExists = false;
2341}
2342{
2343 funcSig = FunctionSignature() ifExists = IfExists()
2344 {
2345 FunctionDropStatement stmt = new FunctionDropStatement(funcSig, ifExists);
2346 return addSourceLocation(stmt, startStmtToken);
2347 }
2348}
2349
2350FeedDropStatement DropFeedStatement(Token startStmtToken) throws ParseException:
2351{
2352 FeedDropStatement stmt = null;
2353}
2354{
2355 <FEED> stmt = DropFeedSpecification(startStmtToken)
2356 {
2357 return stmt;
2358 }
2359}
2360
2361FeedDropStatement DropFeedSpecification(Token startStmtToken) throws ParseException:
2362{
2363 Pair<DataverseName,Identifier> pairId = null;
2364 boolean ifExists = false;
2365}
2366{
2367 pairId = QualifiedName() ifExists = IfExists()
2368 {
2369 FeedDropStatement stmt = new FeedDropStatement(pairId.first, pairId.second, ifExists);
2370 return addSourceLocation(stmt, startStmtToken);
2371 }
2372}
2373
2374FeedPolicyDropStatement DropFeedPolicyStatement(Token startStmtToken) throws ParseException:
2375{
2376 FeedPolicyDropStatement stmt = null;
2377}
2378{
2379 <INGESTION> <POLICY> stmt = DropFeedPolicySpecification(startStmtToken)
2380 {
2381 return stmt;
2382 }
2383}
2384
2385FeedPolicyDropStatement DropFeedPolicySpecification(Token startStmtToken) throws ParseException:
2386{
2387 Pair<DataverseName,Identifier> pairId = null;
2388 boolean ifExists = false;
2389}
2390{
2391 pairId = QualifiedName() ifExists = IfExists()
2392 {
2393 FeedPolicyDropStatement stmt = new FeedPolicyDropStatement(pairId.first, pairId.second, ifExists);
2394 return addSourceLocation(stmt, startStmtToken);
Yingyi Bu391f09e2015-10-29 13:49:39 -07002395 }
2396}
2397
Dmitry Lychagin2a0848e2020-01-08 13:57:22 -08002398SynonymDropStatement DropSynonymStatement(Token startStmtToken) throws ParseException:
2399{
2400 SynonymDropStatement stmt = null;
2401}
2402{
2403 <SYNONYM> stmt = DropSynonymSpecification(startStmtToken)
2404 {
2405 return stmt;
2406 }
2407}
2408
2409SynonymDropStatement DropSynonymSpecification(Token startStmtToken) throws ParseException:
2410{
2411 Pair<DataverseName,Identifier> pairId = null;
2412 boolean ifExists = false;
2413}
2414{
2415 pairId = QualifiedName() ifExists = IfExists()
2416 {
2417 SynonymDropStatement stmt = new SynonymDropStatement(pairId.first, pairId.second.getValue(), ifExists);
2418 return addSourceLocation(stmt, startStmtToken);
2419 }
2420}
2421
Yingyi Bu391f09e2015-10-29 13:49:39 -07002422boolean IfExists() throws ParseException :
2423{
2424}
2425{
2426 ( LOOKAHEAD(1) <IF> <EXISTS>
2427 {
2428 return true;
2429 }
2430 )?
2431 {
2432 return false;
2433 }
2434}
2435
2436InsertStatement InsertStatement() throws ParseException:
2437{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002438 Token startToken = null;
Dmitry Lychagin54c06012019-11-13 15:54:20 -08002439 Pair<DataverseName,Identifier> nameComponents = null;
Yingyi Bucb5bf332017-01-02 22:19:50 -08002440 VariableExpr var = null;
2441 Query query = null;
2442 Expression returnExpression = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07002443}
2444{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002445 <INSERT> { startToken = token; } <INTO> nameComponents = QualifiedName() (<AS> var = Variable())?
Dmitry Lychaginaebd0312019-06-04 08:55:39 -07002446 query = Query()
Yingyi Bucb5bf332017-01-02 22:19:50 -08002447 ( <RETURNING> returnExpression = Expression())?
Yingyi Bu391f09e2015-10-29 13:49:39 -07002448 {
Dmitry Lychagin393215e2019-04-11 10:26:56 -07002449 if (var == null && returnExpression != null) {
2450 var = new VariableExpr(SqlppVariableUtil.toInternalVariableIdentifier(nameComponents.second.getValue()));
2451 addSourceLocation(var, startToken);
Yingyi Bucb5bf332017-01-02 22:19:50 -08002452 }
Yingyi Bucaea8f02015-11-16 15:12:15 -08002453 query.setTopLevel(true);
Dmitry Lychagin2a0848e2020-01-08 13:57:22 -08002454 InsertStatement stmt = new InsertStatement(nameComponents.first, nameComponents.second.getValue(), query,
2455 getVarCounter(), var, returnExpression);
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07002456 return addSourceLocation(stmt, startToken);
Yingyi Bucb5bf332017-01-02 22:19:50 -08002457 }
2458}
2459
2460UpsertStatement UpsertStatement() throws ParseException:
2461{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002462 Token startToken = null;
Dmitry Lychagin54c06012019-11-13 15:54:20 -08002463 Pair<DataverseName,Identifier> nameComponents = null;
Yingyi Bucb5bf332017-01-02 22:19:50 -08002464 VariableExpr var = null;
2465 Query query = null;
2466 Expression returnExpression = null;
2467}
2468{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002469 <UPSERT> { startToken = token; } <INTO> nameComponents = QualifiedName() (<AS> var = Variable())?
Dmitry Lychaginaebd0312019-06-04 08:55:39 -07002470 query = Query()
Yingyi Bucb5bf332017-01-02 22:19:50 -08002471 ( <RETURNING> returnExpression = Expression())?
2472 {
Dmitry Lychagin393215e2019-04-11 10:26:56 -07002473 if (var == null && returnExpression != null) {
2474 var = new VariableExpr(SqlppVariableUtil.toInternalVariableIdentifier(nameComponents.second.getValue()));
2475 addSourceLocation(var, startToken);
Yingyi Bucb5bf332017-01-02 22:19:50 -08002476 }
2477 query.setTopLevel(true);
Dmitry Lychagin2a0848e2020-01-08 13:57:22 -08002478 UpsertStatement stmt = new UpsertStatement(nameComponents.first, nameComponents.second.getValue(), query,
2479 getVarCounter(), var, returnExpression);
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07002480 return addSourceLocation(stmt, startToken);
Yingyi Bu391f09e2015-10-29 13:49:39 -07002481 }
2482}
2483
2484DeleteStatement DeleteStatement() throws ParseException:
2485{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002486 Token startToken = null;
Dmitry Lychagin393215e2019-04-11 10:26:56 -07002487 VariableExpr var = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07002488 Expression condition = null;
Dmitry Lychagin54c06012019-11-13 15:54:20 -08002489 Pair<DataverseName, Identifier> nameComponents;
Yingyi Bu391f09e2015-10-29 13:49:39 -07002490}
2491{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002492 <DELETE> { startToken = token; }
Dmitry Lychagin393215e2019-04-11 10:26:56 -07002493 <FROM> nameComponents = QualifiedName() ((<AS>)? var = Variable())?
Yingyi Bu391f09e2015-10-29 13:49:39 -07002494 (<WHERE> condition = Expression())?
Yingyi Bu20e085b2016-07-06 12:57:27 -07002495 {
Dmitry Lychagin393215e2019-04-11 10:26:56 -07002496 if (var == null) {
2497 var = new VariableExpr(SqlppVariableUtil.toInternalVariableIdentifier(nameComponents.second.getValue()));
2498 addSourceLocation(var, startToken);
Yingyi Bu20e085b2016-07-06 12:57:27 -07002499 }
Dmitry Lychagin2a0848e2020-01-08 13:57:22 -08002500 DeleteStatement stmt = new DeleteStatement(var, nameComponents.first, nameComponents.second.getValue(),
Abdullah Alamoudi6eb01752017-04-01 21:51:19 -07002501 condition, getVarCounter());
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07002502 return addSourceLocation(stmt, startToken);
Yingyi Bu20e085b2016-07-06 12:57:27 -07002503 }
Yingyi Bu391f09e2015-10-29 13:49:39 -07002504}
2505
2506UpdateStatement UpdateStatement() throws ParseException:
2507{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002508 Token startToken = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07002509 VariableExpr vars;
2510 Expression target;
2511 Expression condition;
2512 UpdateClause uc;
2513 List<UpdateClause> ucs = new ArrayList<UpdateClause>();
2514}
2515{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002516 <UPDATE> { startToken = token; } vars = Variable() <IN> target = Expression()
Yingyi Bu391f09e2015-10-29 13:49:39 -07002517 <WHERE> condition = Expression()
2518 <LEFTPAREN> (uc = UpdateClause()
2519 {
2520 ucs.add(uc);
2521 }
2522 (<COMMA> uc = UpdateClause()
2523 {
2524 ucs.add(uc);
2525 }
2526 )*) <RIGHTPAREN>
2527 {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002528 UpdateStatement stmt = new UpdateStatement(vars, target, condition, ucs);
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07002529 return addSourceLocation(stmt, startToken);
Yingyi Bu391f09e2015-10-29 13:49:39 -07002530 }
2531}
2532
2533UpdateClause UpdateClause() throws ParseException:
2534{
2535 Expression target = null;
2536 Expression value = null ;
2537 InsertStatement is = null;
2538 DeleteStatement ds = null;
2539 UpdateStatement us = null;
2540 Expression condition = null;
2541 UpdateClause ifbranch = null;
2542 UpdateClause elsebranch = null;
2543}
2544{
2545 (<SET> target = Expression() <EQ> value = Expression()
2546 | is = InsertStatement()
2547 | ds = DeleteStatement()
2548 | us = UpdateStatement()
2549 | <IF> <LEFTPAREN> condition = Expression() <RIGHTPAREN>
2550 <THEN> ifbranch = UpdateClause()
2551 [LOOKAHEAD(1) <ELSE> elsebranch = UpdateClause()]
2552 {
2553 return new UpdateClause(target, value, is, ds, us, condition, ifbranch, elsebranch);
2554 }
2555 )
2556}
2557
2558Statement SetStatement() throws ParseException:
2559{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002560 Token startToken = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07002561 String pn = null;
2562 String pv = null;
2563}
2564{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002565 <SET> { startToken = token; } pn = Identifier() pv = ConstantString()
Yingyi Bu391f09e2015-10-29 13:49:39 -07002566 {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002567 SetStatement stmt = new SetStatement(pn, pv);
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07002568 return addSourceLocation(stmt, startToken);
Yingyi Bu391f09e2015-10-29 13:49:39 -07002569 }
2570}
2571
2572Statement WriteStatement() throws ParseException:
2573{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002574 Token startToken = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07002575 String nodeName = null;
2576 String fileName = null;
2577 Query query;
2578 String writerClass = null;
2579 Pair<Identifier,Identifier> nameComponents = null;
2580}
2581{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002582 <WRITE> { startToken = token; } <OUTPUT> <TO> nodeName = Identifier() <COLON> fileName = ConstantString()
Yingyi Bu6d57e492016-06-06 21:24:42 -07002583 ( <USING> writerClass = ConstantString() )?
Yingyi Bu391f09e2015-10-29 13:49:39 -07002584 {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002585 WriteStatement stmt = new WriteStatement(new Identifier(nodeName), fileName, writerClass);
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07002586 return addSourceLocation(stmt, startToken);
Yingyi Bu391f09e2015-10-29 13:49:39 -07002587 }
2588}
2589
2590LoadStatement LoadStatement() throws ParseException:
2591{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002592 Token startToken = null;
Dmitry Lychagin54c06012019-11-13 15:54:20 -08002593 DataverseName dataverseName = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07002594 Identifier datasetName = null;
2595 boolean alreadySorted = false;
2596 String adapterName;
2597 Map<String,String> properties;
Dmitry Lychagin54c06012019-11-13 15:54:20 -08002598 Pair<DataverseName,Identifier> nameComponents = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07002599}
2600{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002601 <LOAD> { startToken = token; } Dataset() nameComponents = QualifiedName()
Yingyi Bu391f09e2015-10-29 13:49:39 -07002602 {
2603 dataverseName = nameComponents.first;
2604 datasetName = nameComponents.second;
2605 }
2606 <USING> adapterName = AdapterName() properties = Configuration()
2607 (<PRESORTED>
2608 {
2609 alreadySorted = true;
2610 }
2611 )?
2612 {
Dmitry Lychagin2a0848e2020-01-08 13:57:22 -08002613 LoadStatement stmt = new LoadStatement(dataverseName, datasetName.getValue(), adapterName, properties,
2614 alreadySorted);
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07002615 return addSourceLocation(stmt, startToken);
Yingyi Bu391f09e2015-10-29 13:49:39 -07002616 }
2617}
2618
2619
2620String AdapterName() throws ParseException :
2621{
2622 String adapterName = null;
2623}
2624{
2625 adapterName = Identifier()
2626 {
2627 return adapterName;
2628 }
2629}
2630
2631Statement CompactStatement() throws ParseException:
2632{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002633 Token startToken = null;
Dmitry Lychagin54c06012019-11-13 15:54:20 -08002634 Pair<DataverseName,Identifier> nameComponents = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07002635}
2636{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002637 <COMPACT> { startToken = token; } Dataset() nameComponents = QualifiedName()
Yingyi Bu391f09e2015-10-29 13:49:39 -07002638 {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002639 CompactStatement stmt = new CompactStatement(nameComponents.first, nameComponents.second);
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07002640 return addSourceLocation(stmt, startToken);
Yingyi Bu391f09e2015-10-29 13:49:39 -07002641 }
2642}
2643
Yingyi Buab817482016-08-19 21:29:31 -07002644Statement ConnectionStatement() throws ParseException:
Yingyi Bu391f09e2015-10-29 13:49:39 -07002645{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002646 Token startToken = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07002647 Statement stmt = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07002648}
2649{
2650 (
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002651 <CONNECT> { startToken = token; } stmt = ConnectStatement(startToken)
2652 | <DISCONNECT> { startToken = token; } stmt = DisconnectStatement(startToken)
2653 | <START> { startToken = token; } stmt = StartStatement(startToken)
2654 | <STOP> { startToken = token; } stmt = StopStatement(startToken)
Yingyi Buab817482016-08-19 21:29:31 -07002655 )
2656 {
2657 return stmt;
2658 }
2659}
2660
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002661Statement StartStatement(Token startStmtToken) throws ParseException:
Abdullah Alamoudifff200c2017-02-18 20:32:14 -08002662{
Dmitry Lychagin54c06012019-11-13 15:54:20 -08002663 Pair<DataverseName,Identifier> feedNameComponents = null;
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002664 AbstractStatement stmt = null;
Abdullah Alamoudifff200c2017-02-18 20:32:14 -08002665}
2666{
2667 <FEED> feedNameComponents = QualifiedName()
2668 {
2669 stmt = new StartFeedStatement (feedNameComponents);
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07002670 return addSourceLocation(stmt, startStmtToken);
Abdullah Alamoudifff200c2017-02-18 20:32:14 -08002671 }
2672}
2673
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002674AbstractStatement StopStatement(Token startStmtToken) throws ParseException:
Abdullah Alamoudifff200c2017-02-18 20:32:14 -08002675{
Dmitry Lychagin54c06012019-11-13 15:54:20 -08002676 Pair<DataverseName,Identifier> feedNameComponents = null;
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002677 AbstractStatement stmt = null;
Abdullah Alamoudifff200c2017-02-18 20:32:14 -08002678}
2679{
2680 <FEED> feedNameComponents = QualifiedName()
2681 {
2682 stmt = new StopFeedStatement (feedNameComponents);
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07002683 return addSourceLocation(stmt, startStmtToken);
Abdullah Alamoudifff200c2017-02-18 20:32:14 -08002684 }
2685}
2686
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002687AbstractStatement DisconnectStatement(Token startStmtToken) throws ParseException:
Yingyi Buab817482016-08-19 21:29:31 -07002688{
Dmitry Lychagin54c06012019-11-13 15:54:20 -08002689 Pair<DataverseName,Identifier> feedNameComponents = null;
2690 Pair<DataverseName,Identifier> datasetNameComponents = null;
Yingyi Buab817482016-08-19 21:29:31 -07002691
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002692 AbstractStatement stmt = null;
Yingyi Buab817482016-08-19 21:29:31 -07002693}
2694{
2695 (
2696 <FEED> feedNameComponents = QualifiedName() <FROM> Dataset() datasetNameComponents = QualifiedName()
Yingyi Bu391f09e2015-10-29 13:49:39 -07002697 {
2698 stmt = new DisconnectFeedStatement(feedNameComponents, datasetNameComponents);
2699 }
2700 )
Yingyi Buab817482016-08-19 21:29:31 -07002701 {
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07002702 return addSourceLocation(stmt, startStmtToken);
Yingyi Buab817482016-08-19 21:29:31 -07002703 }
2704}
2705
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002706AbstractStatement ConnectStatement(Token startStmtToken) throws ParseException:
Yingyi Buab817482016-08-19 21:29:31 -07002707{
Dmitry Lychagin54c06012019-11-13 15:54:20 -08002708 Pair<DataverseName,Identifier> feedNameComponents = null;
2709 Pair<DataverseName,Identifier> datasetNameComponents = null;
Yingyi Buab817482016-08-19 21:29:31 -07002710
2711 Map<String,String> configuration = null;
Xikui Wang9d63f622017-05-18 17:50:44 -07002712 List<FunctionSignature> appliedFunctions = new ArrayList<FunctionSignature>();
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002713 AbstractStatement stmt = null;
Yingyi Buab817482016-08-19 21:29:31 -07002714 String policy = null;
Xikui Wangf6741682018-02-22 19:17:17 -08002715 String whereClauseBody = null;
2716 WhereClause whereClause = null;
2717 Token beginPos = null;
2718 Token endPos = null;
Yingyi Buab817482016-08-19 21:29:31 -07002719}
2720{
2721 (
Abdullah Alamoudifff200c2017-02-18 20:32:14 -08002722 <FEED> feedNameComponents = QualifiedName() <TO> Dataset() datasetNameComponents = QualifiedName()
Xikui Wangf6741682018-02-22 19:17:17 -08002723 (ApplyFunction(appliedFunctions))?
2724 (policy = GetPolicy())?
2725 (
2726 <WHERE>
2727 {
2728 beginPos = token;
2729 whereClause = new WhereClause();
2730 Expression whereExpr;
2731 }
2732 whereExpr = Expression()
2733 {
2734 whereClause.setWhereExpr(whereExpr);
2735 }
2736 )?
2737 {
2738 if (whereClause != null) {
2739 endPos = token;
2740 whereClauseBody = extractFragment(beginPos.endLine, beginPos.endColumn, endPos.endLine, endPos.endColumn + 1);
2741 }
2742 }
Yingyi Buab817482016-08-19 21:29:31 -07002743 {
Xikui Wang261dc6d2017-03-29 21:23:15 -07002744 stmt = new ConnectFeedStatement(feedNameComponents, datasetNameComponents, appliedFunctions,
Xikui Wangf6741682018-02-22 19:17:17 -08002745 policy, whereClauseBody, getVarCounter());
Yingyi Buab817482016-08-19 21:29:31 -07002746 }
2747 )
2748 {
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07002749 return addSourceLocation(stmt, startStmtToken);
Yingyi Buab817482016-08-19 21:29:31 -07002750 }
Yingyi Bu391f09e2015-10-29 13:49:39 -07002751}
2752
2753Map<String,String> Configuration() throws ParseException :
2754{
2755 Map<String,String> configuration = new LinkedHashMap<String,String>();
2756 Pair<String, String> keyValuePair = null;
2757}
2758{
2759 <LEFTPAREN> ( keyValuePair = KeyValuePair()
2760 {
2761 configuration.put(keyValuePair.first, keyValuePair.second);
2762 }
2763 ( <COMMA> keyValuePair = KeyValuePair()
2764 {
2765 configuration.put(keyValuePair.first, keyValuePair.second);
2766 }
2767 )* )? <RIGHTPAREN>
2768 {
2769 return configuration;
2770 }
2771}
2772
2773Pair<String, String> KeyValuePair() throws ParseException:
2774{
2775 String key;
2776 String value;
2777}
2778{
Ali Alsulimane2986012020-05-14 18:14:22 -07002779 <LEFTPAREN> key = ConstantString()
2780 <EQ> ( value = ConstantString() | (<TRUE> | <FALSE>) {value = token.image.toLowerCase();} )
2781 <RIGHTPAREN>
Yingyi Bu391f09e2015-10-29 13:49:39 -07002782 {
2783 return new Pair<String, String>(key, value);
2784 }
2785}
2786
2787Map<String,String> Properties() throws ParseException:
2788{
2789 Map<String,String> properties = new HashMap<String,String>();
2790 Pair<String, String> property;
2791}
2792{
2793 (LOOKAHEAD(1) <LEFTPAREN> property = Property()
2794 {
2795 properties.put(property.first, property.second);
2796 }
2797 ( <COMMA> property = Property()
2798 {
2799 properties.put(property.first, property.second);
2800 }
2801 )* <RIGHTPAREN> )?
2802 {
2803 return properties;
2804 }
2805}
2806
2807Pair<String, String> Property() throws ParseException:
2808{
Yingyi Bu6d57e492016-06-06 21:24:42 -07002809 String key = null;
2810 String value = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07002811}
2812{
Yingyi Bu6d57e492016-06-06 21:24:42 -07002813 (key = Identifier() | key = StringLiteral())
2814 <EQ>
2815 ( value = ConstantString() | <INTEGER_LITERAL>
Yingyi Bu391f09e2015-10-29 13:49:39 -07002816 {
2817 try {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002818 value = String.valueOf(Long.parseLong(token.image));
Yingyi Bu391f09e2015-10-29 13:49:39 -07002819 } catch (NumberFormatException nfe) {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002820 throw new SqlppParseException(getSourceLocation(token), "inapproriate value: " + token.image);
Yingyi Bu391f09e2015-10-29 13:49:39 -07002821 }
2822 }
2823 )
2824 {
2825 return new Pair<String, String>(key.toUpperCase(), value);
2826 }
2827}
2828
Glenn58329202021-04-09 12:03:46 -07002829IndexedTypeExpression IndexedTypeExpr(boolean allowQues) throws ParseException:
Yingyi Bu391f09e2015-10-29 13:49:39 -07002830{
2831 TypeExpression typeExpr = null;
Glenn58329202021-04-09 12:03:46 -07002832 boolean isUnknownable = !allowQues;
Yingyi Bu391f09e2015-10-29 13:49:39 -07002833}
2834{
Dmitry Lychaginf7bc6c12020-06-01 18:19:44 -07002835 typeExpr = TypeExpr(false)
Glenn58329202021-04-09 12:03:46 -07002836 ( <QUES>
2837 {
2838 if (!allowQues) {
2839 throw new SqlppParseException(getSourceLocation(token), "'?' quantifier is illegal for the type expression.");
2840 }
2841 isUnknownable = true;
2842 }
2843 )?
Yingyi Bu391f09e2015-10-29 13:49:39 -07002844 {
Dmitry Lychagin8ba59442017-06-16 14:19:45 -07002845 return new IndexedTypeExpression(typeExpr, isUnknownable);
Yingyi Bu391f09e2015-10-29 13:49:39 -07002846 }
2847}
2848
Dmitry Lychaginf7bc6c12020-06-01 18:19:44 -07002849TypeExpression TypeExpr(boolean allowRecordTypeDef) throws ParseException:
Yingyi Bu391f09e2015-10-29 13:49:39 -07002850{
2851 TypeExpression typeExpr = null;
2852}
2853{
2854 (
Dmitry Lychaginf7bc6c12020-06-01 18:19:44 -07002855 typeExpr = TypeReference()
2856 | typeExpr = OrderedListTypeDef(allowRecordTypeDef)
2857 | typeExpr = UnorderedListTypeDef(allowRecordTypeDef)
2858 | typeExpr = RecordTypeDef() {
2859 if (!allowRecordTypeDef) {
2860 throw new SqlppParseException(typeExpr.getSourceLocation(), "Unexpected record type declaration");
2861 }
2862 }
Yingyi Bu391f09e2015-10-29 13:49:39 -07002863 )
2864 {
2865 return typeExpr;
2866 }
2867}
2868
Dmitry Lychagin3e2623c2020-04-01 11:20:04 -07002869RecordTypeDefinition.RecordKind RecordTypeKind() throws ParseException:
2870{
2871 RecordTypeDefinition.RecordKind recordKind = null;
2872}
2873{
2874 (
2875 <CLOSED> { recordKind = RecordTypeDefinition.RecordKind.CLOSED; }
2876 | <OPEN> { recordKind = RecordTypeDefinition.RecordKind.OPEN; }
2877 )
2878 {
2879 return recordKind;
2880 }
2881}
2882
Yingyi Bu391f09e2015-10-29 13:49:39 -07002883RecordTypeDefinition RecordTypeDef() throws ParseException:
2884{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002885 Token startToken = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07002886 RecordTypeDefinition recType = new RecordTypeDefinition();
Dmitry Lychagin3e2623c2020-04-01 11:20:04 -07002887 RecordTypeDefinition.RecordKind recordKind = RecordTypeDefinition.RecordKind.OPEN;
Yingyi Bu391f09e2015-10-29 13:49:39 -07002888}
2889{
Dmitry Lychagin3e2623c2020-04-01 11:20:04 -07002890 ( recordKind = RecordTypeKind() )?
Yingyi Bu391f09e2015-10-29 13:49:39 -07002891 <LEFTBRACE>
2892 {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002893 startToken = token;
Dmitry Lychagine77cdac2019-08-05 11:37:47 -07002894 Token hintToken = fetchHint(token, SqlppHint.GEN_FIELDS_HINT);
2895 if (hintToken != null) {
2896 String hintParams = hintToken.hintParams;
2897 String[] splits = hintParams != null ? hintParams.split("\\s+") : null;
2898 if (splits == null || splits.length != 4) {
2899 throw new SqlppParseException(getSourceLocation(hintToken),
2900 "Expecting: /*+ gen-fields <type> <min> <max> <prefix>*/");
Yingyi Bu391f09e2015-10-29 13:49:39 -07002901 }
Dmitry Lychagine77cdac2019-08-05 11:37:47 -07002902 if (!splits[0].equals("int")) {
2903 throw new SqlppParseException(getSourceLocation(hintToken),
2904 "The only supported type for gen-fields is int.");
2905 }
2906 UndeclaredFieldsDataGen ufdg = new UndeclaredFieldsDataGen(UndeclaredFieldsDataGen.Type.INT,
2907 Integer.parseInt(splits[1]), Integer.parseInt(splits[2]), splits[3]);
2908 recType.setUndeclaredFieldsDataGen(ufdg);
Yingyi Bu391f09e2015-10-29 13:49:39 -07002909 }
Yingyi Bu391f09e2015-10-29 13:49:39 -07002910 }
Dmitry Lychagine77cdac2019-08-05 11:37:47 -07002911 (
2912 RecordField(recType)
2913 ( <COMMA> RecordField(recType) )*
2914 )?
Yingyi Bu391f09e2015-10-29 13:49:39 -07002915 <RIGHTBRACE>
2916 {
Yingyi Bu391f09e2015-10-29 13:49:39 -07002917 recType.setRecordKind(recordKind);
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07002918 return addSourceLocation(recType, startToken);
Yingyi Bu391f09e2015-10-29 13:49:39 -07002919 }
2920}
2921
2922void RecordField(RecordTypeDefinition recType) throws ParseException:
2923{
2924 String fieldName;
2925 TypeExpression type = null;
Dmitry Lychagin3a628022020-05-12 18:09:02 -07002926 boolean nullable = false, missable = false;
Yingyi Bu391f09e2015-10-29 13:49:39 -07002927}
2928{
2929 fieldName = Identifier()
2930 {
Dmitry Lychagine77cdac2019-08-05 11:37:47 -07002931 Token hintToken = fetchHint(token, SqlppHint.VAL_FILE_HINT, SqlppHint.VAL_FILE_SAME_INDEX_HINT,
2932 SqlppHint.LIST_VAL_FILE_HINT, SqlppHint.LIST_HINT, SqlppHint.INTERVAL_HINT, SqlppHint.INSERT_RAND_INT_HINT,
2933 SqlppHint.DATE_BETWEEN_YEARS_HINT, SqlppHint.DATETIME_ADD_RAND_HOURS_HINT, SqlppHint.AUTO_HINT);
2934 IRecordFieldDataGen rfdg = hintToken != null ? parseFieldDataGen(hintToken) : null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07002935 }
Dmitry Lychaginf7bc6c12020-06-01 18:19:44 -07002936 <COLON> type = TypeExpr(true) ( <QUES> { nullable = true; missable = true; } )?
Yingyi Bu391f09e2015-10-29 13:49:39 -07002937 {
Dmitry Lychagin3a628022020-05-12 18:09:02 -07002938 recType.addField(fieldName, type, nullable, missable, rfdg);
Yingyi Bu391f09e2015-10-29 13:49:39 -07002939 }
2940}
2941
2942TypeReferenceExpression TypeReference() throws ParseException:
2943{
Dmitry Lychagin54c06012019-11-13 15:54:20 -08002944 Pair<DataverseName,Identifier> id = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07002945}
2946{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002947 id = QualifiedName()
2948 {
Dmitry Lychagin75f19872019-10-03 17:56:35 -07002949 if (id.first == null && id.second.getValue().equalsIgnoreCase(INT_TYPE_NAME)) {
2950 id.second = new Identifier(BuiltinType.AINT64.getTypeName());
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002951 }
Yingyi Bu391f09e2015-10-29 13:49:39 -07002952
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002953 TypeReferenceExpression typeRef = new TypeReferenceExpression(id);
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07002954 return addSourceLocation(typeRef, token);
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002955 }
Yingyi Bu391f09e2015-10-29 13:49:39 -07002956}
2957
Dmitry Lychaginf7bc6c12020-06-01 18:19:44 -07002958OrderedListTypeDefinition OrderedListTypeDef(boolean allowRecordTypeDef) throws ParseException:
Yingyi Bu391f09e2015-10-29 13:49:39 -07002959{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002960 Token startToken = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07002961 TypeExpression type = null;
2962}
2963{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002964 <LEFTBRACKET> { startToken = token; }
Dmitry Lychaginf7bc6c12020-06-01 18:19:44 -07002965 ( type = TypeExpr(allowRecordTypeDef) )
Yingyi Bu391f09e2015-10-29 13:49:39 -07002966 <RIGHTBRACKET>
2967 {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002968 OrderedListTypeDefinition typeDef = new OrderedListTypeDefinition(type);
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07002969 return addSourceLocation(typeDef, startToken);
Yingyi Bu391f09e2015-10-29 13:49:39 -07002970 }
2971}
2972
Dmitry Lychaginf7bc6c12020-06-01 18:19:44 -07002973UnorderedListTypeDefinition UnorderedListTypeDef(boolean allowRecordTypeDef) throws ParseException:
Yingyi Bu391f09e2015-10-29 13:49:39 -07002974{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002975 Token startToken = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07002976 TypeExpression type = null;
2977}
2978{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002979 <LEFTDBLBRACE> { startToken = token; }
Dmitry Lychaginf7bc6c12020-06-01 18:19:44 -07002980 ( type = TypeExpr(allowRecordTypeDef) )
Yingyi Bu391f09e2015-10-29 13:49:39 -07002981 <RIGHTDBLBRACE>
2982 {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002983 UnorderedListTypeDefinition typeDef = new UnorderedListTypeDefinition(type);
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07002984 return addSourceLocation(typeDef, startToken);
Yingyi Bu391f09e2015-10-29 13:49:39 -07002985 }
2986}
2987
2988FunctionName FunctionName() throws ParseException:
2989{
Dmitry Lychagin13a40e12021-04-08 18:22:57 -07002990 Triple<List<String>, Token, Token> prefix = null;
Dmitry Lychagin54c06012019-11-13 15:54:20 -08002991 String suffix = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07002992}
2993{
Dmitry Lychagin54c06012019-11-13 15:54:20 -08002994 // Note: there's a copy of this production in PrimaryExpr() (LOOKAHEAD for FunctionCallExpr())
2995 // that copy must be kept in sync with this code
Dmitry Lychagin6fd8ab32020-12-03 09:04:14 -08002996 prefix = MultipartIdentifierWithHints(
Tin Vu4f1090d2021-09-21 02:06:32 -07002997 SqlppHint.INDEXED_NESTED_LOOP_JOIN_HINT, SqlppHint.RANGE_HINT, SqlppHint.SKIP_SECONDARY_INDEX_SEARCH_HINT,
2998 SqlppHint.SPATIAL_JOIN_HINT, SqlppHint.USE_SECONDARY_INDEX_SEARCH_HINT
Dmitry Lychagin6fd8ab32020-12-03 09:04:14 -08002999 )
Dmitry Lychagin54c06012019-11-13 15:54:20 -08003000 (<SHARP> suffix = Identifier())?
Yingyi Bu391f09e2015-10-29 13:49:39 -07003001 {
Dmitry Lychagin13a40e12021-04-08 18:22:57 -07003002 Token startToken = prefix.second;
Yingyi Bu391f09e2015-10-29 13:49:39 -07003003 FunctionName result = new FunctionName();
Dmitry Lychagin13a40e12021-04-08 18:22:57 -07003004 result.sourceLoc = getSourceLocation(startToken);
Caleb Herbel8d9c57a2020-08-14 20:41:13 -06003005 result.hintToken = prefix.third;
Dmitry Lychagin54c06012019-11-13 15:54:20 -08003006 List<String> list = prefix.first;
3007 int ln = list.size();
3008 String last = list.get(ln - 1);
3009 if (suffix == null) {
3010 // prefix = (dv_part1.dv_part2...dv_partN.)?func_name
3011 // no library name
3012 result.function = last;
3013 } else {
3014 // prefix = (dv_part1.dv_part2...dv_partN.)?lib_name
3015 // suffix = func_name
3016 result.library = last;
3017 result.function = suffix;
Dmitry Lychagine77cdac2019-08-05 11:37:47 -07003018 }
Dmitry Lychagin54c06012019-11-13 15:54:20 -08003019 if (ln > 1) {
Dmitry Lychagin13a40e12021-04-08 18:22:57 -07003020 result.dataverse = createDataverseName(list, 0, ln - 1, startToken);
Dmitry Lychagin54c06012019-11-13 15:54:20 -08003021 } else {
3022 result.dataverse = defaultDataverse;
Yingyi Bu391f09e2015-10-29 13:49:39 -07003023 }
Yingyi Bu391f09e2015-10-29 13:49:39 -07003024
Dmitry Lychagin54c06012019-11-13 15:54:20 -08003025 if (result.function.equalsIgnoreCase(INT_TYPE_NAME)) {
3026 result.function = BuiltinType.AINT64.getTypeName();
Yingyi Bu391f09e2015-10-29 13:49:39 -07003027 }
Dmitry Lychagin54c06012019-11-13 15:54:20 -08003028 return result;
3029 }
Yingyi Bu391f09e2015-10-29 13:49:39 -07003030}
3031
Dmitry Lychagin54c06012019-11-13 15:54:20 -08003032Pair<DataverseName,Identifier> TypeName() throws ParseException:
Yingyi Bu391f09e2015-10-29 13:49:39 -07003033{
Dmitry Lychagin54c06012019-11-13 15:54:20 -08003034 Pair<DataverseName,Identifier> name = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07003035}
3036{
3037 name = QualifiedName()
3038 {
3039 if (name.first == null) {
Dmitry Lychagin54c06012019-11-13 15:54:20 -08003040 name.first = defaultDataverse;
Yingyi Bu391f09e2015-10-29 13:49:39 -07003041 }
3042 return name;
3043 }
3044}
3045
3046String Identifier() throws ParseException:
3047{
3048 String lit = null;
3049}
3050{
3051 (<IDENTIFIER>
3052 {
3053 return token.image;
3054 }
3055 | lit = QuotedString()
3056 {
3057 return lit;
3058 }
3059 )
3060}
3061
Dmitry Lychagin6fd8ab32020-12-03 09:04:14 -08003062List<String> ParenthesizedIdentifierList() throws ParseException:
3063{
3064 List<String> list = new ArrayList<String>();
3065 String ident = null;
3066}
3067{
3068 <LEFTPAREN>
3069 ident = Identifier() { list.add(ident); }
3070 ( <COMMA> ident = Identifier() { list.add(ident); } )*
3071 <RIGHTPAREN>
3072 {
3073 return list;
3074 }
3075}
3076
Tin Vu4f1090d2021-09-21 02:06:32 -07003077List<Literal> ParenthesizedLiteralList() throws ParseException:
3078{
3079 List<Literal> list = new ArrayList<Literal>();
3080 boolean minus = false;
3081 Expression litExpr = null;
3082 Literal lit = null;
3083}
3084{
3085 <LEFTPAREN>
3086 (<MINUS> { minus = true; })? litExpr = Literal()
3087 {
3088 lit = ((LiteralExpr) litExpr).getValue();
3089 if (minus)
3090 {
3091 try {
3092 lit = ExpressionUtils.reverseSign(lit);
3093 } catch (TypeMismatchException e) {
3094 throw new SqlppParseException(getSourceLocation(token), e.getMessage());
3095 }
3096 minus = false;
3097 }
3098 list.add(lit);
3099 }
3100 ( <COMMA> (<MINUS> { minus = true; })? litExpr = Literal()
3101 {
3102 lit = ((LiteralExpr) litExpr).getValue();
3103 if (minus)
3104 {
3105 try {
3106 lit = ExpressionUtils.reverseSign(lit);
3107 } catch (TypeMismatchException e) {
3108 throw new SqlppParseException(getSourceLocation(token), e.getMessage());
3109 }
3110 minus = false;
3111 }
3112 list.add(lit);
3113 } )*
3114 <RIGHTPAREN>
3115 {
3116 return list;
3117 }
3118}
3119
Dmitry Lychagin8ba59442017-06-16 14:19:45 -07003120Pair<Integer, Pair<List<String>, IndexedTypeExpression>> OpenField() throws ParseException:
Yingyi Bu391f09e2015-10-29 13:49:39 -07003121{
Dmitry Lychagin8ba59442017-06-16 14:19:45 -07003122 IndexedTypeExpression fieldType = null;
Yingyi Buc9bfe252016-03-01 00:02:40 -08003123 Pair<Integer, List<String>> fieldList = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07003124}
3125{
3126 fieldList = NestedField()
Glenn58329202021-04-09 12:03:46 -07003127 ( <COLON> fieldType = IndexedTypeExpr(true) )?
Yingyi Bu391f09e2015-10-29 13:49:39 -07003128 {
Dmitry Lychagin8ba59442017-06-16 14:19:45 -07003129 return new Pair<Integer, Pair<List<String>, IndexedTypeExpression>>
3130 (fieldList.first, new Pair<List<String>, IndexedTypeExpression>(fieldList.second, fieldType));
Yingyi Bu391f09e2015-10-29 13:49:39 -07003131 }
3132}
3133
Yingyi Buc9bfe252016-03-01 00:02:40 -08003134Pair<Integer, List<String>> NestedField() throws ParseException:
Yingyi Bu391f09e2015-10-29 13:49:39 -07003135{
3136 List<String> exprList = new ArrayList<String>();
3137 String lit = null;
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07003138 Token litToken = null;
Yingyi Buc9bfe252016-03-01 00:02:40 -08003139 int source = 0;
Yingyi Bu391f09e2015-10-29 13:49:39 -07003140}
3141{
3142 lit = Identifier()
3143 {
Yingyi Bub9169b62016-02-26 21:21:49 -08003144 boolean meetParens = false;
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07003145 litToken = token;
Yingyi Bub9169b62016-02-26 21:21:49 -08003146 }
3147 (
Yingyi Buc9bfe252016-03-01 00:02:40 -08003148 LOOKAHEAD(1)
Yingyi Bub9169b62016-02-26 21:21:49 -08003149 <LEFTPAREN><RIGHTPAREN>
3150 {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07003151 if(!lit.equalsIgnoreCase("meta")){
3152 throw new SqlppParseException(getSourceLocation(litToken), "The string before () has to be \"meta\".");
Yingyi Bub9169b62016-02-26 21:21:49 -08003153 }
3154 meetParens = true;
Yingyi Buc9bfe252016-03-01 00:02:40 -08003155 source = 1;
Yingyi Bub9169b62016-02-26 21:21:49 -08003156 }
3157 )?
3158 {
3159 if(!meetParens){
3160 exprList.add(lit);
3161 }
Yingyi Bu391f09e2015-10-29 13:49:39 -07003162 }
3163 (<DOT>
3164 lit = Identifier()
3165 {
3166 exprList.add(lit);
3167 }
3168 )*
3169 {
Yingyi Buc9bfe252016-03-01 00:02:40 -08003170 return new Pair<Integer, List<String>>(source, exprList);
Yingyi Bu391f09e2015-10-29 13:49:39 -07003171 }
3172}
3173
Yingyi Bu6d57e492016-06-06 21:24:42 -07003174String ConstantString() throws ParseException:
3175{
3176 String value = null;
3177}
3178{
3179 (value = QuotedString() | value = StringLiteral())
3180 {
3181 return value;
3182 }
3183}
3184
Yingyi Bu391f09e2015-10-29 13:49:39 -07003185String QuotedString() throws ParseException:
3186{
3187}
3188{
3189 <QUOTED_STRING>
3190 {
3191 return removeQuotesAndEscapes(token.image);
3192 }
3193}
3194
Yingyi Bu391f09e2015-10-29 13:49:39 -07003195String StringLiteral() throws ParseException:
3196{
Dmitry Lychagin984bc522021-10-13 16:22:25 -07003197 StringBuilder str = null;
3198 char quote = 0;
3199 boolean ext = false;
3200 Token litToken = null;
3201 String lit = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07003202}
3203{
Dmitry Lychagin984bc522021-10-13 16:22:25 -07003204 ( <STRING_LITERAL>
Yingyi Bu391f09e2015-10-29 13:49:39 -07003205 {
Dmitry Lychagin984bc522021-10-13 16:22:25 -07003206 String quoted = token.image;
3207 char q = quoted.charAt(0);
3208 boolean e = q == 'E';
3209 if (e) {
3210 q = quoted.charAt(1);
3211 quoted = quoted.substring(1);
3212 }
3213 if (lit == null) {
3214 quote = q;
3215 ext = e;
3216 } else {
3217 boolean isAdjacent = litToken.endLine == token.beginLine && litToken.endColumn + 1 == token.beginColumn;
3218 if (!isAdjacent || ext || e || (q != quote)) {
3219 throw new SqlppParseException(getSourceLocation(token), "Invalid string literal");
3220 }
3221 if (str == null) {
3222 str = new StringBuilder();
3223 }
3224 str.append(lit);
3225 str.append(quote);
3226 }
3227 lit = removeQuotesAndEscapes(quoted);
3228 litToken = token;
Yingyi Bu391f09e2015-10-29 13:49:39 -07003229 }
Dmitry Lychagin984bc522021-10-13 16:22:25 -07003230 )+
3231 {
3232 if (str == null) {
3233 return lit;
3234 } else {
3235 str.append(lit);
3236 return str.toString();
3237 }
3238 }
Yingyi Bu391f09e2015-10-29 13:49:39 -07003239}
3240
Dmitry Lychagin13a40e12021-04-08 18:22:57 -07003241Triple<List<String>, Token, Token> MultipartIdentifier() throws ParseException:
Yingyi Bu391f09e2015-10-29 13:49:39 -07003242{
Dmitry Lychagin13a40e12021-04-08 18:22:57 -07003243 Triple<List<String>, Token, Token> result = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07003244}
3245{
Dmitry Lychagin54c06012019-11-13 15:54:20 -08003246 result = MultipartIdentifierWithHints(null)
Yingyi Bu391f09e2015-10-29 13:49:39 -07003247 {
Dmitry Lychagin13a40e12021-04-08 18:22:57 -07003248 return result;
Yingyi Bu391f09e2015-10-29 13:49:39 -07003249 }
3250}
3251
Dmitry Lychagin13a40e12021-04-08 18:22:57 -07003252Triple<List<String>, Token, Token> MultipartIdentifierWithHints(SqlppHint... expectedHints)
Dmitry Lychagin54c06012019-11-13 15:54:20 -08003253 throws ParseException:
Yingyi Bu391f09e2015-10-29 13:49:39 -07003254{
Dmitry Lychagin54c06012019-11-13 15:54:20 -08003255 List<String> list = new ArrayList<String>();
3256 SourceLocation sourceLoc = null;
Dmitry Lychagin13a40e12021-04-08 18:22:57 -07003257 Token startToken, hintToken = null;
Dmitry Lychagin54c06012019-11-13 15:54:20 -08003258 String item = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07003259}
3260{
Dmitry Lychagin54c06012019-11-13 15:54:20 -08003261 item = Identifier()
Yingyi Bu391f09e2015-10-29 13:49:39 -07003262 {
Dmitry Lychagin54c06012019-11-13 15:54:20 -08003263 list.add(item);
Dmitry Lychagin13a40e12021-04-08 18:22:57 -07003264 startToken = token;
Dmitry Lychagin54c06012019-11-13 15:54:20 -08003265 if (expectedHints != null && expectedHints.length > 0) {
Dmitry Lychagin13a40e12021-04-08 18:22:57 -07003266 hintToken = fetchHint(token, expectedHints);
Yingyi Bu391f09e2015-10-29 13:49:39 -07003267 }
Dmitry Lychagin54c06012019-11-13 15:54:20 -08003268 }
3269 (<DOT> item = Identifier() { list.add(item); } )*
3270 {
Dmitry Lychagin13a40e12021-04-08 18:22:57 -07003271 return new Triple<List<String>, Token, Token>(list, startToken, hintToken);
3272 }
3273}
3274
3275DataverseName DataverseName() throws ParseException:
3276{
3277 Triple<List<String>, Token, Token> ident = null;
3278}
3279{
3280 ident = MultipartIdentifier()
3281 {
3282 List<String> list = ident.first;
3283 Token startToken = ident.second;
3284 return createDataverseName(list, 0, list.size(), startToken);
Dmitry Lychagin54c06012019-11-13 15:54:20 -08003285 }
3286}
3287
3288Pair<DataverseName,Identifier> QualifiedName() throws ParseException:
3289{
Dmitry Lychagin13a40e12021-04-08 18:22:57 -07003290 Triple<List<String>, Token, Token> ident = null;
Dmitry Lychagin54c06012019-11-13 15:54:20 -08003291}
3292{
Dmitry Lychagin13a40e12021-04-08 18:22:57 -07003293 ident = MultipartIdentifier()
Dmitry Lychagin54c06012019-11-13 15:54:20 -08003294 {
Dmitry Lychagin13a40e12021-04-08 18:22:57 -07003295 List<String> list = ident.first;
3296 Token startToken = ident.second;
Dmitry Lychagin54c06012019-11-13 15:54:20 -08003297 int len = list.size();
Dmitry Lychagin13a40e12021-04-08 18:22:57 -07003298 DataverseName id1 = len > 1 ? createDataverseName(list, 0, len - 1, startToken) : null;
Dmitry Lychagin54c06012019-11-13 15:54:20 -08003299 Identifier id2 = new Identifier(list.get(len - 1));
3300 return new Pair<DataverseName,Identifier>(id1, id2);
3301 }
3302}
3303
3304Triple<DataverseName, Identifier, Identifier> DoubleQualifiedName() throws ParseException:
3305{
3306 List<String> list = new ArrayList<String>();
3307 String item = null;
Dmitry Lychagin13a40e12021-04-08 18:22:57 -07003308 Token startToken = null;
Dmitry Lychagin54c06012019-11-13 15:54:20 -08003309}
3310{
Dmitry Lychagin13a40e12021-04-08 18:22:57 -07003311 item = Identifier() { list.add(item); startToken = token; }
Dmitry Lychagin54c06012019-11-13 15:54:20 -08003312 (<DOT> item = Identifier() { list.add(item); } )+
3313 {
3314 int len = list.size();
Dmitry Lychagin13a40e12021-04-08 18:22:57 -07003315 DataverseName id1 = len > 2 ? createDataverseName(list, 0, len - 2, startToken) : null;
Dmitry Lychagin54c06012019-11-13 15:54:20 -08003316 Identifier id2 = new Identifier(list.get(len - 2));
3317 Identifier id3 = new Identifier(list.get(len - 1));
3318 return new Triple<DataverseName,Identifier,Identifier>(id1, id2, id3);
Yingyi Bu391f09e2015-10-29 13:49:39 -07003319 }
3320}
3321
3322FunctionDecl FunctionDeclaration() throws ParseException:
3323{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07003324 Token startToken = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07003325 String functionName;
Dmitry Lychagin541652082020-11-09 14:04:53 -08003326 Pair<Integer, List<Pair<VarIdentifier,TypeExpression>>> paramsWithArity = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07003327 Expression funcBody;
3328 createNewScope();
3329}
3330{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07003331 <DECLARE> { startToken = token; } <FUNCTION>
Xikui Wang3de700a2018-03-15 16:32:55 -07003332 functionName = Identifier()
Dmitry Lychagin541652082020-11-09 14:04:53 -08003333 paramsWithArity = FunctionParameters()
Xikui Wang3de700a2018-03-15 16:32:55 -07003334 <LEFTBRACE>
Dmitry Lychagin0d4c1b62020-02-07 17:10:16 -08003335 funcBody = FunctionBody()
Xikui Wang3de700a2018-03-15 16:32:55 -07003336 <RIGHTBRACE>
3337 {
Dmitry Lychagin541652082020-11-09 14:04:53 -08003338 int arity = paramsWithArity.first;
3339 List<Pair<VarIdentifier,TypeExpression>> paramList = paramsWithArity.second;
3340 FunctionSignature signature = new FunctionSignature(defaultDataverse, functionName, arity);
Xikui Wang3de700a2018-03-15 16:32:55 -07003341 getCurrentScope().addFunctionDescriptor(signature, false);
Dmitry Lychaginf7bc6c12020-06-01 18:19:44 -07003342 ensureNoTypeDeclsInFunction(functionName, paramList, null, startToken);
3343 List<VarIdentifier> params = new ArrayList<VarIdentifier>(paramList.size());
3344 for (Pair<VarIdentifier,TypeExpression> p: paramList) {
3345 params.add(p.getFirst());
Ian Maxon38fe9402020-01-29 19:27:40 -08003346 }
Dmitry Lychagin9ba74872021-04-05 14:38:20 -07003347 FunctionDecl stmt = new FunctionDecl(signature, params, funcBody, false);
Xikui Wang3de700a2018-03-15 16:32:55 -07003348 removeCurrentScope();
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07003349 return addSourceLocation(stmt, startToken);
Xikui Wang3de700a2018-03-15 16:32:55 -07003350 }
Yingyi Bu391f09e2015-10-29 13:49:39 -07003351}
3352
Dmitry Lychaginaebd0312019-06-04 08:55:39 -07003353Query Query() throws ParseException:
Yingyi Bu391f09e2015-10-29 13:49:39 -07003354{
Dmitry Lychaginaebd0312019-06-04 08:55:39 -07003355 Query query = new Query();
Yingyi Bu391f09e2015-10-29 13:49:39 -07003356 Expression expr;
3357}
3358{
3359 (
3360 expr = Expression()
3361 |
3362 expr = SelectExpression(false)
3363 )
3364 {
3365 query.setBody(expr);
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07003366 query.setSourceLocation(expr.getSourceLocation());
Yingyi Bu391f09e2015-10-29 13:49:39 -07003367 return query;
3368 }
3369}
3370
3371
Yingyi Bu391f09e2015-10-29 13:49:39 -07003372Expression Expression():
3373{
3374 Expression expr = null;
3375 Expression exprP = null;
3376}
3377{
3378(
3379 LOOKAHEAD(2)
3380 expr = OperatorExpr()
Yingyi Bu391f09e2015-10-29 13:49:39 -07003381 | expr = QuantifiedExpression()
3382)
3383 {
3384 return (exprP==null) ? expr : exprP;
3385 }
3386}
3387
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07003388Expression OperatorExpr() throws ParseException:
Yingyi Bu391f09e2015-10-29 13:49:39 -07003389{
3390 OperatorExpr op = null;
3391 Expression operand = null;
3392}
3393{
3394 operand = AndExpr()
3395 (
Yingyi Bu391f09e2015-10-29 13:49:39 -07003396 <OR>
3397 {
3398 if (op == null) {
3399 op = new OperatorExpr();
3400 op.addOperand(operand);
Xikui Wang3de700a2018-03-15 16:32:55 -07003401 op.setCurrentop(true);
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07003402 addSourceLocation(op, token);
Yingyi Bu391f09e2015-10-29 13:49:39 -07003403 }
Yingyi Bu196db5d2016-07-15 19:07:20 -07003404 try{
3405 op.addOperator(token.image.toLowerCase());
3406 } catch (Exception e){
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07003407 throw new SqlppParseException(getSourceLocation(token), e.getMessage());
Yingyi Bu196db5d2016-07-15 19:07:20 -07003408 }
Xikui Wang3de700a2018-03-15 16:32:55 -07003409 }
Yingyi Bu391f09e2015-10-29 13:49:39 -07003410
Xikui Wang3de700a2018-03-15 16:32:55 -07003411 operand = AndExpr()
3412 {
3413 op.addOperand(operand);
3414 }
Yingyi Bu391f09e2015-10-29 13:49:39 -07003415
3416 )*
3417
3418 {
3419 return op==null? operand: op;
3420 }
3421}
3422
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07003423Expression AndExpr() throws ParseException:
Yingyi Bu391f09e2015-10-29 13:49:39 -07003424{
3425 OperatorExpr op = null;
3426 Expression operand = null;
3427}
3428{
Yingyi Bu196db5d2016-07-15 19:07:20 -07003429 operand = NotExpr()
Yingyi Bu391f09e2015-10-29 13:49:39 -07003430 (
Yingyi Bu391f09e2015-10-29 13:49:39 -07003431 <AND>
3432 {
3433 if (op == null) {
3434 op = new OperatorExpr();
3435 op.addOperand(operand);
Yingyi Bu196db5d2016-07-15 19:07:20 -07003436 op.setCurrentop(true);
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07003437 addSourceLocation(op, token);
Yingyi Bu391f09e2015-10-29 13:49:39 -07003438 }
Yingyi Bu196db5d2016-07-15 19:07:20 -07003439 try{
3440 op.addOperator(token.image.toLowerCase());
Taewoo Kime65e6ca2017-01-14 17:53:28 -08003441 } catch (CompilationException e){
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07003442 throw new SqlppParseException(getSourceLocation(token), e.getMessage());
Yingyi Bu196db5d2016-07-15 19:07:20 -07003443 }
Yingyi Bu391f09e2015-10-29 13:49:39 -07003444 }
3445
Yingyi Bu196db5d2016-07-15 19:07:20 -07003446 operand = NotExpr()
Yingyi Bu391f09e2015-10-29 13:49:39 -07003447 {
3448 op.addOperand(operand);
3449 }
3450
3451 )*
3452
3453 {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07003454 return op==null ? operand: op;
Yingyi Bu391f09e2015-10-29 13:49:39 -07003455 }
3456}
3457
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07003458Expression NotExpr() throws ParseException:
Yingyi Bu196db5d2016-07-15 19:07:20 -07003459{
3460 Expression inputExpr;
3461 boolean not = false;
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07003462 Token startToken = null;
Yingyi Bu196db5d2016-07-15 19:07:20 -07003463}
3464{
Dmitry Lychagin5476f962019-05-31 16:03:11 -07003465 (LOOKAHEAD(2) <NOT> { not = true; startToken = token; } )? inputExpr = RelExpr()
Yingyi Bu196db5d2016-07-15 19:07:20 -07003466 {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07003467 if(not) {
Dmitry Lychagin7c53fcf2017-11-07 12:07:41 -08003468 FunctionSignature signature = new FunctionSignature(BuiltinFunctions.NOT);
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07003469 CallExpr callExpr = new CallExpr(signature, new ArrayList<Expression>(Collections.singletonList(inputExpr)));
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07003470 return addSourceLocation(callExpr, startToken);
Yingyi Bu196db5d2016-07-15 19:07:20 -07003471 } else {
3472 return inputExpr;
3473 }
3474 }
3475}
Yingyi Bu391f09e2015-10-29 13:49:39 -07003476
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07003477Expression RelExpr() throws ParseException:
Yingyi Bu391f09e2015-10-29 13:49:39 -07003478{
Yingyi Bua8baf6d2016-07-05 21:40:44 -07003479 boolean not = false;
Yingyi Bu391f09e2015-10-29 13:49:39 -07003480 OperatorExpr op = null;
Dmitry Lychagin4d5476e2021-08-18 19:43:22 -07003481 Token opToken = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07003482 Expression operand = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07003483 IExpressionAnnotation annotation = null;
3484}
3485{
Yingyi Bu6c638342016-09-02 17:54:34 -07003486 operand = BetweenExpr()
Yingyi Bu391f09e2015-10-29 13:49:39 -07003487
3488 (
Dmitry Lychagin4d5476e2021-08-18 19:43:22 -07003489 LOOKAHEAD(3)( <LT> | <GT> | <LE> | <GE> | <EQ> | <NE> | <LG> |<SIMILAR> | (<NOT> { not = true; })? <IN> |
3490 <IS> (<NOT> { not = true; })? <DISTINCT> { opToken = token; } <FROM> )
Yingyi Bu391f09e2015-10-29 13:49:39 -07003491 {
Dmitry Lychagin4d5476e2021-08-18 19:43:22 -07003492 if (opToken == null) {
3493 opToken = token;
3494 }
Dmitry Lychagin6fd8ab32020-12-03 09:04:14 -08003495 Token hintToken = fetchHint(token,
3496 SqlppHint.HASH_BROADCAST_JOIN_HINT, SqlppHint.INDEXED_NESTED_LOOP_JOIN_HINT,
3497 SqlppHint.SKIP_SECONDARY_INDEX_SEARCH_HINT, SqlppHint.USE_SECONDARY_INDEX_SEARCH_HINT
3498 );
Dmitry Lychagine77cdac2019-08-05 11:37:47 -07003499 if (hintToken != null) {
Dmitry Lychagin6fd8ab32020-12-03 09:04:14 -08003500 annotation = parseExpressionAnnotation(hintToken);
Yingyi Bu391f09e2015-10-29 13:49:39 -07003501 }
Dmitry Lychagin4d5476e2021-08-18 19:43:22 -07003502 String operator = opToken.image.toLowerCase();
Yingyi Bu4a4b8962016-09-16 12:09:11 -07003503 if (operator.equals("<>")){
3504 operator = "!=";
3505 }
3506 if (not) {
Yingyi Bua8baf6d2016-07-05 21:40:44 -07003507 operator = "not_" + operator;
3508 }
Yingyi Bu391f09e2015-10-29 13:49:39 -07003509 if (op == null) {
3510 op = new OperatorExpr();
Shiva2ea73232019-10-09 18:04:05 -07003511 op.addOperand(operand);
Yingyi Bua8baf6d2016-07-05 21:40:44 -07003512 op.setCurrentop(true);
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07003513 addSourceLocation(op, token);
Yingyi Bu391f09e2015-10-29 13:49:39 -07003514 }
Yingyi Bu196db5d2016-07-15 19:07:20 -07003515 try{
3516 op.addOperator(operator);
Taewoo Kime65e6ca2017-01-14 17:53:28 -08003517 } catch (CompilationException e){
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07003518 throw new SqlppParseException(getSourceLocation(token), e.getMessage());
Yingyi Bu196db5d2016-07-15 19:07:20 -07003519 }
Yingyi Bua8baf6d2016-07-05 21:40:44 -07003520 }
Yingyi Bu391f09e2015-10-29 13:49:39 -07003521
Yingyi Bu6c638342016-09-02 17:54:34 -07003522 operand = BetweenExpr()
Yingyi Buea4ec722016-11-04 01:26:16 -07003523 {
Shiva2ea73232019-10-09 18:04:05 -07003524 op.addOperand(operand);
Yingyi Buea4ec722016-11-04 01:26:16 -07003525 }
Yingyi Bu391f09e2015-10-29 13:49:39 -07003526 )?
3527
3528 {
3529 if (annotation != null) {
3530 op.addHint(annotation);
3531 }
3532 return op==null? operand: op;
3533 }
3534}
3535
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07003536Expression BetweenExpr() throws ParseException:
Yingyi Bu6c638342016-09-02 17:54:34 -07003537{
3538 boolean not = false;
3539 OperatorExpr op = null;
3540 Expression operand = null;
3541 IExpressionAnnotation annotation = null;
3542}
3543{
3544 operand = IsExpr()
3545 (
3546 LOOKAHEAD(2)
3547 (<NOT> { not = true; })? <BETWEEN>
3548 {
Dmitry Lychagin6fd8ab32020-12-03 09:04:14 -08003549 Token hintToken = fetchHint(token,
3550 SqlppHint.INDEXED_NESTED_LOOP_JOIN_HINT, SqlppHint.SKIP_SECONDARY_INDEX_SEARCH_HINT,
3551 SqlppHint.USE_SECONDARY_INDEX_SEARCH_HINT
3552 );
Dmitry Lychagine77cdac2019-08-05 11:37:47 -07003553 if (hintToken != null) {
Dmitry Lychagin6fd8ab32020-12-03 09:04:14 -08003554 annotation = parseExpressionAnnotation(hintToken);
Yingyi Bu6c638342016-09-02 17:54:34 -07003555 }
3556 String operator = token.image.toLowerCase();
3557 if(not){
3558 operator = "not_" + operator;
3559 }
3560 if (op == null) {
3561 op = new OperatorExpr();
3562 op.addOperand(operand);
3563 op.setCurrentop(true);
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07003564 addSourceLocation(op, token);
Yingyi Bu6c638342016-09-02 17:54:34 -07003565 }
3566 try{
3567 op.addOperator(operator);
Taewoo Kime65e6ca2017-01-14 17:53:28 -08003568 } catch (CompilationException e){
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07003569 throw new SqlppParseException(getSourceLocation(token), e.getMessage());
Yingyi Bu6c638342016-09-02 17:54:34 -07003570 }
3571 }
3572
3573 operand = IsExpr()
3574 {
3575 op.addOperand(operand);
3576 }
3577
3578 <AND>
3579 operand = IsExpr()
3580 {
Dmitry Lychaginef1719e2017-12-15 08:33:07 -08003581 op.addOperator(OperatorType.AND);
Yingyi Bu6c638342016-09-02 17:54:34 -07003582 op.addOperand(operand);
3583 }
3584 )?
3585
3586 {
3587 if (annotation != null) {
3588 op.addHint(annotation);
3589 }
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07003590 return op==null ? operand: op;
Yingyi Bu6c638342016-09-02 17:54:34 -07003591 }
3592}
3593
Yingyi Budaa549c2016-06-28 22:30:52 -07003594Expression IsExpr() throws ParseException:
3595{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07003596 Token notToken = null;
3597 CallExpr expr = null;
Yingyi Budaa549c2016-06-28 22:30:52 -07003598 Expression operand = null;
3599 boolean not = false;
Dmitry Lychagin7c53fcf2017-11-07 12:07:41 -08003600 FunctionIdentifier fn = null;
Yingyi Budaa549c2016-06-28 22:30:52 -07003601}
3602{
Yingyi Bu6e6a80c2017-01-21 20:18:49 -08003603 operand = LikeExpr()
Dmitry Lychagin4d5476e2021-08-18 19:43:22 -07003604 (
3605 LOOKAHEAD(3)
3606 <IS>
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07003607 (<NOT> { not = true; notToken = token; })?
Dmitry Lychagin7c53fcf2017-11-07 12:07:41 -08003608 (
3609 <NULL> { fn = BuiltinFunctions.IS_NULL; } |
3610 <MISSING> { fn = BuiltinFunctions.IS_MISSING; } |
Dmitry Lychagin7d594a32018-01-15 14:31:03 -08003611 <UNKNOWN> { fn = BuiltinFunctions.IS_UNKNOWN; } |
Dmitry Lychagin1aa0dd42018-04-17 14:35:24 -07003612 (<KNOWN> | <VALUED>) { not = !not; fn = BuiltinFunctions.IS_UNKNOWN; }
Dmitry Lychagin7c53fcf2017-11-07 12:07:41 -08003613 )
Yingyi Budaa549c2016-06-28 22:30:52 -07003614 {
Dmitry Lychagin7c53fcf2017-11-07 12:07:41 -08003615 FunctionSignature signature = new FunctionSignature(fn);
Yingyi Budaa549c2016-06-28 22:30:52 -07003616 expr = new CallExpr(signature, new ArrayList<Expression>(Collections.singletonList(operand)));
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07003617 addSourceLocation(expr, token);
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07003618 if (not) {
Dmitry Lychagin7c53fcf2017-11-07 12:07:41 -08003619 FunctionSignature notSignature = new FunctionSignature(BuiltinFunctions.NOT);
Yingyi Budaa549c2016-06-28 22:30:52 -07003620 expr = new CallExpr(notSignature, new ArrayList<Expression>(Collections.singletonList(expr)));
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07003621 addSourceLocation(expr, notToken);
Yingyi Budaa549c2016-06-28 22:30:52 -07003622 }
3623 }
3624 )?
3625 {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07003626 return expr == null ? operand : expr;
Yingyi Budaa549c2016-06-28 22:30:52 -07003627 }
3628}
3629
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07003630Expression LikeExpr() throws ParseException:
Yingyi Bu6e6a80c2017-01-21 20:18:49 -08003631{
3632 boolean not = false;
3633 OperatorExpr op = null;
3634 Expression operand = null;
3635}
3636{
3637 operand = ConcatExpr()
3638 (
3639 LOOKAHEAD(2)
3640 (<NOT> { not = true; })? <LIKE>
3641 {
3642 op = new OperatorExpr();
3643 op.addOperand(operand);
3644 op.setCurrentop(true);
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07003645 addSourceLocation(op, token);
Yingyi Bu6e6a80c2017-01-21 20:18:49 -08003646
3647 String operator = token.image.toLowerCase();
3648 if (not) {
3649 operator = "not_" + operator;
3650 }
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07003651 try {
Yingyi Bu6e6a80c2017-01-21 20:18:49 -08003652 op.addOperator(operator);
3653 } catch (CompilationException e){
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07003654 throw new SqlppParseException(getSourceLocation(token), e.getMessage());
Yingyi Bu6e6a80c2017-01-21 20:18:49 -08003655 }
3656 }
3657
3658 operand = ConcatExpr()
3659 {
3660 op.addOperand(operand);
3661 }
3662 )?
3663
3664 {
3665 return op == null ? operand : op;
3666 }
3667}
3668
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07003669Expression ConcatExpr() throws ParseException:
Yingyi Bufdc71eb2016-08-24 22:41:57 -07003670{
3671 OperatorExpr op = null;
3672 Expression operand = null;
3673}
3674{
3675 operand = AddExpr()
3676 (
3677 LOOKAHEAD(1)
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07003678 <CONCAT>
Yingyi Bufdc71eb2016-08-24 22:41:57 -07003679 {
3680 if (op == null) {
3681 op = new OperatorExpr();
3682 op.addOperand(operand);
3683 op.setCurrentop(true);
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07003684 addSourceLocation(op, token);
Yingyi Bufdc71eb2016-08-24 22:41:57 -07003685 }
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07003686 op.addOperator(OperatorType.CONCAT);
Yingyi Bufdc71eb2016-08-24 22:41:57 -07003687 }
3688 operand = AddExpr()
3689 {
3690 op.addOperand(operand);
3691 }
3692 )*
3693
3694 {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07003695 return op == null ? operand : op;
Yingyi Bufdc71eb2016-08-24 22:41:57 -07003696 }
3697}
Yingyi Budaa549c2016-06-28 22:30:52 -07003698
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07003699Expression AddExpr() throws ParseException:
Yingyi Bu391f09e2015-10-29 13:49:39 -07003700{
3701 OperatorExpr op = null;
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07003702 OperatorType opType = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07003703 Expression operand = null;
3704}
3705{
3706 operand = MultExpr()
Yingyi Budaa549c2016-06-28 22:30:52 -07003707 (
Yingyi Bufdc71eb2016-08-24 22:41:57 -07003708 LOOKAHEAD(1)
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07003709 (<PLUS> { opType = OperatorType.PLUS; } | <MINUS> { opType = OperatorType.MINUS; } )
Yingyi Bu391f09e2015-10-29 13:49:39 -07003710 {
3711 if (op == null) {
3712 op = new OperatorExpr();
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07003713 op.addOperand(operand);
3714 op.setCurrentop(true);
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07003715 addSourceLocation(op, token);
Yingyi Bu391f09e2015-10-29 13:49:39 -07003716 }
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07003717 op.addOperator(opType);
Yingyi Bu391f09e2015-10-29 13:49:39 -07003718 }
3719
3720 operand = MultExpr()
3721 {
3722 op.addOperand(operand);
3723 }
3724 )*
3725
3726 {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07003727 return op == null ? operand : op;
Yingyi Bu391f09e2015-10-29 13:49:39 -07003728 }
3729}
3730
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07003731Expression MultExpr() throws ParseException:
Yingyi Bu391f09e2015-10-29 13:49:39 -07003732{
3733 OperatorExpr op = null;
Dmitry Lychaginbf48c492018-05-01 18:30:27 -07003734 OperatorType opType = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07003735 Expression operand = null;
3736}
3737{
Yingyi Bu79ccdac2016-07-26 23:49:24 -07003738 operand = ExponentExpr()
Yingyi Bu391f09e2015-10-29 13:49:39 -07003739
Dmitry Lychaginbf48c492018-05-01 18:30:27 -07003740 ( (
3741 <MUL> { opType = OperatorType.MUL; } |
3742 <DIVIDE> { opType = OperatorType.DIVIDE; } |
3743 <DIV> { opType = OperatorType.DIV; } |
3744 ( <MOD> | <PERCENT> ) { opType = OperatorType.MOD; }
3745 )
Yingyi Bu391f09e2015-10-29 13:49:39 -07003746 {
3747 if (op == null) {
3748 op = new OperatorExpr();
Yingyi Bu79ccdac2016-07-26 23:49:24 -07003749 op.addOperand(operand);
3750 op.setCurrentop(true);
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07003751 addSourceLocation(op, token);
Yingyi Bu79ccdac2016-07-26 23:49:24 -07003752 }
Dmitry Lychaginbf48c492018-05-01 18:30:27 -07003753 op.addOperator(opType);
Yingyi Bu79ccdac2016-07-26 23:49:24 -07003754 }
3755 operand = ExponentExpr()
3756 {
3757 op.addOperand(operand);
3758 }
3759 )*
3760
3761 {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07003762 return op == null ? operand : op;
Yingyi Bu79ccdac2016-07-26 23:49:24 -07003763 }
3764}
3765
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07003766Expression ExponentExpr() throws ParseException:
Yingyi Bu79ccdac2016-07-26 23:49:24 -07003767{
3768 OperatorExpr op = null;
3769 Expression operand = null;
3770}
3771{
3772 operand = UnaryExpr()
3773 (<CARET>
3774 {
3775 if (op == null) {
3776 op = new OperatorExpr();
3777 op.addOperand(operand);
3778 op.setCurrentop(true);
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07003779 addSourceLocation(op, token);
Yingyi Bu391f09e2015-10-29 13:49:39 -07003780 }
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07003781 op.addOperator(OperatorType.CARET);
Yingyi Bu391f09e2015-10-29 13:49:39 -07003782 }
3783 operand = UnaryExpr()
3784 {
3785 op.addOperand(operand);
3786 }
Yingyi Bu79ccdac2016-07-26 23:49:24 -07003787 )?
3788 {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07003789 return op == null ? operand : op;
Yingyi Bu79ccdac2016-07-26 23:49:24 -07003790 }
Yingyi Bu391f09e2015-10-29 13:49:39 -07003791}
3792
3793Expression UnaryExpr() throws ParseException:
3794{
Yingyi Bu196db5d2016-07-15 19:07:20 -07003795 boolean not = false;
3796 UnaryExpr uexpr = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07003797 Expression expr = null;
3798}
Yingyi Budaa549c2016-06-28 22:30:52 -07003799{
Yingyi Bu196db5d2016-07-15 19:07:20 -07003800 ( (<PLUS> | <MINUS> | (<NOT> { not = true; } )? <EXISTS> )
Yingyi Bu391f09e2015-10-29 13:49:39 -07003801 {
Yingyi Bu196db5d2016-07-15 19:07:20 -07003802 String exprType = token.image.toLowerCase();
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07003803 if (not) {
Yingyi Bu196db5d2016-07-15 19:07:20 -07003804 exprType = "not_" + exprType;
3805 }
3806 uexpr = new UnaryExpr();
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07003807 addSourceLocation(uexpr, token);
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07003808 try {
Yingyi Bu196db5d2016-07-15 19:07:20 -07003809 uexpr.setExprType(exprType);
Taewoo Kime65e6ca2017-01-14 17:53:28 -08003810 } catch (CompilationException e){
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07003811 throw new SqlppParseException(getSourceLocation(token), e.getMessage());
Yingyi Budaa549c2016-06-28 22:30:52 -07003812 }
Yingyi Bu391f09e2015-10-29 13:49:39 -07003813 }
3814 )?
3815
3816 expr = ValueExpr()
3817 {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07003818 if (uexpr == null) {
3819 return expr;
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07003820 } else {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07003821 uexpr.setExpr(expr);
3822 return uexpr;
3823 }
Yingyi Bu391f09e2015-10-29 13:49:39 -07003824 }
3825}
3826
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07003827Expression ValueExpr() throws ParseException:
Yingyi Bu391f09e2015-10-29 13:49:39 -07003828{
3829 Expression expr = null;
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07003830 AbstractAccessor accessor = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07003831}
3832{
Hussain Towailebc5b5deb2018-12-15 18:48:48 +03003833 expr = PrimaryExpr()
3834 (
3835 accessor = FieldAccessor(accessor != null ? accessor : expr)
3836 |
3837 accessor = IndexAccessor(accessor != null ? accessor : expr)
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07003838 )*
3839 {
3840 return accessor == null ? expr : accessor;
3841 }
Yingyi Bu391f09e2015-10-29 13:49:39 -07003842}
3843
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07003844FieldAccessor FieldAccessor(Expression inputExpr) throws ParseException:
Yingyi Bu391f09e2015-10-29 13:49:39 -07003845{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07003846 Token startToken = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07003847 String ident = null;
3848}
3849{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07003850 <DOT> { startToken = token; } ident = Identifier()
Yingyi Bu391f09e2015-10-29 13:49:39 -07003851 {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07003852 FieldAccessor fa = new FieldAccessor(inputExpr, new Identifier(ident));
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07003853 return addSourceLocation(fa, startToken);
Yingyi Bu391f09e2015-10-29 13:49:39 -07003854 }
3855}
3856
Hussain Towailebc5b5deb2018-12-15 18:48:48 +03003857AbstractAccessor IndexAccessor(Expression inputExpr) throws ParseException:
Yingyi Bu391f09e2015-10-29 13:49:39 -07003858{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07003859 Token startToken = null;
Dmitry Lychagin0a722532020-08-27 18:39:25 -07003860 boolean star = false, slice = false;
3861 Expression expr1 = null, expr2 = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07003862}
3863{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07003864 <LEFTBRACKET> { startToken = token; }
Dmitry Lychagin0a722532020-08-27 18:39:25 -07003865 (
3866 <MUL> { star = true; }
3867 |
3868 ( expr1 = Expression() ( <COLON> { slice = true; } ( expr2 = Expression() )? )? )
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07003869 )
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07003870 <RIGHTBRACKET>
3871 {
Dmitry Lychagin0a722532020-08-27 18:39:25 -07003872 if (expr1 != null && expr1.getKind() == Expression.Kind.LITERAL_EXPRESSION) {
3873 ensureIntegerLiteral( (LiteralExpr) expr1, "Index");
Hussain Towailebc5b5deb2018-12-15 18:48:48 +03003874 }
Dmitry Lychagin0a722532020-08-27 18:39:25 -07003875 if (expr2 != null && expr2.getKind() == Expression.Kind.LITERAL_EXPRESSION) {
3876 ensureIntegerLiteral( (LiteralExpr) expr2, "Index");
3877 }
3878 AbstractAccessor resultAccessor;
3879 if (slice) {
3880 resultAccessor = new ListSliceExpression(inputExpr, expr1, expr2);
3881 } else if (star) {
3882 resultAccessor = new IndexAccessor(inputExpr, IndexAccessor.IndexKind.STAR, null);
3883 } else {
3884 resultAccessor = new IndexAccessor(inputExpr, IndexAccessor.IndexKind.ELEMENT, expr1);
3885 }
3886 return addSourceLocation(resultAccessor, startToken);
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07003887 }
Yingyi Bu391f09e2015-10-29 13:49:39 -07003888}
3889
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07003890Expression PrimaryExpr() throws ParseException:
Yingyi Bu391f09e2015-10-29 13:49:39 -07003891{
3892 Expression expr = null;
3893}
3894{
Dmitry Lychagin54c06012019-11-13 15:54:20 -08003895 (
3896 LOOKAHEAD(Identifier() (<DOT> Identifier())* (<SHARP> Identifier())? <LEFTPAREN>) expr = FunctionCallExpr()
Dmitry Lychagin5fbd04b2018-04-19 16:54:28 -07003897 | expr = CaseExpr()
Yingyi Bu391f09e2015-10-29 13:49:39 -07003898 | expr = Literal()
3899 | expr = VariableRef()
Dmitry Lychagin1bdf8082018-06-13 14:48:23 -07003900 | expr = ExternalVariableRef()
Yingyi Bu391f09e2015-10-29 13:49:39 -07003901 | expr = ListConstructor()
3902 | expr = RecordConstructor()
3903 | expr = ParenthesizedExpression()
3904 )
3905 {
3906 return expr;
3907 }
3908}
3909
3910Expression Literal() throws ParseException:
3911{
3912 LiteralExpr lit = new LiteralExpr();
3913 String str = null;
3914}
3915{
3916 ( str = StringLiteral()
3917 {
3918 lit.setValue(new StringLiteral(str));
3919 }
3920 | <INTEGER_LITERAL>
3921 {
Till Westmann68c6a992016-09-30 00:19:12 -07003922 try {
3923 lit.setValue(new LongIntegerLiteral(Long.valueOf(token.image)));
3924 } catch (NumberFormatException e) {
Ali Alsuliman587b7902019-01-21 14:33:50 -08003925 throw new SqlppParseException(getSourceLocation(token), "Could not parse numeric literal \"" + LogRedactionUtil.userData(token.image) +'"');
Till Westmann68c6a992016-09-30 00:19:12 -07003926 }
Yingyi Bu391f09e2015-10-29 13:49:39 -07003927 }
3928 | <FLOAT_LITERAL>
3929 {
Till Westmann68c6a992016-09-30 00:19:12 -07003930 try {
3931 lit.setValue(new FloatLiteral(Float.valueOf(token.image)));
3932 } catch (NumberFormatException e) {
Ali Alsuliman587b7902019-01-21 14:33:50 -08003933 throw new SqlppParseException(getSourceLocation(token), "Could not parse numeric literal \"" + LogRedactionUtil.userData(token.image) +'"');
Till Westmann68c6a992016-09-30 00:19:12 -07003934 }
Yingyi Bu391f09e2015-10-29 13:49:39 -07003935 }
3936 | <DOUBLE_LITERAL>
3937 {
Till Westmann68c6a992016-09-30 00:19:12 -07003938 try {
3939 lit.setValue(new DoubleLiteral(Double.valueOf(token.image)));
3940 } catch (NumberFormatException e) {
Ali Alsuliman587b7902019-01-21 14:33:50 -08003941 throw new SqlppParseException(getSourceLocation(token), "Could not parse numeric literal \"" + LogRedactionUtil.userData(token.image) +'"');
Till Westmann68c6a992016-09-30 00:19:12 -07003942 }
Yingyi Bu391f09e2015-10-29 13:49:39 -07003943 }
Yingyi Bu535d86b2016-05-23 16:44:25 -07003944 | <MISSING>
3945 {
3946 lit.setValue(MissingLiteral.INSTANCE);
3947 }
Yingyi Bu391f09e2015-10-29 13:49:39 -07003948 | <NULL>
3949 {
3950 lit.setValue(NullLiteral.INSTANCE);
3951 }
3952 | <TRUE>
3953 {
3954 lit.setValue(TrueLiteral.INSTANCE);
3955 }
3956 | <FALSE>
3957 {
3958 lit.setValue(FalseLiteral.INSTANCE);
3959 }
3960 )
3961 {
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07003962 return addSourceLocation(lit, token);
Yingyi Bu391f09e2015-10-29 13:49:39 -07003963 }
3964}
3965
Yingyi Bu391f09e2015-10-29 13:49:39 -07003966VariableExpr VariableRef() throws ParseException:
3967{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07003968 String id = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07003969}
3970{
Dmitry Lychagin0d4c1b62020-02-07 17:10:16 -08003971 id = VariableIdentifier()
Yingyi Bu391f09e2015-10-29 13:49:39 -07003972 {
3973 Identifier ident = lookupSymbol(id);
3974 if (isInForbiddenScopes(id)) {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07003975 throw new SqlppParseException(getSourceLocation(token),
3976 "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 -07003977 }
Dmitry Lychagin75f19872019-10-03 17:56:35 -07003978 VariableExpr varExp;
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07003979 if (ident != null) { // exist such ident
Dmitry Lychagin75f19872019-10-03 17:56:35 -07003980 varExp = new VariableExpr((VarIdentifier)ident);
Yingyi Bu391f09e2015-10-29 13:49:39 -07003981 } else {
Dmitry Lychagin75f19872019-10-03 17:56:35 -07003982 varExp = new VariableExpr(new VarIdentifier(id));
Yingyi Buacc12a92016-03-26 17:25:05 -07003983 varExp.setIsNewVar(false);
Yingyi Bu391f09e2015-10-29 13:49:39 -07003984 }
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07003985 return addSourceLocation(varExp, token);
Yingyi Bu391f09e2015-10-29 13:49:39 -07003986 }
3987}
3988
Yingyi Bu391f09e2015-10-29 13:49:39 -07003989VariableExpr Variable() throws ParseException:
3990{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07003991 String id = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07003992}
3993{
Dmitry Lychagin0d4c1b62020-02-07 17:10:16 -08003994 id = VariableIdentifier()
Yingyi Bu391f09e2015-10-29 13:49:39 -07003995 {
3996 Identifier ident = lookupSymbol(id);
Dmitry Lychagin75f19872019-10-03 17:56:35 -07003997 VariableExpr varExp = new VariableExpr(new VarIdentifier(id));
3998 if (ident != null) { // exist such ident
Yingyi Bu391f09e2015-10-29 13:49:39 -07003999 varExp.setIsNewVar(false);
4000 }
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07004001 return addSourceLocation(varExp, token);
Yingyi Bu391f09e2015-10-29 13:49:39 -07004002 }
4003}
4004
Dmitry Lychagin0d4c1b62020-02-07 17:10:16 -08004005String VariableIdentifier() throws ParseException:
4006{
4007 String id = null;
4008}
4009{
4010 (<IDENTIFIER> { id = token.image; } | id = QuotedString())
4011 {
4012 return SqlppVariableUtil.toInternalVariableName(id); // prefix user-defined variables with "$".
4013 }
4014}
4015
Dmitry Lychaginf2c18aa2018-12-28 21:20:23 -08004016Pair<VariableExpr, List<Pair<Expression, Identifier>>> VariableWithFieldMap() throws ParseException:
4017{
4018 VariableExpr var = null;
4019 List<Pair<Expression, Identifier>> fieldList = new ArrayList<Pair<Expression, Identifier>>();
4020}
4021{
4022 var = Variable()
4023 ( LOOKAHEAD(1)
4024 {
4025 VariableExpr fieldVarExpr = null;
4026 String fieldIdentifierStr = null;
4027 }
4028 <LEFTPAREN>
4029 fieldVarExpr = VariableRef() <AS> fieldIdentifierStr = Identifier()
4030 {
4031 fieldList.add(new Pair<Expression, Identifier>(fieldVarExpr, new Identifier(fieldIdentifierStr)));
4032 }
4033 (<COMMA>
4034 fieldVarExpr = VariableRef() <AS> fieldIdentifierStr = Identifier()
4035 {
4036 fieldList.add(new Pair<Expression, Identifier>(fieldVarExpr, new Identifier(fieldIdentifierStr)));
4037 }
4038 )*
4039 <RIGHTPAREN>
4040 )?
4041 {
4042 return new Pair<VariableExpr, List<Pair<Expression, Identifier>>>(var, fieldList);
4043 }
4044}
4045
Dmitry Lychagin1bdf8082018-06-13 14:48:23 -07004046VariableExpr ExternalVariableRef() throws ParseException:
4047{
4048 String name = null;
4049}
4050{
4051 (
Dmitry Lychagin41b511d2020-12-07 14:48:13 -08004052 <DOLLAR_IDENTIFIER> { name = token.image.substring(1); }
4053 | <DOLLAR_INTEGER_LITERAL> { name = token.image.substring(1); }
4054 | <DOLLAR_QUOTED_STRING> { name = removeQuotesAndEscapes(token.image.substring(1)); }
4055 | <QUES> { name = String.valueOf(++externalVarCounter); }
Dmitry Lychagin1bdf8082018-06-13 14:48:23 -07004056 )
4057 {
4058 String idName = SqlppVariableUtil.toExternalVariableName(name);
4059 VarIdentifier id = new VarIdentifier(idName);
4060 VariableExpr varExp = new VariableExpr(id);
4061 return addSourceLocation(varExp, token);
4062 }
4063}
4064
Yingyi Bu391f09e2015-10-29 13:49:39 -07004065Expression ListConstructor() throws ParseException:
4066{
4067 Expression expr = null;
4068}
4069{
4070 (
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07004071 expr = OrderedListConstructor() |
4072 expr = UnorderedListConstructor()
Yingyi Bu391f09e2015-10-29 13:49:39 -07004073 )
Yingyi Bu391f09e2015-10-29 13:49:39 -07004074 {
4075 return expr;
4076 }
4077}
4078
Yingyi Bu391f09e2015-10-29 13:49:39 -07004079ListConstructor OrderedListConstructor() throws ParseException:
4080{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07004081 Token startToken = null;
4082 List<Expression> exprList = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07004083}
4084{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07004085 <LEFTBRACKET> { startToken = token; }
4086 exprList = ExpressionList()
4087 <RIGHTBRACKET>
4088 {
4089 ListConstructor expr = new ListConstructor(ListConstructor.Type.ORDERED_LIST_CONSTRUCTOR, exprList);
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07004090 return addSourceLocation(expr, startToken);
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07004091 }
Yingyi Bu391f09e2015-10-29 13:49:39 -07004092}
4093
4094ListConstructor UnorderedListConstructor() throws ParseException:
4095{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07004096 Token startToken = null;
4097 List<Expression> exprList = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07004098}
4099{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07004100 <LEFTDBLBRACE> { startToken = token; }
4101 exprList = ExpressionList()
4102 <RIGHTDBLBRACE>
4103 {
4104 ListConstructor expr = new ListConstructor(ListConstructor.Type.UNORDERED_LIST_CONSTRUCTOR, exprList);
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07004105 return addSourceLocation(expr, startToken);
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07004106 }
Yingyi Bu391f09e2015-10-29 13:49:39 -07004107}
4108
4109List<Expression> ExpressionList() throws ParseException:
4110{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07004111 Expression expr = null;
4112 List<Expression> exprList = new ArrayList<Expression>();
Yingyi Bu391f09e2015-10-29 13:49:39 -07004113}
4114{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07004115 (
4116 expr = Expression()
4117 {
4118 exprList.add(expr);
4119 }
4120 ( <COMMA> expr = Expression()
Till Westmann60f89982017-08-11 18:14:20 -07004121 {
4122 exprList.add(expr);
4123 }
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07004124 )*
4125 )?
4126 {
4127 return exprList;
4128 }
Yingyi Bu391f09e2015-10-29 13:49:39 -07004129}
4130
Yingyi Bu391f09e2015-10-29 13:49:39 -07004131RecordConstructor RecordConstructor() throws ParseException:
4132{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07004133 Token startToken = null;
4134 FieldBinding fb = null;
4135 List<FieldBinding> fbList = new ArrayList<FieldBinding>();
Yingyi Bu391f09e2015-10-29 13:49:39 -07004136}
4137{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07004138 <LEFTBRACE> { startToken = token; }
4139 (
4140 fb = FieldBinding() { fbList.add(fb); }
4141 (<COMMA> fb = FieldBinding() { fbList.add(fb); })*
4142 )?
4143 <RIGHTBRACE>
4144 {
4145 RecordConstructor expr = new RecordConstructor(fbList);
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07004146 return addSourceLocation(expr, startToken);
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07004147 }
Yingyi Bu391f09e2015-10-29 13:49:39 -07004148}
4149
4150FieldBinding FieldBinding() throws ParseException:
4151{
Dmitry Lychagincdcb9232019-06-04 13:27:03 -07004152 Expression left, right = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07004153}
4154{
Dmitry Lychagincdcb9232019-06-04 13:27:03 -07004155 left = Expression() ( <COLON> right = Expression() )?
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07004156 {
Dmitry Lychagincdcb9232019-06-04 13:27:03 -07004157 if (right == null) {
4158 String generatedIdentifier = ExpressionToVariableUtil.getGeneratedIdentifier(left, false);
4159 if (generatedIdentifier == null) {
4160 throw new SqlppParseException(getSourceLocation(token), "Cannot infer field name");
4161 }
4162 String generatedName = SqlppVariableUtil.toUserDefinedName(generatedIdentifier);
Ali Alsuliman5760e9e2019-08-22 16:37:36 -07004163 LiteralExpr generatedNameExpr = new LiteralExpr(new StringLiteral(generatedName));
4164 generatedNameExpr.setSourceLocation(left.getSourceLocation());
4165 return new FieldBinding(generatedNameExpr, left);
Dmitry Lychagincdcb9232019-06-04 13:27:03 -07004166 } else {
4167 return new FieldBinding(left, right);
4168 }
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07004169 }
Yingyi Bu391f09e2015-10-29 13:49:39 -07004170}
4171
Yingyi Bu391f09e2015-10-29 13:49:39 -07004172Expression FunctionCallExpr() throws ParseException:
4173{
Yingyi Bu391f09e2015-10-29 13:49:39 -07004174 List<Expression> argList = new ArrayList<Expression>();
Dmitry Lychagin9d469592020-06-01 15:42:51 -07004175 Expression argExpr = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07004176 FunctionName funcName = null;
Yingyi Buf4d09842016-08-26 00:03:52 -07004177 boolean star = false;
Dmitry Lychagin7a4b5682017-09-11 18:53:07 -07004178 boolean distinct = false;
Dmitry Lychagin9d469592020-06-01 15:42:51 -07004179 Expression filterExpr = null;
4180 WindowExpression windowExpr = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07004181}
4182{
4183 funcName = FunctionName()
Dmitry Lychagin7a4b5682017-09-11 18:53:07 -07004184 <LEFTPAREN> (
4185 ( <DISTINCT> { distinct = true; } )?
Dmitry Lychagin9d469592020-06-01 15:42:51 -07004186 ( argExpr = Expression() | <MUL> { star = true; } )
Yingyi Bu391f09e2015-10-29 13:49:39 -07004187 {
Dmitry Lychagin9d469592020-06-01 15:42:51 -07004188 if (star) {
4189 if (funcName.function.equalsIgnoreCase(BuiltinFunctions.SCALAR_COUNT.getName())) {
4190 argExpr = new LiteralExpr(new LongIntegerLiteral(1L));
4191 } else {
4192 throw new SqlppParseException(getSourceLocation(token),
4193 "The parameter * can only be used in " + BuiltinFunctions.SCALAR_COUNT.getName() + "().");
Yingyi Buf4d09842016-08-26 00:03:52 -07004194 }
Yingyi Buf4d09842016-08-26 00:03:52 -07004195 }
Dmitry Lychagin9d469592020-06-01 15:42:51 -07004196 argList.add(argExpr);
Yingyi Bu391f09e2015-10-29 13:49:39 -07004197 }
Dmitry Lychagin9d469592020-06-01 15:42:51 -07004198 (<COMMA> argExpr = Expression()
Yingyi Bu391f09e2015-10-29 13:49:39 -07004199 {
Dmitry Lychagin9d469592020-06-01 15:42:51 -07004200 argList.add(argExpr);
Yingyi Bu391f09e2015-10-29 13:49:39 -07004201 }
4202 )*)? <RIGHTPAREN>
Dmitry Lychagin9d469592020-06-01 15:42:51 -07004203
4204 {
4205 String name = funcName.function;
4206 if (distinct) {
4207 name += FunctionMapUtil.DISTINCT_AGGREGATE_SUFFIX;
4208 }
4209 String fqFunctionName = funcName.library == null ? name : funcName.library + "#" + name;
4210 int arity = argList.size();
4211 FunctionSignature signature = lookupFunctionSignature(funcName.dataverse, fqFunctionName, arity);
4212 if (signature == null) {
4213 signature = new FunctionSignature(funcName.dataverse, fqFunctionName, arity);
4214 }
4215 }
4216
4217 ( <FILTER> <LEFTPAREN> <WHERE> filterExpr = Expression() <RIGHTPAREN> )?
4218
4219 ( LOOKAHEAD(5) windowExpr = WindowExpr(signature, argList, filterExpr) )?
4220
4221 {
4222 if (windowExpr != null) {
4223 return windowExpr;
4224 } else {
4225 CallExpr callExpr = new CallExpr(signature, argList, filterExpr);
Caleb Herbel8d9c57a2020-08-14 20:41:13 -06004226 if (funcName.hintToken != null) {
Dmitry Lychagin6fd8ab32020-12-03 09:04:14 -08004227 IExpressionAnnotation annotation = parseExpressionAnnotation(funcName.hintToken);
4228 if (annotation != null) {
4229 callExpr.addHint(annotation);
Yingyi Bu391f09e2015-10-29 13:49:39 -07004230 }
4231 }
Dmitry Lychagin9d469592020-06-01 15:42:51 -07004232 FunctionMapUtil.normalizedListInputFunctions(callExpr);
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07004233 callExpr.setSourceLocation(funcName.sourceLoc);
Dmitry Lychagin9d469592020-06-01 15:42:51 -07004234 return callExpr;
Yingyi Bu391f09e2015-10-29 13:49:39 -07004235 }
Dmitry Lychaginfdedf622018-10-30 18:12:40 -07004236 }
Yingyi Bu391f09e2015-10-29 13:49:39 -07004237}
4238
Dmitry Lychagin9d469592020-06-01 15:42:51 -07004239WindowExpression WindowExpr(FunctionSignature signature, List<Expression> argList, Expression aggFilterExpr)
4240 throws ParseException:
Dmitry Lychagin5476f962019-05-31 16:03:11 -07004241{
Dmitry Lychagine5e3ad92021-07-15 12:44:47 -07004242 WindowExpression windowExpr = null;
Dmitry Lychagin5476f962019-05-31 16:03:11 -07004243 Boolean fromLast = null, ignoreNulls = null;
4244}
4245{
4246 (
4247 // FROM ( FIRST | LAST ) ( ( RESPECT | IGNORE ) NULLS )? OVER
4248 LOOKAHEAD(5, <FROM> <IDENTIFIER> ( <IDENTIFIER> <IDENTIFIER> )? <OVER>)
4249 <FROM> <IDENTIFIER>
4250 {
4251 if (isToken(FIRST)) {
4252 fromLast = false;
4253 } else if (isToken(LAST)) {
4254 fromLast = true;
4255 } else {
4256 throw createUnexpectedTokenError();
4257 }
4258 }
4259 )?
4260 (
4261 // ( RESPECT | IGNORE ) NULLS OVER
4262 LOOKAHEAD(3, <IDENTIFIER> <IDENTIFIER> <OVER>)
4263 <IDENTIFIER>
4264 {
4265 if (isToken(RESPECT)) {
4266 ignoreNulls = false;
4267 } else if (isToken(IGNORE)) {
4268 ignoreNulls = true;
4269 } else {
4270 throw createUnexpectedTokenError();
4271 }
4272 }
4273 <IDENTIFIER>
4274 {
4275 if (!isToken(NULLS)) {
4276 throw createUnexpectedTokenError();
4277 }
4278 }
4279 )?
Dmitry Lychagine5e3ad92021-07-15 12:44:47 -07004280 <OVER> windowExpr = OverClause(signature, argList, aggFilterExpr, token, fromLast, ignoreNulls)
Dmitry Lychagin5476f962019-05-31 16:03:11 -07004281 {
Dmitry Lychagine5e3ad92021-07-15 12:44:47 -07004282 return windowExpr;
Dmitry Lychagin5476f962019-05-31 16:03:11 -07004283 }
4284}
4285
Dmitry Lychagin9d469592020-06-01 15:42:51 -07004286WindowExpression OverClause(FunctionSignature signature, List<Expression> argList, Expression aggFilterExpr,
4287 Token startToken, Boolean fromLast, Boolean ignoreNulls) throws ParseException:
Dmitry Lychaginf2c18aa2018-12-28 21:20:23 -08004288{
4289 Expression partitionExpr = null;
4290 List<Expression> partitionExprs = new ArrayList<Expression>();
4291 OrderbyClause orderByClause = null;
4292 List<Expression> orderbyList = null;
4293 List<OrderbyClause.OrderModifier> orderbyModifierList = null;
Dmitry Lychagine5e3ad92021-07-15 12:44:47 -07004294 List<OrderbyClause.NullOrderModifier> orderbyNullModifierList = null;
Dmitry Lychaginf2c18aa2018-12-28 21:20:23 -08004295 WindowExpression.FrameMode frameMode = null;
4296 Pair<WindowExpression.FrameBoundaryKind, Expression> frameStart = null, frameEnd = null;
4297 WindowExpression.FrameBoundaryKind frameStartKind = null, frameEndKind = null;
4298 Expression frameStartExpr = null, frameEndExpr = null;
4299 WindowExpression.FrameExclusionKind frameExclusionKind = null;
4300 Pair<VariableExpr, List<Pair<Expression, Identifier>>> windowVarWithFieldList = null;
4301 VariableExpr windowVar = null;
4302 List<Pair<Expression, Identifier>> windowFieldList = null;
4303}
4304{
4305 (
4306 windowVarWithFieldList = VariableWithFieldMap() <AS>
4307 {
4308 windowVar = windowVarWithFieldList.first;
4309 windowFieldList = windowVarWithFieldList.second;
4310 }
4311 )?
4312 <LEFTPAREN>
4313 (
4314 <IDENTIFIER> { expectToken(PARTITION); } <BY>
4315 partitionExpr = Expression() { partitionExprs.add(partitionExpr); }
4316 ( <COMMA> partitionExpr = Expression() { partitionExprs.add(partitionExpr); } )*
4317 )?
4318 (
4319 orderByClause = OrderbyClause()
4320 {
4321 orderbyList = orderByClause.getOrderbyList();
4322 orderbyModifierList = orderByClause.getModifierList();
Dmitry Lychagine5e3ad92021-07-15 12:44:47 -07004323 orderbyNullModifierList = orderByClause.getNullModifierList();
Dmitry Lychaginf2c18aa2018-12-28 21:20:23 -08004324 }
4325 (
4326 frameMode = WindowFrameMode()
4327 (
4328 frameStart = WindowFrameBoundary() |
4329 ( <BETWEEN> frameStart = WindowFrameBoundary() <AND> frameEnd = WindowFrameBoundary() )
4330 )
4331 ( frameExclusionKind = WindowFrameExclusion() )?
4332 {
4333 frameStartKind = frameStart.first;
4334 frameStartExpr = frameStart.second;
4335 if (frameEnd == null) {
4336 frameEndKind = WindowExpression.FrameBoundaryKind.CURRENT_ROW;
4337 } else {
4338 frameEndKind = frameEnd.first;
4339 frameEndExpr = frameEnd.second;
4340 }
4341 if (frameExclusionKind == null) {
4342 frameExclusionKind = WindowExpression.FrameExclusionKind.NO_OTHERS;
4343 }
4344 }
4345 )?
4346 )?
4347 <RIGHTPAREN>
4348 {
Dmitry Lychagin9d469592020-06-01 15:42:51 -07004349 WindowExpression winExpr = new WindowExpression(signature, argList, aggFilterExpr, partitionExprs, orderbyList,
Dmitry Lychagine5e3ad92021-07-15 12:44:47 -07004350 orderbyModifierList, orderbyNullModifierList, frameMode, frameStartKind, frameStartExpr, frameEndKind,
4351 frameEndExpr, frameExclusionKind, windowVar, windowFieldList, ignoreNulls, fromLast);
Dmitry Lychagin9d469592020-06-01 15:42:51 -07004352 return addSourceLocation(winExpr, startToken);
Dmitry Lychaginf2c18aa2018-12-28 21:20:23 -08004353 }
4354}
4355
4356WindowExpression.FrameMode WindowFrameMode() throws ParseException:
4357{
4358}
4359{
4360 <IDENTIFIER>
4361 {
4362 if (isToken(RANGE)) {
4363 return WindowExpression.FrameMode.RANGE;
4364 } else if (isToken(ROWS)) {
4365 return WindowExpression.FrameMode.ROWS;
4366 } else if (isToken(GROUPS)) {
4367 return WindowExpression.FrameMode.GROUPS;
4368 } else {
4369 throw createUnexpectedTokenError();
4370 }
4371 }
4372}
4373
4374Pair<WindowExpression.FrameBoundaryKind, Expression> WindowFrameBoundary() throws ParseException:
4375{
4376 boolean current = false;
4377 Expression expr = null;
4378}
4379{
4380 (
Dmitry Lychagin5476f962019-05-31 16:03:11 -07004381 LOOKAHEAD({ laIdentifier(CURRENT) || laIdentifier(UNBOUNDED) }) <IDENTIFIER> { current = isToken(CURRENT); }
Dmitry Lychaginf2c18aa2018-12-28 21:20:23 -08004382 | expr = Expression()
4383 )
4384 <IDENTIFIER>
4385 {
4386 WindowExpression.FrameBoundaryKind kind;
4387 if (current && isToken(ROW)) {
4388 kind = WindowExpression.FrameBoundaryKind.CURRENT_ROW;
4389 } else if (!current && isToken(PRECEDING)) {
4390 kind = expr == null
4391 ? WindowExpression.FrameBoundaryKind.UNBOUNDED_PRECEDING
4392 : WindowExpression.FrameBoundaryKind.BOUNDED_PRECEDING;
4393 } else if (!current && isToken(FOLLOWING)) {
4394 kind = expr == null
4395 ? WindowExpression.FrameBoundaryKind.UNBOUNDED_FOLLOWING
4396 : WindowExpression.FrameBoundaryKind.BOUNDED_FOLLOWING;
4397 } else {
4398 throw createUnexpectedTokenError();
4399 }
4400 return new Pair<WindowExpression.FrameBoundaryKind, Expression>(kind, expr);
4401 }
4402}
4403
4404WindowExpression.FrameExclusionKind WindowFrameExclusion() throws ParseException:
4405{
4406 boolean current = false, no = false;
4407}
4408{
4409 <IDENTIFIER>
4410 {
4411 expectToken(EXCLUDE);
4412 }
4413 (
4414 <GROUP>
4415 {
4416 return WindowExpression.FrameExclusionKind.GROUP;
4417 }
4418 |
4419 (
4420 <IDENTIFIER>
4421 {
4422 if (isToken(TIES)) {
4423 return WindowExpression.FrameExclusionKind.TIES;
4424 } else if (isToken(CURRENT)) {
4425 current = true;
4426 } else if (isToken(NO)) {
4427 no = true;
4428 } else {
4429 throw createUnexpectedTokenError();
4430 }
4431 }
4432 <IDENTIFIER>
4433 {
4434 if (current && isToken(ROW)) {
4435 return WindowExpression.FrameExclusionKind.CURRENT_ROW;
4436 } else if (no && isToken(OTHERS)) {
4437 return WindowExpression.FrameExclusionKind.NO_OTHERS;
4438 } else {
4439 throw createUnexpectedTokenError();
4440 }
4441 }
4442 )
4443 )
4444}
4445
Yingyi Bu391f09e2015-10-29 13:49:39 -07004446Expression ParenthesizedExpression() throws ParseException:
4447{
Dmitry Lychagine9630592021-08-30 15:29:30 -07004448 Token startToken = null;
4449 Expression expr = null, expr2 = null;
4450 List<Expression> exprList = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07004451}
4452{
4453 (
4454 LOOKAHEAD(2)
Dmitry Lychagine9630592021-08-30 15:29:30 -07004455 <LEFTPAREN> { startToken = token; } expr = Expression()
4456 (
4457 <COMMA> expr2 = Expression()
4458 {
4459 if (exprList == null) {
4460 exprList = new ArrayList<Expression>();
4461 exprList.add(expr);
4462 }
4463 exprList.add(expr2);
4464 }
4465 )*
4466 <RIGHTPAREN>
Yingyi Bu391f09e2015-10-29 13:49:39 -07004467 |
4468 expr = Subquery()
4469 )
4470 {
Dmitry Lychagine9630592021-08-30 15:29:30 -07004471 if (exprList != null) {
4472 ListConstructor listExpr = new ListConstructor(ListConstructor.Type.ORDERED_LIST_CONSTRUCTOR, exprList);
4473 return addSourceLocation(listExpr, startToken);
4474 } else {
4475 return expr;
4476 }
Yingyi Bu391f09e2015-10-29 13:49:39 -07004477 }
4478}
4479
Yingyi Buc8c067c2016-07-25 23:37:19 -07004480Expression CaseExpr() throws ParseException:
Yingyi Bu391f09e2015-10-29 13:49:39 -07004481{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07004482 Token startToken = null;
4483 Expression conditionExpr = null;
Yingyi Buc8c067c2016-07-25 23:37:19 -07004484 List<Expression> whenExprs = new ArrayList<Expression>();
4485 List<Expression> thenExprs = new ArrayList<Expression>();
4486 Expression elseExpr = null;
Yingyi Buc8c067c2016-07-25 23:37:19 -07004487 Expression whenExpr = null;
4488 Expression thenExpr = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07004489}
4490{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07004491 <CASE> { startToken = token; }
4492 ( conditionExpr = Expression() )?
Yingyi Buc8c067c2016-07-25 23:37:19 -07004493 (
4494 <WHEN> whenExpr = Expression()
4495 {
4496 whenExprs.add(whenExpr);
4497 }
4498 <THEN> thenExpr = Expression()
4499 {
4500 thenExprs.add(thenExpr);
4501 }
4502 )*
4503 (<ELSE> elseExpr = Expression() )?
4504 <END>
4505 {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07004506 if (conditionExpr == null) {
4507 LiteralExpr litExpr = new LiteralExpr(TrueLiteral.INSTANCE);
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07004508 conditionExpr = addSourceLocation(litExpr, startToken);
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07004509 }
4510 CaseExpression caseExpr = new CaseExpression(conditionExpr, whenExprs, thenExprs, elseExpr);
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07004511 return addSourceLocation(caseExpr, startToken);
Yingyi Buc8c067c2016-07-25 23:37:19 -07004512 }
Yingyi Bu391f09e2015-10-29 13:49:39 -07004513}
4514
Yingyi Buab817482016-08-19 21:29:31 -07004515SelectExpression SelectExpression(boolean subquery) throws ParseException:
4516{
Yingyi Bu391f09e2015-10-29 13:49:39 -07004517 List<LetClause> letClauses = new ArrayList<LetClause>();
4518 SelectSetOperation selectSetOperation;
4519 OrderbyClause orderbyClause = null;
4520 LimitClause limitClause = null;
4521 createNewScope();
Yingyi Buab817482016-08-19 21:29:31 -07004522}
4523{
Yingyi Bu391f09e2015-10-29 13:49:39 -07004524 ( letClauses = LetClause() )?
4525 selectSetOperation = SelectSetOperation()
4526 (orderbyClause = OrderbyClause() {})?
4527 (limitClause = LimitClause() {})?
4528 {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07004529 SelectExpression selectExpr =
4530 new SelectExpression(letClauses, selectSetOperation, orderbyClause, limitClause, subquery);
4531 selectExpr.setSourceLocation((!letClauses.isEmpty() ? letClauses.get(0) : selectSetOperation).getSourceLocation());
4532 return selectExpr;
Yingyi Bu391f09e2015-10-29 13:49:39 -07004533 }
4534}
4535
Yingyi Buab817482016-08-19 21:29:31 -07004536SelectSetOperation SelectSetOperation() throws ParseException:
4537{
Yingyi Bu391f09e2015-10-29 13:49:39 -07004538 SetOperationInput setOperationInputLeft;
4539 List<SetOperationRight> setOperationRights = new ArrayList<SetOperationRight>();
4540}
4541{
4542 {
4543 SelectBlock selectBlockLeft = null;
4544 SelectExpression subqueryLeft = null;
4545 Expression expr = null;
4546 }
4547 selectBlockLeft = SelectBlock()
4548 {
4549 setOperationInputLeft = new SetOperationInput(selectBlockLeft, subqueryLeft);
4550 }
4551 (
4552 {
4553 SetOpType opType = SetOpType.UNION;
4554 boolean setSemantics = true;
4555 SelectBlock selectBlockRight = null;
4556 SelectExpression subqueryRight = null;
4557 }
4558 (<UNION> {opType = SetOpType.UNION;} |<INTERSECT> {opType = SetOpType.INTERSECT;} |<EXCEPT> {opType = SetOpType.EXCEPT;}) (<ALL> {setSemantics = false;} )?
4559 (selectBlockRight = SelectBlock()| subqueryRight = Subquery())
4560 {
4561 setOperationRights.add(new SetOperationRight(opType, setSemantics, new SetOperationInput(selectBlockRight, subqueryRight)));
4562 }
4563 )*
4564 {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07004565 SelectSetOperation selectSetOp = new SelectSetOperation(setOperationInputLeft, setOperationRights);
4566 selectSetOp.setSourceLocation(selectBlockLeft.getSourceLocation());
4567 return selectSetOp;
Yingyi Bu391f09e2015-10-29 13:49:39 -07004568 }
4569}
4570
Yingyi Buab817482016-08-19 21:29:31 -07004571SelectExpression Subquery() throws ParseException:
4572{
Yingyi Bu391f09e2015-10-29 13:49:39 -07004573 SelectExpression selectExpr = null;
4574}
4575{
4576 <LEFTPAREN> selectExpr = SelectExpression(true) {} <RIGHTPAREN>
4577 {
4578 return selectExpr;
4579 }
4580}
4581
Yingyi Buab817482016-08-19 21:29:31 -07004582SelectBlock SelectBlock() throws ParseException:
4583{
Yingyi Bu391f09e2015-10-29 13:49:39 -07004584 SelectClause selectClause = null;
4585 FromClause fromClause = null;
4586 List<LetClause> fromLetClauses = null;
4587 WhereClause whereClause = null;
Dmitry Lychagin276adf92019-01-15 13:16:40 -08004588 List<AbstractClause> fromLetWhereClauses = new ArrayList<AbstractClause>();
Yingyi Bu391f09e2015-10-29 13:49:39 -07004589 GroupbyClause groupbyClause = null;
4590 List<LetClause> gbyLetClauses = null;
4591 HavingClause havingClause = null;
Dmitry Lychagin276adf92019-01-15 13:16:40 -08004592 List<AbstractClause> gbyLetHavingClauses = new ArrayList<AbstractClause>();
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07004593 SourceLocation startSrcLoc = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07004594}
4595{
4596 (
Dmitry Lychagin214ff552021-07-22 18:55:41 -07004597 (
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07004598 selectClause = SelectClause() { startSrcLoc = selectClause.getSourceLocation(); }
Yingyi Bu391f09e2015-10-29 13:49:39 -07004599 (
Yingyi Bu391f09e2015-10-29 13:49:39 -07004600 (
Dmitry Lychagin368092d2019-06-06 14:39:38 -07004601 fromClause = FromClause()
4602 (
4603 fromLetClauses = LetClause()
4604 )?
Dmitry Lychagin214ff552021-07-22 18:55:41 -07004605 (whereClause = WhereClause())?
4606 (
4607 groupbyClause = GroupbyClause()
4608 (
4609 gbyLetClauses = LetClause()
4610 )?
4611 (havingClause = HavingClause())?
4612 )?
Dmitry Lychagin368092d2019-06-06 14:39:38 -07004613 )
4614 |
4615 (
4616 fromLetClauses = LetClause()
4617 {
4618 // LET without FROM -> create dummy FROM clause: FROM {{missing}} AS #0
4619 SourceLocation sourceLoc = getSourceLocation(token);
4620 LiteralExpr missingExpr = new LiteralExpr(MissingLiteral.INSTANCE);
4621 missingExpr.setSourceLocation(sourceLoc);
4622 List<Expression> list = new ArrayList<Expression>(1);
4623 list.add(missingExpr);
4624 ListConstructor listExpr = new ListConstructor(ListConstructor.Type.ORDERED_LIST_CONSTRUCTOR, list);
4625 listExpr.setSourceLocation(sourceLoc);
4626 List<FromTerm> fromTerms = new ArrayList<FromTerm>(1);
4627 VariableExpr fromVar = new VariableExpr(new VarIdentifier("#0"));
4628 fromVar.setSourceLocation(sourceLoc);
4629 fromTerms.add(new FromTerm(listExpr, fromVar, null, new ArrayList<AbstractBinaryCorrelateClause>()));
4630 fromClause = new FromClause(fromTerms);
4631 }
Dmitry Lychagin214ff552021-07-22 18:55:41 -07004632 (whereClause = WhereClause())?
Dmitry Lychagin368092d2019-06-06 14:39:38 -07004633 )
Yingyi Bu391f09e2015-10-29 13:49:39 -07004634 )?
Dmitry Lychagin214ff552021-07-22 18:55:41 -07004635 )
Yingyi Bu391f09e2015-10-29 13:49:39 -07004636 |
Dmitry Lychagin214ff552021-07-22 18:55:41 -07004637 (
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07004638 fromClause = FromClause() { startSrcLoc = fromClause.getSourceLocation(); }
Yingyi Bu391f09e2015-10-29 13:49:39 -07004639 (
Yingyi Bu391f09e2015-10-29 13:49:39 -07004640 fromLetClauses = LetClause()
4641 )?
4642 (whereClause = WhereClause())?
4643 (
4644 groupbyClause = GroupbyClause()
4645 (
4646 gbyLetClauses = LetClause()
4647 )?
4648 (havingClause = HavingClause())?
4649 )?
4650 selectClause = SelectClause()
Dmitry Lychagin214ff552021-07-22 18:55:41 -07004651 )
Yingyi Bu391f09e2015-10-29 13:49:39 -07004652 )
4653 {
Dmitry Lychagin276adf92019-01-15 13:16:40 -08004654 if (fromLetClauses != null) {
4655 fromLetWhereClauses.addAll(fromLetClauses);
4656 }
4657 if (whereClause != null) {
4658 fromLetWhereClauses.add(whereClause);
4659 }
4660 if (gbyLetClauses != null) {
4661 gbyLetHavingClauses.addAll(gbyLetClauses);
4662 }
4663 if (havingClause != null) {
4664 gbyLetHavingClauses.add(havingClause);
4665 }
4666 SelectBlock selectBlock = new SelectBlock(selectClause, fromClause, fromLetWhereClauses, groupbyClause,
4667 gbyLetHavingClauses);
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07004668 selectBlock.setSourceLocation(startSrcLoc);
4669 return selectBlock;
Yingyi Bu391f09e2015-10-29 13:49:39 -07004670 }
4671}
4672
Yingyi Buab817482016-08-19 21:29:31 -07004673SelectClause SelectClause() throws ParseException:
4674{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07004675 Token startToken = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07004676 SelectRegular selectRegular = null;
4677 SelectElement selectElement = null;
4678 boolean distinct = false;
4679}
4680{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07004681 <SELECT> { startToken = token; } (<ALL>|<DISTINCT> { distinct = true; } )?
Yingyi Bu391f09e2015-10-29 13:49:39 -07004682 (
4683 selectRegular = SelectRegular()
Michael Blowd6cf6412016-06-30 02:44:35 -04004684 |
Yingyi Bu391f09e2015-10-29 13:49:39 -07004685 selectElement = SelectElement()
Yingyi Bua89fae62016-07-06 07:58:55 -07004686 )?
Yingyi Bu391f09e2015-10-29 13:49:39 -07004687 {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07004688 SourceLocation sourceLoc = getSourceLocation(startToken);
4689 if (selectRegular == null && selectElement == null){
Dmitry Lychaginb4121e42021-09-23 15:55:09 -07004690 Projection projection = new Projection(Projection.Kind.STAR, null, null);
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07004691 projection.setSourceLocation(sourceLoc);
Yingyi Bua89fae62016-07-06 07:58:55 -07004692 List<Projection> projections = new ArrayList<Projection>();
4693 projections.add(projection);
4694 selectRegular = new SelectRegular(projections);
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07004695 selectRegular.setSourceLocation(sourceLoc);
Yingyi Bua89fae62016-07-06 07:58:55 -07004696 }
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07004697 SelectClause selectClause = new SelectClause(selectElement, selectRegular, distinct);
4698 selectClause.setSourceLocation(sourceLoc);
4699 return selectClause;
Yingyi Bu391f09e2015-10-29 13:49:39 -07004700 }
4701}
4702
Yingyi Buab817482016-08-19 21:29:31 -07004703SelectRegular SelectRegular() throws ParseException:
4704{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07004705 SourceLocation startSrcLoc = null;
Michael Blowd6cf6412016-06-30 02:44:35 -04004706 List<Projection> projections = new ArrayList<Projection>();
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07004707 Projection projection = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07004708}
4709{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07004710 projection = Projection()
Yingyi Bu391f09e2015-10-29 13:49:39 -07004711 {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07004712 projections.add(projection);
4713 startSrcLoc = projection.getSourceLocation();
4714 }
4715 ( LOOKAHEAD(2) <COMMA> projection = Projection()
4716 {
4717 projections.add(projection);
4718 }
4719 )*
4720 {
4721 SelectRegular selectRegular = new SelectRegular(projections);
4722 selectRegular.setSourceLocation(startSrcLoc);
4723 return selectRegular;
Yingyi Bu391f09e2015-10-29 13:49:39 -07004724 }
4725}
4726
Yingyi Buab817482016-08-19 21:29:31 -07004727SelectElement SelectElement() throws ParseException:
4728{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07004729 Token startToken = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07004730 Expression expr = null;
4731 String name = null;
4732}
4733{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07004734 (<RAW>|<ELEMENT>|<VALUE>) { startToken = token; } expr = Expression()
Yingyi Bu391f09e2015-10-29 13:49:39 -07004735 {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07004736 SelectElement selectElement = new SelectElement(expr);
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07004737 return addSourceLocation(selectElement, startToken);
Yingyi Bu391f09e2015-10-29 13:49:39 -07004738 }
4739}
4740
Yingyi Buab817482016-08-19 21:29:31 -07004741Projection Projection() throws ParseException :
4742{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07004743 SourceLocation startSrcLoc = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07004744 Expression expr = null;
4745 Identifier identifier = null;
4746 String name = null;
Dmitry Lychaginb4121e42021-09-23 15:55:09 -07004747 Projection.Kind kind = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07004748 boolean star = false;
Dmitry Lychagin5cdaa5d2018-02-21 11:11:26 -08004749 boolean varStar = false;
Yingyi Bu391f09e2015-10-29 13:49:39 -07004750}
4751{
4752 (
Dmitry Lychaginb4121e42021-09-23 15:55:09 -07004753 <MUL> { kind = Projection.Kind.STAR; startSrcLoc = getSourceLocation(token); }
4754 | LOOKAHEAD(3) expr = VariableRef() <DOT> <MUL> { kind = Projection.Kind.VAR_STAR; }
Dmitry Lychagin5cdaa5d2018-02-21 11:11:26 -08004755 | expr = Expression() ((<AS>)? name = Identifier())?
4756 {
Dmitry Lychaginb4121e42021-09-23 15:55:09 -07004757 kind = Projection.Kind.NAMED_EXPR;
Dmitry Lychagin5cdaa5d2018-02-21 11:11:26 -08004758 if (name == null) {
4759 String generatedColumnIdentifier = ExpressionToVariableUtil.getGeneratedIdentifier(expr, false);
4760 if (generatedColumnIdentifier != null) {
4761 name = SqlppVariableUtil.toUserDefinedName(generatedColumnIdentifier);
4762 }
4763 }
4764 }
Yingyi Bu391f09e2015-10-29 13:49:39 -07004765 )
4766 {
Dmitry Lychaginb4121e42021-09-23 15:55:09 -07004767 Projection projection = new Projection(kind, expr, name);
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07004768 projection.setSourceLocation(expr != null ? expr.getSourceLocation() : startSrcLoc);
4769 return projection;
Yingyi Bu391f09e2015-10-29 13:49:39 -07004770 }
4771}
4772
4773FromClause FromClause() throws ParseException :
4774{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07004775 Token startToken = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07004776 List<FromTerm> fromTerms = new ArrayList<FromTerm>();
4777 extendCurrentScope();
4778}
4779{
4780 {
4781 FromTerm fromTerm = null;
4782 }
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07004783 <FROM> { startToken = token; } fromTerm = FromTerm() { fromTerms.add(fromTerm); }
Yingyi Bu391f09e2015-10-29 13:49:39 -07004784 (LOOKAHEAD(2) <COMMA> fromTerm = FromTerm() { fromTerms.add(fromTerm); } )*
4785 {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07004786 FromClause fromClause = new FromClause(fromTerms);
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07004787 return addSourceLocation(fromClause, startToken);
Yingyi Bu391f09e2015-10-29 13:49:39 -07004788 }
4789}
4790
4791FromTerm FromTerm() throws ParseException :
4792{
4793 Expression leftExpr = null;
Michael Blowd6cf6412016-06-30 02:44:35 -04004794 VariableExpr leftVar = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07004795 VariableExpr posVar = null;
Dmitry Lychagind4ce84c2020-10-13 16:24:37 -07004796 AbstractBinaryCorrelateClause correlateClause = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07004797 List<AbstractBinaryCorrelateClause> correlateClauses = new ArrayList<AbstractBinaryCorrelateClause>();
4798}
4799{
Yingyi Bu9e3f9be2016-07-01 10:07:37 -07004800 leftExpr = Expression() ((<AS>)? leftVar = Variable())? (<AT> posVar = Variable())?
Yingyi Bu391f09e2015-10-29 13:49:39 -07004801 (
Dmitry Lychagind4ce84c2020-10-13 16:24:37 -07004802 (
4803 correlateClause = JoinOrUnnestClause(JoinType.INNER, UnnestType.INNER)
4804 | ( <INNER> correlateClause = JoinOrUnnestClause(JoinType.INNER, UnnestType.INNER) )
4805 | ( <LEFT> ( <OUTER> )? correlateClause = JoinOrUnnestClause(JoinType.LEFTOUTER, UnnestType.LEFTOUTER) )
4806 | ( <RIGHT> ( <OUTER> )? correlateClause = JoinClause(JoinType.RIGHTOUTER) )
Dmitry Lychagind3eccd42021-08-19 12:18:17 -07004807 | ( <CROSS> correlateClause = CrossJoinClause() )
Yingyi Bu391f09e2015-10-29 13:49:39 -07004808 )
4809 {
4810 correlateClauses.add(correlateClause);
4811 }
4812 )*
4813 {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07004814 if (leftVar == null) {
Yingyi Bu5b2d4c82016-07-13 17:56:48 -07004815 leftVar = ExpressionToVariableUtil.getGeneratedVariable(leftExpr, true);
Yingyi Bu9e3f9be2016-07-01 10:07:37 -07004816 }
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07004817 FromTerm fromTerm = new FromTerm(leftExpr, leftVar, posVar, correlateClauses);
4818 fromTerm.setSourceLocation(leftExpr.getSourceLocation());
4819 return fromTerm;
Yingyi Bu391f09e2015-10-29 13:49:39 -07004820 }
4821}
4822
Dmitry Lychagind4ce84c2020-10-13 16:24:37 -07004823AbstractBinaryCorrelateClause JoinOrUnnestClause(JoinType joinType, UnnestType unnestType) throws ParseException :
4824{
4825 AbstractBinaryCorrelateClause correlateClause = null;
4826}
4827{
4828 ( correlateClause = JoinClause(joinType) | correlateClause = UnnestClause(unnestType) )
4829 {
4830 return correlateClause;
4831 }
4832}
4833
Yingyi Bu391f09e2015-10-29 13:49:39 -07004834JoinClause JoinClause(JoinType joinType) throws ParseException :
4835{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07004836 Token startToken = null;
Dmitry Lychagind3eccd42021-08-19 12:18:17 -07004837 Triple<Expression, VariableExpr, VariableExpr> rightInput = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07004838 Expression conditionExpr = null;
4839}
4840{
Dmitry Lychagind3eccd42021-08-19 12:18:17 -07004841 <JOIN> { startToken = token; } rightInput = JoinClauseRightInput() <ON> conditionExpr = Expression()
4842 {
4843 JoinClause joinClause = new JoinClause(joinType, rightInput.first, rightInput.second, rightInput.third,
Dmitry Lychagin34b72ac2021-11-29 16:25:40 -08004844 conditionExpr, joinType == JoinType.INNER ? null : Literal.Type.MISSING);
Dmitry Lychagind3eccd42021-08-19 12:18:17 -07004845 return addSourceLocation(joinClause, startToken);
4846 }
4847}
4848
4849JoinClause CrossJoinClause() throws ParseException :
4850{
4851 Token startToken = null;
4852 Triple<Expression, VariableExpr, VariableExpr> rightInput = null;
4853 Expression conditionExpr = null;
4854}
4855{
4856 <JOIN> { startToken = token; } rightInput = JoinClauseRightInput()
4857 {
4858 JoinClause joinClause = new JoinClause(JoinType.INNER, rightInput.first, rightInput.second, rightInput.third,
Dmitry Lychagin34b72ac2021-11-29 16:25:40 -08004859 new LiteralExpr(TrueLiteral.INSTANCE), null);
Dmitry Lychagind3eccd42021-08-19 12:18:17 -07004860 return addSourceLocation(joinClause, startToken);
4861 }
4862}
4863
4864Triple<Expression, VariableExpr, VariableExpr> JoinClauseRightInput() throws ParseException :
4865{
4866 Expression rightExpr = null;
4867 VariableExpr rightVar = null;
4868 VariableExpr posVar = null;
4869}
4870{
4871 rightExpr = Expression() ((<AS>)? rightVar = Variable())? (<AT> posVar = Variable())?
Yingyi Bu391f09e2015-10-29 13:49:39 -07004872 {
Dmitry Lychagind4ce84c2020-10-13 16:24:37 -07004873 if (rightVar == null) {
4874 rightVar = ExpressionToVariableUtil.getGeneratedVariable(rightExpr, true);
Yingyi Bu9e3f9be2016-07-01 10:07:37 -07004875 }
Dmitry Lychagind3eccd42021-08-19 12:18:17 -07004876 return new Triple<Expression, VariableExpr, VariableExpr>(rightExpr, rightVar, posVar);
Yingyi Bu391f09e2015-10-29 13:49:39 -07004877 }
4878}
4879
Dmitry Lychagind4ce84c2020-10-13 16:24:37 -07004880UnnestClause UnnestClause(UnnestType unnestType) throws ParseException :
Yingyi Bu391f09e2015-10-29 13:49:39 -07004881{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07004882 Token startToken = null;
Dmitry Lychagin4cf91e42021-03-12 12:53:15 -08004883 Expression rightExpr = null;
4884 VariableExpr rightVar = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07004885 VariableExpr posVar = null;
4886}
4887{
Dmitry Lychagin4cf91e42021-03-12 12:53:15 -08004888 (<UNNEST>|<CORRELATE>|<FLATTEN>) { startToken = token; } rightExpr = Expression() ((<AS>)? rightVar = Variable())? (<AT> posVar = Variable())?
Yingyi Bu391f09e2015-10-29 13:49:39 -07004889 {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07004890 if (rightVar == null) {
4891 rightVar = ExpressionToVariableUtil.getGeneratedVariable(rightExpr, true);
Yingyi Bu9e3f9be2016-07-01 10:07:37 -07004892 }
Dmitry Lychagin34b72ac2021-11-29 16:25:40 -08004893 UnnestClause unnestClause = new UnnestClause(unnestType, rightExpr, rightVar, posVar,
4894 unnestType == UnnestType.INNER ? null : Literal.Type.MISSING);
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07004895 return addSourceLocation(unnestClause, startToken);
Yingyi Bu391f09e2015-10-29 13:49:39 -07004896 }
4897}
4898
Yingyi Bu391f09e2015-10-29 13:49:39 -07004899List<LetClause> LetClause() throws ParseException:
4900{
4901 List<LetClause> letList = new ArrayList<LetClause>();
4902 LetClause letClause;
4903}
4904{
4905 (
4906 (<LET>|<LETTING>) letClause = LetElement() { letList.add(letClause); } (LOOKAHEAD(1) <COMMA> letClause = LetElement() { letList.add(letClause); })*
4907 |
4908 <WITH> letClause = WithElement() { letList.add(letClause); } (LOOKAHEAD(1) <COMMA> letClause = WithElement() { letList.add(letClause); })*
4909 )
4910 {
4911 return letList;
4912 }
4913}
4914
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07004915WhereClause WhereClause() throws ParseException :
Yingyi Bu391f09e2015-10-29 13:49:39 -07004916{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07004917 Token startToken = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07004918 Expression whereExpr;
4919}
4920{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07004921 <WHERE> { startToken = token; } whereExpr = Expression()
Yingyi Bu391f09e2015-10-29 13:49:39 -07004922 {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07004923 WhereClause wc = new WhereClause(whereExpr);
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07004924 return addSourceLocation(wc, startToken);
Yingyi Bu391f09e2015-10-29 13:49:39 -07004925 }
4926}
4927
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07004928OrderbyClause OrderbyClause() throws ParseException :
Yingyi Bu391f09e2015-10-29 13:49:39 -07004929{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07004930 Token startToken = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07004931 OrderbyClause oc = new OrderbyClause();
Dmitry Lychagine5e3ad92021-07-15 12:44:47 -07004932 Triple<Expression, OrderbyClause.OrderModifier, OrderbyClause.NullOrderModifier> orderbyExpr = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07004933 List<Expression> orderbyList = new ArrayList<Expression>();
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07004934 List<OrderbyClause.OrderModifier> modifierList = new ArrayList<OrderbyClause.OrderModifier>();
Dmitry Lychagine5e3ad92021-07-15 12:44:47 -07004935 List<OrderbyClause.NullOrderModifier> nullModifierList = new ArrayList<OrderbyClause.NullOrderModifier>();
Yingyi Bu391f09e2015-10-29 13:49:39 -07004936}
4937{
Dmitry Lychagine5e3ad92021-07-15 12:44:47 -07004938 <ORDER>
4939 {
4940 startToken = token;
4941 Token hintToken = fetchHint(token, SqlppHint.INMEMORY_HINT, SqlppHint.RANGE_HINT);
4942 if (hintToken != null) {
4943 switch (hintToken.hint) {
4944 case INMEMORY_HINT:
4945 String[] splits = hintToken.hintParams.split("\\s+");
4946 int numFrames = Integer.parseInt(splits[0]);
4947 int numTuples = Integer.parseInt(splits[1]);
4948 oc.setNumFrames(numFrames);
4949 oc.setNumTuples(numTuples);
4950 break;
4951 case RANGE_HINT:
4952 try {
4953 Expression rangeExpr = parseExpression(hintToken.hintParams);
4954 RangeMap rangeMap = RangeMapBuilder.parseHint(rangeExpr);
4955 oc.setRangeMap(rangeMap);
4956 } catch (CompilationException e) {
4957 throw new SqlppParseException(getSourceLocation(hintToken), e.getMessage());
Ali Alsuliman80225e22018-10-15 14:17:07 -07004958 }
Dmitry Lychagine5e3ad92021-07-15 12:44:47 -07004959 break;
Yingyi Bu391f09e2015-10-29 13:49:39 -07004960 }
Yingyi Bu391f09e2015-10-29 13:49:39 -07004961 }
Dmitry Lychagine5e3ad92021-07-15 12:44:47 -07004962 }
4963 <BY> orderbyExpr = OrderByExpression()
4964 {
4965 orderbyList.add(orderbyExpr.first);
4966 modifierList.add(orderbyExpr.second);
4967 nullModifierList.add(orderbyExpr.third);
4968 }
4969 (
4970 LOOKAHEAD(2) <COMMA> orderbyExpr = OrderByExpression()
Yingyi Bu391f09e2015-10-29 13:49:39 -07004971 {
Dmitry Lychagine5e3ad92021-07-15 12:44:47 -07004972 orderbyList.add(orderbyExpr.first);
4973 modifierList.add(orderbyExpr.second);
4974 nullModifierList.add(orderbyExpr.third);
Yingyi Bu391f09e2015-10-29 13:49:39 -07004975 }
Dmitry Lychagine5e3ad92021-07-15 12:44:47 -07004976 )*
4977 {
4978 oc.setOrderbyList(orderbyList);
4979 oc.setModifierList(modifierList);
4980 oc.setNullModifierList(nullModifierList);
4981 return addSourceLocation(oc, startToken);
4982 }
4983}
Yingyi Bu391f09e2015-10-29 13:49:39 -07004984
Dmitry Lychagine5e3ad92021-07-15 12:44:47 -07004985Triple<Expression, OrderbyClause.OrderModifier, OrderbyClause.NullOrderModifier> OrderByExpression()
4986 throws ParseException:
4987{
4988 Expression orderbyExpr = null;
4989 OrderbyClause.OrderModifier modif = OrderbyClause.OrderModifier.ASC;
4990 OrderbyClause.NullOrderModifier nullModif = null;
4991}
4992{
4993 orderbyExpr = Expression()
4994 (
4995 <ASC> { modif = OrderbyClause.OrderModifier.ASC; }
4996 |
4997 <DESC> { modif = OrderbyClause.OrderModifier.DESC; }
4998 )?
4999 (
5000 LOOKAHEAD({ laIdentifier(NULLS) }) <IDENTIFIER> { expectToken(NULLS); } <IDENTIFIER>
Yingyi Bu391f09e2015-10-29 13:49:39 -07005001 {
Dmitry Lychagine5e3ad92021-07-15 12:44:47 -07005002 if (isToken(FIRST)) {
5003 nullModif = OrderbyClause.NullOrderModifier.FIRST;
5004 } else if (isToken(LAST)) {
5005 nullModif = OrderbyClause.NullOrderModifier.LAST;
5006 } else {
5007 throw createUnexpectedTokenError();
5008 }
Yingyi Bu391f09e2015-10-29 13:49:39 -07005009 }
Dmitry Lychagine5e3ad92021-07-15 12:44:47 -07005010 )?
5011 {
5012 return new Triple<Expression, OrderbyClause.OrderModifier, OrderbyClause.NullOrderModifier>(orderbyExpr, modif,
5013 nullModif);
5014 }
Yingyi Bu391f09e2015-10-29 13:49:39 -07005015}
5016
5017GroupbyClause GroupbyClause()throws ParseException :
5018{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07005019 Token startToken = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07005020 GroupbyClause gbc = new GroupbyClause();
Dmitry Lychaginac98f482020-03-31 12:26:40 -07005021 List<List<GbyVariableExpressionPair>> gbyList = null;
5022 List<GroupingElement> groupingElementList = null;
Dmitry Lychaginf2c18aa2018-12-28 21:20:23 -08005023 Pair<VariableExpr, List<Pair<Expression, Identifier>>> groupVarWithFieldList = null;
Yingyi Buacc12a92016-03-26 17:25:05 -07005024 VariableExpr groupVar = null;
Dmitry Lychaginf2c18aa2018-12-28 21:20:23 -08005025 List<Pair<Expression, Identifier>> groupFieldList = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07005026}
5027{
Dmitry Lychaginac98f482020-03-31 12:26:40 -07005028 {
5029 Scope newScope = extendCurrentScopeNoPush(true);
5030 // extendCurrentScope(true);
5031 }
Yingyi Bu391f09e2015-10-29 13:49:39 -07005032 <GROUP>
Dmitry Lychaginac98f482020-03-31 12:26:40 -07005033 {
5034 startToken = token;
5035 Token hintToken = fetchHint(token, SqlppHint.HASH_GROUP_BY_HINT);
5036 if (hintToken != null) {
5037 gbc.setHashGroupByHint(true);
Yingyi Bu391f09e2015-10-29 13:49:39 -07005038 }
Dmitry Lychaginac98f482020-03-31 12:26:40 -07005039 }
5040 <BY> groupingElementList = GroupingElementList()
5041 (
5042 <GROUP> <AS> groupVarWithFieldList = VariableWithFieldMap()
Dmitry Lychaginf2c18aa2018-12-28 21:20:23 -08005043 {
5044 groupVar = groupVarWithFieldList.first;
5045 groupFieldList = groupVarWithFieldList.second;
5046 }
Yingyi Buacc12a92016-03-26 17:25:05 -07005047 )?
Yingyi Bu391f09e2015-10-29 13:49:39 -07005048 {
Dmitry Lychaginac98f482020-03-31 12:26:40 -07005049 if (groupingSetsParser == null) {
5050 groupingSetsParser = new SqlppGroupingSetsParser();
5051 }
5052 SourceLocation sourceLoc = getSourceLocation(startToken);
5053 try {
5054 gbyList = groupingSetsParser.parse(groupingElementList, sourceLoc);
5055 } catch (CompilationException e) {
5056 throw new SqlppParseException(sourceLoc, e.getMessage());
5057 }
5058 gbc.setGbyPairList(gbyList);
Yingyi Bu391f09e2015-10-29 13:49:39 -07005059 gbc.setDecorPairList(new ArrayList<GbyVariableExpressionPair>());
Yingyi Bu8671ddf2016-08-14 23:58:43 -07005060 gbc.setWithVarMap(new HashMap<Expression, VariableExpr>());
Yingyi Buacc12a92016-03-26 17:25:05 -07005061 gbc.setGroupVar(groupVar);
5062 gbc.setGroupFieldList(groupFieldList);
Yingyi Bu391f09e2015-10-29 13:49:39 -07005063 replaceCurrentScope(newScope);
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07005064 return addSourceLocation(gbc, startToken);
Yingyi Bu391f09e2015-10-29 13:49:39 -07005065 }
5066}
5067
Dmitry Lychaginac98f482020-03-31 12:26:40 -07005068List<GroupingElement> GroupingElementList() throws ParseException:
5069{
5070 List<GroupingElement> groupingElementList = new ArrayList<GroupingElement>();
5071 GroupingElement groupingElement = null;
5072}
5073{
5074 groupingElement = GroupingElement() { groupingElementList.add(groupingElement); }
5075 ( LOOKAHEAD(1) <COMMA> groupingElement = GroupingElement() { groupingElementList.add(groupingElement); } )*
5076 {
5077 return groupingElementList;
5078 }
5079}
5080
5081GroupingElement GroupingElement() throws ParseException:
5082{
5083 GroupingElement groupingElement = null;
5084 List<GroupingSet> groupingSets = null;
5085 List<GroupingElement> groupingElements = null;
5086}
5087{
5088 (
5089 LOOKAHEAD(2)
5090 <LEFTPAREN> <RIGHTPAREN>
5091 {
5092 groupingElement = GroupingSet.EMPTY;
5093 }
5094 |
5095 LOOKAHEAD({ laIdentifier(ROLLUP) && laToken(2, LEFTPAREN) })
5096 <IDENTIFIER> { expectToken(ROLLUP); }
5097 <LEFTPAREN> groupingSets = OrdinaryGroupingSetList() <RIGHTPAREN>
5098 {
5099 groupingElement = new RollupCube(groupingSets, false);
5100 }
5101 |
5102 LOOKAHEAD({ laIdentifier(CUBE) && laToken(2, LEFTPAREN) })
5103 <IDENTIFIER> { expectToken(CUBE); }
5104 <LEFTPAREN> groupingSets = OrdinaryGroupingSetList() <RIGHTPAREN>
5105 {
5106 groupingElement = new RollupCube(groupingSets, true);
5107 }
5108 |
5109 LOOKAHEAD({ laIdentifier(GROUPING) && laIdentifier(2, SETS) && laToken(3, LEFTPAREN) })
5110 <IDENTIFIER> { expectToken(GROUPING); } <IDENTIFIER> { expectToken(SETS); }
5111 <LEFTPAREN> groupingElements = GroupingElementList() <RIGHTPAREN>
5112 {
5113 groupingElement = new GroupingSets(groupingElements);
5114 }
5115 |
5116 groupingElement = OrdinaryGroupingSet()
5117 )
5118 {
5119 return groupingElement;
5120 }
5121}
5122
5123GroupingSet OrdinaryGroupingSet() throws ParseException:
5124{
5125 GbyVariableExpressionPair gbyExprPair = null;
5126 List<GbyVariableExpressionPair> items = null;
5127}
5128{
5129 (
5130 LOOKAHEAD(1) <LEFTPAREN> items = GbyVariableExpressionPairList() <RIGHTPAREN>
5131 | gbyExprPair = GbyVariableExpressionPair() { items = Collections.singletonList(gbyExprPair); }
5132 )
5133 {
5134 return new GroupingSet(items);
5135 }
5136}
5137
5138List<GroupingSet> OrdinaryGroupingSetList() throws ParseException:
5139{
5140 GroupingSet groupingSet = null;
5141 List<GroupingSet> items = new ArrayList<GroupingSet>();
5142}
5143{
5144 groupingSet = OrdinaryGroupingSet() { items.add(groupingSet); }
5145 ( LOOKAHEAD(1) <COMMA> groupingSet = OrdinaryGroupingSet() { items.add(groupingSet); } )*
5146 {
5147 return items;
5148 }
5149}
5150
5151List<GbyVariableExpressionPair> GbyVariableExpressionPairList() throws ParseException:
5152{
5153 GbyVariableExpressionPair gbyExprPair = null;
5154 List<GbyVariableExpressionPair> items = new ArrayList<GbyVariableExpressionPair>();
5155}
5156{
5157 gbyExprPair = GbyVariableExpressionPair() { items.add(gbyExprPair); }
5158 ( LOOKAHEAD(1) <COMMA> gbyExprPair = GbyVariableExpressionPair() { items.add(gbyExprPair); } )*
5159 {
5160 return items;
5161 }
5162}
5163
5164GbyVariableExpressionPair GbyVariableExpressionPair() throws ParseException:
5165{
5166 Expression expr = null;
5167 VariableExpr var = null;
5168}
5169{
5170 expr = Expression() ( (<AS>)? var = Variable() )?
5171 {
5172 return new GbyVariableExpressionPair(var, expr);
5173 }
5174}
5175
Yingyi Bu391f09e2015-10-29 13:49:39 -07005176HavingClause HavingClause() throws ParseException:
5177{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07005178 Token startToken = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07005179 Expression filterExpr = null;
5180}
5181{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07005182 <HAVING> { startToken = token; } filterExpr = Expression()
Yingyi Bu391f09e2015-10-29 13:49:39 -07005183 {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07005184 HavingClause havingClause = new HavingClause(filterExpr);
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07005185 return addSourceLocation(havingClause, startToken);
Yingyi Bu391f09e2015-10-29 13:49:39 -07005186 }
5187}
5188
5189LimitClause LimitClause() throws ParseException:
5190{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07005191 Token startToken = null;
Dmitry Lychagin761c9a62020-11-19 10:22:11 -08005192 Expression limitExpr = null, offsetExpr = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07005193}
5194{
Dmitry Lychagin761c9a62020-11-19 10:22:11 -08005195 (
5196 (
5197 <LIMIT> { startToken = token; pushForbiddenScope(getCurrentScope()); } limitExpr = Expression()
5198 ( <OFFSET> offsetExpr = Expression() )?
5199 { popForbiddenScope(); }
5200 )
5201 |
5202 (
5203 <OFFSET> { startToken = token; pushForbiddenScope(getCurrentScope()); } offsetExpr = Expression()
5204 { popForbiddenScope(); }
5205 )
5206 )
Yingyi Bu391f09e2015-10-29 13:49:39 -07005207 {
Dmitry Lychagin761c9a62020-11-19 10:22:11 -08005208 LimitClause lc = new LimitClause(limitExpr, offsetExpr);
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07005209 return addSourceLocation(lc, startToken);
Yingyi Bu391f09e2015-10-29 13:49:39 -07005210 }
5211}
5212
5213QuantifiedExpression QuantifiedExpression()throws ParseException:
5214{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07005215 Token startToken = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07005216 QuantifiedExpression qc = new QuantifiedExpression();
5217 List<QuantifiedPair> quantifiedList = new ArrayList<QuantifiedPair>();
5218 Expression satisfiesExpr;
5219 VariableExpr var;
5220 Expression inExpr;
5221 QuantifiedPair pair;
5222}
5223{
5224 {
5225 createNewScope();
5226 }
5227
ggalvizo21e52822021-07-27 10:26:31 -10005228 ( LOOKAHEAD(2)
5229 (<ANY>|<SOME>)<AND><EVERY> { startToken = token; qc.setQuantifier(QuantifiedExpression.Quantifier.SOME_AND_EVERY); }
5230 | (<ANY>|<SOME>) { startToken = token; qc.setQuantifier(QuantifiedExpression.Quantifier.SOME); }
5231 | <EVERY> { startToken = token; qc.setQuantifier(QuantifiedExpression.Quantifier.EVERY); } )
Yingyi Bu391f09e2015-10-29 13:49:39 -07005232 var = Variable() <IN> inExpr = Expression()
5233 {
5234 pair = new QuantifiedPair(var, inExpr);
Yingyi Bu391f09e2015-10-29 13:49:39 -07005235 quantifiedList.add(pair);
5236 }
5237 (
5238 <COMMA> var = Variable() <IN> inExpr = Expression()
5239 {
5240 pair = new QuantifiedPair(var, inExpr);
Yingyi Bu391f09e2015-10-29 13:49:39 -07005241 quantifiedList.add(pair);
5242 }
5243 )*
Yingyi Bu858efae2016-10-13 17:31:57 -07005244 <SATISFIES> satisfiesExpr = Expression() (<END>)?
Yingyi Bu391f09e2015-10-29 13:49:39 -07005245 {
5246 qc.setSatisfiesExpr(satisfiesExpr);
5247 qc.setQuantifiedList(quantifiedList);
5248 removeCurrentScope();
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07005249 return addSourceLocation(qc, startToken);
Yingyi Bu391f09e2015-10-29 13:49:39 -07005250 }
5251}
5252
5253LetClause LetElement() throws ParseException:
5254{
Yingyi Bu391f09e2015-10-29 13:49:39 -07005255 VariableExpr varExp;
5256 Expression beExp;
5257 extendCurrentScope();
5258}
5259{
5260 varExp = Variable() <EQ> beExp = Expression()
5261 {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07005262 LetClause lc = new LetClause(varExp, beExp);
5263 lc.setSourceLocation(varExp.getSourceLocation());
Yingyi Bu391f09e2015-10-29 13:49:39 -07005264 return lc;
5265 }
5266}
5267
5268LetClause WithElement() throws ParseException:
5269{
Yingyi Bu391f09e2015-10-29 13:49:39 -07005270 VariableExpr varExp;
5271 Expression beExp;
5272 extendCurrentScope();
5273}
5274{
5275 varExp = Variable() <AS> beExp = Expression()
5276 {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07005277 LetClause lc = new LetClause(varExp, beExp);
5278 lc.setSourceLocation(varExp.getSourceLocation());
Yingyi Bu391f09e2015-10-29 13:49:39 -07005279 return lc;
5280 }
5281}
5282
5283TOKEN_MGR_DECLS:
5284{
5285 public int commentDepth = 0;
Till Westmanne9b2adf2016-10-15 12:39:01 -07005286 public ArrayDeque<Integer> lexerStateStack = new ArrayDeque<Integer>();
Dmitry Lychagine77cdac2019-08-05 11:37:47 -07005287 public Map<SourceLocation, String> hintCollector;
Yingyi Bu391f09e2015-10-29 13:49:39 -07005288
5289 public void pushState() {
5290 lexerStateStack.push( curLexState );
5291 }
5292
5293 public void popState(String token) {
5294 if (lexerStateStack.size() > 0) {
5295 SwitchTo( lexerStateStack.pop() );
5296 } else {
5297 int errorLine = input_stream.getEndLine();
5298 int errorColumn = input_stream.getEndColumn();
5299 String msg = "Lexical error at line " + errorLine + ", column " + errorColumn + ". Encountered \"" + token
5300 + "\" but state stack is empty.";
5301 throw new TokenMgrError(msg, -1);
5302 }
5303 }
Dmitry Lychagine77cdac2019-08-05 11:37:47 -07005304
5305 void CommonTokenAction(Token token) {
5306 Token hintToken = token.specialToken;
5307 if (hintToken != null) {
5308 hintToken.sourceLocation = new SourceLocation(hintToken.beginLine, hintToken.beginColumn);
5309 String text = hintToken.image.substring(1).trim();
5310 boolean hintFound = hintToken.parseHint(text);
5311 hintCollector.put(hintToken.sourceLocation, hintFound ? hintToken.hint.getIdentifier() : hintToken.hintParams);
5312 }
5313 }
Yingyi Bu391f09e2015-10-29 13:49:39 -07005314}
5315
5316<DEFAULT,IN_DBL_BRACE>
5317TOKEN [IGNORE_CASE]:
5318{
Ian Maxon38fe9402020-01-29 19:27:40 -08005319 <ADAPTER: "adapter">
5320 | <ALL : "all">
Yingyi Bu391f09e2015-10-29 13:49:39 -07005321 | <AND : "and">
Yingyi Bu8aac7242016-09-13 23:14:09 -07005322 | <ANY : "any">
Yingyi Bu391f09e2015-10-29 13:49:39 -07005323 | <APPLY : "apply">
5324 | <AS : "as">
5325 | <ASC : "asc">
5326 | <AT : "at">
5327 | <AUTOGENERATED : "autogenerated">
Yingyi Bua8baf6d2016-07-05 21:40:44 -07005328 | <BETWEEN : "between">
Yingyi Bu391f09e2015-10-29 13:49:39 -07005329 | <BTREE : "btree">
5330 | <BY : "by">
5331 | <CASE : "case">
Ali Alsuliman69ce7d82021-11-01 15:00:16 -07005332 | <CAST : "cast">
Yingyi Bu391f09e2015-10-29 13:49:39 -07005333 | <CLOSED : "closed">
5334 | <CREATE : "create">
Dmitry Lychagind3eccd42021-08-19 12:18:17 -07005335 | <CROSS : "cross">
Dmitry Lychagin0ebc4202021-01-25 13:12:41 -08005336 | <COMPACTION : "compaction"> // no longer used
Yingyi Bu391f09e2015-10-29 13:49:39 -07005337 | <COMPACT : "compact">
5338 | <CONNECT : "connect">
5339 | <CORRELATE : "correlate">
Yingyi Bud56ff032016-08-01 10:26:57 -07005340 | <DATASET : "dataset">
Yingyi Bu1c0fff52016-03-25 20:23:30 -07005341 | <COLLECTION : "collection">
Yingyi Bud56ff032016-08-01 10:26:57 -07005342 | <DATAVERSE : "dataverse">
Yingyi Bu391f09e2015-10-29 13:49:39 -07005343 | <DECLARE : "declare">
5344 | <DEFINITION : "definition">
5345 | <DELETE : "delete">
5346 | <DESC : "desc">
5347 | <DISCONNECT : "disconnect">
5348 | <DISTINCT : "distinct">
Murtadha Hubail29f63912019-04-21 14:23:57 +03005349 | <DIV : "div">
Yingyi Bu391f09e2015-10-29 13:49:39 -07005350 | <DROP : "drop">
5351 | <ELEMENT : "element">
Till Westmann516d1a82016-08-02 14:45:53 -07005352 | <EXPLAIN : "explain">
Yingyi Bu391f09e2015-10-29 13:49:39 -07005353 | <ELSE : "else">
5354 | <ENFORCED : "enforced">
Yingyi Buc8c067c2016-07-25 23:37:19 -07005355 | <END : "end">
Yingyi Bu391f09e2015-10-29 13:49:39 -07005356 | <EVERY : "every">
5357 | <EXCEPT : "except">
5358 | <EXISTS : "exists">
5359 | <EXTERNAL : "external">
Dmitry Lychagin41b511d2020-12-07 14:48:13 -08005360 | <FALSE : "false">
Yingyi Bu391f09e2015-10-29 13:49:39 -07005361 | <FEED : "feed">
5362 | <FILTER : "filter">
5363 | <FLATTEN : "flatten">
5364 | <FOR : "for">
Yingyi Bu391f09e2015-10-29 13:49:39 -07005365 | <FROM : "from">
5366 | <FULL : "full">
Taewoo Kimc49405a2017-01-04 00:30:43 -08005367 | <FULLTEXT : "fulltext">
Yingyi Bu391f09e2015-10-29 13:49:39 -07005368 | <FUNCTION : "function">
5369 | <GROUP : "group">
5370 | <HAVING : "having">
5371 | <HINTS : "hints">
5372 | <IF : "if">
5373 | <INTO : "into">
5374 | <IN : "in">
5375 | <INDEX : "index">
5376 | <INGESTION : "ingestion">
5377 | <INNER : "inner">
5378 | <INSERT : "insert">
5379 | <INTERNAL : "internal">
5380 | <INTERSECT : "intersect">
Yingyi Budaa549c2016-06-28 22:30:52 -07005381 | <IS : "is">
Yingyi Bu391f09e2015-10-29 13:49:39 -07005382 | <JOIN : "join">
5383 | <KEYWORD : "keyword">
5384 | <KEY : "key">
Dmitry Lychagin1aa0dd42018-04-17 14:35:24 -07005385 | <KNOWN : "known">
Yingyi Bu391f09e2015-10-29 13:49:39 -07005386 | <LEFT : "left">
5387 | <LETTING : "letting">
5388 | <LET : "let">
Yingyi Bua8baf6d2016-07-05 21:40:44 -07005389 | <LIKE : "like">
Yingyi Bu391f09e2015-10-29 13:49:39 -07005390 | <LIMIT : "limit">
5391 | <LOAD : "load">
Dmitry Lychagin41b511d2020-12-07 14:48:13 -08005392 | <MISSING : "missing">
Murtadha Hubail29f63912019-04-21 14:23:57 +03005393 | <MOD : "mod">
Yingyi Bu391f09e2015-10-29 13:49:39 -07005394 | <NODEGROUP : "nodegroup">
5395 | <NGRAM : "ngram">
Yingyi Budaa549c2016-06-28 22:30:52 -07005396 | <NOT : "not">
Dmitry Lychagin41b511d2020-12-07 14:48:13 -08005397 | <NULL : "null">
Yingyi Bu391f09e2015-10-29 13:49:39 -07005398 | <OFFSET : "offset">
5399 | <ON : "on">
5400 | <OPEN : "open">
5401 | <OR : "or">
5402 | <ORDER : "order">
5403 | <OUTER : "outer">
5404 | <OUTPUT : "output">
Dmitry Lychaginfdedf622018-10-30 18:12:40 -07005405 | <OVER: "over">
Yingyi Bu391f09e2015-10-29 13:49:39 -07005406 | <PATH : "path">
5407 | <POLICY : "policy">
5408 | <PRESORTED : "pre-sorted">
5409 | <PRIMARY : "primary">
5410 | <RAW : "raw">
5411 | <REFRESH : "refresh">
5412 | <RETURN : "return">
Yingyi Bucb5bf332017-01-02 22:19:50 -08005413 | <RETURNING : "returning">
Dmitry Lychagind4ce84c2020-10-13 16:24:37 -07005414 | <RIGHT : "right">
Yingyi Bu391f09e2015-10-29 13:49:39 -07005415 | <RTREE : "rtree">
5416 | <RUN : "run">
5417 | <SATISFIES : "satisfies">
5418 | <SECONDARY : "secondary">
5419 | <SELECT : "select">
5420 | <SET : "set">
5421 | <SOME : "some">
Abdullah Alamoudifff200c2017-02-18 20:32:14 -08005422 | <START : "start">
5423 | <STOP : "stop">
Dmitry Lychagin2a0848e2020-01-08 13:57:22 -08005424 | <SYNONYM : "synonym">
Murtadha Hubail2c04ae02017-11-21 15:58:01 +03005425 | <TEMPORARY : "temporary"> // intentionally not used but reserved for future usage
Yingyi Bu391f09e2015-10-29 13:49:39 -07005426 | <THEN : "then">
Yingyi Bu391f09e2015-10-29 13:49:39 -07005427 | <TO : "to">
Dmitry Lychagin41b511d2020-12-07 14:48:13 -08005428 | <TRUE : "true">
5429 | <TYPE : "type">
Yingyi Bu391f09e2015-10-29 13:49:39 -07005430 | <UNION : "union">
Dmitry Lychagin8b6578a2017-11-08 15:04:35 -08005431 | <UNKNOWN : "unknown">
Yingyi Bu391f09e2015-10-29 13:49:39 -07005432 | <UNNEST : "unnest">
Yingyi Budaa549c2016-06-28 22:30:52 -07005433 | <UPDATE : "update">
Yingyi Bucb5bf332017-01-02 22:19:50 -08005434 | <UPSERT : "upsert">
Yingyi Budaa549c2016-06-28 22:30:52 -07005435 | <USE : "use">
5436 | <USING : "using">
Yingyi Bu391f09e2015-10-29 13:49:39 -07005437 | <VALUE : "value">
Dmitry Lychagin7d594a32018-01-15 14:31:03 -08005438 | <VALUED : "valued">
Dmitry Lychagin793c39e2021-04-21 16:52:10 -07005439 | <VIEW : "view">
Yingyi Bu391f09e2015-10-29 13:49:39 -07005440 | <WHEN : "when">
5441 | <WHERE : "where">
5442 | <WITH : "with">
5443 | <WRITE : "write">
Yingyi Bu391f09e2015-10-29 13:49:39 -07005444}
5445
5446<DEFAULT,IN_DBL_BRACE>
5447TOKEN :
5448{
5449 <CARET : "^">
Yingyi Bufdc71eb2016-08-24 22:41:57 -07005450 | <CONCAT : "||">
Dmitry Lychaginbf48c492018-05-01 18:30:27 -07005451 | <DIVIDE : "/">
Yingyi Bu391f09e2015-10-29 13:49:39 -07005452 | <MINUS : "-">
Yingyi Bu391f09e2015-10-29 13:49:39 -07005453 | <MUL : "*">
5454 | <PLUS : "+">
5455
5456 | <LEFTPAREN : "(">
5457 | <RIGHTPAREN : ")">
5458 | <LEFTBRACKET : "[">
5459 | <RIGHTBRACKET : "]">
5460
5461 | <ATT : "@">
5462 | <COLON : ":">
5463 | <COMMA : ",">
5464 | <DOT : ".">
Dmitry Lychaginbf48c492018-05-01 18:30:27 -07005465 | <PERCENT: "%">
Yingyi Bu391f09e2015-10-29 13:49:39 -07005466 | <QUES : "?">
5467 | <SEMICOLON : ";">
5468 | <SHARP : "#">
5469
5470 | <LT : "<">
5471 | <GT : ">">
5472 | <LE : "<=">
5473 | <GE : ">=">
5474 | <EQ : "=">
5475 | <NE : "!=">
Yingyi Bu4a4b8962016-09-16 12:09:11 -07005476 | <LG : "<>">
Yingyi Bu391f09e2015-10-29 13:49:39 -07005477 | <SIMILAR : "~=">
5478}
5479
5480<DEFAULT,IN_DBL_BRACE>
5481TOKEN :
5482{
5483 <LEFTBRACE : "{"> { pushState(); } : DEFAULT
5484}
5485
5486<DEFAULT>
5487TOKEN :
5488{
5489 <RIGHTBRACE : "}"> { popState("}"); }
5490}
5491
5492<DEFAULT,IN_DBL_BRACE>
5493TOKEN :
5494{
5495 <LEFTDBLBRACE : "{{"> { pushState(); } : IN_DBL_BRACE
5496}
5497
5498<IN_DBL_BRACE>
5499TOKEN :
5500{
5501 <RIGHTDBLBRACE : "}}"> { popState("}}"); }
5502}
5503
5504<DEFAULT,IN_DBL_BRACE>
5505TOKEN :
5506{
Yingyi Bu391f09e2015-10-29 13:49:39 -07005507 <#DIGIT : ["0" - "9"]>
5508}
5509
5510<DEFAULT,IN_DBL_BRACE>
5511TOKEN:
5512{
Dmitry Lychagin41b511d2020-12-07 14:48:13 -08005513 <INTEGER_LITERAL : <DIGITS> >
5514 | <DOUBLE_LITERAL: <DIGITS> ( "." <DIGITS> ) (("e"|"E") ("+"|"-")? <DIGITS>)?
Dmitry Lychaginee8526b2018-03-30 14:21:01 -07005515 | <DIGITS> (("e"|"E") ("+"|"-")? <DIGITS>)
5516 | "." <DIGITS> (("e"|"E") ("+"|"-")? <DIGITS>)?
Yingyi Bu391f09e2015-10-29 13:49:39 -07005517 >
Dmitry Lychagin41b511d2020-12-07 14:48:13 -08005518 | <FLOAT_LITERAL: <DIGITS> ( "f" | "F" )
Yingyi Bue4d919e2016-10-30 10:47:03 -07005519 | <DIGITS> ( "." <DIGITS> ( "f" | "F" ) )?
5520 | "." <DIGITS> ( "f" | "F" )
Yingyi Bu391f09e2015-10-29 13:49:39 -07005521 >
Dmitry Lychagin41b511d2020-12-07 14:48:13 -08005522 | <#DIGITS : (<DIGIT>)+ >
Yingyi Bu391f09e2015-10-29 13:49:39 -07005523}
5524
5525<DEFAULT,IN_DBL_BRACE>
5526TOKEN :
5527{
5528 <#LETTER : ["A" - "Z", "a" - "z"]>
Dmitry Lychagin41b511d2020-12-07 14:48:13 -08005529 | <#IDENTIFIER_START_SPECIALCHAR : ["_"]>
5530 | <#IDENTIFIER_REST_SPECIALCHAR : ["$"]>
5531 | <#IDENTIFIER_START : <LETTER> | <IDENTIFIER_START_SPECIALCHAR> >
5532 | <#IDENTIFIER_REST : <LETTER> | <DIGIT> | <IDENTIFIER_START_SPECIALCHAR> | <IDENTIFIER_REST_SPECIALCHAR> >
5533 | <IDENTIFIER : <IDENTIFIER_START> (<IDENTIFIER_REST>)* >
Yingyi Bu391f09e2015-10-29 13:49:39 -07005534}
5535
5536<DEFAULT,IN_DBL_BRACE>
5537TOKEN :
5538{
5539 // backslash u + 4 hex digits escapes are handled in the underlying JavaCharStream
Yingyi Bu6d57e492016-06-06 21:24:42 -07005540 <QUOTED_STRING : "`" (
Yingyi Bu391f09e2015-10-29 13:49:39 -07005541 <EscapeQuot>
5542 | <EscapeBslash>
5543 | <EscapeSlash>
5544 | <EscapeBspace>
5545 | <EscapeFormf>
5546 | <EscapeNl>
5547 | <EscapeCr>
5548 | <EscapeTab>
Yingyi Bu6d57e492016-06-06 21:24:42 -07005549 | ~["`","\\"])* "`">
Dmitry Lychagin984bc522021-10-13 16:22:25 -07005550 | <STRING_LITERAL : ( ("E")? "\"" (
Yingyi Bu391f09e2015-10-29 13:49:39 -07005551 <EscapeQuot>
Yingyi Bu391f09e2015-10-29 13:49:39 -07005552 | <EscapeBslash>
5553 | <EscapeSlash>
5554 | <EscapeBspace>
5555 | <EscapeFormf>
5556 | <EscapeNl>
5557 | <EscapeCr>
5558 | <EscapeTab>
Yingyi Bu6d57e492016-06-06 21:24:42 -07005559 | ~["\"","\\"])* "\"")
Dmitry Lychagin984bc522021-10-13 16:22:25 -07005560 | ( ("E")? "\'" (
Yingyi Bu6d57e492016-06-06 21:24:42 -07005561 <EscapeApos>
5562 | <EscapeBslash>
5563 | <EscapeSlash>
5564 | <EscapeBspace>
5565 | <EscapeFormf>
5566 | <EscapeNl>
5567 | <EscapeCr>
5568 | <EscapeTab>
5569 | ~["\'","\\"])* "\'")>
Yingyi Bu391f09e2015-10-29 13:49:39 -07005570 | < #EscapeQuot: "\\\"" >
5571 | < #EscapeApos: "\\\'" >
5572 | < #EscapeBslash: "\\\\" >
5573 | < #EscapeSlash: "\\/" >
5574 | < #EscapeBspace: "\\b" >
5575 | < #EscapeFormf: "\\f" >
5576 | < #EscapeNl: "\\n" >
5577 | < #EscapeCr: "\\r" >
5578 | < #EscapeTab: "\\t" >
5579}
5580
5581<DEFAULT,IN_DBL_BRACE>
5582TOKEN :
5583{
Dmitry Lychagin41b511d2020-12-07 14:48:13 -08005584 <DOLLAR_INTEGER_LITERAL : "$" <INTEGER_LITERAL> >
5585 | <DOLLAR_IDENTIFIER : "$" <IDENTIFIER> >
5586 | <DOLLAR_QUOTED_STRING: "$" <QUOTED_STRING> >
Yingyi Bu391f09e2015-10-29 13:49:39 -07005587}
5588
5589<DEFAULT,IN_DBL_BRACE>
5590SKIP:
5591{
5592 " "
5593 | "\t"
5594 | "\r"
5595 | "\n"
5596}
5597
5598<DEFAULT,IN_DBL_BRACE>
5599SKIP:
5600{
5601 <"//" (~["\n"])* "\n">
5602}
5603
5604<DEFAULT,IN_DBL_BRACE>
5605SKIP:
5606{
5607 <"//" (~["\n","\r"])* ("\n"|"\r"|"\r\n")?>
5608}
5609
5610<DEFAULT,IN_DBL_BRACE>
5611SKIP:
5612{
Yingyi Bu93846a72016-09-13 16:30:39 -07005613 <"--" (~["\n"])* "\n">
5614}
5615
5616
5617<DEFAULT,IN_DBL_BRACE>
5618SKIP:
5619{
5620 <"--" (~["\n","\r"])* ("\n"|"\r"|"\r\n")?>
5621}
5622
5623<DEFAULT,IN_DBL_BRACE>
5624SKIP:
5625{
Yingyi Bu391f09e2015-10-29 13:49:39 -07005626 <"/*"> { pushState(); } : INSIDE_COMMENT
5627}
5628
5629<INSIDE_COMMENT>
5630SPECIAL_TOKEN:
5631{
5632 <"+"(" ")*(~["*"])*>
5633}
5634
5635<INSIDE_COMMENT>
5636SKIP:
5637{
5638 <"/*"> { pushState(); }
5639}
5640
5641<INSIDE_COMMENT>
5642SKIP:
5643{
5644 <"*/"> { popState("*/"); }
5645 | <~[]>
5646}