This is an automated email from the ASF dual-hosted git repository. imaxon pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/asterixdb-graph.git
commit 01f41f47b7150b00790173455208bb626dd7364b Author: ggalvizo <[email protected]> AuthorDate: Tue Apr 26 18:42:38 2022 -0700 [NO-ISSUE][GRAPHIX] Refactoring AST body normalization. Details: - No longer going through hoops to normalize a graph element body (we no longer follow the SQL++ AST rewriter way of normalizing view bodies). - Removing the IGraphExpr interface, this was never used. Change-Id: I852bef041abb876cc2414b0d2b75e40411c60330 Reviewed-on: https://asterix-gerrit.ics.uci.edu/c/asterixdb-graph/+/16204 Tested-by: Jenkins <[email protected]> Reviewed-by: Glenn Galvizo <[email protected]> --- .../app/translator/GraphixQueryTranslator.java | 14 +-- .../function/GraphixFunctionIdentifiers.java | 4 - .../function/rewrite/EdgeIfFunctionRewrite.java | 4 +- .../graphix/lang/expression/EdgePatternExpr.java | 9 +- .../graphix/lang/expression/GraphConstructor.java | 7 +- .../lang/expression/GraphElementBodyExpr.java | 55 ---------- .../graphix/lang/expression/IGraphExpr.java | 34 ------ .../graphix/lang/expression/PathPatternExpr.java | 7 +- .../graphix/lang/expression/VertexPatternExpr.java | 7 +- .../lang/rewrites/GraphixQueryRewriter.java | 119 +++++++-------------- .../expand/DirectedFixedPathExpansion.java | 14 +-- .../rewrites/expand/DirectedVarPathExpansion.java | 7 +- .../rewrites/expand/UndirectedEdgeExpansion.java | 13 ++- .../expand/UndirectedFixedPathExpansion.java | 11 +- .../expand/UndirectedVarPathExpansion.java | 7 +- .../lower/assembly/ExpandEdgeLowerAssembly.java | 19 ++-- .../lower/assembly/IsomorphismLowerAssembly.java | 4 +- .../lower/assembly/NamedPathLowerAssembly.java | 5 +- .../rewrites/print/GraphixASTPrintVisitor.java | 4 +- .../graphix/lang/rewrites/record/EdgeRecord.java | 2 +- .../rewrites/resolve/InferenceBasedResolver.java | 23 ++-- .../rewrites/visitor/PreRewriteCheckVisitor.java | 3 +- .../graphix/lang/struct/EdgeDescriptor.java | 49 ++++----- .../src/main/resources/lang-extension/lang.txt | 15 ++- 24 files changed, 130 insertions(+), 306 deletions(-) diff --git a/asterix-graphix/src/main/java/org/apache/asterix/graphix/app/translator/GraphixQueryTranslator.java b/asterix-graphix/src/main/java/org/apache/asterix/graphix/app/translator/GraphixQueryTranslator.java index 101fc06..9644cef 100644 --- a/asterix-graphix/src/main/java/org/apache/asterix/graphix/app/translator/GraphixQueryTranslator.java +++ b/asterix-graphix/src/main/java/org/apache/asterix/graphix/app/translator/GraphixQueryTranslator.java @@ -33,7 +33,6 @@ import org.apache.asterix.common.functions.FunctionSignature; import org.apache.asterix.common.metadata.DataverseName; import org.apache.asterix.compiler.provider.ILangCompilationProvider; import org.apache.asterix.graphix.extension.GraphixMetadataExtension; -import org.apache.asterix.graphix.lang.expression.GraphElementBodyExpr; import org.apache.asterix.graphix.lang.rewrites.GraphixQueryRewriter; import org.apache.asterix.graphix.lang.rewrites.GraphixRewritingContext; import org.apache.asterix.graphix.lang.statement.GraphDropStatement; @@ -52,10 +51,8 @@ import org.apache.asterix.lang.common.statement.CreateViewStatement; import org.apache.asterix.lang.common.statement.DataverseDropStatement; import org.apache.asterix.lang.common.statement.DropDatasetStatement; import org.apache.asterix.lang.common.statement.FunctionDropStatement; -import org.apache.asterix.lang.common.statement.Query; import org.apache.asterix.lang.common.statement.SynonymDropStatement; import org.apache.asterix.lang.common.statement.ViewDropStatement; -import org.apache.asterix.lang.common.util.ExpressionUtils; import org.apache.asterix.metadata.MetadataManager; import org.apache.asterix.metadata.MetadataTransactionContext; import org.apache.asterix.metadata.declared.MetadataProvider; @@ -76,15 +73,10 @@ public class GraphixQueryTranslator extends QueryTranslator { public void setGraphElementNormalizedBody(MetadataProvider metadataProvider, GraphElementDecl graphElementDecl, GraphixQueryRewriter queryRewriter) throws CompilationException { - // Create a query AST for our rewriter to walk through. - GraphElementBodyExpr functionCall = new GraphElementBodyExpr(graphElementDecl.getIdentifier()); - Query query = ExpressionUtils.createWrappedQuery(functionCall, graphElementDecl.getSourceLocation()); - - // We call our rewriter to set the normalized bodies of GRAPH-ELEMENT-DECL. - LangRewritingContext langRewritingContext = new LangRewritingContext(metadataProvider, declaredFunctions, null, - warningCollector, query.getVarCounter()); + LangRewritingContext langRewritingContext = + new LangRewritingContext(metadataProvider, declaredFunctions, null, warningCollector, 0); GraphixRewritingContext graphixRewritingContext = new GraphixRewritingContext(langRewritingContext); - queryRewriter.loadNormalizedGraphElement(graphixRewritingContext, query, graphElementDecl); + queryRewriter.loadNormalizedGraphElement(graphixRewritingContext, graphElementDecl); } /** diff --git a/asterix-graphix/src/main/java/org/apache/asterix/graphix/function/GraphixFunctionIdentifiers.java b/asterix-graphix/src/main/java/org/apache/asterix/graphix/function/GraphixFunctionIdentifiers.java index 9d58d3f..eee4a1c 100644 --- a/asterix-graphix/src/main/java/org/apache/asterix/graphix/function/GraphixFunctionIdentifiers.java +++ b/asterix-graphix/src/main/java/org/apache/asterix/graphix/function/GraphixFunctionIdentifiers.java @@ -38,10 +38,6 @@ public class GraphixFunctionIdentifiers { return functionIdentifierMap.getOrDefault(functionName, null); } - // Function to be used when we normalize a graph-element body. - public static final FunctionIdentifier GRAPH_ELEMENT_BODY = - new FunctionIdentifier(GRAPHIX_DV.getCanonicalForm(), "graph-element-body", 5); - // Functions that can be called on vertices and edges. public static final FunctionIdentifier ELEMENT_LABEL = new FunctionIdentifier(GRAPHIX_DV.getCanonicalForm(), "element-label", 1); diff --git a/asterix-graphix/src/main/java/org/apache/asterix/graphix/function/rewrite/EdgeIfFunctionRewrite.java b/asterix-graphix/src/main/java/org/apache/asterix/graphix/function/rewrite/EdgeIfFunctionRewrite.java index 24b07ae..319ec1b 100644 --- a/asterix-graphix/src/main/java/org/apache/asterix/graphix/function/rewrite/EdgeIfFunctionRewrite.java +++ b/asterix-graphix/src/main/java/org/apache/asterix/graphix/function/rewrite/EdgeIfFunctionRewrite.java @@ -59,12 +59,12 @@ public class EdgeIfFunctionRewrite implements IFunctionRewrite { FieldAccessor edgeDirAccess = new FieldAccessor(edgeDetailAccess, directionSuffix); // Create a LEFT_TO_RIGHT condition. - LiteralExpr l2RLiteral = new LiteralExpr(new StringLiteral(EdgeDescriptor.EdgeType.LEFT_TO_RIGHT.name())); + LiteralExpr l2RLiteral = new LiteralExpr(new StringLiteral(EdgeDescriptor.EdgeDirection.LEFT_TO_RIGHT.name())); List<Expression> l2ROperands = List.of(edgeDirAccess, l2RLiteral); OperatorExpr l2RCondition = new OperatorExpr(l2ROperands, List.of(OperatorType.EQ), false); // Create a RIGHT_TO_LEFT condition. - LiteralExpr r2LLiteral = new LiteralExpr(new StringLiteral(EdgeDescriptor.EdgeType.RIGHT_TO_LEFT.name())); + LiteralExpr r2LLiteral = new LiteralExpr(new StringLiteral(EdgeDescriptor.EdgeDirection.RIGHT_TO_LEFT.name())); List<Expression> r2LOperands = List.of(edgeDirAccess, r2LLiteral); OperatorExpr r2LCondition = new OperatorExpr(r2LOperands, List.of(OperatorType.EQ), false); diff --git a/asterix-graphix/src/main/java/org/apache/asterix/graphix/lang/expression/EdgePatternExpr.java b/asterix-graphix/src/main/java/org/apache/asterix/graphix/lang/expression/EdgePatternExpr.java index d7d194f..718563a 100644 --- a/asterix-graphix/src/main/java/org/apache/asterix/graphix/lang/expression/EdgePatternExpr.java +++ b/asterix-graphix/src/main/java/org/apache/asterix/graphix/lang/expression/EdgePatternExpr.java @@ -34,7 +34,7 @@ import org.apache.asterix.lang.common.visitor.base.ILangVisitor; * edge labels, an optional edge variable, and the hop range), an list of optional internal {@link VertexPatternExpr} * instances, a left {@link VertexPatternExpr}, and a right {@link VertexPatternExpr}. */ -public class EdgePatternExpr extends AbstractExpression implements IGraphExpr { +public class EdgePatternExpr extends AbstractExpression { private final List<VertexPatternExpr> internalVertices; private final VertexPatternExpr leftVertex; private final VertexPatternExpr rightVertex; @@ -46,7 +46,7 @@ public class EdgePatternExpr extends AbstractExpression implements IGraphExpr { this.edgeDescriptor = Objects.requireNonNull(edgeDescriptor); this.internalVertices = new ArrayList<>(); - if (edgeDescriptor.getEdgeClass() == GraphExprKind.PATH_PATTERN) { + if (edgeDescriptor.getPatternType() == EdgeDescriptor.PatternType.PATH) { // If we have a sub-path, we have an internal vertex that we need to manage. for (int i = 0; i < edgeDescriptor.getMaximumHops() - 1; i++) { this.internalVertices.add(new VertexPatternExpr(null, new HashSet<>())); @@ -85,11 +85,6 @@ public class EdgePatternExpr extends AbstractExpression implements IGraphExpr { return null; } - @Override - public GraphExprKind getGraphExprKind() { - return edgeDescriptor.getEdgeClass(); - } - @Override public <R, T> R accept(ILangVisitor<R, T> visitor, T arg) throws CompilationException { return ((IGraphixLangVisitor<R, T>) visitor).visit(this, arg); diff --git a/asterix-graphix/src/main/java/org/apache/asterix/graphix/lang/expression/GraphConstructor.java b/asterix-graphix/src/main/java/org/apache/asterix/graphix/lang/expression/GraphConstructor.java index e06893a..c0e7c36 100644 --- a/asterix-graphix/src/main/java/org/apache/asterix/graphix/lang/expression/GraphConstructor.java +++ b/asterix-graphix/src/main/java/org/apache/asterix/graphix/lang/expression/GraphConstructor.java @@ -34,7 +34,7 @@ import org.apache.asterix.lang.common.visitor.base.ILangVisitor; * An expression which describes the schema of a graph, containing a list of vertices ({@link VertexConstructor}) and * a list of edges ({@link EdgeConstructor}) that connect the aforementioned vertices. */ -public class GraphConstructor extends AbstractExpression implements IGraphExpr { +public class GraphConstructor extends AbstractExpression { private final List<VertexConstructor> vertexConstructors; private final List<EdgeConstructor> edgeConstructors; @@ -64,11 +64,6 @@ public class GraphConstructor extends AbstractExpression implements IGraphExpr { return null; } - @Override - public GraphExprKind getGraphExprKind() { - return GraphExprKind.GRAPH_CONSTRUCTOR; - } - @Override public <R, T> R accept(ILangVisitor<R, T> visitor, T arg) throws CompilationException { return ((IGraphixLangVisitor<R, T>) visitor).visit(this, arg); diff --git a/asterix-graphix/src/main/java/org/apache/asterix/graphix/lang/expression/GraphElementBodyExpr.java b/asterix-graphix/src/main/java/org/apache/asterix/graphix/lang/expression/GraphElementBodyExpr.java deleted file mode 100644 index bb711f9..0000000 --- a/asterix-graphix/src/main/java/org/apache/asterix/graphix/lang/expression/GraphElementBodyExpr.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * 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. - */ -package org.apache.asterix.graphix.lang.expression; - -import java.util.Collections; - -import org.apache.asterix.common.functions.FunctionSignature; -import org.apache.asterix.graphix.common.metadata.GraphElementIdentifier; -import org.apache.asterix.graphix.common.metadata.GraphIdentifier; -import org.apache.asterix.graphix.function.GraphixFunctionIdentifiers; -import org.apache.asterix.lang.common.expression.CallExpr; - -public class GraphElementBodyExpr extends CallExpr implements IGraphExpr { - // A graph element is uniquely identified by its identifier. - private final GraphElementIdentifier identifier; - - public GraphElementBodyExpr(GraphElementIdentifier identifier) { - super(new FunctionSignature(GraphixFunctionIdentifiers.GRAPH_ELEMENT_BODY), Collections.emptyList(), null); - this.identifier = identifier; - } - - public GraphElementIdentifier getIdentifier() { - return identifier; - } - - public GraphIdentifier getGraphIdentifier() { - return identifier.getGraphIdentifier(); - } - - @Override - public Kind getKind() { - return null; - } - - @Override - public GraphExprKind getGraphExprKind() { - return GraphExprKind.GRAPH_ELEMENT_BODY; - } -} diff --git a/asterix-graphix/src/main/java/org/apache/asterix/graphix/lang/expression/IGraphExpr.java b/asterix-graphix/src/main/java/org/apache/asterix/graphix/lang/expression/IGraphExpr.java deleted file mode 100644 index 18440d7..0000000 --- a/asterix-graphix/src/main/java/org/apache/asterix/graphix/lang/expression/IGraphExpr.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * 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. - */ -package org.apache.asterix.graphix.lang.expression; - -import org.apache.asterix.lang.common.base.ILangExpression; - -public interface IGraphExpr extends ILangExpression { - GraphExprKind getGraphExprKind(); - - enum GraphExprKind { - GRAPH_CONSTRUCTOR, - GRAPH_ELEMENT_BODY, - - EDGE_PATTERN, - VERTEX_PATTERN, - PATH_PATTERN - } -} diff --git a/asterix-graphix/src/main/java/org/apache/asterix/graphix/lang/expression/PathPatternExpr.java b/asterix-graphix/src/main/java/org/apache/asterix/graphix/lang/expression/PathPatternExpr.java index 0091ec7..04efc0d 100644 --- a/asterix-graphix/src/main/java/org/apache/asterix/graphix/lang/expression/PathPatternExpr.java +++ b/asterix-graphix/src/main/java/org/apache/asterix/graphix/lang/expression/PathPatternExpr.java @@ -31,7 +31,7 @@ import org.apache.asterix.lang.common.visitor.base.ILangVisitor; * A path is composed of a list of {@link VertexPatternExpr} instances and a list of {@link EdgePatternExpr} that * utilize the aforementioned vertices. Users can also optionally specify a variable. */ -public class PathPatternExpr extends AbstractExpression implements IGraphExpr { +public class PathPatternExpr extends AbstractExpression { private final List<VertexPatternExpr> vertexExpressions; private final List<EdgePatternExpr> edgeExpressions; private VariableExpr variableExpr; @@ -64,11 +64,6 @@ public class PathPatternExpr extends AbstractExpression implements IGraphExpr { return null; } - @Override - public GraphExprKind getGraphExprKind() { - return GraphExprKind.PATH_PATTERN; - } - @Override public <R, T> R accept(ILangVisitor<R, T> visitor, T arg) throws CompilationException { return ((IGraphixLangVisitor<R, T>) visitor).visit(this, arg); diff --git a/asterix-graphix/src/main/java/org/apache/asterix/graphix/lang/expression/VertexPatternExpr.java b/asterix-graphix/src/main/java/org/apache/asterix/graphix/lang/expression/VertexPatternExpr.java index a9b4ca6..39a4da6 100644 --- a/asterix-graphix/src/main/java/org/apache/asterix/graphix/lang/expression/VertexPatternExpr.java +++ b/asterix-graphix/src/main/java/org/apache/asterix/graphix/lang/expression/VertexPatternExpr.java @@ -35,7 +35,7 @@ import org.apache.asterix.lang.common.visitor.base.ILangVisitor; * A query vertex (not to be confused with a vertex constructor) is composed of a set of labels (which may be empty) * and a variable (which may initially be null). */ -public class VertexPatternExpr extends AbstractExpression implements IGraphExpr { +public class VertexPatternExpr extends AbstractExpression { private final Set<ElementLabel> labels; private VariableExpr variableExpr; @@ -74,11 +74,6 @@ public class VertexPatternExpr extends AbstractExpression implements IGraphExpr return null; } - @Override - public GraphExprKind getGraphExprKind() { - return GraphExprKind.VERTEX_PATTERN; - } - @Override public <R, T> R accept(ILangVisitor<R, T> visitor, T arg) throws CompilationException { return ((IGraphixLangVisitor<R, T>) visitor).visit(this, arg); diff --git a/asterix-graphix/src/main/java/org/apache/asterix/graphix/lang/rewrites/GraphixQueryRewriter.java b/asterix-graphix/src/main/java/org/apache/asterix/graphix/lang/rewrites/GraphixQueryRewriter.java index 0348eb8..1311244 100644 --- a/asterix-graphix/src/main/java/org/apache/asterix/graphix/lang/rewrites/GraphixQueryRewriter.java +++ b/asterix-graphix/src/main/java/org/apache/asterix/graphix/lang/rewrites/GraphixQueryRewriter.java @@ -20,24 +20,16 @@ package org.apache.asterix.graphix.lang.rewrites; import java.io.PrintWriter; import java.io.StringWriter; -import java.util.ArrayDeque; import java.util.Collection; -import java.util.Collections; -import java.util.Deque; import java.util.List; import java.util.Map; -import java.util.Objects; import org.apache.asterix.common.exceptions.CompilationException; import org.apache.asterix.common.exceptions.ErrorCode; -import org.apache.asterix.common.functions.FunctionSignature; import org.apache.asterix.common.metadata.DataverseName; import org.apache.asterix.graphix.algebra.compiler.provider.GraphixCompilationProvider; import org.apache.asterix.graphix.common.metadata.GraphElementIdentifier; -import org.apache.asterix.graphix.common.metadata.GraphIdentifier; -import org.apache.asterix.graphix.function.GraphixFunctionIdentifiers; import org.apache.asterix.graphix.lang.clause.FromGraphClause; -import org.apache.asterix.graphix.lang.expression.GraphElementBodyExpr; import org.apache.asterix.graphix.lang.parser.GraphixParserFactory; import org.apache.asterix.graphix.lang.rewrites.common.ElementLookupTable; import org.apache.asterix.graphix.lang.rewrites.print.SqlppASTPrintQueryVisitor; @@ -54,18 +46,15 @@ import org.apache.asterix.graphix.lang.statement.GraphElementDecl; import org.apache.asterix.lang.common.base.Expression; import org.apache.asterix.lang.common.base.IParserFactory; import org.apache.asterix.lang.common.base.IReturningStatement; -import org.apache.asterix.lang.common.expression.AbstractCallExpression; import org.apache.asterix.lang.common.rewrites.LangRewritingContext; import org.apache.asterix.lang.common.statement.Query; import org.apache.asterix.lang.common.struct.VarIdentifier; import org.apache.asterix.lang.common.util.ExpressionUtils; import org.apache.asterix.lang.sqlpp.rewrites.SqlppFunctionBodyRewriter; import org.apache.asterix.lang.sqlpp.rewrites.SqlppQueryRewriter; -import org.apache.asterix.lang.sqlpp.rewrites.visitor.SqlppGatherFunctionCallsVisitor; import org.apache.asterix.metadata.declared.MetadataProvider; import org.apache.asterix.metadata.entities.Dataverse; import org.apache.hyracks.algebricks.common.exceptions.AlgebricksException; -import org.apache.hyracks.api.exceptions.SourceLocation; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -74,6 +63,7 @@ import org.apache.logging.log4j.Logger; * 1. Perform an error-checking on the fresh AST (immediately after parsing). * 2. Populate the unknowns in our AST (e.g. vertex / edge variables, projections, GROUP-BY keys). * 3. Perform a variable-scoping pass to identify illegal variables (either duplicate or out-of-scope). + * 4. Resolve our Graphix function calls * 4. For the remainder of our Graphix function calls, rewrite each call into a subtree w/o Graphix functions. * 5. Perform resolution of unlabeled vertices / edges, as well as edge directions. * 6. Using the labels of the vertices / edges in our AST, fetch the relevant graph elements from our metadata. @@ -130,38 +120,46 @@ public class GraphixQueryRewriter extends SqlppQueryRewriter { } } - public void loadNormalizedGraphElement(GraphixRewritingContext graphixRewritingContext, IReturningStatement topExpr, + public void loadNormalizedGraphElement(GraphixRewritingContext graphixRewritingContext, GraphElementDecl graphElementDecl) throws CompilationException { - // Gather all function calls. - Deque<AbstractCallExpression> workQueue = new ArrayDeque<>(); - SqlppGatherFunctionCallsVisitor callVisitor = new SqlppGatherFunctionCallsVisitor(workQueue); - for (Expression expr : topExpr.getDirectlyEnclosedExpressions()) { - expr.accept(callVisitor, null); - } - - AbstractCallExpression fnCall; - while ((fnCall = workQueue.poll()) != null) { - // We only care about graph element declarations. - FunctionSignature functionSignature = fnCall.getFunctionSignature(); - if (!functionSignature.getName().equals(GraphixFunctionIdentifiers.GRAPH_ELEMENT_BODY.getName()) - || !Objects.equals(functionSignature.getDataverseName(), GraphixFunctionIdentifiers.GRAPHIX_DV)) { - continue; - } - - // Get our normalized element bodies, by calling our rewriter. - List<Expression> normalizedBodies = graphElementDecl.getNormalizedBodies(); - if (normalizedBodies.size() != graphElementDecl.getBodies().size()) { - GraphIdentifier graphIdentifier = graphElementDecl.getGraphIdentifier(); - for (Expression body : graphElementDecl.getBodies()) { - Expression normalizedBody = - rewriteGraphElementBody(graphixRewritingContext, graphIdentifier.getDataverseName(), body, - Collections.emptyList(), graphElementDecl.getSourceLocation()); - normalizedBodies.add(normalizedBody); + List<Expression> normalizedBodies = graphElementDecl.getNormalizedBodies(); + if (normalizedBodies.size() != graphElementDecl.getBodies().size()) { + for (Expression body : graphElementDecl.getBodies()) { + Dataverse defaultDataverse = graphixRewritingContext.getMetadataProvider().getDefaultDataverse(); + Dataverse targetDataverse; + + // We might need to change our dataverse, if the element definition requires a different one. + DataverseName elementName = graphElementDecl.getIdentifier().getGraphIdentifier().getDataverseName(); + if (elementName.equals(defaultDataverse.getDataverseName())) { + targetDataverse = defaultDataverse; + + } else { + try { + targetDataverse = graphixRewritingContext.getMetadataProvider().findDataverse(elementName); + + } catch (AlgebricksException e) { + throw new CompilationException(ErrorCode.UNKNOWN_DATAVERSE, e, + graphElementDecl.getSourceLocation(), elementName); + } + } + graphixRewritingContext.getMetadataProvider().setDefaultDataverse(targetDataverse); + + // Get the body of the rewritten query. + try { + Query wrappedQuery = ExpressionUtils.createWrappedQuery(body, graphElementDecl.getSourceLocation()); + LangRewritingContext langRewritingContext = graphixRewritingContext.getLangRewritingContext(); + bodyRewriter.rewrite(langRewritingContext, wrappedQuery, false, false, List.of()); + normalizedBodies.add(wrappedQuery.getBody()); + + } catch (CompilationException e) { + throw new CompilationException(ErrorCode.COMPILATION_ERROR, body.getSourceLocation(), + "Bad definition for a graph element: " + e.getMessage()); + + } finally { + // Switch back to the working dataverse. + graphixRewritingContext.getMetadataProvider().setDefaultDataverse(defaultDataverse); } } - - // We should only have one element. We can safely break here. - break; } } @@ -197,9 +195,7 @@ public class GraphixQueryRewriter extends SqlppQueryRewriter { parserFactory, graphixRewritingContext.getWarningCollector()); topStatement.getBody().accept(elementLookupTableVisitor, null); for (GraphElementDecl graphElementDecl : elementLookupTable) { - Query wrappedQuery = ExpressionUtils.createWrappedQuery( - new GraphElementBodyExpr(graphElementDecl.getIdentifier()), graphElementDecl.getSourceLocation()); - loadNormalizedGraphElement(graphixRewritingContext, wrappedQuery, graphElementDecl); + loadNormalizedGraphElement(graphixRewritingContext, graphElementDecl); } // Perform an analysis pass to get our edge dependencies, dangling vertices, and FROM-GRAPH-CLAUSE variables. @@ -244,41 +240,4 @@ public class GraphixQueryRewriter extends SqlppQueryRewriter { } }; } - - private Expression rewriteGraphElementBody(GraphixRewritingContext graphixRewritingContext, - DataverseName elementDataverse, Expression bodyExpr, List<VarIdentifier> externalVars, - SourceLocation sourceLoc) throws CompilationException { - Dataverse defaultDataverse = graphixRewritingContext.getMetadataProvider().getDefaultDataverse(); - Dataverse targetDataverse; - - // We might need to change our dataverse, if the element definition requires a different one. - if (elementDataverse.equals(defaultDataverse.getDataverseName())) { - targetDataverse = defaultDataverse; - - } else { - try { - targetDataverse = graphixRewritingContext.getMetadataProvider().findDataverse(elementDataverse); - - } catch (AlgebricksException e) { - throw new CompilationException(ErrorCode.UNKNOWN_DATAVERSE, e, sourceLoc, elementDataverse); - } - } - graphixRewritingContext.getMetadataProvider().setDefaultDataverse(targetDataverse); - - // Get the body of the rewritten query. - try { - Query wrappedQuery = ExpressionUtils.createWrappedQuery(bodyExpr, sourceLoc); - LangRewritingContext langRewritingContext = graphixRewritingContext.getLangRewritingContext(); - bodyRewriter.rewrite(langRewritingContext, wrappedQuery, false, false, externalVars); - return wrappedQuery.getBody(); - - } catch (CompilationException e) { - throw new CompilationException(ErrorCode.COMPILATION_ERROR, bodyExpr.getSourceLocation(), - "Bad definition for a graph element: " + e.getMessage()); - - } finally { - // Switch back to the working dataverse. - graphixRewritingContext.getMetadataProvider().setDefaultDataverse(defaultDataverse); - } - } } diff --git a/asterix-graphix/src/main/java/org/apache/asterix/graphix/lang/rewrites/expand/DirectedFixedPathExpansion.java b/asterix-graphix/src/main/java/org/apache/asterix/graphix/lang/rewrites/expand/DirectedFixedPathExpansion.java index 214e0a1..744f3b5 100644 --- a/asterix-graphix/src/main/java/org/apache/asterix/graphix/lang/rewrites/expand/DirectedFixedPathExpansion.java +++ b/asterix-graphix/src/main/java/org/apache/asterix/graphix/lang/rewrites/expand/DirectedFixedPathExpansion.java @@ -23,12 +23,11 @@ import java.util.List; import java.util.Objects; import org.apache.asterix.graphix.lang.expression.EdgePatternExpr; -import org.apache.asterix.graphix.lang.expression.IGraphExpr; import org.apache.asterix.graphix.lang.expression.VertexPatternExpr; import org.apache.asterix.graphix.lang.struct.EdgeDescriptor; /** - * Given a sub-path that is **not** {@link EdgeDescriptor.EdgeType#UNDIRECTED} but is fixed in the number of hops + * Given a sub-path that is **not** {@link EdgeDescriptor.EdgeDirection#UNDIRECTED} but is fixed in the number of hops * (denoted N), we build a single set of N directed simple edges. */ public class DirectedFixedPathExpansion implements IEdgePatternExpansion { @@ -42,8 +41,8 @@ public class DirectedFixedPathExpansion implements IEdgePatternExpansion { public Iterable<Iterable<EdgePatternExpr>> expand(EdgePatternExpr edgePatternExpr) { // Ensure we have been given the correct type of sub-path. EdgeDescriptor edgeDescriptor = edgePatternExpr.getEdgeDescriptor(); - if (edgeDescriptor.getEdgeClass() != IGraphExpr.GraphExprKind.PATH_PATTERN - || edgeDescriptor.getEdgeType() == EdgeDescriptor.EdgeType.UNDIRECTED + if (edgeDescriptor.getPatternType() != EdgeDescriptor.PatternType.PATH + || edgeDescriptor.getEdgeDirection() == EdgeDescriptor.EdgeDirection.UNDIRECTED || !Objects.equals(edgeDescriptor.getMinimumHops(), edgeDescriptor.getMaximumHops())) { throw new IllegalArgumentException("Expected a directed fixed sub-path, but given a " + edgeDescriptor); } @@ -64,9 +63,10 @@ public class DirectedFixedPathExpansion implements IEdgePatternExpansion { } // Build our EDGE-PATTERN-EXPR. - EdgeDescriptor newEdgeDescriptor = new EdgeDescriptor(edgePatternExpr.getEdgeDescriptor().getEdgeType(), - IGraphExpr.GraphExprKind.EDGE_PATTERN, edgePatternExpr.getEdgeDescriptor().getEdgeLabels(), - pathEnumerationEnvironment.getNewEdgeVar(), null, null); + EdgeDescriptor newEdgeDescriptor = + new EdgeDescriptor(edgePatternExpr.getEdgeDescriptor().getEdgeDirection(), + EdgeDescriptor.PatternType.EDGE, edgePatternExpr.getEdgeDescriptor().getEdgeLabels(), + pathEnumerationEnvironment.getNewEdgeVar(), null, null); EdgePatternExpr newEdgePattern = new EdgePatternExpr(workingLeftVertex, rightVertex, newEdgeDescriptor); decomposedEdgeList.add(newEdgePattern); diff --git a/asterix-graphix/src/main/java/org/apache/asterix/graphix/lang/rewrites/expand/DirectedVarPathExpansion.java b/asterix-graphix/src/main/java/org/apache/asterix/graphix/lang/rewrites/expand/DirectedVarPathExpansion.java index 91d58d0..0ac81f7 100644 --- a/asterix-graphix/src/main/java/org/apache/asterix/graphix/lang/rewrites/expand/DirectedVarPathExpansion.java +++ b/asterix-graphix/src/main/java/org/apache/asterix/graphix/lang/rewrites/expand/DirectedVarPathExpansion.java @@ -23,7 +23,6 @@ import java.util.List; import java.util.Objects; import org.apache.asterix.graphix.lang.expression.EdgePatternExpr; -import org.apache.asterix.graphix.lang.expression.IGraphExpr; import org.apache.asterix.graphix.lang.struct.EdgeDescriptor; /** @@ -44,8 +43,8 @@ public class DirectedVarPathExpansion implements IEdgePatternExpansion { public Iterable<Iterable<EdgePatternExpr>> expand(EdgePatternExpr edgePatternExpr) { // Ensure we have been given the correct type of sub-path. EdgeDescriptor edgeDescriptor = edgePatternExpr.getEdgeDescriptor(); - if (edgeDescriptor.getEdgeClass() != IGraphExpr.GraphExprKind.PATH_PATTERN - || edgeDescriptor.getEdgeType() == EdgeDescriptor.EdgeType.UNDIRECTED + if (edgeDescriptor.getPatternType() != EdgeDescriptor.PatternType.PATH + || edgeDescriptor.getEdgeDirection() == EdgeDescriptor.EdgeDirection.UNDIRECTED || Objects.equals(edgeDescriptor.getMinimumHops(), edgeDescriptor.getMaximumHops())) { throw new IllegalArgumentException("Expected a directed var sub-path, but given a " + edgeDescriptor); } @@ -53,7 +52,7 @@ public class DirectedVarPathExpansion implements IEdgePatternExpansion { List<List<EdgePatternExpr>> decomposedEdgeList = new ArrayList<>(); for (int i = edgeDescriptor.getMinimumHops(); i <= edgeDescriptor.getMaximumHops(); i++) { EdgeDescriptor fixedEdgeDescriptor = - new EdgeDescriptor(edgeDescriptor.getEdgeType(), IGraphExpr.GraphExprKind.PATH_PATTERN, + new EdgeDescriptor(edgeDescriptor.getEdgeDirection(), EdgeDescriptor.PatternType.PATH, edgeDescriptor.getEdgeLabels(), edgeDescriptor.getVariableExpr(), i, i); EdgePatternExpr fixedEdgePattern = new EdgePatternExpr(edgePatternExpr.getLeftVertex(), edgePatternExpr.getRightVertex(), fixedEdgeDescriptor); diff --git a/asterix-graphix/src/main/java/org/apache/asterix/graphix/lang/rewrites/expand/UndirectedEdgeExpansion.java b/asterix-graphix/src/main/java/org/apache/asterix/graphix/lang/rewrites/expand/UndirectedEdgeExpansion.java index f01ba0d..fa03a40 100644 --- a/asterix-graphix/src/main/java/org/apache/asterix/graphix/lang/rewrites/expand/UndirectedEdgeExpansion.java +++ b/asterix-graphix/src/main/java/org/apache/asterix/graphix/lang/rewrites/expand/UndirectedEdgeExpansion.java @@ -21,22 +21,21 @@ package org.apache.asterix.graphix.lang.rewrites.expand; import java.util.List; import org.apache.asterix.graphix.lang.expression.EdgePatternExpr; -import org.apache.asterix.graphix.lang.expression.IGraphExpr; import org.apache.asterix.graphix.lang.expression.VertexPatternExpr; import org.apache.asterix.graphix.lang.struct.EdgeDescriptor; /** * Given an undirected edge, generate two edges (to feed to the caller's UNION): one edge directed from - * {@link EdgeDescriptor.EdgeType#LEFT_TO_RIGHT},and another edge directed from - * {@link EdgeDescriptor.EdgeType#RIGHT_TO_LEFT}. + * {@link EdgeDescriptor.EdgeDirection#LEFT_TO_RIGHT},and another edge directed from + * {@link EdgeDescriptor.EdgeDirection#RIGHT_TO_LEFT}. */ public class UndirectedEdgeExpansion implements IEdgePatternExpansion { @Override public Iterable<Iterable<EdgePatternExpr>> expand(EdgePatternExpr edgePatternExpr) { // Ensure we have been given the correct type of edge. EdgeDescriptor edgeDescriptor = edgePatternExpr.getEdgeDescriptor(); - if (edgeDescriptor.getEdgeClass() != IGraphExpr.GraphExprKind.EDGE_PATTERN - || edgeDescriptor.getEdgeType() != EdgeDescriptor.EdgeType.UNDIRECTED) { + if (edgeDescriptor.getPatternType() != EdgeDescriptor.PatternType.EDGE + || edgeDescriptor.getEdgeDirection() != EdgeDescriptor.EdgeDirection.UNDIRECTED) { throw new IllegalArgumentException("Expected an undirected edge, but given a " + edgeDescriptor); } VertexPatternExpr leftVertex = edgePatternExpr.getLeftVertex(); @@ -44,13 +43,13 @@ public class UndirectedEdgeExpansion implements IEdgePatternExpansion { // Build our LEFT_TO_RIGHT edge... EdgeDescriptor leftToRightEdgeDescriptor = - new EdgeDescriptor(EdgeDescriptor.EdgeType.LEFT_TO_RIGHT, IGraphExpr.GraphExprKind.EDGE_PATTERN, + new EdgeDescriptor(EdgeDescriptor.EdgeDirection.LEFT_TO_RIGHT, EdgeDescriptor.PatternType.EDGE, edgeDescriptor.getEdgeLabels(), edgeDescriptor.getVariableExpr(), null, null); EdgePatternExpr leftToRightEdge = new EdgePatternExpr(leftVertex, rightVertex, leftToRightEdgeDescriptor); // ...and our RIGHT_TO_LEFT edge... EdgeDescriptor rightToLeftEdgeDescriptor = - new EdgeDescriptor(EdgeDescriptor.EdgeType.RIGHT_TO_LEFT, IGraphExpr.GraphExprKind.EDGE_PATTERN, + new EdgeDescriptor(EdgeDescriptor.EdgeDirection.RIGHT_TO_LEFT, EdgeDescriptor.PatternType.EDGE, edgeDescriptor.getEdgeLabels(), edgeDescriptor.getVariableExpr(), null, null); EdgePatternExpr rightToLeftEdge = new EdgePatternExpr(leftVertex, rightVertex, rightToLeftEdgeDescriptor); diff --git a/asterix-graphix/src/main/java/org/apache/asterix/graphix/lang/rewrites/expand/UndirectedFixedPathExpansion.java b/asterix-graphix/src/main/java/org/apache/asterix/graphix/lang/rewrites/expand/UndirectedFixedPathExpansion.java index 044a58b..0b0fdeb 100644 --- a/asterix-graphix/src/main/java/org/apache/asterix/graphix/lang/rewrites/expand/UndirectedFixedPathExpansion.java +++ b/asterix-graphix/src/main/java/org/apache/asterix/graphix/lang/rewrites/expand/UndirectedFixedPathExpansion.java @@ -25,13 +25,12 @@ import java.util.List; import java.util.Objects; import org.apache.asterix.graphix.lang.expression.EdgePatternExpr; -import org.apache.asterix.graphix.lang.expression.IGraphExpr; import org.apache.asterix.graphix.lang.expression.VertexPatternExpr; import org.apache.asterix.graphix.lang.struct.EdgeDescriptor; import org.apache.asterix.lang.common.expression.VariableExpr; /** - * Given a sub-path that is {@link EdgeDescriptor.EdgeType#UNDIRECTED} but is fixed in the number of hops (denoted N), + * Given a sub-path that is {@link EdgeDescriptor.EdgeDirection#UNDIRECTED} but is fixed in the number of hops (denoted N), * we generate N sets of directed simple edges (the total of which is equal to 2^N). */ public class UndirectedFixedPathExpansion implements IEdgePatternExpansion { @@ -45,8 +44,8 @@ public class UndirectedFixedPathExpansion implements IEdgePatternExpansion { public Iterable<Iterable<EdgePatternExpr>> expand(EdgePatternExpr edgePatternExpr) { // Ensure we have been given the correct type of sub-path. EdgeDescriptor edgeDescriptor = edgePatternExpr.getEdgeDescriptor(); - if (edgeDescriptor.getEdgeClass() != IGraphExpr.GraphExprKind.PATH_PATTERN - || edgeDescriptor.getEdgeType() != EdgeDescriptor.EdgeType.UNDIRECTED + if (edgeDescriptor.getPatternType() != EdgeDescriptor.PatternType.PATH + || edgeDescriptor.getEdgeDirection() != EdgeDescriptor.EdgeDirection.UNDIRECTED || !Objects.equals(edgeDescriptor.getMinimumHops(), edgeDescriptor.getMaximumHops())) { throw new IllegalArgumentException("Expected an undirected fixed sub-path, but given a " + edgeDescriptor); } @@ -76,7 +75,7 @@ public class UndirectedFixedPathExpansion implements IEdgePatternExpansion { // ...and generate two new variants that have an additional LEFT_TO_RIGHT edge... EdgeDescriptor leftToRightEdgeDescriptor = - new EdgeDescriptor(EdgeDescriptor.EdgeType.LEFT_TO_RIGHT, IGraphExpr.GraphExprKind.EDGE_PATTERN, + new EdgeDescriptor(EdgeDescriptor.EdgeDirection.LEFT_TO_RIGHT, EdgeDescriptor.PatternType.EDGE, edgePatternExpr.getEdgeDescriptor().getEdgeLabels(), graphEdgeVar, null, null); List<EdgePatternExpr> leftToRightList = new ArrayList<>(workingEdgePatternList); leftToRightList.add(new EdgePatternExpr(workingLeftVertex, rightVertex, leftToRightEdgeDescriptor)); @@ -84,7 +83,7 @@ public class UndirectedFixedPathExpansion implements IEdgePatternExpansion { // ...and a RIGHT_TO_LEFT edge. EdgeDescriptor rightToLeftEdgeDescriptor = - new EdgeDescriptor(EdgeDescriptor.EdgeType.RIGHT_TO_LEFT, IGraphExpr.GraphExprKind.EDGE_PATTERN, + new EdgeDescriptor(EdgeDescriptor.EdgeDirection.RIGHT_TO_LEFT, EdgeDescriptor.PatternType.EDGE, edgePatternExpr.getEdgeDescriptor().getEdgeLabels(), graphEdgeVar, null, null); List<EdgePatternExpr> rightToLeftList = new ArrayList<>(workingEdgePatternList); rightToLeftList.add(new EdgePatternExpr(workingLeftVertex, rightVertex, rightToLeftEdgeDescriptor)); diff --git a/asterix-graphix/src/main/java/org/apache/asterix/graphix/lang/rewrites/expand/UndirectedVarPathExpansion.java b/asterix-graphix/src/main/java/org/apache/asterix/graphix/lang/rewrites/expand/UndirectedVarPathExpansion.java index 9c85b77..73a9954 100644 --- a/asterix-graphix/src/main/java/org/apache/asterix/graphix/lang/rewrites/expand/UndirectedVarPathExpansion.java +++ b/asterix-graphix/src/main/java/org/apache/asterix/graphix/lang/rewrites/expand/UndirectedVarPathExpansion.java @@ -23,7 +23,6 @@ import java.util.List; import java.util.Objects; import org.apache.asterix.graphix.lang.expression.EdgePatternExpr; -import org.apache.asterix.graphix.lang.expression.IGraphExpr; import org.apache.asterix.graphix.lang.struct.EdgeDescriptor; /** @@ -44,8 +43,8 @@ public class UndirectedVarPathExpansion implements IEdgePatternExpansion { public Iterable<Iterable<EdgePatternExpr>> expand(EdgePatternExpr edgePatternExpr) { // Ensure we have been given the correct type of sub-path. EdgeDescriptor edgeDescriptor = edgePatternExpr.getEdgeDescriptor(); - if (edgeDescriptor.getEdgeClass() != IGraphExpr.GraphExprKind.PATH_PATTERN - || edgeDescriptor.getEdgeType() != EdgeDescriptor.EdgeType.UNDIRECTED + if (edgeDescriptor.getPatternType() != EdgeDescriptor.PatternType.PATH + || edgeDescriptor.getEdgeDirection() != EdgeDescriptor.EdgeDirection.UNDIRECTED || Objects.equals(edgeDescriptor.getMinimumHops(), edgeDescriptor.getMaximumHops())) { throw new IllegalArgumentException("Expected an undirected var sub-path, but given a " + edgeDescriptor); } @@ -53,7 +52,7 @@ public class UndirectedVarPathExpansion implements IEdgePatternExpansion { List<List<EdgePatternExpr>> decomposedEdgeList = new ArrayList<>(); for (int i = edgeDescriptor.getMinimumHops(); i <= edgeDescriptor.getMaximumHops(); i++) { EdgeDescriptor fixedEdgeDescriptor = - new EdgeDescriptor(EdgeDescriptor.EdgeType.UNDIRECTED, IGraphExpr.GraphExprKind.PATH_PATTERN, + new EdgeDescriptor(EdgeDescriptor.EdgeDirection.UNDIRECTED, EdgeDescriptor.PatternType.PATH, edgeDescriptor.getEdgeLabels(), edgeDescriptor.getVariableExpr(), i, i); EdgePatternExpr fixedEdgePattern = new EdgePatternExpr(edgePatternExpr.getLeftVertex(), edgePatternExpr.getRightVertex(), fixedEdgeDescriptor); diff --git a/asterix-graphix/src/main/java/org/apache/asterix/graphix/lang/rewrites/lower/assembly/ExpandEdgeLowerAssembly.java b/asterix-graphix/src/main/java/org/apache/asterix/graphix/lang/rewrites/lower/assembly/ExpandEdgeLowerAssembly.java index 88575ec..cce1229 100644 --- a/asterix-graphix/src/main/java/org/apache/asterix/graphix/lang/rewrites/lower/assembly/ExpandEdgeLowerAssembly.java +++ b/asterix-graphix/src/main/java/org/apache/asterix/graphix/lang/rewrites/lower/assembly/ExpandEdgeLowerAssembly.java @@ -38,7 +38,6 @@ import java.util.stream.Collectors; import org.apache.asterix.common.exceptions.CompilationException; import org.apache.asterix.graphix.common.metadata.GraphElementIdentifier; import org.apache.asterix.graphix.lang.expression.EdgePatternExpr; -import org.apache.asterix.graphix.lang.expression.IGraphExpr; import org.apache.asterix.graphix.lang.expression.VertexPatternExpr; import org.apache.asterix.graphix.lang.rewrites.assembly.ExprAssembler; import org.apache.asterix.graphix.lang.rewrites.expand.DirectedFixedPathExpansion; @@ -106,30 +105,30 @@ public class ExpandEdgeLowerAssembly extends AbstractLowerAssembly { private Iterable<Iterable<EdgePatternExpr>> expandEdgePatternExpr(EdgePatternExpr edgePatternExpr) { EdgeDescriptor edgeDescriptor = edgePatternExpr.getEdgeDescriptor(); - if (edgeDescriptor.getEdgeType() != EdgeDescriptor.EdgeType.UNDIRECTED - && edgeDescriptor.getEdgeClass() == IGraphExpr.GraphExprKind.EDGE_PATTERN) { + if (edgeDescriptor.getEdgeDirection() != EdgeDescriptor.EdgeDirection.UNDIRECTED + && edgeDescriptor.getPatternType() == EdgeDescriptor.PatternType.EDGE) { // We have a single directed edge. We do not need to break this up. return List.of(List.of(edgePatternExpr)); - } else if (edgeDescriptor.getEdgeType() == EdgeDescriptor.EdgeType.UNDIRECTED - && edgeDescriptor.getEdgeClass() == IGraphExpr.GraphExprKind.EDGE_PATTERN) { + } else if (edgeDescriptor.getEdgeDirection() == EdgeDescriptor.EdgeDirection.UNDIRECTED + && edgeDescriptor.getPatternType() == EdgeDescriptor.PatternType.EDGE) { return new UndirectedEdgeExpansion().expand(edgePatternExpr); - } else { // edgeDescriptor.getEdgeClass() == IGraphExpr.GraphExprKind.PATH_PATTERN + } else { // edgeDescriptor.getEdgeClass() == EdgeDescriptor.PatternType.PATH PathEnumerationEnvironment decompositionEnvironment = new PathEnumerationEnvironment(edgePatternExpr, lowerSupplierContext, generatedVertexConjuncts::addLast, generatedEdgeConjuncts::addLast, generatedReboundExpressions::addLast); IEdgePatternExpansion edgePatternDecomposition; - if (edgeDescriptor.getEdgeType() != EdgeDescriptor.EdgeType.UNDIRECTED + if (edgeDescriptor.getEdgeDirection() != EdgeDescriptor.EdgeDirection.UNDIRECTED && Objects.equals(edgeDescriptor.getMinimumHops(), edgeDescriptor.getMaximumHops())) { edgePatternDecomposition = new DirectedFixedPathExpansion(decompositionEnvironment); - } else if (edgeDescriptor.getEdgeType() == EdgeDescriptor.EdgeType.UNDIRECTED + } else if (edgeDescriptor.getEdgeDirection() == EdgeDescriptor.EdgeDirection.UNDIRECTED && Objects.equals(edgeDescriptor.getMinimumHops(), edgeDescriptor.getMaximumHops())) { edgePatternDecomposition = new UndirectedFixedPathExpansion(decompositionEnvironment); - } else if (edgeDescriptor.getEdgeType() != EdgeDescriptor.EdgeType.UNDIRECTED + } else if (edgeDescriptor.getEdgeDirection() != EdgeDescriptor.EdgeDirection.UNDIRECTED && !Objects.equals(edgeDescriptor.getMinimumHops(), edgeDescriptor.getMaximumHops())) { edgePatternDecomposition = new DirectedVarPathExpansion(decompositionEnvironment); @@ -202,7 +201,7 @@ public class ExpandEdgeLowerAssembly extends AbstractLowerAssembly { Function<GraphElementIdentifier, ElementLabel> rightEdgeLabelAccess; Function<GraphElementIdentifier, List<List<String>>> leftEdgeKeyAccess; Function<GraphElementIdentifier, List<List<String>>> rightEdgeKeyAccess; - if (edgeDescriptor.getEdgeType() == EdgeDescriptor.EdgeType.LEFT_TO_RIGHT) { + if (edgeDescriptor.getEdgeDirection() == EdgeDescriptor.EdgeDirection.LEFT_TO_RIGHT) { leftEdgeKeyAccess = elementLookupTable::getEdgeSourceKeys; rightEdgeKeyAccess = elementLookupTable::getEdgeDestKeys; leftEdgeLabelAccess = elementLookupTable::getEdgeSourceLabel; diff --git a/asterix-graphix/src/main/java/org/apache/asterix/graphix/lang/rewrites/lower/assembly/IsomorphismLowerAssembly.java b/asterix-graphix/src/main/java/org/apache/asterix/graphix/lang/rewrites/lower/assembly/IsomorphismLowerAssembly.java index bba86fd..b8e7242 100644 --- a/asterix-graphix/src/main/java/org/apache/asterix/graphix/lang/rewrites/lower/assembly/IsomorphismLowerAssembly.java +++ b/asterix-graphix/src/main/java/org/apache/asterix/graphix/lang/rewrites/lower/assembly/IsomorphismLowerAssembly.java @@ -33,12 +33,12 @@ import org.apache.asterix.common.exceptions.ErrorCode; import org.apache.asterix.common.functions.FunctionSignature; import org.apache.asterix.graphix.algebra.compiler.provider.GraphixCompilationProvider; import org.apache.asterix.graphix.lang.clause.MatchClause; -import org.apache.asterix.graphix.lang.expression.IGraphExpr; import org.apache.asterix.graphix.lang.expression.VertexPatternExpr; import org.apache.asterix.graphix.lang.rewrites.assembly.IExprAssembly; import org.apache.asterix.graphix.lang.rewrites.common.EdgeDependencyGraph; import org.apache.asterix.graphix.lang.rewrites.lower.LowerSupplierNode; import org.apache.asterix.graphix.lang.rewrites.visitor.ElementResolutionVisitor; +import org.apache.asterix.graphix.lang.struct.EdgeDescriptor; import org.apache.asterix.graphix.lang.struct.ElementLabel; import org.apache.asterix.lang.common.base.Expression; import org.apache.asterix.lang.common.clause.WhereClause; @@ -200,7 +200,7 @@ public class IsomorphismLowerAssembly implements IExprAssembly<LowerSupplierNode qualifiedExprMap.put(rightVertexVar, qualifiedProjectionMap.get(rightVarName)); // If we have an edge (and not a sub-path), create a conjunct for this. - if (e.getEdgeDescriptor().getEdgeClass() == IGraphExpr.GraphExprKind.EDGE_PATTERN) { + if (e.getEdgeDescriptor().getPatternType() == EdgeDescriptor.PatternType.EDGE) { VariableExpr edgeVar = e.getEdgeDescriptor().getVariableExpr(); populateVariableMap(e.getEdgeDescriptor().getEdgeLabels(), edgeVar, edgeVariableMap); String edgeVarName = SqlppVariableUtil.toUserDefinedName(edgeVar.getVar().getValue()); diff --git a/asterix-graphix/src/main/java/org/apache/asterix/graphix/lang/rewrites/lower/assembly/NamedPathLowerAssembly.java b/asterix-graphix/src/main/java/org/apache/asterix/graphix/lang/rewrites/lower/assembly/NamedPathLowerAssembly.java index 54b00e9..671a941 100644 --- a/asterix-graphix/src/main/java/org/apache/asterix/graphix/lang/rewrites/lower/assembly/NamedPathLowerAssembly.java +++ b/asterix-graphix/src/main/java/org/apache/asterix/graphix/lang/rewrites/lower/assembly/NamedPathLowerAssembly.java @@ -28,7 +28,6 @@ import java.util.stream.Collectors; import org.apache.asterix.common.exceptions.CompilationException; import org.apache.asterix.common.functions.FunctionSignature; import org.apache.asterix.graphix.lang.expression.EdgePatternExpr; -import org.apache.asterix.graphix.lang.expression.IGraphExpr; import org.apache.asterix.graphix.lang.expression.PathPatternExpr; import org.apache.asterix.graphix.lang.rewrites.assembly.IExprAssembly; import org.apache.asterix.graphix.lang.rewrites.lower.LowerSupplierNode; @@ -68,7 +67,7 @@ public class NamedPathLowerAssembly implements IExprAssembly<LowerSupplierNode> for (EdgePatternExpr edgePatternExpr : pathPatternExpr.getEdgeExpressions()) { EdgeDescriptor edgeDescriptor = edgePatternExpr.getEdgeDescriptor(); - if (edgeDescriptor.getEdgeClass() == IGraphExpr.GraphExprKind.EDGE_PATTERN) { + if (edgeDescriptor.getPatternType() == EdgeDescriptor.PatternType.EDGE) { // "Raw" edges are first put into a list of path records. VariableExpr leftVertexVar = edgePatternExpr.getLeftVertex().getVariableExpr(); VariableExpr rightVertexVar = edgePatternExpr.getRightVertex().getVariableExpr(); @@ -85,7 +84,7 @@ public class NamedPathLowerAssembly implements IExprAssembly<LowerSupplierNode> Expression edgeExpr = qualifiedProjectionMap.get(edgeVarName); workingSimplePath.add(new PathRecord(leftExpr, edgeExpr, rightExpr).getExpression()); - } else { // edgeDescriptor.getEdgeClass() == IGraphExpr.GraphExprKind.PATH_PATTERN + } else { // edgeDescriptor.getEdgeClass() == EdgeDescriptor.PatternType.PATH // If we encounter a sub-path, ARRAY_CONCAT our existing path and sub-path. pathExpressionParts.add(new ListConstructor(ORDERED_LIST_CONSTRUCTOR, workingSimplePath)); VariableExpr subPathVar = edgeDescriptor.getVariableExpr(); diff --git a/asterix-graphix/src/main/java/org/apache/asterix/graphix/lang/rewrites/print/GraphixASTPrintVisitor.java b/asterix-graphix/src/main/java/org/apache/asterix/graphix/lang/rewrites/print/GraphixASTPrintVisitor.java index 6c6482e..867ba00 100644 --- a/asterix-graphix/src/main/java/org/apache/asterix/graphix/lang/rewrites/print/GraphixASTPrintVisitor.java +++ b/asterix-graphix/src/main/java/org/apache/asterix/graphix/lang/rewrites/print/GraphixASTPrintVisitor.java @@ -193,7 +193,7 @@ public class GraphixASTPrintVisitor extends SqlppAstPrintVisitor implements IGra public Void visit(EdgePatternExpr edgePatternExpr, Integer step) throws CompilationException { out.print(skip(step)); edgePatternExpr.getLeftVertex().accept(this, 0); - switch (edgePatternExpr.getEdgeDescriptor().getEdgeType()) { + switch (edgePatternExpr.getEdgeDescriptor().getEdgeDirection()) { case LEFT_TO_RIGHT: case UNDIRECTED: out.print("-["); @@ -219,7 +219,7 @@ public class GraphixASTPrintVisitor extends SqlppAstPrintVisitor implements IGra out.print(","); out.print(edgePatternExpr.getEdgeDescriptor().getMaximumHops().toString()); out.print("}"); - switch (edgePatternExpr.getEdgeDescriptor().getEdgeType()) { + switch (edgePatternExpr.getEdgeDescriptor().getEdgeDirection()) { case LEFT_TO_RIGHT: out.print("]->"); break; diff --git a/asterix-graphix/src/main/java/org/apache/asterix/graphix/lang/rewrites/record/EdgeRecord.java b/asterix-graphix/src/main/java/org/apache/asterix/graphix/lang/rewrites/record/EdgeRecord.java index 81893e1..66d9e76 100644 --- a/asterix-graphix/src/main/java/org/apache/asterix/graphix/lang/rewrites/record/EdgeRecord.java +++ b/asterix-graphix/src/main/java/org/apache/asterix/graphix/lang/rewrites/record/EdgeRecord.java @@ -94,7 +94,7 @@ public class EdgeRecord implements IElementRecord { // Build the direction binding for the edge detail projection. List<FieldBinding> edgeDetailBindings = new ArrayList<>(); LiteralExpr directionFieldValue = - new LiteralExpr(new StringLiteral(edgeDescriptor.getEdgeType().toString().toUpperCase())); + new LiteralExpr(new StringLiteral(edgeDescriptor.getEdgeDirection().toString().toUpperCase())); LiteralExpr directionFieldName = new LiteralExpr(new StringLiteral(DIRECTION_FIELD_NAME)); edgeDetailBindings.add(new FieldBinding(directionFieldName, directionFieldValue)); diff --git a/asterix-graphix/src/main/java/org/apache/asterix/graphix/lang/rewrites/resolve/InferenceBasedResolver.java b/asterix-graphix/src/main/java/org/apache/asterix/graphix/lang/rewrites/resolve/InferenceBasedResolver.java index 9b513cb..c2035cb 100644 --- a/asterix-graphix/src/main/java/org/apache/asterix/graphix/lang/rewrites/resolve/InferenceBasedResolver.java +++ b/asterix-graphix/src/main/java/org/apache/asterix/graphix/lang/rewrites/resolve/InferenceBasedResolver.java @@ -25,7 +25,6 @@ import org.apache.asterix.common.exceptions.CompilationException; import org.apache.asterix.graphix.lang.clause.FromGraphClause; import org.apache.asterix.graphix.lang.clause.MatchClause; import org.apache.asterix.graphix.lang.expression.EdgePatternExpr; -import org.apache.asterix.graphix.lang.expression.IGraphExpr; import org.apache.asterix.graphix.lang.expression.PathPatternExpr; import org.apache.asterix.graphix.lang.expression.VertexPatternExpr; import org.apache.asterix.graphix.lang.rewrites.visitor.LabelConsistencyVisitor; @@ -69,7 +68,7 @@ public class InferenceBasedResolver implements IGraphElementResolver { private boolean resolveEdge(EdgePatternExpr edgePatternExpr) { EdgeDescriptor edgeDescriptor = edgePatternExpr.getEdgeDescriptor(); - if (edgeDescriptor.getEdgeClass() == IGraphExpr.GraphExprKind.PATH_PATTERN) { + if (edgeDescriptor.getPatternType() == EdgeDescriptor.PatternType.PATH) { VertexPatternExpr workingLeftVertex = edgePatternExpr.getLeftVertex(); // We have a sub-path. Recurse with the edges of this sub-path. @@ -86,8 +85,8 @@ public class InferenceBasedResolver implements IGraphElementResolver { } // Build our EDGE-PATTERN-EXPR and recurse. - EdgeDescriptor newDescriptor = new EdgeDescriptor(edgeDescriptor.getEdgeType(), - IGraphExpr.GraphExprKind.EDGE_PATTERN, edgeDescriptor.getEdgeLabels(), null, null, null); + EdgeDescriptor newDescriptor = new EdgeDescriptor(edgeDescriptor.getEdgeDirection(), + EdgeDescriptor.PatternType.EDGE, edgeDescriptor.getEdgeLabels(), null, null, null); intermediateResult &= resolveEdge(new EdgePatternExpr(workingLeftVertex, rightVertex, newDescriptor)); // Update the labels of our edge and our internal vertex. @@ -104,35 +103,35 @@ public class InferenceBasedResolver implements IGraphElementResolver { return intermediateResult; } - if (edgeDescriptor.getEdgeType() == EdgeDescriptor.EdgeType.UNDIRECTED) { + if (edgeDescriptor.getEdgeDirection() == EdgeDescriptor.EdgeDirection.UNDIRECTED) { // We have an undirected edge. Recurse with a LEFT_TO_RIGHT edge... - edgeDescriptor.setEdgeType(EdgeDescriptor.EdgeType.LEFT_TO_RIGHT); + edgeDescriptor.setEdgeDirection(EdgeDescriptor.EdgeDirection.LEFT_TO_RIGHT); boolean isLeftToRightModified = !resolveEdge(edgePatternExpr); // ...and a RIGHT_TO_LEFT edge. - edgeDescriptor.setEdgeType(EdgeDescriptor.EdgeType.RIGHT_TO_LEFT); + edgeDescriptor.setEdgeDirection(EdgeDescriptor.EdgeDirection.RIGHT_TO_LEFT); boolean isRightToLeftModified = !resolveEdge(edgePatternExpr); // Determine the direction of our edge, if possible. if (isLeftToRightModified && !isRightToLeftModified) { - edgeDescriptor.setEdgeType(EdgeDescriptor.EdgeType.LEFT_TO_RIGHT); + edgeDescriptor.setEdgeDirection(EdgeDescriptor.EdgeDirection.LEFT_TO_RIGHT); } else if (!isLeftToRightModified && isRightToLeftModified) { - edgeDescriptor.setEdgeType(EdgeDescriptor.EdgeType.RIGHT_TO_LEFT); + edgeDescriptor.setEdgeDirection(EdgeDescriptor.EdgeDirection.RIGHT_TO_LEFT); } else { - edgeDescriptor.setEdgeType(EdgeDescriptor.EdgeType.UNDIRECTED); + edgeDescriptor.setEdgeDirection(EdgeDescriptor.EdgeDirection.UNDIRECTED); } return !(isLeftToRightModified || isRightToLeftModified); } // We have a _directed_ *edge*. Determine our source and destination vertex. VertexPatternExpr sourceVertexPattern, destinationVertexPattern; - if (edgeDescriptor.getEdgeType() == EdgeDescriptor.EdgeType.LEFT_TO_RIGHT) { + if (edgeDescriptor.getEdgeDirection() == EdgeDescriptor.EdgeDirection.LEFT_TO_RIGHT) { sourceVertexPattern = edgePatternExpr.getLeftVertex(); destinationVertexPattern = edgePatternExpr.getRightVertex(); - } else { // edgeDescriptor.getEdgeType() == EdgeDescriptor.EdgeType.RIGHT_TO_LEFT + } else { // edgeDescriptor.getEdgeDirection() == EdgeDescriptor.EdgeDirection.RIGHT_TO_LEFT sourceVertexPattern = edgePatternExpr.getRightVertex(); destinationVertexPattern = edgePatternExpr.getLeftVertex(); } diff --git a/asterix-graphix/src/main/java/org/apache/asterix/graphix/lang/rewrites/visitor/PreRewriteCheckVisitor.java b/asterix-graphix/src/main/java/org/apache/asterix/graphix/lang/rewrites/visitor/PreRewriteCheckVisitor.java index 0033fee..f2e2605 100644 --- a/asterix-graphix/src/main/java/org/apache/asterix/graphix/lang/rewrites/visitor/PreRewriteCheckVisitor.java +++ b/asterix-graphix/src/main/java/org/apache/asterix/graphix/lang/rewrites/visitor/PreRewriteCheckVisitor.java @@ -32,7 +32,6 @@ import org.apache.asterix.graphix.lang.clause.FromGraphClause; import org.apache.asterix.graphix.lang.clause.MatchClause; import org.apache.asterix.graphix.lang.expression.EdgePatternExpr; import org.apache.asterix.graphix.lang.expression.GraphConstructor; -import org.apache.asterix.graphix.lang.expression.IGraphExpr; import org.apache.asterix.graphix.lang.expression.VertexPatternExpr; import org.apache.asterix.graphix.lang.struct.EdgeDescriptor; import org.apache.asterix.graphix.lang.struct.ElementLabel; @@ -221,7 +220,7 @@ public class PreRewriteCheckVisitor extends AbstractGraphixQueryVisitor { } environmentMap.get(arg).edgeVariables.add(edgeIdentifier); } - if (edgeDescriptor.getEdgeClass() == IGraphExpr.GraphExprKind.PATH_PATTERN) { + if (edgeDescriptor.getPatternType() == EdgeDescriptor.PatternType.PATH) { Integer minimumHops = edgeDescriptor.getMinimumHops(); Integer maximumHops = edgeDescriptor.getMaximumHops(); if (maximumHops == 0 || (minimumHops != null && minimumHops == 0)) { diff --git a/asterix-graphix/src/main/java/org/apache/asterix/graphix/lang/struct/EdgeDescriptor.java b/asterix-graphix/src/main/java/org/apache/asterix/graphix/lang/struct/EdgeDescriptor.java index 2fbf258..c21e30c 100644 --- a/asterix-graphix/src/main/java/org/apache/asterix/graphix/lang/struct/EdgeDescriptor.java +++ b/asterix-graphix/src/main/java/org/apache/asterix/graphix/lang/struct/EdgeDescriptor.java @@ -24,53 +24,43 @@ import java.util.stream.Collectors; import org.apache.asterix.graphix.common.metadata.GraphElementIdentifier; import org.apache.asterix.graphix.common.metadata.GraphIdentifier; -import org.apache.asterix.graphix.lang.expression.IGraphExpr; import org.apache.asterix.lang.common.expression.VariableExpr; /** * Descriptor for a query edge instance. A query edge has the following: * 1. A set of edge labels. * 2. A variable associated with the query edge. - * 3. An edge class. An edge can either be a pure edge, or a sub-path. + * 3. A pattern type. An edge pattern can either be a pure edge, or a sub-path. * 4. A minimum number of hops (allowed to be NULL, indicating a minimum of 1 hop). * 5. A maximum number of hops (not allowed to be NULL). - * 6. An edge type, which denotes the direction (left to right, right to left, or undirected). + * 6. An edge direction (left to right, right to left, or undirected). */ public class EdgeDescriptor { - private final IGraphExpr.GraphExprKind edgeClass; private final Set<ElementLabel> edgeLabels; private final Integer minimumHops; private final Integer maximumHops; + private final PatternType patternType; // We must be able to assign variables to our edges, as well as change the direction of UNDIRECTED edges. private VariableExpr variableExpr; - private EdgeType edgeType; + private EdgeDirection edgeDirection; - public EdgeDescriptor(EdgeType edgeType, IGraphExpr.GraphExprKind edgeClass, Set<ElementLabel> edgeLabels, + public EdgeDescriptor(EdgeDirection edgeDirection, PatternType patternType, Set<ElementLabel> edgeLabels, VariableExpr variableExpr, Integer minimumHops, Integer maximumHops) { - this.edgeType = edgeType; + this.edgeDirection = edgeDirection; this.edgeLabels = edgeLabels; this.minimumHops = minimumHops; this.maximumHops = maximumHops; - this.edgeClass = edgeClass; + this.patternType = patternType; this.variableExpr = variableExpr; - - // We enforce that an edge can take two forms: as a sub-path, and as a pure "edge". - switch (edgeClass) { - case GRAPH_CONSTRUCTOR: - case GRAPH_ELEMENT_BODY: - case VERTEX_PATTERN: - throw new IllegalArgumentException( - "Illegal class of edge specified! An edge can only be a PATH or an EDGE."); - } } - public EdgeType getEdgeType() { - return edgeType; + public EdgeDirection getEdgeDirection() { + return edgeDirection; } - public void setEdgeType(EdgeType edgeType) { - this.edgeType = edgeType; + public void setEdgeDirection(EdgeDirection edgeDirection) { + this.edgeDirection = edgeDirection; } public Set<ElementLabel> getEdgeLabels() { @@ -85,8 +75,8 @@ public class EdgeDescriptor { return maximumHops; } - public IGraphExpr.GraphExprKind getEdgeClass() { - return edgeClass; + public PatternType getPatternType() { + return patternType; } public VariableExpr getVariableExpr() { @@ -107,15 +97,20 @@ public class EdgeDescriptor { public String toString() { String labelsString = edgeLabels.stream().map(ElementLabel::toString).collect(Collectors.joining("|")); String variableString = (variableExpr != null) ? variableExpr.getVar().toString() : ""; - String subPathString = (edgeClass != IGraphExpr.GraphExprKind.PATH_PATTERN) ? "" + String subPathString = (patternType != PatternType.PATH) ? "" : "{" + ((minimumHops == null) ? "" : minimumHops) + "," + maximumHops + "}"; - return String.format("%s-[%s:(%s)%s]-%s", (edgeType == EdgeType.LEFT_TO_RIGHT) ? "" : "<", variableString, - labelsString, subPathString, (edgeType == EdgeType.RIGHT_TO_LEFT) ? "" : ">"); + return String.format("%s-[%s:(%s)%s]-%s", (edgeDirection == EdgeDirection.LEFT_TO_RIGHT) ? "" : "<", + variableString, labelsString, subPathString, (edgeDirection == EdgeDirection.RIGHT_TO_LEFT) ? "" : ">"); } - public enum EdgeType { + public enum EdgeDirection { LEFT_TO_RIGHT, RIGHT_TO_LEFT, UNDIRECTED } + + public enum PatternType { + PATH, + EDGE + } } diff --git a/asterix-graphix/src/main/resources/lang-extension/lang.txt b/asterix-graphix/src/main/resources/lang-extension/lang.txt index 12643bf..a1d12e6 100644 --- a/asterix-graphix/src/main/resources/lang-extension/lang.txt +++ b/asterix-graphix/src/main/resources/lang-extension/lang.txt @@ -26,7 +26,6 @@ import org.apache.asterix.graphix.lang.clause.GraphSelectBlock; import org.apache.asterix.graphix.lang.clause.MatchClause; import org.apache.asterix.graphix.lang.expression.EdgePatternExpr; import org.apache.asterix.graphix.lang.expression.GraphConstructor; -import org.apache.asterix.graphix.lang.expression.IGraphExpr; import org.apache.asterix.graphix.lang.expression.PathPatternExpr; import org.apache.asterix.graphix.lang.expression.VertexPatternExpr; import org.apache.asterix.graphix.lang.optype.MatchType; @@ -577,7 +576,7 @@ EdgeDescriptor EdgeDescriptor() throws ParseException: VariableExpr edgeVariable = null; // We default to undirected edges. - EdgeDescriptor.EdgeType edgeType = EdgeDescriptor.EdgeType.UNDIRECTED; + EdgeDescriptor.EdgeDirection edgeDirection = EdgeDescriptor.EdgeDirection.UNDIRECTED; } { ( @@ -590,11 +589,11 @@ EdgeDescriptor EdgeDescriptor() throws ParseException: ( <COLON> edgeDetail = EdgeDetail() )? <RIGHTBRACKET> <MINUS> )? - ( <GT> { edgeType = EdgeDescriptor.EdgeType.LEFT_TO_RIGHT; } )? + ( <GT> { edgeDirection = EdgeDescriptor.EdgeDirection.LEFT_TO_RIGHT; } )? | <LT> { startToken = token; - edgeType = EdgeDescriptor.EdgeType.RIGHT_TO_LEFT; + edgeDirection = EdgeDescriptor.EdgeDirection.RIGHT_TO_LEFT; } <MINUS> ( @@ -607,8 +606,8 @@ EdgeDescriptor EdgeDescriptor() throws ParseException: )? ) { - // Edges (by default) are of class EDGE_PATTERN and are not sub-paths. - IGraphExpr.GraphExprKind edgeClass = IGraphExpr.GraphExprKind.EDGE_PATTERN; + // Edges (by default) are of pattern type EDGE and are not sub-paths. + EdgeDescriptor.PatternType patternType = EdgeDescriptor.PatternType.EDGE; Integer hopCountMin = 1; Integer hopCountMax = 1; @@ -618,13 +617,13 @@ EdgeDescriptor EdgeDescriptor() throws ParseException: // We have explicitly specified "{" and "}". Use sub-path semantics. if (edgeDetail.second != null) { - edgeClass = IGraphExpr.GraphExprKind.PATH_PATTERN; + patternType = EdgeDescriptor.PatternType.PATH; hopCountMin = edgeDetail.second.first; hopCountMax = edgeDetail.second.second; } } - return new EdgeDescriptor(edgeType, edgeClass, labels, edgeVariable, hopCountMin, hopCountMax); + return new EdgeDescriptor(edgeDirection, patternType, labels, edgeVariable, hopCountMin, hopCountMax); } }
