in asterix-graphix/src/main/java/org/apache/asterix/graphix/lang/rewrite/canonical/CanonicalElementExpansionConsumer.java [230:303]
public void accept(AbstractExpression canonicalExpr, PathPatternExpr pathPatternExpr)
throws CompilationException {
EdgePatternExpr ambiguousEdgePattern = (EdgePatternExpr) ambiguousElement;
VertexPatternExpr ambiguousLeftVertex = ambiguousEdgePattern.getLeftVertex();
VertexPatternExpr ambiguousRightVertex = ambiguousEdgePattern.getRightVertex();
EdgeDescriptor ambiguousEdgeDescriptor = ambiguousEdgePattern.getEdgeDescriptor();
VariableExpr edgeVariable = ambiguousEdgeDescriptor.getVariableExpr();
PathPatternExpr canonicalPathPatternExpr = (PathPatternExpr) canonicalExpr;
List<EdgePatternExpr> canonicalEdges = canonicalPathPatternExpr.getEdgeExpressions();
VertexPatternExpr canonicalLeftVertex = canonicalEdges.get(0).getLeftVertex();
VertexPatternExpr canonicalRightVertex = canonicalEdges.get(canonicalEdges.size() - 1).getRightVertex();
// Iterate through our edge list.
List<EdgePatternExpr> edgeExpressions = pathPatternExpr.getEdgeExpressions();
ListIterator<EdgePatternExpr> edgeIterator = edgeExpressions.listIterator();
while (edgeIterator.hasNext()) {
EdgePatternExpr workingEdge = edgeIterator.next();
if (workingEdge.equals(ambiguousEdgePattern)) {
edgeIterator.remove();
// We need to generate new variables for each edge in our new path.
List<EdgePatternExpr> canonicalEdgeListCopy = new ArrayList<>();
for (EdgePatternExpr canonicalEdge : canonicalEdges) {
EdgePatternExpr canonicalEdgeCopy = deepCopyVisitor.visit(canonicalEdge, null);
EdgeDescriptor canonicalEdgeCopyDescriptor = canonicalEdgeCopy.getEdgeDescriptor();
VariableExpr edgeVariableCopy = graphixRewritingContext.getGraphixVariableCopy(edgeVariable);
canonicalEdgeCopyDescriptor.setVariableExpr(edgeVariableCopy);
canonicalEdgeListCopy.add(canonicalEdgeCopy);
edgeIterator.add(canonicalEdgeCopy);
}
// Determine our new vertex list (we want to keep the order of our current vertex list).
List<VertexPatternExpr> canonicalVertexListCopy = new ArrayList<>();
ListIterator<VertexPatternExpr> pathPatternVertexIterator =
pathPatternExpr.getVertexExpressions().listIterator();
while (pathPatternVertexIterator.hasNext()) {
VertexPatternExpr currentPathPatternVertex = pathPatternVertexIterator.next();
VariableExpr currentVariable = currentPathPatternVertex.getVariableExpr();
VariableExpr ambiguousLeftVar = ambiguousLeftVertex.getVariableExpr();
VariableExpr ambiguousRightVar = ambiguousRightVertex.getVariableExpr();
if (currentVariable.equals(ambiguousLeftVar)) {
// Add canonical path vertices.
List<VertexPatternExpr> canonicalVertices = canonicalPathPatternExpr.getVertexExpressions();
for (VertexPatternExpr vertexExpr : canonicalVertices) {
canonicalVertexListCopy.add(deepCopyVisitor.visit(vertexExpr, null));
VariableExpr vertexVar = vertexExpr.getVariableExpr();
if (!vertexVar.equals(ambiguousLeftVar) && !vertexVar.equals(ambiguousRightVar)) {
pathPatternVertexIterator.add(vertexExpr);
}
}
}
}
// Build a new path record.
RecordConstructor pathRecord = new RecordConstructor();
pathRecord.setSourceLocation(workingEdge.getSourceLocation());
buildPathRecord(canonicalVertexListCopy, canonicalEdgeListCopy, pathRecord);
LetClause pathBinding = new LetClause(deepCopyVisitor.visit(edgeVariable, null), pathRecord);
pathPatternExpr.getReboundSubPathList().add(pathBinding);
} else {
if (workingEdge.getLeftVertex().equals(ambiguousLeftVertex)) {
workingEdge.setLeftVertex(deepCopyVisitor.visit(canonicalLeftVertex, null));
}
if (workingEdge.getRightVertex().equals(ambiguousRightVertex)) {
workingEdge.setRightVertex(deepCopyVisitor.visit(canonicalRightVertex, null));
}
}
}
// Iterate through our vertex list.
replaceEdgeVerticesAndJoinCopiesInIterator(pathPatternExpr, ambiguousLeftVertex, ambiguousRightVertex,
canonicalLeftVertex, canonicalRightVertex);
}