gt:             		new ConstantNode(someUri.getIV()), varS));  
context: /**
  
  Copyright (C) SYSTAP, LLC DBA Blazegraph 2006-2016.  All rights reserved.
  
  Contact:
       SYSTAP, LLC DBA Blazegraph
       2501 Calvert ST NW #106
       Washington, DC 20008
       licenses@blazegraph.com
  
  This program is free software; you can redistribute it and/or modify
  it under the terms of the GNU General Public License as published by
  the Free Software Foundation; version 2 of the License.
  
  This program is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU General Public License for more details.
  
  You should have received a copy of the GNU General Public License
  along with this program; if not, write to the Free Software
  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
  /*
   * Created on Aug 29, 2011
   */
  
  package com.bigdata.rdf.sparql.ast.optimizers;
  
  import java.util.Collections;
  import java.util.List;
  
  import com.bigdata.bop.BOpUtility;
  import com.bigdata.bop.IBindingSet;
  import com.bigdata.rdf.model.BigdataURI;
  import com.bigdata.rdf.model.BigdataValue;
  import com.bigdata.rdf.sparql.ast.ASTContainer;
  import com.bigdata.rdf.sparql.ast.AbstractASTEvaluationTestCase;
  import com.bigdata.rdf.sparql.ast.BSBMQ5Setup;
  import com.bigdata.rdf.sparql.ast.ConstantNode;
  import com.bigdata.rdf.sparql.ast.FilterNode;
  import com.bigdata.rdf.sparql.ast.FunctionNode;
  import com.bigdata.rdf.sparql.ast.GraphPatternGroup;
  import com.bigdata.rdf.sparql.ast.IGroupMemberNode;
  import com.bigdata.rdf.sparql.ast.IQueryNode;
  import com.bigdata.rdf.sparql.ast.JoinGroupNode;
  import com.bigdata.rdf.sparql.ast.ProjectionNode;
  import com.bigdata.rdf.sparql.ast.QueryBase.Annotations;
  import com.bigdata.rdf.sparql.ast.QueryNodeWithBindingSet;
  import com.bigdata.rdf.sparql.ast.QueryRoot;
  import com.bigdata.rdf.sparql.ast.QueryType;
  import com.bigdata.rdf.sparql.ast.StatementPatternNode;
  import com.bigdata.rdf.sparql.ast.SubqueryRoot;
  import com.bigdata.rdf.sparql.ast.VarNode;
  import com.bigdata.rdf.sparql.ast.eval.AST2BOpContext;
  
  /**
   * Test suite for {@link ASTAttachJoinFiltersOptimizer}.
   * 
   * @author <a href="mailto:thompsonbry@users.sourceforge.net">Bryan Thompson</a>
   * @version $Id$
   */
  public class TestASTAttachJoinFiltersOptimizer extends AbstractASTEvaluationTestCase {
  
      /**
       * 
       */
      public TestASTAttachJoinFiltersOptimizer() {
      }
  
      /**
       * @param name
       */
      public TestASTAttachJoinFiltersOptimizer(String name) {
          super(name);
      }
  
      /**
       * Unit test for the attachment of the join filters to the required joins in
       * a {@link JoinGroupNode}.
       * <p>
       * Note: The core logic for deciding join filter attachment is tested
       * elsewhere. This is only testing the attachment once those decisions are
       * made.
       */
      @SuppressWarnings("unchecked")
      public void test_attachFilters() {
  
        /*
        * Note: DO NOT share structures in this test!!!!
        */
       final IBindingSet[] bsets = new IBindingSet[]{};
  
          // The source AST.
          final QueryRoot given;
          {
  
              final BSBMQ5Setup s = new BSBMQ5Setup(store);
              
              given = s.queryRoot;
  
              /**
               * Put the joins into a known order whose correct filter attachments
               * are also known. This order is <code>[5, 3, 1, 0, 2, 4, 6]</code>.
               */
              final GraphPatternGroup<IGroupMemberNode> whereClause = new JoinGroupNode();
              given.setWhereClause(whereClause);
              
              // the required joins in a known order.
              whereClause.addChild(s.p5);
              whereClause.addChild(s.p3);
              whereClause.addChild(s.p1);
              whereClause.addChild(s.p0);
              whereClause.addChild(s.p2);
              whereClause.addChild(s.p4);
              whereClause.addChild(s.p6);
              
              // now add in the filters.
              whereClause.addChild(s.c0);
              whereClause.addChild(s.c1);
              whereClause.addChild(s.c2);
  
          }
  
          // The expected AST after the rewrite.
          final QueryRoot expected;
          {
  
              final BSBMQ5Setup s = new BSBMQ5Setup(store);
              
              expected = s.queryRoot;
  
              /*
               * Build up the join group. The joins will appear in the same order
               * but all of the filters will have been attached to joins.
               */
              final GraphPatternGroup<IGroupMemberNode> whereClause = new JoinGroupNode();
              expected.setWhereClause(whereClause);
              
              // the required joins in the same order.
              whereClause.addChild(s.p5);
              whereClause.addChild(s.p3);
              whereClause.addChild(s.p1);
              whereClause.addChild(s.p0);
              whereClause.addChild(s.p2);
              whereClause.addChild(s.p4);
              whereClause.addChild(s.p6);
              
              // Clear the parent references on the filters.
              s.c0.setParent(null);
              s.c1.setParent(null);
              s.c2.setParent(null);
              
              // now attach the filters to the joins.
              s.p0.setAttachedJoinFilters(Collections.singletonList(s.c0));
              s.p4.setAttachedJoinFilters(Collections.singletonList(s.c1));
              s.p6.setAttachedJoinFilters(Collections.singletonList(s.c2));
              
          }
  
          final IASTOptimizer rewriter = new ASTAttachJoinFiltersOptimizer();
          
          final AST2BOpContext context = new AST2BOpContext(new ASTContainer(
                  given), store);
  
          final IQueryNode actual = rewriter.optimize(context,
                new QueryNodeWithBindingSet(given, bsets)).getQueryNode();
  
          assertSameAST(expected, actual);
  
          /*
           * Verify no change if we feed the output back into the input. This
           * tests the ability to pick up the attached join filters for
           * consideration the next time around.
           * 
           * TODO Actually, the best test would be if we changed the join order
           * as well.
           */
          final IQueryNode actual2 = rewriter.optimize(context,
                new QueryNodeWithBindingSet(BOpUtility.deepCopy(expected), bsets))
                  .getQueryNode();
  
          assertSameAST(expected, actual2);
          
      }
  
      
      
      /**
       * Assert proper handling of redundant (identical) filter expressions.
       */
      @SuppressWarnings("unchecked")
  	public void test_redundantFilter() {
  
          final String sampleInstance = "http://www.example.com/I";
          final BigdataURI someUri = valueFactory.createURI(sampleInstance);
          final BigdataValue[] terms = new BigdataValue[] { someUri };
  
          // resolve terms.
          store.getLexiconRelation()
                  .addTerms(terms, terms.length, false/* readOnly */);
  
          for (BigdataValue bv : terms) {
              // Cache the Value on the IV.
              bv.getIV().setValue(bv);
          }
          
          
      	// The source AST:
          /*
           * QueryType: SELECT
           * SELECT VarNode(s)
           *   JoinGroupNode {
           *     QueryType: SELECT
           *     SELECT VarNode(s)
           *       JoinGroupNode {
           *         StatementPatternNode(VarNode(s), VarNode(p), VarNode(o)) [scope=DEFAULT_CONTEXTS]
           *     }
           *     FILTER( FunctionNode(VarNode(s),VarNode(s))[FunctionNode.scalarVals=null, FunctionNode.functionURI=http://www.w3.org/2005/xpath-functions#not-equal-to, valueExpr=com.bigdata.rdf.internal.constraints.CompareBOp(s,TermId(0U)[eg:b])[ CompareBOp.op=NE]] )
           *     FILTER( FunctionNode(VarNode(s),VarNode(s))[ FunctionNode.scalarVals=null, FunctionNode.functionURI=http://www.w3.org/2005/xpath-functions#not-equal-to, valueExpr=com.bigdata.rdf.internal.constraints.CompareBOp(s,TermId(0U)[eg:b])[ CompareBOp.op=NE]] )
           *   }
           */
          final QueryRoot qUnoptimized = new QueryRoot(QueryType.SELECT);
          {
          	VarNode varS = new VarNode("s");
          	VarNode varP = new VarNode("p");
          	VarNode varO = new VarNode("o");
          	
          	///////////////////////////////////// STEP 1: build inner subquery  	
          	// build innermost join
          	JoinGroupNode innerJoin = new JoinGroupNode();
          	innerJoin.addArg(
          		new StatementPatternNode(varS, varP, varO));
          	
          	// build inner projection
          	ProjectionNode innerProjection = new ProjectionNode();
          	innerProjection.addProjectionVar(new VarNode("s"));
          	
          	// put it together to inner query
          	final SubqueryRoot qUnoptimizedInner = new SubqueryRoot(QueryType.SELECT);
          	qUnoptimizedInner.setProjection(innerProjection);
          	qUnoptimizedInner.setWhereClause(innerJoin);
          	
          	///////////////////////////////////// STEP 1: build outer query
          	// build filter expressions
          	FilterNode f1 = new FilterNode(FunctionNode.NE(
          		new ConstantNode(someUri.getIV()), varS));        	
          	
          	FilterNode f2 = new FilterNode(FunctionNode.NE(
  