private IntermediateQuery pushAboveUnions(IntermediateQuery query) throws EmptyQueryException {
        boolean fixPointReached;
        do {
            fixPointReached = true;
            for (QueryNode node : query.getNodesInTopDownOrder()) {
                if (node instanceof UnionNode) {
                    Optional<PushUpBooleanExpressionProposal> proposal = makeProposalForUnionNode((UnionNode) node, query);
                    if (proposal.isPresent()) {
                        query = ((PushUpBooleanExpressionResults) query.applyProposal(proposal.get())).getResultingQuery();
                        fixPointReached = false;
                    }
                }
            }
        }
        while (!fixPointReached);
        return query;
    }
private IntermediateQuery pushAboveUnions ( IntermediateQuery query ) throws EmptyQueryException { boolean fixPointReached ; do { fixPointReached = true ; for ( QueryNode node : query . getNodesInTopDownOrder ( ) ) { if ( node instanceof UnionNode ) { Optional < PushUpBooleanExpressionProposal > proposal = makeProposalForUnionNode ( ( UnionNode ) node , query ) ; if ( proposal . isPresent ( ) ) { query = ( ( PushUpBooleanExpressionResults ) query . applyProposal ( proposal . get ( ) ) ) . getResultingQuery ( ) ; fixPointReached = false ; } } } } while ( ! fixPointReached ) ; return query ; }
Can be optimized by reducing after each iteration the set of union nodes to be reviewed