You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@asterixdb.apache.org by AsterixDB Code Review <do...@asterix-gerrit.ics.uci.edu> on 2022/04/27 01:46:08 UTC

Change in asterixdb-graph[master]: [NO-ISSUE][GRAPHIX] Refactoring AST body normalization.

From Glenn Galvizo <gg...@uci.edu>:

Glenn Galvizo has uploaded this change for review. ( https://asterix-gerrit.ics.uci.edu/c/asterixdb-graph/+/16204 )


Change subject: [NO-ISSUE][GRAPHIX] Refactoring AST body normalization.
......................................................................

[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
---
M asterix-graphix/src/main/java/org/apache/asterix/graphix/app/translator/GraphixQueryTranslator.java
M asterix-graphix/src/main/java/org/apache/asterix/graphix/function/GraphixFunctionIdentifiers.java
M asterix-graphix/src/main/java/org/apache/asterix/graphix/function/rewrite/EdgeIfFunctionRewrite.java
M asterix-graphix/src/main/java/org/apache/asterix/graphix/lang/expression/EdgePatternExpr.java
M asterix-graphix/src/main/java/org/apache/asterix/graphix/lang/expression/GraphConstructor.java
D asterix-graphix/src/main/java/org/apache/asterix/graphix/lang/expression/GraphElementBodyExpr.java
D asterix-graphix/src/main/java/org/apache/asterix/graphix/lang/expression/IGraphExpr.java
M asterix-graphix/src/main/java/org/apache/asterix/graphix/lang/expression/PathPatternExpr.java
M asterix-graphix/src/main/java/org/apache/asterix/graphix/lang/expression/VertexPatternExpr.java
M asterix-graphix/src/main/java/org/apache/asterix/graphix/lang/rewrites/GraphixQueryRewriter.java
M asterix-graphix/src/main/java/org/apache/asterix/graphix/lang/rewrites/expand/DirectedFixedPathExpansion.java
M asterix-graphix/src/main/java/org/apache/asterix/graphix/lang/rewrites/expand/DirectedVarPathExpansion.java
M asterix-graphix/src/main/java/org/apache/asterix/graphix/lang/rewrites/expand/UndirectedEdgeExpansion.java
M asterix-graphix/src/main/java/org/apache/asterix/graphix/lang/rewrites/expand/UndirectedFixedPathExpansion.java
M asterix-graphix/src/main/java/org/apache/asterix/graphix/lang/rewrites/expand/UndirectedVarPathExpansion.java
M asterix-graphix/src/main/java/org/apache/asterix/graphix/lang/rewrites/lower/assembly/ExpandEdgeLowerAssembly.java
M asterix-graphix/src/main/java/org/apache/asterix/graphix/lang/rewrites/lower/assembly/IsomorphismLowerAssembly.java
M asterix-graphix/src/main/java/org/apache/asterix/graphix/lang/rewrites/lower/assembly/NamedPathLowerAssembly.java
M asterix-graphix/src/main/java/org/apache/asterix/graphix/lang/rewrites/print/GraphixASTPrintVisitor.java
M asterix-graphix/src/main/java/org/apache/asterix/graphix/lang/rewrites/record/EdgeRecord.java
M asterix-graphix/src/main/java/org/apache/asterix/graphix/lang/rewrites/resolve/InferenceBasedResolver.java
M asterix-graphix/src/main/java/org/apache/asterix/graphix/lang/rewrites/visitor/PreRewriteCheckVisitor.java
M asterix-graphix/src/main/java/org/apache/asterix/graphix/lang/struct/EdgeDescriptor.java
M asterix-graphix/src/main/resources/lang-extension/lang.txt
24 files changed, 128 insertions(+), 304 deletions(-)



  git pull ssh://asterix-gerrit.ics.uci.edu:29418/asterixdb-graph refs/changes/04/16204/1

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.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.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 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 @@
         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 @@
         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 @@
  * 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 @@
         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<>()));
@@ -86,11 +86,6 @@
     }
 
     @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 @@
  * 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;
 
@@ -65,11 +65,6 @@
     }
 
     @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 @@
  * 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;
@@ -65,11 +65,6 @@
     }
 
     @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 @@
  * 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;
 
@@ -75,11 +75,6 @@
     }
 
     @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 @@
 
 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.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 @@
  * 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 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);
-        }
+        List<Expression> normalizedBodies = graphElementDecl.getNormalizedBodies();
+        if (normalizedBodies.size() != graphElementDecl.getBodies().size()) {
+            for (Expression body : graphElementDecl.getBodies()) {
+                Dataverse defaultDataverse = graphixRewritingContext.getMetadataProvider().getDefaultDataverse();
+                Dataverse targetDataverse;
 
-        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;
-            }
+                // 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;
 
-            // 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);
+                } 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 @@
                         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 @@
             }
         };
     }
-
-    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.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 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 @@
             }
 
             // 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.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 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 @@
         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 @@
 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 @@
 
         // 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.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 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 @@
 
                 // ...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 @@
 
                 // ...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.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 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 @@
         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 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 @@
     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 @@
                     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.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 @@
             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 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 @@
 
                 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 @@
                         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 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 @@
         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 @@
             // 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.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 @@
 
     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 @@
                 }
 
                 // 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 @@
             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.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 @@
             }
             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 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 @@
         return maximumHops;
     }
 
-    public IGraphExpr.GraphExprKind getEdgeClass() {
-        return edgeClass;
+    public PatternType getPatternType() {
+        return patternType;
     }
 
     public VariableExpr getVariableExpr() {
@@ -107,15 +97,20 @@
     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.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 @@
   VariableExpr edgeVariable = null;
 
   // We default to undirected edges.
-  EdgeDescriptor.EdgeType edgeType = EdgeDescriptor.EdgeType.UNDIRECTED;
+  EdgeDescriptor.EdgeDirection edgeDirection = EdgeDescriptor.EdgeDirection.UNDIRECTED;
 }
 {
   (
@@ -590,11 +589,11 @@
       ( <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 @@
     )?
   )
   {
-    // 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 @@
 
       // 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);
   }
 }
 

-- 
To view, visit https://asterix-gerrit.ics.uci.edu/c/asterixdb-graph/+/16204
To unsubscribe, or for help writing mail filters, visit https://asterix-gerrit.ics.uci.edu/settings

Gerrit-Project: asterixdb-graph
Gerrit-Branch: master
Gerrit-Change-Id: I852bef041abb876cc2414b0d2b75e40411c60330
Gerrit-Change-Number: 16204
Gerrit-PatchSet: 1
Gerrit-Owner: Glenn Galvizo <gg...@uci.edu>
Gerrit-MessageType: newchange

Change in asterixdb-graph[master]: [NO-ISSUE][GRAPHIX] Refactoring AST body normalization.

Posted by AsterixDB Code Review <do...@asterix-gerrit.ics.uci.edu>.
From Glenn Galvizo <gg...@uci.edu>:

Glenn Galvizo has uploaded this change for review. ( https://asterix-gerrit.ics.uci.edu/c/asterixdb-graph/+/16204 )


Change subject: [NO-ISSUE][GRAPHIX] Refactoring AST body normalization.
......................................................................

[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
---
M asterix-graphix/src/main/java/org/apache/asterix/graphix/app/translator/GraphixQueryTranslator.java
M asterix-graphix/src/main/java/org/apache/asterix/graphix/function/GraphixFunctionIdentifiers.java
M asterix-graphix/src/main/java/org/apache/asterix/graphix/function/rewrite/EdgeIfFunctionRewrite.java
M asterix-graphix/src/main/java/org/apache/asterix/graphix/lang/expression/EdgePatternExpr.java
M asterix-graphix/src/main/java/org/apache/asterix/graphix/lang/expression/GraphConstructor.java
D asterix-graphix/src/main/java/org/apache/asterix/graphix/lang/expression/GraphElementBodyExpr.java
D asterix-graphix/src/main/java/org/apache/asterix/graphix/lang/expression/IGraphExpr.java
M asterix-graphix/src/main/java/org/apache/asterix/graphix/lang/expression/PathPatternExpr.java
M asterix-graphix/src/main/java/org/apache/asterix/graphix/lang/expression/VertexPatternExpr.java
M asterix-graphix/src/main/java/org/apache/asterix/graphix/lang/rewrites/GraphixQueryRewriter.java
M asterix-graphix/src/main/java/org/apache/asterix/graphix/lang/rewrites/expand/DirectedFixedPathExpansion.java
M asterix-graphix/src/main/java/org/apache/asterix/graphix/lang/rewrites/expand/DirectedVarPathExpansion.java
M asterix-graphix/src/main/java/org/apache/asterix/graphix/lang/rewrites/expand/UndirectedEdgeExpansion.java
M asterix-graphix/src/main/java/org/apache/asterix/graphix/lang/rewrites/expand/UndirectedFixedPathExpansion.java
M asterix-graphix/src/main/java/org/apache/asterix/graphix/lang/rewrites/expand/UndirectedVarPathExpansion.java
M asterix-graphix/src/main/java/org/apache/asterix/graphix/lang/rewrites/lower/assembly/ExpandEdgeLowerAssembly.java
M asterix-graphix/src/main/java/org/apache/asterix/graphix/lang/rewrites/lower/assembly/IsomorphismLowerAssembly.java
M asterix-graphix/src/main/java/org/apache/asterix/graphix/lang/rewrites/lower/assembly/NamedPathLowerAssembly.java
M asterix-graphix/src/main/java/org/apache/asterix/graphix/lang/rewrites/print/GraphixASTPrintVisitor.java
M asterix-graphix/src/main/java/org/apache/asterix/graphix/lang/rewrites/record/EdgeRecord.java
M asterix-graphix/src/main/java/org/apache/asterix/graphix/lang/rewrites/resolve/InferenceBasedResolver.java
M asterix-graphix/src/main/java/org/apache/asterix/graphix/lang/rewrites/visitor/PreRewriteCheckVisitor.java
M asterix-graphix/src/main/java/org/apache/asterix/graphix/lang/struct/EdgeDescriptor.java
M asterix-graphix/src/main/resources/lang-extension/lang.txt
24 files changed, 128 insertions(+), 304 deletions(-)



  git pull ssh://asterix-gerrit.ics.uci.edu:29418/asterixdb-graph refs/changes/04/16204/1

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.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.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 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 @@
         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 @@
         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 @@
  * 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 @@
         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<>()));
@@ -86,11 +86,6 @@
     }
 
     @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 @@
  * 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;
 
@@ -65,11 +65,6 @@
     }
 
     @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 @@
  * 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;
@@ -65,11 +65,6 @@
     }
 
     @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 @@
  * 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;
 
@@ -75,11 +75,6 @@
     }
 
     @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 @@
 
 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.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 @@
  * 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 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);
-        }
+        List<Expression> normalizedBodies = graphElementDecl.getNormalizedBodies();
+        if (normalizedBodies.size() != graphElementDecl.getBodies().size()) {
+            for (Expression body : graphElementDecl.getBodies()) {
+                Dataverse defaultDataverse = graphixRewritingContext.getMetadataProvider().getDefaultDataverse();
+                Dataverse targetDataverse;
 
-        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;
-            }
+                // 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;
 
-            // 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);
+                } 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 @@
                         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 @@
             }
         };
     }
-
-    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.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 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 @@
             }
 
             // 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.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 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 @@
         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 @@
 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 @@
 
         // 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.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 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 @@
 
                 // ...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 @@
 
                 // ...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.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 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 @@
         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 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 @@
     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 @@
                     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.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 @@
             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 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 @@
 
                 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 @@
                         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 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 @@
         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 @@
             // 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.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 @@
 
     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 @@
                 }
 
                 // 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 @@
             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.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 @@
             }
             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 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 @@
         return maximumHops;
     }
 
-    public IGraphExpr.GraphExprKind getEdgeClass() {
-        return edgeClass;
+    public PatternType getPatternType() {
+        return patternType;
     }
 
     public VariableExpr getVariableExpr() {
@@ -107,15 +97,20 @@
     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.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 @@
   VariableExpr edgeVariable = null;
 
   // We default to undirected edges.
-  EdgeDescriptor.EdgeType edgeType = EdgeDescriptor.EdgeType.UNDIRECTED;
+  EdgeDescriptor.EdgeDirection edgeDirection = EdgeDescriptor.EdgeDirection.UNDIRECTED;
 }
 {
   (
@@ -590,11 +589,11 @@
       ( <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 @@
     )?
   )
   {
-    // 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 @@
 
       // 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);
   }
 }
 

-- 
To view, visit https://asterix-gerrit.ics.uci.edu/c/asterixdb-graph/+/16204
To unsubscribe, or for help writing mail filters, visit https://asterix-gerrit.ics.uci.edu/settings

Gerrit-Project: asterixdb-graph
Gerrit-Branch: master
Gerrit-Change-Id: I852bef041abb876cc2414b0d2b75e40411c60330
Gerrit-Change-Number: 16204
Gerrit-PatchSet: 1
Gerrit-Owner: Glenn Galvizo <gg...@uci.edu>
Gerrit-MessageType: newchange