in asterix-graphix/src/main/java/org/apache/asterix/graphix/lang/rewrite/lower/LoweringEnvironment.java [295:365]
private static Expression generateJoinCondition(ListIterator<AbstractClause> lowerClauseIterator,
IVisitorExtension visitorExtension) throws CompilationException {
final List<Expression> joinConditionExpressions = new ArrayList<>();
final Collection<VariableExpr> freeVariables = new HashSet<>();
final FreeVariableVisitor freeVariableVisitor = new FreeVariableVisitor() {
@Override
public Void visit(IVisitorExtension visitorExtension, Collection<VariableExpr> freeVars)
throws CompilationException {
Collection<VariableExpr> bindingVariables = new HashSet<>();
Collection<VariableExpr> conditionFreeVars = new HashSet<>();
Collection<VariableExpr> clauseFreeVars = new HashSet<>();
while (lowerClauseIterator.hasNext()) {
AbstractClause lowerClause = lowerClauseIterator.next();
clauseFreeVars.clear();
if (lowerClause instanceof AbstractBinaryCorrelateClause) {
AbstractBinaryCorrelateClause correlateClause = (AbstractBinaryCorrelateClause) lowerClause;
correlateClause.getRightExpression().accept(this, clauseFreeVars);
if (lowerClause.getClauseType() == Clause.ClauseType.UNNEST_CLAUSE) {
clauseFreeVars.removeAll(bindingVariables);
if (!clauseFreeVars.isEmpty()) {
throw new CompilationException(ErrorCode.COMPILATION_ILLEGAL_STATE,
"Encountered UNNEST-CLAUSE with free variables.");
}
} else {
AbstractBinaryCorrelateWithConditionClause clauseWithCondition =
(AbstractBinaryCorrelateWithConditionClause) correlateClause;
conditionFreeVars.clear();
clauseWithCondition.getConditionExpression().accept(this, conditionFreeVars);
conditionFreeVars.removeAll(bindingVariables);
conditionFreeVars.remove(correlateClause.getRightVariable());
if (!conditionFreeVars.isEmpty()) {
// We have found a JOIN with a free variable.
joinConditionExpressions.add(clauseWithCondition.getConditionExpression());
clauseWithCondition.setConditionExpression(new LiteralExpr(TrueLiteral.INSTANCE));
}
clauseFreeVars.addAll(conditionFreeVars);
}
// Adds binding variables.
bindingVariables.add(correlateClause.getRightVariable());
freeVars.addAll(clauseFreeVars);
} else if (lowerClause.getClauseType() == Clause.ClauseType.WHERE_CLAUSE) {
WhereClause whereClause = (WhereClause) lowerClause;
whereClause.getWhereExpr().accept(this, clauseFreeVars);
clauseFreeVars.removeAll(bindingVariables);
if (!clauseFreeVars.isEmpty()) {
joinConditionExpressions.add(whereClause.getWhereExpr());
lowerClauseIterator.remove();
}
freeVars.addAll(clauseFreeVars);
} else if (lowerClause.getClauseType() == Clause.ClauseType.LET_CLAUSE) {
LetClause letClause = (LetClause) lowerClause;
letClause.getBindingExpr().accept(this, clauseFreeVars);
clauseFreeVars.removeAll(bindingVariables);
bindingVariables.add(letClause.getVarExpr());
if (!clauseFreeVars.isEmpty()) {
throw new CompilationException(ErrorCode.COMPILATION_ILLEGAL_STATE,
"Encountered LET-CLAUSE with free variables.");
}
}
}
return null;
}
};
freeVariableVisitor.visit(visitorExtension, freeVariables);
return joinConditionExpressions.isEmpty() ? new LiteralExpr(TrueLiteral.INSTANCE)
: LowerRewritingUtil.buildConnectedClauses(joinConditionExpressions, OperatorType.AND);
}