blob: 58810d1f33aa5a25c3851771b04094107f704008 [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;
Ali Alsulimanba91b1c2023-02-22 21:33:55 -080055import org.apache.asterix.common.annotations.ExternalSubpathAnnotation;
Yingyi Bu391f09e2015-10-29 13:49:39 -070056import org.apache.asterix.common.annotations.FieldIntervalDataGen;
57import org.apache.asterix.common.annotations.FieldValFileDataGen;
58import org.apache.asterix.common.annotations.FieldValFileSameIndexDataGen;
59import org.apache.asterix.common.annotations.IRecordFieldDataGen;
Dmitry Lychagin6fd8ab32020-12-03 09:04:14 -080060import org.apache.asterix.common.annotations.IndexedNLJoinExpressionAnnotation;
Yingyi Bu391f09e2015-10-29 13:49:39 -070061import org.apache.asterix.common.annotations.InsertRandIntDataGen;
62import org.apache.asterix.common.annotations.ListDataGen;
63import org.apache.asterix.common.annotations.ListValFileDataGen;
Caleb Herbel8d9c57a2020-08-14 20:41:13 -060064import org.apache.asterix.common.annotations.RangeAnnotation;
Dmitry Lychagin6fd8ab32020-12-03 09:04:14 -080065import org.apache.asterix.common.annotations.SecondaryIndexSearchPreferenceAnnotation;
Yingyi Bu391f09e2015-10-29 13:49:39 -070066import org.apache.asterix.common.annotations.SkipSecondaryIndexSearchExpressionAnnotation;
Tin Vu4f1090d2021-09-21 02:06:32 -070067import org.apache.asterix.common.annotations.SpatialJoinAnnotation;
Yingyi Bu391f09e2015-10-29 13:49:39 -070068import org.apache.asterix.common.annotations.TypeDataGen;
69import org.apache.asterix.common.annotations.UndeclaredFieldsDataGen;
70import org.apache.asterix.common.config.DatasetConfig.DatasetType;
71import org.apache.asterix.common.config.DatasetConfig.IndexType;
Dmitry Lychagin13a40e12021-04-08 18:22:57 -070072import org.apache.asterix.common.exceptions.AsterixException;
Taewoo Kime65e6ca2017-01-14 17:53:28 -080073import org.apache.asterix.common.exceptions.CompilationException;
Dmitry Lychagin85142c02018-04-05 17:27:36 -070074import org.apache.asterix.common.exceptions.ErrorCode;
Dmitry Lychagin1f6a6e32019-07-02 11:59:53 -070075import org.apache.asterix.common.exceptions.WarningCollector;
Dmitry Lychagin7c53fcf2017-11-07 12:07:41 -080076import org.apache.asterix.common.functions.FunctionConstants;
Yingyi Bu391f09e2015-10-29 13:49:39 -070077import org.apache.asterix.common.functions.FunctionSignature;
Dmitry Lychagin54c06012019-11-13 15:54:20 -080078import org.apache.asterix.common.metadata.DataverseName;
Dmitry Lychagin793c39e2021-04-21 16:52:10 -070079import org.apache.asterix.common.metadata.DatasetFullyQualifiedName;
Dmitry Lychaginf3eec282022-06-10 12:44:25 -070080import org.apache.asterix.external.dataset.adapter.AdapterIdentifier;
Dmitry Lychagin276adf92019-01-15 13:16:40 -080081import org.apache.asterix.lang.common.base.AbstractClause;
Dmitry Lychaginee54cc02018-05-25 19:26:18 -070082import org.apache.asterix.lang.common.base.AbstractLangExpression;
83import org.apache.asterix.lang.common.base.AbstractStatement;
Yingyi Bu391f09e2015-10-29 13:49:39 -070084import org.apache.asterix.lang.common.base.Expression;
85import org.apache.asterix.lang.common.base.Literal;
86import org.apache.asterix.lang.common.base.IParser;
Dmitry Lychaginee54cc02018-05-25 19:26:18 -070087import org.apache.asterix.lang.common.base.ILangExpression;
Ali Alsuliman80225e22018-10-15 14:17:07 -070088import org.apache.asterix.lang.common.base.IParserFactory;
Yingyi Bu391f09e2015-10-29 13:49:39 -070089import org.apache.asterix.lang.common.base.Statement;
90import org.apache.asterix.lang.common.clause.GroupbyClause;
91import org.apache.asterix.lang.common.clause.LetClause;
92import org.apache.asterix.lang.common.clause.LimitClause;
93import org.apache.asterix.lang.common.clause.OrderbyClause;
94import org.apache.asterix.lang.common.clause.UpdateClause;
95import org.apache.asterix.lang.common.clause.WhereClause;
96import org.apache.asterix.lang.common.context.RootScopeFactory;
97import org.apache.asterix.lang.common.context.Scope;
98import org.apache.asterix.lang.common.expression.AbstractAccessor;
99import org.apache.asterix.lang.common.expression.CallExpr;
100import org.apache.asterix.lang.common.expression.FieldAccessor;
101import org.apache.asterix.lang.common.expression.FieldBinding;
102import org.apache.asterix.lang.common.expression.GbyVariableExpressionPair;
103import org.apache.asterix.lang.common.expression.IfExpr;
104import org.apache.asterix.lang.common.expression.IndexAccessor;
Dmitry Lychagin8ba59442017-06-16 14:19:45 -0700105import org.apache.asterix.lang.common.expression.IndexedTypeExpression;
Yingyi Bu391f09e2015-10-29 13:49:39 -0700106import org.apache.asterix.lang.common.expression.ListConstructor;
Hussain Towailebc5b5deb2018-12-15 18:48:48 +0300107import org.apache.asterix.lang.common.expression.ListSliceExpression;
Yingyi Bu391f09e2015-10-29 13:49:39 -0700108import org.apache.asterix.lang.common.expression.LiteralExpr;
109import org.apache.asterix.lang.common.expression.OperatorExpr;
110import org.apache.asterix.lang.common.expression.OrderedListTypeDefinition;
111import org.apache.asterix.lang.common.expression.QuantifiedExpression;
112import org.apache.asterix.lang.common.expression.RecordConstructor;
113import org.apache.asterix.lang.common.expression.RecordTypeDefinition;
114import org.apache.asterix.lang.common.expression.TypeExpression;
115import org.apache.asterix.lang.common.expression.TypeReferenceExpression;
116import org.apache.asterix.lang.common.expression.UnaryExpr;
Yingyi Bu391f09e2015-10-29 13:49:39 -0700117import org.apache.asterix.lang.common.expression.UnorderedListTypeDefinition;
118import org.apache.asterix.lang.common.expression.VariableExpr;
119import org.apache.asterix.lang.common.literal.DoubleLiteral;
120import org.apache.asterix.lang.common.literal.FalseLiteral;
121import org.apache.asterix.lang.common.literal.FloatLiteral;
122import org.apache.asterix.lang.common.literal.LongIntegerLiteral;
Yingyi Bu535d86b2016-05-23 16:44:25 -0700123import org.apache.asterix.lang.common.literal.MissingLiteral;
Yingyi Bu391f09e2015-10-29 13:49:39 -0700124import org.apache.asterix.lang.common.literal.NullLiteral;
125import org.apache.asterix.lang.common.literal.StringLiteral;
126import org.apache.asterix.lang.common.literal.TrueLiteral;
127import org.apache.asterix.lang.common.parser.ScopeChecker;
Dmitry Lychagin20905cd2020-08-06 20:34:55 -0700128import org.apache.asterix.lang.common.statement.AdapterDropStatement;
Dmitry Lychaginf3eec282022-06-10 12:44:25 -0700129import org.apache.asterix.lang.common.statement.AnalyzeStatement;
Ali Alsuliman6d72d5e2022-08-08 13:41:08 -0700130import org.apache.asterix.lang.common.statement.AnalyzeDropStatement;
Yingyi Bu391f09e2015-10-29 13:49:39 -0700131import org.apache.asterix.lang.common.statement.CompactStatement;
132import org.apache.asterix.lang.common.statement.ConnectFeedStatement;
Abdullah Alamoudifff200c2017-02-18 20:32:14 -0800133import org.apache.asterix.lang.common.statement.StartFeedStatement;
134import org.apache.asterix.lang.common.statement.StopFeedStatement;
Ian Maxon38fe9402020-01-29 19:27:40 -0800135import org.apache.asterix.lang.common.statement.CreateAdapterStatement;
Yingyi Bu391f09e2015-10-29 13:49:39 -0700136import org.apache.asterix.lang.common.statement.CreateDataverseStatement;
137import org.apache.asterix.lang.common.statement.CreateFeedPolicyStatement;
138import org.apache.asterix.lang.common.statement.CreateFeedStatement;
139import org.apache.asterix.lang.common.statement.CreateFunctionStatement;
140import org.apache.asterix.lang.common.statement.CreateIndexStatement;
Dmitry Lychagin2a0848e2020-01-08 13:57:22 -0800141import org.apache.asterix.lang.common.statement.CreateSynonymStatement;
Rui Guoe6986dd2020-11-25 19:50:06 -0800142import org.apache.asterix.lang.common.statement.CreateFullTextFilterStatement;
143import org.apache.asterix.lang.common.statement.CreateFullTextConfigStatement;
Dmitry Lychagin793c39e2021-04-21 16:52:10 -0700144import org.apache.asterix.lang.common.statement.CreateViewStatement;
Yingyi Bu391f09e2015-10-29 13:49:39 -0700145import org.apache.asterix.lang.common.statement.DatasetDecl;
146import org.apache.asterix.lang.common.statement.DataverseDecl;
147import org.apache.asterix.lang.common.statement.DataverseDropStatement;
148import org.apache.asterix.lang.common.statement.DeleteStatement;
149import org.apache.asterix.lang.common.statement.DisconnectFeedStatement;
Yingyi Buab817482016-08-19 21:29:31 -0700150import org.apache.asterix.lang.common.statement.DropDatasetStatement;
Yingyi Bu391f09e2015-10-29 13:49:39 -0700151import org.apache.asterix.lang.common.statement.ExternalDetailsDecl;
152import org.apache.asterix.lang.common.statement.FeedDropStatement;
Abdullah Alamoudi5dc73ed2016-07-28 05:03:13 +0300153import org.apache.asterix.lang.common.statement.FeedPolicyDropStatement;
Yingyi Bu391f09e2015-10-29 13:49:39 -0700154import org.apache.asterix.lang.common.statement.FunctionDecl;
155import org.apache.asterix.lang.common.statement.FunctionDropStatement;
156import org.apache.asterix.lang.common.statement.IndexDropStatement;
Rui Guoe6986dd2020-11-25 19:50:06 -0800157import org.apache.asterix.lang.common.statement.FullTextFilterDropStatement;
158import org.apache.asterix.lang.common.statement.FullTextConfigDropStatement;
Yingyi Bu391f09e2015-10-29 13:49:39 -0700159import org.apache.asterix.lang.common.statement.InsertStatement;
160import org.apache.asterix.lang.common.statement.InternalDetailsDecl;
161import org.apache.asterix.lang.common.statement.LoadStatement;
162import org.apache.asterix.lang.common.statement.NodeGroupDropStatement;
163import org.apache.asterix.lang.common.statement.NodegroupDecl;
164import org.apache.asterix.lang.common.statement.Query;
165import org.apache.asterix.lang.common.statement.RefreshExternalDatasetStatement;
Yingyi Bu391f09e2015-10-29 13:49:39 -0700166import org.apache.asterix.lang.common.statement.SetStatement;
Dmitry Lychagin2a0848e2020-01-08 13:57:22 -0800167import org.apache.asterix.lang.common.statement.SynonymDropStatement;
Yingyi Bu391f09e2015-10-29 13:49:39 -0700168import org.apache.asterix.lang.common.statement.TypeDecl;
169import org.apache.asterix.lang.common.statement.TypeDropStatement;
170import org.apache.asterix.lang.common.statement.UpdateStatement;
Yingyi Bucb5bf332017-01-02 22:19:50 -0800171import org.apache.asterix.lang.common.statement.UpsertStatement;
Dmitry Lychagin793c39e2021-04-21 16:52:10 -0700172import org.apache.asterix.lang.common.statement.ViewDecl;
173import org.apache.asterix.lang.common.statement.ViewDropStatement;
Yingyi Bu391f09e2015-10-29 13:49:39 -0700174import org.apache.asterix.lang.common.statement.WriteStatement;
175import org.apache.asterix.lang.common.struct.Identifier;
Dmitry Lychaginef1719e2017-12-15 08:33:07 -0800176import org.apache.asterix.lang.common.struct.OperatorType;
Yingyi Bu391f09e2015-10-29 13:49:39 -0700177import org.apache.asterix.lang.common.struct.QuantifiedPair;
178import org.apache.asterix.lang.common.struct.VarIdentifier;
Dmitry Lychagin4fb583d2021-11-10 17:25:28 -0800179import org.apache.asterix.lang.common.util.DatasetDeclParametersUtil;
Tin Vu4f1090d2021-09-21 02:06:32 -0700180import org.apache.asterix.lang.common.util.ExpressionUtils;
Ali Alsuliman80225e22018-10-15 14:17:07 -0700181import org.apache.asterix.lang.common.util.RangeMapBuilder;
Yingyi Bu391f09e2015-10-29 13:49:39 -0700182import org.apache.asterix.lang.sqlpp.clause.AbstractBinaryCorrelateClause;
183import org.apache.asterix.lang.sqlpp.clause.FromClause;
184import org.apache.asterix.lang.sqlpp.clause.FromTerm;
185import org.apache.asterix.lang.sqlpp.clause.HavingClause;
186import org.apache.asterix.lang.sqlpp.clause.JoinClause;
Yingyi Bu391f09e2015-10-29 13:49:39 -0700187import org.apache.asterix.lang.sqlpp.clause.Projection;
188import org.apache.asterix.lang.sqlpp.clause.SelectBlock;
189import org.apache.asterix.lang.sqlpp.clause.SelectClause;
190import org.apache.asterix.lang.sqlpp.clause.SelectElement;
191import org.apache.asterix.lang.sqlpp.clause.SelectRegular;
192import org.apache.asterix.lang.sqlpp.clause.SelectSetOperation;
193import org.apache.asterix.lang.sqlpp.clause.UnnestClause;
Xikui Wangf6741682018-02-22 19:17:17 -0800194import org.apache.asterix.lang.common.clause.WhereClause;
Yingyi Buc8c067c2016-07-25 23:37:19 -0700195import org.apache.asterix.lang.sqlpp.expression.CaseExpression;
Yingyi Bu391f09e2015-10-29 13:49:39 -0700196import org.apache.asterix.lang.sqlpp.expression.SelectExpression;
Dmitry Lychaginfdedf622018-10-30 18:12:40 -0700197import org.apache.asterix.lang.sqlpp.expression.WindowExpression;
Yingyi Bu391f09e2015-10-29 13:49:39 -0700198import org.apache.asterix.lang.sqlpp.optype.JoinType;
199import org.apache.asterix.lang.sqlpp.optype.SetOpType;
Dmitry Lychagind4ce84c2020-10-13 16:24:37 -0700200import org.apache.asterix.lang.sqlpp.optype.UnnestType;
Dmitry Lychaginac98f482020-03-31 12:26:40 -0700201import org.apache.asterix.lang.sqlpp.parser.SqlppGroupingSetsParser;
202import org.apache.asterix.lang.sqlpp.parser.SqlppGroupingSetsParser.GroupingElement;
203import org.apache.asterix.lang.sqlpp.parser.SqlppGroupingSetsParser.GroupingSet;
204import org.apache.asterix.lang.sqlpp.parser.SqlppGroupingSetsParser.GroupingSets;
205import org.apache.asterix.lang.sqlpp.parser.SqlppGroupingSetsParser.RollupCube;
Dmitry Lychagine77cdac2019-08-05 11:37:47 -0700206import org.apache.asterix.lang.sqlpp.parser.SqlppHint;
Yingyi Bu391f09e2015-10-29 13:49:39 -0700207import org.apache.asterix.lang.sqlpp.struct.SetOperationInput;
208import org.apache.asterix.lang.sqlpp.struct.SetOperationRight;
Yingyi Bu9e3f9be2016-07-01 10:07:37 -0700209import org.apache.asterix.lang.sqlpp.util.ExpressionToVariableUtil;
Xikui Wang96fd4022017-04-10 14:23:31 -0700210import org.apache.asterix.lang.sqlpp.util.FunctionMapUtil;
Yingyi Buacc12a92016-03-26 17:25:05 -0700211import org.apache.asterix.lang.sqlpp.util.SqlppVariableUtil;
Dmitry Lychaginf3eec282022-06-10 12:44:25 -0700212import org.apache.asterix.metadata.utils.MetadataConstants;
Tin Vu4f1090d2021-09-21 02:06:32 -0700213import org.apache.asterix.om.exceptions.TypeMismatchException;
Dmitry Lychagin7c53fcf2017-11-07 12:07:41 -0800214import org.apache.asterix.om.functions.BuiltinFunctions;
Dmitry Lychagin75f19872019-10-03 17:56:35 -0700215import org.apache.asterix.om.types.BuiltinType;
Dmitry Lychagine77cdac2019-08-05 11:37:47 -0700216import org.apache.commons.lang3.ArrayUtils;
Dmitry Lychagin1f6a6e32019-07-02 11:59:53 -0700217import org.apache.commons.lang3.StringUtils;
Yingyi Bu391f09e2015-10-29 13:49:39 -0700218import org.apache.hyracks.algebricks.common.utils.Pair;
219import org.apache.hyracks.algebricks.common.utils.Triple;
Xikui Wang5a61b2a2018-01-02 14:14:03 -0800220import org.apache.hyracks.algebricks.common.exceptions.AlgebricksException;
Shiva2ea73232019-10-09 18:04:05 -0700221import org.apache.hyracks.algebricks.core.algebra.expressions.BroadcastExpressionAnnotation;
Vijay Sarathy243ef2a2022-08-23 11:56:56 -0700222import org.apache.hyracks.algebricks.core.algebra.expressions.HashJoinExpressionAnnotation;
Yingyi Bu391f09e2015-10-29 13:49:39 -0700223import org.apache.hyracks.algebricks.core.algebra.expressions.IExpressionAnnotation;
Vijay Sarathy243ef2a2022-08-23 11:56:56 -0700224import org.apache.hyracks.algebricks.core.algebra.expressions.JoinProductivityAnnotation;
225import org.apache.hyracks.algebricks.core.algebra.expressions.PredicateCardinalityAnnotation;
Yingyi Bu391f09e2015-10-29 13:49:39 -0700226import org.apache.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
Dmitry Lychagin67714e22021-01-29 11:18:58 -0800227import org.apache.hyracks.api.exceptions.IWarningCollector;
Dmitry Lychaginee54cc02018-05-25 19:26:18 -0700228import org.apache.hyracks.api.exceptions.SourceLocation;
Dmitry Lychagin1f6a6e32019-07-02 11:59:53 -0700229import org.apache.hyracks.api.exceptions.Warning;
Dmitry Lychagin70bf47a2020-10-22 13:25:57 -0700230import org.apache.hyracks.dataflow.common.data.partition.range.RangeMap;
Ali Alsuliman587b7902019-01-21 14:33:50 -0800231import org.apache.hyracks.util.LogRedactionUtil;
Dmitry Lychagine77cdac2019-08-05 11:37:47 -0700232import org.apache.hyracks.util.StringUtil;
Vijay Sarathy243ef2a2022-08-23 11:56:56 -0700233import java.util.regex.Matcher;
234import java.util.regex.Pattern;
Yingyi Bu391f09e2015-10-29 13:49:39 -0700235
Yingyi Bucaea8f02015-11-16 15:12:15 -0800236class SQLPPParser extends ScopeChecker implements IParser {
Yingyi Bu391f09e2015-10-29 13:49:39 -0700237
Dmitry Lychaginf2c18aa2018-12-28 21:20:23 -0800238 // tokens parsed as identifiers
Dmitry Lychaginac98f482020-03-31 12:26:40 -0700239 private static final String CUBE = "CUBE";
Dmitry Lychaginf2c18aa2018-12-28 21:20:23 -0800240 private static final String CURRENT = "CURRENT";
Dmitry Lychagin33c77f92021-07-21 15:59:04 -0700241 private static final String DEFAULT = "DEFAULT";
Dmitry Lychaginf2c18aa2018-12-28 21:20:23 -0800242 private static final String EXCLUDE = "EXCLUDE";
Ali Alsuliman931e7382021-08-08 21:55:59 +0300243 private static final String INCLUDE = "INCLUDE";
Dmitry Lychagin5476f962019-05-31 16:03:11 -0700244 private static final String FIRST = "FIRST";
Dmitry Lychaginf2c18aa2018-12-28 21:20:23 -0800245 private static final String FOLLOWING = "FOLLOWING";
Dmitry Lychagin914983f2021-09-30 15:11:11 -0700246 private static final String FOREIGN = "FOREIGN";
Dmitry Lychaginac98f482020-03-31 12:26:40 -0700247 private static final String GROUPING = "GROUPING";
Dmitry Lychaginf2c18aa2018-12-28 21:20:23 -0800248 private static final String GROUPS = "GROUPS";
Dmitry Lychagin3346cea2019-05-28 12:11:54 -0700249 private static final String IGNORE = "IGNORE";
Dmitry Lychagin5476f962019-05-31 16:03:11 -0700250 private static final String LAST = "LAST";
Glenn67fd1f32021-02-25 16:04:49 -0800251 private static final String META = "META";
Dmitry Lychaginf2c18aa2018-12-28 21:20:23 -0800252 private static final String NO = "NO";
Dmitry Lychagin3346cea2019-05-28 12:11:54 -0700253 private static final String NULLS = "NULLS";
Dmitry Lychaginf2c18aa2018-12-28 21:20:23 -0800254 private static final String OTHERS = "OTHERS";
255 private static final String PARTITION = "PARTITION";
256 private static final String PRECEDING = "PRECEDING";
257 private static final String RANGE = "RANGE";
Dmitry Lychagin914983f2021-09-30 15:11:11 -0700258 private static final String REFERENCES = "REFERENCES";
Dmitry Lychagin3346cea2019-05-28 12:11:54 -0700259 private static final String RESPECT = "RESPECT";
Dmitry Lychaginac98f482020-03-31 12:26:40 -0700260 private static final String ROLLUP = "ROLLUP";
Dmitry Lychaginf2c18aa2018-12-28 21:20:23 -0800261 private static final String ROW = "ROW";
262 private static final String ROWS = "ROWS";
Dmitry Lychaginac98f482020-03-31 12:26:40 -0700263 private static final String SETS = "SETS";
Dmitry Lychaginf2c18aa2018-12-28 21:20:23 -0800264 private static final String TIES = "TIES";
265 private static final String UNBOUNDED = "UNBOUNDED";
Dmitry Lychagindcb4ad22020-08-26 15:49:09 -0700266 private static final String REPLACE = "REPLACE";
Ian Maxon38fe9402020-01-29 19:27:40 -0800267 private static final String RETURNS = "RETURNS";
Rui Guoe6986dd2020-11-25 19:50:06 -0800268 private static final String CONFIG = "CONFIG";
Ali Alsuliman6d72d5e2022-08-08 13:41:08 -0700269 private static final String STATISTICS = "STATISTICS";
Rui Guoe6986dd2020-11-25 19:50:06 -0800270
Dmitry Lychaginf2c18aa2018-12-28 21:20:23 -0800271
Dmitry Lychagin75f19872019-10-03 17:56:35 -0700272 private static final String INT_TYPE_NAME = "int";
Dmitry Lychagin541652082020-11-09 14:04:53 -0800273 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 -0700274
Till Westmann7199a562016-09-17 16:07:32 -0700275 // error configuration
276 protected static final boolean REPORT_EXPECTED_TOKENS = false;
277
Dmitry Lychagin1bdf8082018-06-13 14:48:23 -0700278 private int externalVarCounter;
279
Dmitry Lychagin54c06012019-11-13 15:54:20 -0800280 private DataverseName defaultDataverse;
281
Dmitry Lychaginac98f482020-03-31 12:26:40 -0700282 private SqlppGroupingSetsParser groupingSetsParser;
283
Dmitry Lychagin1f6a6e32019-07-02 11:59:53 -0700284 private final WarningCollector warningCollector = new WarningCollector();
285
Dmitry Lychagine77cdac2019-08-05 11:37:47 -0700286 private final Map<SourceLocation, String> hintCollector = new HashMap<SourceLocation, String>();
287
Yingyi Bu391f09e2015-10-29 13:49:39 -0700288 private static class IndexParams {
289 public IndexType type;
290 public int gramLength;
Rui Guoe6986dd2020-11-25 19:50:06 -0800291 public String fullTextConfig;
Yingyi Bu391f09e2015-10-29 13:49:39 -0700292
Rui Guoe6986dd2020-11-25 19:50:06 -0800293 public IndexParams(IndexType type, int gramLength, String fullTextConfig) {
Yingyi Bu391f09e2015-10-29 13:49:39 -0700294 this.type = type;
295 this.gramLength = gramLength;
Rui Guoe6986dd2020-11-25 19:50:06 -0800296 this.fullTextConfig = fullTextConfig;
Yingyi Bu391f09e2015-10-29 13:49:39 -0700297 }
Ali Alsuliman69ce7d82021-11-01 15:00:16 -0700298 }
Yingyi Bu391f09e2015-10-29 13:49:39 -0700299
300 private static class FunctionName {
Dmitry Lychagin54c06012019-11-13 15:54:20 -0800301 public DataverseName dataverse;
Dmitry Lychaginee54cc02018-05-25 19:26:18 -0700302 public String library;
303 public String function;
Caleb Herbel8d9c57a2020-08-14 20:41:13 -0600304 public Token hintToken;
Dmitry Lychaginee54cc02018-05-25 19:26:18 -0700305 public SourceLocation sourceLoc;
Yingyi Bu391f09e2015-10-29 13:49:39 -0700306 }
307
Dmitry Lychagine77cdac2019-08-05 11:37:47 -0700308 private IRecordFieldDataGen parseFieldDataGen(Token hintToken) throws ParseException {
309 String[] splits = hintToken.hintParams != null ? hintToken.hintParams.split("\\s+") : null;
310 switch (hintToken.hint) {
311 case VAL_FILE_HINT:
312 File[] valFiles = new File[splits.length];
313 for (int k=0; k<splits.length; k++) {
314 valFiles[k] = new File(splits[k]);
315 }
316 return new FieldValFileDataGen(valFiles);
317 case VAL_FILE_SAME_INDEX_HINT:
318 return new FieldValFileSameIndexDataGen(new File(splits[0]), splits[1]);
319 case LIST_VAL_FILE_HINT:
320 return new ListValFileDataGen(new File(splits[0]), Integer.parseInt(splits[1]), Integer.parseInt(splits[2]));
321 case LIST_HINT:
322 return new ListDataGen(Integer.parseInt(splits[0]), Integer.parseInt(splits[1]));
323 case INTERVAL_HINT:
324 FieldIntervalDataGen.ValueType vt;
325 switch (splits[0]) {
326 case "int":
327 vt = FieldIntervalDataGen.ValueType.INT;
328 break;
329 case "long":
330 vt = FieldIntervalDataGen.ValueType.LONG;
331 break;
332 case "float":
333 vt = FieldIntervalDataGen.ValueType.FLOAT;
334 break;
335 case "double":
336 vt = FieldIntervalDataGen.ValueType.DOUBLE;
337 break;
338 default:
339 throw new SqlppParseException(getSourceLocation(hintToken),
340 "Unknown type for interval data gen: " + splits[0]);
341 }
342 return new FieldIntervalDataGen(vt, splits[1], splits[2]);
343 case INSERT_RAND_INT_HINT:
344 return new InsertRandIntDataGen(splits[0], splits[1]);
345 case DATE_BETWEEN_YEARS_HINT:
346 return new DateBetweenYearsDataGen(Integer.parseInt(splits[0]), Integer.parseInt(splits[1]));
347 case DATETIME_BETWEEN_YEARS_HINT:
348 return new DatetimeBetweenYearsDataGen(Integer.parseInt(splits[0]), Integer.parseInt(splits[1]));
349 case DATETIME_ADD_RAND_HOURS_HINT:
350 return new DatetimeAddRandHoursDataGen(Integer.parseInt(splits[0]), Integer.parseInt(splits[1]), splits[2]);
351 case AUTO_HINT:
352 return new AutoDataGen(splits[0]);
353 default:
354 return null;
Yingyi Bu391f09e2015-10-29 13:49:39 -0700355 }
Yingyi Bu391f09e2015-10-29 13:49:39 -0700356 }
357
Till Westmann7199a562016-09-17 16:07:32 -0700358 public SQLPPParser(String s) {
Yingyi Bu391f09e2015-10-29 13:49:39 -0700359 this(new StringReader(s));
360 super.setInput(s);
361 }
362
Ali Alsuliman69ce7d82021-11-01 15:00:16 -0700363 public static void main(String[] args) throws ParseException, TokenMgrError, IOException, FileNotFoundException, CompilationException {
Yingyi Bu391f09e2015-10-29 13:49:39 -0700364 File file = new File(args[0]);
365 Reader fis = new BufferedReader(new InputStreamReader(new FileInputStream(file), "UTF-8"));
366 SQLPPParser parser = new SQLPPParser(fis);
367 List<Statement> st = parser.parse();
368 //st.accept(new SQLPPPrintVisitor(), 0);
369 }
370
Dmitry Lychagin45de2342020-02-03 12:01:28 -0800371 @Override
Taewoo Kime65e6ca2017-01-14 17:53:28 -0800372 public List<Statement> parse() throws CompilationException {
Dmitry Lychagin1227f022019-08-01 13:14:30 -0700373 return parseImpl(new ParseFunction<List<Statement>>() {
374 @Override
375 public List<Statement> parse() throws ParseException {
376 return SQLPPParser.this.Statement();
377 }
378 });
379 }
380
Dmitry Lychagin62f0beb2020-09-08 11:44:19 -0700381 @Override
382 public Expression parseExpression() throws CompilationException {
Dmitry Lychagin1227f022019-08-01 13:14:30 -0700383 return parseImpl(new ParseFunction<Expression>() {
384 @Override
385 public Expression parse() throws ParseException {
386 return SQLPPParser.this.Expression();
387 }
388 });
389 }
390
391 private static Expression parseExpression(String text) throws CompilationException {
392 return new SQLPPParser(text).parseExpression();
393 }
394
Dmitry Lychagin45de2342020-02-03 12:01:28 -0800395 @Override
Dmitry Lychaginef680d7d2020-10-15 13:10:41 -0700396 public List<String> parseMultipartIdentifier() throws CompilationException {
397 return parseImpl(new ParseFunction<List<String>>() {
398 @Override
399 public List<String> parse() throws ParseException {
Dmitry Lychagin13a40e12021-04-08 18:22:57 -0700400 return SQLPPParser.this.MultipartIdentifier().first;
Dmitry Lychaginef680d7d2020-10-15 13:10:41 -0700401 }
402 });
403 }
404
Dmitry Lychagin6fd8ab32020-12-03 09:04:14 -0800405 private List<String> parseParenthesizedIdentifierList() throws CompilationException {
406 return parseImpl(new ParseFunction<List<String>>() {
407 @Override
408 public List<String> parse() throws ParseException {
409 return SQLPPParser.this.ParenthesizedIdentifierList();
410 }
411 });
412 }
413
414 private static List<String> parseParenthesizedIdentifierList(String text) throws CompilationException {
415 return new SQLPPParser(text).parseParenthesizedIdentifierList();
416 }
417
Vijay Sarathy691e93b2022-11-20 14:31:47 -0800418 private Pair<HashJoinExpressionAnnotation.BuildOrProbe, String> parseHashJoinParams() throws CompilationException {
419 return parseImpl(new ParseFunction<Pair<HashJoinExpressionAnnotation.BuildOrProbe, String>>() {
420 @Override
421 public Pair<HashJoinExpressionAnnotation.BuildOrProbe, String> parse() throws ParseException {
422 return SQLPPParser.this.buildOrProbeParenthesizedIdentifier();
423 }
424 });
425 }
426
427 private static Pair<HashJoinExpressionAnnotation.BuildOrProbe, String> parseHashJoinParams(String text) throws CompilationException {
428 return new SQLPPParser(text).parseHashJoinParams();
429 }
430
431 private String parseBroadcastJoinParams() throws CompilationException {
432 return parseImpl(new ParseFunction<String>() {
433 @Override
434 public String parse() throws ParseException {
435 return SQLPPParser.this.parenthesizedIdentifier();
436 }
437 });
438 }
439
440 private static String parseBroadcastJoinParams(String text) throws CompilationException {
441 return new SQLPPParser(text).parseBroadcastJoinParams();
442 }
443
Tin Vu4f1090d2021-09-21 02:06:32 -0700444 private List<Literal> parseParenthesizedLiteralList() throws CompilationException {
445 return parseImpl(new ParseFunction<List<Literal>>() {
446 @Override
447 public List<Literal> parse() throws ParseException {
448 return SQLPPParser.this.ParenthesizedLiteralList();
449 }
450 });
451 }
452
453 private static List<Literal> parseParenthesizedLiteralList(String text) throws CompilationException {
454 return new SQLPPParser(text).parseParenthesizedLiteralList();
455 }
456
Dmitry Lychaginef680d7d2020-10-15 13:10:41 -0700457 @Override
Dmitry Lychagin9ba74872021-04-05 14:38:20 -0700458 public FunctionDecl parseFunctionBody(FunctionSignature signature, List<String> paramNames, boolean isStored)
Dmitry Lychagin45de2342020-02-03 12:01:28 -0800459 throws CompilationException {
Dmitry Lychagine74454b2020-02-06 13:44:21 -0800460 return parseImpl(new ParseFunction<FunctionDecl>() {
Dmitry Lychagin45de2342020-02-03 12:01:28 -0800461 @Override
Dmitry Lychagine74454b2020-02-06 13:44:21 -0800462 public FunctionDecl parse() throws ParseException {
Dmitry Lychagin45de2342020-02-03 12:01:28 -0800463 DataverseName dataverse = defaultDataverse;
464 defaultDataverse = signature.getDataverseName();
465 createNewScope();
Dmitry Lychagine74454b2020-02-06 13:44:21 -0800466 List<VarIdentifier> paramVars = new ArrayList<VarIdentifier>(paramNames.size());
467 for (String paramName : paramNames) {
468 paramVars.add(SqlppVariableUtil.toInternalVariableIdentifier(paramName));
469 }
Dmitry Lychagin45de2342020-02-03 12:01:28 -0800470 Expression functionBodyExpr = SQLPPParser.this.FunctionBody();
471 removeCurrentScope();
472 defaultDataverse = dataverse;
Dmitry Lychagin9ba74872021-04-05 14:38:20 -0700473 return new FunctionDecl(signature, paramVars, functionBodyExpr, isStored);
Dmitry Lychagin45de2342020-02-03 12:01:28 -0800474 }
475 });
476 }
477
Dmitry Lychagin793c39e2021-04-21 16:52:10 -0700478 @Override
479 public ViewDecl parseViewBody(DatasetFullyQualifiedName viewName) throws CompilationException {
480 return parseImpl(new ParseFunction<ViewDecl>() {
481 @Override
482 public ViewDecl parse() throws ParseException {
483 DataverseName dataverse = defaultDataverse;
484 defaultDataverse = viewName.getDataverseName();
485 createNewScope();
486 Expression viewBodyExpr = SQLPPParser.this.ViewBody();
487 removeCurrentScope();
488 defaultDataverse = dataverse;
489 return new ViewDecl(viewName, viewBodyExpr);
490 }
491 });
492 }
493
Dmitry Lychagin1227f022019-08-01 13:14:30 -0700494 private <T> T parseImpl(ParseFunction<T> parseFunction) throws CompilationException {
Dmitry Lychagin1f6a6e32019-07-02 11:59:53 -0700495 warningCollector.clear();
Dmitry Lychagine77cdac2019-08-05 11:37:47 -0700496 hintCollector.clear();
Dmitry Lychagin67714e22021-01-29 11:18:58 -0800497 token_source.hintCollector = hintCollector;
Yingyi Bu391f09e2015-10-29 13:49:39 -0700498 try {
Dmitry Lychagin1227f022019-08-01 13:14:30 -0700499 return parseFunction.parse();
Dmitry Lychagin3e2623c2020-04-01 11:20:04 -0700500 } catch (SqlppParseException e) {
Dmitry Lychagin13a40e12021-04-08 18:22:57 -0700501 if (e.getCause() instanceof AlgebricksException) {
502 AlgebricksException cause = (AlgebricksException) e.getCause();
503 if (cause.getError().isPresent() && cause.getError().get() instanceof ErrorCode) {
504 throw new CompilationException((ErrorCode) cause.getError().get(), e.getSourceLocation(),
505 cause.getParams());
506 }
507 }
508 throw new CompilationException(ErrorCode.PARSE_ERROR, e.getSourceLocation(),
509 LogRedactionUtil.userData(getMessage(e)));
Dmitry Lychagin3e2623c2020-04-01 11:20:04 -0700510 } catch (ParseException e) {
511 throw new CompilationException(ErrorCode.PARSE_ERROR, LogRedactionUtil.userData(getMessage(e)));
Yingyi Bu391f09e2015-10-29 13:49:39 -0700512 } catch (Error e) {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -0700513 // 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 -0700514 // 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 -0700515 final String msg = e.getClass().getSimpleName() + (e.getMessage() != null ? ": " + e.getMessage() : "");
Ali Alsulimanfe901892019-03-19 01:40:35 -0700516 throw new CompilationException(ErrorCode.PARSE_ERROR, LogRedactionUtil.userData(msg));
Dmitry Lychagine77cdac2019-08-05 11:37:47 -0700517 } finally {
518 reportUnclaimedHints();
Yingyi Bu391f09e2015-10-29 13:49:39 -0700519 }
520 }
Till Westmann7199a562016-09-17 16:07:32 -0700521
Dmitry Lychagin1227f022019-08-01 13:14:30 -0700522 @FunctionalInterface
523 private interface ParseFunction<T> {
524 T parse() throws ParseException;
525 }
526
Dmitry Lychagin1f6a6e32019-07-02 11:59:53 -0700527 @Override
Dmitry Lychagin67714e22021-01-29 11:18:58 -0800528 public void getWarnings(IWarningCollector outWarningCollector) {
529 warningCollector.getWarnings(outWarningCollector);
530 }
531
532 @Override
Ali Alsuliman6a9e2b02019-09-16 20:50:41 -0700533 public void getWarnings(Collection<? super Warning> outWarnings, long maxWarnings) {
534 warningCollector.getWarnings(outWarnings, maxWarnings);
535 }
536
537 @Override
538 public long getTotalWarningsCount() {
539 return warningCollector.getTotalWarningsCount();
Dmitry Lychagin1f6a6e32019-07-02 11:59:53 -0700540 }
541
Till Westmann7199a562016-09-17 16:07:32 -0700542 protected String getMessage(ParseException pe) {
543 Token currentToken = pe.currentToken;
544 if (currentToken == null) {
545 return pe.getMessage();
546 }
547 int[][] expectedTokenSequences = pe.expectedTokenSequences;
548 String[] tokenImage = pe.tokenImage;
549 String sep = REPORT_EXPECTED_TOKENS ? eol : " ";
550 StringBuilder expected = REPORT_EXPECTED_TOKENS ? new StringBuilder() : null;
551 int maxSize = appendExpected(expected, expectedTokenSequences, tokenImage);
552 Token tok = currentToken.next;
553 int line = tok.beginLine;
Dmitry Lychaginee54cc02018-05-25 19:26:18 -0700554 StringBuilder message = new StringBuilder(128);
555 message.append("In line ").append(line).append(" >>").append(getLine(line)).append("<<").append(sep).append("Encountered ");
Till Westmann7199a562016-09-17 16:07:32 -0700556 for (int i = 0; i < maxSize; i++) {
557 if (i != 0) {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -0700558 message.append(' ');
Till Westmann7199a562016-09-17 16:07:32 -0700559 }
560 if (tok.kind == 0) {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -0700561 message.append(fixQuotes(tokenImage[0]));
Till Westmann7199a562016-09-17 16:07:32 -0700562 break;
563 }
Till Westmanne3c9f272016-10-09 11:09:26 -0700564 final String fixedTokenImage = tokenImage[tok.kind];
565 if (! tok.image.equalsIgnoreCase(stripQuotes(fixedTokenImage))) {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -0700566 message.append(fixQuotes(fixedTokenImage)).append(' ');
Till Westmanne3c9f272016-10-09 11:09:26 -0700567 }
Dmitry Lychaginee54cc02018-05-25 19:26:18 -0700568 message.append(quot).append(addEscapes(tok.image)).append(quot);
Till Westmann7199a562016-09-17 16:07:32 -0700569 tok = tok.next;
570 }
Dmitry Lychaginee54cc02018-05-25 19:26:18 -0700571 message.append(" at column ").append(currentToken.next.beginColumn).append('.').append(sep);
Till Westmann7199a562016-09-17 16:07:32 -0700572 if (REPORT_EXPECTED_TOKENS) {
573 if (expectedTokenSequences.length == 1) {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -0700574 message.append("Was expecting:").append(sep).append(" ");
Till Westmann7199a562016-09-17 16:07:32 -0700575 } else {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -0700576 message.append("Was expecting one of:").append(sep).append(" ");
Till Westmann7199a562016-09-17 16:07:32 -0700577 }
Dmitry Lychaginee54cc02018-05-25 19:26:18 -0700578 message.append(expected);
Till Westmann7199a562016-09-17 16:07:32 -0700579 }
Dmitry Lychaginee54cc02018-05-25 19:26:18 -0700580 return message.toString();
Till Westmann7199a562016-09-17 16:07:32 -0700581 }
582
Dmitry Lychaginee54cc02018-05-25 19:26:18 -0700583 protected static SourceLocation getSourceLocation(Token token) {
Dmitry Lychagine77cdac2019-08-05 11:37:47 -0700584 return
585 token == null ? null :
586 token.sourceLocation != null ? token.sourceLocation :
587 new SourceLocation(token.beginLine, token.beginColumn);
Dmitry Lychaginee54cc02018-05-25 19:26:18 -0700588 }
589
Dmitry Lychagin5c26b422018-06-01 10:22:16 -0700590 protected static <T extends AbstractLangExpression> T addSourceLocation(T expr, Token token) {
591 expr.setSourceLocation(getSourceLocation(token));
592 return expr;
Dmitry Lychaginee54cc02018-05-25 19:26:18 -0700593 }
Dmitry Lychaginf2c18aa2018-12-28 21:20:23 -0800594
595 private boolean isToken(String image) {
Dmitry Lychagindcb4ad22020-08-26 15:49:09 -0700596 return isToken(token, image);
597 }
598
599 private static boolean isToken(Token token, String image) {
Dmitry Lychaginf2c18aa2018-12-28 21:20:23 -0800600 return token.image.equalsIgnoreCase(image);
601 }
602
603 private void expectToken(String image) throws SqlppParseException {
Dmitry Lychagindcb4ad22020-08-26 15:49:09 -0700604 expectToken(token, image);
605 }
606
607 private static void expectToken(Token token, String image) throws SqlppParseException {
608 if (!isToken(token, image)) {
609 throw createUnexpectedTokenError(token);
Dmitry Lychaginf2c18aa2018-12-28 21:20:23 -0800610 }
611 }
612
613 private SqlppParseException createUnexpectedTokenError() {
Dmitry Lychagin5cc254a2020-05-08 17:12:47 -0700614 return createUnexpectedTokenError(token, null);
Dmitry Lychagin3e2623c2020-04-01 11:20:04 -0700615 }
616
Dmitry Lychagindcb4ad22020-08-26 15:49:09 -0700617 private static SqlppParseException createUnexpectedTokenError(Token t) {
Dmitry Lychagin5cc254a2020-05-08 17:12:47 -0700618 return createUnexpectedTokenError(t, null);
Dmitry Lychagin0d4c1b62020-02-07 17:10:16 -0800619 }
620
621 private SqlppParseException createUnexpectedTokenError(String expected) {
Dmitry Lychagin5cc254a2020-05-08 17:12:47 -0700622 return createUnexpectedTokenError(token, expected);
623 }
624
Dmitry Lychagindcb4ad22020-08-26 15:49:09 -0700625 private static SqlppParseException createUnexpectedTokenError(Token t, String expected) {
Dmitry Lychagin5cc254a2020-05-08 17:12:47 -0700626 String message = "Unexpected token: " + LogRedactionUtil.userData(t.image) +
Dmitry Lychagin0d4c1b62020-02-07 17:10:16 -0800627 (expected == null ? "" : ". Expected: " + LogRedactionUtil.userData(expected));
Dmitry Lychagin5cc254a2020-05-08 17:12:47 -0700628 return new SqlppParseException(getSourceLocation(t), message);
Dmitry Lychaginf2c18aa2018-12-28 21:20:23 -0800629 }
630
Dmitry Lychaginac98f482020-03-31 12:26:40 -0700631 private boolean laToken(int idx, int kind) {
632 Token t = getToken(idx);
633 return t.kind == kind;
634 }
635
Dmitry Lychaginf2c18aa2018-12-28 21:20:23 -0800636 private boolean laToken(int idx, int kind, String image) {
637 Token t = getToken(idx);
638 return t.kind == kind && t.image.equalsIgnoreCase(image);
639 }
640
641 private boolean laIdentifier(int idx, String image) {
642 return laToken(idx, IDENTIFIER, image);
643 }
644
645 private boolean laIdentifier(String image) {
646 return laIdentifier(1, image);
647 }
Dmitry Lychagin1f6a6e32019-07-02 11:59:53 -0700648
Dmitry Lychagine77cdac2019-08-05 11:37:47 -0700649 private Token fetchHint(Token token, SqlppHint... expectedHints) {
650 Token hintToken = token.specialToken;
651 if (hintToken == null) {
652 return null;
653 }
654 SourceLocation sourceLoc = getSourceLocation(hintToken);
655 hintCollector.remove(sourceLoc);
656 if (hintToken.hint == null) {
657 warnUnexpectedHint(hintToken.hintParams, sourceLoc, expectedHints);
658 return null;
659 } else if (!ArrayUtils.contains(expectedHints, hintToken.hint)) {
660 warnUnexpectedHint(hintToken.hint.getIdentifier(), sourceLoc, expectedHints);
661 return null;
662 } else {
663 return hintToken;
664 }
665 }
666
667 private void reportUnclaimedHints() {
668 for (Map.Entry<SourceLocation, String> me : hintCollector.entrySet()) {
669 warnUnexpectedHint(me.getValue(), me.getKey(), "None");
670 }
671 }
672
673 private void warnUnexpectedHint(String actualHint, SourceLocation sourceLoc, SqlppHint... expectedHints) {
674 warnUnexpectedHint(actualHint, sourceLoc, StringUtil.join(expectedHints, ", ", "\""));
675 }
676
677 private void warnUnexpectedHint(String actualHint, SourceLocation sourceLoc, String expectedHints) {
Ali Alsulimanaa118862019-09-10 20:55:45 -0700678 if (warningCollector.shouldWarn()) {
Michael Blow7c838de2021-02-23 16:12:48 -0500679 warningCollector.warn(Warning.of(sourceLoc, ErrorCode.UNEXPECTED_HINT, actualHint, expectedHints));
Ali Alsulimanaa118862019-09-10 20:55:45 -0700680 }
Dmitry Lychagin1f6a6e32019-07-02 11:59:53 -0700681 }
Dmitry Lychaginf7bc6c12020-06-01 18:19:44 -0700682
Dmitry Lychagin7c624522020-12-04 18:01:45 -0800683 private IExpressionAnnotation parseExpressionAnnotation(Token hintToken) {
684 // placeholder for the annotation that should be returned if this hint's parameters cannot be parsed
685 IExpressionAnnotation onParseErrorReturn = null;
Vijay Sarathy243ef2a2022-08-23 11:56:56 -0700686 double selectivity, cardinality, productivity;
687 Pattern number = Pattern.compile("\\d+\\.\\d+");
688 Pattern stringNumber = Pattern.compile("\\w+\\s+\\d+\\.\\d+");
689 Pattern lessThanOnePat = Pattern.compile("0\\.\\d+");
Dmitry Lychagin6fd8ab32020-12-03 09:04:14 -0800690 try {
691 switch (hintToken.hint) {
Vijay Sarathy7ba271a2023-03-09 08:07:43 -0800692 case SINGLE_DATASET_PREDICATE_SELECTIVITY_HINT:
693 if (hintToken.hintParams == null) {
694 throw new SqlppParseException(getSourceLocation(hintToken), "Expected selectivity value");
695 }
696 else {
697 selectivity = 1.0; // uninitialized
698 Matcher mat = lessThanOnePat.matcher(hintToken.hintParams);
699 if (mat.find()) {
700 selectivity = Double.parseDouble (mat.group());
701 }
702 else {
Vijay Sarathyc70bae02023-03-13 13:24:05 -0700703 throw new SqlppParseException(getSourceLocation(hintToken), "Selectivity has to be a decimal value greater than 0 and less than 1");
Vijay Sarathy7ba271a2023-03-09 08:07:43 -0800704 }
705 return new PredicateCardinalityAnnotation(selectivity);
706 }
707 case JOIN_PREDICATE_PRODUCTIVITY_HINT:
708 if (hintToken.hintParams == null) {
709 throw new SqlppParseException(getSourceLocation(hintToken), "Expected productivity collection name and value");
710 }
711 else {
712 productivity = 1.0; // uninitialized
713 String leftSideDataSet = null;
714 Matcher StringNum = stringNumber.matcher(hintToken.hintParams);
715 if (StringNum.find()) {
716 String matchedGroup = StringNum.group();
717 Pattern var = Pattern.compile("[a-zA-Z]\\w*"); // any word character [a-zA-Z_0-9]
718 Matcher matVar = var.matcher(matchedGroup);
719 if (matVar.find()) {
720 leftSideDataSet = matVar.group();
721 }
722 else {
723 throw new SqlppParseException(getSourceLocation(hintToken), "Expected productivity collection name");
724 }
725 Matcher numMat = number.matcher(matchedGroup);
726 if (numMat.find()) {
727 productivity = Double.parseDouble (numMat.group());
728 }
729 else {
Vijay Sarathyc70bae02023-03-13 13:24:05 -0700730 throw new SqlppParseException(getSourceLocation(hintToken), "Productivity has to be a decimal value greater than 0");
Vijay Sarathy7ba271a2023-03-09 08:07:43 -0800731 }
732 }
733 else {
734 throw new SqlppParseException(getSourceLocation(hintToken), "Invalid format for productivity values");
735 }
736 // attach hint to global scope
737 return new JoinProductivityAnnotation (productivity, leftSideDataSet);
738 }
Dmitry Lychagin6fd8ab32020-12-03 09:04:14 -0800739 case HASH_BROADCAST_JOIN_HINT:
Vijay Sarathy691e93b2022-11-20 14:31:47 -0800740 if (hintToken.hintParams == null) {
741 return new BroadcastExpressionAnnotation(BroadcastExpressionAnnotation.BroadcastSide.RIGHT);
742 }
743 else {
744 // if parameter parsing fails then ignore this hint.
745 String name = parseBroadcastJoinParams(hintToken.hintParams);
746 return new BroadcastExpressionAnnotation(name);
747 }
Vijay Sarathy243ef2a2022-08-23 11:56:56 -0700748 case HASH_JOIN_HINT:
Vijay Sarathy691e93b2022-11-20 14:31:47 -0800749 if (hintToken.hintParams == null) {
750 throw new SqlppParseException(getSourceLocation(hintToken), "Expected hash join build/probe collection name");
751 }
752 else {
753 // if parameter parsing fails then ignore this hint.
754 Pair<HashJoinExpressionAnnotation.BuildOrProbe, String> pair = parseHashJoinParams(hintToken.hintParams);
755 return new HashJoinExpressionAnnotation(pair);
756 }
Dmitry Lychagin6fd8ab32020-12-03 09:04:14 -0800757 case INDEXED_NESTED_LOOP_JOIN_HINT:
758 if (hintToken.hintParams == null) {
759 return IndexedNLJoinExpressionAnnotation.INSTANCE_ANY_INDEX;
760 } else {
Dmitry Lychagin7c624522020-12-04 18:01:45 -0800761 // if parameter parsing fails then return hint annotation without parameters
762 onParseErrorReturn = IndexedNLJoinExpressionAnnotation.INSTANCE_ANY_INDEX;
Dmitry Lychagin6fd8ab32020-12-03 09:04:14 -0800763 List<String> indexNames = parseParenthesizedIdentifierList(hintToken.hintParams);
764 return IndexedNLJoinExpressionAnnotation.newInstance(indexNames);
765 }
766 case RANGE_HINT:
767 Expression rangeExpr = parseExpression(hintToken.hintParams);
768 RangeMap rangeMap = RangeMapBuilder.parseHint(rangeExpr);
769 return new RangeAnnotation(rangeMap);
770 case SKIP_SECONDARY_INDEX_SEARCH_HINT:
771 if (hintToken.hintParams == null) {
772 return SkipSecondaryIndexSearchExpressionAnnotation.INSTANCE_ANY_INDEX;
773 } else {
Dmitry Lychagin7c624522020-12-04 18:01:45 -0800774 // if parameter parsing fails then ignore this hint
Dmitry Lychagin6fd8ab32020-12-03 09:04:14 -0800775 List<String> indexNames = parseParenthesizedIdentifierList(hintToken.hintParams);
776 return SkipSecondaryIndexSearchExpressionAnnotation.newInstance(indexNames);
777 }
Tin Vu4f1090d2021-09-21 02:06:32 -0700778 case SPATIAL_JOIN_HINT:
779 List<Literal> hintValues = parseParenthesizedLiteralList(hintToken.hintParams);
780
781 // Handle exceptions
782 if (hintValues.size() != 6) {
783 throw new SqlppParseException(getSourceLocation(hintToken), String.format("Unexpected hint: %s. 6 arguments are required.",
784 hintToken.hint.toString()));
785 }
786
787 for (int i = 0; i < 4; i++) {
788 Literal lit = hintValues.get(i);
789 if ((lit.getLiteralType() != Literal.Type.DOUBLE)
790 && (lit.getLiteralType() != Literal.Type.FLOAT)
791 && (lit.getLiteralType() != Literal.Type.LONG)
792 && (lit.getLiteralType() != Literal.Type.INTEGER)){
793 throw new SqlppParseException(getSourceLocation(hintToken), String.format("Unexpected hint: %s. Numeric value is required for first 4 arguments.",
794 hintToken.hint.toString()));
795 }
796 }
797
798 for (int i = 4; i < 6; i++) {
799 Literal lit = hintValues.get(i);
800 if ((lit.getLiteralType() != Literal.Type.LONG)
801 && (lit.getLiteralType() != Literal.Type.INTEGER)) {
802 throw new SqlppParseException(getSourceLocation(hintToken), String.format("Unexpected hint: %s. Long/int is required for last 2 arguments.",
803 hintToken.hint.toString()));
804 }
805 }
806
807 try {
808 double minX = ExpressionUtils.getDoubleValue(hintValues.get(0));
809 double minY = ExpressionUtils.getDoubleValue(hintValues.get(1));
810 double maxX = ExpressionUtils.getDoubleValue(hintValues.get(2));
811 double maxY = ExpressionUtils.getDoubleValue(hintValues.get(3));
812 int numRows = (int) ExpressionUtils.getLongValue(hintValues.get(4));
813 int numColumns = (int) ExpressionUtils.getLongValue(hintValues.get(5));
814 SpatialJoinAnnotation spatialJoinAnn = new SpatialJoinAnnotation(minX, minY, maxX, maxY, numRows, numColumns);
815 return spatialJoinAnn;
816 } catch (TypeMismatchException e) {
817 throw new SqlppParseException(getSourceLocation(hintToken), e.getMessage());
818 }
Dmitry Lychagin6fd8ab32020-12-03 09:04:14 -0800819 case USE_SECONDARY_INDEX_SEARCH_HINT:
820 if (hintToken.hintParams == null) {
Dmitry Lychagin7c624522020-12-04 18:01:45 -0800821 throw new SqlppParseException(getSourceLocation(hintToken), "Expected index name(s)");
Dmitry Lychagin6fd8ab32020-12-03 09:04:14 -0800822 } else {
Dmitry Lychagin7c624522020-12-04 18:01:45 -0800823 // if parameter parsing fails then ignore this hint
Dmitry Lychagin6fd8ab32020-12-03 09:04:14 -0800824 List<String> indexNames = parseParenthesizedIdentifierList(hintToken.hintParams);
825 return SecondaryIndexSearchPreferenceAnnotation.newInstance(indexNames);
826 }
827 default:
Dmitry Lychagin7c624522020-12-04 18:01:45 -0800828 throw new SqlppParseException(getSourceLocation(hintToken), "Unexpected hint");
Dmitry Lychagin6fd8ab32020-12-03 09:04:14 -0800829 }
Dmitry Lychagin7c624522020-12-04 18:01:45 -0800830 } catch (SqlppParseException e) {
831 if (warningCollector.shouldWarn()) {
Michael Blow7c838de2021-02-23 16:12:48 -0500832 warningCollector.warn(Warning.of(getSourceLocation(hintToken), ErrorCode.INVALID_HINT,
Dmitry Lychagin7c624522020-12-04 18:01:45 -0800833 hintToken.hint.toString(), e.getMessage()));
834 }
835 return onParseErrorReturn;
Dmitry Lychagin6fd8ab32020-12-03 09:04:14 -0800836 } catch (CompilationException e) {
Dmitry Lychagin7c624522020-12-04 18:01:45 -0800837 if (warningCollector.shouldWarn()) {
Michael Blow7c838de2021-02-23 16:12:48 -0500838 warningCollector.warn(Warning.of(getSourceLocation(hintToken), ErrorCode.INVALID_HINT,
Dmitry Lychagin7c624522020-12-04 18:01:45 -0800839 hintToken.hint.toString(), e.getMessage()));
840 }
841 return onParseErrorReturn;
Dmitry Lychagin6fd8ab32020-12-03 09:04:14 -0800842 }
843 }
844
Dmitry Lychaginf7bc6c12020-06-01 18:19:44 -0700845 private void ensureNoTypeDeclsInFunction(String fnName, List<Pair<VarIdentifier, TypeExpression>> paramList,
846 TypeExpression returnType, Token startToken) throws SqlppParseException {
847 for (Pair<VarIdentifier, TypeExpression> p : paramList) {
848 if (p.second != null) {
849 String paramName = SqlppVariableUtil.toUserDefinedName(p.first.getValue());
850 throw new SqlppParseException(getSourceLocation(startToken),
851 "Unexpected type declaration for parameter " + paramName + " in function " + fnName);
852 }
853 }
854 if (returnType != null) {
855 throw new SqlppParseException(getSourceLocation(startToken),
856 "Unexpected return type declaration for function " + fnName);
857 }
858 }
Dmitry Lychagin0a722532020-08-27 18:39:25 -0700859
860 private void ensureIntegerLiteral(LiteralExpr expr, String errorPrefix) throws SqlppParseException {
861 Literal lit = expr.getValue();
862 if (lit.getLiteralType() != Literal.Type.INTEGER && lit.getLiteralType() != Literal.Type.LONG) {
863 throw new SqlppParseException(expr.getSourceLocation(), errorPrefix + " should be an INTEGER");
864 }
865 }
Dmitry Lychagin13a40e12021-04-08 18:22:57 -0700866
867 private DataverseName createDataverseName(List<String> parts, int fromIndex, int toIndex, Token startToken)
868 throws SqlppParseException {
869 try {
870 return DataverseName.create(parts, fromIndex, toIndex);
871 } catch (AsterixException e) {
872 SqlppParseException pe = new SqlppParseException(getSourceLocation(startToken), e.getMessage());
873 pe.initCause(e);
874 throw pe;
875 }
876 }
Yingyi Bu391f09e2015-10-29 13:49:39 -0700877}
878
879PARSER_END(SQLPPParser)
880
Yingyi Bu391f09e2015-10-29 13:49:39 -0700881List<Statement> Statement() throws ParseException:
882{
883 scopeStack.push(RootScopeFactory.createRootScope(this));
884 List<Statement> decls = new ArrayList<Statement>();
885 Statement stmt = null;
886}
887{
Murtadha Hubaildc775222017-08-21 15:22:45 +0300888 (
Dmitry Lychaginaebd0312019-06-04 08:55:39 -0700889 (stmt = ExplainStatement()
Murtadha Hubaildc775222017-08-21 15:22:45 +0300890 {
891 decls.add(stmt);
892 }
893 )?
894 (<SEMICOLON>)+
Yingyi Bu391f09e2015-10-29 13:49:39 -0700895 )*
896 <EOF>
897 {
898 return decls;
899 }
900}
901
Dmitry Lychaginaebd0312019-06-04 08:55:39 -0700902Statement ExplainStatement() throws ParseException:
903{
904 Statement stmt = null;
905 Token explainToken = null;
906}
907{
908 ( <EXPLAIN> { explainToken = token; } )?
909 stmt = SingleStatement()
910 {
911 if (explainToken != null) {
912 if (stmt.getKind() == Statement.Kind.QUERY) {
913 ((Query)stmt).setExplain(true);
914 } else {
915 throw new SqlppParseException(getSourceLocation(explainToken),
916 "EXPLAIN is not supported for this kind of statement");
917 }
918 }
919 return stmt;
920 }
921}
922
Yingyi Bu391f09e2015-10-29 13:49:39 -0700923Statement SingleStatement() throws ParseException:
924{
925 Statement stmt = null;
926}
927{
928 (
929 stmt = DataverseDeclaration()
930 | stmt = FunctionDeclaration()
931 | stmt = CreateStatement()
932 | stmt = LoadStatement()
933 | stmt = DropStatement()
934 | stmt = WriteStatement()
935 | stmt = SetStatement()
936 | stmt = InsertStatement()
937 | stmt = DeleteStatement()
938 | stmt = UpdateStatement()
Yingyi Bucb5bf332017-01-02 22:19:50 -0800939 | stmt = UpsertStatement()
Yingyi Buab817482016-08-19 21:29:31 -0700940 | stmt = ConnectionStatement()
Yingyi Bu391f09e2015-10-29 13:49:39 -0700941 | stmt = CompactStatement()
Dmitry Lychaginf3eec282022-06-10 12:44:25 -0700942 | stmt = AnalyzeStatement()
Dmitry Lychaginaebd0312019-06-04 08:55:39 -0700943 | stmt = Query()
Yingyi Bu391f09e2015-10-29 13:49:39 -0700944 | stmt = RefreshExternalDatasetStatement()
Yingyi Bu391f09e2015-10-29 13:49:39 -0700945 )
946 {
947 return stmt;
948 }
949}
950
951DataverseDecl DataverseDeclaration() throws ParseException:
952{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -0700953 Token startToken = null;
Dmitry Lychagin13a40e12021-04-08 18:22:57 -0700954 DataverseName dvName = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -0700955}
956{
Dmitry Lychagin13a40e12021-04-08 18:22:57 -0700957 <USE> { startToken = token; } dvName = DataverseName()
Yingyi Bu391f09e2015-10-29 13:49:39 -0700958 {
Dmitry Lychagin13a40e12021-04-08 18:22:57 -0700959 defaultDataverse = dvName;
Dmitry Lychagin54c06012019-11-13 15:54:20 -0800960 DataverseDecl dvDecl = new DataverseDecl(defaultDataverse);
Dmitry Lychagin5c26b422018-06-01 10:22:16 -0700961 return addSourceLocation(dvDecl, startToken);
Yingyi Bu391f09e2015-10-29 13:49:39 -0700962 }
963}
964
965Statement CreateStatement() throws ParseException:
966{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -0700967 Token startToken = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -0700968 Statement stmt = null;
969}
970{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -0700971 <CREATE> { startToken = token; }
Yingyi Bu391f09e2015-10-29 13:49:39 -0700972 (
Dmitry Lychagindcb4ad22020-08-26 15:49:09 -0700973 stmt = CreateOrReplaceStatement(startToken)
974 | stmt = CreateTypeStatement(startToken)
Dmitry Lychagin314e2792019-11-26 14:35:42 -0800975 | stmt = CreateNodegroupStatement(startToken)
976 | stmt = CreateDatasetStatement(startToken)
977 | stmt = CreateIndexStatement(startToken)
978 | stmt = CreateDataverseStatement(startToken)
Dmitry Lychagindcb4ad22020-08-26 15:49:09 -0700979 | stmt = CreateFunctionStatement(startToken, false)
Ian Maxon38fe9402020-01-29 19:27:40 -0800980 | stmt = CreateAdapterStatement(startToken)
Dmitry Lychagin2a0848e2020-01-08 13:57:22 -0800981 | stmt = CreateSynonymStatement(startToken)
Dmitry Lychagin314e2792019-11-26 14:35:42 -0800982 | stmt = CreateFeedStatement(startToken)
983 | stmt = CreateFeedPolicyStatement(startToken)
Rui Guoe6986dd2020-11-25 19:50:06 -0800984 | stmt = CreateFullTextStatement(startToken)
Dmitry Lychagin793c39e2021-04-21 16:52:10 -0700985 | stmt = CreateViewStatement(startToken, false)
Yingyi Bu391f09e2015-10-29 13:49:39 -0700986 )
987 {
988 return stmt;
989 }
990}
991
Dmitry Lychagindcb4ad22020-08-26 15:49:09 -0700992Statement CreateOrReplaceStatement(Token startStmtToken) throws ParseException:
993{
994 Statement stmt = null;
995 Token replaceToken = null;
996}
997{
998 <OR> <IDENTIFIER> { replaceToken = token; }
999 (
1000 stmt = CreateFunctionStatement(startStmtToken, true)
Dmitry Lychagin793c39e2021-04-21 16:52:10 -07001001 | stmt = CreateViewStatement(startStmtToken, true)
Dmitry Lychagindcb4ad22020-08-26 15:49:09 -07001002 )
1003 {
1004 // check expected token here to make the grammar extension plugin happy
1005 expectToken(replaceToken, REPLACE);
1006 return stmt;
1007 }
1008}
1009
Dmitry Lychagin314e2792019-11-26 14:35:42 -08001010TypeDecl CreateTypeStatement(Token startStmtToken) throws ParseException:
1011{
1012 TypeDecl stmt = null;
1013}
1014{
1015 <TYPE> stmt = TypeSpecification(startStmtToken)
1016 {
1017 return stmt;
1018 }
1019}
1020
Dmitry Lychagine77cdac2019-08-05 11:37:47 -07001021TypeDecl TypeSpecification(Token startStmtToken) throws ParseException:
Yingyi Bu391f09e2015-10-29 13:49:39 -07001022{
Dmitry Lychagin54c06012019-11-13 15:54:20 -08001023 Pair<DataverseName,Identifier> nameComponents = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07001024 boolean ifNotExists = false;
1025 TypeExpression typeExpr = null;
1026}
1027{
Dmitry Lychagin314e2792019-11-26 14:35:42 -08001028 nameComponents = TypeName() ifNotExists = IfNotExists()
Till Westmannf6028272016-09-30 14:34:42 -07001029 <AS> typeExpr = RecordTypeDef()
Dmitry Lychagin314e2792019-11-26 14:35:42 -08001030 {
1031 boolean dgen = false;
1032 long numValues = -1;
1033 String filename = null;
1034 Token hintToken = fetchHint(startStmtToken, SqlppHint.DGEN_HINT);
1035 if (hintToken != null) {
1036 String hintParams = hintToken.hintParams;
1037 String[] splits = hintParams != null ? hintParams.split("\\s+") : null;
1038 if (splits == null || splits.length != 2) {
1039 throw new SqlppParseException(getSourceLocation(hintToken),
1040 "Expecting /*+ dgen <filename> <numberOfItems> */");
1041 }
1042 dgen = true;
1043 filename = splits[0];
1044 numValues = Long.parseLong(splits[1]);
Yingyi Bu391f09e2015-10-29 13:49:39 -07001045 }
Dmitry Lychagin314e2792019-11-26 14:35:42 -08001046 TypeDataGen tddg = new TypeDataGen(dgen, filename, numValues);
1047 TypeDecl stmt = new TypeDecl(nameComponents.first, nameComponents.second, typeExpr, tddg, ifNotExists);
1048 return addSourceLocation(stmt, startStmtToken);
1049 }
1050}
1051
1052NodegroupDecl CreateNodegroupStatement(Token startStmtToken) throws ParseException:
1053{
1054 NodegroupDecl stmt = null;
1055}
1056{
1057 <NODEGROUP> stmt = NodegroupSpecification(startStmtToken)
1058 {
1059 return stmt;
1060 }
Yingyi Bu391f09e2015-10-29 13:49:39 -07001061}
1062
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07001063NodegroupDecl NodegroupSpecification(Token startStmtToken) throws ParseException:
Yingyi Bu391f09e2015-10-29 13:49:39 -07001064{
1065 String name = null;
1066 String tmp = null;
1067 boolean ifNotExists = false;
Dmitry Lychagin314e2792019-11-26 14:35:42 -08001068 List<Identifier> ncNames = new ArrayList<Identifier>();
Yingyi Bu391f09e2015-10-29 13:49:39 -07001069}
1070{
Dmitry Lychagin314e2792019-11-26 14:35:42 -08001071 name = Identifier() ifNotExists = IfNotExists()
1072 <ON> tmp = Identifier()
1073 {
1074 ncNames.add(new Identifier(tmp));
1075 }
Yingyi Bu391f09e2015-10-29 13:49:39 -07001076 ( <COMMA> tmp = Identifier()
1077 {
1078 ncNames.add(new Identifier(tmp));
1079 }
1080 )*
Dmitry Lychagin314e2792019-11-26 14:35:42 -08001081 {
1082 NodegroupDecl stmt = new NodegroupDecl(new Identifier(name), ncNames, ifNotExists);
1083 return addSourceLocation(stmt, startStmtToken);
1084 }
1085}
1086
1087void Dataset() throws ParseException:
1088{
1089}
1090{
1091 (<DATASET>|<COLLECTION>)
1092}
1093
Ali Alsuliman7e5c5742022-11-18 12:21:13 -08001094void DatasetToken() throws ParseException:
1095{
1096}
1097{
1098 Dataset()
1099}
1100
Dmitry Lychagin314e2792019-11-26 14:35:42 -08001101DatasetDecl CreateDatasetStatement(Token startStmtToken) throws ParseException:
1102{
1103 DatasetDecl stmt = null;
1104}
1105{
1106 (
1107 (<INTERNAL>)? Dataset() stmt = DatasetSpecification(startStmtToken)
1108 | <EXTERNAL> Dataset() stmt = ExternalDatasetSpecification(startStmtToken)
1109 )
1110 {
1111 return stmt;
1112 }
Yingyi Bu391f09e2015-10-29 13:49:39 -07001113}
1114
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07001115DatasetDecl DatasetSpecification(Token startStmtToken) throws ParseException:
Yingyi Bu391f09e2015-10-29 13:49:39 -07001116{
Dmitry Lychagin54c06012019-11-13 15:54:20 -08001117 Pair<DataverseName,Identifier> nameComponents = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07001118 boolean ifNotExists = false;
Dmitry Lychagin3e2623c2020-04-01 11:20:04 -07001119 TypeExpression typeExpr = null;
1120 TypeExpression metaTypeExpr = null;
Yingyi Buc9bfe252016-03-01 00:02:40 -08001121 Pair<List<Integer>, List<List<String>>> primaryKeyFields = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07001122 Map<String,String> hints = new HashMap<String,String>();
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07001123 DatasetDecl stmt = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07001124 boolean autogenerated = false;
Yingyi Buc9bfe252016-03-01 00:02:40 -08001125 Pair<Integer, List<String>> filterField = null;
Till Westmannf3aa19f2017-12-01 17:42:35 -08001126 RecordConstructor withRecord = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07001127}
1128{
Dmitry Lychagin314e2792019-11-26 14:35:42 -08001129 nameComponents = QualifiedName()
Dmitry Lychagin5cc254a2020-05-08 17:12:47 -07001130 typeExpr = DatasetTypeSpecification()
Yingyi Bu391f09e2015-10-29 13:49:39 -07001131 (
Dmitry Lychagin314e2792019-11-26 14:35:42 -08001132 { String name; }
1133 <WITH>
1134 name = Identifier()
Yingyi Bu391f09e2015-10-29 13:49:39 -07001135 {
Dmitry Lychagin314e2792019-11-26 14:35:42 -08001136 if (!name.equalsIgnoreCase("meta")){
1137 throw new SqlppParseException(getSourceLocation(startStmtToken),
1138 "We can only support one additional associated field called \"meta\".");
1139 }
Yingyi Bu391f09e2015-10-29 13:49:39 -07001140 }
Dmitry Lychagin5cc254a2020-05-08 17:12:47 -07001141 metaTypeExpr = DatasetTypeSpecification()
Dmitry Lychagin314e2792019-11-26 14:35:42 -08001142 )?
1143 ifNotExists = IfNotExists()
1144 primaryKeyFields = PrimaryKey()
1145 (<AUTOGENERATED> { autogenerated = true; } )?
Dmitry Lychagin314e2792019-11-26 14:35:42 -08001146 ( <HINTS> hints = Properties() )?
1147 ( LOOKAHEAD(2) <WITH> <FILTER> <ON> filterField = NestedField() )?
1148 ( <WITH> withRecord = RecordConstructor() )?
1149 {
Dmitry Lychagin314e2792019-11-26 14:35:42 -08001150 try {
Xikui Wangca7927f2020-09-03 11:27:57 -07001151 InternalDetailsDecl idd = new InternalDetailsDecl(primaryKeyFields.second, primaryKeyFields.first, autogenerated,
1152 filterField == null? null : filterField.first, filterField == null? null : filterField.second);
Dmitry Lychagin4fb583d2021-11-10 17:25:28 -08001153 DatasetDeclParametersUtil.adjustInlineTypeDecl(typeExpr, primaryKeyFields.second, primaryKeyFields.first, false);
1154 if (metaTypeExpr != null) {
1155 DatasetDeclParametersUtil.adjustInlineTypeDecl(metaTypeExpr, primaryKeyFields.second, primaryKeyFields.first,
1156 true);
1157 }
Murtadha Hubail353e95f2020-08-24 22:18:04 +03001158 stmt = new DatasetDecl(nameComponents.first, nameComponents.second, typeExpr, metaTypeExpr, hints,
1159 DatasetType.INTERNAL, idd, withRecord, ifNotExists);
Dmitry Lychagin314e2792019-11-26 14:35:42 -08001160 return addSourceLocation(stmt, startStmtToken);
1161 } catch (CompilationException e) {
1162 throw new SqlppParseException(getSourceLocation(startStmtToken), e.getMessage());
1163 }
1164 }
1165}
1166
1167DatasetDecl ExternalDatasetSpecification(Token startStmtToken) throws ParseException:
1168{
1169 Pair<DataverseName,Identifier> nameComponents = null;
Dmitry Lychagin5cc254a2020-05-08 17:12:47 -07001170 TypeExpression typeExpr = null;
Dmitry Lychagin314e2792019-11-26 14:35:42 -08001171 boolean ifNotExists = false;
Dmitry Lychagin314e2792019-11-26 14:35:42 -08001172 String adapterName = null;
1173 Map<String,String> properties = null;
Dmitry Lychagin314e2792019-11-26 14:35:42 -08001174 Map<String,String> hints = new HashMap<String,String>();
1175 DatasetDecl stmt = null;
Dmitry Lychagin314e2792019-11-26 14:35:42 -08001176 RecordConstructor withRecord = null;
1177}
1178{
1179 nameComponents = QualifiedName()
Dmitry Lychagin5cc254a2020-05-08 17:12:47 -07001180 typeExpr = DatasetTypeSpecification()
Dmitry Lychagin314e2792019-11-26 14:35:42 -08001181 ifNotExists = IfNotExists()
1182 <USING> adapterName = AdapterName() properties = Configuration()
Dmitry Lychagin314e2792019-11-26 14:35:42 -08001183 ( <HINTS> hints = Properties() )?
1184 ( <WITH> withRecord = RecordConstructor() )?
1185 {
1186 ExternalDetailsDecl edd = new ExternalDetailsDecl();
1187 edd.setAdapter(adapterName);
1188 edd.setProperties(properties);
1189 try {
Murtadha Hubail353e95f2020-08-24 22:18:04 +03001190 stmt = new DatasetDecl(nameComponents.first, nameComponents.second, typeExpr, null, hints, DatasetType.EXTERNAL,
1191 edd, withRecord, ifNotExists);
Dmitry Lychagin314e2792019-11-26 14:35:42 -08001192 return addSourceLocation(stmt, startStmtToken);
1193 } catch (CompilationException e) {
1194 throw new SqlppParseException(getSourceLocation(startStmtToken), e.getMessage());
1195 }
1196 }
Yingyi Bu391f09e2015-10-29 13:49:39 -07001197}
1198
Dmitry Lychagin3e2623c2020-04-01 11:20:04 -07001199TypeExpression DatasetTypeSpecification() throws ParseException:
1200{
1201 TypeExpression typeExpr = null;
1202}
1203{
1204 (
1205 LOOKAHEAD(3) typeExpr = DatasetRecordTypeSpecification(true)
1206 | typeExpr = DatasetReferenceTypeSpecification()
1207 )
1208 {
1209 return typeExpr;
1210 }
1211}
1212
1213TypeExpression DatasetReferenceTypeSpecification() throws ParseException:
1214{
1215 TypeExpression typeExpr = null;
1216}
1217{
1218 <LEFTPAREN> typeExpr = TypeReference() <RIGHTPAREN>
1219 {
1220 return typeExpr;
1221 }
1222}
1223
Dmitry Lychagin33c77f92021-07-21 15:59:04 -07001224RecordTypeDefinition DatasetRecordTypeSpecification(boolean allowRecordKindModifier) throws ParseException:
Dmitry Lychagin3e2623c2020-04-01 11:20:04 -07001225{
1226 RecordTypeDefinition recordTypeDef = null;
1227 RecordTypeDefinition.RecordKind recordKind = null;
Dmitry Lychagin6c239e72020-06-19 19:46:27 -07001228 Token startToken = null, recordKindToken = null;
Dmitry Lychagin3e2623c2020-04-01 11:20:04 -07001229}
1230{
Dmitry Lychagin6c239e72020-06-19 19:46:27 -07001231 <LEFTPAREN> { startToken = token; } recordTypeDef = DatasetRecordTypeDef() <RIGHTPAREN>
Dmitry Lychagin3e2623c2020-04-01 11:20:04 -07001232 ( recordKind = RecordTypeKind() { recordKindToken = token; } <TYPE> )?
1233 {
1234 if (recordKind == null) {
1235 recordKind = RecordTypeDefinition.RecordKind.CLOSED;
1236 } else if (!allowRecordKindModifier) {
1237 throw createUnexpectedTokenError(recordKindToken);
1238 }
1239 recordTypeDef.setRecordKind(recordKind);
Dmitry Lychagin6c239e72020-06-19 19:46:27 -07001240 return addSourceLocation(recordTypeDef, startToken);
Dmitry Lychagin3e2623c2020-04-01 11:20:04 -07001241 }
1242}
1243
1244RecordTypeDefinition DatasetRecordTypeDef() throws ParseException:
1245{
1246 RecordTypeDefinition recType = new RecordTypeDefinition();
1247}
1248{
1249 DatasetRecordField(recType) ( <COMMA> DatasetRecordField(recType) )*
1250 {
1251 return recType;
1252 }
1253}
1254
1255void DatasetRecordField(RecordTypeDefinition recType) throws ParseException:
1256{
1257 String fieldName;
1258 TypeExpression type = null;
Dmitry Lychagin3a628022020-05-12 18:09:02 -07001259 boolean nullable = true, missable = true;
Dmitry Lychagin3e2623c2020-04-01 11:20:04 -07001260}
1261{
1262 fieldName = Identifier()
Dmitry Lychagin3a628022020-05-12 18:09:02 -07001263 type = TypeReference() ( <NOT> <UNKNOWN> { nullable = false; missable = false; } )?
Dmitry Lychagin3e2623c2020-04-01 11:20:04 -07001264 {
Dmitry Lychagin3a628022020-05-12 18:09:02 -07001265 recType.addField(fieldName, type, nullable, missable);
Dmitry Lychagin3e2623c2020-04-01 11:20:04 -07001266 }
1267}
1268
Yingyi Bu391f09e2015-10-29 13:49:39 -07001269RefreshExternalDatasetStatement RefreshExternalDatasetStatement() throws ParseException:
1270{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07001271 Token startToken = null;
Dmitry Lychagin54c06012019-11-13 15:54:20 -08001272 Pair<DataverseName,Identifier> nameComponents = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07001273 String datasetName = null;
1274}
1275{
Dmitry Lychagin314e2792019-11-26 14:35:42 -08001276 <REFRESH> { startToken = token; } <EXTERNAL> Dataset() nameComponents = QualifiedName()
1277 {
1278 RefreshExternalDatasetStatement stmt = new RefreshExternalDatasetStatement();
1279 stmt.setDataverseName(nameComponents.first);
1280 stmt.setDatasetName(nameComponents.second);
1281 return addSourceLocation(stmt, startToken);
1282 }
1283}
1284
1285CreateIndexStatement CreateIndexStatement(Token startStmtToken) throws ParseException:
1286{
1287 CreateIndexStatement stmt = null;
1288}
1289{
1290 (
1291 <INDEX> stmt = IndexSpecification(startStmtToken)
1292 | <PRIMARY> <INDEX> stmt = PrimaryIndexSpecification(startStmtToken)
1293 )
1294 {
1295 return stmt;
1296 }
Yingyi Bu391f09e2015-10-29 13:49:39 -07001297}
1298
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07001299CreateIndexStatement IndexSpecification(Token startStmtToken) throws ParseException:
Yingyi Bu391f09e2015-10-29 13:49:39 -07001300{
Dmitry Lychagin54c06012019-11-13 15:54:20 -08001301 Pair<DataverseName,Identifier> nameComponents = null;
Glenn67fd1f32021-02-25 16:04:49 -08001302 String indexName = null;
1303 IndexParams indexParams = null;
1304 CreateIndexStatement.IndexedElement indexedElement = null;
1305 List<CreateIndexStatement.IndexedElement> indexedElementList = new ArrayList<CreateIndexStatement.IndexedElement>();
Yingyi Bu391f09e2015-10-29 13:49:39 -07001306 boolean enforced = false;
Glenn67fd1f32021-02-25 16:04:49 -08001307 boolean ifNotExists = false;
1308 boolean hasUnnest = false;
1309 String fullTextConfigName = null;
1310 Token startElementToken = null;
Ali Alsuliman931e7382021-08-08 21:55:59 +03001311 Boolean excludeUnknown = null;
Ali Alsuliman465a7282021-11-24 12:51:32 -08001312 Pair<Map<String, String>, Boolean> castConfigDefaultNull;
Ali Alsuliman69ce7d82021-11-01 15:00:16 -07001313 Boolean castDefaultNull = null;
Ali Alsuliman465a7282021-11-24 12:51:32 -08001314 Map<String, String> castConfig = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07001315}
1316{
Ali Alsuliman8351d252017-09-24 00:43:15 -07001317 (
Dmitry Lychagin314e2792019-11-26 14:35:42 -08001318 indexName = Identifier() ifNotExists = IfNotExists()
Ali Alsuliman8351d252017-09-24 00:43:15 -07001319 <ON> nameComponents = QualifiedName()
Glenn67fd1f32021-02-25 16:04:49 -08001320 <LEFTPAREN> { startElementToken = token; }
1321 indexedElement = IndexedElement(startElementToken) {
1322 indexedElementList.add(indexedElement);
1323 hasUnnest |= indexedElement.hasUnnest();
Yingyi Bu391f09e2015-10-29 13:49:39 -07001324 }
Glenn67fd1f32021-02-25 16:04:49 -08001325 (<COMMA> { startElementToken = token; }
1326 indexedElement = IndexedElement(startElementToken) {
1327 indexedElementList.add(indexedElement);
1328 hasUnnest |= indexedElement.hasUnnest();
1329 }
1330 )*
1331 <RIGHTPAREN>
1332 ( <TYPE> indexParams = IndexType() )? ( <ENFORCED> { enforced = true; } )?
Ali Alsuliman69ce7d82021-11-01 15:00:16 -07001333 ( LOOKAHEAD({laIdentifier(EXCLUDE) || laIdentifier(INCLUDE)}) <IDENTIFIER>
1334 {
1335 if (isToken(EXCLUDE)) {
1336 excludeUnknown = true;
1337 } else if (isToken(INCLUDE)) {
1338 excludeUnknown = false;
1339 } else {
1340 throw createUnexpectedTokenError();
1341 }
1342 } <UNKNOWN> <KEY>
Ali Alsuliman931e7382021-08-08 21:55:59 +03001343 )?
Ali Alsuliman69ce7d82021-11-01 15:00:16 -07001344
Ali Alsuliman465a7282021-11-24 12:51:32 -08001345 ( <CAST><LEFTPAREN> castConfigDefaultNull = CastDefaultNull() <RIGHTPAREN>
1346 {
1347 castConfig = castConfigDefaultNull.first;
1348 castDefaultNull = castConfigDefaultNull.second;
1349 }
1350 )?
Ali Alsuliman8351d252017-09-24 00:43:15 -07001351 )
1352 {
Glenn67fd1f32021-02-25 16:04:49 -08001353 IndexType indexType;
1354 int gramLength;
1355 if (indexParams != null) {
1356 indexType = indexParams.type;
1357 gramLength = indexParams.gramLength;
1358 fullTextConfigName = indexParams.fullTextConfig;
1359 } else {
1360 indexType = hasUnnest ? IndexType.ARRAY : IndexType.BTREE;
1361 gramLength = -1;
1362 fullTextConfigName = null;
Ali Alsuliman8351d252017-09-24 00:43:15 -07001363 }
Glenn67fd1f32021-02-25 16:04:49 -08001364 CreateIndexStatement stmt = new CreateIndexStatement(nameComponents.first, nameComponents.second,
Ali Alsuliman931e7382021-08-08 21:55:59 +03001365 new Identifier(indexName), indexType, indexedElementList, enforced, gramLength, fullTextConfigName, ifNotExists,
Ali Alsuliman465a7282021-11-24 12:51:32 -08001366 excludeUnknown, castDefaultNull, castConfig);
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07001367 return addSourceLocation(stmt, startStmtToken);
Ali Alsuliman8351d252017-09-24 00:43:15 -07001368 }
Yingyi Bu391f09e2015-10-29 13:49:39 -07001369}
1370
Glenn67fd1f32021-02-25 16:04:49 -08001371CreateIndexStatement.IndexedElement IndexedElement(Token startElementToken) throws ParseException:
1372{
1373 Triple<Integer, List<List<String>>, List<Pair<List<String>, IndexedTypeExpression>>> element = null;
1374 Pair<List<String>, IndexedTypeExpression> elementSimple = null;
1375 int elementSimpleSource = 0;
1376}
1377{
1378 (
1379 element = IndexedElementUnnestSelect()
1380 | (
1381 LOOKAHEAD({ laIdentifier(META) && laToken(2, LEFTPAREN) && laToken(3, RIGHTPAREN) })
1382 <IDENTIFIER> { expectToken(META); } <LEFTPAREN> <RIGHTPAREN>
1383 <DOT> elementSimple = IndexedField()
1384 { elementSimpleSource = 1; }
1385 )
1386 | elementSimple = IndexedField()
1387 | <LEFTPAREN> ( element = IndexedElementUnnestSelect() | elementSimple = IndexedField() ) <RIGHTPAREN>
1388 )
1389 {
1390 int source;
1391 List<List<String>> unnestList;
1392 List<Pair<List<String>, IndexedTypeExpression>> projectList;
1393 if (elementSimple != null) {
1394 source = elementSimpleSource;
1395 unnestList = null;
1396 projectList = Collections.singletonList(elementSimple);
1397 } else {
1398 source = element.first;
1399 unnestList = element.second;
1400 projectList = element.third;
1401 }
1402 CreateIndexStatement.IndexedElement ie = new CreateIndexStatement.IndexedElement(source, unnestList, projectList);
1403 ie.setSourceLocation(getSourceLocation(startElementToken));
1404 return ie;
1405 }
1406}
1407
1408Triple<Integer, List<List<String>>, List<Pair<List<String>, IndexedTypeExpression>>> IndexedElementUnnestSelect()
1409 throws ParseException:
1410{
1411 int source = 0;
1412 Pair<List<List<String>>, List<Pair<List<String>, IndexedTypeExpression>>> element = null;
1413}
1414{
1415 <UNNEST>
1416 (
1417 (
1418 LOOKAHEAD({ laIdentifier(META) && laToken(2, LEFTPAREN) && laToken(3, RIGHTPAREN) })
1419 <IDENTIFIER> { expectToken(META); } <LEFTPAREN> <RIGHTPAREN>
1420 <DOT> element = IndexedElementUnnestSelectBody() { source = 1; }
1421 ) | element = IndexedElementUnnestSelectBody()
1422 )
1423 {
1424 return new Triple<Integer, List<List<String>>, List<Pair<List<String>, IndexedTypeExpression>>>(
1425 source, element.first, element.second
1426 );
1427 }
1428}
1429
1430Pair<List<List<String>>, List<Pair<List<String>, IndexedTypeExpression>>> IndexedElementUnnestSelectBody()
1431 throws ParseException:
1432{
Dmitry Lychaginb9393132021-04-12 17:21:22 -07001433 Triple<List<String>, Token, Token> path = null;
Glenn67fd1f32021-02-25 16:04:49 -08001434 IndexedTypeExpression type = null;
1435 List<List<String>> unnestList = new ArrayList();
Glenn67fd1f32021-02-25 16:04:49 -08001436 List<Pair<List<String>, IndexedTypeExpression>> projectList = new ArrayList();
1437}
1438{
Dmitry Lychaginb9393132021-04-12 17:21:22 -07001439 path = MultipartIdentifier() { unnestList.add(path.first); }
1440 ( <UNNEST> path = MultipartIdentifier() { unnestList.add(path.first); })*
Glenn67fd1f32021-02-25 16:04:49 -08001441 (
Glenn58329202021-04-09 12:03:46 -07001442 ( <COLON> type = IndexedTypeExpr(false)
Glenn67fd1f32021-02-25 16:04:49 -08001443 {
1444 projectList.add(new Pair<List<String>, IndexedTypeExpression>(null, type));
1445 }
1446 ) |
1447 (
Glenn58329202021-04-09 12:03:46 -07001448 <SELECT> path = MultipartIdentifier() ( <COLON> type = IndexedTypeExpr(false) )?
1449 {
Dmitry Lychaginb9393132021-04-12 17:21:22 -07001450 projectList.add(new Pair<List<String>, IndexedTypeExpression>(path.first, type));
Glenn58329202021-04-09 12:03:46 -07001451 }
1452 ( <COMMA> path = MultipartIdentifier() ( <COLON> type = IndexedTypeExpr(false) )?
1453 {
Dmitry Lychaginb9393132021-04-12 17:21:22 -07001454 projectList.add(new Pair<List<String>, IndexedTypeExpression>(path.first, type));
Glenn58329202021-04-09 12:03:46 -07001455 }
1456 )*
Glenn67fd1f32021-02-25 16:04:49 -08001457 )
1458 )?
1459 {
1460 if (projectList.isEmpty()) {
1461 // To support the case (<UNNEST> IDENTIFIER)* IDENTIFIER w/o any type specification.
1462 projectList.add(new Pair<List<String>, IndexedTypeExpression>(null, null));
1463 }
1464
1465 return new Pair<List<List<String>>, List<Pair<List<String>, IndexedTypeExpression>>>(unnestList, projectList);
1466 }
1467}
1468
1469Pair<List<String>, IndexedTypeExpression> IndexedField() throws ParseException:
1470{
Dmitry Lychaginb9393132021-04-12 17:21:22 -07001471 Triple<List<String>, Token, Token> path = null;
Glenn67fd1f32021-02-25 16:04:49 -08001472 IndexedTypeExpression type = null;
1473}
1474{
Glenn58329202021-04-09 12:03:46 -07001475 path = MultipartIdentifier() ( <COLON> type = IndexedTypeExpr(true) )?
Glenn67fd1f32021-02-25 16:04:49 -08001476 {
Dmitry Lychaginb9393132021-04-12 17:21:22 -07001477 return new Pair<List<String>, IndexedTypeExpression>(path.first, type);
Glenn67fd1f32021-02-25 16:04:49 -08001478 }
1479}
1480
Dmitry Lychagin314e2792019-11-26 14:35:42 -08001481CreateIndexStatement PrimaryIndexSpecification(Token startStmtToken) throws ParseException:
1482{
Glenn67fd1f32021-02-25 16:04:49 -08001483 Pair<DataverseName,Identifier> nameComponents = null;
Dmitry Lychagin314e2792019-11-26 14:35:42 -08001484 String indexName = null;
1485 boolean ifNotExists = false;
Dmitry Lychagin314e2792019-11-26 14:35:42 -08001486}
1487{
1488 (indexName = Identifier())? ifNotExists = IfNotExists()
1489 <ON> nameComponents = QualifiedName() (<TYPE> <BTREE>)?
1490 {
1491 if (indexName == null) {
Dmitry Lychaginf3eec282022-06-10 12:44:25 -07001492 indexName = MetadataConstants.PRIMARY_INDEX_PREFIX + nameComponents.second;
Dmitry Lychagin314e2792019-11-26 14:35:42 -08001493 }
Glenn67fd1f32021-02-25 16:04:49 -08001494 CreateIndexStatement stmt = new CreateIndexStatement(nameComponents.first, nameComponents.second,
Ali Alsuliman465a7282021-11-24 12:51:32 -08001495 new Identifier(indexName), IndexType.BTREE, Collections.emptyList(), false, -1, null, ifNotExists, null, null,
1496 Collections.emptyMap());
Dmitry Lychagin314e2792019-11-26 14:35:42 -08001497 return addSourceLocation(stmt, startStmtToken);
1498 }
1499}
1500
Yingyi Bu391f09e2015-10-29 13:49:39 -07001501String FilterField() throws ParseException :
1502{
1503 String filterField = null;
1504}
1505{
1506 filterField = Identifier()
1507 {
1508 return filterField;
1509 }
1510}
1511
1512IndexParams IndexType() throws ParseException:
1513{
1514 IndexType type = null;
1515 int gramLength = 0;
Rui Guoe6986dd2020-11-25 19:50:06 -08001516 String fullTextConfig = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07001517}
1518{
1519 (<BTREE>
1520 {
1521 type = IndexType.BTREE;
1522 }
1523 | <RTREE>
1524 {
1525 type = IndexType.RTREE;
1526 }
1527 | <KEYWORD>
1528 {
1529 type = IndexType.LENGTH_PARTITIONED_WORD_INVIX;
1530 }
Rui Guoe6986dd2020-11-25 19:50:06 -08001531 | <FULLTEXT>
Taewoo Kimc49405a2017-01-04 00:30:43 -08001532 {
1533 type = IndexType.SINGLE_PARTITION_WORD_INVIX;
1534 }
Rui Guoe6986dd2020-11-25 19:50:06 -08001535 // For now we don't allow inverted index creation using a full-text config in another data verse.
1536 // We may want to support corss-dataverse full-text config access later
1537 // If so, replace the Identifier() with QualifiedName() to get the dataverse name
1538 ( <USING> Identifier()
1539 {
1540 fullTextConfig = token.image;
1541 }
1542 )?
Yingyi Bu391f09e2015-10-29 13:49:39 -07001543 | <NGRAM> <LEFTPAREN> <INTEGER_LITERAL>
1544 {
1545 type = IndexType.LENGTH_PARTITIONED_NGRAM_INVIX;
1546 gramLength = Integer.valueOf(token.image);
1547 }
1548 <RIGHTPAREN>)
1549 {
Rui Guoe6986dd2020-11-25 19:50:06 -08001550 return new IndexParams(type, gramLength, fullTextConfig);
Yingyi Bu391f09e2015-10-29 13:49:39 -07001551 }
1552}
1553
Dmitry Lychagin314e2792019-11-26 14:35:42 -08001554CreateDataverseStatement CreateDataverseStatement(Token startStmtToken) throws ParseException :
1555{
1556 CreateDataverseStatement stmt = null;
1557}
1558{
1559 <DATAVERSE> stmt = DataverseSpecification(startStmtToken)
1560 {
1561 return stmt;
1562 }
1563}
1564
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07001565CreateDataverseStatement DataverseSpecification(Token startStmtToken) throws ParseException :
Yingyi Bu391f09e2015-10-29 13:49:39 -07001566{
Dmitry Lychagin13a40e12021-04-08 18:22:57 -07001567 DataverseName dvName = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07001568 boolean ifNotExists = false;
Yingyi Bu391f09e2015-10-29 13:49:39 -07001569}
1570{
Dmitry Lychagin13a40e12021-04-08 18:22:57 -07001571 dvName = DataverseName() ifNotExists = IfNotExists()
Dmitry Lychagin314e2792019-11-26 14:35:42 -08001572 {
Dmitry Lychagin13a40e12021-04-08 18:22:57 -07001573 CreateDataverseStatement stmt = new CreateDataverseStatement(dvName, null, ifNotExists);
Dmitry Lychagin314e2792019-11-26 14:35:42 -08001574 return addSourceLocation(stmt, startStmtToken);
1575 }
1576}
1577
Ian Maxon38fe9402020-01-29 19:27:40 -08001578CreateAdapterStatement CreateAdapterStatement(Token startStmtToken) throws ParseException:
1579{
1580 CreateAdapterStatement stmt = null;
1581}
1582{
1583 <ADAPTER> stmt = AdapterSpecification(startStmtToken)
1584 {
1585 return stmt;
1586 }
1587}
1588
1589CreateAdapterStatement AdapterSpecification(Token startStmtToken) throws ParseException:
1590{
Dmitry Lychagin20905cd2020-08-06 20:34:55 -07001591 Pair<DataverseName,Identifier> adapterName = null;
1592 Pair<DataverseName,Identifier> libraryName = null;
1593 List<String> externalIdentifier = null;
Ian Maxon38fe9402020-01-29 19:27:40 -08001594 boolean ifNotExists = false;
1595}
1596{
Dmitry Lychagin20905cd2020-08-06 20:34:55 -07001597 adapterName = QualifiedName()
1598 ifNotExists = IfNotExists()
1599 <AS> externalIdentifier = FunctionExternalIdentifier()
1600 <AT> libraryName = QualifiedName()
1601 {
1602 CreateAdapterStatement stmt = new CreateAdapterStatement(adapterName.first, adapterName.second.getValue(),
1603 libraryName.first, libraryName.second.getValue(), externalIdentifier, ifNotExists);
1604 return addSourceLocation(stmt, startStmtToken);
1605 }
1606}
Ian Maxon38fe9402020-01-29 19:27:40 -08001607
Dmitry Lychagin793c39e2021-04-21 16:52:10 -07001608CreateViewStatement CreateViewStatement(Token startStmtToken, boolean orReplace) throws ParseException:
1609{
1610 CreateViewStatement stmt = null;
1611}
1612{
1613 <VIEW> stmt = ViewSpecification(startStmtToken, orReplace)
1614 {
1615 return stmt;
1616 }
1617}
1618
1619CreateViewStatement ViewSpecification(Token startStmtToken, boolean orReplace) throws ParseException:
1620{
1621 Pair<DataverseName, Identifier> nameComponents = null;
Dmitry Lychagin33c77f92021-07-21 15:59:04 -07001622 TypeExpression typeExpr = null;
Dmitry Lychagin793c39e2021-04-21 16:52:10 -07001623 boolean ifNotExists = false;
1624 Token beginPos = null, endPos = null;
1625 Expression viewBodyExpr = null;
Ali Alsuliman465a7282021-11-24 12:51:32 -08001626 Pair<Map<String, String>, Boolean> viewConfigDefaultNull;
Dmitry Lychagin33c77f92021-07-21 15:59:04 -07001627 Boolean defaultNull = null;
Dmitry Lychagin1f6f24e2021-08-19 21:41:57 -07001628 Map<String, String> viewConfig = null;
Dmitry Lychagin81578f92021-08-24 11:57:07 -07001629 Pair<List<Integer>, List<List<String>>> primaryKeyFields = null;
Dmitry Lychagin914983f2021-09-30 15:11:11 -07001630 Pair<List<Integer>, List<List<String>>> foreignKeyFields = null;
1631 Pair<DataverseName, Identifier> refNameComponents = null;
1632 List<CreateViewStatement.ForeignKeyDecl> foreignKeyDecls = null;
Dmitry Lychagin793c39e2021-04-21 16:52:10 -07001633 DataverseName currentDataverse = defaultDataverse;
1634}
1635{
1636 nameComponents = QualifiedName()
Dmitry Lychagin33c77f92021-07-21 15:59:04 -07001637 (
Dmitry Lychagin1f6f24e2021-08-19 21:41:57 -07001638 (
1639 typeExpr = DatasetTypeSpecification()
1640 ifNotExists = IfNotExists()
Ali Alsuliman465a7282021-11-24 12:51:32 -08001641 viewConfigDefaultNull = CastDefaultNull()
1642 {
1643 viewConfig = viewConfigDefaultNull.first;
1644 defaultNull = viewConfigDefaultNull.second;
1645 }
Dmitry Lychagin914983f2021-09-30 15:11:11 -07001646 (
1647 <PRIMARY> <KEY> <LEFTPAREN> primaryKeyFields = PrimaryKeyFields() <RIGHTPAREN>
1648 <NOT> <ENFORCED>
1649 )?
1650 (
1651 <IDENTIFIER> { expectToken(FOREIGN); } <KEY> <LEFTPAREN> foreignKeyFields = PrimaryKeyFields() <RIGHTPAREN>
1652 <IDENTIFIER> { expectToken(REFERENCES); } refNameComponents = QualifiedName()
1653 <NOT> <ENFORCED>
1654 {
1655 if (foreignKeyDecls == null) {
1656 foreignKeyDecls = new ArrayList<CreateViewStatement.ForeignKeyDecl>();
1657 }
1658 foreignKeyDecls.add(new CreateViewStatement.ForeignKeyDecl(foreignKeyFields.second,
1659 foreignKeyFields.first, refNameComponents.first, refNameComponents.second));
1660 }
1661 )*
Dmitry Lychagin1f6f24e2021-08-19 21:41:57 -07001662 )
1663 |
1664 ( ifNotExists = IfNotExists() )
Dmitry Lychagin33c77f92021-07-21 15:59:04 -07001665 )
Dmitry Lychagin793c39e2021-04-21 16:52:10 -07001666 {
1667 if (orReplace && ifNotExists) {
Dmitry Lychagin33c77f92021-07-21 15:59:04 -07001668 throw new SqlppParseException(getSourceLocation(startStmtToken), "Unexpected IF NOT EXISTS");
Dmitry Lychagin793c39e2021-04-21 16:52:10 -07001669 }
1670 }
1671 <AS>
1672 {
1673 beginPos = token;
1674 createNewScope();
1675 if (nameComponents.first != null) {
1676 defaultDataverse = nameComponents.first;
1677 }
1678 }
1679 viewBodyExpr = ViewBody()
1680 {
1681 endPos = token;
1682 String viewBody = extractFragment(beginPos.beginLine, beginPos.beginColumn + 1, endPos.endLine,
1683 endPos.endColumn + 1);
1684 removeCurrentScope();
1685 defaultDataverse = currentDataverse;
Dmitry Lychagin4fb583d2021-11-10 17:25:28 -08001686 if (typeExpr != null && primaryKeyFields != null) {
1687 DatasetDeclParametersUtil.adjustInlineTypeDecl(typeExpr, primaryKeyFields.second, primaryKeyFields.first, false);
1688 }
Dmitry Lychagin914983f2021-09-30 15:11:11 -07001689 CreateViewStatement.KeyDecl primaryKeyDecl = primaryKeyFields != null ?
1690 new CreateViewStatement.KeyDecl(primaryKeyFields.second, primaryKeyFields.first) : null;
1691 CreateViewStatement stmt = new CreateViewStatement(nameComponents.first, nameComponents.second.getValue(),
1692 typeExpr, viewBody, viewBodyExpr, defaultNull, viewConfig, primaryKeyDecl, foreignKeyDecls, orReplace,
1693 ifNotExists);
Dmitry Lychagin793c39e2021-04-21 16:52:10 -07001694 return addSourceLocation(stmt, startStmtToken);
1695 }
1696}
1697
1698Expression ViewBody() throws ParseException:
1699{
1700 Expression viewBodyExpr = null;
1701}
1702{
Dmitry Lychagin33c77f92021-07-21 15:59:04 -07001703 (
1704 ( viewBodyExpr = VariableRef() ( viewBodyExpr = FieldAccessor(viewBodyExpr) )* )
1705 | viewBodyExpr = SelectExpression(true)
1706 )
Dmitry Lychagin793c39e2021-04-21 16:52:10 -07001707 {
1708 return viewBodyExpr;
1709 }
1710}
1711
Ali Alsuliman465a7282021-11-24 12:51:32 -08001712Pair<Map<String, String>, Boolean> CastDefaultNull() throws ParseException:
1713{
1714 Map<String, String> castConfig = null;
1715 Boolean defaultNull = null;
1716 String propertyName = null, propertyValue = null;
1717}
1718{
1719 <IDENTIFIER> { expectToken(DEFAULT); } <NULL> { defaultNull = true; }
1720 (
1721 LOOKAHEAD(2) <IDENTIFIER> { propertyName = token.image.toLowerCase(); } propertyValue = StringLiteral()
1722 {
1723 if (castConfig == null) {
1724 castConfig = new HashMap<String, String>();
1725 }
1726 castConfig.put(propertyName, propertyValue);
1727 }
1728 )*
1729 {
1730 return new Pair<Map<String, String>, Boolean>(castConfig, defaultNull);
1731 }
1732}
1733
Dmitry Lychagindcb4ad22020-08-26 15:49:09 -07001734CreateFunctionStatement CreateFunctionStatement(Token startStmtToken, boolean orReplace) throws ParseException:
Dmitry Lychagin20905cd2020-08-06 20:34:55 -07001735{
1736 CreateFunctionStatement stmt = null;
1737}
1738{
Dmitry Lychagindcb4ad22020-08-26 15:49:09 -07001739 <FUNCTION> stmt = FunctionSpecification(startStmtToken, orReplace)
Dmitry Lychagin20905cd2020-08-06 20:34:55 -07001740 {
1741 return stmt;
1742 }
Ian Maxon38fe9402020-01-29 19:27:40 -08001743}
1744
Dmitry Lychagindcb4ad22020-08-26 15:49:09 -07001745CreateFunctionStatement FunctionSpecification(Token startStmtToken, boolean orReplace) throws ParseException:
Yingyi Bu391f09e2015-10-29 13:49:39 -07001746{
Ian Maxon38fe9402020-01-29 19:27:40 -08001747 FunctionSignature signature = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07001748 FunctionName fctName = null;
Dmitry Lychagin541652082020-11-09 14:04:53 -08001749 Pair<Integer, List<Pair<VarIdentifier,TypeExpression>>> paramsWithArity = null;
Dmitry Lychaginf7bc6c12020-06-01 18:19:44 -07001750 List<Pair<VarIdentifier,TypeExpression>> params = null;
Dmitry Lychagin541652082020-11-09 14:04:53 -08001751 int arity = 0;
Dmitry Lychagin20905cd2020-08-06 20:34:55 -07001752 TypeExpression returnType = null;
1753 Token beginPos = null, endPos = null;
1754 Expression functionBodyExpr = null;
1755 Pair<DataverseName,Identifier> libraryName = null;
1756 List<String> externalIdentifier = null;
1757 RecordConstructor withOptions = null;
1758 boolean ifNotExists = false;
1759 CreateFunctionStatement stmt = null;
1760 DataverseName currentDataverse = defaultDataverse;
Yingyi Bu391f09e2015-10-29 13:49:39 -07001761}
1762{
Dmitry Lychagin314e2792019-11-26 14:35:42 -08001763 fctName = FunctionName()
Steven Glenn Jacobs665e9fe2017-12-27 10:30:39 -08001764 {
1765 defaultDataverse = fctName.dataverse;
1766 }
Dmitry Lychagin541652082020-11-09 14:04:53 -08001767 paramsWithArity = FunctionParameters()
1768 {
1769 arity = paramsWithArity.first;
1770 params = paramsWithArity.second;
Dmitry Lychagin265e3ce2021-03-02 12:22:38 -08001771 signature = new FunctionSignature(fctName.dataverse, fctName.function, arity);
Dmitry Lychagin541652082020-11-09 14:04:53 -08001772 }
Dmitry Lychagin265e3ce2021-03-02 12:22:38 -08001773 ifNotExists = IfNotExists()
Dmitry Lychagin793c39e2021-04-21 16:52:10 -07001774 {
1775 if (orReplace && ifNotExists) {
1776 throw new SqlppParseException(getSourceLocation(token), "Unexpected IF NOT EXISTS");
1777 }
1778 }
Dmitry Lychagin0d4c1b62020-02-07 17:10:16 -08001779 returnType = FunctionReturnType()
Ian Maxon38fe9402020-01-29 19:27:40 -08001780 (
1781 (
1782 <LEFTBRACE>
1783 {
Dmitry Lychagin20905cd2020-08-06 20:34:55 -07001784 beginPos = token;
1785 createNewScope();
Ian Maxon38fe9402020-01-29 19:27:40 -08001786 }
Dmitry Lychagin45de2342020-02-03 12:01:28 -08001787 functionBodyExpr = FunctionBody()
Dmitry Lychagin20905cd2020-08-06 20:34:55 -07001788 <RIGHTBRACE>
1789 {
1790 endPos = token;
1791 String functionBody = extractFragment(beginPos.beginLine, beginPos.beginColumn, endPos.beginLine,
1792 endPos.beginColumn);
Dmitry Lychagin20905cd2020-08-06 20:34:55 -07001793 getCurrentScope().addFunctionDescriptor(signature, false);
1794 removeCurrentScope();
Dmitry Lychagin20905cd2020-08-06 20:34:55 -07001795 ensureNoTypeDeclsInFunction(fctName.function, params, returnType, startStmtToken);
Dmitry Lychagindcb4ad22020-08-26 15:49:09 -07001796 stmt = new CreateFunctionStatement(signature, params, functionBody, functionBodyExpr, orReplace, ifNotExists);
Dmitry Lychagin20905cd2020-08-06 20:34:55 -07001797 }
Ian Maxon38fe9402020-01-29 19:27:40 -08001798 )
1799 |
Dmitry Lychagin20905cd2020-08-06 20:34:55 -07001800 (
1801 <AS> externalIdentifier = FunctionExternalIdentifier()
1802 <AT> libraryName = QualifiedName()
1803 (<WITH> withOptions = RecordConstructor())?
1804 {
Dmitry Lychagin20905cd2020-08-06 20:34:55 -07001805 try {
1806 stmt = new CreateFunctionStatement(signature, params, returnType, libraryName.first,
Dmitry Lychagindcb4ad22020-08-26 15:49:09 -07001807 libraryName.second.getValue(), externalIdentifier, withOptions, orReplace, ifNotExists);
Dmitry Lychagin20905cd2020-08-06 20:34:55 -07001808 } catch (AlgebricksException e) {
1809 throw new SqlppParseException(getSourceLocation(startStmtToken), e.getMessage());
1810 }
Dmitry Lychagin20905cd2020-08-06 20:34:55 -07001811 }
1812 )
Ian Maxon38fe9402020-01-29 19:27:40 -08001813 )
Dmitry Lychagin265e3ce2021-03-02 12:22:38 -08001814 {
Dmitry Lychagin265e3ce2021-03-02 12:22:38 -08001815 defaultDataverse = currentDataverse;
1816 return addSourceLocation(stmt, startStmtToken);
1817 }
Dmitry Lychagin314e2792019-11-26 14:35:42 -08001818}
1819
Dmitry Lychagin541652082020-11-09 14:04:53 -08001820Pair<Integer, List<Pair<VarIdentifier, TypeExpression>>> FunctionParameters() :
Dmitry Lychagin0d4c1b62020-02-07 17:10:16 -08001821{
Dmitry Lychagin541652082020-11-09 14:04:53 -08001822 Pair<Integer, List<Pair<VarIdentifier, TypeExpression>>> params = null;
Dmitry Lychagin0d4c1b62020-02-07 17:10:16 -08001823}
1824{
Dmitry Lychagin541652082020-11-09 14:04:53 -08001825 <LEFTPAREN> (params = FunctionParameterList())? <RIGHTPAREN>
Dmitry Lychagin0d4c1b62020-02-07 17:10:16 -08001826 {
Dmitry Lychagin541652082020-11-09 14:04:53 -08001827 if (params == null) {
1828 params = new Pair<Integer, List<Pair<VarIdentifier, TypeExpression>>>(
1829 0, Collections.<Pair<VarIdentifier, TypeExpression>>emptyList()
1830 );
1831 }
1832 return params;
Dmitry Lychagin0d4c1b62020-02-07 17:10:16 -08001833 }
1834}
1835
Dmitry Lychagin541652082020-11-09 14:04:53 -08001836Pair<Integer, List<Pair<VarIdentifier, TypeExpression>>> FunctionParameterList() :
Dmitry Lychagin0d4c1b62020-02-07 17:10:16 -08001837{
Dmitry Lychagin541652082020-11-09 14:04:53 -08001838 List<Pair<VarIdentifier, TypeExpression>> paramList = null;
1839 Pair<VarIdentifier, TypeExpression> param = null;
1840 int arity = 0;
Dmitry Lychagin0d4c1b62020-02-07 17:10:16 -08001841}
1842{
Dmitry Lychagin541652082020-11-09 14:04:53 -08001843 (
1844 (
1845 <DOT> <DOT> <DOT>
1846 {
1847 param = new Pair<VarIdentifier, TypeExpression>(
1848 SqlppVariableUtil.toInternalVariableIdentifier(UDF_VARARGS_PARAM_NAME), null
1849 );
1850 paramList = Collections.<Pair<VarIdentifier, TypeExpression>>singletonList(param);
1851 arity = FunctionIdentifier.VARARGS;
1852 }
1853 )
1854 |
1855 (
1856 param = FunctionParameter()
1857 {
1858 paramList = new ArrayList<Pair<VarIdentifier, TypeExpression>>();
1859 paramList.add(param);
1860 }
1861 ( <COMMA> param = FunctionParameter() { paramList.add(param); } )*
1862 {
1863 arity = paramList.size();
1864 }
1865 )
1866 )
Dmitry Lychaginf7bc6c12020-06-01 18:19:44 -07001867 {
Dmitry Lychagin541652082020-11-09 14:04:53 -08001868 return new Pair<Integer, List<Pair<VarIdentifier, TypeExpression>>>(arity, paramList);
Dmitry Lychaginf7bc6c12020-06-01 18:19:44 -07001869 }
Dmitry Lychagin0d4c1b62020-02-07 17:10:16 -08001870}
1871
Dmitry Lychaginf7bc6c12020-06-01 18:19:44 -07001872Pair<VarIdentifier,TypeExpression> FunctionParameter() throws ParseException:
Dmitry Lychagin0d4c1b62020-02-07 17:10:16 -08001873{
Dmitry Lychaginf7bc6c12020-06-01 18:19:44 -07001874 String name = null;
1875 TypeExpression type = null;
Dmitry Lychagin0d4c1b62020-02-07 17:10:16 -08001876}
1877{
Dmitry Lychaginf7bc6c12020-06-01 18:19:44 -07001878 name = VariableIdentifier()
1879 ( LOOKAHEAD(3) (<COLON>)? type = TypeExpr(false) )?
1880 {
1881 return new Pair<VarIdentifier,TypeExpression>(new VarIdentifier(name), type);
1882 }
1883}
1884
1885TypeExpression FunctionReturnType() throws ParseException:
1886{
1887 TypeExpression returnType = null;
1888}
1889{
1890 ( LOOKAHEAD({laIdentifier(RETURNS)}) <IDENTIFIER> returnType = TypeExpr(false) )?
Dmitry Lychagin0d4c1b62020-02-07 17:10:16 -08001891 {
1892 return returnType;
1893 }
1894}
1895
Dmitry Lychagin45de2342020-02-03 12:01:28 -08001896Expression FunctionBody() throws ParseException:
1897{
1898 Expression functionBodyExpr = null;
1899}
1900{
1901 ( functionBodyExpr = SelectExpression(true) | functionBodyExpr = Expression() )
1902 {
1903 return functionBodyExpr;
1904 }
1905}
1906
Dmitry Lychagin20905cd2020-08-06 20:34:55 -07001907List<String> FunctionExternalIdentifier() throws ParseException:
1908{
1909 String ident = null;
1910 List<String> identList = new ArrayList(2);
1911}
1912{
1913 ident = StringLiteral() { identList.add(ident.trim()); }
1914 ( <COMMA> ident = StringLiteral() { identList.add(ident.trim()); } )*
1915 {
1916 return identList;
1917 }
1918}
1919
Dmitry Lychagin314e2792019-11-26 14:35:42 -08001920CreateFeedStatement CreateFeedStatement(Token startStmtToken) throws ParseException:
1921{
1922 CreateFeedStatement stmt = null;
1923}
1924{
1925 <FEED> stmt = FeedSpecification(startStmtToken)
1926 {
1927 return stmt;
1928 }
Yingyi Bu391f09e2015-10-29 13:49:39 -07001929}
1930
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07001931CreateFeedStatement FeedSpecification(Token startStmtToken) throws ParseException:
Yingyi Bu391f09e2015-10-29 13:49:39 -07001932{
Dmitry Lychagin54c06012019-11-13 15:54:20 -08001933 Pair<DataverseName,Identifier> nameComponents = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07001934 boolean ifNotExists = false;
1935 String adapterName = null;
1936 Map<String,String> properties = null;
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07001937 CreateFeedStatement stmt = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07001938 Pair<Identifier,Identifier> sourceNameComponents = null;
Xikui Wang5a61b2a2018-01-02 14:14:03 -08001939 RecordConstructor withRecord = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07001940}
1941{
Dmitry Lychagin314e2792019-11-26 14:35:42 -08001942 nameComponents = QualifiedName() ifNotExists = IfNotExists()
Xikui Wang5a61b2a2018-01-02 14:14:03 -08001943 <WITH> withRecord = RecordConstructor()
Abdullah Alamoudifff200c2017-02-18 20:32:14 -08001944 {
Xikui Wang5a61b2a2018-01-02 14:14:03 -08001945 try {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07001946 stmt = new CreateFeedStatement(nameComponents, withRecord, ifNotExists);
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07001947 return addSourceLocation(stmt, startStmtToken);
Xikui Wang5a61b2a2018-01-02 14:14:03 -08001948 } catch (AlgebricksException e) {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07001949 throw new SqlppParseException(getSourceLocation(startStmtToken), e.getMessage());
Xikui Wang5a61b2a2018-01-02 14:14:03 -08001950 }
Abdullah Alamoudifff200c2017-02-18 20:32:14 -08001951 }
Yingyi Bu391f09e2015-10-29 13:49:39 -07001952}
1953
Dmitry Lychagin314e2792019-11-26 14:35:42 -08001954CreateFeedPolicyStatement CreateFeedPolicyStatement(Token startStmtToken) throws ParseException:
1955{
1956 CreateFeedPolicyStatement stmt = null;
1957}
1958{
1959 <INGESTION> <POLICY> stmt = FeedPolicySpecification(startStmtToken)
1960 {
1961 return stmt;
1962 }
1963}
1964
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07001965CreateFeedPolicyStatement FeedPolicySpecification(Token startStmtToken) throws ParseException:
Yingyi Bu391f09e2015-10-29 13:49:39 -07001966{
Michael Blowd6cf6412016-06-30 02:44:35 -04001967 String policyName = null;
1968 String basePolicyName = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07001969 String sourcePolicyFile = null;
1970 String definition = null;
1971 boolean ifNotExists = false;
1972 Map<String,String> properties = null;
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07001973 CreateFeedPolicyStatement stmt = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07001974}
1975{
Dmitry Lychagin314e2792019-11-26 14:35:42 -08001976 policyName = Identifier() ifNotExists = IfNotExists()
1977 <FROM>
1978 (<POLICY> basePolicyName = Identifier() properties = Configuration() (<DEFINITION> definition = ConstantString())?
Yingyi Bu391f09e2015-10-29 13:49:39 -07001979 {
Dmitry Lychagin314e2792019-11-26 14:35:42 -08001980 stmt = new CreateFeedPolicyStatement(policyName, basePolicyName, properties, definition, ifNotExists);
Yingyi Bu391f09e2015-10-29 13:49:39 -07001981 }
Dmitry Lychagin314e2792019-11-26 14:35:42 -08001982 | <PATH> sourcePolicyFile = ConstantString() (<DEFINITION> definition = ConstantString())?
1983 {
1984 stmt = new CreateFeedPolicyStatement(policyName, sourcePolicyFile, definition, ifNotExists);
1985 }
1986 )
1987 {
1988 return addSourceLocation(stmt, startStmtToken);
1989 }
Yingyi Bu391f09e2015-10-29 13:49:39 -07001990}
1991
Rui Guoe6986dd2020-11-25 19:50:06 -08001992Statement CreateFullTextStatement(Token startStmtToken) throws ParseException:
1993{
1994 Statement stmt = null;
1995}
1996{
1997 (
1998 <FULLTEXT>
1999 (
2000 <FILTER> stmt = CreateFullTextFilterSpec(startStmtToken)
2001 | (<IDENTIFIER> { expectToken(CONFIG); } stmt = CreateFullTextConfigSpec(startStmtToken))
2002 )
2003 )
2004 {
2005 return stmt;
2006 }
2007}
2008
2009CreateFullTextFilterStatement CreateFullTextFilterSpec(Token startStmtToken) throws ParseException:
2010{
2011 CreateFullTextFilterStatement stmt = null;
2012 Pair<DataverseName,Identifier> nameComponents = null;
2013 boolean ifNotExists = false;
2014 RecordConstructor expr = null;
2015}
2016{
2017 (
2018 nameComponents = QualifiedName() ifNotExists = IfNotExists()
2019 <AS>
2020 expr = RecordConstructor()
2021 )
2022 {
2023 try {
2024 stmt = new CreateFullTextFilterStatement(nameComponents.first, nameComponents.second.getValue(), ifNotExists, expr);
2025 return addSourceLocation(stmt, startStmtToken);
2026 } catch (CompilationException e) {
2027 throw new SqlppParseException(getSourceLocation(startStmtToken), e.getMessage());
2028 }
2029 }
2030}
2031
2032CreateFullTextConfigStatement CreateFullTextConfigSpec(Token startStmtToken) throws ParseException:
2033{
2034 CreateFullTextConfigStatement stmt = null;
2035 Pair<DataverseName,Identifier> nameComponents = null;
2036 boolean ifNotExists = false;
2037 RecordConstructor expr = null;
2038}
2039{
2040 (
2041 nameComponents = QualifiedName() ifNotExists = IfNotExists()
2042 <AS>
2043 expr = RecordConstructor()
2044 )
2045 {
2046 try {
2047 stmt = new CreateFullTextConfigStatement(nameComponents.first, nameComponents.second.getValue(), ifNotExists, expr);
2048 return addSourceLocation(stmt, startStmtToken);
2049 } catch (CompilationException e) {
2050 throw new SqlppParseException(getSourceLocation(startStmtToken), e.getMessage());
2051 }
2052 }
2053}
2054
Dmitry Lychagin2a0848e2020-01-08 13:57:22 -08002055CreateSynonymStatement CreateSynonymStatement(Token startStmtToken) throws ParseException:
2056{
2057 CreateSynonymStatement stmt = null;
2058}
2059{
2060 <SYNONYM> stmt = SynonymSpecification(startStmtToken)
2061 {
2062 return stmt;
2063 }
2064}
2065
2066CreateSynonymStatement SynonymSpecification(Token startStmtToken) throws ParseException:
2067{
2068 Pair<DataverseName,Identifier> nameComponents = null;
2069 Pair<DataverseName,Identifier> objectNameComponents = null;
2070 boolean ifNotExists = false;
2071}
2072{
2073 nameComponents = QualifiedName() ifNotExists = IfNotExists()
2074 <FOR> objectNameComponents = QualifiedName()
2075 {
2076 CreateSynonymStatement stmt = new CreateSynonymStatement(nameComponents.first, nameComponents.second.getValue(),
2077 objectNameComponents.first, objectNameComponents.second.getValue(), ifNotExists);
2078 return addSourceLocation(stmt, startStmtToken);
2079 }
2080}
2081
Yingyi Bu391f09e2015-10-29 13:49:39 -07002082boolean IfNotExists() throws ParseException:
2083{
2084}
2085{
Yingyi Budaa549c2016-06-28 22:30:52 -07002086 ( LOOKAHEAD(1) <IF> <NOT> <EXISTS>
Yingyi Bu391f09e2015-10-29 13:49:39 -07002087 {
2088 return true;
2089 }
2090 )?
2091 {
2092 return false;
2093 }
2094}
2095
Xikui Wang9d63f622017-05-18 17:50:44 -07002096void ApplyFunction(List<FunctionSignature> funcSigs) throws ParseException:
Yingyi Bu391f09e2015-10-29 13:49:39 -07002097{
Dmitry Lychagin54c06012019-11-13 15:54:20 -08002098 FunctionName functionName = null;
Xikui Wang261dc6d2017-03-29 21:23:15 -07002099 String fqFunctionName = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07002100}
2101{
Dmitry Lychagin54c06012019-11-13 15:54:20 -08002102 <APPLY> <FUNCTION> functionName = FunctionName()
Dmitry Lychagin314e2792019-11-26 14:35:42 -08002103 {
2104 fqFunctionName = functionName.library == null ? functionName.function : functionName.library + "#" + functionName.function;
2105 funcSigs.add(new FunctionSignature(functionName.dataverse, fqFunctionName, 1));
2106 }
Xikui Wang261dc6d2017-03-29 21:23:15 -07002107 (
Dmitry Lychagin54c06012019-11-13 15:54:20 -08002108 <COMMA> functionName = FunctionName()
Xikui Wang261dc6d2017-03-29 21:23:15 -07002109 {
Dmitry Lychagin54c06012019-11-13 15:54:20 -08002110 fqFunctionName = functionName.library == null ? functionName.function : functionName.library + "#" + functionName.function;
2111 funcSigs.add(new FunctionSignature(functionName.dataverse, fqFunctionName, 1));
Xikui Wang261dc6d2017-03-29 21:23:15 -07002112 }
2113 )*
Yingyi Bu391f09e2015-10-29 13:49:39 -07002114}
2115
2116String GetPolicy() throws ParseException:
2117{
2118 String policy = null;
2119}
2120{
2121 <USING> <POLICY> policy = Identifier()
2122 {
2123 return policy;
2124 }
2125
2126}
2127
2128FunctionSignature FunctionSignature() throws ParseException:
2129{
2130 FunctionName fctName = null;
Dmitry Lychagin541652082020-11-09 14:04:53 -08002131 Pair<Integer, List<Pair<VarIdentifier,TypeExpression>>> params = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07002132 int arity = 0;
2133}
2134{
Dmitry Lychagindcb4ad22020-08-26 15:49:09 -07002135 fctName = FunctionName()
2136 (
Dmitry Lychagin541652082020-11-09 14:04:53 -08002137 LOOKAHEAD(2) params = FunctionParameters() { arity = params.first; }
Dmitry Lychagindcb4ad22020-08-26 15:49:09 -07002138 | ( <LEFTPAREN> arity = FunctionArity() <RIGHTPAREN> )
2139 | ( <ATT> arity = FunctionArity() ) // back-compat
2140 )
2141 {
2142 return new FunctionSignature(fctName.dataverse, fctName.function, arity);
2143 }
2144}
Yingyi Bu391f09e2015-10-29 13:49:39 -07002145
Dmitry Lychagindcb4ad22020-08-26 15:49:09 -07002146int FunctionArity() throws ParseException:
2147{
2148 int arity;
2149}
2150{
2151 <INTEGER_LITERAL>
2152 {
2153 try {
2154 arity = Integer.parseInt(token.image);
2155 } catch (NumberFormatException e) {
2156 throw new SqlppParseException(getSourceLocation(token), "Invalid arity: " + token.image);
Yingyi Bu391f09e2015-10-29 13:49:39 -07002157 }
Dmitry Lychagindcb4ad22020-08-26 15:49:09 -07002158 if (arity < 0 && arity != FunctionIdentifier.VARARGS) {
2159 throw new SqlppParseException(getSourceLocation(token), "Invalid arity: " + arity);
2160 }
2161 return arity;
2162 }
Yingyi Bu391f09e2015-10-29 13:49:39 -07002163}
2164
Yingyi Buc9bfe252016-03-01 00:02:40 -08002165Pair<List<Integer>, List<List<String>>> PrimaryKey() throws ParseException:
Yingyi Bu391f09e2015-10-29 13:49:39 -07002166{
Dmitry Lychagin81578f92021-08-24 11:57:07 -07002167 Pair<List<Integer>, List<List<String>>> primaryKeyFields = null;
2168}
2169{
2170 <PRIMARY> <KEY> primaryKeyFields = PrimaryKeyFields()
2171 {
2172 return primaryKeyFields;
2173 }
2174}
2175
2176Pair<List<Integer>, List<List<String>>> PrimaryKeyFields() throws ParseException:
2177{
Yingyi Buc9bfe252016-03-01 00:02:40 -08002178 Pair<Integer, List<String>> tmp = null;
2179 List<Integer> keyFieldSourceIndicators = new ArrayList<Integer>();
Yingyi Bu391f09e2015-10-29 13:49:39 -07002180 List<List<String>> primaryKeyFields = new ArrayList<List<String>>();
2181}
2182{
Dmitry Lychagin81578f92021-08-24 11:57:07 -07002183 tmp = NestedField()
Yingyi Bu391f09e2015-10-29 13:49:39 -07002184 {
Yingyi Buc9bfe252016-03-01 00:02:40 -08002185 keyFieldSourceIndicators.add(tmp.first);
2186 primaryKeyFields.add(tmp.second);
Yingyi Bu391f09e2015-10-29 13:49:39 -07002187 }
2188 ( <COMMA> tmp = NestedField()
2189 {
Yingyi Buc9bfe252016-03-01 00:02:40 -08002190 keyFieldSourceIndicators.add(tmp.first);
2191 primaryKeyFields.add(tmp.second);
Yingyi Bu391f09e2015-10-29 13:49:39 -07002192 }
2193 )*
2194 {
Yingyi Buc9bfe252016-03-01 00:02:40 -08002195 return new Pair<List<Integer>, List<List<String>>> (keyFieldSourceIndicators, primaryKeyFields);
Yingyi Bu391f09e2015-10-29 13:49:39 -07002196 }
2197}
2198
2199Statement DropStatement() throws ParseException:
2200{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002201 Token startToken = null;
Dmitry Lychagin314e2792019-11-26 14:35:42 -08002202 Statement stmt = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07002203}
2204{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002205 <DROP> { startToken = token; }
Yingyi Bu391f09e2015-10-29 13:49:39 -07002206 (
Dmitry Lychagin314e2792019-11-26 14:35:42 -08002207 stmt = DropDatasetStatement(startToken)
2208 | stmt = DropIndexStatement(startToken)
2209 | stmt = DropNodeGroupStatement(startToken)
2210 | stmt = DropTypeStatement(startToken)
2211 | stmt = DropDataverseStatement(startToken)
Dmitry Lychagin20905cd2020-08-06 20:34:55 -07002212 | stmt = DropAdapterStatement(startToken)
Dmitry Lychagin314e2792019-11-26 14:35:42 -08002213 | stmt = DropFunctionStatement(startToken)
2214 | stmt = DropFeedStatement(startToken)
2215 | stmt = DropFeedPolicyStatement(startToken)
Dmitry Lychagin2a0848e2020-01-08 13:57:22 -08002216 | stmt = DropSynonymStatement(startToken)
Rui Guoe6986dd2020-11-25 19:50:06 -08002217 | stmt = DropFullTextStatement(startToken)
Dmitry Lychagin793c39e2021-04-21 16:52:10 -07002218 | stmt = DropViewStatement(startToken)
Yingyi Bu391f09e2015-10-29 13:49:39 -07002219 )
2220 {
Dmitry Lychagin314e2792019-11-26 14:35:42 -08002221 return stmt;
2222 }
2223}
2224
2225DropDatasetStatement DropDatasetStatement(Token startStmtToken) throws ParseException:
2226{
2227 DropDatasetStatement stmt = null;
2228}
2229{
2230 Dataset() stmt = DropDatasetSpecification(startStmtToken)
2231 {
2232 return stmt;
2233 }
2234}
2235
2236DropDatasetStatement DropDatasetSpecification(Token startStmtToken) throws ParseException:
2237{
2238 Pair<DataverseName,Identifier> pairId = null;
2239 boolean ifExists = false;
2240}
2241{
2242 pairId = QualifiedName() ifExists = IfExists()
2243 {
2244 DropDatasetStatement stmt = new DropDatasetStatement(pairId.first, pairId.second, ifExists);
2245 return addSourceLocation(stmt, startStmtToken);
2246 }
2247}
2248
Dmitry Lychagin793c39e2021-04-21 16:52:10 -07002249ViewDropStatement DropViewStatement(Token startStmtToken) throws ParseException:
2250{
2251 ViewDropStatement stmt = null;
2252}
2253{
2254 <VIEW> stmt = DropViewSpecification(startStmtToken)
2255 {
2256 return stmt;
2257 }
2258}
2259
2260ViewDropStatement DropViewSpecification(Token startStmtToken) throws ParseException:
2261{
2262 Pair<DataverseName,Identifier> pairId = null;
2263 boolean ifExists = false;
2264}
2265{
2266 pairId = QualifiedName() ifExists = IfExists()
2267 {
2268 ViewDropStatement stmt = new ViewDropStatement(pairId.first, pairId.second, ifExists);
2269 return addSourceLocation(stmt, startStmtToken);
2270 }
2271}
2272
Dmitry Lychagin314e2792019-11-26 14:35:42 -08002273IndexDropStatement DropIndexStatement(Token startStmtToken) throws ParseException:
2274{
2275 IndexDropStatement stmt = null;
2276}
2277{
2278 <INDEX> stmt = DropIndexSpecification(startStmtToken)
2279 {
2280 return stmt;
2281 }
2282}
2283
2284IndexDropStatement DropIndexSpecification(Token startStmtToken) throws ParseException:
2285{
2286 Triple<DataverseName,Identifier,Identifier> tripleId = null;
2287 boolean ifExists = false;
2288}
2289{
2290 tripleId = DoubleQualifiedName() ifExists = IfExists()
2291 {
2292 IndexDropStatement stmt = new IndexDropStatement(tripleId.first, tripleId.second, tripleId.third, ifExists);
2293 return addSourceLocation(stmt, startStmtToken);
2294 }
2295}
2296
Rui Guoe6986dd2020-11-25 19:50:06 -08002297Statement DropFullTextStatement(Token startStmtToken) throws ParseException:
2298{
2299 Statement stmt = null;
2300}
2301{
2302 <FULLTEXT>
2303 (
2304 <FILTER> stmt = DropFullTextFilterSpec(startStmtToken)
2305 | (<IDENTIFIER> { expectToken(CONFIG); } stmt = DropFullTextConfigSpec(startStmtToken))
2306 )
2307 {
2308 return stmt;
2309 }
2310}
2311
2312FullTextFilterDropStatement DropFullTextFilterSpec(Token startStmtToken) throws ParseException:
2313{
2314 FullTextFilterDropStatement stmt = null;
2315 Pair<DataverseName,Identifier> nameComponents = null;
2316 boolean ifExists = false;
2317}
2318{
2319 nameComponents = QualifiedName() ifExists = IfExists()
2320 {
2321 stmt = new FullTextFilterDropStatement(nameComponents.first, nameComponents.second.getValue(), ifExists);
2322 return addSourceLocation(stmt, startStmtToken);
2323 }
2324}
2325
2326FullTextConfigDropStatement DropFullTextConfigSpec(Token startStmtToken) throws ParseException:
2327{
2328 FullTextConfigDropStatement stmt = null;
2329 Pair<DataverseName,Identifier> nameComponents = null;
2330 boolean ifExists = false;
2331}
2332{
2333 nameComponents = QualifiedName() ifExists = IfExists()
2334 {
2335 stmt = new FullTextConfigDropStatement(nameComponents.first, nameComponents.second.getValue(), ifExists);
2336 return addSourceLocation(stmt, startStmtToken);
2337 }
2338}
2339
2340
Dmitry Lychagin314e2792019-11-26 14:35:42 -08002341NodeGroupDropStatement DropNodeGroupStatement(Token startStmtToken) throws ParseException:
2342{
2343 NodeGroupDropStatement stmt = null;
2344}
2345{
2346 <NODEGROUP> stmt = DropNodeGroupSpecification(startStmtToken)
2347 {
2348 return stmt;
2349 }
2350}
2351
2352NodeGroupDropStatement DropNodeGroupSpecification(Token startStmtToken) throws ParseException:
2353{
2354 String id = null;
2355 boolean ifExists = false;
2356}
2357{
2358 id = Identifier() ifExists = IfExists()
2359 {
2360 NodeGroupDropStatement stmt = new NodeGroupDropStatement(new Identifier(id), ifExists);
2361 return addSourceLocation(stmt, startStmtToken);
2362 }
2363}
2364
2365TypeDropStatement DropTypeStatement(Token startStmtToken) throws ParseException:
2366{
2367 TypeDropStatement stmt = null;
2368}
2369{
2370 <TYPE> stmt = DropTypeSpecification(startStmtToken)
2371 {
2372 return stmt;
2373 }
2374}
2375
2376TypeDropStatement DropTypeSpecification(Token startStmtToken) throws ParseException:
2377{
2378 Pair<DataverseName,Identifier> pairId = null;
2379 boolean ifExists = false;
2380}
2381{
2382 pairId = TypeName() ifExists = IfExists()
2383 {
2384 TypeDropStatement stmt = new TypeDropStatement(pairId.first, pairId.second, ifExists);
2385 return addSourceLocation(stmt, startStmtToken);
2386 }
2387}
2388
2389DataverseDropStatement DropDataverseStatement(Token startStmtToken) throws ParseException:
2390{
2391 DataverseDropStatement stmt = null;
2392}
2393{
2394 <DATAVERSE> stmt = DropDataverseSpecification(startStmtToken)
2395 {
2396 return stmt;
2397 }
2398}
2399
2400DataverseDropStatement DropDataverseSpecification(Token startStmtToken) throws ParseException:
2401{
Dmitry Lychagin13a40e12021-04-08 18:22:57 -07002402 DataverseName dvName = null;
Dmitry Lychagin314e2792019-11-26 14:35:42 -08002403 boolean ifExists = false;
2404}
2405{
Dmitry Lychagin13a40e12021-04-08 18:22:57 -07002406 dvName = DataverseName() ifExists = IfExists()
Dmitry Lychagin314e2792019-11-26 14:35:42 -08002407 {
Dmitry Lychagin13a40e12021-04-08 18:22:57 -07002408 DataverseDropStatement stmt = new DataverseDropStatement(dvName, ifExists);
Dmitry Lychagin314e2792019-11-26 14:35:42 -08002409 return addSourceLocation(stmt, startStmtToken);
2410 }
2411}
2412
Dmitry Lychagin20905cd2020-08-06 20:34:55 -07002413AdapterDropStatement DropAdapterStatement(Token startStmtToken) throws ParseException:
2414{
2415 AdapterDropStatement stmt = null;
2416}
2417{
2418 <ADAPTER> stmt = DropAdapterSpecification(startStmtToken)
2419 {
2420 return stmt;
2421 }
2422}
2423
2424AdapterDropStatement DropAdapterSpecification(Token startStmtToken) throws ParseException:
2425{
2426 Pair<DataverseName,Identifier> adapterName = null;
2427 boolean ifExists = false;
2428}
2429{
2430 adapterName = QualifiedName() ifExists = IfExists()
2431 {
2432 AdapterDropStatement stmt = new AdapterDropStatement(adapterName.first, adapterName.second.getValue(), ifExists);
2433 return addSourceLocation(stmt, startStmtToken);
2434 }
2435}
2436
Dmitry Lychagin314e2792019-11-26 14:35:42 -08002437FunctionDropStatement DropFunctionStatement(Token startStmtToken) throws ParseException:
2438{
2439 FunctionDropStatement stmt = null;
2440}
2441{
2442 <FUNCTION> stmt = DropFunctionSpecification(startStmtToken)
2443 {
2444 return stmt;
2445 }
2446}
2447
2448FunctionDropStatement DropFunctionSpecification(Token startStmtToken) throws ParseException:
2449{
2450 FunctionSignature funcSig = null;
2451 boolean ifExists = false;
2452}
2453{
2454 funcSig = FunctionSignature() ifExists = IfExists()
2455 {
2456 FunctionDropStatement stmt = new FunctionDropStatement(funcSig, ifExists);
2457 return addSourceLocation(stmt, startStmtToken);
2458 }
2459}
2460
2461FeedDropStatement DropFeedStatement(Token startStmtToken) throws ParseException:
2462{
2463 FeedDropStatement stmt = null;
2464}
2465{
2466 <FEED> stmt = DropFeedSpecification(startStmtToken)
2467 {
2468 return stmt;
2469 }
2470}
2471
2472FeedDropStatement DropFeedSpecification(Token startStmtToken) throws ParseException:
2473{
2474 Pair<DataverseName,Identifier> pairId = null;
2475 boolean ifExists = false;
2476}
2477{
2478 pairId = QualifiedName() ifExists = IfExists()
2479 {
2480 FeedDropStatement stmt = new FeedDropStatement(pairId.first, pairId.second, ifExists);
2481 return addSourceLocation(stmt, startStmtToken);
2482 }
2483}
2484
2485FeedPolicyDropStatement DropFeedPolicyStatement(Token startStmtToken) throws ParseException:
2486{
2487 FeedPolicyDropStatement stmt = null;
2488}
2489{
2490 <INGESTION> <POLICY> stmt = DropFeedPolicySpecification(startStmtToken)
2491 {
2492 return stmt;
2493 }
2494}
2495
2496FeedPolicyDropStatement DropFeedPolicySpecification(Token startStmtToken) throws ParseException:
2497{
2498 Pair<DataverseName,Identifier> pairId = null;
2499 boolean ifExists = false;
2500}
2501{
2502 pairId = QualifiedName() ifExists = IfExists()
2503 {
2504 FeedPolicyDropStatement stmt = new FeedPolicyDropStatement(pairId.first, pairId.second, ifExists);
2505 return addSourceLocation(stmt, startStmtToken);
Yingyi Bu391f09e2015-10-29 13:49:39 -07002506 }
2507}
2508
Dmitry Lychagin2a0848e2020-01-08 13:57:22 -08002509SynonymDropStatement DropSynonymStatement(Token startStmtToken) throws ParseException:
2510{
2511 SynonymDropStatement stmt = null;
2512}
2513{
2514 <SYNONYM> stmt = DropSynonymSpecification(startStmtToken)
2515 {
2516 return stmt;
2517 }
2518}
2519
2520SynonymDropStatement DropSynonymSpecification(Token startStmtToken) throws ParseException:
2521{
2522 Pair<DataverseName,Identifier> pairId = null;
2523 boolean ifExists = false;
2524}
2525{
2526 pairId = QualifiedName() ifExists = IfExists()
2527 {
2528 SynonymDropStatement stmt = new SynonymDropStatement(pairId.first, pairId.second.getValue(), ifExists);
2529 return addSourceLocation(stmt, startStmtToken);
2530 }
2531}
2532
Yingyi Bu391f09e2015-10-29 13:49:39 -07002533boolean IfExists() throws ParseException :
2534{
2535}
2536{
2537 ( LOOKAHEAD(1) <IF> <EXISTS>
2538 {
2539 return true;
2540 }
2541 )?
2542 {
2543 return false;
2544 }
2545}
2546
2547InsertStatement InsertStatement() throws ParseException:
2548{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002549 Token startToken = null;
Dmitry Lychagin54c06012019-11-13 15:54:20 -08002550 Pair<DataverseName,Identifier> nameComponents = null;
Yingyi Bucb5bf332017-01-02 22:19:50 -08002551 VariableExpr var = null;
2552 Query query = null;
2553 Expression returnExpression = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07002554}
2555{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002556 <INSERT> { startToken = token; } <INTO> nameComponents = QualifiedName() (<AS> var = Variable())?
Dmitry Lychaginaebd0312019-06-04 08:55:39 -07002557 query = Query()
Yingyi Bucb5bf332017-01-02 22:19:50 -08002558 ( <RETURNING> returnExpression = Expression())?
Yingyi Bu391f09e2015-10-29 13:49:39 -07002559 {
Dmitry Lychagin393215e2019-04-11 10:26:56 -07002560 if (var == null && returnExpression != null) {
2561 var = new VariableExpr(SqlppVariableUtil.toInternalVariableIdentifier(nameComponents.second.getValue()));
2562 addSourceLocation(var, startToken);
Yingyi Bucb5bf332017-01-02 22:19:50 -08002563 }
Yingyi Bucaea8f02015-11-16 15:12:15 -08002564 query.setTopLevel(true);
Dmitry Lychagin2a0848e2020-01-08 13:57:22 -08002565 InsertStatement stmt = new InsertStatement(nameComponents.first, nameComponents.second.getValue(), query,
2566 getVarCounter(), var, returnExpression);
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07002567 return addSourceLocation(stmt, startToken);
Yingyi Bucb5bf332017-01-02 22:19:50 -08002568 }
2569}
2570
2571UpsertStatement UpsertStatement() throws ParseException:
2572{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002573 Token startToken = null;
Dmitry Lychagin54c06012019-11-13 15:54:20 -08002574 Pair<DataverseName,Identifier> nameComponents = null;
Yingyi Bucb5bf332017-01-02 22:19:50 -08002575 VariableExpr var = null;
2576 Query query = null;
2577 Expression returnExpression = null;
2578}
2579{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002580 <UPSERT> { startToken = token; } <INTO> nameComponents = QualifiedName() (<AS> var = Variable())?
Dmitry Lychaginaebd0312019-06-04 08:55:39 -07002581 query = Query()
Yingyi Bucb5bf332017-01-02 22:19:50 -08002582 ( <RETURNING> returnExpression = Expression())?
2583 {
Dmitry Lychagin393215e2019-04-11 10:26:56 -07002584 if (var == null && returnExpression != null) {
2585 var = new VariableExpr(SqlppVariableUtil.toInternalVariableIdentifier(nameComponents.second.getValue()));
2586 addSourceLocation(var, startToken);
Yingyi Bucb5bf332017-01-02 22:19:50 -08002587 }
2588 query.setTopLevel(true);
Dmitry Lychagin2a0848e2020-01-08 13:57:22 -08002589 UpsertStatement stmt = new UpsertStatement(nameComponents.first, nameComponents.second.getValue(), query,
2590 getVarCounter(), var, returnExpression);
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07002591 return addSourceLocation(stmt, startToken);
Yingyi Bu391f09e2015-10-29 13:49:39 -07002592 }
2593}
2594
2595DeleteStatement DeleteStatement() throws ParseException:
2596{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002597 Token startToken = null;
Dmitry Lychagin393215e2019-04-11 10:26:56 -07002598 VariableExpr var = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07002599 Expression condition = null;
Dmitry Lychagin54c06012019-11-13 15:54:20 -08002600 Pair<DataverseName, Identifier> nameComponents;
Yingyi Bu391f09e2015-10-29 13:49:39 -07002601}
2602{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002603 <DELETE> { startToken = token; }
Dmitry Lychagin393215e2019-04-11 10:26:56 -07002604 <FROM> nameComponents = QualifiedName() ((<AS>)? var = Variable())?
Yingyi Bu391f09e2015-10-29 13:49:39 -07002605 (<WHERE> condition = Expression())?
Yingyi Bu20e085b2016-07-06 12:57:27 -07002606 {
Dmitry Lychagin393215e2019-04-11 10:26:56 -07002607 if (var == null) {
2608 var = new VariableExpr(SqlppVariableUtil.toInternalVariableIdentifier(nameComponents.second.getValue()));
2609 addSourceLocation(var, startToken);
Yingyi Bu20e085b2016-07-06 12:57:27 -07002610 }
Dmitry Lychagin2a0848e2020-01-08 13:57:22 -08002611 DeleteStatement stmt = new DeleteStatement(var, nameComponents.first, nameComponents.second.getValue(),
Abdullah Alamoudi6eb01752017-04-01 21:51:19 -07002612 condition, getVarCounter());
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07002613 return addSourceLocation(stmt, startToken);
Yingyi Bu20e085b2016-07-06 12:57:27 -07002614 }
Yingyi Bu391f09e2015-10-29 13:49:39 -07002615}
2616
2617UpdateStatement UpdateStatement() throws ParseException:
2618{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002619 Token startToken = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07002620 VariableExpr vars;
2621 Expression target;
2622 Expression condition;
2623 UpdateClause uc;
2624 List<UpdateClause> ucs = new ArrayList<UpdateClause>();
2625}
2626{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002627 <UPDATE> { startToken = token; } vars = Variable() <IN> target = Expression()
Yingyi Bu391f09e2015-10-29 13:49:39 -07002628 <WHERE> condition = Expression()
2629 <LEFTPAREN> (uc = UpdateClause()
2630 {
2631 ucs.add(uc);
2632 }
2633 (<COMMA> uc = UpdateClause()
2634 {
2635 ucs.add(uc);
2636 }
2637 )*) <RIGHTPAREN>
2638 {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002639 UpdateStatement stmt = new UpdateStatement(vars, target, condition, ucs);
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07002640 return addSourceLocation(stmt, startToken);
Yingyi Bu391f09e2015-10-29 13:49:39 -07002641 }
2642}
2643
2644UpdateClause UpdateClause() throws ParseException:
2645{
2646 Expression target = null;
2647 Expression value = null ;
2648 InsertStatement is = null;
2649 DeleteStatement ds = null;
2650 UpdateStatement us = null;
2651 Expression condition = null;
2652 UpdateClause ifbranch = null;
2653 UpdateClause elsebranch = null;
2654}
2655{
2656 (<SET> target = Expression() <EQ> value = Expression()
2657 | is = InsertStatement()
2658 | ds = DeleteStatement()
2659 | us = UpdateStatement()
2660 | <IF> <LEFTPAREN> condition = Expression() <RIGHTPAREN>
2661 <THEN> ifbranch = UpdateClause()
2662 [LOOKAHEAD(1) <ELSE> elsebranch = UpdateClause()]
2663 {
2664 return new UpdateClause(target, value, is, ds, us, condition, ifbranch, elsebranch);
2665 }
2666 )
2667}
2668
2669Statement SetStatement() throws ParseException:
2670{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002671 Token startToken = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07002672 String pn = null;
2673 String pv = null;
2674}
2675{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002676 <SET> { startToken = token; } pn = Identifier() pv = ConstantString()
Yingyi Bu391f09e2015-10-29 13:49:39 -07002677 {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002678 SetStatement stmt = new SetStatement(pn, pv);
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07002679 return addSourceLocation(stmt, startToken);
Yingyi Bu391f09e2015-10-29 13:49:39 -07002680 }
2681}
2682
2683Statement WriteStatement() throws ParseException:
2684{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002685 Token startToken = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07002686 String nodeName = null;
2687 String fileName = null;
2688 Query query;
2689 String writerClass = null;
2690 Pair<Identifier,Identifier> nameComponents = null;
2691}
2692{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002693 <WRITE> { startToken = token; } <OUTPUT> <TO> nodeName = Identifier() <COLON> fileName = ConstantString()
Yingyi Bu6d57e492016-06-06 21:24:42 -07002694 ( <USING> writerClass = ConstantString() )?
Yingyi Bu391f09e2015-10-29 13:49:39 -07002695 {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002696 WriteStatement stmt = new WriteStatement(new Identifier(nodeName), fileName, writerClass);
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07002697 return addSourceLocation(stmt, startToken);
Yingyi Bu391f09e2015-10-29 13:49:39 -07002698 }
2699}
2700
2701LoadStatement LoadStatement() throws ParseException:
2702{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002703 Token startToken = null;
Dmitry Lychagin54c06012019-11-13 15:54:20 -08002704 DataverseName dataverseName = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07002705 Identifier datasetName = null;
2706 boolean alreadySorted = false;
2707 String adapterName;
2708 Map<String,String> properties;
Dmitry Lychagin54c06012019-11-13 15:54:20 -08002709 Pair<DataverseName,Identifier> nameComponents = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07002710}
2711{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002712 <LOAD> { startToken = token; } Dataset() nameComponents = QualifiedName()
Yingyi Bu391f09e2015-10-29 13:49:39 -07002713 {
2714 dataverseName = nameComponents.first;
2715 datasetName = nameComponents.second;
2716 }
2717 <USING> adapterName = AdapterName() properties = Configuration()
2718 (<PRESORTED>
2719 {
2720 alreadySorted = true;
2721 }
2722 )?
2723 {
Dmitry Lychagin2a0848e2020-01-08 13:57:22 -08002724 LoadStatement stmt = new LoadStatement(dataverseName, datasetName.getValue(), adapterName, properties,
2725 alreadySorted);
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07002726 return addSourceLocation(stmt, startToken);
Yingyi Bu391f09e2015-10-29 13:49:39 -07002727 }
2728}
2729
2730
2731String AdapterName() throws ParseException :
2732{
2733 String adapterName = null;
2734}
2735{
2736 adapterName = Identifier()
2737 {
2738 return adapterName;
2739 }
2740}
2741
Dmitry Lychaginf3eec282022-06-10 12:44:25 -07002742Statement AnalyzeStatement() throws ParseException:
2743{
2744 Token startToken = null;
Ali Alsuliman6d72d5e2022-08-08 13:41:08 -07002745 Statement stmt = null;
Dmitry Lychaginf3eec282022-06-10 12:44:25 -07002746 Pair<DataverseName,Identifier> nameComponents = null;
Dmitry Lychaginf3eec282022-06-10 12:44:25 -07002747}
2748{
Ali Alsuliman7e5c5742022-11-18 12:21:13 -08002749 <ANALYZE> { startToken = token; } DatasetToken() nameComponents = QualifiedName()
Ali Alsuliman6d72d5e2022-08-08 13:41:08 -07002750 (
2751 stmt = AnalyzeDatasetDropStatement(startToken, nameComponents.first, nameComponents.second)
2752 | stmt = AnalyzeDatasetStatement(startToken, nameComponents.first, nameComponents.second)
2753 )
2754 {
2755 return stmt;
2756 }
2757}
2758
2759Statement AnalyzeDatasetStatement(Token startToken, DataverseName dvName, Identifier identifier) throws ParseException:
2760{
2761 RecordConstructor withRecord = null;
2762}
2763{
Dmitry Lychaginf3eec282022-06-10 12:44:25 -07002764 ( <WITH> withRecord = RecordConstructor() )?
2765 {
2766 try {
Ali Alsuliman6d72d5e2022-08-08 13:41:08 -07002767 AnalyzeStatement stmt = new AnalyzeStatement(dvName, identifier.getValue(), withRecord);
Dmitry Lychaginf3eec282022-06-10 12:44:25 -07002768 return addSourceLocation(stmt, startToken);
2769 } catch (CompilationException e) {
2770 throw new SqlppParseException(getSourceLocation(startToken), e.getMessage());
2771 }
2772 }
2773}
2774
Ali Alsuliman6d72d5e2022-08-08 13:41:08 -07002775Statement AnalyzeDatasetDropStatement(Token startToken, DataverseName dvName, Identifier identifier) throws ParseException:
2776{
2777}
2778{
2779 <DROP> <IDENTIFIER> { expectToken(STATISTICS); }
2780 {
2781 AnalyzeDropStatement stmt = new AnalyzeDropStatement(dvName, identifier.getValue());
2782 return addSourceLocation(stmt, startToken);
2783 }
2784}
2785
Yingyi Bu391f09e2015-10-29 13:49:39 -07002786Statement CompactStatement() throws ParseException:
2787{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002788 Token startToken = null;
Dmitry Lychagin54c06012019-11-13 15:54:20 -08002789 Pair<DataverseName,Identifier> nameComponents = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07002790}
2791{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002792 <COMPACT> { startToken = token; } Dataset() nameComponents = QualifiedName()
Yingyi Bu391f09e2015-10-29 13:49:39 -07002793 {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002794 CompactStatement stmt = new CompactStatement(nameComponents.first, nameComponents.second);
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07002795 return addSourceLocation(stmt, startToken);
Yingyi Bu391f09e2015-10-29 13:49:39 -07002796 }
2797}
2798
Yingyi Buab817482016-08-19 21:29:31 -07002799Statement ConnectionStatement() throws ParseException:
Yingyi Bu391f09e2015-10-29 13:49:39 -07002800{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002801 Token startToken = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07002802 Statement stmt = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07002803}
2804{
2805 (
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002806 <CONNECT> { startToken = token; } stmt = ConnectStatement(startToken)
2807 | <DISCONNECT> { startToken = token; } stmt = DisconnectStatement(startToken)
2808 | <START> { startToken = token; } stmt = StartStatement(startToken)
2809 | <STOP> { startToken = token; } stmt = StopStatement(startToken)
Yingyi Buab817482016-08-19 21:29:31 -07002810 )
2811 {
2812 return stmt;
2813 }
2814}
2815
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002816Statement StartStatement(Token startStmtToken) throws ParseException:
Abdullah Alamoudifff200c2017-02-18 20:32:14 -08002817{
Dmitry Lychagin54c06012019-11-13 15:54:20 -08002818 Pair<DataverseName,Identifier> feedNameComponents = null;
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002819 AbstractStatement stmt = null;
Abdullah Alamoudifff200c2017-02-18 20:32:14 -08002820}
2821{
2822 <FEED> feedNameComponents = QualifiedName()
2823 {
2824 stmt = new StartFeedStatement (feedNameComponents);
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07002825 return addSourceLocation(stmt, startStmtToken);
Abdullah Alamoudifff200c2017-02-18 20:32:14 -08002826 }
2827}
2828
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002829AbstractStatement StopStatement(Token startStmtToken) throws ParseException:
Abdullah Alamoudifff200c2017-02-18 20:32:14 -08002830{
Dmitry Lychagin54c06012019-11-13 15:54:20 -08002831 Pair<DataverseName,Identifier> feedNameComponents = null;
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002832 AbstractStatement stmt = null;
Abdullah Alamoudifff200c2017-02-18 20:32:14 -08002833}
2834{
2835 <FEED> feedNameComponents = QualifiedName()
2836 {
2837 stmt = new StopFeedStatement (feedNameComponents);
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07002838 return addSourceLocation(stmt, startStmtToken);
Abdullah Alamoudifff200c2017-02-18 20:32:14 -08002839 }
2840}
2841
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002842AbstractStatement DisconnectStatement(Token startStmtToken) throws ParseException:
Yingyi Buab817482016-08-19 21:29:31 -07002843{
Dmitry Lychagin54c06012019-11-13 15:54:20 -08002844 Pair<DataverseName,Identifier> feedNameComponents = null;
2845 Pair<DataverseName,Identifier> datasetNameComponents = null;
Yingyi Buab817482016-08-19 21:29:31 -07002846
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002847 AbstractStatement stmt = null;
Yingyi Buab817482016-08-19 21:29:31 -07002848}
2849{
2850 (
2851 <FEED> feedNameComponents = QualifiedName() <FROM> Dataset() datasetNameComponents = QualifiedName()
Yingyi Bu391f09e2015-10-29 13:49:39 -07002852 {
2853 stmt = new DisconnectFeedStatement(feedNameComponents, datasetNameComponents);
2854 }
2855 )
Yingyi Buab817482016-08-19 21:29:31 -07002856 {
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07002857 return addSourceLocation(stmt, startStmtToken);
Yingyi Buab817482016-08-19 21:29:31 -07002858 }
2859}
2860
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002861AbstractStatement ConnectStatement(Token startStmtToken) throws ParseException:
Yingyi Buab817482016-08-19 21:29:31 -07002862{
Dmitry Lychagin54c06012019-11-13 15:54:20 -08002863 Pair<DataverseName,Identifier> feedNameComponents = null;
2864 Pair<DataverseName,Identifier> datasetNameComponents = null;
Yingyi Buab817482016-08-19 21:29:31 -07002865
2866 Map<String,String> configuration = null;
Xikui Wang9d63f622017-05-18 17:50:44 -07002867 List<FunctionSignature> appliedFunctions = new ArrayList<FunctionSignature>();
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002868 AbstractStatement stmt = null;
Yingyi Buab817482016-08-19 21:29:31 -07002869 String policy = null;
Xikui Wangf6741682018-02-22 19:17:17 -08002870 String whereClauseBody = null;
2871 WhereClause whereClause = null;
2872 Token beginPos = null;
2873 Token endPos = null;
Yingyi Buab817482016-08-19 21:29:31 -07002874}
2875{
2876 (
Abdullah Alamoudifff200c2017-02-18 20:32:14 -08002877 <FEED> feedNameComponents = QualifiedName() <TO> Dataset() datasetNameComponents = QualifiedName()
Xikui Wangf6741682018-02-22 19:17:17 -08002878 (ApplyFunction(appliedFunctions))?
2879 (policy = GetPolicy())?
2880 (
2881 <WHERE>
2882 {
2883 beginPos = token;
2884 whereClause = new WhereClause();
2885 Expression whereExpr;
2886 }
2887 whereExpr = Expression()
2888 {
2889 whereClause.setWhereExpr(whereExpr);
2890 }
2891 )?
2892 {
2893 if (whereClause != null) {
2894 endPos = token;
2895 whereClauseBody = extractFragment(beginPos.endLine, beginPos.endColumn, endPos.endLine, endPos.endColumn + 1);
2896 }
2897 }
Yingyi Buab817482016-08-19 21:29:31 -07002898 {
Xikui Wang261dc6d2017-03-29 21:23:15 -07002899 stmt = new ConnectFeedStatement(feedNameComponents, datasetNameComponents, appliedFunctions,
Xikui Wangf6741682018-02-22 19:17:17 -08002900 policy, whereClauseBody, getVarCounter());
Yingyi Buab817482016-08-19 21:29:31 -07002901 }
2902 )
2903 {
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07002904 return addSourceLocation(stmt, startStmtToken);
Yingyi Buab817482016-08-19 21:29:31 -07002905 }
Yingyi Bu391f09e2015-10-29 13:49:39 -07002906}
2907
2908Map<String,String> Configuration() throws ParseException :
2909{
2910 Map<String,String> configuration = new LinkedHashMap<String,String>();
2911 Pair<String, String> keyValuePair = null;
2912}
2913{
2914 <LEFTPAREN> ( keyValuePair = KeyValuePair()
2915 {
2916 configuration.put(keyValuePair.first, keyValuePair.second);
2917 }
2918 ( <COMMA> keyValuePair = KeyValuePair()
2919 {
2920 configuration.put(keyValuePair.first, keyValuePair.second);
2921 }
2922 )* )? <RIGHTPAREN>
2923 {
2924 return configuration;
2925 }
2926}
2927
2928Pair<String, String> KeyValuePair() throws ParseException:
2929{
2930 String key;
2931 String value;
2932}
2933{
Ali Alsulimane2986012020-05-14 18:14:22 -07002934 <LEFTPAREN> key = ConstantString()
2935 <EQ> ( value = ConstantString() | (<TRUE> | <FALSE>) {value = token.image.toLowerCase();} )
2936 <RIGHTPAREN>
Yingyi Bu391f09e2015-10-29 13:49:39 -07002937 {
2938 return new Pair<String, String>(key, value);
2939 }
2940}
2941
2942Map<String,String> Properties() throws ParseException:
2943{
2944 Map<String,String> properties = new HashMap<String,String>();
2945 Pair<String, String> property;
2946}
2947{
2948 (LOOKAHEAD(1) <LEFTPAREN> property = Property()
2949 {
2950 properties.put(property.first, property.second);
2951 }
2952 ( <COMMA> property = Property()
2953 {
2954 properties.put(property.first, property.second);
2955 }
2956 )* <RIGHTPAREN> )?
2957 {
2958 return properties;
2959 }
2960}
2961
2962Pair<String, String> Property() throws ParseException:
2963{
Yingyi Bu6d57e492016-06-06 21:24:42 -07002964 String key = null;
2965 String value = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07002966}
2967{
Yingyi Bu6d57e492016-06-06 21:24:42 -07002968 (key = Identifier() | key = StringLiteral())
2969 <EQ>
2970 ( value = ConstantString() | <INTEGER_LITERAL>
Yingyi Bu391f09e2015-10-29 13:49:39 -07002971 {
2972 try {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002973 value = String.valueOf(Long.parseLong(token.image));
Yingyi Bu391f09e2015-10-29 13:49:39 -07002974 } catch (NumberFormatException nfe) {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07002975 throw new SqlppParseException(getSourceLocation(token), "inapproriate value: " + token.image);
Yingyi Bu391f09e2015-10-29 13:49:39 -07002976 }
2977 }
2978 )
2979 {
2980 return new Pair<String, String>(key.toUpperCase(), value);
2981 }
2982}
2983
Glenn58329202021-04-09 12:03:46 -07002984IndexedTypeExpression IndexedTypeExpr(boolean allowQues) throws ParseException:
Yingyi Bu391f09e2015-10-29 13:49:39 -07002985{
2986 TypeExpression typeExpr = null;
Glenn58329202021-04-09 12:03:46 -07002987 boolean isUnknownable = !allowQues;
Yingyi Bu391f09e2015-10-29 13:49:39 -07002988}
2989{
Dmitry Lychaginf7bc6c12020-06-01 18:19:44 -07002990 typeExpr = TypeExpr(false)
Glenn58329202021-04-09 12:03:46 -07002991 ( <QUES>
2992 {
2993 if (!allowQues) {
2994 throw new SqlppParseException(getSourceLocation(token), "'?' quantifier is illegal for the type expression.");
2995 }
2996 isUnknownable = true;
2997 }
2998 )?
Yingyi Bu391f09e2015-10-29 13:49:39 -07002999 {
Dmitry Lychagin8ba59442017-06-16 14:19:45 -07003000 return new IndexedTypeExpression(typeExpr, isUnknownable);
Yingyi Bu391f09e2015-10-29 13:49:39 -07003001 }
3002}
3003
Dmitry Lychaginf7bc6c12020-06-01 18:19:44 -07003004TypeExpression TypeExpr(boolean allowRecordTypeDef) throws ParseException:
Yingyi Bu391f09e2015-10-29 13:49:39 -07003005{
3006 TypeExpression typeExpr = null;
3007}
3008{
3009 (
Dmitry Lychaginf7bc6c12020-06-01 18:19:44 -07003010 typeExpr = TypeReference()
3011 | typeExpr = OrderedListTypeDef(allowRecordTypeDef)
3012 | typeExpr = UnorderedListTypeDef(allowRecordTypeDef)
3013 | typeExpr = RecordTypeDef() {
3014 if (!allowRecordTypeDef) {
3015 throw new SqlppParseException(typeExpr.getSourceLocation(), "Unexpected record type declaration");
3016 }
3017 }
Yingyi Bu391f09e2015-10-29 13:49:39 -07003018 )
3019 {
3020 return typeExpr;
3021 }
3022}
3023
Dmitry Lychagin3e2623c2020-04-01 11:20:04 -07003024RecordTypeDefinition.RecordKind RecordTypeKind() throws ParseException:
3025{
3026 RecordTypeDefinition.RecordKind recordKind = null;
3027}
3028{
3029 (
3030 <CLOSED> { recordKind = RecordTypeDefinition.RecordKind.CLOSED; }
3031 | <OPEN> { recordKind = RecordTypeDefinition.RecordKind.OPEN; }
3032 )
3033 {
3034 return recordKind;
3035 }
3036}
3037
Yingyi Bu391f09e2015-10-29 13:49:39 -07003038RecordTypeDefinition RecordTypeDef() throws ParseException:
3039{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07003040 Token startToken = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07003041 RecordTypeDefinition recType = new RecordTypeDefinition();
Dmitry Lychagin3e2623c2020-04-01 11:20:04 -07003042 RecordTypeDefinition.RecordKind recordKind = RecordTypeDefinition.RecordKind.OPEN;
Yingyi Bu391f09e2015-10-29 13:49:39 -07003043}
3044{
Dmitry Lychagin3e2623c2020-04-01 11:20:04 -07003045 ( recordKind = RecordTypeKind() )?
Yingyi Bu391f09e2015-10-29 13:49:39 -07003046 <LEFTBRACE>
3047 {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07003048 startToken = token;
Dmitry Lychagine77cdac2019-08-05 11:37:47 -07003049 Token hintToken = fetchHint(token, SqlppHint.GEN_FIELDS_HINT);
3050 if (hintToken != null) {
3051 String hintParams = hintToken.hintParams;
3052 String[] splits = hintParams != null ? hintParams.split("\\s+") : null;
3053 if (splits == null || splits.length != 4) {
3054 throw new SqlppParseException(getSourceLocation(hintToken),
3055 "Expecting: /*+ gen-fields <type> <min> <max> <prefix>*/");
Yingyi Bu391f09e2015-10-29 13:49:39 -07003056 }
Dmitry Lychagine77cdac2019-08-05 11:37:47 -07003057 if (!splits[0].equals("int")) {
3058 throw new SqlppParseException(getSourceLocation(hintToken),
3059 "The only supported type for gen-fields is int.");
3060 }
3061 UndeclaredFieldsDataGen ufdg = new UndeclaredFieldsDataGen(UndeclaredFieldsDataGen.Type.INT,
3062 Integer.parseInt(splits[1]), Integer.parseInt(splits[2]), splits[3]);
3063 recType.setUndeclaredFieldsDataGen(ufdg);
Yingyi Bu391f09e2015-10-29 13:49:39 -07003064 }
Yingyi Bu391f09e2015-10-29 13:49:39 -07003065 }
Dmitry Lychagine77cdac2019-08-05 11:37:47 -07003066 (
3067 RecordField(recType)
3068 ( <COMMA> RecordField(recType) )*
3069 )?
Yingyi Bu391f09e2015-10-29 13:49:39 -07003070 <RIGHTBRACE>
3071 {
Yingyi Bu391f09e2015-10-29 13:49:39 -07003072 recType.setRecordKind(recordKind);
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07003073 return addSourceLocation(recType, startToken);
Yingyi Bu391f09e2015-10-29 13:49:39 -07003074 }
3075}
3076
3077void RecordField(RecordTypeDefinition recType) throws ParseException:
3078{
3079 String fieldName;
3080 TypeExpression type = null;
Dmitry Lychagin3a628022020-05-12 18:09:02 -07003081 boolean nullable = false, missable = false;
Yingyi Bu391f09e2015-10-29 13:49:39 -07003082}
3083{
3084 fieldName = Identifier()
3085 {
Dmitry Lychagine77cdac2019-08-05 11:37:47 -07003086 Token hintToken = fetchHint(token, SqlppHint.VAL_FILE_HINT, SqlppHint.VAL_FILE_SAME_INDEX_HINT,
3087 SqlppHint.LIST_VAL_FILE_HINT, SqlppHint.LIST_HINT, SqlppHint.INTERVAL_HINT, SqlppHint.INSERT_RAND_INT_HINT,
3088 SqlppHint.DATE_BETWEEN_YEARS_HINT, SqlppHint.DATETIME_ADD_RAND_HOURS_HINT, SqlppHint.AUTO_HINT);
3089 IRecordFieldDataGen rfdg = hintToken != null ? parseFieldDataGen(hintToken) : null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07003090 }
Dmitry Lychaginf7bc6c12020-06-01 18:19:44 -07003091 <COLON> type = TypeExpr(true) ( <QUES> { nullable = true; missable = true; } )?
Yingyi Bu391f09e2015-10-29 13:49:39 -07003092 {
Dmitry Lychagin3a628022020-05-12 18:09:02 -07003093 recType.addField(fieldName, type, nullable, missable, rfdg);
Yingyi Bu391f09e2015-10-29 13:49:39 -07003094 }
3095}
3096
3097TypeReferenceExpression TypeReference() throws ParseException:
3098{
Dmitry Lychagin54c06012019-11-13 15:54:20 -08003099 Pair<DataverseName,Identifier> id = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07003100}
3101{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07003102 id = QualifiedName()
3103 {
Dmitry Lychagin75f19872019-10-03 17:56:35 -07003104 if (id.first == null && id.second.getValue().equalsIgnoreCase(INT_TYPE_NAME)) {
3105 id.second = new Identifier(BuiltinType.AINT64.getTypeName());
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07003106 }
Yingyi Bu391f09e2015-10-29 13:49:39 -07003107
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07003108 TypeReferenceExpression typeRef = new TypeReferenceExpression(id);
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07003109 return addSourceLocation(typeRef, token);
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07003110 }
Yingyi Bu391f09e2015-10-29 13:49:39 -07003111}
3112
Dmitry Lychaginf7bc6c12020-06-01 18:19:44 -07003113OrderedListTypeDefinition OrderedListTypeDef(boolean allowRecordTypeDef) throws ParseException:
Yingyi Bu391f09e2015-10-29 13:49:39 -07003114{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07003115 Token startToken = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07003116 TypeExpression type = null;
3117}
3118{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07003119 <LEFTBRACKET> { startToken = token; }
Dmitry Lychaginf7bc6c12020-06-01 18:19:44 -07003120 ( type = TypeExpr(allowRecordTypeDef) )
Yingyi Bu391f09e2015-10-29 13:49:39 -07003121 <RIGHTBRACKET>
3122 {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07003123 OrderedListTypeDefinition typeDef = new OrderedListTypeDefinition(type);
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07003124 return addSourceLocation(typeDef, startToken);
Yingyi Bu391f09e2015-10-29 13:49:39 -07003125 }
3126}
3127
Dmitry Lychaginf7bc6c12020-06-01 18:19:44 -07003128UnorderedListTypeDefinition UnorderedListTypeDef(boolean allowRecordTypeDef) throws ParseException:
Yingyi Bu391f09e2015-10-29 13:49:39 -07003129{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07003130 Token startToken = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07003131 TypeExpression type = null;
3132}
3133{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07003134 <LEFTDBLBRACE> { startToken = token; }
Dmitry Lychaginf7bc6c12020-06-01 18:19:44 -07003135 ( type = TypeExpr(allowRecordTypeDef) )
Yingyi Bu391f09e2015-10-29 13:49:39 -07003136 <RIGHTDBLBRACE>
3137 {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07003138 UnorderedListTypeDefinition typeDef = new UnorderedListTypeDefinition(type);
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07003139 return addSourceLocation(typeDef, startToken);
Yingyi Bu391f09e2015-10-29 13:49:39 -07003140 }
3141}
3142
3143FunctionName FunctionName() throws ParseException:
3144{
Dmitry Lychagin13a40e12021-04-08 18:22:57 -07003145 Triple<List<String>, Token, Token> prefix = null;
Dmitry Lychagin54c06012019-11-13 15:54:20 -08003146 String suffix = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07003147}
3148{
Dmitry Lychagin54c06012019-11-13 15:54:20 -08003149 // Note: there's a copy of this production in PrimaryExpr() (LOOKAHEAD for FunctionCallExpr())
3150 // that copy must be kept in sync with this code
Dmitry Lychagin6fd8ab32020-12-03 09:04:14 -08003151 prefix = MultipartIdentifierWithHints(
Vijay Sarathy243ef2a2022-08-23 11:56:56 -07003152 SqlppHint.INDEXED_NESTED_LOOP_JOIN_HINT, SqlppHint.RANGE_HINT, SqlppHint.HASH_JOIN_HINT, SqlppHint.SKIP_SECONDARY_INDEX_SEARCH_HINT,
Tin Vu4f1090d2021-09-21 02:06:32 -07003153 SqlppHint.SPATIAL_JOIN_HINT, SqlppHint.USE_SECONDARY_INDEX_SEARCH_HINT
Dmitry Lychagin6fd8ab32020-12-03 09:04:14 -08003154 )
Dmitry Lychagin54c06012019-11-13 15:54:20 -08003155 (<SHARP> suffix = Identifier())?
Yingyi Bu391f09e2015-10-29 13:49:39 -07003156 {
Dmitry Lychagin13a40e12021-04-08 18:22:57 -07003157 Token startToken = prefix.second;
Yingyi Bu391f09e2015-10-29 13:49:39 -07003158 FunctionName result = new FunctionName();
Dmitry Lychagin13a40e12021-04-08 18:22:57 -07003159 result.sourceLoc = getSourceLocation(startToken);
Caleb Herbel8d9c57a2020-08-14 20:41:13 -06003160 result.hintToken = prefix.third;
Dmitry Lychagin54c06012019-11-13 15:54:20 -08003161 List<String> list = prefix.first;
3162 int ln = list.size();
3163 String last = list.get(ln - 1);
3164 if (suffix == null) {
3165 // prefix = (dv_part1.dv_part2...dv_partN.)?func_name
3166 // no library name
3167 result.function = last;
3168 } else {
3169 // prefix = (dv_part1.dv_part2...dv_partN.)?lib_name
3170 // suffix = func_name
3171 result.library = last;
3172 result.function = suffix;
Dmitry Lychagine77cdac2019-08-05 11:37:47 -07003173 }
Dmitry Lychagin54c06012019-11-13 15:54:20 -08003174 if (ln > 1) {
Dmitry Lychagin13a40e12021-04-08 18:22:57 -07003175 result.dataverse = createDataverseName(list, 0, ln - 1, startToken);
Dmitry Lychagin54c06012019-11-13 15:54:20 -08003176 } else {
3177 result.dataverse = defaultDataverse;
Yingyi Bu391f09e2015-10-29 13:49:39 -07003178 }
Yingyi Bu391f09e2015-10-29 13:49:39 -07003179
Dmitry Lychagin54c06012019-11-13 15:54:20 -08003180 if (result.function.equalsIgnoreCase(INT_TYPE_NAME)) {
3181 result.function = BuiltinType.AINT64.getTypeName();
Yingyi Bu391f09e2015-10-29 13:49:39 -07003182 }
Dmitry Lychagin54c06012019-11-13 15:54:20 -08003183 return result;
3184 }
Yingyi Bu391f09e2015-10-29 13:49:39 -07003185}
3186
Dmitry Lychagin54c06012019-11-13 15:54:20 -08003187Pair<DataverseName,Identifier> TypeName() throws ParseException:
Yingyi Bu391f09e2015-10-29 13:49:39 -07003188{
Dmitry Lychagin54c06012019-11-13 15:54:20 -08003189 Pair<DataverseName,Identifier> name = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07003190}
3191{
3192 name = QualifiedName()
3193 {
3194 if (name.first == null) {
Dmitry Lychagin54c06012019-11-13 15:54:20 -08003195 name.first = defaultDataverse;
Yingyi Bu391f09e2015-10-29 13:49:39 -07003196 }
3197 return name;
3198 }
3199}
3200
3201String Identifier() throws ParseException:
3202{
3203 String lit = null;
3204}
3205{
3206 (<IDENTIFIER>
3207 {
3208 return token.image;
3209 }
3210 | lit = QuotedString()
3211 {
3212 return lit;
3213 }
3214 )
3215}
3216
Dmitry Lychagin6fd8ab32020-12-03 09:04:14 -08003217List<String> ParenthesizedIdentifierList() throws ParseException:
3218{
3219 List<String> list = new ArrayList<String>();
3220 String ident = null;
3221}
3222{
3223 <LEFTPAREN>
3224 ident = Identifier() { list.add(ident); }
3225 ( <COMMA> ident = Identifier() { list.add(ident); } )*
3226 <RIGHTPAREN>
3227 {
3228 return list;
3229 }
3230}
3231
Vijay Sarathy691e93b2022-11-20 14:31:47 -08003232Pair<HashJoinExpressionAnnotation.BuildOrProbe, String> buildOrProbeParenthesizedIdentifier() throws ParseException:
3233{
3234 String ident1 = null;
3235 String ident2 = null;
3236}
3237{
3238 ident1 = Identifier() <LEFTPAREN> ident2 = Identifier() <RIGHTPAREN>
3239 {
3240 // check
3241 if (ident1.equals("build")) {
3242 return new Pair<HashJoinExpressionAnnotation.BuildOrProbe, String>(HashJoinExpressionAnnotation.BuildOrProbe.BUILD, ident2);
3243 }
3244 else if (ident1.equals("probe")) {
3245 return new Pair<HashJoinExpressionAnnotation.BuildOrProbe, String>(HashJoinExpressionAnnotation.BuildOrProbe.PROBE, ident2);
3246 }
3247 else {
3248 throw new SqlppParseException(getSourceLocation(token), "The string after hashjoin has to be \"build\" or \"probe\".");
3249 }
3250 return null;
3251 }
3252}
3253
3254String parenthesizedIdentifier() throws ParseException:
3255{
3256 String ident = null;
3257}
3258{
3259 <LEFTPAREN> ident = Identifier() <RIGHTPAREN>
3260 {
3261 return ident;
3262 }
3263}
3264
Tin Vu4f1090d2021-09-21 02:06:32 -07003265List<Literal> ParenthesizedLiteralList() throws ParseException:
3266{
3267 List<Literal> list = new ArrayList<Literal>();
3268 boolean minus = false;
3269 Expression litExpr = null;
3270 Literal lit = null;
3271}
3272{
3273 <LEFTPAREN>
3274 (<MINUS> { minus = true; })? litExpr = Literal()
3275 {
3276 lit = ((LiteralExpr) litExpr).getValue();
3277 if (minus)
3278 {
3279 try {
3280 lit = ExpressionUtils.reverseSign(lit);
3281 } catch (TypeMismatchException e) {
3282 throw new SqlppParseException(getSourceLocation(token), e.getMessage());
3283 }
3284 minus = false;
3285 }
3286 list.add(lit);
3287 }
3288 ( <COMMA> (<MINUS> { minus = true; })? litExpr = Literal()
3289 {
3290 lit = ((LiteralExpr) litExpr).getValue();
3291 if (minus)
3292 {
3293 try {
3294 lit = ExpressionUtils.reverseSign(lit);
3295 } catch (TypeMismatchException e) {
3296 throw new SqlppParseException(getSourceLocation(token), e.getMessage());
3297 }
3298 minus = false;
3299 }
3300 list.add(lit);
3301 } )*
3302 <RIGHTPAREN>
3303 {
3304 return list;
3305 }
3306}
3307
Dmitry Lychagin8ba59442017-06-16 14:19:45 -07003308Pair<Integer, Pair<List<String>, IndexedTypeExpression>> OpenField() throws ParseException:
Yingyi Bu391f09e2015-10-29 13:49:39 -07003309{
Dmitry Lychagin8ba59442017-06-16 14:19:45 -07003310 IndexedTypeExpression fieldType = null;
Yingyi Buc9bfe252016-03-01 00:02:40 -08003311 Pair<Integer, List<String>> fieldList = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07003312}
3313{
3314 fieldList = NestedField()
Glenn58329202021-04-09 12:03:46 -07003315 ( <COLON> fieldType = IndexedTypeExpr(true) )?
Yingyi Bu391f09e2015-10-29 13:49:39 -07003316 {
Dmitry Lychagin8ba59442017-06-16 14:19:45 -07003317 return new Pair<Integer, Pair<List<String>, IndexedTypeExpression>>
3318 (fieldList.first, new Pair<List<String>, IndexedTypeExpression>(fieldList.second, fieldType));
Yingyi Bu391f09e2015-10-29 13:49:39 -07003319 }
3320}
3321
Yingyi Buc9bfe252016-03-01 00:02:40 -08003322Pair<Integer, List<String>> NestedField() throws ParseException:
Yingyi Bu391f09e2015-10-29 13:49:39 -07003323{
3324 List<String> exprList = new ArrayList<String>();
3325 String lit = null;
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07003326 Token litToken = null;
Yingyi Buc9bfe252016-03-01 00:02:40 -08003327 int source = 0;
Yingyi Bu391f09e2015-10-29 13:49:39 -07003328}
3329{
3330 lit = Identifier()
3331 {
Yingyi Bub9169b62016-02-26 21:21:49 -08003332 boolean meetParens = false;
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07003333 litToken = token;
Yingyi Bub9169b62016-02-26 21:21:49 -08003334 }
3335 (
Yingyi Buc9bfe252016-03-01 00:02:40 -08003336 LOOKAHEAD(1)
Yingyi Bub9169b62016-02-26 21:21:49 -08003337 <LEFTPAREN><RIGHTPAREN>
3338 {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07003339 if(!lit.equalsIgnoreCase("meta")){
3340 throw new SqlppParseException(getSourceLocation(litToken), "The string before () has to be \"meta\".");
Yingyi Bub9169b62016-02-26 21:21:49 -08003341 }
3342 meetParens = true;
Yingyi Buc9bfe252016-03-01 00:02:40 -08003343 source = 1;
Yingyi Bub9169b62016-02-26 21:21:49 -08003344 }
3345 )?
3346 {
3347 if(!meetParens){
3348 exprList.add(lit);
3349 }
Yingyi Bu391f09e2015-10-29 13:49:39 -07003350 }
3351 (<DOT>
3352 lit = Identifier()
3353 {
3354 exprList.add(lit);
3355 }
3356 )*
3357 {
Yingyi Buc9bfe252016-03-01 00:02:40 -08003358 return new Pair<Integer, List<String>>(source, exprList);
Yingyi Bu391f09e2015-10-29 13:49:39 -07003359 }
3360}
3361
Yingyi Bu6d57e492016-06-06 21:24:42 -07003362String ConstantString() throws ParseException:
3363{
3364 String value = null;
3365}
3366{
3367 (value = QuotedString() | value = StringLiteral())
3368 {
3369 return value;
3370 }
3371}
3372
Yingyi Bu391f09e2015-10-29 13:49:39 -07003373String QuotedString() throws ParseException:
3374{
3375}
3376{
3377 <QUOTED_STRING>
3378 {
3379 return removeQuotesAndEscapes(token.image);
3380 }
3381}
3382
Yingyi Bu391f09e2015-10-29 13:49:39 -07003383String StringLiteral() throws ParseException:
3384{
Dmitry Lychagin984bc522021-10-13 16:22:25 -07003385 StringBuilder str = null;
3386 char quote = 0;
3387 boolean ext = false;
3388 Token litToken = null;
3389 String lit = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07003390}
3391{
Dmitry Lychagin984bc522021-10-13 16:22:25 -07003392 ( <STRING_LITERAL>
Yingyi Bu391f09e2015-10-29 13:49:39 -07003393 {
Dmitry Lychagin984bc522021-10-13 16:22:25 -07003394 String quoted = token.image;
3395 char q = quoted.charAt(0);
3396 boolean e = q == 'E';
3397 if (e) {
3398 q = quoted.charAt(1);
3399 quoted = quoted.substring(1);
3400 }
3401 if (lit == null) {
3402 quote = q;
3403 ext = e;
3404 } else {
3405 boolean isAdjacent = litToken.endLine == token.beginLine && litToken.endColumn + 1 == token.beginColumn;
3406 if (!isAdjacent || ext || e || (q != quote)) {
3407 throw new SqlppParseException(getSourceLocation(token), "Invalid string literal");
3408 }
3409 if (str == null) {
3410 str = new StringBuilder();
3411 }
3412 str.append(lit);
3413 str.append(quote);
3414 }
3415 lit = removeQuotesAndEscapes(quoted);
3416 litToken = token;
Yingyi Bu391f09e2015-10-29 13:49:39 -07003417 }
Dmitry Lychagin984bc522021-10-13 16:22:25 -07003418 )+
3419 {
3420 if (str == null) {
3421 return lit;
3422 } else {
3423 str.append(lit);
3424 return str.toString();
3425 }
3426 }
Yingyi Bu391f09e2015-10-29 13:49:39 -07003427}
3428
Dmitry Lychagin13a40e12021-04-08 18:22:57 -07003429Triple<List<String>, Token, Token> MultipartIdentifier() throws ParseException:
Yingyi Bu391f09e2015-10-29 13:49:39 -07003430{
Dmitry Lychagin13a40e12021-04-08 18:22:57 -07003431 Triple<List<String>, Token, Token> result = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07003432}
3433{
Dmitry Lychagin54c06012019-11-13 15:54:20 -08003434 result = MultipartIdentifierWithHints(null)
Yingyi Bu391f09e2015-10-29 13:49:39 -07003435 {
Dmitry Lychagin13a40e12021-04-08 18:22:57 -07003436 return result;
Yingyi Bu391f09e2015-10-29 13:49:39 -07003437 }
3438}
3439
Dmitry Lychagin13a40e12021-04-08 18:22:57 -07003440Triple<List<String>, Token, Token> MultipartIdentifierWithHints(SqlppHint... expectedHints)
Dmitry Lychagin54c06012019-11-13 15:54:20 -08003441 throws ParseException:
Yingyi Bu391f09e2015-10-29 13:49:39 -07003442{
Dmitry Lychagin54c06012019-11-13 15:54:20 -08003443 List<String> list = new ArrayList<String>();
3444 SourceLocation sourceLoc = null;
Dmitry Lychagin13a40e12021-04-08 18:22:57 -07003445 Token startToken, hintToken = null;
Dmitry Lychagin54c06012019-11-13 15:54:20 -08003446 String item = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07003447}
3448{
Dmitry Lychagin54c06012019-11-13 15:54:20 -08003449 item = Identifier()
Yingyi Bu391f09e2015-10-29 13:49:39 -07003450 {
Dmitry Lychagin54c06012019-11-13 15:54:20 -08003451 list.add(item);
Dmitry Lychagin13a40e12021-04-08 18:22:57 -07003452 startToken = token;
Dmitry Lychagin54c06012019-11-13 15:54:20 -08003453 if (expectedHints != null && expectedHints.length > 0) {
Dmitry Lychagin13a40e12021-04-08 18:22:57 -07003454 hintToken = fetchHint(token, expectedHints);
Yingyi Bu391f09e2015-10-29 13:49:39 -07003455 }
Dmitry Lychagin54c06012019-11-13 15:54:20 -08003456 }
3457 (<DOT> item = Identifier() { list.add(item); } )*
3458 {
Dmitry Lychagin13a40e12021-04-08 18:22:57 -07003459 return new Triple<List<String>, Token, Token>(list, startToken, hintToken);
3460 }
3461}
3462
3463DataverseName DataverseName() throws ParseException:
3464{
3465 Triple<List<String>, Token, Token> ident = null;
3466}
3467{
3468 ident = MultipartIdentifier()
3469 {
3470 List<String> list = ident.first;
3471 Token startToken = ident.second;
3472 return createDataverseName(list, 0, list.size(), startToken);
Dmitry Lychagin54c06012019-11-13 15:54:20 -08003473 }
3474}
3475
3476Pair<DataverseName,Identifier> QualifiedName() throws ParseException:
3477{
Dmitry Lychagin13a40e12021-04-08 18:22:57 -07003478 Triple<List<String>, Token, Token> ident = null;
Dmitry Lychagin54c06012019-11-13 15:54:20 -08003479}
3480{
Dmitry Lychagin13a40e12021-04-08 18:22:57 -07003481 ident = MultipartIdentifier()
Dmitry Lychagin54c06012019-11-13 15:54:20 -08003482 {
Dmitry Lychagin13a40e12021-04-08 18:22:57 -07003483 List<String> list = ident.first;
3484 Token startToken = ident.second;
Dmitry Lychagin54c06012019-11-13 15:54:20 -08003485 int len = list.size();
Dmitry Lychagin13a40e12021-04-08 18:22:57 -07003486 DataverseName id1 = len > 1 ? createDataverseName(list, 0, len - 1, startToken) : null;
Dmitry Lychagin54c06012019-11-13 15:54:20 -08003487 Identifier id2 = new Identifier(list.get(len - 1));
3488 return new Pair<DataverseName,Identifier>(id1, id2);
3489 }
3490}
3491
3492Triple<DataverseName, Identifier, Identifier> DoubleQualifiedName() throws ParseException:
3493{
3494 List<String> list = new ArrayList<String>();
3495 String item = null;
Dmitry Lychagin13a40e12021-04-08 18:22:57 -07003496 Token startToken = null;
Dmitry Lychagin54c06012019-11-13 15:54:20 -08003497}
3498{
Dmitry Lychagin13a40e12021-04-08 18:22:57 -07003499 item = Identifier() { list.add(item); startToken = token; }
Dmitry Lychagin54c06012019-11-13 15:54:20 -08003500 (<DOT> item = Identifier() { list.add(item); } )+
3501 {
3502 int len = list.size();
Dmitry Lychagin13a40e12021-04-08 18:22:57 -07003503 DataverseName id1 = len > 2 ? createDataverseName(list, 0, len - 2, startToken) : null;
Dmitry Lychagin54c06012019-11-13 15:54:20 -08003504 Identifier id2 = new Identifier(list.get(len - 2));
3505 Identifier id3 = new Identifier(list.get(len - 1));
3506 return new Triple<DataverseName,Identifier,Identifier>(id1, id2, id3);
Yingyi Bu391f09e2015-10-29 13:49:39 -07003507 }
3508}
3509
3510FunctionDecl FunctionDeclaration() throws ParseException:
3511{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07003512 Token startToken = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07003513 String functionName;
Dmitry Lychagin541652082020-11-09 14:04:53 -08003514 Pair<Integer, List<Pair<VarIdentifier,TypeExpression>>> paramsWithArity = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07003515 Expression funcBody;
3516 createNewScope();
3517}
3518{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07003519 <DECLARE> { startToken = token; } <FUNCTION>
Xikui Wang3de700a2018-03-15 16:32:55 -07003520 functionName = Identifier()
Dmitry Lychagin541652082020-11-09 14:04:53 -08003521 paramsWithArity = FunctionParameters()
Xikui Wang3de700a2018-03-15 16:32:55 -07003522 <LEFTBRACE>
Dmitry Lychagin0d4c1b62020-02-07 17:10:16 -08003523 funcBody = FunctionBody()
Xikui Wang3de700a2018-03-15 16:32:55 -07003524 <RIGHTBRACE>
3525 {
Dmitry Lychagin541652082020-11-09 14:04:53 -08003526 int arity = paramsWithArity.first;
3527 List<Pair<VarIdentifier,TypeExpression>> paramList = paramsWithArity.second;
3528 FunctionSignature signature = new FunctionSignature(defaultDataverse, functionName, arity);
Xikui Wang3de700a2018-03-15 16:32:55 -07003529 getCurrentScope().addFunctionDescriptor(signature, false);
Dmitry Lychaginf7bc6c12020-06-01 18:19:44 -07003530 ensureNoTypeDeclsInFunction(functionName, paramList, null, startToken);
3531 List<VarIdentifier> params = new ArrayList<VarIdentifier>(paramList.size());
3532 for (Pair<VarIdentifier,TypeExpression> p: paramList) {
3533 params.add(p.getFirst());
Ian Maxon38fe9402020-01-29 19:27:40 -08003534 }
Dmitry Lychagin9ba74872021-04-05 14:38:20 -07003535 FunctionDecl stmt = new FunctionDecl(signature, params, funcBody, false);
Xikui Wang3de700a2018-03-15 16:32:55 -07003536 removeCurrentScope();
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07003537 return addSourceLocation(stmt, startToken);
Xikui Wang3de700a2018-03-15 16:32:55 -07003538 }
Yingyi Bu391f09e2015-10-29 13:49:39 -07003539}
3540
Dmitry Lychaginaebd0312019-06-04 08:55:39 -07003541Query Query() throws ParseException:
Yingyi Bu391f09e2015-10-29 13:49:39 -07003542{
Dmitry Lychaginaebd0312019-06-04 08:55:39 -07003543 Query query = new Query();
Yingyi Bu391f09e2015-10-29 13:49:39 -07003544 Expression expr;
3545}
3546{
3547 (
3548 expr = Expression()
3549 |
3550 expr = SelectExpression(false)
3551 )
3552 {
3553 query.setBody(expr);
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07003554 query.setSourceLocation(expr.getSourceLocation());
Yingyi Bu391f09e2015-10-29 13:49:39 -07003555 return query;
3556 }
3557}
3558
3559
Yingyi Bu391f09e2015-10-29 13:49:39 -07003560Expression Expression():
3561{
3562 Expression expr = null;
3563 Expression exprP = null;
3564}
3565{
3566(
3567 LOOKAHEAD(2)
3568 expr = OperatorExpr()
Yingyi Bu391f09e2015-10-29 13:49:39 -07003569 | expr = QuantifiedExpression()
3570)
3571 {
3572 return (exprP==null) ? expr : exprP;
3573 }
3574}
3575
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07003576Expression OperatorExpr() throws ParseException:
Yingyi Bu391f09e2015-10-29 13:49:39 -07003577{
3578 OperatorExpr op = null;
3579 Expression operand = null;
3580}
3581{
3582 operand = AndExpr()
3583 (
Yingyi Bu391f09e2015-10-29 13:49:39 -07003584 <OR>
3585 {
3586 if (op == null) {
3587 op = new OperatorExpr();
3588 op.addOperand(operand);
Xikui Wang3de700a2018-03-15 16:32:55 -07003589 op.setCurrentop(true);
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07003590 addSourceLocation(op, token);
Yingyi Bu391f09e2015-10-29 13:49:39 -07003591 }
Yingyi Bu196db5d2016-07-15 19:07:20 -07003592 try{
3593 op.addOperator(token.image.toLowerCase());
3594 } catch (Exception e){
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07003595 throw new SqlppParseException(getSourceLocation(token), e.getMessage());
Yingyi Bu196db5d2016-07-15 19:07:20 -07003596 }
Xikui Wang3de700a2018-03-15 16:32:55 -07003597 }
Yingyi Bu391f09e2015-10-29 13:49:39 -07003598
Xikui Wang3de700a2018-03-15 16:32:55 -07003599 operand = AndExpr()
3600 {
3601 op.addOperand(operand);
3602 }
Yingyi Bu391f09e2015-10-29 13:49:39 -07003603
3604 )*
3605
3606 {
3607 return op==null? operand: op;
3608 }
3609}
3610
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07003611Expression AndExpr() throws ParseException:
Yingyi Bu391f09e2015-10-29 13:49:39 -07003612{
3613 OperatorExpr op = null;
3614 Expression operand = null;
3615}
3616{
Yingyi Bu196db5d2016-07-15 19:07:20 -07003617 operand = NotExpr()
Yingyi Bu391f09e2015-10-29 13:49:39 -07003618 (
Yingyi Bu391f09e2015-10-29 13:49:39 -07003619 <AND>
3620 {
3621 if (op == null) {
3622 op = new OperatorExpr();
3623 op.addOperand(operand);
Yingyi Bu196db5d2016-07-15 19:07:20 -07003624 op.setCurrentop(true);
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07003625 addSourceLocation(op, token);
Yingyi Bu391f09e2015-10-29 13:49:39 -07003626 }
Yingyi Bu196db5d2016-07-15 19:07:20 -07003627 try{
3628 op.addOperator(token.image.toLowerCase());
Taewoo Kime65e6ca2017-01-14 17:53:28 -08003629 } catch (CompilationException e){
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07003630 throw new SqlppParseException(getSourceLocation(token), e.getMessage());
Yingyi Bu196db5d2016-07-15 19:07:20 -07003631 }
Yingyi Bu391f09e2015-10-29 13:49:39 -07003632 }
3633
Yingyi Bu196db5d2016-07-15 19:07:20 -07003634 operand = NotExpr()
Yingyi Bu391f09e2015-10-29 13:49:39 -07003635 {
3636 op.addOperand(operand);
3637 }
3638
3639 )*
3640
3641 {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07003642 return op==null ? operand: op;
Yingyi Bu391f09e2015-10-29 13:49:39 -07003643 }
3644}
3645
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07003646Expression NotExpr() throws ParseException:
Yingyi Bu196db5d2016-07-15 19:07:20 -07003647{
3648 Expression inputExpr;
3649 boolean not = false;
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07003650 Token startToken = null;
Yingyi Bu196db5d2016-07-15 19:07:20 -07003651}
3652{
Dmitry Lychagin5476f962019-05-31 16:03:11 -07003653 (LOOKAHEAD(2) <NOT> { not = true; startToken = token; } )? inputExpr = RelExpr()
Yingyi Bu196db5d2016-07-15 19:07:20 -07003654 {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07003655 if(not) {
Dmitry Lychagin7c53fcf2017-11-07 12:07:41 -08003656 FunctionSignature signature = new FunctionSignature(BuiltinFunctions.NOT);
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07003657 CallExpr callExpr = new CallExpr(signature, new ArrayList<Expression>(Collections.singletonList(inputExpr)));
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07003658 return addSourceLocation(callExpr, startToken);
Yingyi Bu196db5d2016-07-15 19:07:20 -07003659 } else {
3660 return inputExpr;
3661 }
3662 }
3663}
Yingyi Bu391f09e2015-10-29 13:49:39 -07003664
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07003665Expression RelExpr() throws ParseException:
Yingyi Bu391f09e2015-10-29 13:49:39 -07003666{
Yingyi Bua8baf6d2016-07-05 21:40:44 -07003667 boolean not = false;
Yingyi Bu391f09e2015-10-29 13:49:39 -07003668 OperatorExpr op = null;
Dmitry Lychagin4d5476e2021-08-18 19:43:22 -07003669 Token opToken = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07003670 Expression operand = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07003671 IExpressionAnnotation annotation = null;
Vijay Sarathy243ef2a2022-08-23 11:56:56 -07003672 List<IExpressionAnnotation> annotationList = new ArrayList<IExpressionAnnotation>();
Yingyi Bu391f09e2015-10-29 13:49:39 -07003673}
3674{
Yingyi Bu6c638342016-09-02 17:54:34 -07003675 operand = BetweenExpr()
Yingyi Bu391f09e2015-10-29 13:49:39 -07003676
3677 (
Dmitry Lychagin4d5476e2021-08-18 19:43:22 -07003678 LOOKAHEAD(3)( <LT> | <GT> | <LE> | <GE> | <EQ> | <NE> | <LG> |<SIMILAR> | (<NOT> { not = true; })? <IN> |
3679 <IS> (<NOT> { not = true; })? <DISTINCT> { opToken = token; } <FROM> )
Yingyi Bu391f09e2015-10-29 13:49:39 -07003680 {
Dmitry Lychagin4d5476e2021-08-18 19:43:22 -07003681 if (opToken == null) {
3682 opToken = token;
3683 }
Dmitry Lychagin6fd8ab32020-12-03 09:04:14 -08003684 Token hintToken = fetchHint(token,
3685 SqlppHint.HASH_BROADCAST_JOIN_HINT, SqlppHint.INDEXED_NESTED_LOOP_JOIN_HINT,
Vijay Sarathy243ef2a2022-08-23 11:56:56 -07003686 SqlppHint.HASH_JOIN_HINT, SqlppHint.SKIP_SECONDARY_INDEX_SEARCH_HINT, SqlppHint.USE_SECONDARY_INDEX_SEARCH_HINT,
3687 SqlppHint.SINGLE_DATASET_PREDICATE_SELECTIVITY_HINT, SqlppHint.JOIN_PREDICATE_PRODUCTIVITY_HINT
Dmitry Lychagin6fd8ab32020-12-03 09:04:14 -08003688 );
Vijay Sarathy243ef2a2022-08-23 11:56:56 -07003689 while (hintToken != null) {
Dmitry Lychagin6fd8ab32020-12-03 09:04:14 -08003690 annotation = parseExpressionAnnotation(hintToken);
Vijay Sarathyebf08b82023-03-20 18:31:35 -07003691 if (annotation != null) {
3692 // annotation may be null if hints are malformed
3693 annotationList.add(annotation);
3694 }
Vijay Sarathy243ef2a2022-08-23 11:56:56 -07003695 hintToken = hintToken.specialToken;
Vijay Sarathy8f4fccd2022-12-05 14:29:02 -08003696 if (hintToken != null) {
3697 SourceLocation sourceLoc = getSourceLocation(hintToken);
3698 hintCollector.remove(sourceLoc);
3699 }
Yingyi Bu391f09e2015-10-29 13:49:39 -07003700 }
Dmitry Lychagin4d5476e2021-08-18 19:43:22 -07003701 String operator = opToken.image.toLowerCase();
Yingyi Bu4a4b8962016-09-16 12:09:11 -07003702 if (operator.equals("<>")){
3703 operator = "!=";
3704 }
3705 if (not) {
Yingyi Bua8baf6d2016-07-05 21:40:44 -07003706 operator = "not_" + operator;
3707 }
Yingyi Bu391f09e2015-10-29 13:49:39 -07003708 if (op == null) {
3709 op = new OperatorExpr();
Shiva2ea73232019-10-09 18:04:05 -07003710 op.addOperand(operand);
Yingyi Bua8baf6d2016-07-05 21:40:44 -07003711 op.setCurrentop(true);
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07003712 addSourceLocation(op, token);
Yingyi Bu391f09e2015-10-29 13:49:39 -07003713 }
Yingyi Bu196db5d2016-07-15 19:07:20 -07003714 try{
3715 op.addOperator(operator);
Taewoo Kime65e6ca2017-01-14 17:53:28 -08003716 } catch (CompilationException e){
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07003717 throw new SqlppParseException(getSourceLocation(token), e.getMessage());
Yingyi Bu196db5d2016-07-15 19:07:20 -07003718 }
Yingyi Bua8baf6d2016-07-05 21:40:44 -07003719 }
Yingyi Bu391f09e2015-10-29 13:49:39 -07003720
Yingyi Bu6c638342016-09-02 17:54:34 -07003721 operand = BetweenExpr()
Yingyi Buea4ec722016-11-04 01:26:16 -07003722 {
Shiva2ea73232019-10-09 18:04:05 -07003723 op.addOperand(operand);
Yingyi Buea4ec722016-11-04 01:26:16 -07003724 }
Yingyi Bu391f09e2015-10-29 13:49:39 -07003725 )?
3726
3727 {
3728 if (annotation != null) {
Vijay Sarathy243ef2a2022-08-23 11:56:56 -07003729 op.addHints(annotationList);
Yingyi Bu391f09e2015-10-29 13:49:39 -07003730 }
3731 return op==null? operand: op;
3732 }
3733}
3734
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07003735Expression BetweenExpr() throws ParseException:
Yingyi Bu6c638342016-09-02 17:54:34 -07003736{
3737 boolean not = false;
3738 OperatorExpr op = null;
3739 Expression operand = null;
3740 IExpressionAnnotation annotation = null;
3741}
3742{
3743 operand = IsExpr()
3744 (
3745 LOOKAHEAD(2)
3746 (<NOT> { not = true; })? <BETWEEN>
3747 {
Dmitry Lychagin6fd8ab32020-12-03 09:04:14 -08003748 Token hintToken = fetchHint(token,
Vijay Sarathy243ef2a2022-08-23 11:56:56 -07003749 SqlppHint.INDEXED_NESTED_LOOP_JOIN_HINT, SqlppHint.SKIP_SECONDARY_INDEX_SEARCH_HINT, SqlppHint.HASH_JOIN_HINT,
3750 SqlppHint.USE_SECONDARY_INDEX_SEARCH_HINT, SqlppHint.SINGLE_DATASET_PREDICATE_SELECTIVITY_HINT
Dmitry Lychagin6fd8ab32020-12-03 09:04:14 -08003751 );
Dmitry Lychagine77cdac2019-08-05 11:37:47 -07003752 if (hintToken != null) {
Dmitry Lychagin6fd8ab32020-12-03 09:04:14 -08003753 annotation = parseExpressionAnnotation(hintToken);
Yingyi Bu6c638342016-09-02 17:54:34 -07003754 }
3755 String operator = token.image.toLowerCase();
3756 if(not){
3757 operator = "not_" + operator;
3758 }
3759 if (op == null) {
3760 op = new OperatorExpr();
3761 op.addOperand(operand);
3762 op.setCurrentop(true);
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07003763 addSourceLocation(op, token);
Yingyi Bu6c638342016-09-02 17:54:34 -07003764 }
3765 try{
3766 op.addOperator(operator);
Taewoo Kime65e6ca2017-01-14 17:53:28 -08003767 } catch (CompilationException e){
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07003768 throw new SqlppParseException(getSourceLocation(token), e.getMessage());
Yingyi Bu6c638342016-09-02 17:54:34 -07003769 }
3770 }
3771
3772 operand = IsExpr()
3773 {
3774 op.addOperand(operand);
3775 }
3776
3777 <AND>
3778 operand = IsExpr()
3779 {
Dmitry Lychaginef1719e2017-12-15 08:33:07 -08003780 op.addOperator(OperatorType.AND);
Yingyi Bu6c638342016-09-02 17:54:34 -07003781 op.addOperand(operand);
3782 }
3783 )?
3784
3785 {
3786 if (annotation != null) {
3787 op.addHint(annotation);
3788 }
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07003789 return op==null ? operand: op;
Yingyi Bu6c638342016-09-02 17:54:34 -07003790 }
3791}
3792
Yingyi Budaa549c2016-06-28 22:30:52 -07003793Expression IsExpr() throws ParseException:
3794{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07003795 Token notToken = null;
3796 CallExpr expr = null;
Yingyi Budaa549c2016-06-28 22:30:52 -07003797 Expression operand = null;
3798 boolean not = false;
Dmitry Lychagin7c53fcf2017-11-07 12:07:41 -08003799 FunctionIdentifier fn = null;
Yingyi Budaa549c2016-06-28 22:30:52 -07003800}
3801{
Yingyi Bu6e6a80c2017-01-21 20:18:49 -08003802 operand = LikeExpr()
Dmitry Lychagin4d5476e2021-08-18 19:43:22 -07003803 (
3804 LOOKAHEAD(3)
3805 <IS>
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07003806 (<NOT> { not = true; notToken = token; })?
Dmitry Lychagin7c53fcf2017-11-07 12:07:41 -08003807 (
3808 <NULL> { fn = BuiltinFunctions.IS_NULL; } |
3809 <MISSING> { fn = BuiltinFunctions.IS_MISSING; } |
Dmitry Lychagin7d594a32018-01-15 14:31:03 -08003810 <UNKNOWN> { fn = BuiltinFunctions.IS_UNKNOWN; } |
Dmitry Lychagin1aa0dd42018-04-17 14:35:24 -07003811 (<KNOWN> | <VALUED>) { not = !not; fn = BuiltinFunctions.IS_UNKNOWN; }
Dmitry Lychagin7c53fcf2017-11-07 12:07:41 -08003812 )
Yingyi Budaa549c2016-06-28 22:30:52 -07003813 {
Dmitry Lychagin7c53fcf2017-11-07 12:07:41 -08003814 FunctionSignature signature = new FunctionSignature(fn);
Yingyi Budaa549c2016-06-28 22:30:52 -07003815 expr = new CallExpr(signature, new ArrayList<Expression>(Collections.singletonList(operand)));
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07003816 addSourceLocation(expr, token);
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07003817 if (not) {
Dmitry Lychagin7c53fcf2017-11-07 12:07:41 -08003818 FunctionSignature notSignature = new FunctionSignature(BuiltinFunctions.NOT);
Yingyi Budaa549c2016-06-28 22:30:52 -07003819 expr = new CallExpr(notSignature, new ArrayList<Expression>(Collections.singletonList(expr)));
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07003820 addSourceLocation(expr, notToken);
Yingyi Budaa549c2016-06-28 22:30:52 -07003821 }
3822 }
3823 )?
3824 {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07003825 return expr == null ? operand : expr;
Yingyi Budaa549c2016-06-28 22:30:52 -07003826 }
3827}
3828
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07003829Expression LikeExpr() throws ParseException:
Yingyi Bu6e6a80c2017-01-21 20:18:49 -08003830{
3831 boolean not = false;
3832 OperatorExpr op = null;
3833 Expression operand = null;
Vijay Sarathy243ef2a2022-08-23 11:56:56 -07003834 IExpressionAnnotation annotation = null;
Yingyi Bu6e6a80c2017-01-21 20:18:49 -08003835}
3836{
3837 operand = ConcatExpr()
3838 (
3839 LOOKAHEAD(2)
3840 (<NOT> { not = true; })? <LIKE>
3841 {
Vijay Sarathy243ef2a2022-08-23 11:56:56 -07003842 Token hintToken = fetchHint(token, SqlppHint.SINGLE_DATASET_PREDICATE_SELECTIVITY_HINT);
3843 if (hintToken != null) {
3844 annotation = parseExpressionAnnotation(hintToken);
3845 }
Yingyi Bu6e6a80c2017-01-21 20:18:49 -08003846 op = new OperatorExpr();
3847 op.addOperand(operand);
3848 op.setCurrentop(true);
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07003849 addSourceLocation(op, token);
Yingyi Bu6e6a80c2017-01-21 20:18:49 -08003850
3851 String operator = token.image.toLowerCase();
3852 if (not) {
3853 operator = "not_" + operator;
3854 }
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07003855 try {
Yingyi Bu6e6a80c2017-01-21 20:18:49 -08003856 op.addOperator(operator);
3857 } catch (CompilationException e){
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07003858 throw new SqlppParseException(getSourceLocation(token), e.getMessage());
Yingyi Bu6e6a80c2017-01-21 20:18:49 -08003859 }
Vijay Sarathy243ef2a2022-08-23 11:56:56 -07003860 if (annotation != null) {
3861 op.addHint(annotation);
3862 }
Yingyi Bu6e6a80c2017-01-21 20:18:49 -08003863 }
3864
3865 operand = ConcatExpr()
3866 {
3867 op.addOperand(operand);
3868 }
3869 )?
3870
3871 {
3872 return op == null ? operand : op;
3873 }
3874}
3875
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07003876Expression ConcatExpr() throws ParseException:
Yingyi Bufdc71eb2016-08-24 22:41:57 -07003877{
3878 OperatorExpr op = null;
3879 Expression operand = null;
3880}
3881{
3882 operand = AddExpr()
3883 (
3884 LOOKAHEAD(1)
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07003885 <CONCAT>
Yingyi Bufdc71eb2016-08-24 22:41:57 -07003886 {
3887 if (op == null) {
3888 op = new OperatorExpr();
3889 op.addOperand(operand);
3890 op.setCurrentop(true);
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07003891 addSourceLocation(op, token);
Yingyi Bufdc71eb2016-08-24 22:41:57 -07003892 }
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07003893 op.addOperator(OperatorType.CONCAT);
Yingyi Bufdc71eb2016-08-24 22:41:57 -07003894 }
3895 operand = AddExpr()
3896 {
3897 op.addOperand(operand);
3898 }
3899 )*
3900
3901 {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07003902 return op == null ? operand : op;
Yingyi Bufdc71eb2016-08-24 22:41:57 -07003903 }
3904}
Yingyi Budaa549c2016-06-28 22:30:52 -07003905
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07003906Expression AddExpr() throws ParseException:
Yingyi Bu391f09e2015-10-29 13:49:39 -07003907{
3908 OperatorExpr op = null;
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07003909 OperatorType opType = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07003910 Expression operand = null;
3911}
3912{
3913 operand = MultExpr()
Yingyi Budaa549c2016-06-28 22:30:52 -07003914 (
Yingyi Bufdc71eb2016-08-24 22:41:57 -07003915 LOOKAHEAD(1)
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07003916 (<PLUS> { opType = OperatorType.PLUS; } | <MINUS> { opType = OperatorType.MINUS; } )
Yingyi Bu391f09e2015-10-29 13:49:39 -07003917 {
3918 if (op == null) {
3919 op = new OperatorExpr();
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07003920 op.addOperand(operand);
3921 op.setCurrentop(true);
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07003922 addSourceLocation(op, token);
Yingyi Bu391f09e2015-10-29 13:49:39 -07003923 }
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07003924 op.addOperator(opType);
Yingyi Bu391f09e2015-10-29 13:49:39 -07003925 }
3926
3927 operand = MultExpr()
3928 {
3929 op.addOperand(operand);
3930 }
3931 )*
3932
3933 {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07003934 return op == null ? operand : op;
Yingyi Bu391f09e2015-10-29 13:49:39 -07003935 }
3936}
3937
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07003938Expression MultExpr() throws ParseException:
Yingyi Bu391f09e2015-10-29 13:49:39 -07003939{
3940 OperatorExpr op = null;
Dmitry Lychaginbf48c492018-05-01 18:30:27 -07003941 OperatorType opType = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07003942 Expression operand = null;
3943}
3944{
Yingyi Bu79ccdac2016-07-26 23:49:24 -07003945 operand = ExponentExpr()
Yingyi Bu391f09e2015-10-29 13:49:39 -07003946
Dmitry Lychaginbf48c492018-05-01 18:30:27 -07003947 ( (
3948 <MUL> { opType = OperatorType.MUL; } |
3949 <DIVIDE> { opType = OperatorType.DIVIDE; } |
3950 <DIV> { opType = OperatorType.DIV; } |
3951 ( <MOD> | <PERCENT> ) { opType = OperatorType.MOD; }
3952 )
Yingyi Bu391f09e2015-10-29 13:49:39 -07003953 {
3954 if (op == null) {
3955 op = new OperatorExpr();
Yingyi Bu79ccdac2016-07-26 23:49:24 -07003956 op.addOperand(operand);
3957 op.setCurrentop(true);
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07003958 addSourceLocation(op, token);
Yingyi Bu79ccdac2016-07-26 23:49:24 -07003959 }
Dmitry Lychaginbf48c492018-05-01 18:30:27 -07003960 op.addOperator(opType);
Yingyi Bu79ccdac2016-07-26 23:49:24 -07003961 }
3962 operand = ExponentExpr()
3963 {
3964 op.addOperand(operand);
3965 }
3966 )*
3967
3968 {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07003969 return op == null ? operand : op;
Yingyi Bu79ccdac2016-07-26 23:49:24 -07003970 }
3971}
3972
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07003973Expression ExponentExpr() throws ParseException:
Yingyi Bu79ccdac2016-07-26 23:49:24 -07003974{
3975 OperatorExpr op = null;
3976 Expression operand = null;
3977}
3978{
3979 operand = UnaryExpr()
3980 (<CARET>
3981 {
3982 if (op == null) {
3983 op = new OperatorExpr();
3984 op.addOperand(operand);
3985 op.setCurrentop(true);
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07003986 addSourceLocation(op, token);
Yingyi Bu391f09e2015-10-29 13:49:39 -07003987 }
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07003988 op.addOperator(OperatorType.CARET);
Yingyi Bu391f09e2015-10-29 13:49:39 -07003989 }
3990 operand = UnaryExpr()
3991 {
3992 op.addOperand(operand);
3993 }
Yingyi Bu79ccdac2016-07-26 23:49:24 -07003994 )?
3995 {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07003996 return op == null ? operand : op;
Yingyi Bu79ccdac2016-07-26 23:49:24 -07003997 }
Yingyi Bu391f09e2015-10-29 13:49:39 -07003998}
3999
4000Expression UnaryExpr() throws ParseException:
4001{
Yingyi Bu196db5d2016-07-15 19:07:20 -07004002 boolean not = false;
4003 UnaryExpr uexpr = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07004004 Expression expr = null;
4005}
Yingyi Budaa549c2016-06-28 22:30:52 -07004006{
Yingyi Bu196db5d2016-07-15 19:07:20 -07004007 ( (<PLUS> | <MINUS> | (<NOT> { not = true; } )? <EXISTS> )
Yingyi Bu391f09e2015-10-29 13:49:39 -07004008 {
Yingyi Bu196db5d2016-07-15 19:07:20 -07004009 String exprType = token.image.toLowerCase();
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07004010 if (not) {
Yingyi Bu196db5d2016-07-15 19:07:20 -07004011 exprType = "not_" + exprType;
4012 }
4013 uexpr = new UnaryExpr();
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07004014 addSourceLocation(uexpr, token);
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07004015 try {
Yingyi Bu196db5d2016-07-15 19:07:20 -07004016 uexpr.setExprType(exprType);
Taewoo Kime65e6ca2017-01-14 17:53:28 -08004017 } catch (CompilationException e){
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07004018 throw new SqlppParseException(getSourceLocation(token), e.getMessage());
Yingyi Budaa549c2016-06-28 22:30:52 -07004019 }
Yingyi Bu391f09e2015-10-29 13:49:39 -07004020 }
4021 )?
4022
4023 expr = ValueExpr()
4024 {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07004025 if (uexpr == null) {
4026 return expr;
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07004027 } else {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07004028 uexpr.setExpr(expr);
4029 return uexpr;
4030 }
Yingyi Bu391f09e2015-10-29 13:49:39 -07004031 }
4032}
4033
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07004034Expression ValueExpr() throws ParseException:
Yingyi Bu391f09e2015-10-29 13:49:39 -07004035{
4036 Expression expr = null;
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07004037 AbstractAccessor accessor = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07004038}
4039{
Hussain Towailebc5b5deb2018-12-15 18:48:48 +03004040 expr = PrimaryExpr()
4041 (
4042 accessor = FieldAccessor(accessor != null ? accessor : expr)
4043 |
4044 accessor = IndexAccessor(accessor != null ? accessor : expr)
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07004045 )*
4046 {
4047 return accessor == null ? expr : accessor;
4048 }
Yingyi Bu391f09e2015-10-29 13:49:39 -07004049}
4050
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07004051FieldAccessor FieldAccessor(Expression inputExpr) throws ParseException:
Yingyi Bu391f09e2015-10-29 13:49:39 -07004052{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07004053 Token startToken = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07004054 String ident = null;
4055}
4056{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07004057 <DOT> { startToken = token; } ident = Identifier()
Yingyi Bu391f09e2015-10-29 13:49:39 -07004058 {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07004059 FieldAccessor fa = new FieldAccessor(inputExpr, new Identifier(ident));
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07004060 return addSourceLocation(fa, startToken);
Yingyi Bu391f09e2015-10-29 13:49:39 -07004061 }
4062}
4063
Hussain Towailebc5b5deb2018-12-15 18:48:48 +03004064AbstractAccessor IndexAccessor(Expression inputExpr) throws ParseException:
Yingyi Bu391f09e2015-10-29 13:49:39 -07004065{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07004066 Token startToken = null;
Dmitry Lychagin0a722532020-08-27 18:39:25 -07004067 boolean star = false, slice = false;
4068 Expression expr1 = null, expr2 = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07004069}
4070{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07004071 <LEFTBRACKET> { startToken = token; }
Dmitry Lychagin0a722532020-08-27 18:39:25 -07004072 (
4073 <MUL> { star = true; }
4074 |
4075 ( expr1 = Expression() ( <COLON> { slice = true; } ( expr2 = Expression() )? )? )
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07004076 )
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07004077 <RIGHTBRACKET>
4078 {
Dmitry Lychagin0a722532020-08-27 18:39:25 -07004079 if (expr1 != null && expr1.getKind() == Expression.Kind.LITERAL_EXPRESSION) {
4080 ensureIntegerLiteral( (LiteralExpr) expr1, "Index");
Hussain Towailebc5b5deb2018-12-15 18:48:48 +03004081 }
Dmitry Lychagin0a722532020-08-27 18:39:25 -07004082 if (expr2 != null && expr2.getKind() == Expression.Kind.LITERAL_EXPRESSION) {
4083 ensureIntegerLiteral( (LiteralExpr) expr2, "Index");
4084 }
4085 AbstractAccessor resultAccessor;
4086 if (slice) {
4087 resultAccessor = new ListSliceExpression(inputExpr, expr1, expr2);
4088 } else if (star) {
4089 resultAccessor = new IndexAccessor(inputExpr, IndexAccessor.IndexKind.STAR, null);
4090 } else {
4091 resultAccessor = new IndexAccessor(inputExpr, IndexAccessor.IndexKind.ELEMENT, expr1);
4092 }
4093 return addSourceLocation(resultAccessor, startToken);
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07004094 }
Yingyi Bu391f09e2015-10-29 13:49:39 -07004095}
4096
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07004097Expression PrimaryExpr() throws ParseException:
Yingyi Bu391f09e2015-10-29 13:49:39 -07004098{
4099 Expression expr = null;
4100}
4101{
Dmitry Lychagin54c06012019-11-13 15:54:20 -08004102 (
4103 LOOKAHEAD(Identifier() (<DOT> Identifier())* (<SHARP> Identifier())? <LEFTPAREN>) expr = FunctionCallExpr()
Dmitry Lychagin5fbd04b2018-04-19 16:54:28 -07004104 | expr = CaseExpr()
Yingyi Bu391f09e2015-10-29 13:49:39 -07004105 | expr = Literal()
4106 | expr = VariableRef()
Dmitry Lychagin1bdf8082018-06-13 14:48:23 -07004107 | expr = ExternalVariableRef()
Yingyi Bu391f09e2015-10-29 13:49:39 -07004108 | expr = ListConstructor()
4109 | expr = RecordConstructor()
4110 | expr = ParenthesizedExpression()
4111 )
4112 {
4113 return expr;
4114 }
4115}
4116
4117Expression Literal() throws ParseException:
4118{
4119 LiteralExpr lit = new LiteralExpr();
4120 String str = null;
4121}
4122{
4123 ( str = StringLiteral()
4124 {
4125 lit.setValue(new StringLiteral(str));
4126 }
4127 | <INTEGER_LITERAL>
4128 {
Till Westmann68c6a992016-09-30 00:19:12 -07004129 try {
4130 lit.setValue(new LongIntegerLiteral(Long.valueOf(token.image)));
4131 } catch (NumberFormatException e) {
Ali Alsuliman587b7902019-01-21 14:33:50 -08004132 throw new SqlppParseException(getSourceLocation(token), "Could not parse numeric literal \"" + LogRedactionUtil.userData(token.image) +'"');
Till Westmann68c6a992016-09-30 00:19:12 -07004133 }
Yingyi Bu391f09e2015-10-29 13:49:39 -07004134 }
4135 | <FLOAT_LITERAL>
4136 {
Till Westmann68c6a992016-09-30 00:19:12 -07004137 try {
4138 lit.setValue(new FloatLiteral(Float.valueOf(token.image)));
4139 } catch (NumberFormatException e) {
Ali Alsuliman587b7902019-01-21 14:33:50 -08004140 throw new SqlppParseException(getSourceLocation(token), "Could not parse numeric literal \"" + LogRedactionUtil.userData(token.image) +'"');
Till Westmann68c6a992016-09-30 00:19:12 -07004141 }
Yingyi Bu391f09e2015-10-29 13:49:39 -07004142 }
4143 | <DOUBLE_LITERAL>
4144 {
Till Westmann68c6a992016-09-30 00:19:12 -07004145 try {
4146 lit.setValue(new DoubleLiteral(Double.valueOf(token.image)));
4147 } catch (NumberFormatException e) {
Ali Alsuliman587b7902019-01-21 14:33:50 -08004148 throw new SqlppParseException(getSourceLocation(token), "Could not parse numeric literal \"" + LogRedactionUtil.userData(token.image) +'"');
Till Westmann68c6a992016-09-30 00:19:12 -07004149 }
Yingyi Bu391f09e2015-10-29 13:49:39 -07004150 }
Yingyi Bu535d86b2016-05-23 16:44:25 -07004151 | <MISSING>
4152 {
4153 lit.setValue(MissingLiteral.INSTANCE);
4154 }
Yingyi Bu391f09e2015-10-29 13:49:39 -07004155 | <NULL>
4156 {
4157 lit.setValue(NullLiteral.INSTANCE);
4158 }
4159 | <TRUE>
4160 {
4161 lit.setValue(TrueLiteral.INSTANCE);
4162 }
4163 | <FALSE>
4164 {
4165 lit.setValue(FalseLiteral.INSTANCE);
4166 }
4167 )
4168 {
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07004169 return addSourceLocation(lit, token);
Yingyi Bu391f09e2015-10-29 13:49:39 -07004170 }
4171}
4172
Yingyi Bu391f09e2015-10-29 13:49:39 -07004173VariableExpr VariableRef() throws ParseException:
4174{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07004175 String id = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07004176}
4177{
Dmitry Lychagin0d4c1b62020-02-07 17:10:16 -08004178 id = VariableIdentifier()
Yingyi Bu391f09e2015-10-29 13:49:39 -07004179 {
4180 Identifier ident = lookupSymbol(id);
4181 if (isInForbiddenScopes(id)) {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07004182 throw new SqlppParseException(getSourceLocation(token),
4183 "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 -07004184 }
Dmitry Lychagin75f19872019-10-03 17:56:35 -07004185 VariableExpr varExp;
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07004186 if (ident != null) { // exist such ident
Dmitry Lychagin75f19872019-10-03 17:56:35 -07004187 varExp = new VariableExpr((VarIdentifier)ident);
Yingyi Bu391f09e2015-10-29 13:49:39 -07004188 } else {
Dmitry Lychagin75f19872019-10-03 17:56:35 -07004189 varExp = new VariableExpr(new VarIdentifier(id));
Yingyi Buacc12a92016-03-26 17:25:05 -07004190 varExp.setIsNewVar(false);
Yingyi Bu391f09e2015-10-29 13:49:39 -07004191 }
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07004192 return addSourceLocation(varExp, token);
Yingyi Bu391f09e2015-10-29 13:49:39 -07004193 }
4194}
4195
Yingyi Bu391f09e2015-10-29 13:49:39 -07004196VariableExpr Variable() throws ParseException:
4197{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07004198 String id = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07004199}
4200{
Dmitry Lychagin0d4c1b62020-02-07 17:10:16 -08004201 id = VariableIdentifier()
Yingyi Bu391f09e2015-10-29 13:49:39 -07004202 {
4203 Identifier ident = lookupSymbol(id);
Dmitry Lychagin75f19872019-10-03 17:56:35 -07004204 VariableExpr varExp = new VariableExpr(new VarIdentifier(id));
4205 if (ident != null) { // exist such ident
Yingyi Bu391f09e2015-10-29 13:49:39 -07004206 varExp.setIsNewVar(false);
4207 }
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07004208 return addSourceLocation(varExp, token);
Yingyi Bu391f09e2015-10-29 13:49:39 -07004209 }
4210}
4211
Dmitry Lychagin0d4c1b62020-02-07 17:10:16 -08004212String VariableIdentifier() throws ParseException:
4213{
4214 String id = null;
4215}
4216{
4217 (<IDENTIFIER> { id = token.image; } | id = QuotedString())
4218 {
4219 return SqlppVariableUtil.toInternalVariableName(id); // prefix user-defined variables with "$".
4220 }
4221}
4222
Dmitry Lychaginf2c18aa2018-12-28 21:20:23 -08004223Pair<VariableExpr, List<Pair<Expression, Identifier>>> VariableWithFieldMap() throws ParseException:
4224{
4225 VariableExpr var = null;
4226 List<Pair<Expression, Identifier>> fieldList = new ArrayList<Pair<Expression, Identifier>>();
4227}
4228{
4229 var = Variable()
4230 ( LOOKAHEAD(1)
4231 {
4232 VariableExpr fieldVarExpr = null;
4233 String fieldIdentifierStr = null;
4234 }
4235 <LEFTPAREN>
4236 fieldVarExpr = VariableRef() <AS> fieldIdentifierStr = Identifier()
4237 {
4238 fieldList.add(new Pair<Expression, Identifier>(fieldVarExpr, new Identifier(fieldIdentifierStr)));
4239 }
4240 (<COMMA>
4241 fieldVarExpr = VariableRef() <AS> fieldIdentifierStr = Identifier()
4242 {
4243 fieldList.add(new Pair<Expression, Identifier>(fieldVarExpr, new Identifier(fieldIdentifierStr)));
4244 }
4245 )*
4246 <RIGHTPAREN>
4247 )?
4248 {
4249 return new Pair<VariableExpr, List<Pair<Expression, Identifier>>>(var, fieldList);
4250 }
4251}
4252
Dmitry Lychagin1bdf8082018-06-13 14:48:23 -07004253VariableExpr ExternalVariableRef() throws ParseException:
4254{
4255 String name = null;
4256}
4257{
4258 (
Dmitry Lychagin41b511d2020-12-07 14:48:13 -08004259 <DOLLAR_IDENTIFIER> { name = token.image.substring(1); }
4260 | <DOLLAR_INTEGER_LITERAL> { name = token.image.substring(1); }
4261 | <DOLLAR_QUOTED_STRING> { name = removeQuotesAndEscapes(token.image.substring(1)); }
4262 | <QUES> { name = String.valueOf(++externalVarCounter); }
Dmitry Lychagin1bdf8082018-06-13 14:48:23 -07004263 )
4264 {
4265 String idName = SqlppVariableUtil.toExternalVariableName(name);
4266 VarIdentifier id = new VarIdentifier(idName);
4267 VariableExpr varExp = new VariableExpr(id);
4268 return addSourceLocation(varExp, token);
4269 }
4270}
4271
Yingyi Bu391f09e2015-10-29 13:49:39 -07004272Expression ListConstructor() throws ParseException:
4273{
4274 Expression expr = null;
4275}
4276{
4277 (
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07004278 expr = OrderedListConstructor() |
4279 expr = UnorderedListConstructor()
Yingyi Bu391f09e2015-10-29 13:49:39 -07004280 )
Yingyi Bu391f09e2015-10-29 13:49:39 -07004281 {
4282 return expr;
4283 }
4284}
4285
Yingyi Bu391f09e2015-10-29 13:49:39 -07004286ListConstructor OrderedListConstructor() throws ParseException:
4287{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07004288 Token startToken = null;
4289 List<Expression> exprList = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07004290}
4291{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07004292 <LEFTBRACKET> { startToken = token; }
4293 exprList = ExpressionList()
4294 <RIGHTBRACKET>
4295 {
4296 ListConstructor expr = new ListConstructor(ListConstructor.Type.ORDERED_LIST_CONSTRUCTOR, exprList);
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07004297 return addSourceLocation(expr, startToken);
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07004298 }
Yingyi Bu391f09e2015-10-29 13:49:39 -07004299}
4300
4301ListConstructor UnorderedListConstructor() throws ParseException:
4302{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07004303 Token startToken = null;
4304 List<Expression> exprList = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07004305}
4306{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07004307 <LEFTDBLBRACE> { startToken = token; }
4308 exprList = ExpressionList()
4309 <RIGHTDBLBRACE>
4310 {
4311 ListConstructor expr = new ListConstructor(ListConstructor.Type.UNORDERED_LIST_CONSTRUCTOR, exprList);
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07004312 return addSourceLocation(expr, startToken);
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07004313 }
Yingyi Bu391f09e2015-10-29 13:49:39 -07004314}
4315
4316List<Expression> ExpressionList() throws ParseException:
4317{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07004318 Expression expr = null;
4319 List<Expression> exprList = new ArrayList<Expression>();
Yingyi Bu391f09e2015-10-29 13:49:39 -07004320}
4321{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07004322 (
4323 expr = Expression()
4324 {
4325 exprList.add(expr);
4326 }
4327 ( <COMMA> expr = Expression()
Till Westmann60f89982017-08-11 18:14:20 -07004328 {
4329 exprList.add(expr);
4330 }
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07004331 )*
4332 )?
4333 {
4334 return exprList;
4335 }
Yingyi Bu391f09e2015-10-29 13:49:39 -07004336}
4337
Yingyi Bu391f09e2015-10-29 13:49:39 -07004338RecordConstructor RecordConstructor() throws ParseException:
4339{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07004340 Token startToken = null;
4341 FieldBinding fb = null;
4342 List<FieldBinding> fbList = new ArrayList<FieldBinding>();
Yingyi Bu391f09e2015-10-29 13:49:39 -07004343}
4344{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07004345 <LEFTBRACE> { startToken = token; }
4346 (
4347 fb = FieldBinding() { fbList.add(fb); }
4348 (<COMMA> fb = FieldBinding() { fbList.add(fb); })*
4349 )?
4350 <RIGHTBRACE>
4351 {
4352 RecordConstructor expr = new RecordConstructor(fbList);
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07004353 return addSourceLocation(expr, startToken);
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07004354 }
Yingyi Bu391f09e2015-10-29 13:49:39 -07004355}
4356
4357FieldBinding FieldBinding() throws ParseException:
4358{
Dmitry Lychagincdcb9232019-06-04 13:27:03 -07004359 Expression left, right = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07004360}
4361{
Dmitry Lychagincdcb9232019-06-04 13:27:03 -07004362 left = Expression() ( <COLON> right = Expression() )?
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07004363 {
Dmitry Lychagincdcb9232019-06-04 13:27:03 -07004364 if (right == null) {
4365 String generatedIdentifier = ExpressionToVariableUtil.getGeneratedIdentifier(left, false);
4366 if (generatedIdentifier == null) {
4367 throw new SqlppParseException(getSourceLocation(token), "Cannot infer field name");
4368 }
4369 String generatedName = SqlppVariableUtil.toUserDefinedName(generatedIdentifier);
Ali Alsuliman5760e9e2019-08-22 16:37:36 -07004370 LiteralExpr generatedNameExpr = new LiteralExpr(new StringLiteral(generatedName));
4371 generatedNameExpr.setSourceLocation(left.getSourceLocation());
4372 return new FieldBinding(generatedNameExpr, left);
Dmitry Lychagincdcb9232019-06-04 13:27:03 -07004373 } else {
4374 return new FieldBinding(left, right);
4375 }
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07004376 }
Yingyi Bu391f09e2015-10-29 13:49:39 -07004377}
4378
Yingyi Bu391f09e2015-10-29 13:49:39 -07004379Expression FunctionCallExpr() throws ParseException:
4380{
Yingyi Bu391f09e2015-10-29 13:49:39 -07004381 List<Expression> argList = new ArrayList<Expression>();
Dmitry Lychagin9d469592020-06-01 15:42:51 -07004382 Expression argExpr = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07004383 FunctionName funcName = null;
Yingyi Buf4d09842016-08-26 00:03:52 -07004384 boolean star = false;
Dmitry Lychagin7a4b5682017-09-11 18:53:07 -07004385 boolean distinct = false;
Dmitry Lychagin9d469592020-06-01 15:42:51 -07004386 Expression filterExpr = null;
4387 WindowExpression windowExpr = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07004388}
4389{
4390 funcName = FunctionName()
Dmitry Lychagin7a4b5682017-09-11 18:53:07 -07004391 <LEFTPAREN> (
4392 ( <DISTINCT> { distinct = true; } )?
Dmitry Lychagin9d469592020-06-01 15:42:51 -07004393 ( argExpr = Expression() | <MUL> { star = true; } )
Yingyi Bu391f09e2015-10-29 13:49:39 -07004394 {
Dmitry Lychagin9d469592020-06-01 15:42:51 -07004395 if (star) {
4396 if (funcName.function.equalsIgnoreCase(BuiltinFunctions.SCALAR_COUNT.getName())) {
4397 argExpr = new LiteralExpr(new LongIntegerLiteral(1L));
4398 } else {
4399 throw new SqlppParseException(getSourceLocation(token),
4400 "The parameter * can only be used in " + BuiltinFunctions.SCALAR_COUNT.getName() + "().");
Yingyi Buf4d09842016-08-26 00:03:52 -07004401 }
Yingyi Buf4d09842016-08-26 00:03:52 -07004402 }
Dmitry Lychagin9d469592020-06-01 15:42:51 -07004403 argList.add(argExpr);
Yingyi Bu391f09e2015-10-29 13:49:39 -07004404 }
Dmitry Lychagin9d469592020-06-01 15:42:51 -07004405 (<COMMA> argExpr = Expression()
Yingyi Bu391f09e2015-10-29 13:49:39 -07004406 {
Dmitry Lychagin9d469592020-06-01 15:42:51 -07004407 argList.add(argExpr);
Yingyi Bu391f09e2015-10-29 13:49:39 -07004408 }
4409 )*)? <RIGHTPAREN>
Dmitry Lychagin9d469592020-06-01 15:42:51 -07004410
4411 {
4412 String name = funcName.function;
4413 if (distinct) {
4414 name += FunctionMapUtil.DISTINCT_AGGREGATE_SUFFIX;
4415 }
4416 String fqFunctionName = funcName.library == null ? name : funcName.library + "#" + name;
4417 int arity = argList.size();
4418 FunctionSignature signature = lookupFunctionSignature(funcName.dataverse, fqFunctionName, arity);
4419 if (signature == null) {
4420 signature = new FunctionSignature(funcName.dataverse, fqFunctionName, arity);
4421 }
4422 }
4423
4424 ( <FILTER> <LEFTPAREN> <WHERE> filterExpr = Expression() <RIGHTPAREN> )?
4425
4426 ( LOOKAHEAD(5) windowExpr = WindowExpr(signature, argList, filterExpr) )?
4427
4428 {
4429 if (windowExpr != null) {
4430 return windowExpr;
4431 } else {
4432 CallExpr callExpr = new CallExpr(signature, argList, filterExpr);
Caleb Herbel8d9c57a2020-08-14 20:41:13 -06004433 if (funcName.hintToken != null) {
Dmitry Lychagin6fd8ab32020-12-03 09:04:14 -08004434 IExpressionAnnotation annotation = parseExpressionAnnotation(funcName.hintToken);
4435 if (annotation != null) {
4436 callExpr.addHint(annotation);
Yingyi Bu391f09e2015-10-29 13:49:39 -07004437 }
4438 }
Dmitry Lychagin9d469592020-06-01 15:42:51 -07004439 FunctionMapUtil.normalizedListInputFunctions(callExpr);
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07004440 callExpr.setSourceLocation(funcName.sourceLoc);
Dmitry Lychagin9d469592020-06-01 15:42:51 -07004441 return callExpr;
Yingyi Bu391f09e2015-10-29 13:49:39 -07004442 }
Dmitry Lychaginfdedf622018-10-30 18:12:40 -07004443 }
Yingyi Bu391f09e2015-10-29 13:49:39 -07004444}
4445
Dmitry Lychagin9d469592020-06-01 15:42:51 -07004446WindowExpression WindowExpr(FunctionSignature signature, List<Expression> argList, Expression aggFilterExpr)
4447 throws ParseException:
Dmitry Lychagin5476f962019-05-31 16:03:11 -07004448{
Dmitry Lychagine5e3ad92021-07-15 12:44:47 -07004449 WindowExpression windowExpr = null;
Dmitry Lychagin5476f962019-05-31 16:03:11 -07004450 Boolean fromLast = null, ignoreNulls = null;
4451}
4452{
4453 (
4454 // FROM ( FIRST | LAST ) ( ( RESPECT | IGNORE ) NULLS )? OVER
4455 LOOKAHEAD(5, <FROM> <IDENTIFIER> ( <IDENTIFIER> <IDENTIFIER> )? <OVER>)
4456 <FROM> <IDENTIFIER>
4457 {
4458 if (isToken(FIRST)) {
4459 fromLast = false;
4460 } else if (isToken(LAST)) {
4461 fromLast = true;
4462 } else {
4463 throw createUnexpectedTokenError();
4464 }
4465 }
4466 )?
4467 (
4468 // ( RESPECT | IGNORE ) NULLS OVER
4469 LOOKAHEAD(3, <IDENTIFIER> <IDENTIFIER> <OVER>)
4470 <IDENTIFIER>
4471 {
4472 if (isToken(RESPECT)) {
4473 ignoreNulls = false;
4474 } else if (isToken(IGNORE)) {
4475 ignoreNulls = true;
4476 } else {
4477 throw createUnexpectedTokenError();
4478 }
4479 }
4480 <IDENTIFIER>
4481 {
4482 if (!isToken(NULLS)) {
4483 throw createUnexpectedTokenError();
4484 }
4485 }
4486 )?
Dmitry Lychagine5e3ad92021-07-15 12:44:47 -07004487 <OVER> windowExpr = OverClause(signature, argList, aggFilterExpr, token, fromLast, ignoreNulls)
Dmitry Lychagin5476f962019-05-31 16:03:11 -07004488 {
Dmitry Lychagine5e3ad92021-07-15 12:44:47 -07004489 return windowExpr;
Dmitry Lychagin5476f962019-05-31 16:03:11 -07004490 }
4491}
4492
Dmitry Lychagin9d469592020-06-01 15:42:51 -07004493WindowExpression OverClause(FunctionSignature signature, List<Expression> argList, Expression aggFilterExpr,
4494 Token startToken, Boolean fromLast, Boolean ignoreNulls) throws ParseException:
Dmitry Lychaginf2c18aa2018-12-28 21:20:23 -08004495{
4496 Expression partitionExpr = null;
4497 List<Expression> partitionExprs = new ArrayList<Expression>();
4498 OrderbyClause orderByClause = null;
4499 List<Expression> orderbyList = null;
4500 List<OrderbyClause.OrderModifier> orderbyModifierList = null;
Dmitry Lychagine5e3ad92021-07-15 12:44:47 -07004501 List<OrderbyClause.NullOrderModifier> orderbyNullModifierList = null;
Dmitry Lychaginf2c18aa2018-12-28 21:20:23 -08004502 WindowExpression.FrameMode frameMode = null;
4503 Pair<WindowExpression.FrameBoundaryKind, Expression> frameStart = null, frameEnd = null;
4504 WindowExpression.FrameBoundaryKind frameStartKind = null, frameEndKind = null;
4505 Expression frameStartExpr = null, frameEndExpr = null;
4506 WindowExpression.FrameExclusionKind frameExclusionKind = null;
4507 Pair<VariableExpr, List<Pair<Expression, Identifier>>> windowVarWithFieldList = null;
4508 VariableExpr windowVar = null;
4509 List<Pair<Expression, Identifier>> windowFieldList = null;
4510}
4511{
4512 (
4513 windowVarWithFieldList = VariableWithFieldMap() <AS>
4514 {
4515 windowVar = windowVarWithFieldList.first;
4516 windowFieldList = windowVarWithFieldList.second;
4517 }
4518 )?
4519 <LEFTPAREN>
4520 (
4521 <IDENTIFIER> { expectToken(PARTITION); } <BY>
4522 partitionExpr = Expression() { partitionExprs.add(partitionExpr); }
4523 ( <COMMA> partitionExpr = Expression() { partitionExprs.add(partitionExpr); } )*
4524 )?
4525 (
4526 orderByClause = OrderbyClause()
4527 {
4528 orderbyList = orderByClause.getOrderbyList();
4529 orderbyModifierList = orderByClause.getModifierList();
Dmitry Lychagine5e3ad92021-07-15 12:44:47 -07004530 orderbyNullModifierList = orderByClause.getNullModifierList();
Dmitry Lychaginf2c18aa2018-12-28 21:20:23 -08004531 }
4532 (
4533 frameMode = WindowFrameMode()
4534 (
4535 frameStart = WindowFrameBoundary() |
4536 ( <BETWEEN> frameStart = WindowFrameBoundary() <AND> frameEnd = WindowFrameBoundary() )
4537 )
4538 ( frameExclusionKind = WindowFrameExclusion() )?
4539 {
4540 frameStartKind = frameStart.first;
4541 frameStartExpr = frameStart.second;
4542 if (frameEnd == null) {
4543 frameEndKind = WindowExpression.FrameBoundaryKind.CURRENT_ROW;
4544 } else {
4545 frameEndKind = frameEnd.first;
4546 frameEndExpr = frameEnd.second;
4547 }
4548 if (frameExclusionKind == null) {
4549 frameExclusionKind = WindowExpression.FrameExclusionKind.NO_OTHERS;
4550 }
4551 }
4552 )?
4553 )?
4554 <RIGHTPAREN>
4555 {
Dmitry Lychagin9d469592020-06-01 15:42:51 -07004556 WindowExpression winExpr = new WindowExpression(signature, argList, aggFilterExpr, partitionExprs, orderbyList,
Dmitry Lychagine5e3ad92021-07-15 12:44:47 -07004557 orderbyModifierList, orderbyNullModifierList, frameMode, frameStartKind, frameStartExpr, frameEndKind,
4558 frameEndExpr, frameExclusionKind, windowVar, windowFieldList, ignoreNulls, fromLast);
Dmitry Lychagin9d469592020-06-01 15:42:51 -07004559 return addSourceLocation(winExpr, startToken);
Dmitry Lychaginf2c18aa2018-12-28 21:20:23 -08004560 }
4561}
4562
4563WindowExpression.FrameMode WindowFrameMode() throws ParseException:
4564{
4565}
4566{
4567 <IDENTIFIER>
4568 {
4569 if (isToken(RANGE)) {
4570 return WindowExpression.FrameMode.RANGE;
4571 } else if (isToken(ROWS)) {
4572 return WindowExpression.FrameMode.ROWS;
4573 } else if (isToken(GROUPS)) {
4574 return WindowExpression.FrameMode.GROUPS;
4575 } else {
4576 throw createUnexpectedTokenError();
4577 }
4578 }
4579}
4580
4581Pair<WindowExpression.FrameBoundaryKind, Expression> WindowFrameBoundary() throws ParseException:
4582{
4583 boolean current = false;
4584 Expression expr = null;
4585}
4586{
4587 (
Dmitry Lychagin5476f962019-05-31 16:03:11 -07004588 LOOKAHEAD({ laIdentifier(CURRENT) || laIdentifier(UNBOUNDED) }) <IDENTIFIER> { current = isToken(CURRENT); }
Dmitry Lychaginf2c18aa2018-12-28 21:20:23 -08004589 | expr = Expression()
4590 )
4591 <IDENTIFIER>
4592 {
4593 WindowExpression.FrameBoundaryKind kind;
4594 if (current && isToken(ROW)) {
4595 kind = WindowExpression.FrameBoundaryKind.CURRENT_ROW;
4596 } else if (!current && isToken(PRECEDING)) {
4597 kind = expr == null
4598 ? WindowExpression.FrameBoundaryKind.UNBOUNDED_PRECEDING
4599 : WindowExpression.FrameBoundaryKind.BOUNDED_PRECEDING;
4600 } else if (!current && isToken(FOLLOWING)) {
4601 kind = expr == null
4602 ? WindowExpression.FrameBoundaryKind.UNBOUNDED_FOLLOWING
4603 : WindowExpression.FrameBoundaryKind.BOUNDED_FOLLOWING;
4604 } else {
4605 throw createUnexpectedTokenError();
4606 }
4607 return new Pair<WindowExpression.FrameBoundaryKind, Expression>(kind, expr);
4608 }
4609}
4610
4611WindowExpression.FrameExclusionKind WindowFrameExclusion() throws ParseException:
4612{
4613 boolean current = false, no = false;
4614}
4615{
4616 <IDENTIFIER>
4617 {
4618 expectToken(EXCLUDE);
4619 }
4620 (
4621 <GROUP>
4622 {
4623 return WindowExpression.FrameExclusionKind.GROUP;
4624 }
4625 |
4626 (
4627 <IDENTIFIER>
4628 {
4629 if (isToken(TIES)) {
4630 return WindowExpression.FrameExclusionKind.TIES;
4631 } else if (isToken(CURRENT)) {
4632 current = true;
4633 } else if (isToken(NO)) {
4634 no = true;
4635 } else {
4636 throw createUnexpectedTokenError();
4637 }
4638 }
4639 <IDENTIFIER>
4640 {
4641 if (current && isToken(ROW)) {
4642 return WindowExpression.FrameExclusionKind.CURRENT_ROW;
4643 } else if (no && isToken(OTHERS)) {
4644 return WindowExpression.FrameExclusionKind.NO_OTHERS;
4645 } else {
4646 throw createUnexpectedTokenError();
4647 }
4648 }
4649 )
4650 )
4651}
4652
Yingyi Bu391f09e2015-10-29 13:49:39 -07004653Expression ParenthesizedExpression() throws ParseException:
4654{
Dmitry Lychagine9630592021-08-30 15:29:30 -07004655 Token startToken = null;
4656 Expression expr = null, expr2 = null;
4657 List<Expression> exprList = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07004658}
4659{
4660 (
4661 LOOKAHEAD(2)
Dmitry Lychagine9630592021-08-30 15:29:30 -07004662 <LEFTPAREN> { startToken = token; } expr = Expression()
4663 (
4664 <COMMA> expr2 = Expression()
4665 {
4666 if (exprList == null) {
4667 exprList = new ArrayList<Expression>();
4668 exprList.add(expr);
4669 }
4670 exprList.add(expr2);
4671 }
4672 )*
4673 <RIGHTPAREN>
Yingyi Bu391f09e2015-10-29 13:49:39 -07004674 |
4675 expr = Subquery()
4676 )
4677 {
Dmitry Lychagine9630592021-08-30 15:29:30 -07004678 if (exprList != null) {
4679 ListConstructor listExpr = new ListConstructor(ListConstructor.Type.ORDERED_LIST_CONSTRUCTOR, exprList);
4680 return addSourceLocation(listExpr, startToken);
4681 } else {
4682 return expr;
4683 }
Yingyi Bu391f09e2015-10-29 13:49:39 -07004684 }
4685}
4686
Yingyi Buc8c067c2016-07-25 23:37:19 -07004687Expression CaseExpr() throws ParseException:
Yingyi Bu391f09e2015-10-29 13:49:39 -07004688{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07004689 Token startToken = null;
4690 Expression conditionExpr = null;
Yingyi Buc8c067c2016-07-25 23:37:19 -07004691 List<Expression> whenExprs = new ArrayList<Expression>();
4692 List<Expression> thenExprs = new ArrayList<Expression>();
4693 Expression elseExpr = null;
Yingyi Buc8c067c2016-07-25 23:37:19 -07004694 Expression whenExpr = null;
4695 Expression thenExpr = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07004696}
4697{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07004698 <CASE> { startToken = token; }
4699 ( conditionExpr = Expression() )?
Yingyi Buc8c067c2016-07-25 23:37:19 -07004700 (
4701 <WHEN> whenExpr = Expression()
4702 {
4703 whenExprs.add(whenExpr);
4704 }
4705 <THEN> thenExpr = Expression()
4706 {
4707 thenExprs.add(thenExpr);
4708 }
4709 )*
4710 (<ELSE> elseExpr = Expression() )?
4711 <END>
4712 {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07004713 if (conditionExpr == null) {
4714 LiteralExpr litExpr = new LiteralExpr(TrueLiteral.INSTANCE);
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07004715 conditionExpr = addSourceLocation(litExpr, startToken);
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07004716 }
4717 CaseExpression caseExpr = new CaseExpression(conditionExpr, whenExprs, thenExprs, elseExpr);
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07004718 return addSourceLocation(caseExpr, startToken);
Yingyi Buc8c067c2016-07-25 23:37:19 -07004719 }
Yingyi Bu391f09e2015-10-29 13:49:39 -07004720}
4721
Yingyi Buab817482016-08-19 21:29:31 -07004722SelectExpression SelectExpression(boolean subquery) throws ParseException:
4723{
Yingyi Bu391f09e2015-10-29 13:49:39 -07004724 List<LetClause> letClauses = new ArrayList<LetClause>();
4725 SelectSetOperation selectSetOperation;
4726 OrderbyClause orderbyClause = null;
4727 LimitClause limitClause = null;
4728 createNewScope();
Yingyi Buab817482016-08-19 21:29:31 -07004729}
4730{
Yingyi Bu391f09e2015-10-29 13:49:39 -07004731 ( letClauses = LetClause() )?
4732 selectSetOperation = SelectSetOperation()
4733 (orderbyClause = OrderbyClause() {})?
4734 (limitClause = LimitClause() {})?
4735 {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07004736 SelectExpression selectExpr =
4737 new SelectExpression(letClauses, selectSetOperation, orderbyClause, limitClause, subquery);
4738 selectExpr.setSourceLocation((!letClauses.isEmpty() ? letClauses.get(0) : selectSetOperation).getSourceLocation());
4739 return selectExpr;
Yingyi Bu391f09e2015-10-29 13:49:39 -07004740 }
4741}
4742
Yingyi Buab817482016-08-19 21:29:31 -07004743SelectSetOperation SelectSetOperation() throws ParseException:
4744{
Yingyi Bu391f09e2015-10-29 13:49:39 -07004745 SetOperationInput setOperationInputLeft;
4746 List<SetOperationRight> setOperationRights = new ArrayList<SetOperationRight>();
4747}
4748{
4749 {
4750 SelectBlock selectBlockLeft = null;
4751 SelectExpression subqueryLeft = null;
4752 Expression expr = null;
4753 }
4754 selectBlockLeft = SelectBlock()
4755 {
4756 setOperationInputLeft = new SetOperationInput(selectBlockLeft, subqueryLeft);
4757 }
4758 (
4759 {
4760 SetOpType opType = SetOpType.UNION;
4761 boolean setSemantics = true;
4762 SelectBlock selectBlockRight = null;
4763 SelectExpression subqueryRight = null;
4764 }
4765 (<UNION> {opType = SetOpType.UNION;} |<INTERSECT> {opType = SetOpType.INTERSECT;} |<EXCEPT> {opType = SetOpType.EXCEPT;}) (<ALL> {setSemantics = false;} )?
4766 (selectBlockRight = SelectBlock()| subqueryRight = Subquery())
4767 {
4768 setOperationRights.add(new SetOperationRight(opType, setSemantics, new SetOperationInput(selectBlockRight, subqueryRight)));
4769 }
4770 )*
4771 {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07004772 SelectSetOperation selectSetOp = new SelectSetOperation(setOperationInputLeft, setOperationRights);
4773 selectSetOp.setSourceLocation(selectBlockLeft.getSourceLocation());
4774 return selectSetOp;
Yingyi Bu391f09e2015-10-29 13:49:39 -07004775 }
4776}
4777
Yingyi Buab817482016-08-19 21:29:31 -07004778SelectExpression Subquery() throws ParseException:
4779{
Yingyi Bu391f09e2015-10-29 13:49:39 -07004780 SelectExpression selectExpr = null;
4781}
4782{
4783 <LEFTPAREN> selectExpr = SelectExpression(true) {} <RIGHTPAREN>
4784 {
4785 return selectExpr;
4786 }
4787}
4788
Yingyi Buab817482016-08-19 21:29:31 -07004789SelectBlock SelectBlock() throws ParseException:
4790{
Yingyi Bu391f09e2015-10-29 13:49:39 -07004791 SelectClause selectClause = null;
4792 FromClause fromClause = null;
4793 List<LetClause> fromLetClauses = null;
4794 WhereClause whereClause = null;
Dmitry Lychagin276adf92019-01-15 13:16:40 -08004795 List<AbstractClause> fromLetWhereClauses = new ArrayList<AbstractClause>();
Yingyi Bu391f09e2015-10-29 13:49:39 -07004796 GroupbyClause groupbyClause = null;
4797 List<LetClause> gbyLetClauses = null;
4798 HavingClause havingClause = null;
Dmitry Lychagin276adf92019-01-15 13:16:40 -08004799 List<AbstractClause> gbyLetHavingClauses = new ArrayList<AbstractClause>();
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07004800 SourceLocation startSrcLoc = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07004801}
4802{
4803 (
Dmitry Lychagin214ff552021-07-22 18:55:41 -07004804 (
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07004805 selectClause = SelectClause() { startSrcLoc = selectClause.getSourceLocation(); }
Yingyi Bu391f09e2015-10-29 13:49:39 -07004806 (
Yingyi Bu391f09e2015-10-29 13:49:39 -07004807 (
Dmitry Lychagin368092d2019-06-06 14:39:38 -07004808 fromClause = FromClause()
4809 (
4810 fromLetClauses = LetClause()
4811 )?
Dmitry Lychagin214ff552021-07-22 18:55:41 -07004812 (whereClause = WhereClause())?
4813 (
4814 groupbyClause = GroupbyClause()
4815 (
4816 gbyLetClauses = LetClause()
4817 )?
4818 (havingClause = HavingClause())?
4819 )?
Dmitry Lychagin368092d2019-06-06 14:39:38 -07004820 )
4821 |
4822 (
4823 fromLetClauses = LetClause()
4824 {
4825 // LET without FROM -> create dummy FROM clause: FROM {{missing}} AS #0
4826 SourceLocation sourceLoc = getSourceLocation(token);
4827 LiteralExpr missingExpr = new LiteralExpr(MissingLiteral.INSTANCE);
4828 missingExpr.setSourceLocation(sourceLoc);
4829 List<Expression> list = new ArrayList<Expression>(1);
4830 list.add(missingExpr);
4831 ListConstructor listExpr = new ListConstructor(ListConstructor.Type.ORDERED_LIST_CONSTRUCTOR, list);
4832 listExpr.setSourceLocation(sourceLoc);
4833 List<FromTerm> fromTerms = new ArrayList<FromTerm>(1);
4834 VariableExpr fromVar = new VariableExpr(new VarIdentifier("#0"));
4835 fromVar.setSourceLocation(sourceLoc);
4836 fromTerms.add(new FromTerm(listExpr, fromVar, null, new ArrayList<AbstractBinaryCorrelateClause>()));
4837 fromClause = new FromClause(fromTerms);
4838 }
Dmitry Lychagin214ff552021-07-22 18:55:41 -07004839 (whereClause = WhereClause())?
Dmitry Lychagin368092d2019-06-06 14:39:38 -07004840 )
Yingyi Bu391f09e2015-10-29 13:49:39 -07004841 )?
Dmitry Lychagin214ff552021-07-22 18:55:41 -07004842 )
Yingyi Bu391f09e2015-10-29 13:49:39 -07004843 |
Dmitry Lychagin214ff552021-07-22 18:55:41 -07004844 (
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07004845 fromClause = FromClause() { startSrcLoc = fromClause.getSourceLocation(); }
Yingyi Bu391f09e2015-10-29 13:49:39 -07004846 (
Yingyi Bu391f09e2015-10-29 13:49:39 -07004847 fromLetClauses = LetClause()
4848 )?
4849 (whereClause = WhereClause())?
4850 (
4851 groupbyClause = GroupbyClause()
4852 (
4853 gbyLetClauses = LetClause()
4854 )?
4855 (havingClause = HavingClause())?
4856 )?
4857 selectClause = SelectClause()
Dmitry Lychagin214ff552021-07-22 18:55:41 -07004858 )
Yingyi Bu391f09e2015-10-29 13:49:39 -07004859 )
4860 {
Dmitry Lychagin276adf92019-01-15 13:16:40 -08004861 if (fromLetClauses != null) {
4862 fromLetWhereClauses.addAll(fromLetClauses);
4863 }
4864 if (whereClause != null) {
4865 fromLetWhereClauses.add(whereClause);
4866 }
4867 if (gbyLetClauses != null) {
4868 gbyLetHavingClauses.addAll(gbyLetClauses);
4869 }
4870 if (havingClause != null) {
4871 gbyLetHavingClauses.add(havingClause);
4872 }
4873 SelectBlock selectBlock = new SelectBlock(selectClause, fromClause, fromLetWhereClauses, groupbyClause,
4874 gbyLetHavingClauses);
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07004875 selectBlock.setSourceLocation(startSrcLoc);
4876 return selectBlock;
Yingyi Bu391f09e2015-10-29 13:49:39 -07004877 }
4878}
4879
Yingyi Buab817482016-08-19 21:29:31 -07004880SelectClause SelectClause() throws ParseException:
4881{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07004882 Token startToken = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07004883 SelectRegular selectRegular = null;
4884 SelectElement selectElement = null;
ggalvizo82499442022-10-24 12:46:15 -07004885 List<List<String>> fieldExclusions = new ArrayList<List<String>>();
4886 List<String> nestedField = new ArrayList<String>();
4887 String identifier;
Yingyi Bu391f09e2015-10-29 13:49:39 -07004888 boolean distinct = false;
4889}
4890{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07004891 <SELECT> { startToken = token; } (<ALL>|<DISTINCT> { distinct = true; } )?
Yingyi Bu391f09e2015-10-29 13:49:39 -07004892 (
ggalvizo82499442022-10-24 12:46:15 -07004893 (
4894 selectRegular = SelectRegular()
4895 ( LOOKAHEAD({laIdentifier(EXCLUDE)}) <IDENTIFIER>
4896 identifier = Identifier() { nestedField.add(identifier); }
4897 ( <DOT> identifier = Identifier() { nestedField.add(identifier); } )*
4898 {
4899 fieldExclusions.add(nestedField);
4900 nestedField = new ArrayList<String>();
4901 }
4902 ( LOOKAHEAD(1) // Force <COMMA> to be recognized for a nested field in our EXCLUDE list.
4903 <COMMA> identifier = Identifier() { nestedField.add(identifier); }
4904 ( <DOT> identifier = Identifier() { nestedField.add(identifier); } )*
4905 {
4906 fieldExclusions.add(nestedField);
4907 nestedField = new ArrayList<String>();
4908 }
4909 )*
4910 )?
4911 )
Michael Blowd6cf6412016-06-30 02:44:35 -04004912 |
Yingyi Bu391f09e2015-10-29 13:49:39 -07004913 selectElement = SelectElement()
Yingyi Bua89fae62016-07-06 07:58:55 -07004914 )?
Yingyi Bu391f09e2015-10-29 13:49:39 -07004915 {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07004916 SourceLocation sourceLoc = getSourceLocation(startToken);
4917 if (selectRegular == null && selectElement == null){
Dmitry Lychaginb4121e42021-09-23 15:55:09 -07004918 Projection projection = new Projection(Projection.Kind.STAR, null, null);
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07004919 projection.setSourceLocation(sourceLoc);
Yingyi Bua89fae62016-07-06 07:58:55 -07004920 List<Projection> projections = new ArrayList<Projection>();
4921 projections.add(projection);
4922 selectRegular = new SelectRegular(projections);
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07004923 selectRegular.setSourceLocation(sourceLoc);
Yingyi Bua89fae62016-07-06 07:58:55 -07004924 }
ggalvizo82499442022-10-24 12:46:15 -07004925 SelectClause selectClause = new SelectClause(selectElement, selectRegular, fieldExclusions, distinct);
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07004926 selectClause.setSourceLocation(sourceLoc);
4927 return selectClause;
Yingyi Bu391f09e2015-10-29 13:49:39 -07004928 }
4929}
4930
Yingyi Buab817482016-08-19 21:29:31 -07004931SelectRegular SelectRegular() throws ParseException:
4932{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07004933 SourceLocation startSrcLoc = null;
Michael Blowd6cf6412016-06-30 02:44:35 -04004934 List<Projection> projections = new ArrayList<Projection>();
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07004935 Projection projection = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07004936}
4937{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07004938 projection = Projection()
Yingyi Bu391f09e2015-10-29 13:49:39 -07004939 {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07004940 projections.add(projection);
4941 startSrcLoc = projection.getSourceLocation();
4942 }
4943 ( LOOKAHEAD(2) <COMMA> projection = Projection()
4944 {
4945 projections.add(projection);
4946 }
4947 )*
4948 {
4949 SelectRegular selectRegular = new SelectRegular(projections);
4950 selectRegular.setSourceLocation(startSrcLoc);
4951 return selectRegular;
Yingyi Bu391f09e2015-10-29 13:49:39 -07004952 }
4953}
4954
Yingyi Buab817482016-08-19 21:29:31 -07004955SelectElement SelectElement() throws ParseException:
4956{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07004957 Token startToken = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07004958 Expression expr = null;
4959 String name = null;
4960}
4961{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07004962 (<RAW>|<ELEMENT>|<VALUE>) { startToken = token; } expr = Expression()
Yingyi Bu391f09e2015-10-29 13:49:39 -07004963 {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07004964 SelectElement selectElement = new SelectElement(expr);
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07004965 return addSourceLocation(selectElement, startToken);
Yingyi Bu391f09e2015-10-29 13:49:39 -07004966 }
4967}
4968
Yingyi Buab817482016-08-19 21:29:31 -07004969Projection Projection() throws ParseException :
4970{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07004971 SourceLocation startSrcLoc = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07004972 Expression expr = null;
4973 Identifier identifier = null;
4974 String name = null;
Dmitry Lychaginb4121e42021-09-23 15:55:09 -07004975 Projection.Kind kind = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07004976 boolean star = false;
Dmitry Lychagin5cdaa5d2018-02-21 11:11:26 -08004977 boolean varStar = false;
Yingyi Bu391f09e2015-10-29 13:49:39 -07004978}
4979{
4980 (
Dmitry Lychaginb4121e42021-09-23 15:55:09 -07004981 <MUL> { kind = Projection.Kind.STAR; startSrcLoc = getSourceLocation(token); }
4982 | LOOKAHEAD(3) expr = VariableRef() <DOT> <MUL> { kind = Projection.Kind.VAR_STAR; }
ggalvizo82499442022-10-24 12:46:15 -07004983 | expr = Expression()
4984 ( // EXCLUDE is a soft-keyword-- we want to avoid mistaking EXCLUDE as an identifier here.
4985 LOOKAHEAD({ getToken(1).kind == AS || getToken(1).kind == QUOTED_STRING
4986 || (getToken(1).kind == IDENTIFIER && !laIdentifier(1, EXCLUDE)) })
4987 (<AS>)? name = Identifier()
4988 )?
Dmitry Lychagin5cdaa5d2018-02-21 11:11:26 -08004989 {
Dmitry Lychaginb4121e42021-09-23 15:55:09 -07004990 kind = Projection.Kind.NAMED_EXPR;
Dmitry Lychagin5cdaa5d2018-02-21 11:11:26 -08004991 if (name == null) {
4992 String generatedColumnIdentifier = ExpressionToVariableUtil.getGeneratedIdentifier(expr, false);
4993 if (generatedColumnIdentifier != null) {
4994 name = SqlppVariableUtil.toUserDefinedName(generatedColumnIdentifier);
4995 }
4996 }
4997 }
Yingyi Bu391f09e2015-10-29 13:49:39 -07004998 )
4999 {
Dmitry Lychaginb4121e42021-09-23 15:55:09 -07005000 Projection projection = new Projection(kind, expr, name);
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07005001 projection.setSourceLocation(expr != null ? expr.getSourceLocation() : startSrcLoc);
5002 return projection;
Yingyi Bu391f09e2015-10-29 13:49:39 -07005003 }
5004}
5005
5006FromClause FromClause() throws ParseException :
5007{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07005008 Token startToken = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07005009 List<FromTerm> fromTerms = new ArrayList<FromTerm>();
5010 extendCurrentScope();
5011}
5012{
5013 {
5014 FromTerm fromTerm = null;
5015 }
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07005016 <FROM> { startToken = token; } fromTerm = FromTerm() { fromTerms.add(fromTerm); }
Yingyi Bu391f09e2015-10-29 13:49:39 -07005017 (LOOKAHEAD(2) <COMMA> fromTerm = FromTerm() { fromTerms.add(fromTerm); } )*
5018 {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07005019 FromClause fromClause = new FromClause(fromTerms);
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07005020 return addSourceLocation(fromClause, startToken);
Yingyi Bu391f09e2015-10-29 13:49:39 -07005021 }
5022}
5023
5024FromTerm FromTerm() throws ParseException :
5025{
5026 Expression leftExpr = null;
Michael Blowd6cf6412016-06-30 02:44:35 -04005027 VariableExpr leftVar = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07005028 VariableExpr posVar = null;
Dmitry Lychagind4ce84c2020-10-13 16:24:37 -07005029 AbstractBinaryCorrelateClause correlateClause = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07005030 List<AbstractBinaryCorrelateClause> correlateClauses = new ArrayList<AbstractBinaryCorrelateClause>();
5031}
5032{
Ali Alsulimanba91b1c2023-02-22 21:33:55 -08005033 leftExpr = Expression()
5034 {
5035 if (leftExpr.getKind() == Expression.Kind.VARIABLE_EXPRESSION) {
5036 Token hintToken = fetchHint(token, SqlppHint.SUBPATH_HINT);
5037 if (hintToken != null) {
5038 String subPath = hintToken.hintParams;
5039 ((VariableExpr) leftExpr).addHint(new ExternalSubpathAnnotation(subPath));
5040 }
5041 }
5042 } ((<AS>)? leftVar = Variable())? (<AT> posVar = Variable())?
Yingyi Bu391f09e2015-10-29 13:49:39 -07005043 (
Dmitry Lychagind4ce84c2020-10-13 16:24:37 -07005044 (
5045 correlateClause = JoinOrUnnestClause(JoinType.INNER, UnnestType.INNER)
5046 | ( <INNER> correlateClause = JoinOrUnnestClause(JoinType.INNER, UnnestType.INNER) )
5047 | ( <LEFT> ( <OUTER> )? correlateClause = JoinOrUnnestClause(JoinType.LEFTOUTER, UnnestType.LEFTOUTER) )
5048 | ( <RIGHT> ( <OUTER> )? correlateClause = JoinClause(JoinType.RIGHTOUTER) )
Dmitry Lychagind3eccd42021-08-19 12:18:17 -07005049 | ( <CROSS> correlateClause = CrossJoinClause() )
Yingyi Bu391f09e2015-10-29 13:49:39 -07005050 )
5051 {
5052 correlateClauses.add(correlateClause);
5053 }
5054 )*
5055 {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07005056 if (leftVar == null) {
Yingyi Bu5b2d4c82016-07-13 17:56:48 -07005057 leftVar = ExpressionToVariableUtil.getGeneratedVariable(leftExpr, true);
Yingyi Bu9e3f9be2016-07-01 10:07:37 -07005058 }
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07005059 FromTerm fromTerm = new FromTerm(leftExpr, leftVar, posVar, correlateClauses);
5060 fromTerm.setSourceLocation(leftExpr.getSourceLocation());
5061 return fromTerm;
Yingyi Bu391f09e2015-10-29 13:49:39 -07005062 }
5063}
5064
Dmitry Lychagind4ce84c2020-10-13 16:24:37 -07005065AbstractBinaryCorrelateClause JoinOrUnnestClause(JoinType joinType, UnnestType unnestType) throws ParseException :
5066{
5067 AbstractBinaryCorrelateClause correlateClause = null;
5068}
5069{
5070 ( correlateClause = JoinClause(joinType) | correlateClause = UnnestClause(unnestType) )
5071 {
5072 return correlateClause;
5073 }
5074}
5075
Yingyi Bu391f09e2015-10-29 13:49:39 -07005076JoinClause JoinClause(JoinType joinType) throws ParseException :
5077{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07005078 Token startToken = null;
Dmitry Lychagind3eccd42021-08-19 12:18:17 -07005079 Triple<Expression, VariableExpr, VariableExpr> rightInput = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07005080 Expression conditionExpr = null;
5081}
5082{
Dmitry Lychagind3eccd42021-08-19 12:18:17 -07005083 <JOIN> { startToken = token; } rightInput = JoinClauseRightInput() <ON> conditionExpr = Expression()
5084 {
5085 JoinClause joinClause = new JoinClause(joinType, rightInput.first, rightInput.second, rightInput.third,
Dmitry Lychagin34b72ac2021-11-29 16:25:40 -08005086 conditionExpr, joinType == JoinType.INNER ? null : Literal.Type.MISSING);
Dmitry Lychagind3eccd42021-08-19 12:18:17 -07005087 return addSourceLocation(joinClause, startToken);
5088 }
5089}
5090
5091JoinClause CrossJoinClause() throws ParseException :
5092{
5093 Token startToken = null;
5094 Triple<Expression, VariableExpr, VariableExpr> rightInput = null;
5095 Expression conditionExpr = null;
5096}
5097{
5098 <JOIN> { startToken = token; } rightInput = JoinClauseRightInput()
5099 {
5100 JoinClause joinClause = new JoinClause(JoinType.INNER, rightInput.first, rightInput.second, rightInput.third,
Dmitry Lychagin34b72ac2021-11-29 16:25:40 -08005101 new LiteralExpr(TrueLiteral.INSTANCE), null);
Dmitry Lychagind3eccd42021-08-19 12:18:17 -07005102 return addSourceLocation(joinClause, startToken);
5103 }
5104}
5105
5106Triple<Expression, VariableExpr, VariableExpr> JoinClauseRightInput() throws ParseException :
5107{
5108 Expression rightExpr = null;
5109 VariableExpr rightVar = null;
5110 VariableExpr posVar = null;
5111}
5112{
Ali Alsulimanba91b1c2023-02-22 21:33:55 -08005113 rightExpr = Expression()
5114 {
5115 if (rightExpr.getKind() == Expression.Kind.VARIABLE_EXPRESSION) {
5116 Token hintToken = fetchHint(token, SqlppHint.SUBPATH_HINT);
5117 if (hintToken != null) {
5118 String subPath = hintToken.hintParams;
5119 ((VariableExpr) rightExpr).addHint(new ExternalSubpathAnnotation(subPath));
5120 }
5121 }
5122 } ((<AS>)? rightVar = Variable())? (<AT> posVar = Variable())?
Yingyi Bu391f09e2015-10-29 13:49:39 -07005123 {
Dmitry Lychagind4ce84c2020-10-13 16:24:37 -07005124 if (rightVar == null) {
5125 rightVar = ExpressionToVariableUtil.getGeneratedVariable(rightExpr, true);
Yingyi Bu9e3f9be2016-07-01 10:07:37 -07005126 }
Dmitry Lychagind3eccd42021-08-19 12:18:17 -07005127 return new Triple<Expression, VariableExpr, VariableExpr>(rightExpr, rightVar, posVar);
Yingyi Bu391f09e2015-10-29 13:49:39 -07005128 }
5129}
5130
Dmitry Lychagind4ce84c2020-10-13 16:24:37 -07005131UnnestClause UnnestClause(UnnestType unnestType) throws ParseException :
Yingyi Bu391f09e2015-10-29 13:49:39 -07005132{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07005133 Token startToken = null;
Dmitry Lychagin4cf91e42021-03-12 12:53:15 -08005134 Expression rightExpr = null;
5135 VariableExpr rightVar = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07005136 VariableExpr posVar = null;
5137}
5138{
Dmitry Lychagin4cf91e42021-03-12 12:53:15 -08005139 (<UNNEST>|<CORRELATE>|<FLATTEN>) { startToken = token; } rightExpr = Expression() ((<AS>)? rightVar = Variable())? (<AT> posVar = Variable())?
Yingyi Bu391f09e2015-10-29 13:49:39 -07005140 {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07005141 if (rightVar == null) {
5142 rightVar = ExpressionToVariableUtil.getGeneratedVariable(rightExpr, true);
Yingyi Bu9e3f9be2016-07-01 10:07:37 -07005143 }
Dmitry Lychagin34b72ac2021-11-29 16:25:40 -08005144 UnnestClause unnestClause = new UnnestClause(unnestType, rightExpr, rightVar, posVar,
5145 unnestType == UnnestType.INNER ? null : Literal.Type.MISSING);
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07005146 return addSourceLocation(unnestClause, startToken);
Yingyi Bu391f09e2015-10-29 13:49:39 -07005147 }
5148}
5149
Yingyi Bu391f09e2015-10-29 13:49:39 -07005150List<LetClause> LetClause() throws ParseException:
5151{
5152 List<LetClause> letList = new ArrayList<LetClause>();
5153 LetClause letClause;
5154}
5155{
5156 (
5157 (<LET>|<LETTING>) letClause = LetElement() { letList.add(letClause); } (LOOKAHEAD(1) <COMMA> letClause = LetElement() { letList.add(letClause); })*
5158 |
5159 <WITH> letClause = WithElement() { letList.add(letClause); } (LOOKAHEAD(1) <COMMA> letClause = WithElement() { letList.add(letClause); })*
5160 )
5161 {
5162 return letList;
5163 }
5164}
5165
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07005166WhereClause WhereClause() throws ParseException :
Yingyi Bu391f09e2015-10-29 13:49:39 -07005167{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07005168 Token startToken = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07005169 Expression whereExpr;
5170}
5171{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07005172 <WHERE> { startToken = token; } whereExpr = Expression()
Yingyi Bu391f09e2015-10-29 13:49:39 -07005173 {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07005174 WhereClause wc = new WhereClause(whereExpr);
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07005175 return addSourceLocation(wc, startToken);
Yingyi Bu391f09e2015-10-29 13:49:39 -07005176 }
5177}
5178
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07005179OrderbyClause OrderbyClause() throws ParseException :
Yingyi Bu391f09e2015-10-29 13:49:39 -07005180{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07005181 Token startToken = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07005182 OrderbyClause oc = new OrderbyClause();
Dmitry Lychagine5e3ad92021-07-15 12:44:47 -07005183 Triple<Expression, OrderbyClause.OrderModifier, OrderbyClause.NullOrderModifier> orderbyExpr = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07005184 List<Expression> orderbyList = new ArrayList<Expression>();
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07005185 List<OrderbyClause.OrderModifier> modifierList = new ArrayList<OrderbyClause.OrderModifier>();
Dmitry Lychagine5e3ad92021-07-15 12:44:47 -07005186 List<OrderbyClause.NullOrderModifier> nullModifierList = new ArrayList<OrderbyClause.NullOrderModifier>();
Yingyi Bu391f09e2015-10-29 13:49:39 -07005187}
5188{
Dmitry Lychagine5e3ad92021-07-15 12:44:47 -07005189 <ORDER>
5190 {
5191 startToken = token;
5192 Token hintToken = fetchHint(token, SqlppHint.INMEMORY_HINT, SqlppHint.RANGE_HINT);
5193 if (hintToken != null) {
5194 switch (hintToken.hint) {
5195 case INMEMORY_HINT:
5196 String[] splits = hintToken.hintParams.split("\\s+");
5197 int numFrames = Integer.parseInt(splits[0]);
5198 int numTuples = Integer.parseInt(splits[1]);
5199 oc.setNumFrames(numFrames);
5200 oc.setNumTuples(numTuples);
5201 break;
5202 case RANGE_HINT:
5203 try {
5204 Expression rangeExpr = parseExpression(hintToken.hintParams);
5205 RangeMap rangeMap = RangeMapBuilder.parseHint(rangeExpr);
5206 oc.setRangeMap(rangeMap);
5207 } catch (CompilationException e) {
5208 throw new SqlppParseException(getSourceLocation(hintToken), e.getMessage());
Ali Alsuliman80225e22018-10-15 14:17:07 -07005209 }
Dmitry Lychagine5e3ad92021-07-15 12:44:47 -07005210 break;
Yingyi Bu391f09e2015-10-29 13:49:39 -07005211 }
Yingyi Bu391f09e2015-10-29 13:49:39 -07005212 }
Dmitry Lychagine5e3ad92021-07-15 12:44:47 -07005213 }
5214 <BY> orderbyExpr = OrderByExpression()
5215 {
5216 orderbyList.add(orderbyExpr.first);
5217 modifierList.add(orderbyExpr.second);
5218 nullModifierList.add(orderbyExpr.third);
5219 }
5220 (
5221 LOOKAHEAD(2) <COMMA> orderbyExpr = OrderByExpression()
Yingyi Bu391f09e2015-10-29 13:49:39 -07005222 {
Dmitry Lychagine5e3ad92021-07-15 12:44:47 -07005223 orderbyList.add(orderbyExpr.first);
5224 modifierList.add(orderbyExpr.second);
5225 nullModifierList.add(orderbyExpr.third);
Yingyi Bu391f09e2015-10-29 13:49:39 -07005226 }
Dmitry Lychagine5e3ad92021-07-15 12:44:47 -07005227 )*
5228 {
5229 oc.setOrderbyList(orderbyList);
5230 oc.setModifierList(modifierList);
5231 oc.setNullModifierList(nullModifierList);
5232 return addSourceLocation(oc, startToken);
5233 }
5234}
Yingyi Bu391f09e2015-10-29 13:49:39 -07005235
Dmitry Lychagine5e3ad92021-07-15 12:44:47 -07005236Triple<Expression, OrderbyClause.OrderModifier, OrderbyClause.NullOrderModifier> OrderByExpression()
5237 throws ParseException:
5238{
5239 Expression orderbyExpr = null;
5240 OrderbyClause.OrderModifier modif = OrderbyClause.OrderModifier.ASC;
5241 OrderbyClause.NullOrderModifier nullModif = null;
5242}
5243{
5244 orderbyExpr = Expression()
5245 (
5246 <ASC> { modif = OrderbyClause.OrderModifier.ASC; }
5247 |
5248 <DESC> { modif = OrderbyClause.OrderModifier.DESC; }
5249 )?
5250 (
5251 LOOKAHEAD({ laIdentifier(NULLS) }) <IDENTIFIER> { expectToken(NULLS); } <IDENTIFIER>
Yingyi Bu391f09e2015-10-29 13:49:39 -07005252 {
Dmitry Lychagine5e3ad92021-07-15 12:44:47 -07005253 if (isToken(FIRST)) {
5254 nullModif = OrderbyClause.NullOrderModifier.FIRST;
5255 } else if (isToken(LAST)) {
5256 nullModif = OrderbyClause.NullOrderModifier.LAST;
5257 } else {
5258 throw createUnexpectedTokenError();
5259 }
Yingyi Bu391f09e2015-10-29 13:49:39 -07005260 }
Dmitry Lychagine5e3ad92021-07-15 12:44:47 -07005261 )?
5262 {
5263 return new Triple<Expression, OrderbyClause.OrderModifier, OrderbyClause.NullOrderModifier>(orderbyExpr, modif,
5264 nullModif);
5265 }
Yingyi Bu391f09e2015-10-29 13:49:39 -07005266}
5267
5268GroupbyClause GroupbyClause()throws ParseException :
5269{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07005270 Token startToken = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07005271 GroupbyClause gbc = new GroupbyClause();
Dmitry Lychaginac98f482020-03-31 12:26:40 -07005272 List<List<GbyVariableExpressionPair>> gbyList = null;
5273 List<GroupingElement> groupingElementList = null;
Dmitry Lychaginf2c18aa2018-12-28 21:20:23 -08005274 Pair<VariableExpr, List<Pair<Expression, Identifier>>> groupVarWithFieldList = null;
Yingyi Buacc12a92016-03-26 17:25:05 -07005275 VariableExpr groupVar = null;
Dmitry Lychaginf2c18aa2018-12-28 21:20:23 -08005276 List<Pair<Expression, Identifier>> groupFieldList = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07005277}
5278{
Dmitry Lychaginac98f482020-03-31 12:26:40 -07005279 {
5280 Scope newScope = extendCurrentScopeNoPush(true);
5281 // extendCurrentScope(true);
5282 }
Yingyi Bu391f09e2015-10-29 13:49:39 -07005283 <GROUP>
Dmitry Lychaginac98f482020-03-31 12:26:40 -07005284 {
5285 startToken = token;
5286 Token hintToken = fetchHint(token, SqlppHint.HASH_GROUP_BY_HINT);
5287 if (hintToken != null) {
5288 gbc.setHashGroupByHint(true);
Yingyi Bu391f09e2015-10-29 13:49:39 -07005289 }
Dmitry Lychaginac98f482020-03-31 12:26:40 -07005290 }
5291 <BY> groupingElementList = GroupingElementList()
5292 (
5293 <GROUP> <AS> groupVarWithFieldList = VariableWithFieldMap()
Dmitry Lychaginf2c18aa2018-12-28 21:20:23 -08005294 {
5295 groupVar = groupVarWithFieldList.first;
5296 groupFieldList = groupVarWithFieldList.second;
5297 }
Yingyi Buacc12a92016-03-26 17:25:05 -07005298 )?
Yingyi Bu391f09e2015-10-29 13:49:39 -07005299 {
Dmitry Lychaginac98f482020-03-31 12:26:40 -07005300 if (groupingSetsParser == null) {
5301 groupingSetsParser = new SqlppGroupingSetsParser();
5302 }
5303 SourceLocation sourceLoc = getSourceLocation(startToken);
5304 try {
5305 gbyList = groupingSetsParser.parse(groupingElementList, sourceLoc);
5306 } catch (CompilationException e) {
5307 throw new SqlppParseException(sourceLoc, e.getMessage());
5308 }
5309 gbc.setGbyPairList(gbyList);
Yingyi Bu391f09e2015-10-29 13:49:39 -07005310 gbc.setDecorPairList(new ArrayList<GbyVariableExpressionPair>());
Yingyi Bu8671ddf2016-08-14 23:58:43 -07005311 gbc.setWithVarMap(new HashMap<Expression, VariableExpr>());
Yingyi Buacc12a92016-03-26 17:25:05 -07005312 gbc.setGroupVar(groupVar);
5313 gbc.setGroupFieldList(groupFieldList);
Yingyi Bu391f09e2015-10-29 13:49:39 -07005314 replaceCurrentScope(newScope);
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07005315 return addSourceLocation(gbc, startToken);
Yingyi Bu391f09e2015-10-29 13:49:39 -07005316 }
5317}
5318
Dmitry Lychaginac98f482020-03-31 12:26:40 -07005319List<GroupingElement> GroupingElementList() throws ParseException:
5320{
5321 List<GroupingElement> groupingElementList = new ArrayList<GroupingElement>();
5322 GroupingElement groupingElement = null;
5323}
5324{
5325 groupingElement = GroupingElement() { groupingElementList.add(groupingElement); }
5326 ( LOOKAHEAD(1) <COMMA> groupingElement = GroupingElement() { groupingElementList.add(groupingElement); } )*
5327 {
5328 return groupingElementList;
5329 }
5330}
5331
5332GroupingElement GroupingElement() throws ParseException:
5333{
5334 GroupingElement groupingElement = null;
5335 List<GroupingSet> groupingSets = null;
5336 List<GroupingElement> groupingElements = null;
5337}
5338{
5339 (
5340 LOOKAHEAD(2)
5341 <LEFTPAREN> <RIGHTPAREN>
5342 {
5343 groupingElement = GroupingSet.EMPTY;
5344 }
5345 |
5346 LOOKAHEAD({ laIdentifier(ROLLUP) && laToken(2, LEFTPAREN) })
5347 <IDENTIFIER> { expectToken(ROLLUP); }
5348 <LEFTPAREN> groupingSets = OrdinaryGroupingSetList() <RIGHTPAREN>
5349 {
5350 groupingElement = new RollupCube(groupingSets, false);
5351 }
5352 |
5353 LOOKAHEAD({ laIdentifier(CUBE) && laToken(2, LEFTPAREN) })
5354 <IDENTIFIER> { expectToken(CUBE); }
5355 <LEFTPAREN> groupingSets = OrdinaryGroupingSetList() <RIGHTPAREN>
5356 {
5357 groupingElement = new RollupCube(groupingSets, true);
5358 }
5359 |
5360 LOOKAHEAD({ laIdentifier(GROUPING) && laIdentifier(2, SETS) && laToken(3, LEFTPAREN) })
5361 <IDENTIFIER> { expectToken(GROUPING); } <IDENTIFIER> { expectToken(SETS); }
5362 <LEFTPAREN> groupingElements = GroupingElementList() <RIGHTPAREN>
5363 {
5364 groupingElement = new GroupingSets(groupingElements);
5365 }
5366 |
5367 groupingElement = OrdinaryGroupingSet()
5368 )
5369 {
5370 return groupingElement;
5371 }
5372}
5373
5374GroupingSet OrdinaryGroupingSet() throws ParseException:
5375{
5376 GbyVariableExpressionPair gbyExprPair = null;
5377 List<GbyVariableExpressionPair> items = null;
5378}
5379{
5380 (
5381 LOOKAHEAD(1) <LEFTPAREN> items = GbyVariableExpressionPairList() <RIGHTPAREN>
5382 | gbyExprPair = GbyVariableExpressionPair() { items = Collections.singletonList(gbyExprPair); }
5383 )
5384 {
5385 return new GroupingSet(items);
5386 }
5387}
5388
5389List<GroupingSet> OrdinaryGroupingSetList() throws ParseException:
5390{
5391 GroupingSet groupingSet = null;
5392 List<GroupingSet> items = new ArrayList<GroupingSet>();
5393}
5394{
5395 groupingSet = OrdinaryGroupingSet() { items.add(groupingSet); }
5396 ( LOOKAHEAD(1) <COMMA> groupingSet = OrdinaryGroupingSet() { items.add(groupingSet); } )*
5397 {
5398 return items;
5399 }
5400}
5401
5402List<GbyVariableExpressionPair> GbyVariableExpressionPairList() throws ParseException:
5403{
5404 GbyVariableExpressionPair gbyExprPair = null;
5405 List<GbyVariableExpressionPair> items = new ArrayList<GbyVariableExpressionPair>();
5406}
5407{
5408 gbyExprPair = GbyVariableExpressionPair() { items.add(gbyExprPair); }
5409 ( LOOKAHEAD(1) <COMMA> gbyExprPair = GbyVariableExpressionPair() { items.add(gbyExprPair); } )*
5410 {
5411 return items;
5412 }
5413}
5414
5415GbyVariableExpressionPair GbyVariableExpressionPair() throws ParseException:
5416{
5417 Expression expr = null;
5418 VariableExpr var = null;
5419}
5420{
5421 expr = Expression() ( (<AS>)? var = Variable() )?
5422 {
5423 return new GbyVariableExpressionPair(var, expr);
5424 }
5425}
5426
Yingyi Bu391f09e2015-10-29 13:49:39 -07005427HavingClause HavingClause() throws ParseException:
5428{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07005429 Token startToken = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07005430 Expression filterExpr = null;
5431}
5432{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07005433 <HAVING> { startToken = token; } filterExpr = Expression()
Yingyi Bu391f09e2015-10-29 13:49:39 -07005434 {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07005435 HavingClause havingClause = new HavingClause(filterExpr);
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07005436 return addSourceLocation(havingClause, startToken);
Yingyi Bu391f09e2015-10-29 13:49:39 -07005437 }
5438}
5439
5440LimitClause LimitClause() throws ParseException:
5441{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07005442 Token startToken = null;
Dmitry Lychagin761c9a62020-11-19 10:22:11 -08005443 Expression limitExpr = null, offsetExpr = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07005444}
5445{
Dmitry Lychagin761c9a62020-11-19 10:22:11 -08005446 (
5447 (
5448 <LIMIT> { startToken = token; pushForbiddenScope(getCurrentScope()); } limitExpr = Expression()
5449 ( <OFFSET> offsetExpr = Expression() )?
5450 { popForbiddenScope(); }
5451 )
5452 |
5453 (
5454 <OFFSET> { startToken = token; pushForbiddenScope(getCurrentScope()); } offsetExpr = Expression()
5455 { popForbiddenScope(); }
5456 )
5457 )
Yingyi Bu391f09e2015-10-29 13:49:39 -07005458 {
Dmitry Lychagin761c9a62020-11-19 10:22:11 -08005459 LimitClause lc = new LimitClause(limitExpr, offsetExpr);
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07005460 return addSourceLocation(lc, startToken);
Yingyi Bu391f09e2015-10-29 13:49:39 -07005461 }
5462}
5463
5464QuantifiedExpression QuantifiedExpression()throws ParseException:
5465{
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07005466 Token startToken = null;
Yingyi Bu391f09e2015-10-29 13:49:39 -07005467 QuantifiedExpression qc = new QuantifiedExpression();
5468 List<QuantifiedPair> quantifiedList = new ArrayList<QuantifiedPair>();
5469 Expression satisfiesExpr;
5470 VariableExpr var;
5471 Expression inExpr;
5472 QuantifiedPair pair;
5473}
5474{
5475 {
5476 createNewScope();
5477 }
5478
ggalvizo21e52822021-07-27 10:26:31 -10005479 ( LOOKAHEAD(2)
5480 (<ANY>|<SOME>)<AND><EVERY> { startToken = token; qc.setQuantifier(QuantifiedExpression.Quantifier.SOME_AND_EVERY); }
5481 | (<ANY>|<SOME>) { startToken = token; qc.setQuantifier(QuantifiedExpression.Quantifier.SOME); }
5482 | <EVERY> { startToken = token; qc.setQuantifier(QuantifiedExpression.Quantifier.EVERY); } )
Yingyi Bu391f09e2015-10-29 13:49:39 -07005483 var = Variable() <IN> inExpr = Expression()
5484 {
5485 pair = new QuantifiedPair(var, inExpr);
Yingyi Bu391f09e2015-10-29 13:49:39 -07005486 quantifiedList.add(pair);
5487 }
5488 (
5489 <COMMA> var = Variable() <IN> inExpr = Expression()
5490 {
5491 pair = new QuantifiedPair(var, inExpr);
Yingyi Bu391f09e2015-10-29 13:49:39 -07005492 quantifiedList.add(pair);
5493 }
5494 )*
Yingyi Bu858efae2016-10-13 17:31:57 -07005495 <SATISFIES> satisfiesExpr = Expression() (<END>)?
Yingyi Bu391f09e2015-10-29 13:49:39 -07005496 {
5497 qc.setSatisfiesExpr(satisfiesExpr);
5498 qc.setQuantifiedList(quantifiedList);
5499 removeCurrentScope();
Dmitry Lychagin5c26b422018-06-01 10:22:16 -07005500 return addSourceLocation(qc, startToken);
Yingyi Bu391f09e2015-10-29 13:49:39 -07005501 }
5502}
5503
5504LetClause LetElement() throws ParseException:
5505{
Yingyi Bu391f09e2015-10-29 13:49:39 -07005506 VariableExpr varExp;
5507 Expression beExp;
5508 extendCurrentScope();
5509}
5510{
5511 varExp = Variable() <EQ> beExp = Expression()
5512 {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07005513 LetClause lc = new LetClause(varExp, beExp);
5514 lc.setSourceLocation(varExp.getSourceLocation());
Yingyi Bu391f09e2015-10-29 13:49:39 -07005515 return lc;
5516 }
5517}
5518
5519LetClause WithElement() throws ParseException:
5520{
Yingyi Bu391f09e2015-10-29 13:49:39 -07005521 VariableExpr varExp;
5522 Expression beExp;
5523 extendCurrentScope();
5524}
5525{
5526 varExp = Variable() <AS> beExp = Expression()
5527 {
Dmitry Lychaginee54cc02018-05-25 19:26:18 -07005528 LetClause lc = new LetClause(varExp, beExp);
5529 lc.setSourceLocation(varExp.getSourceLocation());
Yingyi Bu391f09e2015-10-29 13:49:39 -07005530 return lc;
5531 }
5532}
5533
5534TOKEN_MGR_DECLS:
5535{
5536 public int commentDepth = 0;
Till Westmanne9b2adf2016-10-15 12:39:01 -07005537 public ArrayDeque<Integer> lexerStateStack = new ArrayDeque<Integer>();
Dmitry Lychagine77cdac2019-08-05 11:37:47 -07005538 public Map<SourceLocation, String> hintCollector;
Yingyi Bu391f09e2015-10-29 13:49:39 -07005539
5540 public void pushState() {
5541 lexerStateStack.push( curLexState );
5542 }
5543
5544 public void popState(String token) {
5545 if (lexerStateStack.size() > 0) {
5546 SwitchTo( lexerStateStack.pop() );
5547 } else {
5548 int errorLine = input_stream.getEndLine();
5549 int errorColumn = input_stream.getEndColumn();
5550 String msg = "Lexical error at line " + errorLine + ", column " + errorColumn + ". Encountered \"" + token
5551 + "\" but state stack is empty.";
5552 throw new TokenMgrError(msg, -1);
5553 }
5554 }
Dmitry Lychagine77cdac2019-08-05 11:37:47 -07005555
5556 void CommonTokenAction(Token token) {
5557 Token hintToken = token.specialToken;
Vijay Sarathy243ef2a2022-08-23 11:56:56 -07005558 while (hintToken != null) { // make this a while loop
Dmitry Lychagine77cdac2019-08-05 11:37:47 -07005559 hintToken.sourceLocation = new SourceLocation(hintToken.beginLine, hintToken.beginColumn);
5560 String text = hintToken.image.substring(1).trim();
5561 boolean hintFound = hintToken.parseHint(text);
5562 hintCollector.put(hintToken.sourceLocation, hintFound ? hintToken.hint.getIdentifier() : hintToken.hintParams);
Vijay Sarathy243ef2a2022-08-23 11:56:56 -07005563 hintToken = hintToken.specialToken;
Dmitry Lychagine77cdac2019-08-05 11:37:47 -07005564 }
5565 }
Yingyi Bu391f09e2015-10-29 13:49:39 -07005566}
5567
5568<DEFAULT,IN_DBL_BRACE>
5569TOKEN [IGNORE_CASE]:
5570{
Ian Maxon38fe9402020-01-29 19:27:40 -08005571 <ADAPTER: "adapter">
5572 | <ALL : "all">
Dmitry Lychaginf3eec282022-06-10 12:44:25 -07005573 | <ANALYZE: "analyze">
Yingyi Bu391f09e2015-10-29 13:49:39 -07005574 | <AND : "and">
Yingyi Bu8aac7242016-09-13 23:14:09 -07005575 | <ANY : "any">
Yingyi Bu391f09e2015-10-29 13:49:39 -07005576 | <APPLY : "apply">
5577 | <AS : "as">
5578 | <ASC : "asc">
5579 | <AT : "at">
5580 | <AUTOGENERATED : "autogenerated">
Yingyi Bua8baf6d2016-07-05 21:40:44 -07005581 | <BETWEEN : "between">
Yingyi Bu391f09e2015-10-29 13:49:39 -07005582 | <BTREE : "btree">
5583 | <BY : "by">
5584 | <CASE : "case">
Ali Alsuliman69ce7d82021-11-01 15:00:16 -07005585 | <CAST : "cast">
Yingyi Bu391f09e2015-10-29 13:49:39 -07005586 | <CLOSED : "closed">
5587 | <CREATE : "create">
Dmitry Lychagind3eccd42021-08-19 12:18:17 -07005588 | <CROSS : "cross">
Dmitry Lychagin0ebc4202021-01-25 13:12:41 -08005589 | <COMPACTION : "compaction"> // no longer used
Yingyi Bu391f09e2015-10-29 13:49:39 -07005590 | <COMPACT : "compact">
5591 | <CONNECT : "connect">
5592 | <CORRELATE : "correlate">
Yingyi Bud56ff032016-08-01 10:26:57 -07005593 | <DATASET : "dataset">
Yingyi Bu1c0fff52016-03-25 20:23:30 -07005594 | <COLLECTION : "collection">
Yingyi Bud56ff032016-08-01 10:26:57 -07005595 | <DATAVERSE : "dataverse">
Yingyi Bu391f09e2015-10-29 13:49:39 -07005596 | <DECLARE : "declare">
5597 | <DEFINITION : "definition">
5598 | <DELETE : "delete">
5599 | <DESC : "desc">
5600 | <DISCONNECT : "disconnect">
5601 | <DISTINCT : "distinct">
Murtadha Hubail29f63912019-04-21 14:23:57 +03005602 | <DIV : "div">
Yingyi Bu391f09e2015-10-29 13:49:39 -07005603 | <DROP : "drop">
5604 | <ELEMENT : "element">
Till Westmann516d1a82016-08-02 14:45:53 -07005605 | <EXPLAIN : "explain">
Yingyi Bu391f09e2015-10-29 13:49:39 -07005606 | <ELSE : "else">
5607 | <ENFORCED : "enforced">
Yingyi Buc8c067c2016-07-25 23:37:19 -07005608 | <END : "end">
Yingyi Bu391f09e2015-10-29 13:49:39 -07005609 | <EVERY : "every">
5610 | <EXCEPT : "except">
5611 | <EXISTS : "exists">
5612 | <EXTERNAL : "external">
Dmitry Lychagin41b511d2020-12-07 14:48:13 -08005613 | <FALSE : "false">
Yingyi Bu391f09e2015-10-29 13:49:39 -07005614 | <FEED : "feed">
5615 | <FILTER : "filter">
5616 | <FLATTEN : "flatten">
5617 | <FOR : "for">
Yingyi Bu391f09e2015-10-29 13:49:39 -07005618 | <FROM : "from">
5619 | <FULL : "full">
Taewoo Kimc49405a2017-01-04 00:30:43 -08005620 | <FULLTEXT : "fulltext">
Yingyi Bu391f09e2015-10-29 13:49:39 -07005621 | <FUNCTION : "function">
5622 | <GROUP : "group">
5623 | <HAVING : "having">
5624 | <HINTS : "hints">
5625 | <IF : "if">
5626 | <INTO : "into">
5627 | <IN : "in">
5628 | <INDEX : "index">
5629 | <INGESTION : "ingestion">
5630 | <INNER : "inner">
5631 | <INSERT : "insert">
5632 | <INTERNAL : "internal">
5633 | <INTERSECT : "intersect">
Yingyi Budaa549c2016-06-28 22:30:52 -07005634 | <IS : "is">
Yingyi Bu391f09e2015-10-29 13:49:39 -07005635 | <JOIN : "join">
5636 | <KEYWORD : "keyword">
5637 | <KEY : "key">
Dmitry Lychagin1aa0dd42018-04-17 14:35:24 -07005638 | <KNOWN : "known">
Yingyi Bu391f09e2015-10-29 13:49:39 -07005639 | <LEFT : "left">
5640 | <LETTING : "letting">
5641 | <LET : "let">
Yingyi Bua8baf6d2016-07-05 21:40:44 -07005642 | <LIKE : "like">
Yingyi Bu391f09e2015-10-29 13:49:39 -07005643 | <LIMIT : "limit">
5644 | <LOAD : "load">
Dmitry Lychagin41b511d2020-12-07 14:48:13 -08005645 | <MISSING : "missing">
Murtadha Hubail29f63912019-04-21 14:23:57 +03005646 | <MOD : "mod">
Yingyi Bu391f09e2015-10-29 13:49:39 -07005647 | <NODEGROUP : "nodegroup">
5648 | <NGRAM : "ngram">
Yingyi Budaa549c2016-06-28 22:30:52 -07005649 | <NOT : "not">
Dmitry Lychagin41b511d2020-12-07 14:48:13 -08005650 | <NULL : "null">
Yingyi Bu391f09e2015-10-29 13:49:39 -07005651 | <OFFSET : "offset">
5652 | <ON : "on">
5653 | <OPEN : "open">
5654 | <OR : "or">
5655 | <ORDER : "order">
5656 | <OUTER : "outer">
5657 | <OUTPUT : "output">
Dmitry Lychaginfdedf622018-10-30 18:12:40 -07005658 | <OVER: "over">
Yingyi Bu391f09e2015-10-29 13:49:39 -07005659 | <PATH : "path">
5660 | <POLICY : "policy">
5661 | <PRESORTED : "pre-sorted">
5662 | <PRIMARY : "primary">
5663 | <RAW : "raw">
5664 | <REFRESH : "refresh">
5665 | <RETURN : "return">
Yingyi Bucb5bf332017-01-02 22:19:50 -08005666 | <RETURNING : "returning">
Dmitry Lychagind4ce84c2020-10-13 16:24:37 -07005667 | <RIGHT : "right">
Yingyi Bu391f09e2015-10-29 13:49:39 -07005668 | <RTREE : "rtree">
5669 | <RUN : "run">
5670 | <SATISFIES : "satisfies">
5671 | <SECONDARY : "secondary">
5672 | <SELECT : "select">
5673 | <SET : "set">
5674 | <SOME : "some">
Abdullah Alamoudifff200c2017-02-18 20:32:14 -08005675 | <START : "start">
5676 | <STOP : "stop">
Dmitry Lychagin2a0848e2020-01-08 13:57:22 -08005677 | <SYNONYM : "synonym">
Murtadha Hubail2c04ae02017-11-21 15:58:01 +03005678 | <TEMPORARY : "temporary"> // intentionally not used but reserved for future usage
Yingyi Bu391f09e2015-10-29 13:49:39 -07005679 | <THEN : "then">
Yingyi Bu391f09e2015-10-29 13:49:39 -07005680 | <TO : "to">
Dmitry Lychagin41b511d2020-12-07 14:48:13 -08005681 | <TRUE : "true">
5682 | <TYPE : "type">
Yingyi Bu391f09e2015-10-29 13:49:39 -07005683 | <UNION : "union">
Dmitry Lychagin8b6578a2017-11-08 15:04:35 -08005684 | <UNKNOWN : "unknown">
Yingyi Bu391f09e2015-10-29 13:49:39 -07005685 | <UNNEST : "unnest">
Yingyi Budaa549c2016-06-28 22:30:52 -07005686 | <UPDATE : "update">
Yingyi Bucb5bf332017-01-02 22:19:50 -08005687 | <UPSERT : "upsert">
Yingyi Budaa549c2016-06-28 22:30:52 -07005688 | <USE : "use">
5689 | <USING : "using">
Yingyi Bu391f09e2015-10-29 13:49:39 -07005690 | <VALUE : "value">
Dmitry Lychagin7d594a32018-01-15 14:31:03 -08005691 | <VALUED : "valued">
Dmitry Lychagin793c39e2021-04-21 16:52:10 -07005692 | <VIEW : "view">
Yingyi Bu391f09e2015-10-29 13:49:39 -07005693 | <WHEN : "when">
5694 | <WHERE : "where">
5695 | <WITH : "with">
5696 | <WRITE : "write">
Yingyi Bu391f09e2015-10-29 13:49:39 -07005697}
5698
5699<DEFAULT,IN_DBL_BRACE>
5700TOKEN :
5701{
5702 <CARET : "^">
Yingyi Bufdc71eb2016-08-24 22:41:57 -07005703 | <CONCAT : "||">
Dmitry Lychaginbf48c492018-05-01 18:30:27 -07005704 | <DIVIDE : "/">
Yingyi Bu391f09e2015-10-29 13:49:39 -07005705 | <MINUS : "-">
Yingyi Bu391f09e2015-10-29 13:49:39 -07005706 | <MUL : "*">
5707 | <PLUS : "+">
5708
5709 | <LEFTPAREN : "(">
5710 | <RIGHTPAREN : ")">
5711 | <LEFTBRACKET : "[">
5712 | <RIGHTBRACKET : "]">
5713
5714 | <ATT : "@">
5715 | <COLON : ":">
5716 | <COMMA : ",">
5717 | <DOT : ".">
Dmitry Lychaginbf48c492018-05-01 18:30:27 -07005718 | <PERCENT: "%">
Yingyi Bu391f09e2015-10-29 13:49:39 -07005719 | <QUES : "?">
5720 | <SEMICOLON : ";">
5721 | <SHARP : "#">
5722
5723 | <LT : "<">
5724 | <GT : ">">
5725 | <LE : "<=">
5726 | <GE : ">=">
5727 | <EQ : "=">
5728 | <NE : "!=">
Yingyi Bu4a4b8962016-09-16 12:09:11 -07005729 | <LG : "<>">
Yingyi Bu391f09e2015-10-29 13:49:39 -07005730 | <SIMILAR : "~=">
5731}
5732
5733<DEFAULT,IN_DBL_BRACE>
5734TOKEN :
5735{
5736 <LEFTBRACE : "{"> { pushState(); } : DEFAULT
5737}
5738
5739<DEFAULT>
5740TOKEN :
5741{
5742 <RIGHTBRACE : "}"> { popState("}"); }
5743}
5744
5745<DEFAULT,IN_DBL_BRACE>
5746TOKEN :
5747{
5748 <LEFTDBLBRACE : "{{"> { pushState(); } : IN_DBL_BRACE
5749}
5750
5751<IN_DBL_BRACE>
5752TOKEN :
5753{
5754 <RIGHTDBLBRACE : "}}"> { popState("}}"); }
5755}
5756
5757<DEFAULT,IN_DBL_BRACE>
5758TOKEN :
5759{
Yingyi Bu391f09e2015-10-29 13:49:39 -07005760 <#DIGIT : ["0" - "9"]>
5761}
5762
5763<DEFAULT,IN_DBL_BRACE>
5764TOKEN:
5765{
Dmitry Lychagin41b511d2020-12-07 14:48:13 -08005766 <INTEGER_LITERAL : <DIGITS> >
5767 | <DOUBLE_LITERAL: <DIGITS> ( "." <DIGITS> ) (("e"|"E") ("+"|"-")? <DIGITS>)?
Dmitry Lychaginee8526b2018-03-30 14:21:01 -07005768 | <DIGITS> (("e"|"E") ("+"|"-")? <DIGITS>)
5769 | "." <DIGITS> (("e"|"E") ("+"|"-")? <DIGITS>)?
Yingyi Bu391f09e2015-10-29 13:49:39 -07005770 >
Dmitry Lychagin41b511d2020-12-07 14:48:13 -08005771 | <FLOAT_LITERAL: <DIGITS> ( "f" | "F" )
Yingyi Bue4d919e2016-10-30 10:47:03 -07005772 | <DIGITS> ( "." <DIGITS> ( "f" | "F" ) )?
5773 | "." <DIGITS> ( "f" | "F" )
Yingyi Bu391f09e2015-10-29 13:49:39 -07005774 >
Dmitry Lychagin41b511d2020-12-07 14:48:13 -08005775 | <#DIGITS : (<DIGIT>)+ >
Yingyi Bu391f09e2015-10-29 13:49:39 -07005776}
5777
5778<DEFAULT,IN_DBL_BRACE>
5779TOKEN :
5780{
5781 <#LETTER : ["A" - "Z", "a" - "z"]>
Dmitry Lychagin41b511d2020-12-07 14:48:13 -08005782 | <#IDENTIFIER_START_SPECIALCHAR : ["_"]>
5783 | <#IDENTIFIER_REST_SPECIALCHAR : ["$"]>
5784 | <#IDENTIFIER_START : <LETTER> | <IDENTIFIER_START_SPECIALCHAR> >
5785 | <#IDENTIFIER_REST : <LETTER> | <DIGIT> | <IDENTIFIER_START_SPECIALCHAR> | <IDENTIFIER_REST_SPECIALCHAR> >
5786 | <IDENTIFIER : <IDENTIFIER_START> (<IDENTIFIER_REST>)* >
Yingyi Bu391f09e2015-10-29 13:49:39 -07005787}
5788
5789<DEFAULT,IN_DBL_BRACE>
5790TOKEN :
5791{
5792 // backslash u + 4 hex digits escapes are handled in the underlying JavaCharStream
Yingyi Bu6d57e492016-06-06 21:24:42 -07005793 <QUOTED_STRING : "`" (
Yingyi Bu391f09e2015-10-29 13:49:39 -07005794 <EscapeQuot>
5795 | <EscapeBslash>
5796 | <EscapeSlash>
5797 | <EscapeBspace>
5798 | <EscapeFormf>
5799 | <EscapeNl>
5800 | <EscapeCr>
5801 | <EscapeTab>
Yingyi Bu6d57e492016-06-06 21:24:42 -07005802 | ~["`","\\"])* "`">
Dmitry Lychagin984bc522021-10-13 16:22:25 -07005803 | <STRING_LITERAL : ( ("E")? "\"" (
Yingyi Bu391f09e2015-10-29 13:49:39 -07005804 <EscapeQuot>
Yingyi Bu391f09e2015-10-29 13:49:39 -07005805 | <EscapeBslash>
5806 | <EscapeSlash>
5807 | <EscapeBspace>
5808 | <EscapeFormf>
5809 | <EscapeNl>
5810 | <EscapeCr>
5811 | <EscapeTab>
Yingyi Bu6d57e492016-06-06 21:24:42 -07005812 | ~["\"","\\"])* "\"")
Dmitry Lychagin984bc522021-10-13 16:22:25 -07005813 | ( ("E")? "\'" (
Yingyi Bu6d57e492016-06-06 21:24:42 -07005814 <EscapeApos>
5815 | <EscapeBslash>
5816 | <EscapeSlash>
5817 | <EscapeBspace>
5818 | <EscapeFormf>
5819 | <EscapeNl>
5820 | <EscapeCr>
5821 | <EscapeTab>
5822 | ~["\'","\\"])* "\'")>
Yingyi Bu391f09e2015-10-29 13:49:39 -07005823 | < #EscapeQuot: "\\\"" >
5824 | < #EscapeApos: "\\\'" >
5825 | < #EscapeBslash: "\\\\" >
5826 | < #EscapeSlash: "\\/" >
5827 | < #EscapeBspace: "\\b" >
5828 | < #EscapeFormf: "\\f" >
5829 | < #EscapeNl: "\\n" >
5830 | < #EscapeCr: "\\r" >
5831 | < #EscapeTab: "\\t" >
5832}
5833
5834<DEFAULT,IN_DBL_BRACE>
5835TOKEN :
5836{
Dmitry Lychagin41b511d2020-12-07 14:48:13 -08005837 <DOLLAR_INTEGER_LITERAL : "$" <INTEGER_LITERAL> >
5838 | <DOLLAR_IDENTIFIER : "$" <IDENTIFIER> >
5839 | <DOLLAR_QUOTED_STRING: "$" <QUOTED_STRING> >
Yingyi Bu391f09e2015-10-29 13:49:39 -07005840}
5841
5842<DEFAULT,IN_DBL_BRACE>
5843SKIP:
5844{
5845 " "
5846 | "\t"
5847 | "\r"
5848 | "\n"
5849}
5850
5851<DEFAULT,IN_DBL_BRACE>
5852SKIP:
5853{
5854 <"//" (~["\n"])* "\n">
5855}
5856
5857<DEFAULT,IN_DBL_BRACE>
5858SKIP:
5859{
5860 <"//" (~["\n","\r"])* ("\n"|"\r"|"\r\n")?>
5861}
5862
5863<DEFAULT,IN_DBL_BRACE>
5864SKIP:
5865{
Yingyi Bu93846a72016-09-13 16:30:39 -07005866 <"--" (~["\n"])* "\n">
5867}
5868
5869
5870<DEFAULT,IN_DBL_BRACE>
5871SKIP:
5872{
5873 <"--" (~["\n","\r"])* ("\n"|"\r"|"\r\n")?>
5874}
5875
5876<DEFAULT,IN_DBL_BRACE>
5877SKIP:
5878{
Yingyi Bu391f09e2015-10-29 13:49:39 -07005879 <"/*"> { pushState(); } : INSIDE_COMMENT
5880}
5881
5882<INSIDE_COMMENT>
5883SPECIAL_TOKEN:
5884{
5885 <"+"(" ")*(~["*"])*>
5886}
5887
5888<INSIDE_COMMENT>
5889SKIP:
5890{
5891 <"/*"> { pushState(); }
5892}
5893
5894<INSIDE_COMMENT>
5895SKIP:
5896{
5897 <"*/"> { popState("*/"); }
5898 | <~[]>
5899}