in asterix-graphix/src/main/java/org/apache/asterix/graphix/lang/rewrite/visitor/SubqueryVertexJoinVisitor.java [86:146]
public Expression visit(MatchClause matchClause, ILangExpression arg) throws CompilationException {
GraphIdentifier workingGraphIdentifier = graphIdentifierStack.peek();
ScopeChecker workingScopeChecker = vertexScopeMap.get(workingGraphIdentifier);
Scope precedingScope = workingScopeChecker.getPrecedingScope();
Scope currentScope = workingScopeChecker.getCurrentScope();
Map<VariableExpr, VariableExpr> remappedVariables = new HashMap<>();
for (PathPatternExpr pathExpression : matchClause.getPathExpressions()) {
for (VertexPatternExpr vertexExpression : pathExpression.getVertexExpressions()) {
VariableExpr vertexVariable = vertexExpression.getVariableExpr();
VarIdentifier vertexName = vertexVariable.getVar();
if (precedingScope == null || precedingScope.getParentScope() == null) {
// We are in a top-level FROM-GRAPH-CLAUSE. Add this variable to our current scope.
currentScope.addSymbolToScope(vertexName);
} else if (currentScope.findLocalSymbol(vertexName.getValue()) == null
&& currentScope.findSymbol(vertexName.getValue()) != null) {
// We have a nested Graphix query, and we have found a vertex that references an outer vertex.
SelectBlock parentSelectBlock = (SelectBlock) arg;
// Replace the current vertex variable with a copy.
VariableExpr newVariable = graphixRewritingContext.getGraphixVariableCopy(vertexVariable);
vertexExpression.setVariableExpr(newVariable);
vertexExpression.getVariableExpr().setSourceLocation(vertexVariable.getSourceLocation());
vertexExpression.addHint(new SubqueryVertexJoinAnnotation(vertexVariable));
remappedVariables.put(vertexVariable, newVariable);
// JOIN our copy with the parent vertex variable.
List<Expression> joinArgs = List.of(vertexVariable, newVariable);
OperatorExpr joinExpr = new OperatorExpr(joinArgs, List.of(OperatorType.EQ), false);
parentSelectBlock.getLetWhereList().add(new WhereClause(joinExpr));
} else if (currentScope.findLocalSymbol(vertexName.getValue()) == null) {
// We have a nested Graphix query that does not correlate with an outer query.
currentScope.addSymbolToScope(vertexName);
} else if (remappedVariables.containsKey(vertexVariable)) {
// We have replaced this variable already. Update the reference.
VariableExpr remappedVertexVariable = remappedVariables.get(vertexVariable);
vertexExpression.setVariableExpr(graphixDeepCopyVisitor.visit(remappedVertexVariable, null));
vertexExpression.getVariableExpr().setSourceLocation(vertexVariable.getSourceLocation());
vertexExpression.addHint(new SubqueryVertexJoinAnnotation(vertexVariable));
}
}
for (EdgePatternExpr edgeExpression : pathExpression.getEdgeExpressions()) {
VertexPatternExpr leftVertex = edgeExpression.getLeftVertex();
VertexPatternExpr rightVertex = edgeExpression.getRightVertex();
if (remappedVariables.containsKey(leftVertex.getVariableExpr())) {
VariableExpr leftVariableRemap = remappedVariables.get(leftVertex.getVariableExpr());
leftVertex.setVariableExpr(graphixDeepCopyVisitor.visit(leftVariableRemap, null));
leftVertex.addHint(new SubqueryVertexJoinAnnotation(leftVariableRemap));
}
if (remappedVariables.containsKey(rightVertex.getVariableExpr())) {
VariableExpr rightVariableRemap = remappedVariables.get(rightVertex.getVariableExpr());
rightVertex.setVariableExpr(graphixDeepCopyVisitor.visit(rightVariableRemap, null));
rightVertex.addHint(new SubqueryVertexJoinAnnotation(rightVariableRemap));
}
}
}
return null;
}