/**
 * END USER LICENSE AGREEMENT (“EULA”)
 *
 * READ THIS AGREEMENT CAREFULLY (date: 9/13/2011):
 * http://www.akiban.com/licensing/20110913
 *
 * BY INSTALLING OR USING ALL OR ANY PORTION OF THE SOFTWARE, YOU ARE ACCEPTING
 * ALL OF THE TERMS AND CONDITIONS OF THIS AGREEMENT. YOU AGREE THAT THIS
 * AGREEMENT IS ENFORCEABLE LIKE ANY WRITTEN AGREEMENT SIGNED BY YOU.
 *
 * IF YOU HAVE PAID A LICENSE FEE FOR USE OF THE SOFTWARE AND DO NOT AGREE TO
 * THESE TERMS, YOU MAY RETURN THE SOFTWARE FOR A FULL REFUND PROVIDED YOU (A) DO
 * NOT USE THE SOFTWARE AND (B) RETURN THE SOFTWARE WITHIN THIRTY (30) DAYS OF
 * YOUR INITIAL PURCHASE.
 *
 * IF YOU WISH TO USE THE SOFTWARE AS AN EMPLOYEE, CONTRACTOR, OR AGENT OF A
 * CORPORATION, PARTNERSHIP OR SIMILAR ENTITY, THEN YOU MUST BE AUTHORIZED TO SIGN
 * FOR AND BIND THE ENTITY IN ORDER TO ACCEPT THE TERMS OF THIS AGREEMENT. THE
 * LICENSES GRANTED UNDER THIS AGREEMENT ARE EXPRESSLY CONDITIONED UPON ACCEPTANCE
 * BY SUCH AUTHORIZED PERSONNEL.
 *
 * IF YOU HAVE ENTERED INTO A SEPARATE WRITTEN LICENSE AGREEMENT WITH AKIBAN FOR
 * USE OF THE SOFTWARE, THE TERMS AND CONDITIONS OF SUCH OTHER AGREEMENT SHALL
 * PREVAIL OVER ANY CONFLICTING TERMS OR CONDITIONS IN THIS AGREEMENT.
 */

package com.akiban.sql.optimizer.plan;

/** Application of a Bloom filter. */
public class BloomFilterFilter extends BasePlanWithInput
{
    private BloomFilter bloomFilter;
    private PlanNode check;

    public BloomFilterFilter(BloomFilter bloomFilter, PlanNode input, PlanNode check) {
        super(input);
        this.bloomFilter = bloomFilter;
        this.check = check;
        check.setOutput(this);
    }

    public BloomFilter getBloomFilter() {
        return bloomFilter;
    }

    public PlanNode getCheck() {
        return check;
    }
    public void setCheck(PlanNode check) {
        this.check = check;
        check.setOutput(this);
    }

    @Override
    public void replaceInput(PlanNode oldInput, PlanNode newInput) {
        super.replaceInput(oldInput, newInput);
        if (check == oldInput) {
            check = newInput;
            check.setOutput(this);
        }
    }

    @Override
    public boolean accept(PlanVisitor v) {
        if (v.visitEnter(this)) {
            check.accept(v);
            getInput().accept(v);
        }
        return v.visitLeave(this);
    }

    @Override
    public String summaryString() {
        StringBuilder str = new StringBuilder(super.summaryString());
        str.append("(");
        str.append(bloomFilter);
        str.append(")");
        return str.toString();
    }

    @Override
    protected void deepCopy(DuplicateMap map) {
        super.deepCopy(map);
        check = (PlanNode)check.duplicate(map);
    }

}

@@ -1267,16 +1267,40 @@
 .plan;%0A%0A
+import java.util.List;%0A%0A
 /** Appl
@@ -1421,24 +1421,76 @@
 loomFilter;%0A
+    private List%3CExpressionNode%3E lookupExpressions;%0A
     private 
@@ -1559,16 +1559,86 @@
 mFilter,
+ List%3CExpressionNode%3E lookupExpressions, %0A                            
  PlanNod
@@ -1722,24 +1722,76 @@
 loomFilter;%0A
+        this.lookupExpressions = lookupExpressions;%0A
         this
@@ -1915,24 +1915,121 @@
 ilter;%0A    %7D
+%0A    public List%3CExpressionNode%3E getLookupExpressions() %7B%0A        return lookupExpressions;%0A    %7D
 %0A%0A    public
@@ -2533,24 +2533,28 @@
             
+if (
 check.accept
@@ -2560,43 +2560,601 @@
 t(v)
-;%0A            getInput().accept(v);
+ && getInput().accept(v)) %7B%0A                if (v instanceof ExpressionRewriteVisitor) %7B%0A                    for (int i = 0; i %3C lookupExpressions.size(); i++) %7B%0A                        lookupExpressions.set(i, lookupExpressions.get(i).accept((ExpressionRewriteVisitor)v));%0A                    %7D%0A                %7D%0A                else if (v instanceof ExpressionVisitor) %7B%0A                    for (ExpressionNode expr : lookupExpressions) %7B%0A                        if (!expr.accept((ExpressionVisitor)v))%0A                            break;%0A                    %7D%0A                %7D%0A            %7D
 %0A   

Add more state.