in asterix-graphix/src/main/java/org/apache/asterix/graphix/lang/rewrite/lower/EnvironmentActionFactory.java [546:691]
public IEnvironmentAction buildBoundVertexAction(VertexPatternExpr vertexPatternExpr,
EdgePatternExpr edgePatternExpr, Function<EdgeIdentifier, List<List<String>>> edgeKeyAccess)
throws CompilationException {
VariableExpr edgeVar = edgePatternExpr.getEdgeDescriptor().getVariableExpr();
VariableExpr vertexVar = vertexPatternExpr.getVariableExpr();
VariableExpr iterationVar = graphixRewritingContext.getGraphixVariableCopy(vertexVar);
VariableExpr intermediateVar = graphixRewritingContext.getGraphixVariableCopy(vertexVar);
// We should only be working with one edge identifier...
List<EdgeIdentifier> edgeElementIDs = edgePatternExpr.generateIdentifiers(graphIdentifier);
if (edgeElementIDs.size() != 1) {
throw new CompilationException(ErrorCode.COMPILATION_ILLEGAL_STATE, "Found non-canonical edge pattern!");
}
EdgeIdentifier edgeIdentifier = edgeElementIDs.get(0);
// ...and only one vertex identifier (given that we only have one label).
List<VertexIdentifier> vertexElementIDs = vertexPatternExpr.generateIdentifiers(graphIdentifier);
if (vertexElementIDs.size() != 1) {
throw new CompilationException(ErrorCode.COMPILATION_ILLEGAL_STATE, "Found non-canonical vertex pattern!");
}
VertexIdentifier vertexIdentifier = vertexElementIDs.get(0);
ElementBodyAnalysisContext vertexAnalysisContext = analysisContextMap.get(vertexIdentifier);
Expression datasetCallExpression = vertexAnalysisContext.getDatasetCallExpression();
if (vertexAnalysisContext.isExpressionInline() && vertexAnalysisContext.isSelectClauseInline()) {
return new AbstractInlineAction(graphixRewritingContext, vertexAnalysisContext, iterationVar) {
@Override
public void apply(LoweringEnvironment loweringEnvironment) throws CompilationException {
// Join our vertex iteration variable to our edge variable.
loweringEnvironment.acceptTransformer(lowerList -> {
VariableExpr edgeJoinExpr = aliasLookupTable.getJoinAlias(edgeVar);
VariableExpr edgeJoinCopy = graphixDeepCopyVisitor.visit(edgeJoinExpr, null);
VariableExpr iterationVarCopy1 = graphixDeepCopyVisitor.visit(iterationVar, null);
VariableExpr iterationVarCopy2 = graphixDeepCopyVisitor.visit(iterationVar, null);
Expression vertexEdgeJoin = buildVertexEdgeJoin(
buildAccessorList(iterationVarCopy1, elementLookupTable.getVertexKey(vertexIdentifier)),
buildAccessorList(edgeJoinCopy, edgeKeyAccess.apply(edgeIdentifier)));
JoinClause joinClause = new JoinClause(JoinType.INNER, datasetCallExpression, iterationVarCopy2,
null, vertexEdgeJoin, null);
joinClause.setSourceLocation(vertexPatternExpr.getSourceLocation());
lowerList.addNonRepresentativeClause(joinClause);
});
// Inline our vertex body.
super.apply(loweringEnvironment);
// If we have a filter expression, add it as a WHERE clause here.
final Expression filterExpr = vertexPatternExpr.getFilterExpr();
if (filterExpr != null) {
loweringEnvironment.acceptAction(buildFilterExprAction(filterExpr, vertexVar, iterationVar));
}
// Bind our intermediate (join) variable and vertex variable.
loweringEnvironment.acceptTransformer(lowerList -> {
VariableExpr iterationVarCopy1 = graphixDeepCopyVisitor.visit(iterationVar, null);
VariableExpr iterationVarCopy2 = graphixDeepCopyVisitor.visit(iterationVar, null);
VariableExpr intermediateVarCopy = graphixDeepCopyVisitor.visit(intermediateVar, null);
LetClause nonRepresentativeBinding = new LetClause(intermediateVarCopy, iterationVarCopy1);
lowerList.addNonRepresentativeClause(nonRepresentativeBinding);
lowerList.addVertexBinding(vertexVar, iterationVarCopy2);
});
aliasLookupTable.addIterationAlias(vertexVar, iterationVar);
aliasLookupTable.addJoinAlias(vertexVar, intermediateVar);
}
};
} else if (vertexAnalysisContext.isExpressionInline()) {
return new AbstractInlineAction(graphixRewritingContext, vertexAnalysisContext, iterationVar) {
@Override
public void apply(LoweringEnvironment loweringEnvironment) throws CompilationException {
// Join our vertex iteration variable to our edge variable.
loweringEnvironment.acceptTransformer(lowerList -> {
VariableExpr edgeJoinExpr = aliasLookupTable.getJoinAlias(edgeVar);
VariableExpr edgeJoinCopy = graphixDeepCopyVisitor.visit(edgeJoinExpr, null);
VariableExpr iterationVarCopy1 = graphixDeepCopyVisitor.visit(iterationVar, null);
VariableExpr iterationVarCopy2 = graphixDeepCopyVisitor.visit(iterationVar, null);
Expression vertexEdgeJoin = buildVertexEdgeJoin(
buildAccessorList(iterationVarCopy1, elementLookupTable.getVertexKey(vertexIdentifier)),
buildAccessorList(edgeJoinCopy, edgeKeyAccess.apply(edgeIdentifier)));
JoinClause joinClause = new JoinClause(JoinType.INNER, datasetCallExpression, iterationVarCopy2,
null, vertexEdgeJoin, null);
joinClause.setSourceLocation(vertexPatternExpr.getSourceLocation());
lowerList.addNonRepresentativeClause(joinClause);
});
// Inline our vertex body.
super.apply(loweringEnvironment);
// If we have a filter expression, add it as a WHERE clause here.
final Expression filterExpr = vertexPatternExpr.getFilterExpr();
if (filterExpr != null) {
loweringEnvironment.acceptAction(buildFilterExprAction(filterExpr, vertexVar, iterationVar));
}
// Build a record constructor from our context to bind to our vertex variable.
loweringEnvironment.acceptTransformer(lowerList -> {
VariableExpr intermediateVarCopy = graphixDeepCopyVisitor.visit(intermediateVar, null);
RecordConstructor recordConstructor1 = buildRecordConstructor();
RecordConstructor recordConstructor2 = buildRecordConstructor();
LetClause nonRepresentativeBinding = new LetClause(intermediateVarCopy, recordConstructor1);
lowerList.addNonRepresentativeClause(nonRepresentativeBinding);
lowerList.addVertexBinding(vertexVar, recordConstructor2);
});
aliasLookupTable.addIterationAlias(vertexVar, iterationVar);
aliasLookupTable.addJoinAlias(vertexVar, intermediateVar);
}
};
} else {
GraphElementDeclaration elementDeclaration = elementLookupTable.getElementDecl(vertexIdentifier);
return loweringEnvironment -> {
// Join our vertex body to our edge variable.
loweringEnvironment.acceptTransformer(lowerList -> {
VariableExpr edgeJoinExpr = aliasLookupTable.getJoinAlias(edgeVar);
VariableExpr edgeJoinCopy = graphixDeepCopyVisitor.visit(edgeJoinExpr, null);
VariableExpr iterationVarCopy1 = graphixDeepCopyVisitor.visit(iterationVar, null);
VariableExpr iterationVarCopy2 = graphixDeepCopyVisitor.visit(iterationVar, null);
Expression vertexEdgeJoin = buildVertexEdgeJoin(
buildAccessorList(iterationVarCopy1, elementLookupTable.getVertexKey(vertexIdentifier)),
buildAccessorList(edgeJoinCopy, edgeKeyAccess.apply(edgeIdentifier)));
ILangExpression declBodyCopy = SqlppRewriteUtil.deepCopy(elementDeclaration.getNormalizedBody());
JoinClause joinClause = new JoinClause(JoinType.INNER, (Expression) declBodyCopy, iterationVarCopy2,
null, vertexEdgeJoin, null);
joinClause.setSourceLocation(vertexPatternExpr.getSourceLocation());
lowerList.addNonRepresentativeClause(joinClause);
});
// If we have a filter expression, add it as a WHERE clause here.
final Expression filterExpr = vertexPatternExpr.getFilterExpr();
if (filterExpr != null) {
loweringEnvironment.acceptAction(buildFilterExprAction(filterExpr, vertexVar, iterationVar));
}
// Bind our intermediate (join) variable and vertex variable.
loweringEnvironment.acceptTransformer(lowerList -> {
VariableExpr iterationVarCopy1 = graphixDeepCopyVisitor.visit(iterationVar, null);
VariableExpr iterationVarCopy2 = graphixDeepCopyVisitor.visit(iterationVar, null);
VariableExpr intermediateVarCopy = graphixDeepCopyVisitor.visit(intermediateVar, null);
LetClause nonRepresentativeBinding = new LetClause(intermediateVarCopy, iterationVarCopy1);
lowerList.addNonRepresentativeClause(nonRepresentativeBinding);
lowerList.addVertexBinding(vertexVar, iterationVarCopy2);
});
aliasLookupTable.addIterationAlias(vertexVar, iterationVar);
aliasLookupTable.addJoinAlias(vertexVar, intermediateVar);
};
}
}