Repository: incubator-rya
Updated Branches:
  refs/heads/develop 14073a23f -> 1b12872f9


http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/96dd55ec/extras/indexing/src/test/java/mvm/rya/indexing/external/tupleSet/QueryVariableNormalizerTest.java
----------------------------------------------------------------------
diff --git 
a/extras/indexing/src/test/java/mvm/rya/indexing/external/tupleSet/QueryVariableNormalizerTest.java
 
b/extras/indexing/src/test/java/mvm/rya/indexing/external/tupleSet/QueryVariableNormalizerTest.java
index aec959e..9922682 100644
--- 
a/extras/indexing/src/test/java/mvm/rya/indexing/external/tupleSet/QueryVariableNormalizerTest.java
+++ 
b/extras/indexing/src/test/java/mvm/rya/indexing/external/tupleSet/QueryVariableNormalizerTest.java
@@ -24,7 +24,7 @@ package mvm.rya.indexing.external.tupleSet;
 import java.util.List;
 import java.util.Set;
 
-import mvm.rya.indexing.external.QueryVariableNormalizer;
+import mvm.rya.indexing.pcj.matching.QueryVariableNormalizer;
 
 import org.junit.Assert;
 import org.junit.Test;

http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/96dd55ec/extras/indexing/src/test/java/mvm/rya/indexing/external/tupleSet/VarConstQueryVariableNormalizerTest.java
----------------------------------------------------------------------
diff --git 
a/extras/indexing/src/test/java/mvm/rya/indexing/external/tupleSet/VarConstQueryVariableNormalizerTest.java
 
b/extras/indexing/src/test/java/mvm/rya/indexing/external/tupleSet/VarConstQueryVariableNormalizerTest.java
index 002a0e1..e21a3a6 100644
--- 
a/extras/indexing/src/test/java/mvm/rya/indexing/external/tupleSet/VarConstQueryVariableNormalizerTest.java
+++ 
b/extras/indexing/src/test/java/mvm/rya/indexing/external/tupleSet/VarConstQueryVariableNormalizerTest.java
@@ -23,7 +23,7 @@ package mvm.rya.indexing.external.tupleSet;
 import java.util.List;
 import java.util.Set;
 
-import mvm.rya.indexing.external.QueryVariableNormalizer;
+import mvm.rya.indexing.pcj.matching.QueryVariableNormalizer;
 
 import org.junit.Assert;
 import org.junit.Test;

http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/96dd55ec/extras/indexing/src/test/java/mvm/rya/indexing/pcj/matching/FlattenedOptionalTest.java
----------------------------------------------------------------------
diff --git 
a/extras/indexing/src/test/java/mvm/rya/indexing/pcj/matching/FlattenedOptionalTest.java
 
b/extras/indexing/src/test/java/mvm/rya/indexing/pcj/matching/FlattenedOptionalTest.java
new file mode 100644
index 0000000..a3accd1
--- /dev/null
+++ 
b/extras/indexing/src/test/java/mvm/rya/indexing/pcj/matching/FlattenedOptionalTest.java
@@ -0,0 +1,133 @@
+package mvm.rya.indexing.pcj.matching;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.junit.Assert;
+import org.junit.Test;
+import org.openrdf.query.MalformedQueryException;
+import org.openrdf.query.algebra.Filter;
+import org.openrdf.query.algebra.Join;
+import org.openrdf.query.algebra.LeftJoin;
+import org.openrdf.query.algebra.Projection;
+import org.openrdf.query.algebra.TupleExpr;
+import org.openrdf.query.parser.ParsedQuery;
+import org.openrdf.query.parser.sparql.SPARQLParser;
+
+public class FlattenedOptionalTest {
+
+       @Test
+       public void testBasicOptional() throws MalformedQueryException {
+
+               String query = ""//
+                               + "SELECT ?e ?c ?l" //
+                               + "{" //
+                               + "  ?e a ?c . "//
+                               + "  ?e 
<http://www.w3.org/2000/01/rdf-schema#label> ?l "//
+                               + "  OPTIONAL{?e <uri:talksTo> ?l } . "//
+                               + "}";//
+
+               SPARQLParser parser = new SPARQLParser();
+               ParsedQuery pq = parser.parseQuery(query, null);
+               List<TupleExpr> joinArgs = getJoinArgs(pq.getTupleExpr(),
+                               new ArrayList<TupleExpr>());
+               FlattenedOptional optional = (FlattenedOptional) 
joinArgs.get(0);
+               TupleExpr sp1 = joinArgs.get(1);
+               TupleExpr sp2 = joinArgs.get(2);
+
+               Assert.assertEquals(false, optional.canRemoveTuple(sp2));
+               Assert.assertEquals(true, optional.canRemoveTuple(sp1));
+//             System.out.println(joinArgs);
+
+       }
+
+
+       @Test
+       public void testReOrderedBasicOptional() throws MalformedQueryException 
{
+
+               String query = ""//
+                               + "SELECT ?e ?c ?l" //
+                               + "{" //
+                               + "  ?e a ?c . "//
+                               + "  OPTIONAL{?e <uri:talksTo> ?l } . "//
+                               + "  ?e 
<http://www.w3.org/2000/01/rdf-schema#label> ?l "//
+                               + "}";//
+
+               SPARQLParser parser = new SPARQLParser();
+               ParsedQuery pq = parser.parseQuery(query, null);
+               System.out.println(pq.getTupleExpr());
+               List<TupleExpr> joinArgs = getJoinArgs(pq.getTupleExpr(),
+                               new ArrayList<TupleExpr>());
+//             System.out.println(joinArgs);
+               FlattenedOptional optional = (FlattenedOptional) 
joinArgs.get(0);
+               TupleExpr sp1 = joinArgs.get(1);
+               TupleExpr sp2 = joinArgs.get(2);
+
+               Assert.assertEquals(false, optional.canRemoveTuple(sp1));
+               Assert.assertEquals(false, optional.canAddTuple(sp2));
+
+
+       }
+
+       @Test
+       public void testEqualsAndHashCode() throws MalformedQueryException {
+
+               String query1 = ""//
+                               + "SELECT ?e ?c ?l" //
+                               + "{" //
+                               + "  ?e <uri:worksAt> ?c . "//
+                               + "  OPTIONAL{?e <uri:talksTo> ?l } . "//
+                               + "  ?e 
<http://www.w3.org/2000/01/rdf-schema#label> ?l "//
+                               + "}";//
+
+               SPARQLParser parser = new SPARQLParser();
+               ParsedQuery pq1 = parser.parseQuery(query1, null);
+               List<TupleExpr> joinArgs1 = getJoinArgs(pq1.getTupleExpr(),
+                               new ArrayList<TupleExpr>());
+
+
+               String query2 = ""//
+                               + "SELECT ?e ?c ?l" //
+                               + "{" //
+                               + "  ?e a ?c . "//
+                               + "  ?e 
<http://www.w3.org/2000/01/rdf-schema#label> ?l "//
+                               + "  OPTIONAL{?e <uri:talksTo> ?l } . "//
+                               + "}";//
+
+               parser = new SPARQLParser();
+               ParsedQuery pq2 = parser.parseQuery(query2, null);
+               List<TupleExpr> joinArgs2 = getJoinArgs(pq2.getTupleExpr(),
+                               new ArrayList<TupleExpr>());
+               FlattenedOptional optional1 = (FlattenedOptional) 
joinArgs1.get(0);
+               FlattenedOptional optional2 = (FlattenedOptional) 
joinArgs2.get(0);
+               System.out.println(optional1 +  " and " + optional2);
+
+               Assert.assertEquals(optional1, optional2);
+               Assert.assertEquals(optional1.hashCode(), optional2.hashCode());
+
+
+       }
+
+
+       private List<TupleExpr> getJoinArgs(TupleExpr tupleExpr,
+                       List<TupleExpr> joinArgs) {
+               if (tupleExpr instanceof Projection) {
+                       Projection projection = (Projection) tupleExpr;
+                       getJoinArgs(projection.getArg(), joinArgs);
+               } else if (tupleExpr instanceof Join) {
+                       Join join = (Join) tupleExpr;
+                       getJoinArgs(join.getLeftArg(), joinArgs);
+                       getJoinArgs(join.getRightArg(), joinArgs);
+               } else if (tupleExpr instanceof LeftJoin) {
+                       LeftJoin lj = (LeftJoin) tupleExpr;
+                       joinArgs.add(new FlattenedOptional(lj));
+                       getJoinArgs(lj.getLeftArg(), joinArgs);
+               } else if (tupleExpr instanceof Filter) {
+                       getJoinArgs(((Filter) tupleExpr).getArg(), joinArgs);
+               } else {
+                       joinArgs.add(tupleExpr);
+               }
+               return joinArgs;
+       }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/96dd55ec/extras/indexing/src/test/java/mvm/rya/indexing/pcj/matching/JoinSegmentPCJMatcherTest.java
----------------------------------------------------------------------
diff --git 
a/extras/indexing/src/test/java/mvm/rya/indexing/pcj/matching/JoinSegmentPCJMatcherTest.java
 
b/extras/indexing/src/test/java/mvm/rya/indexing/pcj/matching/JoinSegmentPCJMatcherTest.java
new file mode 100644
index 0000000..610f0c2
--- /dev/null
+++ 
b/extras/indexing/src/test/java/mvm/rya/indexing/pcj/matching/JoinSegmentPCJMatcherTest.java
@@ -0,0 +1,214 @@
+package mvm.rya.indexing.pcj.matching;
+
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import mvm.rya.indexing.external.tupleSet.ExternalTupleSet;
+import mvm.rya.indexing.external.tupleSet.SimpleExternalTupleSet;
+
+import org.junit.Assert;
+import org.junit.Test;
+import org.openrdf.query.MalformedQueryException;
+import org.openrdf.query.algebra.Filter;
+import org.openrdf.query.algebra.Join;
+import org.openrdf.query.algebra.LeftJoin;
+import org.openrdf.query.algebra.Projection;
+import org.openrdf.query.algebra.QueryModelNode;
+import org.openrdf.query.algebra.StatementPattern;
+import org.openrdf.query.algebra.TupleExpr;
+import org.openrdf.query.algebra.helpers.QueryModelVisitorBase;
+import org.openrdf.query.parser.ParsedQuery;
+import org.openrdf.query.parser.sparql.SPARQLParser;
+
+public class JoinSegmentPCJMatcherTest {
+
+
+       @Test
+       public void testBasicSegment() throws MalformedQueryException {
+
+               String query1 = ""//
+                               + "SELECT ?e ?c ?l" //
+                               + "{" //
+                               + "  ?e a ?c . "//
+                               + "  ?e <uri:talksTo> ?l  . "//
+                               + "  ?e 
<http://www.w3.org/2000/01/rdf-schema#label> ?l "//
+                               + "}";//
+
+               String query2 = ""//
+                               + "SELECT ?e ?c ?l" //
+                               + "{" //
+                               + "  ?e a ?c . "//
+                               + "  ?e <uri:talksTo> ?l  . "//
+                               + "}";//
+
+               SPARQLParser parser = new SPARQLParser();
+               ParsedQuery pq1 = parser.parseQuery(query1, null);
+               ParsedQuery pq2 = parser.parseQuery(query2, null);
+               TupleExpr te1 = pq1.getTupleExpr();
+               TupleExpr te2 = pq2.getTupleExpr();
+               Projection proj = (Projection) te1;
+               Join join = (Join) proj.getArg();
+
+               JoinSegmentPCJMatcher jsm = new JoinSegmentPCJMatcher(join);
+               SimpleExternalTupleSet pcj = new 
SimpleExternalTupleSet((Projection)te2);
+               Assert.assertEquals(true, jsm.matchPCJ(pcj));
+               TupleExpr te = jsm.getQuery();
+               Assert.assertEquals(new HashSet<QueryModelNode>(), 
jsm.getUnmatchedArgs());
+
+               Set<QueryModelNode> qNodes = QueryNodeGatherer.getNodes(te);
+               List<QueryModelNode> nodes = jsm.getOrderedNodes();
+               Set<QueryModelNode> nodeSet = new HashSet<>();
+               nodeSet.add(nodes.get(0));
+               nodeSet.add(pcj);
+
+               Assert.assertEquals(nodeSet, new 
HashSet<QueryModelNode>(nodes));
+               Assert.assertEquals(nodeSet, qNodes);
+
+       }
+
+
+       @Test
+       public void testBasicMatchWithFilter() throws Exception {
+
+               String query1 = ""//
+                               + "SELECT ?e ?c ?l" //
+                               + "{" //
+                               + " Filter(?e = <uri:Bob>)" //
+                               + " Filter(?c = <uri:Lawyer>)" //
+                               + "  ?e 
<http://www.w3.org/2000/01/rdf-schema#label> ?l . "//
+                               + "  ?e a ?c . "//
+                               + "  ?e <uri:talksTo> ?l  . "//
+                               + "}";//
+
+               String query2 = ""//
+                               + "SELECT ?e ?c ?l" //
+                               + "{" //
+                               + " Filter(?e = <uri:Bob>)" //
+                               + " ?e a ?c . "//
+                               + " ?e <uri:talksTo> ?l . "//
+                               + "}";//
+
+               SPARQLParser parser = new SPARQLParser();
+               ParsedQuery pq1 = parser.parseQuery(query1, null);
+               ParsedQuery pq2 = parser.parseQuery(query2, null);
+               TupleExpr te1 = pq1.getTupleExpr();
+               TupleExpr te2 = pq2.getTupleExpr();
+               Projection proj = (Projection) te1;
+               Filter filter = (Filter) proj.getArg();
+
+               JoinSegmentPCJMatcher jsm = new JoinSegmentPCJMatcher(filter);
+               SimpleExternalTupleSet pcj = new 
SimpleExternalTupleSet((Projection)te2);
+               Assert.assertEquals(true, jsm.matchPCJ(pcj));
+               TupleExpr te = jsm.getQuery();
+               Assert.assertEquals(new HashSet<QueryModelNode>(), 
jsm.getUnmatchedArgs());
+
+               Set<QueryModelNode> qNodes = QueryNodeGatherer.getNodes(te);
+               List<QueryModelNode> nodes = jsm.getOrderedNodes();
+               Set<QueryModelNode> nodeSet = new HashSet<>();
+               nodeSet.add(nodes.get(0));
+               nodeSet.add(pcj);
+               nodeSet.add(nodes.get(1));
+
+               Assert.assertEquals(nodeSet, new 
HashSet<QueryModelNode>(nodes));
+               Assert.assertEquals(nodeSet, qNodes);
+
+       }
+
+
+
+       @Test
+       public void testWithUnmatchedNodes() throws Exception {
+
+               String query1 = ""//
+                               + "SELECT ?e ?c ?l" //
+                               + "{" //
+                               + " Filter(?e = <uri:Bob>)" //
+                               + " Filter(?c = <uri:Lawyer>)" //
+                               + " ?l <uri:workAt> <uri:Company1> ."
+                               + " OPTIONAL { ?e 
<http://www.w3.org/2000/01/rdf-schema#label> ?l } . "//
+                               + "  ?e a ?c . "//
+                               + "  ?e <uri:talksTo> ?l  . "//
+                               + "}";//
+
+               String query2 = ""//
+                               + "SELECT ?e ?c ?l" //
+                               + "{" //
+                               + " Filter(?e = <uri:Bob>)" //
+                               + " ?e a ?c . "//
+                               + " ?e <uri:talksTo> ?l . "//
+                               + "}";//
+
+               SPARQLParser parser = new SPARQLParser();
+               ParsedQuery pq1 = parser.parseQuery(query1, null);
+               ParsedQuery pq2 = parser.parseQuery(query2, null);
+               TupleExpr te1 = pq1.getTupleExpr();
+               TupleExpr te2 = pq2.getTupleExpr();
+               Projection proj = (Projection) te1;
+               Join join = (Join) proj.getArg();
+
+               JoinSegmentPCJMatcher jsm = new JoinSegmentPCJMatcher(join);
+               SimpleExternalTupleSet pcj = new 
SimpleExternalTupleSet((Projection)te2);
+               Assert.assertEquals(true, jsm.matchPCJ(pcj));
+               TupleExpr te = jsm.getQuery();
+
+
+               Set<QueryModelNode> qNodes = QueryNodeGatherer.getNodes(te);
+               List<QueryModelNode> nodes = jsm.getOrderedNodes();
+               Set<QueryModelNode> nodeSet = new HashSet<>();
+               nodeSet.add(nodes.get(0));
+               nodeSet.add(nodes.get(1));
+               nodeSet.add(pcj);
+
+               Assert.assertEquals(1, jsm.getUnmatchedArgs().size());
+               Assert.assertEquals(true, 
jsm.getUnmatchedArgs().contains(nodes.get(1)));
+
+               Assert.assertEquals(nodeSet, new 
HashSet<QueryModelNode>(nodes));
+               Assert.assertEquals(nodeSet, qNodes);
+
+       }
+
+
+
+
+
+       static class QueryNodeGatherer extends 
QueryModelVisitorBase<RuntimeException> {
+
+               private static Set<QueryModelNode> nodes;
+
+               public static Set<QueryModelNode> getNodes(TupleExpr te) {
+                       nodes = new HashSet<>();
+                       te.visit(new QueryNodeGatherer());
+                       return nodes;
+               }
+
+
+               @Override
+               public void meetNode(QueryModelNode node) {
+                       if(node instanceof ExternalTupleSet) {
+                               nodes.add(node);
+                       }
+                       super.meetNode(node);
+               }
+
+               @Override
+               public void meet(StatementPattern node) {
+                       nodes.add(node);
+               }
+
+               @Override
+               public void meet(Filter node) {
+                       nodes.add(node.getCondition());
+                       super.meet(node);
+               }
+
+               @Override
+               public void meet(LeftJoin node) {
+                       nodes.add(node);
+               }
+
+       }
+
+
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/96dd55ec/extras/indexing/src/test/java/mvm/rya/indexing/pcj/matching/JoinSegmentTest.java
----------------------------------------------------------------------
diff --git 
a/extras/indexing/src/test/java/mvm/rya/indexing/pcj/matching/JoinSegmentTest.java
 
b/extras/indexing/src/test/java/mvm/rya/indexing/pcj/matching/JoinSegmentTest.java
new file mode 100644
index 0000000..2169ebc
--- /dev/null
+++ 
b/extras/indexing/src/test/java/mvm/rya/indexing/pcj/matching/JoinSegmentTest.java
@@ -0,0 +1,204 @@
+package mvm.rya.indexing.pcj.matching;
+
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import mvm.rya.indexing.external.tupleSet.SimpleExternalTupleSet;
+
+import org.junit.Assert;
+import org.junit.Test;
+import org.openrdf.query.MalformedQueryException;
+import org.openrdf.query.algebra.Filter;
+import org.openrdf.query.algebra.Join;
+import org.openrdf.query.algebra.Projection;
+import org.openrdf.query.algebra.QueryModelNode;
+import org.openrdf.query.algebra.TupleExpr;
+import org.openrdf.query.parser.ParsedQuery;
+import org.openrdf.query.parser.sparql.SPARQLParser;
+
+public class JoinSegmentTest {
+
+
+       @Test
+       public void testBasicSegment() throws MalformedQueryException {
+
+               String query1 = ""//
+                               + "SELECT ?e ?c ?l" //
+                               + "{" //
+                               + "  ?e a ?c . "//
+                               + "  ?e <uri:talksTo> ?l  . "//
+                               + "  ?e 
<http://www.w3.org/2000/01/rdf-schema#label> ?l "//
+                               + "}";//
+
+               String query2 = ""//
+                               + "SELECT ?e ?c ?l" //
+                               + "{" //
+                               + "  ?e a ?c . "//
+                               + "  ?e <uri:talksTo> ?l  . "//
+                               + "}";//
+
+               SPARQLParser parser = new SPARQLParser();
+               ParsedQuery pq1 = parser.parseQuery(query1, null);
+               ParsedQuery pq2 = parser.parseQuery(query2, null);
+               TupleExpr te1 = pq1.getTupleExpr();
+               TupleExpr te2 = pq2.getTupleExpr();
+               Join join1 = (Join) ((Projection) te1).getArg();
+               Join join2 = (Join) ((Projection) te2).getArg();
+
+               OptionalJoinSegment seg1 = new OptionalJoinSegment(join1);
+               OptionalJoinSegment seg2 = new OptionalJoinSegment(join2);
+
+               Assert.assertEquals(true, seg1.containsQuerySegment(seg2));
+               Assert.assertEquals(join1, seg1.getQuery().getTupleExpr());
+               Assert.assertEquals(join2, seg2.getQuery().getTupleExpr());
+
+               SimpleExternalTupleSet pcj = new 
SimpleExternalTupleSet((Projection)te2);
+               List<QueryModelNode> nodes = seg1.getOrderedNodes();
+               QueryModelNode node = nodes.get(0);
+               seg1.replaceWithPcj(seg2, pcj);
+
+               Set<QueryModelNode> nodeSet = new HashSet<>();
+               nodeSet.add(node);
+               nodeSet.add(pcj);
+
+               Assert.assertEquals(nodeSet, seg1.getUnOrderedNodes());
+
+       }
+
+
+       @Test
+       public void testBasicMatchWithFilter() throws Exception {
+
+               String query1 = ""//
+                               + "SELECT ?e ?c ?l" //
+                               + "{" //
+                               + " Filter(?e = <uri:Bob>)" //
+                               + "  ?e 
<http://www.w3.org/2000/01/rdf-schema#label> ?l . "//
+                               + "  ?e a ?c . "//
+                               + "  ?e <uri:talksTo> ?l  . "//
+                               + "}";//
+
+               String query2 = ""//
+                               + "SELECT ?e ?c ?l" //
+                               + "{" //
+                               + " Filter(?e = <uri:Bob>)" //
+                               + " ?e a ?c . "//
+                               + " ?e <uri:talksTo> ?l . "//
+                               + "}";//
+
+               SPARQLParser parser = new SPARQLParser();
+               ParsedQuery pq1 = parser.parseQuery(query1, null);
+               ParsedQuery pq2 = parser.parseQuery(query2, null);
+               TupleExpr te1 = pq1.getTupleExpr();
+               TupleExpr te2 = pq2.getTupleExpr();
+               TopOfQueryFilterRelocator.moveFiltersToTop(te1);
+               TopOfQueryFilterRelocator.moveFiltersToTop(te1);
+               Filter filter1 = (Filter) ((Projection) te1).getArg();
+               Filter filter2 = (Filter) ((Projection) te2).getArg();
+
+               OptionalJoinSegment seg1 = new OptionalJoinSegment(filter1);
+               OptionalJoinSegment seg2 = new OptionalJoinSegment(filter2);
+
+               Assert.assertEquals(filter1, seg1.getQuery().getTupleExpr());
+               Assert.assertEquals(filter2, seg2.getQuery().getTupleExpr());
+               Assert.assertEquals(true, seg1.containsQuerySegment(seg2));
+
+               SimpleExternalTupleSet pcj = new 
SimpleExternalTupleSet((Projection)te2);
+               List<QueryModelNode> nodes = seg1.getOrderedNodes();
+               QueryModelNode node = nodes.get(3);
+               seg1.replaceWithPcj(seg2, pcj);
+
+               Set<QueryModelNode> nodeSet = new HashSet<>();
+               nodeSet.add(node);
+               nodeSet.add(pcj);
+
+               Assert.assertEquals(nodeSet, seg1.getUnOrderedNodes());
+
+       }
+
+
+
+       @Test
+       public void testNoMatch() throws Exception {
+
+               String query1 = ""//
+                               + "SELECT ?e ?c ?l" //
+                               + "{" //
+                               + " Filter(?e = <uri:Bob>)" //
+                               + "  ?e 
<http://www.w3.org/2000/01/rdf-schema#label> ?l . "//
+                               + "  ?e a ?c . "//
+                               + "  ?e <uri:talksTo> ?l  . "//
+                               + "}";//
+
+               String query2 = ""//
+                               + "SELECT ?e ?c ?l" //
+                               + "{" //
+                               + " Filter(?e = <uri:Bob>)" //
+                               + " ?e a ?c . "//
+                               + " ?e <uri:worksAt> ?l . "//
+                               + "}";//
+
+               SPARQLParser parser = new SPARQLParser();
+               ParsedQuery pq1 = parser.parseQuery(query1, null);
+               ParsedQuery pq2 = parser.parseQuery(query2, null);
+               TupleExpr te1 = pq1.getTupleExpr();
+               TupleExpr te2 = pq2.getTupleExpr();
+               TopOfQueryFilterRelocator.moveFiltersToTop(te1);
+               TopOfQueryFilterRelocator.moveFiltersToTop(te1);
+               Filter filter1 = (Filter) ((Projection) te1).getArg();
+               Filter filter2 = (Filter) ((Projection) te2).getArg();
+
+               OptionalJoinSegment seg1 = new OptionalJoinSegment(filter1);
+               OptionalJoinSegment seg2 = new OptionalJoinSegment(filter2);
+
+               Assert.assertEquals(false, seg1.containsQuerySegment(seg2));
+
+       }
+
+
+
+       @Test
+       public void testNoMatchTooLarge() throws Exception {
+
+               String query1 = ""//
+                               + "SELECT ?e ?c ?l" //
+                               + "{" //
+                               + "  ?e 
<http://www.w3.org/2000/01/rdf-schema#label> ?l . "//
+                               + "  ?e a ?c . "//
+                               + "  ?e <uri:talksTo> ?l  . "//
+                               + "}";//
+
+               String query2 = ""//
+                               + "SELECT ?e ?c ?l" //
+                               + "{" //
+                               + " ?e a ?c . "//
+                               + " ?e <uri:worksAt> ?l . "//
+                               + "}";//
+
+               SPARQLParser parser = new SPARQLParser();
+               ParsedQuery pq1 = parser.parseQuery(query1, null);
+               ParsedQuery pq2 = parser.parseQuery(query2, null);
+               TupleExpr te1 = pq1.getTupleExpr();
+               TupleExpr te2 = pq2.getTupleExpr();
+               TopOfQueryFilterRelocator.moveFiltersToTop(te1);
+               TopOfQueryFilterRelocator.moveFiltersToTop(te1);
+               Join join1 = (Join) ((Projection) te1).getArg();
+               Join join2 = (Join) ((Projection) te2).getArg();
+
+               OptionalJoinSegment seg1 = new OptionalJoinSegment(join1);
+               OptionalJoinSegment seg2 = new OptionalJoinSegment(join2);
+
+               Assert.assertEquals(false, seg2.containsQuerySegment(seg1));
+
+       }
+
+
+
+
+
+
+
+
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/96dd55ec/extras/indexing/src/test/java/mvm/rya/indexing/pcj/matching/OptionalJoinSegmentPCJMatcherTest.java
----------------------------------------------------------------------
diff --git 
a/extras/indexing/src/test/java/mvm/rya/indexing/pcj/matching/OptionalJoinSegmentPCJMatcherTest.java
 
b/extras/indexing/src/test/java/mvm/rya/indexing/pcj/matching/OptionalJoinSegmentPCJMatcherTest.java
new file mode 100644
index 0000000..1161ad2
--- /dev/null
+++ 
b/extras/indexing/src/test/java/mvm/rya/indexing/pcj/matching/OptionalJoinSegmentPCJMatcherTest.java
@@ -0,0 +1,274 @@
+package mvm.rya.indexing.pcj.matching;
+
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import mvm.rya.indexing.external.tupleSet.ExternalTupleSet;
+import mvm.rya.indexing.external.tupleSet.SimpleExternalTupleSet;
+
+import org.junit.Assert;
+import org.junit.Test;
+import org.openrdf.query.MalformedQueryException;
+import org.openrdf.query.algebra.Filter;
+import org.openrdf.query.algebra.Join;
+import org.openrdf.query.algebra.LeftJoin;
+import org.openrdf.query.algebra.Projection;
+import org.openrdf.query.algebra.QueryModelNode;
+import org.openrdf.query.algebra.StatementPattern;
+import org.openrdf.query.algebra.TupleExpr;
+import org.openrdf.query.algebra.Union;
+import org.openrdf.query.algebra.helpers.QueryModelVisitorBase;
+import org.openrdf.query.parser.ParsedQuery;
+import org.openrdf.query.parser.sparql.SPARQLParser;
+
+public class OptionalJoinSegmentPCJMatcherTest {
+
+
+       @Test
+       public void testBasicSegment() throws MalformedQueryException {
+
+               String query1 = ""//
+                               + "SELECT ?e ?c ?l" //
+                               + "{" //
+                               + "  ?e a ?c . "//
+                               + "  OPTIONAL {?e <uri:talksTo> ?l}  . "//
+                               + "  ?e 
<http://www.w3.org/2000/01/rdf-schema#label> ?l "//
+                               + "}";//
+
+               String query2 = ""//
+                               + "SELECT ?e ?c ?l" //
+                               + "{" //
+                               + "  ?e a ?c . "//
+                               + "  OPTIONAL {?e <uri:talksTo> ?l}  . "//
+                               + "}";//
+
+               SPARQLParser parser = new SPARQLParser();
+               ParsedQuery pq1 = parser.parseQuery(query1, null);
+               ParsedQuery pq2 = parser.parseQuery(query2, null);
+               TupleExpr te1 = pq1.getTupleExpr();
+               TupleExpr te2 = pq2.getTupleExpr();
+               Projection proj = (Projection) te1;
+               Join join = (Join) proj.getArg();
+
+               OptionalJoinSegmentPCJMatcher jsm = new 
OptionalJoinSegmentPCJMatcher(join);
+               SimpleExternalTupleSet pcj = new 
SimpleExternalTupleSet((Projection)te2);
+               Assert.assertEquals(true, jsm.matchPCJ(pcj));
+               TupleExpr te = jsm.getQuery();
+               Assert.assertEquals(new HashSet<QueryModelNode>(), 
jsm.getUnmatchedArgs());
+
+               Set<QueryModelNode> qNodes = 
LeftJoinQueryNodeGatherer.getNodes(te);
+               List<QueryModelNode> nodes = jsm.getOrderedNodes();
+               Set<QueryModelNode> nodeSet = new HashSet<>();
+               nodeSet.add(nodes.get(0));
+               nodeSet.add(pcj);
+
+               Assert.assertEquals(nodeSet, new 
HashSet<QueryModelNode>(nodes));
+               Assert.assertEquals(nodeSet, qNodes);
+
+       }
+
+
+       @Test
+       public void testBasicMatchWithFilter() throws Exception {
+
+               String query1 = ""//
+                               + "SELECT ?e ?c ?l" //
+                               + "{" //
+                               + " Filter(?e = <uri:Bob>)" //
+                               + " Filter(?c = <uri:Lawyer>)" //
+                               + "  ?e 
<http://www.w3.org/2000/01/rdf-schema#label> ?l . "//
+                               + "  ?e a ?c . "//
+                               + "  OPTIONAL {?e <uri:talksTo> ?l}  . "//
+                               + "}";//
+
+               String query2 = ""//
+                               + "SELECT ?e ?c ?l" //
+                               + "{" //
+                               + " Filter(?e = <uri:Bob>)" //
+                               + " ?e a ?c . "//
+                               + " OPTIONAL {?e <uri:talksTo> ?l} . "//
+                               + "}";//
+
+               SPARQLParser parser = new SPARQLParser();
+               ParsedQuery pq1 = parser.parseQuery(query1, null);
+               ParsedQuery pq2 = parser.parseQuery(query2, null);
+               TupleExpr te1 = pq1.getTupleExpr();
+               TupleExpr te2 = pq2.getTupleExpr();
+               Projection proj = (Projection) te1;
+               Filter filter = (Filter) proj.getArg();
+
+               OptionalJoinSegmentPCJMatcher jsm = new 
OptionalJoinSegmentPCJMatcher(filter);
+               SimpleExternalTupleSet pcj = new 
SimpleExternalTupleSet((Projection)te2);
+               Assert.assertEquals(true, jsm.matchPCJ(pcj));
+               TupleExpr te = jsm.getQuery();
+               Assert.assertEquals(new HashSet<QueryModelNode>(), 
jsm.getUnmatchedArgs());
+
+               Set<QueryModelNode> qNodes = 
LeftJoinQueryNodeGatherer.getNodes(te);
+               List<QueryModelNode> nodes = jsm.getOrderedNodes();
+               Set<QueryModelNode> nodeSet = new HashSet<>();
+               nodeSet.add(nodes.get(0));
+               nodeSet.add(pcj);
+               nodeSet.add(nodes.get(2));
+
+               Assert.assertEquals(nodeSet, new 
HashSet<QueryModelNode>(nodes));
+               Assert.assertEquals(nodeSet, qNodes);
+
+       }
+
+
+
+       @Test
+       public void testMultipleFilters() throws Exception {
+
+               String query1 = ""//
+                               + "SELECT ?e ?c ?l" //
+                               + "{" //
+                               + " Filter(?e = <uri:Bob>)" //
+                               + " Filter(?c = <uri:Lawyer>)" //
+                               + " ?l <uri:workAt> <uri:Company1> ."
+                               + " OPTIONAL { ?e 
<http://www.w3.org/2000/01/rdf-schema#label> ?l } . "//
+                               + "  ?e a ?c . "//
+                               + "  ?e <uri:talksTo> ?l  . "//
+                               + "}";//
+
+               String query2 = ""//
+                               + "SELECT ?e ?c ?l" //
+                               + "{" //
+                               + " Filter(?e = <uri:Bob>)" //
+                               + " ?e a ?c . "//
+                               + " ?e <uri:talksTo> ?l . "//
+                               + "}";//
+
+               SPARQLParser parser = new SPARQLParser();
+               ParsedQuery pq1 = parser.parseQuery(query1, null);
+               ParsedQuery pq2 = parser.parseQuery(query2, null);
+               TupleExpr te1 = pq1.getTupleExpr();
+               TupleExpr te2 = pq2.getTupleExpr();
+               Projection proj = (Projection) te1;
+               Join join = (Join) proj.getArg();
+
+               OptionalJoinSegmentPCJMatcher jsm = new 
OptionalJoinSegmentPCJMatcher(join);
+               SimpleExternalTupleSet pcj = new 
SimpleExternalTupleSet((Projection)te2);
+               Assert.assertEquals(true, jsm.matchPCJ(pcj));
+               TupleExpr te = jsm.getQuery();
+               Assert.assertEquals(new HashSet<QueryModelNode>(), 
jsm.getUnmatchedArgs());
+
+               Set<QueryModelNode> qNodes = 
LeftJoinQueryNodeGatherer.getNodes(te);
+               List<QueryModelNode> nodes = jsm.getOrderedNodes();
+               Set<QueryModelNode> nodeSet = new HashSet<>();
+               nodeSet.add(nodes.get(0));
+               nodeSet.add(nodes.get(2));
+               nodeSet.add(nodes.get(3));
+               nodeSet.add(pcj);
+
+               Assert.assertEquals(nodeSet, new 
HashSet<QueryModelNode>(nodes));
+               Assert.assertEquals(nodeSet, qNodes);
+
+       }
+
+
+
+       @Test
+       public void testWithUnmatchedNodes() throws Exception {
+
+               String query1 = ""//
+                               + "SELECT ?a ?b ?c ?d ?e" //
+                               + "{" //
+                               + " Filter(?a = <uri:s1>)" //
+                               + " Filter(?b = <uri:s2>)" //
+                               + " {?e <uri:p3> <uri:o2> } UNION {?d <uri:p4> 
<uri:o3>} ."
+                               + " ?a <uri:workAt> <uri:Company1> ."
+                               + "  ?b <uri:talksTo> ?c  . "//
+                               + " OPTIONAL { ?b <uri:p1> ?c } . "//
+                               + "  ?b <uri:p2> <uri:o1> . "//
+                               + "}";//
+
+               String query2 = ""//
+                               + "SELECT ?e ?c ?l" //
+                               + "{" //
+                               + "  ?b <uri:talksTo> ?c  . "//
+                               + " OPTIONAL { ?b <uri:p1> ?c } . "//
+                               + "  ?b <uri:p2> <uri:o1> . "//
+                               + " Filter(?b = <uri:s2>)" //
+                               + "}";//
+
+               SPARQLParser parser = new SPARQLParser();
+               ParsedQuery pq1 = parser.parseQuery(query1, null);
+               ParsedQuery pq2 = parser.parseQuery(query2, null);
+               TupleExpr te1 = pq1.getTupleExpr();
+               TupleExpr te2 = pq2.getTupleExpr();
+               Projection proj = (Projection) te1;
+               Join join = (Join) proj.getArg();
+
+               OptionalJoinSegmentPCJMatcher jsm = new 
OptionalJoinSegmentPCJMatcher(join);
+               SimpleExternalTupleSet pcj = new 
SimpleExternalTupleSet((Projection)te2);
+               Assert.assertEquals(true, jsm.matchPCJ(pcj));
+               TupleExpr te = jsm.getQuery();
+               Set<QueryModelNode> qNodes = 
LeftJoinQueryNodeGatherer.getNodes(te);
+               List<QueryModelNode> nodes = jsm.getOrderedNodes();
+
+               Assert.assertEquals(1, jsm.getUnmatchedArgs().size());
+               Assert.assertEquals(true, 
jsm.getUnmatchedArgs().contains(nodes.get(3)));
+
+               Set<QueryModelNode> nodeSet = new HashSet<>();
+               nodeSet.add(nodes.get(0));
+               nodeSet.add(nodes.get(2));
+               nodeSet.add(nodes.get(3));
+               nodeSet.add(pcj);
+
+               Assert.assertEquals(nodeSet, new 
HashSet<QueryModelNode>(nodes));
+               Assert.assertEquals(nodeSet, qNodes);
+
+       }
+
+
+
+
+       static class LeftJoinQueryNodeGatherer extends 
QueryModelVisitorBase<RuntimeException> {
+
+               private static Set<QueryModelNode> nodes;
+
+               public static Set<QueryModelNode> getNodes(TupleExpr te) {
+                       nodes = new HashSet<>();
+                       te.visit(new LeftJoinQueryNodeGatherer());
+                       return nodes;
+               }
+
+               @Override
+               public void meetNode(QueryModelNode node) {
+                       if(node instanceof ExternalTupleSet) {
+                               nodes.add(node);
+                       }
+                       super.meetNode(node);
+               }
+
+               @Override
+               public void meet(StatementPattern node) {
+                       nodes.add(node);
+               }
+
+               @Override
+               public void meet(Filter node) {
+                       nodes.add(node.getCondition());
+                       super.meet(node);
+               }
+
+               @Override
+               public void meet(LeftJoin node) {
+                       nodes.add(new FlattenedOptional(node));
+                       node.getLeftArg().visit(this);
+               }
+
+               @Override
+               public void meet(Union node) {
+                       nodes.add(node);
+               }
+
+
+       }
+
+
+
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/96dd55ec/extras/indexing/src/test/java/mvm/rya/indexing/pcj/matching/OptionalJoinSegmentTest.java
----------------------------------------------------------------------
diff --git 
a/extras/indexing/src/test/java/mvm/rya/indexing/pcj/matching/OptionalJoinSegmentTest.java
 
b/extras/indexing/src/test/java/mvm/rya/indexing/pcj/matching/OptionalJoinSegmentTest.java
new file mode 100644
index 0000000..ec3d919
--- /dev/null
+++ 
b/extras/indexing/src/test/java/mvm/rya/indexing/pcj/matching/OptionalJoinSegmentTest.java
@@ -0,0 +1,122 @@
+package mvm.rya.indexing.pcj.matching;
+
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import mvm.rya.indexing.external.tupleSet.SimpleExternalTupleSet;
+
+import org.junit.Assert;
+import org.junit.Test;
+import org.openrdf.query.MalformedQueryException;
+import org.openrdf.query.algebra.Filter;
+import org.openrdf.query.algebra.Join;
+import org.openrdf.query.algebra.LeftJoin;
+import org.openrdf.query.algebra.Projection;
+import org.openrdf.query.algebra.QueryModelNode;
+import org.openrdf.query.algebra.TupleExpr;
+import org.openrdf.query.parser.ParsedQuery;
+import org.openrdf.query.parser.sparql.SPARQLParser;
+
+public class OptionalJoinSegmentTest {
+
+
+
+       @Test
+       public void testBasicOptional() throws MalformedQueryException {
+
+               String query1 = ""//
+                               + "SELECT ?e ?c ?l" //
+                               + "{" //
+                               + "  ?e a ?c . "//
+                               + "  OPTIONAL{?e <uri:talksTo> ?l } . "//
+                               + "  ?e 
<http://www.w3.org/2000/01/rdf-schema#label> ?l "//
+                               + "}";//
+
+               String query2 = ""//
+                               + "SELECT ?e ?c ?l" //
+                               + "{" //
+                               + "  ?e a ?c . "//
+                               + "  OPTIONAL{?e <uri:talksTo> ?l } . "//
+                               + "}";//
+
+               SPARQLParser parser = new SPARQLParser();
+               ParsedQuery pq1 = parser.parseQuery(query1, null);
+               ParsedQuery pq2 = parser.parseQuery(query2, null);
+               TupleExpr te1 = pq1.getTupleExpr();
+               TupleExpr te2 = pq2.getTupleExpr();
+               Join join = (Join) ((Projection) te1).getArg();
+               LeftJoin lj = (LeftJoin) ((Projection) te2).getArg();
+
+               OptionalJoinSegment seg1 = new OptionalJoinSegment(join);
+               OptionalJoinSegment seg2 = new OptionalJoinSegment(lj);
+
+               Assert.assertEquals(true, seg1.containsQuerySegment(seg2));
+               Assert.assertEquals(join, seg1.getQuery().getTupleExpr());
+
+               SimpleExternalTupleSet pcj = new 
SimpleExternalTupleSet((Projection)te2);
+               List<QueryModelNode> nodes = seg1.getOrderedNodes();
+               QueryModelNode node = nodes.get(0);
+               seg1.replaceWithPcj(seg2, pcj);
+
+               Set<QueryModelNode> nodeSet = new HashSet<>();
+               nodeSet.add(node);
+               nodeSet.add(pcj);
+
+               Assert.assertEquals(nodeSet, seg1.getUnOrderedNodes());
+
+       }
+
+
+       @Test
+       public void testBasicOptionalWithFilter() throws Exception {
+
+               String query1 = ""//
+                               + "SELECT ?e ?c ?l" //
+                               + "{" //
+                               + " Filter(?e = <uri:Bob>)" //
+                               + "  ?e 
<http://www.w3.org/2000/01/rdf-schema#label> ?l . "//
+                               + "  ?e a ?c . "//
+                               + "  OPTIONAL{?e <uri:talksTo> ?l } . "//
+                               + "}";//
+
+               String query2 = ""//
+                               + "SELECT ?e ?c ?l" //
+                               + "{" //
+                               + " Filter(?e = <uri:Bob>)" //
+                               + "  ?e a ?c . "//
+                               + "  OPTIONAL{?e <uri:talksTo> ?l } . "//
+                               + "}";//
+
+               SPARQLParser parser = new SPARQLParser();
+               ParsedQuery pq1 = parser.parseQuery(query1, null);
+               ParsedQuery pq2 = parser.parseQuery(query2, null);
+               TupleExpr te1 = pq1.getTupleExpr();
+               TupleExpr te2 = pq2.getTupleExpr();
+               TopOfQueryFilterRelocator.moveFiltersToTop(te1);
+               Filter filter1 = (Filter) ((Projection) te1).getArg();
+               Filter filter2 = (Filter) ((Projection) te2).getArg();
+
+               OptionalJoinSegment seg1 = new OptionalJoinSegment(filter1);
+               OptionalJoinSegment seg2 = new OptionalJoinSegment(filter2);
+
+               Assert.assertEquals(filter1, seg1.getQuery().getTupleExpr());
+               Assert.assertEquals(true, seg1.containsQuerySegment(seg2));
+
+               SimpleExternalTupleSet pcj = new 
SimpleExternalTupleSet((Projection)te2);
+               List<QueryModelNode> nodes = seg1.getOrderedNodes();
+               QueryModelNode node = nodes.get(3);
+               seg1.replaceWithPcj(seg2, pcj);
+
+               Set<QueryModelNode> nodeSet = new HashSet<>();
+               nodeSet.add(node);
+               nodeSet.add(pcj);
+
+               Assert.assertEquals(nodeSet, seg1.getUnOrderedNodes());
+
+       }
+
+
+
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/96dd55ec/extras/indexing/src/test/java/mvm/rya/indexing/pcj/matching/PCJNodeConsolidatorTest.java
----------------------------------------------------------------------
diff --git 
a/extras/indexing/src/test/java/mvm/rya/indexing/pcj/matching/PCJNodeConsolidatorTest.java
 
b/extras/indexing/src/test/java/mvm/rya/indexing/pcj/matching/PCJNodeConsolidatorTest.java
new file mode 100644
index 0000000..993140c
--- /dev/null
+++ 
b/extras/indexing/src/test/java/mvm/rya/indexing/pcj/matching/PCJNodeConsolidatorTest.java
@@ -0,0 +1,459 @@
+package mvm.rya.indexing.pcj.matching;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.junit.Assert;
+import org.junit.Test;
+import org.openrdf.query.algebra.Filter;
+import org.openrdf.query.algebra.Join;
+import org.openrdf.query.algebra.LeftJoin;
+import org.openrdf.query.algebra.Projection;
+import org.openrdf.query.algebra.QueryModelNode;
+import org.openrdf.query.algebra.TupleExpr;
+import org.openrdf.query.parser.ParsedQuery;
+import org.openrdf.query.parser.sparql.SPARQLParser;
+
+public class PCJNodeConsolidatorTest {
+
+
+       @Test
+       public void testBasicOptionalWithFilter() throws Exception {
+
+               String query1 = ""//
+                               + "SELECT ?e ?c ?l" //
+                               + "{" //
+                               + "  Filter(?e = <uri:Bob>)" //
+                               + "  ?e 
<http://www.w3.org/2000/01/rdf-schema#label> ?l . "//
+                               + "  OPTIONAL{?e <uri:talksTo> ?l } . "//
+                               + "  OPTIONAL{?c <uri:worksAt> <uri:Apple>} . " 
//
+                               + "  ?e a ?c . "//
+                               + "  ?e <uri:livesIn> <uri:Virginia>"
+                               + "}";//
+
+               String query2 = ""//
+                               + "SELECT ?e ?c ?l" //
+                               + "{" //
+                               + " Filter(?e = <uri:Bob>)" //
+                               + "  ?e a ?c . "//
+                               + "  OPTIONAL{?e <uri:talksTo> ?l } . "//
+                               + "}";//
+
+               SPARQLParser parser = new SPARQLParser();
+               ParsedQuery pq1 = parser.parseQuery(query1, null);
+               ParsedQuery pq2 = parser.parseQuery(query2, null);
+               TupleExpr te1 = pq1.getTupleExpr();
+               TupleExpr te2 = pq2.getTupleExpr();
+               TopOfQueryFilterRelocator.moveFiltersToTop(te1);
+               TopOfQueryFilterRelocator.moveFiltersToTop(te2);
+               Filter filter1 = (Filter) ((Projection) te1).getArg();
+               Filter filter2 = (Filter) ((Projection) te2).getArg();
+
+               OptionalJoinSegment seg1 = new OptionalJoinSegment(filter1);
+               OptionalJoinSegment seg2 = new OptionalJoinSegment(filter2);
+
+               PCJNodeConsolidator consolidator = new 
PCJNodeConsolidator(seg1.getOrderedNodes(), seg2.getOrderedNodes());
+
+               List<QueryModelNode> queryNodes = new 
ArrayList<>(seg1.getOrderedNodes());
+               QueryModelNode node = queryNodes.remove(0);
+               queryNodes.add(1,node);
+               node = queryNodes.remove(4);
+               queryNodes.add(2, node);
+
+               Assert.assertTrue(consolidator.consolidateNodes());
+               Assert.assertEquals(consolidator.getQueryNodes(), queryNodes);
+
+       }
+
+
+
+       @Test
+       public void testUpperLowerBoundOptional() throws Exception {
+
+               String query1 = ""//
+                               + "SELECT ?a ?b ?c ?d" //
+                               + "{" //
+                               + "  ?a <uri:p5> <uri:const3>" //
+                               + "  OPTIONAL{<uri:const2> <uri:p4> ?d } . "//
+                               + "  ?a <uri:p4> ?b . "//
+                               + "  OPTIONAL{?a <uri:p3> ?c} . " //
+                               + "  OPTIONAL{<uri:const1> <uri:p2> ?b} . "//
+                               + "  ?c <uri:p1> ?d "
+                               + "}";//
+
+               String query2 = ""//
+                               + "SELECT ?a ?b ?c ?d" //
+                               + "{" //
+                               + "  ?a <uri:p4> ?b . "//
+                               + "  OPTIONAL{<uri:const2> <uri:p4> ?d } . "//
+                               + "  ?c <uri:p1> ?d "
+                               + "}";//
+
+               SPARQLParser parser = new SPARQLParser();
+               ParsedQuery pq1 = parser.parseQuery(query1, null);
+               ParsedQuery pq2 = parser.parseQuery(query2, null);
+               TupleExpr te1 = pq1.getTupleExpr();
+               TupleExpr te2 = pq2.getTupleExpr();
+               Join join1 = (Join) ((Projection) te1).getArg();
+               Join join2 = (Join) ((Projection) te2).getArg();
+
+               OptionalJoinSegment seg1 = new OptionalJoinSegment(join1);
+               OptionalJoinSegment seg2 = new OptionalJoinSegment(join2);
+
+               PCJNodeConsolidator consolidator = new 
PCJNodeConsolidator(seg1.getOrderedNodes(), seg2.getOrderedNodes());
+
+               List<QueryModelNode> queryNodes = new 
ArrayList<>(seg1.getOrderedNodes());
+               QueryModelNode node = queryNodes.remove(0);
+               queryNodes.add(1,node);
+               node = queryNodes.remove(3);
+               queryNodes.add(2, node);
+               node = queryNodes.remove(4);
+               queryNodes.add(2, node);
+
+               Assert.assertTrue(consolidator.consolidateNodes());
+               Assert.assertEquals(consolidator.getQueryNodes(), queryNodes);
+
+       }
+
+
+       @Test
+       public void testAlreadyInOrder() throws Exception {
+
+               String query1 = ""//
+                               + "SELECT ?a ?b ?c ?d" //
+                               + "{" //
+                               + "  ?a <uri:p5> <uri:const3>" //
+                               + "  OPTIONAL{?a <uri:p3> ?c} . " //
+                               + "  ?a <uri:p4> ?b . "//
+                               + "  OPTIONAL{<uri:const2> <uri:p4> ?d } . "//
+                               + "  ?c <uri:p1> ?d "
+                               + "  OPTIONAL{<uri:const1> <uri:p2> ?b} . "//
+                               + "}";//
+
+               String query2 = ""//
+                               + "SELECT ?a ?b ?c ?d" //
+                               + "{" //
+                               + "  ?a <uri:p4> ?b . "//
+                               + "  OPTIONAL{<uri:const2> <uri:p4> ?d } . "//
+                               + "  ?c <uri:p1> ?d "
+                               + "}";//
+
+               SPARQLParser parser = new SPARQLParser();
+               ParsedQuery pq1 = parser.parseQuery(query1, null);
+               ParsedQuery pq2 = parser.parseQuery(query2, null);
+               TupleExpr te1 = pq1.getTupleExpr();
+               TupleExpr te2 = pq2.getTupleExpr();
+               LeftJoin join1 = (LeftJoin) ((Projection) te1).getArg();
+               Join join2 = (Join) ((Projection) te2).getArg();
+
+               OptionalJoinSegment seg1 = new OptionalJoinSegment(join1);
+               OptionalJoinSegment seg2 = new OptionalJoinSegment(join2);
+
+               PCJNodeConsolidator consolidator = new 
PCJNodeConsolidator(seg1.getOrderedNodes(), seg2.getOrderedNodes());
+               List<QueryModelNode> queryNodes = new 
ArrayList<>(seg1.getOrderedNodes());
+
+               Assert.assertTrue(consolidator.consolidateNodes());
+               Assert.assertEquals(consolidator.getQueryNodes(), queryNodes);
+
+       }
+
+
+       @Test
+       public void testInvalidOrder() throws Exception {
+
+               String query1 = ""//
+                               + "SELECT ?a ?b ?c ?d" //
+                               + "{" //
+                               + "  ?a <uri:p5> <uri:const3>" //
+                               + "  OPTIONAL{<uri:const2> <uri:p4> ?d } . "//
+                               + "  ?a <uri:p4> ?b . "//
+                               + "  OPTIONAL{?a <uri:p3> ?c} . " //
+                               + "  OPTIONAL{<uri:const1> <uri:p2> ?b} . "//
+                               + "  ?c <uri:p1> ?d "
+                               + "}";//
+
+               String query2 = ""//
+                               + "SELECT ?a ?b ?c ?d" //
+                               + "{" //
+                               + "  ?a <uri:p4> ?b . "//
+                               + "  ?c <uri:p1> ?d "
+                               + "  OPTIONAL{<uri:const2> <uri:p4> ?d } . "//
+                               + "}";//
+
+               SPARQLParser parser = new SPARQLParser();
+               ParsedQuery pq1 = parser.parseQuery(query1, null);
+               ParsedQuery pq2 = parser.parseQuery(query2, null);
+               TupleExpr te1 = pq1.getTupleExpr();
+               TupleExpr te2 = pq2.getTupleExpr();
+               Join join1 = (Join) ((Projection) te1).getArg();
+               LeftJoin join2 = (LeftJoin) ((Projection) te2).getArg();
+
+               OptionalJoinSegment seg1 = new OptionalJoinSegment(join1);
+               OptionalJoinSegment seg2 = new OptionalJoinSegment(join2);
+
+               PCJNodeConsolidator consolidator = new 
PCJNodeConsolidator(seg1.getOrderedNodes(), seg2.getOrderedNodes());
+
+               Assert.assertTrue(!consolidator.consolidateNodes());
+       }
+
+
+
+       @Test
+       public void testCantConsolidate() throws Exception {
+
+               String query1 = ""//
+                               + "SELECT ?a ?b ?c" //
+                               + "{" //
+                               + "  ?c <uri:p5> <uri:o2> ." //
+                               + "  ?a <uri:p4> <uri:o1> . "//
+                               + "  OPTIONAL{?a <uri:p3> ?b} . " //
+                               + "  OPTIONAL{<uri:s2> <uri:p2> ?b} . "//
+                               + "  <uri:s1> <uri:p1> ?b "
+                               + "}";//
+
+               String query2 = ""//
+                               + "SELECT ?a ?b" //
+                               + "{" //
+                               + "  <uri:s1> <uri:p1> ?b . "//
+                               + "  ?a <uri:p4> <uri:o1> "
+                               + "}";//
+
+               SPARQLParser parser = new SPARQLParser();
+               ParsedQuery pq1 = parser.parseQuery(query1, null);
+               ParsedQuery pq2 = parser.parseQuery(query2, null);
+               TupleExpr te1 = pq1.getTupleExpr();
+               TupleExpr te2 = pq2.getTupleExpr();
+               Join join1 = (Join) ((Projection) te1).getArg();
+               Join join2 = (Join) ((Projection) te2).getArg();
+
+               OptionalJoinSegment seg1 = new OptionalJoinSegment(join1);
+               OptionalJoinSegment seg2 = new OptionalJoinSegment(join2);
+
+               PCJNodeConsolidator consolidator = new 
PCJNodeConsolidator(seg1.getOrderedNodes(), seg2.getOrderedNodes());
+
+               Assert.assertTrue(!consolidator.consolidateNodes());
+       }
+
+
+       @Test
+       public void testMoveAcrossMultipleLeftJoins() throws Exception {
+
+               String query1 = ""//
+                               + "SELECT ?a ?b ?c ?e ?f" //
+                               + "{" //
+                               + "  ?c <uri:p5> <uri:o2> ." //
+                               + "  ?a <uri:p4> <uri:o1> . "//
+                               + "  OPTIONAL{?a <uri:p3> ?b} . " //
+                               + "  OPTIONAL{<uri:s2> <uri:p2> ?e} . "//
+                               + "  OPTIONAL{<uri:s2> <uri:p2> ?f} . "//
+                               + "  <uri:s1> <uri:p1> ?f "
+                               + "}";//
+
+               String query2 = ""//
+                               + "SELECT ?f ?c" //
+                               + "{" //
+                               + "  ?c <uri:p5> <uri:o2> . "//
+                               + "  <uri:s1> <uri:p1> ?f "
+                               + "}";//
+
+               SPARQLParser parser = new SPARQLParser();
+               ParsedQuery pq1 = parser.parseQuery(query1, null);
+               ParsedQuery pq2 = parser.parseQuery(query2, null);
+               TupleExpr te1 = pq1.getTupleExpr();
+               TupleExpr te2 = pq2.getTupleExpr();
+               Join join1 = (Join) ((Projection) te1).getArg();
+               Join join2 = (Join) ((Projection) te2).getArg();
+
+               OptionalJoinSegment seg1 = new OptionalJoinSegment(join1);
+               OptionalJoinSegment seg2 = new OptionalJoinSegment(join2);
+
+               PCJNodeConsolidator consolidator = new 
PCJNodeConsolidator(seg1.getOrderedNodes(), seg2.getOrderedNodes());
+
+               List<QueryModelNode> queryNodes = new 
ArrayList<>(seg1.getOrderedNodes());
+               QueryModelNode node = queryNodes.remove(5);
+               queryNodes.add(1,node);
+
+               Assert.assertTrue(consolidator.consolidateNodes());
+               Assert.assertEquals(consolidator.getQueryNodes(), queryNodes);
+       }
+
+
+
+       @Test
+       public void testExactMatchReOrdered() throws Exception {
+
+               String query1 = ""//
+                               + "SELECT ?a ?b ?c ?d ?e ?f ?g ?h" //
+                               + "{" //
+                               + "  ?a <uri:p0> ?b ." //
+                               + "  OPTIONAL{?b <uri:p2> ?c. ?c <uri:p1> ?d} . 
" //
+                               + "  OPTIONAL{?b <uri:p3> ?e. ?e <uri:p1> ?f} . 
"//
+                               + "  OPTIONAL{?b <uri:p4> ?g. ?g <uri:p1> ?h} . 
"//
+                               + "}";//
+
+               String query2 = ""//
+                               + "SELECT ?a ?b ?c ?d ?e ?f ?g ?h" //
+                               + "{" //
+                               + "  ?a <uri:p0> ?b ." //
+                               + "  OPTIONAL{?b <uri:p2> ?c. ?c <uri:p1> ?d} . 
" //
+                               + "  OPTIONAL{?b <uri:p4> ?g. ?g <uri:p1> ?h} . 
"//
+                               + "  OPTIONAL{?b <uri:p3> ?e. ?e <uri:p1> ?f} . 
"//
+                               + "}";//
+
+               SPARQLParser parser = new SPARQLParser();
+               ParsedQuery pq1 = parser.parseQuery(query1, null);
+               ParsedQuery pq2 = parser.parseQuery(query2, null);
+               TupleExpr te1 = pq1.getTupleExpr();
+               TupleExpr te2 = pq2.getTupleExpr();
+               LeftJoin join1 = (LeftJoin) ((Projection) te1).getArg();
+               LeftJoin join2 = (LeftJoin) ((Projection) te2).getArg();
+
+               OptionalJoinSegment seg1 = new OptionalJoinSegment(join1);
+               OptionalJoinSegment seg2 = new OptionalJoinSegment(join2);
+
+               PCJNodeConsolidator consolidator = new 
PCJNodeConsolidator(seg1.getOrderedNodes(), seg2.getOrderedNodes());
+               List<QueryModelNode> queryNodes = new 
ArrayList<>(seg2.getOrderedNodes());
+
+               Assert.assertTrue(consolidator.consolidateNodes());
+               Assert.assertEquals(consolidator.getQueryNodes(), queryNodes);
+       }
+
+
+       @Test
+       public void testExactMatchLargeReOrdered() throws Exception {
+
+               String query1 = ""//
+                               + "SELECT ?a ?b ?c ?d ?e ?f ?g ?h" //
+                               + "{" //
+                               + "  ?a <uri:p0> ?b ." //
+                               + "  OPTIONAL{?b <uri:p2> ?c. ?c <uri:p1> ?d} . 
" //
+                               + "  OPTIONAL{?b <uri:p3> ?e. ?e <uri:p1> ?f} . 
"//
+                               + "  OPTIONAL{?b <uri:p4> ?g. ?g <uri:p1> ?h} . 
"//
+                               + "  OPTIONAL{?b <uri:p4> ?i. ?i <uri:p1> ?j} . 
"//
+                               + "  OPTIONAL{?b <uri:p4> ?k. ?k <uri:p1> ?l} . 
"//
+                               + "  OPTIONAL{?b <uri:p4> ?m. ?m <uri:p1> ?n} . 
"//
+                               + "  OPTIONAL{?b <uri:p4> ?o. ?o <uri:p1> ?p} . 
"//
+                               + "}";//
+
+               String query2 = ""//
+                               + "SELECT ?a ?b ?c ?d ?e ?f ?g ?h" //
+                               + "{" //
+                               + "  ?a <uri:p0> ?b ." //
+                               + "  OPTIONAL{?b <uri:p4> ?o. ?o <uri:p1> ?p} . 
"//
+                               + "  OPTIONAL{?b <uri:p4> ?g. ?g <uri:p1> ?h} . 
"//
+                               + "  OPTIONAL{?b <uri:p2> ?c. ?c <uri:p1> ?d} . 
" //
+                               + "  OPTIONAL{?b <uri:p4> ?i. ?i <uri:p1> ?j} . 
"//
+                               + "  OPTIONAL{?b <uri:p4> ?m. ?m <uri:p1> ?n} . 
"//
+                               + "  OPTIONAL{?b <uri:p4> ?k. ?k <uri:p1> ?l} . 
"//
+                               + "  OPTIONAL{?b <uri:p3> ?e. ?e <uri:p1> ?f} . 
"//
+                               + "}";//
+
+               SPARQLParser parser = new SPARQLParser();
+               ParsedQuery pq1 = parser.parseQuery(query1, null);
+               ParsedQuery pq2 = parser.parseQuery(query2, null);
+               TupleExpr te1 = pq1.getTupleExpr();
+               TupleExpr te2 = pq2.getTupleExpr();
+               LeftJoin join1 = (LeftJoin) ((Projection) te1).getArg();
+               LeftJoin join2 = (LeftJoin) ((Projection) te2).getArg();
+
+               OptionalJoinSegment seg1 = new OptionalJoinSegment(join1);
+               OptionalJoinSegment seg2 = new OptionalJoinSegment(join2);
+
+               PCJNodeConsolidator consolidator = new 
PCJNodeConsolidator(seg1.getOrderedNodes(), seg2.getOrderedNodes());
+               List<QueryModelNode> queryNodes = new 
ArrayList<>(seg2.getOrderedNodes());
+
+               Assert.assertTrue(consolidator.consolidateNodes());
+               Assert.assertEquals(consolidator.getQueryNodes(), queryNodes);
+       }
+
+
+       @Test
+       public void testSwitchBoundVars() throws Exception {
+
+               String query1 = ""//
+                               + "SELECT ?a ?b " //
+                               + "{" //
+                               + "  ?a <uri:p0> ?b ." //
+                               + " OPTIONAL{ ?a <uri:p1> <uri:o1> } ." //
+                               + " ?a <uri:p2> <uri:o2> " //
+                               + "}";//
+
+               String query2 = ""//
+                               + "SELECT ?a ?b " //
+                               + "{" //
+                               + " ?a <uri:p2> <uri:o2> " //
+                               + " OPTIONAL{ ?a <uri:p1> <uri:o1> } ." //
+                               + "  ?a <uri:p0> ?b ." //
+                               + "}";//
+
+               SPARQLParser parser = new SPARQLParser();
+               ParsedQuery pq1 = parser.parseQuery(query1, null);
+               ParsedQuery pq2 = parser.parseQuery(query2, null);
+               TupleExpr te1 = pq1.getTupleExpr();
+               TupleExpr te2 = pq2.getTupleExpr();
+               Join join1 = (Join) ((Projection) te1).getArg();
+               Join join2 = (Join) ((Projection) te2).getArg();
+
+               OptionalJoinSegment seg1 = new OptionalJoinSegment(join1);
+               OptionalJoinSegment seg2 = new OptionalJoinSegment(join2);
+
+               PCJNodeConsolidator consolidator = new 
PCJNodeConsolidator(seg1.getOrderedNodes(), seg2.getOrderedNodes());
+               List<QueryModelNode> queryNodes = new 
ArrayList<>(seg2.getOrderedNodes());
+
+               Assert.assertTrue(consolidator.consolidateNodes());
+               Assert.assertEquals(consolidator.getQueryNodes(), queryNodes);
+       }
+
+
+
+       @Test
+       public void testSwitchTwoBoundVars() throws Exception {
+
+               String query1 = ""//
+                               + "SELECT ?a ?b ?c " //
+                               + "{" //
+                               + "  ?a <uri:p0> ?c ." //
+                               + "  ?b<uri:p1> ?c ." //
+                               + " OPTIONAL{ ?a <uri:p1> ?b } ." //
+                               + " ?a <uri:p2> <uri:o2>. " //
+                               + " ?b <uri:p3> <uri:o3> " //
+                               + "}";//
+
+               String query2 = ""//
+                               + "SELECT ?a ?b ?c" //
+                               + "{" //
+                               + " ?a <uri:p2> <uri:o2>. " //
+                               + " ?b <uri:p3> <uri:o3>. " //
+                               + " OPTIONAL{ ?a <uri:p1> ?b } ." //
+                               + "  ?a <uri:p0> ?c ." //
+                               + "  ?b<uri:p1> ?c " //
+                               + "}";//
+
+               SPARQLParser parser = new SPARQLParser();
+               ParsedQuery pq1 = parser.parseQuery(query1, null);
+               ParsedQuery pq2 = parser.parseQuery(query2, null);
+               TupleExpr te1 = pq1.getTupleExpr();
+               TupleExpr te2 = pq2.getTupleExpr();
+               Join join1 = (Join) ((Projection) te1).getArg();
+               Join join2 = (Join) ((Projection) te2).getArg();
+
+               OptionalJoinSegment seg1 = new OptionalJoinSegment(join1);
+               OptionalJoinSegment seg2 = new OptionalJoinSegment(join2);
+
+               PCJNodeConsolidator consolidator = new 
PCJNodeConsolidator(seg1.getOrderedNodes(), seg2.getOrderedNodes());
+               List<QueryModelNode> queryNodes = new 
ArrayList<>(seg2.getOrderedNodes());
+
+               Assert.assertTrue(consolidator.consolidateNodes());
+               Assert.assertEquals(consolidator.getQueryNodes(), queryNodes);
+       }
+
+
+
+
+
+
+
+
+
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/96dd55ec/extras/indexing/src/test/java/mvm/rya/indexing/pcj/matching/PCJOptimizerTest.java
----------------------------------------------------------------------
diff --git 
a/extras/indexing/src/test/java/mvm/rya/indexing/pcj/matching/PCJOptimizerTest.java
 
b/extras/indexing/src/test/java/mvm/rya/indexing/pcj/matching/PCJOptimizerTest.java
new file mode 100644
index 0000000..74f5767
--- /dev/null
+++ 
b/extras/indexing/src/test/java/mvm/rya/indexing/pcj/matching/PCJOptimizerTest.java
@@ -0,0 +1,463 @@
+package mvm.rya.indexing.pcj.matching;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import mvm.rya.indexing.external.tupleSet.ExternalTupleSet;
+import mvm.rya.indexing.external.tupleSet.SimpleExternalTupleSet;
+
+import org.junit.Test;
+import org.openrdf.query.MalformedQueryException;
+import org.openrdf.query.algebra.Projection;
+import org.openrdf.query.algebra.TupleExpr;
+import org.openrdf.query.parser.ParsedQuery;
+import org.openrdf.query.parser.sparql.SPARQLParser;
+
+public class PCJOptimizerTest {
+
+       @Test
+       public void testBasicSegment() throws MalformedQueryException {
+
+               String query1 = ""//
+                               + "SELECT ?e ?c ?l" //
+                               + "{" //
+                               + "  ?e a ?c . "//
+                               + "  OPTIONAL {?e <uri:talksTo> ?l}  . "//
+                               + "  ?e 
<http://www.w3.org/2000/01/rdf-schema#label> ?l "//
+                               + "}";//
+
+               String query2 = ""//
+                               + "SELECT ?a ?b ?m" //
+                               + "{" //
+                               + "  ?a a ?b . "//
+                               + "  OPTIONAL {?a <uri:talksTo> ?m}  . "//
+                               + "}";//
+
+               SPARQLParser parser = new SPARQLParser();
+               ParsedQuery pq1 = parser.parseQuery(query1, null);
+               ParsedQuery pq2 = parser.parseQuery(query2, null);
+               TupleExpr te1 = pq1.getTupleExpr();
+               TupleExpr te2 = pq2.getTupleExpr();
+
+               SimpleExternalTupleSet pcj = new SimpleExternalTupleSet(
+                               (Projection) te2);
+               List<ExternalTupleSet> externalList = new ArrayList<>();
+               externalList.add(pcj);
+
+               PCJOptimizer optimizer = new PCJOptimizer(externalList, false);
+               optimizer.optimize(te1, null, null);
+               System.out.println(te1);
+
+               // Assert.assertEquals(true, jsm.matchPCJ(pcj));
+               // TupleExpr te = jsm.getQuery();
+               // Assert.assertEquals(new HashSet<QueryModelNode>(),
+               // jsm.getUnmatchedArgs());
+               //
+               // Set<QueryModelNode> qNodes = 
LeftJoinQueryNodeGatherer.getNodes(te);
+               // List<QueryModelNode> nodes = jsm.getOrderedNodes();
+               // Set<QueryModelNode> nodeSet = new HashSet<>();
+               // nodeSet.add(nodes.get(0));
+               // nodeSet.add(pcj);
+               //
+               // Assert.assertEquals(nodeSet, new 
HashSet<QueryModelNode>(nodes));
+               // Assert.assertEquals(nodeSet, qNodes);
+
+       }
+
+       @Test
+       public void testSegmentWithUnion() throws MalformedQueryException {
+
+               String query1 = ""//
+                               + "SELECT ?e ?c ?l" //
+                               + "{" //
+                               + " {?e <uri:p1> <uri:o1>. } UNION { ?e a ?c. 
OPTIONAL {?e <uri:talksTo> ?l}. ?e <uri:p5> <uri:o4>. ?e <uri:p4> <uri:o3> }  . 
"//
+                               + "  ?e <uri:p2> ?c . "//
+                               + "  ?e <uri:p3> <uri:o2>  . "//
+                               + "}";//
+
+               String query2 = ""//
+                               + "SELECT ?a ?b ?m" //
+                               + "{" //
+                               + " ?a <uri:p5> <uri:o4> ." //
+                               + " ?a <uri:p4> <uri:o3> ." //
+                               + "  OPTIONAL {?a <uri:talksTo> ?m} . "//
+                               + "  ?a a ?b . "//
+                               + "}";//
+
+               String query3 = ""//
+                               + "SELECT ?h ?i" //
+                               + "{" //
+                               + "  ?h <uri:p2> ?i . "//
+                               + "  ?h <uri:p3> <uri:o2>  . "//
+                               + "}";//
+
+               SPARQLParser parser = new SPARQLParser();
+               ParsedQuery pq1 = parser.parseQuery(query1, null);
+               ParsedQuery pq2 = parser.parseQuery(query2, null);
+               ParsedQuery pq3 = parser.parseQuery(query3, null);
+               TupleExpr te1 = pq1.getTupleExpr();
+               TupleExpr te2 = pq2.getTupleExpr();
+               TupleExpr te3 = pq3.getTupleExpr();
+
+               SimpleExternalTupleSet pcj1 = new SimpleExternalTupleSet(
+                               (Projection) te2);
+               SimpleExternalTupleSet pcj2 = new SimpleExternalTupleSet(
+                               (Projection) te3);
+               List<ExternalTupleSet> externalList = new ArrayList<>();
+               externalList.add(pcj1);
+               externalList.add(pcj2);
+
+               PCJOptimizer optimizer = new PCJOptimizer(externalList, false);
+               optimizer.optimize(te1, null, null);
+               System.out.println(te1);
+
+               // Assert.assertEquals(true, jsm.matchPCJ(pcj));
+               // TupleExpr te = jsm.getQuery();
+               // Assert.assertEquals(new HashSet<QueryModelNode>(),
+               // jsm.getUnmatchedArgs());
+               //
+               // Set<QueryModelNode> qNodes = 
LeftJoinQueryNodeGatherer.getNodes(te);
+               // List<QueryModelNode> nodes = jsm.getOrderedNodes();
+               // Set<QueryModelNode> nodeSet = new HashSet<>();
+               // nodeSet.add(nodes.get(0));
+               // nodeSet.add(pcj);
+               //
+               // Assert.assertEquals(nodeSet, new 
HashSet<QueryModelNode>(nodes));
+               // Assert.assertEquals(nodeSet, qNodes);
+
+       }
+
+       @Test
+       public void testExactMatchLargeReOrdered() throws Exception {
+
+               String query1 = ""//
+                               + "SELECT ?a ?b ?c ?d ?e ?f ?g ?h" //
+                               + "{" //
+                               + "  ?a <uri:p0> ?b ." //
+                               + "  OPTIONAL{?b <uri:p2> ?c. ?c <uri:p1> ?d} . 
" //
+                               + "  OPTIONAL{?b <uri:p3> ?e. ?e <uri:p1> ?f} . 
"//
+                               + "  OPTIONAL{?b <uri:p4> ?g. ?g <uri:p1> ?h} . 
"//
+                               + "  OPTIONAL{?b <uri:p4> ?i. ?i <uri:p1> ?j} . 
"//
+                               + "  OPTIONAL{?b <uri:p4> ?k. ?k <uri:p1> ?l} . 
"//
+                               + "  OPTIONAL{?b <uri:p4> ?m. ?m <uri:p1> ?n} . 
"//
+                               + "  OPTIONAL{?b <uri:p4> ?o. ?o <uri:p1> ?p} . 
"//
+                               + "}";//
+
+               String query2 = ""//
+                               + "SELECT ?a ?b ?c ?d ?e ?f ?g ?h" //
+                               + "{" //
+                               + "  ?a <uri:p0> ?b ." //
+                               + "  OPTIONAL{?b <uri:p4> ?o. ?o <uri:p1> ?p} . 
"//
+                               + "  OPTIONAL{?b <uri:p4> ?g. ?g <uri:p1> ?h} . 
"//
+                               + "  OPTIONAL{?b <uri:p2> ?c. ?c <uri:p1> ?d} . 
" //
+                               + "  OPTIONAL{?b <uri:p4> ?i. ?i <uri:p1> ?j} . 
"//
+                               + "  OPTIONAL{?b <uri:p4> ?m. ?m <uri:p1> ?n} . 
"//
+                               + "  OPTIONAL{?b <uri:p4> ?k. ?k <uri:p1> ?l} . 
"//
+                               + "  OPTIONAL{?b <uri:p3> ?e. ?e <uri:p1> ?f} . 
"//
+                               + "}";//
+
+               SPARQLParser parser = new SPARQLParser();
+               ParsedQuery pq1 = parser.parseQuery(query1, null);
+               ParsedQuery pq2 = parser.parseQuery(query2, null);
+               TupleExpr te1 = pq1.getTupleExpr();
+               TupleExpr te2 = pq2.getTupleExpr();
+
+               SimpleExternalTupleSet pcj = new SimpleExternalTupleSet(
+                               (Projection) te2);
+               List<ExternalTupleSet> externalList = new ArrayList<>();
+               externalList.add(pcj);
+
+               PCJOptimizer optimizer = new PCJOptimizer(externalList, false);
+               optimizer.optimize(te1, null, null);
+               System.out.println(te1);
+       }
+
+       @Test
+       public void testSubsetMatchLargeReOrdered() throws Exception {
+
+               String query1 = ""//
+                               + "SELECT ?a ?b ?c ?d ?e ?f ?g ?h" //
+                               + "{" //
+                               + "  ?a <uri:p0> ?b ." //
+                               + "  OPTIONAL{?b <uri:p2> ?c. ?c <uri:p1> ?d} . 
" //
+                               + "  OPTIONAL{?b <uri:p3> ?e. ?e <uri:p1> ?f} . 
"//
+                               + "  OPTIONAL{?b <uri:p4> ?g. ?g <uri:p1> ?h} . 
"//
+                               + "  OPTIONAL{?b <uri:p4> ?i. ?i <uri:p1> ?j} . 
"//
+                               + "  OPTIONAL{?b <uri:p4> ?k. ?k <uri:p1> ?l} . 
"//
+                               + "  OPTIONAL{?b <uri:p4> ?m. ?m <uri:p1> ?n} . 
"//
+                               + "  OPTIONAL{?b <uri:p4> ?o. ?o <uri:p1> ?p} . 
"//
+                               + "}";//
+
+               String query2 = ""//
+                               + "SELECT ?a ?b ?c ?d ?e ?f ?g ?h" //
+                               + "{" //
+                               + "  ?a <uri:p0> ?b ." //
+                               + "  OPTIONAL{?b <uri:p4> ?o. ?o <uri:p1> ?p} . 
"//
+                               + "  OPTIONAL{?b <uri:p4> ?g. ?g <uri:p1> ?h} . 
"//
+                               + "  OPTIONAL{?b <uri:p2> ?c. ?c <uri:p1> ?d} . 
" //
+                               + "  OPTIONAL{?b <uri:p3> ?e. ?e <uri:p1> ?f} . 
"//
+                               + "}";//
+
+               SPARQLParser parser = new SPARQLParser();
+               ParsedQuery pq1 = parser.parseQuery(query1, null);
+               ParsedQuery pq2 = parser.parseQuery(query2, null);
+               TupleExpr te1 = pq1.getTupleExpr();
+               TupleExpr te2 = pq2.getTupleExpr();
+
+               SimpleExternalTupleSet pcj = new SimpleExternalTupleSet(
+                               (Projection) te2);
+               List<ExternalTupleSet> externalList = new ArrayList<>();
+               externalList.add(pcj);
+
+               PCJOptimizer optimizer = new PCJOptimizer(externalList, false);
+               optimizer.optimize(te1, null, null);
+               System.out.println(te1);
+       }
+
+       @Test
+       public void testSwitchTwoBoundVars() throws Exception {
+
+               String query1 = ""//
+                               + "SELECT ?a ?b ?c " //
+                               + "{" //
+                               + "  ?a <uri:p0> ?c ." //
+                               + "  ?c <uri:p5> <uri:o5> ." //
+                               + " OPTIONAL{?c <uri:p4> <uri:o4>} ." + "  
?b<uri:p1> ?c ." //
+                               + " OPTIONAL{ ?a <uri:p1> ?b } ." //
+                               + " ?a <uri:p2> <uri:o2>. " //
+                               + " ?b <uri:p3> <uri:o3> " //
+                               + "}";//
+
+               String query2 = ""//
+                               + "SELECT ?a ?b ?c " //
+                               + "{" //
+                               + " ?a <uri:p2> <uri:o2>. " //
+                               + " ?b <uri:p3> <uri:o3>. " //
+                               + " OPTIONAL{ ?a <uri:p1> ?b } ." //
+                               + "  ?a <uri:p0> ?c ." //
+                               + "  ?b<uri:p1> ?c " //
+                               + "}";//
+
+               SPARQLParser parser = new SPARQLParser();
+               ParsedQuery pq1 = parser.parseQuery(query1, null);
+               ParsedQuery pq2 = parser.parseQuery(query2, null);
+               TupleExpr te1 = pq1.getTupleExpr();
+               TupleExpr te2 = pq2.getTupleExpr();
+               SimpleExternalTupleSet pcj = new SimpleExternalTupleSet(
+                               (Projection) te2);
+               List<ExternalTupleSet> externalList = new ArrayList<>();
+               externalList.add(pcj);
+
+               PCJOptimizer optimizer = new PCJOptimizer(externalList, false);
+               optimizer.optimize(te1, null, null);
+               System.out.println(te1);
+       }
+
+       @Test
+       public void testSegmentWithLargeUnion() throws MalformedQueryException {
+
+               String query1 = ""//
+                               + "SELECT ?e ?c ?l" //
+                               + "{" //
+                               + " {?e <uri:p1> <uri:o1>. } UNION { " //
+                               + "  ?e <uri:p0> ?l ." //
+                               + "  ?l <uri:p5> <uri:o5> ." //
+                               + " OPTIONAL{?l <uri:p4> <uri:o4>} ." + "  
?c<uri:p1> ?l ." //
+                               + " OPTIONAL{ ?e <uri:p1> ?c } ." //
+                               + " ?e <uri:p2> <uri:o2>. " //
+                               + " ?c <uri:p3> <uri:o3> " //
+                               + " }  . "//
+                               + "  ?e <uri:p2> ?c . "//
+                               + "  ?e <uri:p3> <uri:o2>  . "//
+                               + "}";//
+
+               String query2 = ""//
+                               + "SELECT ?a ?b ?c " //
+                               + "{" //
+                               + " ?a <uri:p2> <uri:o2>. " //
+                               + " ?b <uri:p3> <uri:o3>. " //
+                               + " OPTIONAL{ ?a <uri:p1> ?b } ." //
+                               + "  ?a <uri:p0> ?c ." //
+                               + "  ?b<uri:p1> ?c " //
+                               + "}";//
+
+               String query3 = ""//
+                               + "SELECT ?h ?i" //
+                               + "{" //
+                               + "  ?h <uri:p2> ?i . "//
+                               + "  ?h <uri:p3> <uri:o2>  . "//
+                               + "}";//
+
+               SPARQLParser parser = new SPARQLParser();
+               ParsedQuery pq1 = parser.parseQuery(query1, null);
+               ParsedQuery pq2 = parser.parseQuery(query2, null);
+               ParsedQuery pq3 = parser.parseQuery(query3, null);
+               TupleExpr te1 = pq1.getTupleExpr();
+               TupleExpr te2 = pq2.getTupleExpr();
+               TupleExpr te3 = pq3.getTupleExpr();
+
+               SimpleExternalTupleSet pcj1 = new SimpleExternalTupleSet(
+                               (Projection) te2);
+               SimpleExternalTupleSet pcj2 = new SimpleExternalTupleSet(
+                               (Projection) te3);
+               List<ExternalTupleSet> externalList = new ArrayList<>();
+               externalList.add(pcj1);
+               externalList.add(pcj2);
+
+               PCJOptimizer optimizer = new PCJOptimizer(externalList, false);
+               optimizer.optimize(te1, null, null);
+               System.out.println(te1);
+
+               // Assert.assertEquals(true, jsm.matchPCJ(pcj));
+               // TupleExpr te = jsm.getQuery();
+               // Assert.assertEquals(new HashSet<QueryModelNode>(),
+               // jsm.getUnmatchedArgs());
+               //
+               // Set<QueryModelNode> qNodes = 
LeftJoinQueryNodeGatherer.getNodes(te);
+               // List<QueryModelNode> nodes = jsm.getOrderedNodes();
+               // Set<QueryModelNode> nodeSet = new HashSet<>();
+               // nodeSet.add(nodes.get(0));
+               // nodeSet.add(pcj);
+               //
+               // Assert.assertEquals(nodeSet, new 
HashSet<QueryModelNode>(nodes));
+               // Assert.assertEquals(nodeSet, qNodes);
+
+       }
+
+       @Test
+       public void testSegmentWithUnionAndFilters() throws 
MalformedQueryException {
+
+               String query1 = ""//
+                               + "SELECT ?e ?c ?l" //
+                               + "{" //
+                               + " Filter(?e = <uri:s1>) " //
+                               + " Filter(?c = <uri:s2>) " //
+                               + " {?e <uri:p1> <uri:o1>. } UNION { ?e a ?c. 
OPTIONAL {?e <uri:talksTo> ?l}. ?e <uri:p5> <uri:o4>. ?e <uri:p4> <uri:o3> }  . 
"//
+                               + "  ?e <uri:p2> ?c . "//
+                               + "  ?e <uri:p3> <uri:o2>  . "//
+                               + "}";//
+
+               String query2 = ""//
+                               + "SELECT ?a ?b ?m" //
+                               + "{" //
+                               + " Filter(?b = <uri:s2>) " //
+                               + " ?a <uri:p5> <uri:o4> ." //
+                               + " ?a <uri:p4> <uri:o3> ." //
+                               + "  OPTIONAL {?a <uri:talksTo> ?m} . "//
+                               + "  ?a a ?b . "//
+                               + "}";//
+
+               String query3 = ""//
+                               + "SELECT ?h ?i" //
+                               + "{" //
+                               + " Filter(?h = <uri:s1>) " //
+                               + "  ?h <uri:p2> ?i . "//
+                               + "  ?h <uri:p3> <uri:o2>  . "//
+                               + "}";//
+
+               SPARQLParser parser = new SPARQLParser();
+               ParsedQuery pq1 = parser.parseQuery(query1, null);
+               ParsedQuery pq2 = parser.parseQuery(query2, null);
+               ParsedQuery pq3 = parser.parseQuery(query3, null);
+               TupleExpr te1 = pq1.getTupleExpr();
+               TupleExpr te2 = pq2.getTupleExpr();
+               TupleExpr te3 = pq3.getTupleExpr();
+
+               SimpleExternalTupleSet pcj1 = new SimpleExternalTupleSet(
+                               (Projection) te2);
+               SimpleExternalTupleSet pcj2 = new SimpleExternalTupleSet(
+                               (Projection) te3);
+               List<ExternalTupleSet> externalList = new ArrayList<>();
+               externalList.add(pcj1);
+               externalList.add(pcj2);
+
+               PCJOptimizer optimizer = new PCJOptimizer(externalList, false);
+               optimizer.optimize(te1, null, null);
+               System.out.println(te1);
+
+               // Assert.assertEquals(true, jsm.matchPCJ(pcj));
+               // TupleExpr te = jsm.getQuery();
+               // Assert.assertEquals(new HashSet<QueryModelNode>(),
+               // jsm.getUnmatchedArgs());
+               //
+               // Set<QueryModelNode> qNodes = 
LeftJoinQueryNodeGatherer.getNodes(te);
+               // List<QueryModelNode> nodes = jsm.getOrderedNodes();
+               // Set<QueryModelNode> nodeSet = new HashSet<>();
+               // nodeSet.add(nodes.get(0));
+               // nodeSet.add(pcj);
+               //
+               // Assert.assertEquals(nodeSet, new 
HashSet<QueryModelNode>(nodes));
+               // Assert.assertEquals(nodeSet, qNodes);
+
+       }
+
+       @Test
+       public void testSegmentWithLeftJoinsAndFilters()
+                       throws MalformedQueryException {
+
+               String query1 = ""//
+                               + "SELECT ?e ?c ?l" //
+                               + "{" //
+                               + " Filter(?e = <uri:s1>) " //
+                               + " Filter(?c = <uri:s2>) " //
+                               + " ?e <uri:p1> <uri:o1>. "
+                               + " OPTIONAL {?e <uri:p2> ?l}. "
+                               + " ?c <uri:p3> <uri:o3>  . "//
+                               + "  ?c <uri:p4> ?e  . "//
+                               + " OPTIONAL {?e <uri:p2> ?c } . "//
+                               + "}";//
+
+               String query2 = ""//
+                               + "SELECT ?e ?c ?l" //
+                               + "{" //
+                               + " Filter(?c = <uri:s2>) " //
+                               + " ?e <uri:p1> <uri:o1>. "
+                               + " OPTIONAL {?e <uri:p2> ?l}. "
+                               + " ?c <uri:p3> <uri:o3>  . "//
+                               + "}";//
+
+               String query3 = ""//
+                               + "SELECT ?e ?c" //
+                               + "{" //
+                               + " Filter(?e = <uri:s1>) " //
+                               + "  ?c <uri:p4> ?e  . "//
+                               + " OPTIONAL {?e <uri:p2> ?c } . "//
+                               + "}";//
+
+               SPARQLParser parser = new SPARQLParser();
+               ParsedQuery pq1 = parser.parseQuery(query1, null);
+               ParsedQuery pq2 = parser.parseQuery(query2, null);
+               ParsedQuery pq3 = parser.parseQuery(query3, null);
+               TupleExpr te1 = pq1.getTupleExpr();
+               TupleExpr te2 = pq2.getTupleExpr();
+               TupleExpr te3 = pq3.getTupleExpr();
+
+               SimpleExternalTupleSet pcj1 = new SimpleExternalTupleSet(
+                               (Projection) te2);
+               SimpleExternalTupleSet pcj2 = new SimpleExternalTupleSet(
+                               (Projection) te3);
+               List<ExternalTupleSet> externalList = new ArrayList<>();
+               externalList.add(pcj1);
+               externalList.add(pcj2);
+
+               PCJOptimizer optimizer = new PCJOptimizer(externalList, false);
+               optimizer.optimize(te1, null, null);
+               System.out.println(te1);
+
+               // Assert.assertEquals(true, jsm.matchPCJ(pcj));
+               // TupleExpr te = jsm.getQuery();
+               // Assert.assertEquals(new HashSet<QueryModelNode>(),
+               // jsm.getUnmatchedArgs());
+               //
+               // Set<QueryModelNode> qNodes = 
LeftJoinQueryNodeGatherer.getNodes(te);
+               // List<QueryModelNode> nodes = jsm.getOrderedNodes();
+               // Set<QueryModelNode> nodeSet = new HashSet<>();
+               // nodeSet.add(nodes.get(0));
+               // nodeSet.add(pcj);
+               //
+               // Assert.assertEquals(nodeSet, new 
HashSet<QueryModelNode>(nodes));
+               // Assert.assertEquals(nodeSet, qNodes);
+
+       }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/96dd55ec/extras/indexing/src/test/java/mvm/rya/indexing/pcj/matching/PCJOptimizerUtilitesTest.java
----------------------------------------------------------------------
diff --git 
a/extras/indexing/src/test/java/mvm/rya/indexing/pcj/matching/PCJOptimizerUtilitesTest.java
 
b/extras/indexing/src/test/java/mvm/rya/indexing/pcj/matching/PCJOptimizerUtilitesTest.java
new file mode 100644
index 0000000..f66ee91
--- /dev/null
+++ 
b/extras/indexing/src/test/java/mvm/rya/indexing/pcj/matching/PCJOptimizerUtilitesTest.java
@@ -0,0 +1,96 @@
+package mvm.rya.indexing.pcj.matching;
+
+import mvm.rya.indexing.external.tupleSet.SimpleExternalTupleSet;
+
+import org.junit.Assert;
+import org.junit.Test;
+import org.openrdf.query.MalformedQueryException;
+import org.openrdf.query.algebra.Projection;
+import org.openrdf.query.algebra.TupleExpr;
+import org.openrdf.query.parser.ParsedQuery;
+import org.openrdf.query.parser.sparql.SPARQLParser;
+
+public class PCJOptimizerUtilitesTest {
+
+       @Test
+       public void testValidPCJ() throws MalformedQueryException {
+
+               String query1 = ""//
+                               + "SELECT ?e ?c " //
+                               + "{" //
+                               + "  ?e a ?c . "//
+                               + "}";//
+
+               String query2 = ""//
+                               + "SELECT ?a ?b ?m" //
+                               + "{" //
+                               + "  ?a a ?b . "//
+                               + "  OPTIONAL {?a <uri:talksTo> ?m}  . "//
+                               + "}";//
+
+               String query3 = ""//
+                               + "SELECT ?a ?b ?m" //
+                               + "{" //
+                               + "  ?a a ?b . "//
+                               + "  ?a <uri:talksTo> ?m  . "//
+                               + "}";//
+
+               String query4 = ""//
+                               + "SELECT ?a ?b ?m ?n" //
+                               + "{" //
+                               + "  ?a a ?b . "//
+                               + "  OPTIONAL {?a <uri:talksTo> ?m}  . "//
+                               + "}";//
+
+               String query5 = ""//
+                               + "SELECT ?e ?c " //
+                               + "{" //
+                               + "Filter(?e = <uri:s1>) " //
+                               + "  ?e a ?c . "//
+                               + "}";//
+
+               String query6 = ""//
+                               + "SELECT ?e ?c " //
+                               + "{" //
+                               + "Filter(?f = <uri:s1>) " //
+                               + "  ?e a ?c . "//
+                               + "  ?c <uri:p1> <uri:o1> " //
+                               + "}";//
+
+               SPARQLParser parser = new SPARQLParser();
+               ParsedQuery pq1 = parser.parseQuery(query1, null);
+               ParsedQuery pq2 = parser.parseQuery(query2, null);
+               ParsedQuery pq3 = parser.parseQuery(query3, null);
+               ParsedQuery pq4 = parser.parseQuery(query4, null);
+               ParsedQuery pq5 = parser.parseQuery(query5, null);
+               ParsedQuery pq6 = parser.parseQuery(query6, null);
+               TupleExpr te1 = pq1.getTupleExpr();
+               TupleExpr te2 = pq2.getTupleExpr();
+               TupleExpr te3 = pq3.getTupleExpr();
+               TupleExpr te4 = pq4.getTupleExpr();
+               TupleExpr te5 = pq5.getTupleExpr();
+               TupleExpr te6 = pq6.getTupleExpr();
+
+               SimpleExternalTupleSet pcj1 = new SimpleExternalTupleSet(
+                               (Projection) te1);
+               SimpleExternalTupleSet pcj2 = new SimpleExternalTupleSet(
+                               (Projection) te2);
+               SimpleExternalTupleSet pcj3 = new SimpleExternalTupleSet(
+                               (Projection) te3);
+               SimpleExternalTupleSet pcj4 = new SimpleExternalTupleSet(
+                               (Projection) te4);
+               SimpleExternalTupleSet pcj5 = new SimpleExternalTupleSet(
+                               (Projection) te5);
+               SimpleExternalTupleSet pcj6 = new SimpleExternalTupleSet(
+                               (Projection) te6);
+
+               Assert.assertEquals(false , 
PCJOptimizerUtilities.isPCJValid(pcj1));
+               Assert.assertEquals(true , 
PCJOptimizerUtilities.isPCJValid(pcj2));
+               Assert.assertEquals(true , 
PCJOptimizerUtilities.isPCJValid(pcj3));
+               Assert.assertEquals(false , 
PCJOptimizerUtilities.isPCJValid(pcj4));
+               Assert.assertEquals(true , 
PCJOptimizerUtilities.isPCJValid(pcj5));
+               Assert.assertEquals(false , 
PCJOptimizerUtilities.isPCJValid(pcj6));
+
+       }
+
+}

Reply via email to