| // |
| // Licensed to the Apache Software Foundation (ASF) under one |
| // or more contributor license agreements. See the NOTICE file |
| // distributed with this work for additional information |
| // regarding copyright ownership. The ASF licenses this file |
| // to you under the Apache License, Version 2.0 (the |
| // "License"); you may not use this file except in compliance |
| // with the License. You may obtain a copy of the License at |
| // |
| // http://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, |
| // software distributed under the License is distributed on an |
| // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| // KIND, either express or implied. See the License for the |
| // specific language governing permissions and limitations |
| // under the License. |
| // |
| |
| import org.apache.asterix.graphix.common.metadata.GraphElementIdentifier; |
| import org.apache.asterix.graphix.lang.expression.GraphConstructor; |
| import org.apache.asterix.graphix.lang.statement.CreateGraphStatement; |
| import org.apache.asterix.graphix.lang.statement.GraphDropStatement; |
| import org.apache.asterix.graphix.lang.statement.GraphElementDecl; |
| import org.apache.asterix.lang.sqlpp.parser.ParseException; |
| import org.apache.asterix.lang.sqlpp.parser.SqlppParseException; |
| import org.apache.asterix.lang.sqlpp.parser.Token; |
| |
| @new_at_the_class_def |
| public GraphElementDecl parseGraphElementBody(GraphElementIdentifier identifier) throws CompilationException { |
| return parseImpl(new ParseFunction<GraphElementDecl>() { |
| @Override |
| public GraphElementDecl parse() throws ParseException { |
| DataverseName dataverse = defaultDataverse; |
| defaultDataverse = identifier.getGraphIdentifier().getDataverseName(); |
| |
| // We borrow the ViewBody production, where we have a SelectExpression or a VariableRef. |
| createNewScope(); |
| Expression elementBodyExpr = GraphixParser.this.ViewBody(); |
| removeCurrentScope(); |
| |
| defaultDataverse = dataverse; |
| return new GraphElementDecl(identifier, elementBodyExpr); |
| } |
| }); |
| } |
| |
| @merge |
| Statement CreateStatement() throws ParseException: |
| { |
| // merge area 1 |
| before: |
| after: |
| } |
| { |
| ( |
| // merge area 2 |
| before: |
| after: | stmt = CreateGraphStatement(startToken, false) |
| ) |
| { |
| // merge area 3 |
| } |
| } |
| |
| @merge |
| Statement CreateOrReplaceStatement(Token startStmtToken) throws ParseException: |
| { |
| // merge area 1 |
| before: |
| after: |
| } |
| { |
| ( |
| // merge area 2 |
| before: |
| after: | stmt = CreateGraphStatement(startStmtToken, true) |
| ) |
| { |
| // merge area 3 |
| } |
| } |
| |
| @merge |
| Statement DropStatement() throws ParseException: |
| { |
| // merge area 1 |
| before: |
| after: |
| } |
| { |
| ( |
| // merge area 2 |
| before: |
| after: | stmt = DropGraphStatement(startToken) |
| ) |
| { |
| // merge area 3 |
| } |
| } |
| |
| @new |
| CreateGraphStatement CreateGraphStatement(Token startStmtToken, boolean orReplace) throws ParseException: |
| { |
| CreateGraphStatement stmt = null; |
| } |
| { |
| <GRAPH> stmt = CreateGraphSpecification(startStmtToken, orReplace) |
| { |
| return stmt; |
| } |
| } |
| |
| @new |
| CreateGraphStatement CreateGraphSpecification(Token startStmtToken, boolean orReplace) throws ParseException: |
| { |
| Pair<DataverseName, Identifier> nameComponents = null; |
| GraphConstructor graphConstructor = null; |
| boolean ifNotExists = false; |
| } |
| { |
| nameComponents = QualifiedName() |
| ifNotExists = IfNotExists() |
| { |
| if (orReplace && ifNotExists) { |
| throw new SqlppParseException(getSourceLocation(startStmtToken), "Unexpected IF NOT EXISTS"); |
| } |
| } |
| <AS> graphConstructor = GraphConstructor(token) |
| { |
| CreateGraphStatement stmt = new CreateGraphStatement(nameComponents.first, nameComponents.second.getValue(), |
| orReplace, ifNotExists, graphConstructor); |
| return addSourceLocation(stmt, startStmtToken); |
| } |
| } |
| |
| @new |
| GraphDropStatement DropGraphStatement(Token startStmtToken) throws ParseException: |
| { |
| GraphDropStatement stmt = null; |
| } |
| { |
| <GRAPH> stmt = DropGraphSpecification(startStmtToken) |
| { |
| return stmt; |
| } |
| } |
| |
| @new |
| GraphDropStatement DropGraphSpecification(Token startStmtToken) throws ParseException: |
| { |
| Pair<DataverseName, Identifier> pairId = null; |
| boolean ifExists = false; |
| } |
| { |
| pairId = QualifiedName() ifExists = IfExists() |
| { |
| GraphDropStatement stmt = new GraphDropStatement(pairId.first, pairId.second.getValue(), ifExists); |
| return addSourceLocation(stmt, startStmtToken); |
| } |
| } |
| |
| @new |
| Pair<List<Integer>, List<List<String>>> KeyFields() throws ParseException: |
| { |
| Pair<List<Integer>, List<List<String>>> keyFields = null; |
| } |
| { |
| // This is essentially an alias for the production PrimaryKeyFields. |
| keyFields = PrimaryKeyFields() |
| { |
| return keyFields; |
| } |
| } |
| |
| @new |
| GraphConstructor GraphConstructor(Token startStmtToken) throws ParseException: |
| { |
| List<GraphConstructor.VertexElement> vertexElements = new ArrayList<GraphConstructor.VertexElement>(); |
| List<GraphConstructor.EdgeElement> edgeElements = new ArrayList<GraphConstructor.EdgeElement>(); |
| GraphConstructor.VertexElement vertexElement = null; |
| GraphConstructor.EdgeElement edgeElement = null; |
| } |
| { |
| vertexElement = GraphVertexSpecification(startStmtToken) { vertexElements.add(vertexElement); } |
| ( <COMMA> |
| ( |
| ( vertexElement = GraphVertexSpecification(token) { vertexElements.add(vertexElement); } ) |
| | ( edgeElement = GraphEdgeSpecification(token) { edgeElements.add(edgeElement); } ) |
| ) |
| )* |
| { |
| GraphConstructor graphConstructor = new GraphConstructor(vertexElements, edgeElements); |
| return addSourceLocation(graphConstructor, startStmtToken); |
| } |
| } |
| |
| @new |
| GraphConstructor.VertexElement GraphVertexSpecification(Token startStmtToken) throws ParseException: |
| { |
| Pair<List<Integer>, List<List<String>>> primaryKeyFields; |
| Token beginPos = null, endPos = null; |
| Expression vertexDefinitionExpr; |
| String vertexName; |
| } |
| { |
| <VERTEX> |
| vertexName = GraphVertexDefinitionPattern() |
| <PRIMARY> <KEY> <LEFTPAREN> primaryKeyFields = KeyFields() <RIGHTPAREN> |
| <AS> |
| { |
| beginPos = token; |
| createNewScope(); |
| } |
| ( |
| vertexDefinitionExpr = ViewBody() |
| | <LEFTPAREN> vertexDefinitionExpr = ViewBody() <RIGHTPAREN> |
| ) |
| { |
| endPos = token; |
| String vDef = extractFragment(beginPos.beginLine, beginPos.beginColumn + 1, endPos.endLine, endPos.endColumn + 1); |
| removeCurrentScope(); |
| GraphConstructor.VertexElement vertexElement = new GraphConstructor.VertexElement(vertexName, |
| primaryKeyFields.second, primaryKeyFields.first, vertexDefinitionExpr, vDef); |
| return addSourceLocation(vertexElement, startStmtToken); |
| } |
| } |
| |
| @new |
| String GraphVertexDefinitionPattern() throws ParseException: |
| { |
| String vertexName; |
| } |
| { |
| <LEFTPAREN> <COLON> vertexName = Identifier() <RIGHTPAREN> |
| { |
| return vertexName; |
| } |
| } |
| |
| @new |
| GraphConstructor.EdgeElement GraphEdgeSpecification(Token startStmtToken) throws ParseException: |
| { |
| Pair<Triple<String, String, String>, Boolean> edgeDefinitionPattern; |
| Pair<List<Integer>, List<List<String>>> keyFields; |
| Token beginPos = null, endPos = null; |
| Expression edgeDefinitionExpr = null; |
| |
| List<Integer> destinationKeySourceIndicators = null; |
| List<Integer> sourceKeySourceIndicators = null; |
| List<Integer> primaryKeySourceIndicators = null; |
| List<List<String>> destinationKeyFields = null; |
| List<List<String>> sourceKeyFields = null; |
| List<List<String>> primaryKeyFields = null; |
| } |
| { |
| <EDGE> |
| edgeDefinitionPattern = GraphEdgeDefinitionPattern() |
| ( |
| ( |
| <PRIMARY> <KEY> <LEFTPAREN> keyFields = KeyFields() <RIGHTPAREN> |
| { |
| primaryKeyFields = keyFields.second; |
| primaryKeySourceIndicators = keyFields.first; |
| } |
| <SOURCE> <KEY> <LEFTPAREN> keyFields = KeyFields() <RIGHTPAREN> |
| { |
| sourceKeyFields = keyFields.second; |
| sourceKeySourceIndicators = keyFields.first; |
| } |
| <DESTINATION> <KEY> <LEFTPAREN> keyFields = KeyFields() <RIGHTPAREN> |
| { |
| destinationKeyFields = keyFields.second; |
| destinationKeySourceIndicators = keyFields.first; |
| } |
| <AS> |
| { |
| beginPos = token; |
| createNewScope(); |
| } |
| ( |
| edgeDefinitionExpr = ViewBody() |
| | <LEFTPAREN> edgeDefinitionExpr = ViewBody() <RIGHTPAREN> |
| ) |
| ) |
| | |
| ( |
| <DESTINATION> <KEY> <LEFTPAREN> keyFields = KeyFields() <RIGHTPAREN> |
| { |
| destinationKeyFields = keyFields.second; |
| destinationKeySourceIndicators = keyFields.first; |
| } |
| ) |
| ) |
| { |
| String destinationLabel, edgeLabel, sourceLabel; |
| if (edgeDefinitionPattern.second) { // isDirectedLeft |
| sourceLabel = edgeDefinitionPattern.first.third; |
| edgeLabel = edgeDefinitionPattern.first.second; |
| destinationLabel = edgeDefinitionPattern.first.first; |
| } else { |
| sourceLabel = edgeDefinitionPattern.first.first; |
| edgeLabel = edgeDefinitionPattern.first.second; |
| destinationLabel = edgeDefinitionPattern.first.third; |
| } |
| |
| String eDef = null; |
| if (edgeDefinitionExpr != null) { |
| endPos = token; |
| eDef = extractFragment(beginPos.beginLine, beginPos.beginColumn + 1, endPos.endLine, endPos.endColumn + 1); |
| removeCurrentScope(); |
| } |
| |
| GraphConstructor.EdgeElement edgeElement = new GraphConstructor.EdgeElement(edgeLabel, destinationLabel, |
| sourceLabel, primaryKeyFields, primaryKeySourceIndicators, destinationKeyFields, destinationKeySourceIndicators, |
| sourceKeyFields, sourceKeySourceIndicators, edgeDefinitionExpr, eDef); |
| return addSourceLocation(edgeElement, startStmtToken); |
| } |
| } |
| |
| @new |
| Pair<Triple<String, String, String>, Boolean> GraphEdgeDefinitionPattern() throws ParseException: |
| { |
| String leftVertexName, edgeName, rightVertexName; |
| boolean isDirectedLeft; |
| } |
| { |
| leftVertexName = GraphVertexDefinitionPattern() |
| ( <MINUS> <LEFTBRACKET> <COLON> edgeName = Identifier() <RIGHTBRACKET> <MINUS> <GT> { isDirectedLeft = false; } |
| | <LT> <MINUS> <LEFTBRACKET> <COLON> edgeName = Identifier() <RIGHTBRACKET> <MINUS> { isDirectedLeft = true; } ) |
| rightVertexName = GraphVertexDefinitionPattern() |
| { |
| Triple<String, String, String> t = new Triple<String, String, String>(leftVertexName, edgeName, rightVertexName); |
| return new Pair<Triple<String, String, String>, Boolean>(t, isDirectedLeft); |
| } |
| } |
| |
| @new |
| <DEFAULT,IN_DBL_BRACE> |
| TOKEN [IGNORE_CASE]: |
| { |
| <DESTINATION: "destination"> |
| | <EDGE: "edge"> |
| | <GRAPH: "graph"> |
| | <SOURCE: "source"> |
| | <VERTEX: "vertex"> |
| } |
| |
| @new_at_the_end |
| <DEFAULT,IN_DBL_BRACE> |
| TOKEN : |
| { |
| <BAR: "|"> |
| } |