in asterix-graphix/src/main/java/org/apache/asterix/graphix/lang/rewrite/visitor/GraphixLoweringVisitor.java [258:365]
private void lowerCanonicalExpandedEdge(EdgePatternExpr edgePatternExpr, LoweringEnvironment environment)
throws CompilationException {
EdgeDescriptor edgeDescriptor = edgePatternExpr.getEdgeDescriptor();
// We should be working with a canonical edge.
GraphIdentifier graphIdentifier = environment.getGraphIdentifier();
List<EdgeIdentifier> edgeElementIDs = edgePatternExpr.generateIdentifiers(graphIdentifier);
if (edgeElementIDs.size() != 1) {
throw new CompilationException(ErrorCode.COMPILATION_ILLEGAL_STATE,
"Encountered non-fixed-point edge pattern!");
}
EdgeIdentifier edgeIdentifier = edgeElementIDs.get(0);
ElementBodyAnalysisContext edgeBodyAnalysisContext = analysisContextMap.get(edgeIdentifier);
DataverseName edgeDataverseName = edgeBodyAnalysisContext.getDataverseName();
String edgeDatasetName = edgeBodyAnalysisContext.getDatasetName();
// Determine our source and destination vertices.
VertexPatternExpr sourceVertex, destVertex;
if (edgeDescriptor.getEdgeDirection() == EdgeDescriptor.EdgeDirection.LEFT_TO_RIGHT) {
sourceVertex = edgePatternExpr.getLeftVertex();
destVertex = edgePatternExpr.getRightVertex();
} else { // edgeDescriptor.getEdgeDirection() == EdgeDescriptor.EdgeDirection.RIGHT_TO_LEFT
sourceVertex = edgePatternExpr.getRightVertex();
destVertex = edgePatternExpr.getLeftVertex();
}
// Collect information about our source vertex.
VertexIdentifier sourceIdentifier = sourceVertex.generateIdentifiers(graphIdentifier).get(0);
ElementBodyAnalysisContext sourceBodyAnalysisContext = analysisContextMap.get(sourceIdentifier);
VariableExpr sourceVertexVariable = sourceVertex.getVariableExpr();
List<List<String>> sourceVertexKey = elementLookupTable.getVertexKey(sourceIdentifier);
Function<EdgeIdentifier, List<List<String>>> sourceKey = elementLookupTable::getEdgeSourceKey;
boolean isSourceInline = sourceBodyAnalysisContext.isExpressionInline() && environment.isInlineLegal();
boolean isSourceIntroduced = aliasLookupTable.getIterationAlias(sourceVertexVariable) != null;
// ...and our destination vertex...
VertexIdentifier destIdentifier = destVertex.generateIdentifiers(graphIdentifier).get(0);
ElementBodyAnalysisContext destBodyAnalysisContext = analysisContextMap.get(destIdentifier);
VariableExpr destVertexVariable = destVertex.getVariableExpr();
List<List<String>> destVertexKey = elementLookupTable.getVertexKey(destIdentifier);
Function<EdgeIdentifier, List<List<String>>> destKey = elementLookupTable::getEdgeDestKey;
boolean isDestInline = destBodyAnalysisContext.isExpressionInline() && environment.isInlineLegal();
boolean isDestIntroduced = aliasLookupTable.getIterationAlias(destVertexVariable) != null;
// ...and our edge.
List<List<String>> sourceEdgeKey = elementLookupTable.getEdgeSourceKey(edgeIdentifier);
List<List<String>> destEdgeKey = elementLookupTable.getEdgeDestKey(edgeIdentifier);
String sourceBodyDatasetName = sourceBodyAnalysisContext.getDatasetName();
String destBodyDatasetName = destBodyAnalysisContext.getDatasetName();
boolean isEdgeInline = edgeBodyAnalysisContext.isExpressionInline() && environment.isInlineLegal();
boolean isSourceFolded = isSourceInline && sourceBodyDatasetName.equals(edgeDatasetName)
&& sourceBodyAnalysisContext.getDataverseName().equals(edgeDataverseName)
&& sourceVertexKey.equals(sourceEdgeKey);
boolean isDestFolded = isDestInline && destBodyDatasetName.equals(edgeDatasetName)
&& destBodyAnalysisContext.getDataverseName().equals(edgeDataverseName)
&& destVertexKey.equals(destEdgeKey);
// Condition our strategy on which vertices are currently introduced.
if (isEdgeInline && isSourceFolded) {
if (!isSourceIntroduced) {
environment.acceptAction(actionFactory.buildDanglingVertexAction(sourceVertex));
}
environment.acceptAction(actionFactory.buildFoldedEdgeAction(sourceVertex, edgePatternExpr));
environment.acceptAction(
!isDestIntroduced ? actionFactory.buildBoundVertexAction(destVertex, edgePatternExpr, destKey)
: actionFactory.buildRawJoinVertexAction(destVertex, edgePatternExpr, destKey));
} else if (isEdgeInline && isDestFolded) {
if (!isDestIntroduced) {
environment.acceptAction(actionFactory.buildDanglingVertexAction(destVertex));
}
environment.acceptAction(actionFactory.buildFoldedEdgeAction(destVertex, edgePatternExpr));
environment.acceptAction(
!isSourceIntroduced ? actionFactory.buildBoundVertexAction(sourceVertex, edgePatternExpr, sourceKey)
: actionFactory.buildRawJoinVertexAction(sourceVertex, edgePatternExpr, sourceKey));
} else if (isSourceIntroduced && isDestIntroduced) {
environment.acceptAction(actionFactory.buildNonFoldedEdgeAction(sourceVertex, edgePatternExpr, sourceKey));
environment.acceptAction(actionFactory.buildRawJoinVertexAction(destVertex, edgePatternExpr, destKey));
} else if (isSourceIntroduced) { // !isDestIntroduced
environment.acceptAction(actionFactory.buildNonFoldedEdgeAction(sourceVertex, edgePatternExpr, sourceKey));
environment.acceptAction(actionFactory.buildBoundVertexAction(destVertex, edgePatternExpr, destKey));
} else if (isDestIntroduced) { // !isSourceIntroduced
environment.acceptAction(actionFactory.buildNonFoldedEdgeAction(destVertex, edgePatternExpr, destKey));
environment.acceptAction(actionFactory.buildBoundVertexAction(sourceVertex, edgePatternExpr, sourceKey));
} else { // !isSourceIntroduced && !isDestIntroduced
// When nothing is introduced, start off from LEFT to RIGHT instead of considering our source and dest.
VertexPatternExpr leftVertex = edgePatternExpr.getLeftVertex();
VertexPatternExpr rightVertex = edgePatternExpr.getRightVertex();
Function<EdgeIdentifier, List<List<String>>> leftKey;
Function<EdgeIdentifier, List<List<String>>> rightKey;
if (edgeDescriptor.getEdgeDirection() == EdgeDescriptor.EdgeDirection.LEFT_TO_RIGHT) {
leftKey = sourceKey;
rightKey = destKey;
} else { // edgeDescriptor.getEdgeDirection() == EdgeDescriptor.EdgeDirection.RIGHT_TO_LEFT
leftKey = destKey;
rightKey = sourceKey;
}
environment.acceptAction(actionFactory.buildDanglingVertexAction(leftVertex));
environment.acceptAction(actionFactory.buildNonFoldedEdgeAction(leftVertex, edgePatternExpr, leftKey));
environment.acceptAction(actionFactory.buildBoundVertexAction(rightVertex, edgePatternExpr, rightKey));
}
}