You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by mi...@apache.org on 2011/11/27 20:30:19 UTC

svn commit: r1206807 - in /lucene/dev/trunk/modules/join/src: java/org/apache/lucene/search/join/BlockJoinQuery.java test/org/apache/lucene/search/TestBlockJoin.java

Author: mikemccand
Date: Sun Nov 27 19:30:17 2011
New Revision: 1206807

URL: http://svn.apache.org/viewvc?rev=1206807&view=rev
Log:
LUCENE-3600: fix BJQ to not trip assert when parent doc has no children

Modified:
    lucene/dev/trunk/modules/join/src/java/org/apache/lucene/search/join/BlockJoinQuery.java
    lucene/dev/trunk/modules/join/src/test/org/apache/lucene/search/TestBlockJoin.java

Modified: lucene/dev/trunk/modules/join/src/java/org/apache/lucene/search/join/BlockJoinQuery.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/modules/join/src/java/org/apache/lucene/search/join/BlockJoinQuery.java?rev=1206807&r1=1206806&r2=1206807&view=diff
==============================================================================
--- lucene/dev/trunk/modules/join/src/java/org/apache/lucene/search/join/BlockJoinQuery.java (original)
+++ lucene/dev/trunk/modules/join/src/java/org/apache/lucene/search/join/BlockJoinQuery.java Sun Nov 27 19:30:17 2011
@@ -26,7 +26,6 @@ import org.apache.lucene.index.IndexRead
 import org.apache.lucene.index.IndexReader;
 import org.apache.lucene.index.IndexWriter;       // javadocs
 import org.apache.lucene.index.Term;
-import org.apache.lucene.search.BooleanClause;
 import org.apache.lucene.search.DocIdSet;
 import org.apache.lucene.search.DocIdSetIterator;
 import org.apache.lucene.search.Explanation;
@@ -194,7 +193,7 @@ public class BlockJoinQuery extends Quer
     private final Scorer childScorer;
     private final FixedBitSet parentBits;
     private final ScoreMode scoreMode;
-    private int parentDoc;
+    private int parentDoc = -1;
     private float parentScore;
     private int nextChildDoc;
 
@@ -324,8 +323,15 @@ public class BlockJoinQuery extends Quer
         return parentDoc = NO_MORE_DOCS;
       }
 
-      // Every parent must have at least one child:
-      assert parentTarget != 0;
+      if (parentTarget == 0) {
+        // Callers should only be passing in a docID from
+        // the parent space, so this means this parent
+        // has no children (it got docID 0), so it cannot
+        // possibly match.  We must handle this case
+        // separately otherwise we pass invalid -1 to
+        // prevSetBit below:
+        return nextDoc();
+      }
 
       final int prevParentDoc = parentBits.prevSetBit(parentTarget-1);
 

Modified: lucene/dev/trunk/modules/join/src/test/org/apache/lucene/search/TestBlockJoin.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/modules/join/src/test/org/apache/lucene/search/TestBlockJoin.java?rev=1206807&r1=1206806&r2=1206807&view=diff
==============================================================================
--- lucene/dev/trunk/modules/join/src/test/org/apache/lucene/search/TestBlockJoin.java (original)
+++ lucene/dev/trunk/modules/join/src/test/org/apache/lucene/search/TestBlockJoin.java Sun Nov 27 19:30:17 2011
@@ -21,11 +21,13 @@ import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
 
+import org.apache.lucene.analysis.MockAnalyzer;
 import org.apache.lucene.document.Document;
 import org.apache.lucene.document.Field;
 import org.apache.lucene.document.NumericField;
 import org.apache.lucene.document.StringField;
 import org.apache.lucene.index.IndexReader;
+import org.apache.lucene.index.LogDocMergePolicy;
 import org.apache.lucene.index.RandomIndexWriter;
 import org.apache.lucene.index.Term;
 import org.apache.lucene.search.BooleanClause.Occur;
@@ -36,6 +38,7 @@ import org.apache.lucene.search.join.Blo
 import org.apache.lucene.store.Directory;
 import org.apache.lucene.util.BytesRef;
 import org.apache.lucene.util.LuceneTestCase;
+import org.apache.lucene.util.ReaderUtil;
 import org.apache.lucene.util._TestUtil;
 
 public class TestBlockJoin extends LuceneTestCase {
@@ -85,7 +88,7 @@ public class TestBlockJoin extends Lucen
 
     IndexReader r = w.getReader();
     w.close();
-    IndexSearcher s = new IndexSearcher(r);
+    IndexSearcher s = newSearcher(r);
 
     // Create a filter that defines "parent" documents in the index - in this case resumes
     Filter parentsFilter = new CachingWrapperFilter(new QueryWrapperFilter(new TermQuery(new Term("docType", "resume"))));
@@ -282,10 +285,10 @@ public class TestBlockJoin extends Lucen
       }
     }
 
-    final IndexSearcher s = new IndexSearcher(r);
+    final IndexSearcher s = newSearcher(r);
     s.setDefaultFieldSortScoring(true, true);
 
-    final IndexSearcher joinS = new IndexSearcher(joinR);
+    final IndexSearcher joinS = newSearcher(joinR);
 
     final Filter parentsFilter = new CachingWrapperFilter(new QueryWrapperFilter(new TermQuery(new Term("isParent", "x"))));
 
@@ -516,7 +519,7 @@ public class TestBlockJoin extends Lucen
 
     IndexReader r = w.getReader();
     w.close();
-    IndexSearcher s = new IndexSearcher(r);
+    IndexSearcher s = newSearcher(r);
 
     // Create a filter that defines "parent" documents in the index - in this case resumes
     Filter parentsFilter = new CachingWrapperFilter(new QueryWrapperFilter(new TermQuery(new Term("docType", "resume"))));
@@ -590,4 +593,62 @@ public class TestBlockJoin extends Lucen
     r.close();
     dir.close();
   }
+
+  public void testAdvanceSingleParentSingleChild() throws Exception {
+    Directory dir = newDirectory();
+    RandomIndexWriter w = new RandomIndexWriter(random, dir);
+    Document childDoc = new Document();
+    childDoc.add(newField("child", "1", StringField.TYPE_UNSTORED));
+    Document parentDoc = new Document();
+    parentDoc.add(newField("parent", "1", StringField.TYPE_UNSTORED));
+    w.addDocuments(Arrays.asList(new Document[] {childDoc, parentDoc}));
+    IndexReader r = w.getReader();
+    w.close();
+    IndexSearcher s = newSearcher(r);
+    Query tq = new TermQuery(new Term("child", "1"));
+    Filter parentFilter = new CachingWrapperFilter(
+                            new QueryWrapperFilter(
+                              new TermQuery(new Term("parent", "1"))));
+
+    BlockJoinQuery q = new BlockJoinQuery(tq, parentFilter, BlockJoinQuery.ScoreMode.Avg);
+    Weight weight = s.createNormalizedWeight(q);
+    DocIdSetIterator disi = weight.scorer(ReaderUtil.leaves(s.getIndexReader().getTopReaderContext())[0], true, true, null);
+    assertEquals(1, disi.advance(1));
+    r.close();
+    dir.close();
+  }
+
+  public void testAdvanceSingleParentNoChild() throws Exception {
+    Directory dir = newDirectory();
+    RandomIndexWriter w = new RandomIndexWriter(random, dir, newIndexWriterConfig(TEST_VERSION_CURRENT, new MockAnalyzer(random)).setMergePolicy(new LogDocMergePolicy()));
+    Document parentDoc = new Document();
+    parentDoc.add(newField("parent", "1", StringField.TYPE_UNSTORED));
+    parentDoc.add(newField("isparent", "yes", StringField.TYPE_UNSTORED));
+    w.addDocuments(Arrays.asList(new Document[] {parentDoc}));
+
+    // Add another doc so scorer is not null
+    parentDoc = new Document();
+    parentDoc.add(newField("parent", "2", StringField.TYPE_UNSTORED));
+    parentDoc.add(newField("isparent", "yes", StringField.TYPE_UNSTORED));
+    Document childDoc = new Document();
+    childDoc.add(newField("child", "2", StringField.TYPE_UNSTORED));
+    w.addDocuments(Arrays.asList(new Document[] {childDoc, parentDoc}));
+
+    // Need single seg:
+    w.forceMerge(1);
+    IndexReader r = w.getReader();
+    w.close();
+    IndexSearcher s = newSearcher(r);
+    Query tq = new TermQuery(new Term("child", "2"));
+    Filter parentFilter = new CachingWrapperFilter(
+                            new QueryWrapperFilter(
+                              new TermQuery(new Term("isparent", "yes"))));
+
+    BlockJoinQuery q = new BlockJoinQuery(tq, parentFilter, BlockJoinQuery.ScoreMode.Avg);
+    Weight weight = s.createNormalizedWeight(q);
+    DocIdSetIterator disi = weight.scorer(ReaderUtil.leaves(s.getIndexReader().getTopReaderContext())[0], true, true, null);
+    assertEquals(2, disi.advance(0));
+    r.close();
+    dir.close();
+  }
 }