[Mulgara-svn] r1775 - in branches/distinct_queries: . src/jar/content-rdfxml/java/org/mulgara/content/rdfxml/writer src/jar/krule/java/org/mulgara/krule src/jar/query/java/org/mulgara/connection src/jar/query/java/org/mulgara/jena src/jar/query/java/org/mulgara/query src/jar/querylang/java/org/mulgara/itql src/jar/querylang/java/org/mulgara/sparql src/jar/querylang/sablecc src/jar/resolver/java/org/mulgara/resolver src/jar/resolver-distributed/java/org/mulgara/resolver/distributed src/jar/resolver-gis/java/org/mulgara/resolver/gis src/jar/resolver-relational/java/org/mulgara/resolver/relational src/jar/resolver-spi/java/org/mulgara/resolver/spi src/jar/resolver-spi/java/org/mulgara/store/statement src/jar/resolver-test/java/org/mulgara/resolver/test src/jar/resolver-view/java/org/mulgara/resolver/view src/jar/swrl/java/org/mulgara/swrl src/jar/tuples/java/org/mulgara/store/tuples

pag at mulgara.org pag at mulgara.org
Thu Aug 13 18:33:17 UTC 2009


Author: pag
Date: 2009-08-13 11:33:16 -0700 (Thu, 13 Aug 2009)
New Revision: 1775

Modified:
   branches/distinct_queries/.project
   branches/distinct_queries/src/jar/content-rdfxml/java/org/mulgara/content/rdfxml/writer/RDFXMLWriter.java
   branches/distinct_queries/src/jar/content-rdfxml/java/org/mulgara/content/rdfxml/writer/TestStatementsComparator.java
   branches/distinct_queries/src/jar/krule/java/org/mulgara/krule/KruleLoader.java
   branches/distinct_queries/src/jar/krule/java/org/mulgara/krule/QueryStruct.java
   branches/distinct_queries/src/jar/query/java/org/mulgara/connection/ConnectionFactoryUnitTest.java
   branches/distinct_queries/src/jar/query/java/org/mulgara/jena/PatternMulgara.java
   branches/distinct_queries/src/jar/query/java/org/mulgara/query/AskQuery.java
   branches/distinct_queries/src/jar/query/java/org/mulgara/query/ConstraintOperation.java
   branches/distinct_queries/src/jar/query/java/org/mulgara/query/ConstructQuery.java
   branches/distinct_queries/src/jar/query/java/org/mulgara/query/Query.java
   branches/distinct_queries/src/jar/query/java/org/mulgara/query/QueryUnitTest.java
   branches/distinct_queries/src/jar/querylang/java/org/mulgara/itql/TqlInterpreter.java
   branches/distinct_queries/src/jar/querylang/java/org/mulgara/sparql/SparqlInterpreter.java
   branches/distinct_queries/src/jar/querylang/sablecc/itql.grammar
   branches/distinct_queries/src/jar/resolver-distributed/java/org/mulgara/resolver/distributed/NetworkDelegator.java
   branches/distinct_queries/src/jar/resolver-gis/java/org/mulgara/resolver/gis/WritableGISResolver.java
   branches/distinct_queries/src/jar/resolver-relational/java/org/mulgara/resolver/relational/RelationalResolverUnitTest.java
   branches/distinct_queries/src/jar/resolver-spi/java/org/mulgara/resolver/spi/QueryEvaluationContext.java
   branches/distinct_queries/src/jar/resolver-spi/java/org/mulgara/resolver/spi/SumOfProductExpansionTransformer.java
   branches/distinct_queries/src/jar/resolver-spi/java/org/mulgara/store/statement/StatementStoreAbstractUnitTest.java
   branches/distinct_queries/src/jar/resolver-test/java/org/mulgara/resolver/test/TestResolverUnitTest.java
   branches/distinct_queries/src/jar/resolver-view/java/org/mulgara/resolver/view/ViewResolverUnitTest.java
   branches/distinct_queries/src/jar/resolver/java/org/mulgara/resolver/AdvDatabaseSessionUnitTest.java
   branches/distinct_queries/src/jar/resolver/java/org/mulgara/resolver/BasicDatabaseSessionUnitTest.java
   branches/distinct_queries/src/jar/resolver/java/org/mulgara/resolver/DatabaseOperationContext.java
   branches/distinct_queries/src/jar/resolver/java/org/mulgara/resolver/DatabaseSessionListQueryUnitTest.java
   branches/distinct_queries/src/jar/resolver/java/org/mulgara/resolver/DatabaseSessionUnitTest.java
   branches/distinct_queries/src/jar/resolver/java/org/mulgara/resolver/DefaultConstraintHandlers.java
   branches/distinct_queries/src/jar/resolver/java/org/mulgara/resolver/ExternalTransactionUnitTest.java
   branches/distinct_queries/src/jar/resolver/java/org/mulgara/resolver/JotmTransactionStandaloneTest.java
   branches/distinct_queries/src/jar/resolver/java/org/mulgara/resolver/LocalJRDFDatabaseSession.java
   branches/distinct_queries/src/jar/resolver/java/org/mulgara/resolver/LocalQueryResolver.java
   branches/distinct_queries/src/jar/resolver/java/org/mulgara/resolver/XADatabaseSessionUnitTest.java
   branches/distinct_queries/src/jar/swrl/java/org/mulgara/swrl/SWRLLoader.java
   branches/distinct_queries/src/jar/tuples/java/org/mulgara/store/tuples/TuplesOperations.java
Log:
Initial cut at full distinct vs non-distinct capabilities. Some optimization still needed in the SumOfProductExpansionTransformer as mentioned in the top comment

Modified: branches/distinct_queries/.project
===================================================================
--- branches/distinct_queries/.project	2009-08-13 17:39:34 UTC (rev 1774)
+++ branches/distinct_queries/.project	2009-08-13 18:33:16 UTC (rev 1775)
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <projectDescription>
-	<name>mulgara</name>
+	<name>nondistinct</name>
 	<comment></comment>
 	<projects>
 	</projects>

Modified: branches/distinct_queries/src/jar/content-rdfxml/java/org/mulgara/content/rdfxml/writer/RDFXMLWriter.java
===================================================================
--- branches/distinct_queries/src/jar/content-rdfxml/java/org/mulgara/content/rdfxml/writer/RDFXMLWriter.java	2009-08-13 17:39:34 UTC (rev 1774)
+++ branches/distinct_queries/src/jar/content-rdfxml/java/org/mulgara/content/rdfxml/writer/RDFXMLWriter.java	2009-08-13 18:33:16 UTC (rev 1775)
@@ -198,7 +198,7 @@
 
     // ensure variables are in the right order
     Tuples projectedTuples = TuplesOperations.project(materializedTuples,
-        Arrays.asList(vars));
+        Arrays.asList(vars), true);
     materializedTuples.close();
 
     // tuples must be sorted by subject for writing

Modified: branches/distinct_queries/src/jar/content-rdfxml/java/org/mulgara/content/rdfxml/writer/TestStatementsComparator.java
===================================================================
--- branches/distinct_queries/src/jar/content-rdfxml/java/org/mulgara/content/rdfxml/writer/TestStatementsComparator.java	2009-08-13 17:39:34 UTC (rev 1774)
+++ branches/distinct_queries/src/jar/content-rdfxml/java/org/mulgara/content/rdfxml/writer/TestStatementsComparator.java	2009-08-13 18:33:16 UTC (rev 1775)
@@ -252,7 +252,7 @@
     Tuples projectedTuples = TuplesOperations.project(sortedTuples,
         Arrays.asList(new Variable[] {
         StatementStore.VARIABLES[0], StatementStore.VARIABLES[1],
-        StatementStore.VARIABLES[2]}));
+        StatementStore.VARIABLES[2]}), true);
     sortedTuples.close();
 
     return new TuplesWrapperStatements(projectedTuples,

Modified: branches/distinct_queries/src/jar/krule/java/org/mulgara/krule/KruleLoader.java
===================================================================
--- branches/distinct_queries/src/jar/krule/java/org/mulgara/krule/KruleLoader.java	2009-08-13 17:39:34 UTC (rev 1774)
+++ branches/distinct_queries/src/jar/krule/java/org/mulgara/krule/KruleLoader.java	2009-08-13 18:33:16 UTC (rev 1775)
@@ -1054,6 +1054,7 @@
         (List<Order>)Collections.EMPTY_LIST,        // ORDER BY
         null,                                       // LIMIT
         0,                                          // OFFSET
+        true,                                       // DISTINCT
         UNCONSTRAINED                               // GIVEN
     );
   }

Modified: branches/distinct_queries/src/jar/krule/java/org/mulgara/krule/QueryStruct.java
===================================================================
--- branches/distinct_queries/src/jar/krule/java/org/mulgara/krule/QueryStruct.java	2009-08-13 17:39:34 UTC (rev 1774)
+++ branches/distinct_queries/src/jar/krule/java/org/mulgara/krule/QueryStruct.java	2009-08-13 18:33:16 UTC (rev 1775)
@@ -237,7 +237,7 @@
   @SuppressWarnings("unchecked")
   public Query extractQuery() {
     logger.debug("Extracting query");
-    return new Query(variables, graphs, where, having, (List<Order>)Collections.EMPTY_LIST, null, 0, new UnconstrainedAnswer());
+    return new Query(variables, graphs, where, having, (List<Order>)Collections.EMPTY_LIST, null, 0, true, new UnconstrainedAnswer());
   }
 
 }

Modified: branches/distinct_queries/src/jar/query/java/org/mulgara/connection/ConnectionFactoryUnitTest.java
===================================================================
--- branches/distinct_queries/src/jar/query/java/org/mulgara/connection/ConnectionFactoryUnitTest.java	2009-08-13 17:39:34 UTC (rev 1774)
+++ branches/distinct_queries/src/jar/query/java/org/mulgara/connection/ConnectionFactoryUnitTest.java	2009-08-13 18:33:16 UTC (rev 1775)
@@ -95,6 +95,7 @@
       }),
       null,                                             // LIMIT
       0,                                                // OFFSET
+      true,                                             // DISTINCT
       new UnconstrainedAnswer()                         // GIVEN
     );
   }

Modified: branches/distinct_queries/src/jar/query/java/org/mulgara/jena/PatternMulgara.java
===================================================================
--- branches/distinct_queries/src/jar/query/java/org/mulgara/jena/PatternMulgara.java	2009-08-13 17:39:34 UTC (rev 1774)
+++ branches/distinct_queries/src/jar/query/java/org/mulgara/jena/PatternMulgara.java	2009-08-13 18:33:16 UTC (rev 1775)
@@ -96,6 +96,7 @@
          x,                        // ORDER
          null,                     // LIMIT
          0,                        // OFFSET
+         true,                     // DISTINCT
          new UnconstrainedAnswer() // Initial Answer
     );
 

Modified: branches/distinct_queries/src/jar/query/java/org/mulgara/query/AskQuery.java
===================================================================
--- branches/distinct_queries/src/jar/query/java/org/mulgara/query/AskQuery.java	2009-08-13 17:39:34 UTC (rev 1774)
+++ branches/distinct_queries/src/jar/query/java/org/mulgara/query/AskQuery.java	2009-08-13 18:33:16 UTC (rev 1775)
@@ -45,6 +45,7 @@
         (List<Order>)Collections.EMPTY_LIST, // no ordering
         null, // no limit
         0, // zero offset
+        true, // distinct TODO: change to false when non-distinct is tested
         new UnconstrainedAnswer());
   }
 

Modified: branches/distinct_queries/src/jar/query/java/org/mulgara/query/ConstraintOperation.java
===================================================================
--- branches/distinct_queries/src/jar/query/java/org/mulgara/query/ConstraintOperation.java	2009-08-13 17:39:34 UTC (rev 1774)
+++ branches/distinct_queries/src/jar/query/java/org/mulgara/query/ConstraintOperation.java	2009-08-13 18:33:16 UTC (rev 1775)
@@ -115,7 +115,16 @@
     // assert elements.size() > 1;
 
     // Initialize fields
-    this.elements = new ArrayList<ConstraintExpression>(elements);
+    this.elements = new ArrayList<ConstraintExpression>();
+
+    // add all the elements, flattening if needed
+    for (ConstraintExpression op: elements) {
+      if (op.getClass().equals(getClass())) {
+        this.elements.addAll(((ConstraintOperation)op).getElements());
+      } else {
+        this.elements.add(op);
+      }
+    }
   }
 
 

Modified: branches/distinct_queries/src/jar/query/java/org/mulgara/query/ConstructQuery.java
===================================================================
--- branches/distinct_queries/src/jar/query/java/org/mulgara/query/ConstructQuery.java	2009-08-13 17:39:34 UTC (rev 1774)
+++ branches/distinct_queries/src/jar/query/java/org/mulgara/query/ConstructQuery.java	2009-08-13 18:33:16 UTC (rev 1775)
@@ -41,6 +41,7 @@
         orderList,
         limit,
         offset,
+        true,
         new UnconstrainedAnswer());
   }
 

Modified: branches/distinct_queries/src/jar/query/java/org/mulgara/query/Query.java
===================================================================
--- branches/distinct_queries/src/jar/query/java/org/mulgara/query/Query.java	2009-08-13 17:39:34 UTC (rev 1774)
+++ branches/distinct_queries/src/jar/query/java/org/mulgara/query/Query.java	2009-08-13 18:33:16 UTC (rev 1775)
@@ -106,6 +106,9 @@
   /** The offset on rows in the result. This value is never negative. */
   private int offset;
 
+  /** Indicates that the results must be without duplicates. */
+  private boolean distinct = true;
+
   /** The accumulated solutions. This can be <code>null</code>, indicating no solutions. */
   private Answer answer;
 
@@ -149,7 +152,7 @@
   public Query(List<? extends SelectElement> variableList, GraphExpression graphExpression,
       ConstraintExpression constraintExpression,
       ConstraintHaving havingExpression, List<Order> orderList, Integer limit,
-      int offset, Answer answer) {
+      int offset, boolean distinct, Answer answer) {
 
     // Validate parameters
     if (graphExpression == null) {
@@ -189,6 +192,7 @@
     this.orderList = Collections.unmodifiableList(new ArrayList<Order>(orderList));
     this.limit = limit;
     this.offset = offset;
+    this.distinct = distinct;
     this.answer = answer;
   }
 
@@ -206,6 +210,7 @@
     this.orderList = query.orderList;
     this.limit = query.limit;
     this.offset = query.offset;
+    this.distinct = query.distinct;
     this.answer = (query.answer != null) ?(Answer)query.answer.clone() : new UnconstrainedAnswer();
     /*
       this(query.getVariableList(),
@@ -343,6 +348,13 @@
     return answer;
   }
 
+  /**
+   * Accessor for the DISTINCT property on this query.
+   * @return <code>true</code> if results of the query should not contain duplicates.
+   */
+  public boolean isDistinct() {
+    return distinct;
+  }
 
   //
   // Methods overriding Object

Modified: branches/distinct_queries/src/jar/query/java/org/mulgara/query/QueryUnitTest.java
===================================================================
--- branches/distinct_queries/src/jar/query/java/org/mulgara/query/QueryUnitTest.java	2009-08-13 17:39:34 UTC (rev 1774)
+++ branches/distinct_queries/src/jar/query/java/org/mulgara/query/QueryUnitTest.java	2009-08-13 18:33:16 UTC (rev 1775)
@@ -109,6 +109,7 @@
         (List<Order>)Collections.EMPTY_LIST,    // no ordering
         null,                                   // no limit
         0,                                      // zero offset
+        true,                                   // no duplicates
         new UnconstrainedAnswer());
   }
 
@@ -155,6 +156,7 @@
         (List<Order>)Collections.EMPTY_LIST,   // no ordering
         null,                                  // no limit
         0,                                     // zero offset
+        true,                                  // no duplicates
         new UnconstrainedAnswer());
 
     // These truths we hold to be self-evident:

Modified: branches/distinct_queries/src/jar/querylang/java/org/mulgara/itql/TqlInterpreter.java
===================================================================
--- branches/distinct_queries/src/jar/querylang/java/org/mulgara/itql/TqlInterpreter.java	2009-08-13 17:39:34 UTC (rev 1774)
+++ branches/distinct_queries/src/jar/querylang/java/org/mulgara/itql/TqlInterpreter.java	2009-08-13 18:33:16 UTC (rev 1775)
@@ -867,7 +867,8 @@
     AHavingClause havingClause;
     ALimitClause limitClause;
     AOffsetClause offsetClause;
-  
+    boolean distinct = true;
+
     // cast the correct way (we don't have a common superclass, event though we
     // have methods with the same names)
     if (rawQuery instanceof AQuery) {
@@ -875,6 +876,7 @@
       AQuery query = (AQuery) rawQuery;
       PSelectClause selectClause = query.getSelectClause();
       if (selectClause instanceof ANormalSelectSelectClause) {
+        distinct = ((ANormalSelectSelectClause)selectClause).getNondistinct() == null;
         variables = (LinkedList<PElement>)((ANormalSelectSelectClause)selectClause).getElement();
       }
       fromClause = ((AFromClause)query.getFromClause());
@@ -944,7 +946,7 @@
   
     // build a query using the information we've obtained from the parser
     return new Query(variableList, graphExpression, constraintExpression,
-        havingExpression, orderList, limit, offset, new UnconstrainedAnswer());
+        havingExpression, orderList, limit, offset, distinct, new UnconstrainedAnswer());
   }
 
 

Modified: branches/distinct_queries/src/jar/querylang/java/org/mulgara/sparql/SparqlInterpreter.java
===================================================================
--- branches/distinct_queries/src/jar/querylang/java/org/mulgara/sparql/SparqlInterpreter.java	2009-08-13 17:39:34 UTC (rev 1774)
+++ branches/distinct_queries/src/jar/querylang/java/org/mulgara/sparql/SparqlInterpreter.java	2009-08-13 18:33:16 UTC (rev 1775)
@@ -254,8 +254,9 @@
     List<Order> orderBy = getOrdering(queryStruct);
     Integer limit = getLimit(queryStruct);
     int offset = queryStruct.getOffset();
+    boolean distinct = queryStruct.isDistinct();
     // null having, unconstrained answer
-    return new Query(selection, defaultGraphs, whereClause, null, orderBy, limit, offset, new UnconstrainedAnswer());
+    return new Query(selection, defaultGraphs, whereClause, null, orderBy, limit, offset, distinct, new UnconstrainedAnswer());
   }
 
   /**

Modified: branches/distinct_queries/src/jar/querylang/sablecc/itql.grammar
===================================================================
--- branches/distinct_queries/src/jar/querylang/sablecc/itql.grammar	2009-08-13 17:39:34 UTC (rev 1774)
+++ branches/distinct_queries/src/jar/querylang/sablecc/itql.grammar	2009-08-13 18:33:16 UTC (rev 1775)
@@ -57,6 +57,7 @@
   {def}                limit       = 'limit';
   {def}                load        = 'load';
   {def}                minus       = 'minus';
+  {def}                nondistinct = 'nondistinct';
   {def}                off         = 'off';
   {def}                offset      = 'offset';
   {def}                or          = 'or';
@@ -208,8 +209,8 @@
     {on} on   ;
 
   select_clause =
-    {empty_select} select |
-    {normal_select} select element+;
+    {empty_select} select nondistinct? |
+    {normal_select} select nondistinct? element+;
 
   from_clause =
     from model_expression;

Modified: branches/distinct_queries/src/jar/resolver/java/org/mulgara/resolver/AdvDatabaseSessionUnitTest.java
===================================================================
--- branches/distinct_queries/src/jar/resolver/java/org/mulgara/resolver/AdvDatabaseSessionUnitTest.java	2009-08-13 17:39:34 UTC (rev 1774)
+++ branches/distinct_queries/src/jar/resolver/java/org/mulgara/resolver/AdvDatabaseSessionUnitTest.java	2009-08-13 18:33:16 UTC (rev 1775)
@@ -310,6 +310,7 @@
           ),
           null,                                             // LIMIT
           0,                                                // OFFSET
+          true,                                             // DISTINCT
           new UnconstrainedAnswer()                         // GIVEN
         )));
 
@@ -327,6 +328,7 @@
           ),
           null,                                             // LIMIT
           0,                                                // OFFSET
+          true,                                             // DISTINCT
           new UnconstrainedAnswer()                         // GIVEN
         ));
 
@@ -385,6 +387,7 @@
           ),
           null,                                             // LIMIT
           0,                                                // OFFSET
+          true,                                             // DISTINCT
           new UnconstrainedAnswer()                         // GIVEN
         )));
 
@@ -402,6 +405,7 @@
           ),
           null,                                             // LIMIT
           0,                                                // OFFSET
+          true,                                             // DISTINCT
           new UnconstrainedAnswer()                         // GIVEN
         ));
 
@@ -1073,7 +1077,7 @@
         session1.createModel(delayTwoSecs, new URI(Mulgara.NAMESPACE + "MockModel"));
 
         try {
-          Answer answer = session1.query(createQuery(delayTwoSecs));
+          session1.query(createQuery(delayTwoSecs));
           fail("query should've gotten interrupted");
         } catch (QueryException qe) {
           logger.debug("query was interrupted", qe);
@@ -1100,7 +1104,7 @@
         logger.debug("Slept for 2sec");
 
         try {
-          Answer answer = session1.query(createQuery(model3URI));
+          session1.query(createQuery(model3URI));
           fail("query should've gotten interrupted");
         } catch (QueryException qe) {
           logger.debug("query was interrupted", qe);
@@ -1256,6 +1260,7 @@
           }),
           null,                                             // LIMIT
           0,                                                // OFFSET
+          true,                                             // DISTINCT
           new UnconstrainedAnswer()                         // GIVEN
         ));
 
@@ -1684,6 +1689,7 @@
       }),
       null,                                             // LIMIT
       0,                                                // OFFSET
+      true,                                             // DISTINCT
       new UnconstrainedAnswer()                         // GIVEN
     );
   }

Modified: branches/distinct_queries/src/jar/resolver/java/org/mulgara/resolver/BasicDatabaseSessionUnitTest.java
===================================================================
--- branches/distinct_queries/src/jar/resolver/java/org/mulgara/resolver/BasicDatabaseSessionUnitTest.java	2009-08-13 17:39:34 UTC (rev 1774)
+++ branches/distinct_queries/src/jar/resolver/java/org/mulgara/resolver/BasicDatabaseSessionUnitTest.java	2009-08-13 18:33:16 UTC (rev 1775)
@@ -210,6 +210,7 @@
             ),
             null,                               // LIMIT
             0,                                  // OFFSET
+            true,                               // DISTINCT
             new UnconstrainedAnswer()           // GIVEN
           )));
 
@@ -304,6 +305,7 @@
           ),
           null,                                             // LIMIT
           0,                                                // OFFSET
+          true,                                             // DISTINCT
           new UnconstrainedAnswer()                         // GIVEN
         )));
       } finally {

Modified: branches/distinct_queries/src/jar/resolver/java/org/mulgara/resolver/DatabaseOperationContext.java
===================================================================
--- branches/distinct_queries/src/jar/resolver/java/org/mulgara/resolver/DatabaseOperationContext.java	2009-08-13 17:39:34 UTC (rev 1774)
+++ branches/distinct_queries/src/jar/resolver/java/org/mulgara/resolver/DatabaseOperationContext.java	2009-08-13 18:33:16 UTC (rev 1775)
@@ -34,6 +34,7 @@
 import java.net.URISyntaxException;
 import java.net.InetAddress;
 import java.net.UnknownHostException;
+import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Iterator;
@@ -59,6 +60,7 @@
 import org.mulgara.resolver.spi.ResolverFactoryException;
 import org.mulgara.resolver.spi.SecurityAdapter;
 import org.mulgara.resolver.spi.Statements;
+import org.mulgara.resolver.spi.SumOfProductExpansionTransformer;
 import org.mulgara.resolver.spi.SymbolicTransformation;
 import org.mulgara.resolver.spi.SymbolicTransformationContext;
 import org.mulgara.resolver.spi.SystemResolver;
@@ -818,7 +820,16 @@
     }
 
     MutableLocalQueryImpl mutable = new MutableLocalQueryImpl(query);
-    Iterator<SymbolicTransformation> i = symbolicTransformationList.iterator();
+    List<SymbolicTransformation> symTxList;
+    symTxList = symbolicTransformationList;
+
+    // non-DISTINCT queries need to be expanded so the disjunction is at the root
+    if (!query.isDistinct()) {
+      symTxList = new ArrayList<SymbolicTransformation>(symbolicTransformationList);
+      symTxList.add(new SumOfProductExpansionTransformer());
+    }
+
+    Iterator<SymbolicTransformation> i = symTxList.iterator();
     while (i.hasNext()) {
       SymbolicTransformation symbolicTransformation = i.next();
       assert symbolicTransformation != null;
@@ -839,7 +850,7 @@
         mutable = new MutableLocalQueryImpl(query);
 
         // start again
-        i = symbolicTransformationList.iterator();
+        i = symTxList.iterator();
       }
     }
 

Modified: branches/distinct_queries/src/jar/resolver/java/org/mulgara/resolver/DatabaseSessionListQueryUnitTest.java
===================================================================
--- branches/distinct_queries/src/jar/resolver/java/org/mulgara/resolver/DatabaseSessionListQueryUnitTest.java	2009-08-13 17:39:34 UTC (rev 1774)
+++ branches/distinct_queries/src/jar/resolver/java/org/mulgara/resolver/DatabaseSessionListQueryUnitTest.java	2009-08-13 18:33:16 UTC (rev 1775)
@@ -302,6 +302,7 @@
         (List<Order>)Collections.EMPTY_LIST, // no ordering
         null, // no limit
         0, // zero offset
+        true, // distinct results
         new UnconstrainedAnswer() // nothing given
         );
   }

Modified: branches/distinct_queries/src/jar/resolver/java/org/mulgara/resolver/DatabaseSessionUnitTest.java
===================================================================
--- branches/distinct_queries/src/jar/resolver/java/org/mulgara/resolver/DatabaseSessionUnitTest.java	2009-08-13 17:39:34 UTC (rev 1774)
+++ branches/distinct_queries/src/jar/resolver/java/org/mulgara/resolver/DatabaseSessionUnitTest.java	2009-08-13 18:33:16 UTC (rev 1775)
@@ -547,7 +547,6 @@
   // Test cases
   //
 
-  @SuppressWarnings("unchecked")
   public void testModel() {
     try {
       logger.debug("Testing: " + test.errorString);
@@ -565,6 +564,7 @@
           orderList,                // ORDER BY
           null,                     // LIMIT
           0,                        // OFFSET
+          true,                                             // DISTINCT
           new UnconstrainedAnswer() // GIVEN
         )));
 

Modified: branches/distinct_queries/src/jar/resolver/java/org/mulgara/resolver/DefaultConstraintHandlers.java
===================================================================
--- branches/distinct_queries/src/jar/resolver/java/org/mulgara/resolver/DefaultConstraintHandlers.java	2009-08-13 17:39:34 UTC (rev 1774)
+++ branches/distinct_queries/src/jar/resolver/java/org/mulgara/resolver/DefaultConstraintHandlers.java	2009-08-13 18:33:16 UTC (rev 1775)
@@ -176,7 +176,8 @@
             List l =
                 context.resolveConstraintOperation(modelExpr, (ConstraintOperation)constraintExpr);
             try {
-              return TuplesOperations.append(l);
+              if (context.isDistinctQuery()) return TuplesOperations.append(l);
+              else return TuplesOperations.unorderedAppend(l);
             } finally {
               Iterator i = l.iterator();
               while (i.hasNext()) {
@@ -187,13 +188,19 @@
         }),
         new NVPair(ConstraintDifference.class, new ConstraintResolutionHandler() {
           public Tuples resolve(QueryEvaluationContext context, GraphExpression modelExpr, ConstraintExpression constraintExpr) throws Exception {
-            List args = context.resolveConstraintOperation(modelExpr, (ConstraintOperation)constraintExpr);
-            assert args.size() == 2;
+            List<ConstraintExpression> constraints = ((ConstraintOperation)constraintExpr).getElements();
+            assert constraints.size() == 2;
+            Tuples lhs = ConstraintOperations.resolveConstraintExpression(context, modelExpr, constraints.get(0));
+            // The RHS must be searchable, so it must return a distinct result
+            // since DISTINCT forces sorting
+            boolean distinct = context.setDistinctQuery(true);
+            Tuples rhs = ConstraintOperations.resolveConstraintExpression(context, modelExpr, constraints.get(1));
+            context.setDistinctQuery(distinct);
             try {
-              return TuplesOperations.subtract((Tuples)args.get(0), (Tuples)args.get(1));
+              return TuplesOperations.subtract(lhs, rhs);
             } finally {
-              ((Tuples)args.get(0)).close();
-              ((Tuples)args.get(1)).close();
+              lhs.close();
+              rhs.close();
             }
           }
         }),

Modified: branches/distinct_queries/src/jar/resolver/java/org/mulgara/resolver/ExternalTransactionUnitTest.java
===================================================================
--- branches/distinct_queries/src/jar/resolver/java/org/mulgara/resolver/ExternalTransactionUnitTest.java	2009-08-13 17:39:34 UTC (rev 1774)
+++ branches/distinct_queries/src/jar/resolver/java/org/mulgara/resolver/ExternalTransactionUnitTest.java	2009-08-13 18:33:16 UTC (rev 1775)
@@ -602,6 +602,7 @@
           ),
           null,                                             // LIMIT
           0,                                                // OFFSET
+          true,                                             // DISTINCT
           new UnconstrainedAnswer()                         // GIVEN
         )));
 
@@ -619,6 +620,7 @@
           ),
           null,                                             // LIMIT
           0,                                                // OFFSET
+          true,                                             // DISTINCT
           new UnconstrainedAnswer()                         // GIVEN
         ));
 
@@ -683,6 +685,7 @@
           ),
           null,                                             // LIMIT
           0,                                                // OFFSET
+          true,                                             // DISTINCT
           new UnconstrainedAnswer()                         // GIVEN
         )));
 
@@ -700,6 +703,7 @@
           ),
           null,                                             // LIMIT
           0,                                                // OFFSET
+          true,                                             // DISTINCT
           new UnconstrainedAnswer()                         // GIVEN
         ));
 
@@ -2578,6 +2582,7 @@
       }),
       null,                                             // LIMIT
       0,                                                // OFFSET
+      true,                                             // DISTINCT
       new UnconstrainedAnswer()                         // GIVEN
     );
   }

Modified: branches/distinct_queries/src/jar/resolver/java/org/mulgara/resolver/JotmTransactionStandaloneTest.java
===================================================================
--- branches/distinct_queries/src/jar/resolver/java/org/mulgara/resolver/JotmTransactionStandaloneTest.java	2009-08-13 17:39:34 UTC (rev 1774)
+++ branches/distinct_queries/src/jar/resolver/java/org/mulgara/resolver/JotmTransactionStandaloneTest.java	2009-08-13 18:33:16 UTC (rev 1775)
@@ -503,6 +503,7 @@
           ),
           null,                                             // LIMIT
           0,                                                // OFFSET
+          true,                                             // DISTINCT
           new UnconstrainedAnswer()                         // GIVEN
         )));
 
@@ -520,6 +521,7 @@
           ),
           null,                                             // LIMIT
           0,                                                // OFFSET
+          true,                                             // DISTINCT
           new UnconstrainedAnswer()                         // GIVEN
         ));
 
@@ -1523,6 +1525,7 @@
       }),
       null,                                             // LIMIT
       0,                                                // OFFSET
+      true,                                             // DISTINCT
       new UnconstrainedAnswer()                         // GIVEN
     );
   }

Modified: branches/distinct_queries/src/jar/resolver/java/org/mulgara/resolver/LocalJRDFDatabaseSession.java
===================================================================
--- branches/distinct_queries/src/jar/resolver/java/org/mulgara/resolver/LocalJRDFDatabaseSession.java	2009-08-13 17:39:34 UTC (rev 1774)
+++ branches/distinct_queries/src/jar/resolver/java/org/mulgara/resolver/LocalJRDFDatabaseSession.java	2009-08-13 18:33:16 UTC (rev 1775)
@@ -196,6 +196,7 @@
           (List<Order>)Collections.EMPTY_LIST,          // no ordering
           null,                            // no limit
           0,                               // zero offset
+          true,                            // distinct results
           new UnconstrainedAnswer()        // nothing given
       );
 

Modified: branches/distinct_queries/src/jar/resolver/java/org/mulgara/resolver/LocalQueryResolver.java
===================================================================
--- branches/distinct_queries/src/jar/resolver/java/org/mulgara/resolver/LocalQueryResolver.java	2009-08-13 17:39:34 UTC (rev 1774)
+++ branches/distinct_queries/src/jar/resolver/java/org/mulgara/resolver/LocalQueryResolver.java	2009-08-13 18:33:16 UTC (rev 1775)
@@ -91,6 +91,8 @@
 
   private ResolverSession resolverSession;
 
+  private boolean distinctQuery = false;
+
   // Constructor
   LocalQueryResolver(DatabaseOperationContext operationContext, ResolverSession resolverSession) {
     if (operationContext == null) {
@@ -207,8 +209,26 @@
     return resolverSession;
   }
 
-  Tuples resolveMap(Query query, Map outerBindings) throws QueryException
-  {
+  /**
+   * Indicates that the query being run in this context should return distinct results.
+   * @return If <code>true</code>, then return distinct results. Otherwise allow for duplicates.
+   */
+  public boolean isDistinctQuery() {
+    return distinctQuery;
+  }
+
+  /**
+   * Sets the "distinct" status of a query context, returning the previous value.
+   * @param newValue The new value to set the distinct status to. 
+   * @return The previous value of the distinct status.
+   */
+  public boolean setDistinctQuery(boolean newValue) {
+    boolean oldValue = distinctQuery;
+    distinctQuery = newValue;
+    return oldValue;
+  }
+
+  Tuples resolveMap(Query query, Map outerBindings) throws QueryException {
     try {
       Query newQuery = new Query(
           query.getVariableList(),
@@ -220,6 +240,7 @@
           query.getOrderList(),
           query.getLimit(),
           query.getOffset(),
+          query.isDistinct(),
           (Answer)query.getGiven().clone());
           
       return operationContext.innerCount(newQuery);
@@ -266,6 +287,7 @@
         logger.debug(new StackTrace().toString());
       }
 
+//    distinctQuery = query.isDistinct();
       Tuples result = ConstraintOperations.resolveConstraintExpression(this,
           query.getModelExpression(), query.getConstraintExpression());
 
@@ -307,7 +329,7 @@
           }
         }
 
-        result = TuplesOperations.project(result, variables);
+        result = TuplesOperations.project(result, variables, query.isDistinct());
       } finally {
         tmp.close();
       }

Modified: branches/distinct_queries/src/jar/resolver/java/org/mulgara/resolver/XADatabaseSessionUnitTest.java
===================================================================
--- branches/distinct_queries/src/jar/resolver/java/org/mulgara/resolver/XADatabaseSessionUnitTest.java	2009-08-13 17:39:34 UTC (rev 1774)
+++ branches/distinct_queries/src/jar/resolver/java/org/mulgara/resolver/XADatabaseSessionUnitTest.java	2009-08-13 18:33:16 UTC (rev 1775)
@@ -618,6 +618,7 @@
           orderList,                // ORDER BY
           null,                     // LIMIT
           0,                        // OFFSET
+          true,                     // DISTINCT
           new UnconstrainedAnswer() // GIVEN
         )));
 

Modified: branches/distinct_queries/src/jar/resolver-distributed/java/org/mulgara/resolver/distributed/NetworkDelegator.java
===================================================================
--- branches/distinct_queries/src/jar/resolver-distributed/java/org/mulgara/resolver/distributed/NetworkDelegator.java	2009-08-13 17:39:34 UTC (rev 1774)
+++ branches/distinct_queries/src/jar/resolver-distributed/java/org/mulgara/resolver/distributed/NetworkDelegator.java	2009-08-13 18:33:16 UTC (rev 1775)
@@ -216,7 +216,7 @@
     // convert the variable set to a variable list - add types via unchecked casts
     List<Variable> variables = new ArrayList<Variable>((Set<Variable>)globalConstraint.getVariables());
     // build the new query
-    return new Query(variables, new GraphResource(model.getURI()), globalConstraint, null, Collections.EMPTY_LIST, null, 0, new UnconstrainedAnswer());
+    return new Query(variables, new GraphResource(model.getURI()), globalConstraint, null, Collections.EMPTY_LIST, null, 0, true, new UnconstrainedAnswer());
   }
 
 
@@ -357,3 +357,4 @@
     }
   }
 }
+

Modified: branches/distinct_queries/src/jar/resolver-gis/java/org/mulgara/resolver/gis/WritableGISResolver.java
===================================================================
--- branches/distinct_queries/src/jar/resolver-gis/java/org/mulgara/resolver/gis/WritableGISResolver.java	2009-08-13 17:39:34 UTC (rev 1774)
+++ branches/distinct_queries/src/jar/resolver-gis/java/org/mulgara/resolver/gis/WritableGISResolver.java	2009-08-13 18:33:16 UTC (rev 1775)
@@ -247,7 +247,7 @@
           StatementStore.VARIABLES[1],
           StatementStore.VARIABLES[2]
       };
-      projectedDistTypes = TuplesOperations.project(distanceTypes, Arrays.asList(vars));
+      projectedDistTypes = TuplesOperations.project(distanceTypes, Arrays.asList(vars), true);
       if (!isEmpty(distanceTypes)) {
         distTypeStatements = new TuplesWrapperStatements((Tuples)distanceTypes.clone(), d, vars[1], vars[2]);
       }

Modified: branches/distinct_queries/src/jar/resolver-relational/java/org/mulgara/resolver/relational/RelationalResolverUnitTest.java
===================================================================
--- branches/distinct_queries/src/jar/resolver-relational/java/org/mulgara/resolver/relational/RelationalResolverUnitTest.java	2009-08-13 17:39:34 UTC (rev 1774)
+++ branches/distinct_queries/src/jar/resolver-relational/java/org/mulgara/resolver/relational/RelationalResolverUnitTest.java	2009-08-13 18:33:16 UTC (rev 1775)
@@ -387,6 +387,7 @@
           Collections.singletonList(new Order(new Variable("s"), true)),     // ORDER BY
           null,                     // LIMIT
           0,                        // OFFSET
+          true,                     // DISTINCT
           new UnconstrainedAnswer() // GIVEN
         ));
 
@@ -429,6 +430,7 @@
           orderList,     // ORDER BY
           null,                     // LIMIT
           0,                        // OFFSET
+          true,                     // DISTINCT
           new UnconstrainedAnswer() // GIVEN
         ));
 
@@ -474,6 +476,7 @@
           orderList,     // ORDER BY
           null,                     // LIMIT
           0,                        // OFFSET
+          true,                     // DISTINCT
           new UnconstrainedAnswer() // GIVEN
         ));
 
@@ -515,6 +518,7 @@
           orderList,     // ORDER BY
           null,                     // LIMIT
           0,                        // OFFSET
+          true,                     // DISTINCT
           new UnconstrainedAnswer() // GIVEN
         ));
 
@@ -561,6 +565,7 @@
           orderList,     // ORDER BY
           null,                     // LIMIT
           0,                        // OFFSET
+          true,                     // DISTINCT
           new UnconstrainedAnswer() // GIVEN
         ));
 
@@ -597,6 +602,7 @@
           Collections.singletonList(new Order(new Variable("s"), true)),     // ORDER BY
           null,                     // LIMIT
           0,                        // OFFSET
+          true,                     // DISTINCT
           new UnconstrainedAnswer() // GIVEN
         ));
 
@@ -639,6 +645,7 @@
           orderList,     // ORDER BY
           null,                     // LIMIT
           0,                        // OFFSET
+          true,                     // DISTINCT
           new UnconstrainedAnswer() // GIVEN
         ));
 
@@ -683,6 +690,7 @@
           orderList,     // ORDER BY
           null,                     // LIMIT
           0,                        // OFFSET
+          true,                     // DISTINCT
           new UnconstrainedAnswer() // GIVEN
         ));
 
@@ -725,6 +733,7 @@
           orderList,     // ORDER BY
           null,                     // LIMIT
           0,                        // OFFSET
+          true,                     // DISTINCT
           new UnconstrainedAnswer() // GIVEN
         ));
 
@@ -810,6 +819,7 @@
           orderList,     // ORDER BY
           null,                     // LIMIT
           0,                        // OFFSET
+          true,                     // DISTINCT
           new UnconstrainedAnswer() // GIVEN
         ));
 
@@ -855,6 +865,7 @@
           orderList,     // ORDER BY
           null,                     // LIMIT
           0,                        // OFFSET
+          true,                     // DISTINCT
           new UnconstrainedAnswer() // GIVEN
         ));
 
@@ -904,6 +915,7 @@
           orderList,     // ORDER BY
           null,                     // LIMIT
           0,                        // OFFSET
+          true,                     // DISTINCT
           new UnconstrainedAnswer() // GIVEN
         ));
 
@@ -962,6 +974,7 @@
           orderList,     // ORDER BY
           null,                     // LIMIT
           0,                        // OFFSET
+          true,                     // DISTINCT
           new UnconstrainedAnswer() // GIVEN
         ));
 
@@ -1010,6 +1023,7 @@
           orderList,     // ORDER BY
           null,                     // LIMIT
           0,                        // OFFSET
+          true,                     // DISTINCT
           new UnconstrainedAnswer() // GIVEN
         ));
 
@@ -1051,6 +1065,7 @@
           orderList,     // ORDER BY
           null,                     // LIMIT
           0,                        // OFFSET
+          true,                     // DISTINCT
           new UnconstrainedAnswer() // GIVEN
         ));
 
@@ -1105,6 +1120,7 @@
           orderList,     // ORDER BY
           null,                     // LIMIT
           0,                        // OFFSET
+          true,                     // DISTINCT
           new UnconstrainedAnswer() // GIVEN
         ));
 
@@ -1174,6 +1190,7 @@
           orderList,     // ORDER BY
           null,                     // LIMIT
           0,                        // OFFSET
+          true,                     // DISTINCT
           new UnconstrainedAnswer() // GIVEN
         ));
 
@@ -1232,6 +1249,7 @@
           orderList,     // ORDER BY
           null,                     // LIMIT
           0,                        // OFFSET
+          true,                     // DISTINCT
           new UnconstrainedAnswer() // GIVEN
         ));
 
@@ -1292,6 +1310,7 @@
           orderList,     // ORDER BY
           null,                     // LIMIT
           0,                        // OFFSET
+          true,                     // DISTINCT
           new UnconstrainedAnswer() // GIVEN
         ));
 
@@ -1347,6 +1366,7 @@
           orderList,     // ORDER BY
           null,                     // LIMIT
           0,                        // OFFSET
+          true,                     // DISTINCT
           new UnconstrainedAnswer() // GIVEN
         ));
 
@@ -1402,6 +1422,7 @@
           orderList,     // ORDER BY
           null,                     // LIMIT
           0,                        // OFFSET
+          true,                     // DISTINCT
           new UnconstrainedAnswer() // GIVEN
         ));
 
@@ -1474,6 +1495,7 @@
           orderList,     // ORDER BY
           null,                     // LIMIT
           0,                        // OFFSET
+          true,                     // DISTINCT
           new UnconstrainedAnswer() // GIVEN
         ));
 

Modified: branches/distinct_queries/src/jar/resolver-spi/java/org/mulgara/resolver/spi/QueryEvaluationContext.java
===================================================================
--- branches/distinct_queries/src/jar/resolver-spi/java/org/mulgara/resolver/spi/QueryEvaluationContext.java	2009-08-13 17:39:34 UTC (rev 1774)
+++ branches/distinct_queries/src/jar/resolver-spi/java/org/mulgara/resolver/spi/QueryEvaluationContext.java	2009-08-13 18:33:16 UTC (rev 1775)
@@ -87,4 +87,18 @@
 
   public List<Tuples> resolveConstraintOperation(GraphExpression modelExpr,
                                         ConstraintOperation constraintOper) throws QueryException;
+
+  /**
+   * Indicates that the query being run in this context should return distinct results.
+   * @return If <code>true</code>, then return distinct results. Otherwise allow for duplicates.
+   */
+  public boolean isDistinctQuery();
+
+  /**
+   * Sets the "distinct" status of a query context, returning the previous value.
+   * @param newValue The new value to set the distinct status to. 
+   * @return The previous value of the distinct status.
+   */
+  public boolean setDistinctQuery(boolean newValue);
+
 }

Modified: branches/distinct_queries/src/jar/resolver-spi/java/org/mulgara/resolver/spi/SumOfProductExpansionTransformer.java
===================================================================
--- branches/distinct_queries/src/jar/resolver-spi/java/org/mulgara/resolver/spi/SumOfProductExpansionTransformer.java	2009-08-13 17:39:34 UTC (rev 1774)
+++ branches/distinct_queries/src/jar/resolver-spi/java/org/mulgara/resolver/spi/SumOfProductExpansionTransformer.java	2009-08-13 18:33:16 UTC (rev 1775)
@@ -29,6 +29,11 @@
 /**
  * A transformer that works on the basis of expanding a product of sums into a sum of products.
  * This is needed because our disjunctions (sums) are very inefficient, particularly for searching.
+ * Performs the following transforms:
+ * A and (B or C) -> (A and B) or (A and C)
+ * FILTER(A or B, F) -> FILTER(A, F) or FILTER(B, F)
+ * TODO:
+ * A and ((B or C) - D) -> (A and (B - D)) or (A and (C - D))
  *
  * @created August 7, 2009
  * @author Paul Gearon

Modified: branches/distinct_queries/src/jar/resolver-spi/java/org/mulgara/store/statement/StatementStoreAbstractUnitTest.java
===================================================================
--- branches/distinct_queries/src/jar/resolver-spi/java/org/mulgara/store/statement/StatementStoreAbstractUnitTest.java	2009-08-13 17:39:34 UTC (rev 1774)
+++ branches/distinct_queries/src/jar/resolver-spi/java/org/mulgara/store/statement/StatementStoreAbstractUnitTest.java	2009-08-13 18:33:16 UTC (rev 1775)
@@ -185,7 +185,7 @@
     TestTuples expected = getDump();
 
     Tuples t = store.findTuples(NodePool.NONE, NodePool.NONE, NodePool.NONE, NodePool.NONE);
-    Tuples r = TuplesOperations.project(t, Arrays.asList(StatementStore.VARIABLES));
+    Tuples r = TuplesOperations.project(t, Arrays.asList(StatementStore.VARIABLES), true);
     assertEquals(expected, r);
     t.close();
     r.close();

Modified: branches/distinct_queries/src/jar/resolver-test/java/org/mulgara/resolver/test/TestResolverUnitTest.java
===================================================================
--- branches/distinct_queries/src/jar/resolver-test/java/org/mulgara/resolver/test/TestResolverUnitTest.java	2009-08-13 17:39:34 UTC (rev 1774)
+++ branches/distinct_queries/src/jar/resolver-test/java/org/mulgara/resolver/test/TestResolverUnitTest.java	2009-08-13 18:33:16 UTC (rev 1775)
@@ -142,9 +142,10 @@
           { new Order(varArray[0], true), new Order(varArray[1], true), }),     // ORDER BY
       null,                                                                     // LIMIT
       0,                                                                        // OFFSET
+      true,                                                                     // DISTINCT
       new UnconstrainedAnswer()                                                 // GIVEN
     ));
-    
+
     String[][] result = new String[][] {
       new String[] { "A", "A" },
       new String[] { "A", "B" },
@@ -189,6 +190,7 @@
           { new Order(varArray[0], true), new Order(varArray[1], true), }),     // ORDER BY
       null,                                                                     // LIMIT
       0,                                                                        // OFFSET
+      true,                                                                     // DISTINCT
       new UnconstrainedAnswer()                                                 // GIVEN
     ));
     
@@ -238,6 +240,7 @@
 				new Order(varArray[2], true) }),
       null,                                                                     // LIMIT
       0,                                                                        // OFFSET
+      true,                                                                     // DISTINCT
       new UnconstrainedAnswer()                                                 // GIVEN
     ));
     
@@ -289,6 +292,7 @@
 				new Order(varArray[2], true) }),
       null,                                                                     // LIMIT
       0,                                                                        // OFFSET
+      true,                                                                     // DISTINCT
       new UnconstrainedAnswer()                                                 // GIVEN
     ));
     
@@ -341,6 +345,7 @@
 					new Order(varArray[2], true) }),
 				null,                                                                     // LIMIT
 				0,                                                                        // OFFSET
+        true,                                                                     // DISTINCT
 				new UnconstrainedAnswer()                                                 // GIVEN
 			));
 
@@ -358,6 +363,7 @@
    *
    * @throws Exception EXCEPTION TO DO
    */
+  @SuppressWarnings("deprecation")
   protected void setUp() throws Exception {
 		if (database == null) {
 			// Create the persistence directory

Modified: branches/distinct_queries/src/jar/resolver-view/java/org/mulgara/resolver/view/ViewResolverUnitTest.java
===================================================================
--- branches/distinct_queries/src/jar/resolver-view/java/org/mulgara/resolver/view/ViewResolverUnitTest.java	2009-08-13 17:39:34 UTC (rev 1774)
+++ branches/distinct_queries/src/jar/resolver-view/java/org/mulgara/resolver/view/ViewResolverUnitTest.java	2009-08-13 18:33:16 UTC (rev 1775)
@@ -615,6 +615,7 @@
           orderList,                // ORDER BY
           null,                     // LIMIT
           0,                        // OFFSET
+          true,                     // DISTINCT
           new UnconstrainedAnswer() // GIVEN
         )));
 

Modified: branches/distinct_queries/src/jar/swrl/java/org/mulgara/swrl/SWRLLoader.java
===================================================================
--- branches/distinct_queries/src/jar/swrl/java/org/mulgara/swrl/SWRLLoader.java	2009-08-13 17:39:34 UTC (rev 1774)
+++ branches/distinct_queries/src/jar/swrl/java/org/mulgara/swrl/SWRLLoader.java	2009-08-13 18:33:16 UTC (rev 1775)
@@ -813,6 +813,7 @@
         (List<Order>)Collections.EMPTY_LIST,        // ORDER BY
         null,                                       // LIMIT
         0,                                          // OFFSET
+        true,                                       // DISTINCT
         UNCONSTRAINED                               // GIVEN
     );
   }

Modified: branches/distinct_queries/src/jar/tuples/java/org/mulgara/store/tuples/TuplesOperations.java
===================================================================
--- branches/distinct_queries/src/jar/tuples/java/org/mulgara/store/tuples/TuplesOperations.java	2009-08-13 17:39:34 UTC (rev 1774)
+++ branches/distinct_queries/src/jar/tuples/java/org/mulgara/store/tuples/TuplesOperations.java	2009-08-13 18:33:16 UTC (rev 1775)
@@ -178,7 +178,7 @@
     } else {
       List<Tuples> projected = new ArrayList<Tuples>();
       for (Tuples operand: operands) {
-        Tuples proj = project(operand, variables);
+        Tuples proj = project(operand, variables, true);
         Tuples sorted = sort(proj);
         projected.add(sorted);
         proj.close();
@@ -257,7 +257,7 @@
     } else {
       List<Tuples> projected = new ArrayList<Tuples>();
       for (Tuples operand: operands) {
-        Tuples proj = project(operand, variables);
+        Tuples proj = project(operand, variables, false);
         projected.add(proj);
         operand.close();
       }
@@ -409,7 +409,7 @@
         // yes, there are extra variables
         logger.debug("removing extra variables not needed in subtraction");
         // project out the extra variables (sorting happens in projection)
-        sortedSubtrahend = project(subtrahend, new ArrayList<Variable>(matchingVars));
+        sortedSubtrahend = project(subtrahend, new ArrayList<Variable>(matchingVars), true);
       } else {
         // there were no extra variables in the subtrahend
         logger.debug("All variables needed");
@@ -794,12 +794,13 @@
    * Relational projection. This eliminates any columns not in the specified
    * list, and eliminates any duplicate rows that result.
    *
-   * @param tuples PARAMETER TO DO
+   * @param tuples The original tuples to project
    * @param variableList the list of {@link Variable}s to project on
-   * @return RETURNED VALUE TO DO
+   * @param distinct indicates that duplicate rows should be removed
+   * @return The tuples, with only the required columns, and possibly with duplicates removed
    * @throws TuplesException if the projection operation fails
    */
-  public static Tuples project(Tuples tuples, List<Variable> variableList) throws TuplesException {
+  public static Tuples project(Tuples tuples, List<Variable> variableList, boolean distinct) throws TuplesException {
     try {
 
       boolean noVariables = (variableList == null) || (variableList.size() == 0);
@@ -812,9 +813,9 @@
       if (logger.isDebugEnabled()) logger.debug("Projecting to " + variableList);
 
       // Perform the actual projection
-      Tuples oldTuples = tuples;
+      Tuples originalTuples = tuples;
       tuples = new UnorderedProjection(tuples, variableList);
-      assert tuples != oldTuples;
+      assert tuples != originalTuples;
 
       // Test whether creating an unordered projects has removed variables.
       if (tuples.isUnconstrained()) {
@@ -823,18 +824,19 @@
       }
 
       // Eliminate any duplicates
-      oldTuples = tuples;
-      tuples = removeDuplicates(tuples);
-      assert tuples != oldTuples;
+      if (distinct) {
+        Tuples oldTuples = tuples;
+        tuples = removeDuplicates(tuples);
+        assert tuples != oldTuples;
 
-      if (tuples == oldTuples) {
-        logger.warn("removeDuplicates does not change the underlying tuples");
-      } else {
-        oldTuples.close();
+        if (tuples == oldTuples) {
+          logger.warn("removeDuplicates does not change the underlying tuples");
+        } else {
+          oldTuples.close();
+        }
+        assert tuples.hasNoDuplicates();
       }
 
-      assert tuples.hasNoDuplicates();
-
       return tuples;
     } catch (TuplesException e) {
       throw new TuplesException("Couldn't perform projection", e);




More information about the Mulgara-svn mailing list