blob: 6d215f0c9f55763a7a93791c2f78bd0c0e081f51 [file] [log] [blame]
ggalvizoab83c3b2021-12-22 14:15:50 -08001//
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//
19
20import org.apache.asterix.graphix.common.metadata.GraphElementIdentifier;
21import org.apache.asterix.graphix.lang.expression.GraphConstructor;
22import org.apache.asterix.graphix.lang.statement.CreateGraphStatement;
23import org.apache.asterix.graphix.lang.statement.GraphDropStatement;
24import org.apache.asterix.graphix.lang.statement.GraphElementDecl;
25import org.apache.asterix.lang.sqlpp.parser.ParseException;
26import org.apache.asterix.lang.sqlpp.parser.SqlppParseException;
27import org.apache.asterix.lang.sqlpp.parser.Token;
28
29@new_at_the_class_def
30public GraphElementDecl parseGraphElementBody(GraphElementIdentifier identifier) throws CompilationException {
31 return parseImpl(new ParseFunction<GraphElementDecl>() {
32 @Override
33 public GraphElementDecl parse() throws ParseException {
34 DataverseName dataverse = defaultDataverse;
35 defaultDataverse = identifier.getGraphIdentifier().getDataverseName();
36
37 // We borrow the ViewBody production, where we have a SelectExpression or a VariableRef.
38 createNewScope();
39 Expression elementBodyExpr = GraphixParser.this.ViewBody();
40 removeCurrentScope();
41
42 defaultDataverse = dataverse;
43 return new GraphElementDecl(identifier, elementBodyExpr);
44 }
45 });
46}
47
48@merge
49Statement CreateStatement() throws ParseException:
50{
51 // merge area 1
52 before:
53 after:
54}
55{
56 (
57 // merge area 2
58 before:
59 after: | stmt = CreateGraphStatement(startToken, false)
60 )
61 {
62 // merge area 3
63 }
64}
65
66@merge
67Statement CreateOrReplaceStatement(Token startStmtToken) throws ParseException:
68{
69 // merge area 1
70 before:
71 after:
72}
73{
74 (
75 // merge area 2
76 before:
77 after: | stmt = CreateGraphStatement(startStmtToken, true)
78 )
79 {
80 // merge area 3
81 }
82}
83
84@merge
85Statement DropStatement() throws ParseException:
86{
87 // merge area 1
88 before:
89 after:
90}
91{
92 (
93 // merge area 2
94 before:
95 after: | stmt = DropGraphStatement(startToken)
96 )
97 {
98 // merge area 3
99 }
100}
101
102@new
103CreateGraphStatement CreateGraphStatement(Token startStmtToken, boolean orReplace) throws ParseException:
104{
105 CreateGraphStatement stmt = null;
106}
107{
108 <GRAPH> stmt = CreateGraphSpecification(startStmtToken, orReplace)
109 {
110 return stmt;
111 }
112}
113
114@new
115CreateGraphStatement CreateGraphSpecification(Token startStmtToken, boolean orReplace) throws ParseException:
116{
117 Pair<DataverseName, Identifier> nameComponents = null;
118 GraphConstructor graphConstructor = null;
119 boolean ifNotExists = false;
120}
121{
122 nameComponents = QualifiedName()
123 ifNotExists = IfNotExists()
124 {
125 if (orReplace && ifNotExists) {
126 throw new SqlppParseException(getSourceLocation(startStmtToken), "Unexpected IF NOT EXISTS");
127 }
128 }
129 <AS> graphConstructor = GraphConstructor(token)
130 {
131 CreateGraphStatement stmt = new CreateGraphStatement(nameComponents.first, nameComponents.second.getValue(),
132 orReplace, ifNotExists, graphConstructor);
133 return addSourceLocation(stmt, startStmtToken);
134 }
135}
136
137@new
138GraphDropStatement DropGraphStatement(Token startStmtToken) throws ParseException:
139{
140 GraphDropStatement stmt = null;
141}
142{
143 <GRAPH> stmt = DropGraphSpecification(startStmtToken)
144 {
145 return stmt;
146 }
147}
148
149@new
150GraphDropStatement DropGraphSpecification(Token startStmtToken) throws ParseException:
151{
152 Pair<DataverseName, Identifier> pairId = null;
153 boolean ifExists = false;
154}
155{
156 pairId = QualifiedName() ifExists = IfExists()
157 {
158 GraphDropStatement stmt = new GraphDropStatement(pairId.first, pairId.second.getValue(), ifExists);
159 return addSourceLocation(stmt, startStmtToken);
160 }
161}
162
163@new
164Pair<List<Integer>, List<List<String>>> KeyFields() throws ParseException:
165{
166 Pair<List<Integer>, List<List<String>>> keyFields = null;
167}
168{
169 // This is essentially an alias for the production PrimaryKeyFields.
170 keyFields = PrimaryKeyFields()
171 {
172 return keyFields;
173 }
174}
175
176@new
177GraphConstructor GraphConstructor(Token startStmtToken) throws ParseException:
178{
179 List<GraphConstructor.VertexElement> vertexElements = new ArrayList<GraphConstructor.VertexElement>();
180 List<GraphConstructor.EdgeElement> edgeElements = new ArrayList<GraphConstructor.EdgeElement>();
181 GraphConstructor.VertexElement vertexElement = null;
182 GraphConstructor.EdgeElement edgeElement = null;
183}
184{
185 vertexElement = GraphVertexSpecification(startStmtToken) { vertexElements.add(vertexElement); }
186 ( <COMMA>
187 (
188 ( vertexElement = GraphVertexSpecification(token) { vertexElements.add(vertexElement); } )
189 | ( edgeElement = GraphEdgeSpecification(token) { edgeElements.add(edgeElement); } )
190 )
191 )*
192 {
193 GraphConstructor graphConstructor = new GraphConstructor(vertexElements, edgeElements);
194 return addSourceLocation(graphConstructor, startStmtToken);
195 }
196}
197
198@new
199GraphConstructor.VertexElement GraphVertexSpecification(Token startStmtToken) throws ParseException:
200{
201 Pair<List<Integer>, List<List<String>>> primaryKeyFields;
202 Token beginPos = null, endPos = null;
203 Expression vertexDefinitionExpr;
204 String vertexName;
205}
206{
207 <VERTEX>
208 vertexName = GraphVertexDefinitionPattern()
209 <PRIMARY> <KEY> <LEFTPAREN> primaryKeyFields = KeyFields() <RIGHTPAREN>
210 <AS>
211 {
212 beginPos = token;
213 createNewScope();
214 }
215 (
216 vertexDefinitionExpr = ViewBody()
217 | <LEFTPAREN> vertexDefinitionExpr = ViewBody() <RIGHTPAREN>
218 )
219 {
220 endPos = token;
221 String vDef = extractFragment(beginPos.beginLine, beginPos.beginColumn + 1, endPos.endLine, endPos.endColumn + 1);
222 removeCurrentScope();
223 GraphConstructor.VertexElement vertexElement = new GraphConstructor.VertexElement(vertexName,
224 primaryKeyFields.second, primaryKeyFields.first, vertexDefinitionExpr, vDef);
225 return addSourceLocation(vertexElement, startStmtToken);
226 }
227}
228
229@new
230String GraphVertexDefinitionPattern() throws ParseException:
231{
232 String vertexName;
233}
234{
235 <LEFTPAREN> <COLON> vertexName = Identifier() <RIGHTPAREN>
236 {
237 return vertexName;
238 }
239}
240
241@new
242GraphConstructor.EdgeElement GraphEdgeSpecification(Token startStmtToken) throws ParseException:
243{
244 Pair<Triple<String, String, String>, Boolean> edgeDefinitionPattern;
245 Pair<List<Integer>, List<List<String>>> keyFields;
246 Token beginPos = null, endPos = null;
247 Expression edgeDefinitionExpr = null;
248
249 List<Integer> destinationKeySourceIndicators = null;
250 List<Integer> sourceKeySourceIndicators = null;
251 List<Integer> primaryKeySourceIndicators = null;
252 List<List<String>> destinationKeyFields = null;
253 List<List<String>> sourceKeyFields = null;
254 List<List<String>> primaryKeyFields = null;
255}
256{
257 <EDGE>
258 edgeDefinitionPattern = GraphEdgeDefinitionPattern()
259 (
260 (
261 <PRIMARY> <KEY> <LEFTPAREN> keyFields = KeyFields() <RIGHTPAREN>
262 {
263 primaryKeyFields = keyFields.second;
264 primaryKeySourceIndicators = keyFields.first;
265 }
266 <SOURCE> <KEY> <LEFTPAREN> keyFields = KeyFields() <RIGHTPAREN>
267 {
268 sourceKeyFields = keyFields.second;
269 sourceKeySourceIndicators = keyFields.first;
270 }
271 <DESTINATION> <KEY> <LEFTPAREN> keyFields = KeyFields() <RIGHTPAREN>
272 {
273 destinationKeyFields = keyFields.second;
274 destinationKeySourceIndicators = keyFields.first;
275 }
276 <AS>
277 {
278 beginPos = token;
279 createNewScope();
280 }
281 (
282 edgeDefinitionExpr = ViewBody()
283 | <LEFTPAREN> edgeDefinitionExpr = ViewBody() <RIGHTPAREN>
284 )
285 )
286 |
287 (
288 <DESTINATION> <KEY> <LEFTPAREN> keyFields = KeyFields() <RIGHTPAREN>
289 {
290 destinationKeyFields = keyFields.second;
291 destinationKeySourceIndicators = keyFields.first;
292 }
293 )
294 )
295 {
296 String destinationLabel, edgeLabel, sourceLabel;
297 if (edgeDefinitionPattern.second) { // isDirectedLeft
298 sourceLabel = edgeDefinitionPattern.first.third;
299 edgeLabel = edgeDefinitionPattern.first.second;
300 destinationLabel = edgeDefinitionPattern.first.first;
301 } else {
302 sourceLabel = edgeDefinitionPattern.first.first;
303 edgeLabel = edgeDefinitionPattern.first.second;
304 destinationLabel = edgeDefinitionPattern.first.third;
305 }
306
307 String eDef = null;
308 if (edgeDefinitionExpr != null) {
309 endPos = token;
310 eDef = extractFragment(beginPos.beginLine, beginPos.beginColumn + 1, endPos.endLine, endPos.endColumn + 1);
311 removeCurrentScope();
312 }
313
314 GraphConstructor.EdgeElement edgeElement = new GraphConstructor.EdgeElement(edgeLabel, destinationLabel,
315 sourceLabel, primaryKeyFields, primaryKeySourceIndicators, destinationKeyFields, destinationKeySourceIndicators,
316 sourceKeyFields, sourceKeySourceIndicators, edgeDefinitionExpr, eDef);
317 return addSourceLocation(edgeElement, startStmtToken);
318 }
319}
320
321@new
322Pair<Triple<String, String, String>, Boolean> GraphEdgeDefinitionPattern() throws ParseException:
323{
324 String leftVertexName, edgeName, rightVertexName;
325 boolean isDirectedLeft;
326}
327{
328 leftVertexName = GraphVertexDefinitionPattern()
329 ( <MINUS> <LEFTBRACKET> <COLON> edgeName = Identifier() <RIGHTBRACKET> <MINUS> <GT> { isDirectedLeft = false; }
330 | <LT> <MINUS> <LEFTBRACKET> <COLON> edgeName = Identifier() <RIGHTBRACKET> <MINUS> { isDirectedLeft = true; } )
331 rightVertexName = GraphVertexDefinitionPattern()
332 {
333 Triple<String, String, String> t = new Triple<String, String, String>(leftVertexName, edgeName, rightVertexName);
334 return new Pair<Triple<String, String, String>, Boolean>(t, isDirectedLeft);
335 }
336}
337
338@new
339<DEFAULT,IN_DBL_BRACE>
340TOKEN [IGNORE_CASE]:
341{
342 <DESTINATION: "destination">
343 | <EDGE: "edge">
344 | <GRAPH: "graph">
345 | <SOURCE: "source">
346 | <VERTEX: "vertex">
347}
348
349@new_at_the_end
350<DEFAULT,IN_DBL_BRACE>
351TOKEN :
352{
353 <BAR: "|">
354}