[Mulgara-svn] r1439 - trunk/src/jar/resolver-lucene/java/org/mulgara/resolver/lucene

ronald at mulgara.org ronald at mulgara.org
Mon Jan 19 11:28:04 UTC 2009


Author: ronald
Date: 2009-01-19 03:28:03 -0800 (Mon, 19 Jan 2009)
New Revision: 1439

Modified:
   trunk/src/jar/resolver-lucene/java/org/mulgara/resolver/lucene/FullTextStringIndexTuples.java
   trunk/src/jar/resolver-lucene/java/org/mulgara/resolver/lucene/LuceneConstraint.java
   trunk/src/jar/resolver-lucene/java/org/mulgara/resolver/lucene/LuceneResolverUnitTest.java
   trunk/src/jar/resolver-lucene/java/org/mulgara/resolver/lucene/LuceneTransformer.java
Log:
Fix embarassing screwup in r1366: lucene constraints may now again contain
literals in the subject position. Added tests for this.

Modified: trunk/src/jar/resolver-lucene/java/org/mulgara/resolver/lucene/FullTextStringIndexTuples.java
===================================================================
--- trunk/src/jar/resolver-lucene/java/org/mulgara/resolver/lucene/FullTextStringIndexTuples.java	2009-01-19 11:27:58 UTC (rev 1438)
+++ trunk/src/jar/resolver-lucene/java/org/mulgara/resolver/lucene/FullTextStringIndexTuples.java	2009-01-19 11:28:03 UTC (rev 1439)
@@ -140,10 +140,6 @@
       // Validate and globalize subject
       String subject = null;
       ConstraintElement subjectElement = constraint.getSubject();
-      if (subjectElement == null) {
-        // backwards compat with simple constraint
-        subjectElement = constraint.getBindingVar();
-      }
 
       if (subjectElement instanceof Variable) {
         variableList.add((Variable)subjectElement);

Modified: trunk/src/jar/resolver-lucene/java/org/mulgara/resolver/lucene/LuceneConstraint.java
===================================================================
--- trunk/src/jar/resolver-lucene/java/org/mulgara/resolver/lucene/LuceneConstraint.java	2009-01-19 11:27:58 UTC (rev 1438)
+++ trunk/src/jar/resolver-lucene/java/org/mulgara/resolver/lucene/LuceneConstraint.java	2009-01-19 11:28:03 UTC (rev 1439)
@@ -96,33 +96,35 @@
     ConstraintElement p = constraint.getElement(1);
     ConstraintElement o = constraint.getElement(2);
 
-    // extract the binding variable
-    ConstraintElement b = p.equals(searchPred) ? o : s;
-
-    if (!(b instanceof Variable)) {
-      throw new SymbolicTransformationException("Lucene query binder must be a variable: " + b);
-    }
-
-    binder = (Variable)b;
-
     // extract predicate, object, score
     if (p.equals(searchPred)) {
-      if (s.equals(binder)) {
+      if (s.equals(o)) {
         throw new SymbolicTransformationException("subject and object of '" + searchPred +
                                                   "' may not be the same: " + s);
       }
       subject = s;
+      assignBinder(o);
     } else if (p.equals(scorePred)) {
       if (!(o instanceof Variable)) {
         throw new SymbolicTransformationException("Lucene query score must be a variable: " + o);
       }
       score = (Variable)o;
+      assignBinder(s);
     } else {
+      subject = s;
       predicate = p;
       object = o;
     }
   }
 
+  private final void assignBinder(ConstraintElement b) throws SymbolicTransformationException {
+    if (!(b instanceof Variable)) {
+      throw new SymbolicTransformationException("Lucene query binder must be a variable: " + b);
+    }
+
+    binder = (Variable)b;
+  }
+
   /**
    * Merge the given constraint into this lucene constraint.
    *
@@ -130,11 +132,22 @@
    */
   void conjoinWith(LuceneConstraint constraint) throws SymbolicTransformationException {
     model = getNoDup(constraint.model, model, "Can't combine lucene constraints against different models", "model");
-    subject = getNoDup(constraint.subject, subject, "Can't combine lucene constraints with different subjects", "subj");
+
+    if (binder != null && constraint.binder != null) {
+      subject = getNoDup(constraint.subject, subject, "Can't combine lucene constraints with different subjects", "subj");
+      assignBinder(getNoDup(constraint.binder, binder, "Mismatched binder variable", "var"));
+    } else if (binder != null) {
+      assignBinder(getNoDup(constraint.subject, binder, "Mismatched binder variable", "var"));
+    } else if (constraint.binder != null) {
+      assignBinder(getNoDup(constraint.binder, subject, "Mismatched binder variable", "var"));
+      subject = constraint.subject;
+    } else {
+      subject = getNoDup(constraint.subject, subject, "Can't combine lucene constraints with different subjects", "subj");
+    }
+
     predicate = getNoDup(constraint.predicate, predicate, "Only one predicate supported per search", "pred");
     object = getNoDup(constraint.object, object, "Only one object supported per search", "obj");
 
-    binder = getNoDup(constraint.binder, binder, "Mismatched binder variable", "var");
     score = getNoDup(constraint.score, score, "Only one score supported per search", "score");
   }
 
@@ -165,7 +178,7 @@
     if (subject == null && score != null)
       throw new SymbolicTransformationException("Missing <mulgara:search> for lucene constraint: " +
                                                 "binder=" + binder + ", predicate=" + predicate +
-                                                "query=" + object + ", score=" + score);
+                                                ", query=" + object + ", score=" + score);
   }
 
   public ConstraintElement getModel() {

Modified: trunk/src/jar/resolver-lucene/java/org/mulgara/resolver/lucene/LuceneResolverUnitTest.java
===================================================================
--- trunk/src/jar/resolver-lucene/java/org/mulgara/resolver/lucene/LuceneResolverUnitTest.java	2009-01-19 11:27:58 UTC (rev 1438)
+++ trunk/src/jar/resolver-lucene/java/org/mulgara/resolver/lucene/LuceneResolverUnitTest.java	2009-01-19 11:28:03 UTC (rev 1439)
@@ -80,7 +80,8 @@
 
   public static Test suite() {
     TestSuite suite = new TestSuite();
-    suite.addTest(new LuceneResolverUnitTest("testConcurrentQuery"));
+    suite.addTest(new LuceneResolverUnitTest("testBasicQueries"));
+    suite.addTest(new LuceneResolverUnitTest("testConcurrentQueries"));
     suite.addTest(new LuceneResolverUnitTest("testConcurrentReadTransaction"));
     suite.addTest(new LuceneResolverUnitTest("testTransactionIsolation"));
     suite.addTest(new LuceneResolverUnitTest("testLuceneConstraint"));
@@ -161,10 +162,79 @@
   }
 
   /**
+   * Basic queries.
+   */
+  public void testBasicQueries() throws Exception {
+    logger.info("Testing basic queries");
+
+    try {
+      Session session = database.newSession();
+
+      try {
+        // Load some test data
+        URI fileURI = new File(textDirectory + File.separator + "data.n3").toURI();
+
+        if (session.modelExists(modelURI)) {
+          session.removeModel(modelURI);
+        }
+        session.createModel(modelURI, luceneModelType);
+        session.setModel(modelURI, new GraphResource(fileURI));
+
+        // Run simple query with variable subject and fixed predicate
+        String q = "select $s from <foo:bar> where $s <foo:hasText> 'American' in <" + modelURI + ">;";
+        Answer answer = session.query(parseQuery(q));
+        compareResults(new String[][] { { "foo:node5" }, { "foo:node6" }, { "foo:node7" } }, answer);
+        answer.close();
+
+        // Run simple query with variable subject and predicate
+        q = "select $s $p from <foo:bar> where $s $p 'American' in <" + modelURI + ">;";
+        answer = session.query(parseQuery(q));
+        compareResults(new String[][] { { "foo:node5", "foo:hasText" },
+                                        { "foo:node6", "foo:hasText" },
+                                        { "foo:node7", "foo:hasText" } },
+                       answer);
+        answer.close();
+
+        // Run simple query with fixed subject and variable predicate
+        q = "select $p from <foo:bar> where <foo:node6> $p 'American' in <" + modelURI + ">;";
+        answer = session.query(parseQuery(q));
+        compareResults(new String[][] { { "foo:hasText" } }, answer);
+        answer.close();
+
+        // Run extended query with variable subject and fixed predicate
+        q = "select $s from <foo:bar> where $s <mulgara:search> $b in <" + modelURI + "> and $b <foo:hasText> 'American' in <" + modelURI + ">;";
+        answer = session.query(parseQuery(q));
+        compareResults(new String[][] { { "foo:node5" }, { "foo:node6" }, { "foo:node7" } }, answer);
+        answer.close();
+
+        // Run extended query with variable subject and predicate
+        q = "select $s $p from <foo:bar> where $s <mulgara:search> $b in <" + modelURI + "> and $b $p 'American' in <" + modelURI + ">;";
+        answer = session.query(parseQuery(q));
+        compareResults(new String[][] { { "foo:node5", "foo:hasText" },
+                                        { "foo:node6", "foo:hasText" },
+                                        { "foo:node7", "foo:hasText" } },
+                       answer);
+        answer.close();
+
+        // Run extended query with fixed subject and variable predicate
+        q = "select $p from <foo:bar> where <foo:node6> <mulgara:search> $b in <" + modelURI + "> and $b $p 'American' in <" + modelURI + ">;";
+        answer = session.query(parseQuery(q));
+        compareResults(new String[][] { { "foo:hasText" } }, answer);
+        answer.close();
+
+      } finally {
+        session.close();
+      }
+    } catch (Exception e) {
+      fail(e);
+    }
+  }
+
+  /**
    * Two queries, in parallel.
    */
-  public void testConcurrentQuery() throws Exception {
-    logger.info("Testing concurrentQuery");
+  public void testConcurrentQueries() throws Exception {
+    logger.info("Testing concurrentQueries");
 
     try {
       // Load some test data
@@ -446,7 +516,7 @@
       transf.transform(context, q);
 
       ConstraintExpression ce = q.getConstraintExpression();
-      checkConstraint(ce, null, "test:title", "blah", "foo", null);
+      checkConstraint(ce, "foo", "test:title", "blah", null, null);
 
       // basic complex query
       q = new TestMutableLocalQuery(parseQuery(
@@ -504,8 +574,8 @@
       transf.transform(context, q);
 
       cc = checkConstraint(q.getConstraintExpression(), 2);
-      checkConstraint(cc.getElements().get(0), null, "test:title", "blah", "foo", null);
-      checkConstraint(cc.getElements().get(1), null, "test:author", "Smith", "foo", null);
+      checkConstraint(cc.getElements().get(0), "foo", "test:title", "blah", null, null);
+      checkConstraint(cc.getElements().get(1), "foo", "test:author", "Smith", null, null);
 
       // two simple queries, shared var and predicate
       q = new TestMutableLocalQuery(parseQuery(
@@ -516,8 +586,8 @@
       transf.transform(context, q);
 
       cc = checkConstraint(q.getConstraintExpression(), 2);
-      checkConstraint(cc.getElements().get(0), null, "test:title", "blah", "foo", null);
-      checkConstraint(cc.getElements().get(1), null, "test:title", "Smith", "foo", null);
+      checkConstraint(cc.getElements().get(0), "foo", "test:title", "blah", null, null);
+      checkConstraint(cc.getElements().get(1), "foo", "test:title", "Smith", null, null);
 
       // two simple queries, separate vars
       q = new TestMutableLocalQuery(parseQuery(
@@ -528,8 +598,8 @@
       transf.transform(context, q);
 
       cc = checkConstraint(q.getConstraintExpression(), 2);
-      checkConstraint(cc.getElements().get(0), null, "test:title", "blah", "foo", null);
-      checkConstraint(cc.getElements().get(1), null, "test:author", "Smith", "bar", null);
+      checkConstraint(cc.getElements().get(0), "foo", "test:title", "blah", null, null);
+      checkConstraint(cc.getElements().get(1), "bar", "test:author", "Smith", null, null);
 
       // two complex queries with scores but shared var
       q = new TestMutableLocalQuery(parseQuery(
@@ -574,7 +644,7 @@
       transf.transform(context, q);
 
       cc = checkConstraint(q.getConstraintExpression(), 2);
-      checkConstraint(cc.getElements().get(0), null, "test:title", "blah", "foo", null);
+      checkConstraint(cc.getElements().get(0), "foo", "test:title", "blah", null, null);
       checkConstraint(cc.getElements().get(1), "foo", "test:author", "Smith", "search2", "score2");
 
       // a simple query and a complex query, shared var, different constraint order
@@ -588,7 +658,7 @@
       transf.transform(context, q);
 
       cc = checkConstraint(q.getConstraintExpression(), 2);
-      checkConstraint(cc.getElements().get(0), null, "test:title", "blah", "foo", null);
+      checkConstraint(cc.getElements().get(0), "foo", "test:title", "blah", null, null);
       checkConstraint(cc.getElements().get(1), "foo", "test:author", "Smith", "search2", "score2");
 
       // a simple query and a complex query, separate vars
@@ -602,7 +672,7 @@
       transf.transform(context, q);
 
       cc = checkConstraint(q.getConstraintExpression(), 2);
-      checkConstraint(cc.getElements().get(0), null, "test:title", "blah", "foo", null);
+      checkConstraint(cc.getElements().get(0), "foo", "test:title", "blah", null, null);
       checkConstraint(cc.getElements().get(1), "bar", "test:author", "Smith", "search2", "score2");
 
       // invalid: complex query with multiple different predicates
@@ -727,12 +797,7 @@
     assertTrue(ce instanceof LuceneConstraint);
     LuceneConstraint lc = (LuceneConstraint)ce;
 
-    if (expSubj != null) {
-      assertTrue(lc.getSubject() instanceof Variable);
-      assertEquals(expSubj, ((Variable)lc.getSubject()).getName());
-    } else {
-      assertNull(lc.getSubject());
-    }
+    assertEquals(expSubj, ((Variable)lc.getSubject()).getName());
 
     assertTrue(lc.getPredicate() instanceof URIReference);
     assertEquals(URI.create(expPred), ((URIReference)lc.getPredicate()).getURI());
@@ -740,7 +805,11 @@
     assertTrue(lc.getObject() instanceof Literal);
     assertEquals(expObj, ((Literal)lc.getObject()).getLexicalForm());
 
-    assertEquals(expBind, lc.getBindingVar().getName());
+    if (expBind != null) {
+      assertEquals(expBind, lc.getBindingVar().getName());
+    } else {
+      assertNull(lc.getBindingVar());
+    }
 
     if (expScore != null) {
       assertEquals(expScore, lc.getScoreVar().getName());

Modified: trunk/src/jar/resolver-lucene/java/org/mulgara/resolver/lucene/LuceneTransformer.java
===================================================================
--- trunk/src/jar/resolver-lucene/java/org/mulgara/resolver/lucene/LuceneTransformer.java	2009-01-19 11:27:58 UTC (rev 1438)
+++ trunk/src/jar/resolver-lucene/java/org/mulgara/resolver/lucene/LuceneTransformer.java	2009-01-19 11:28:03 UTC (rev 1439)
@@ -34,6 +34,7 @@
 import org.mulgara.query.ConstraintConjunction;
 import org.mulgara.query.ConstraintOperation;
 import org.mulgara.query.QueryException;
+import org.mulgara.query.Variable;
 import org.mulgara.query.rdf.URIReferenceImpl;
 import org.mulgara.resolver.spi.AbstractSymbolicTransformer;
 import org.mulgara.resolver.spi.SymbolicTransformationContext;
@@ -117,22 +118,30 @@
 
       if (trans instanceof LuceneConstraint) {
         LuceneConstraint lc = (LuceneConstraint)trans;
-        List<LuceneConstraint> cumulative = luceneArgs.get(lc.getBindingVar());
+        Variable b = lc.getBindingVar();
+        if (b == null && lc.getSubject() instanceof Variable) b = (Variable)lc.getSubject();
+        if (b == null) {
+          retainedArgs.add(lc);
+          continue;
+        }
+
+        List<LuceneConstraint> cumulative = luceneArgs.get(b);
         if (cumulative == null) {
           cumulative = new ArrayList<LuceneConstraint>();
           cumulative.add(lc);
-          luceneArgs.put(lc.getBindingVar(), cumulative);
+          luceneArgs.put(b, cumulative);
         } else if (cumulative.size() > 1 ||
-                   cumulative.get(0).getSubject() == null &&
+                   cumulative.get(0).getBindingVar() == null &&
                    cumulative.get(0).getPredicate() != null &&
-                   lc.getSubject() == null && lc.getPredicate() != null) {
+                   lc.getBindingVar() == null && lc.getPredicate() != null) {
           // backwards compat hack for multiple simple queries
           cumulative.add(lc);
         } else {
           cumulative.iterator().next().conjoinWith(lc);
-          if (logger.isTraceEnabled()) logger.trace("Updated LC with: " + cumulative.iterator().next() + "; result: " + lc);
           transformed = true;
         }
+
+        if (logger.isTraceEnabled()) logger.trace("Updated LC with: " + lc + "; result: " + cumulative);
       } else {
         retainedArgs.add(trans);
       }




More information about the Mulgara-svn mailing list