private static Expression generateJoinCondition()

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);
    }