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 2015/02/27 15:02:48 UTC
svn commit: r1662681 - in /lucene/dev/trunk/lucene: CHANGES.txt
facet/src/java/org/apache/lucene/facet/DrillSidewaysScorer.java
facet/src/test/org/apache/lucene/facet/TestDrillSideways.java
Author: mikemccand
Date: Fri Feb 27 14:02:47 2015
New Revision: 1662681
URL: http://svn.apache.org/r1662681
Log:
LUCENE-6001: DrillSideways hits NullPointerException for some BooleanQuery searches
Modified:
lucene/dev/trunk/lucene/CHANGES.txt
lucene/dev/trunk/lucene/facet/src/java/org/apache/lucene/facet/DrillSidewaysScorer.java
lucene/dev/trunk/lucene/facet/src/test/org/apache/lucene/facet/TestDrillSideways.java
Modified: lucene/dev/trunk/lucene/CHANGES.txt
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/CHANGES.txt?rev=1662681&r1=1662680&r2=1662681&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/CHANGES.txt (original)
+++ lucene/dev/trunk/lucene/CHANGES.txt Fri Feb 27 14:02:47 2015
@@ -61,6 +61,10 @@ Bug Fixes
* LUCENE-6293: Fixed TimSorter bug. (Adrien Grand)
+* LUCENE-6001: DrillSideways hits NullPointerException for certain
+ BooleanQuery searches. (Dragan Jotannovic, jane chang via Mike
+ McCandless)
+
Optimizations
* LUCENE-6183, LUCENE-5647: Avoid recompressing stored fields
Modified: lucene/dev/trunk/lucene/facet/src/java/org/apache/lucene/facet/DrillSidewaysScorer.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/facet/src/java/org/apache/lucene/facet/DrillSidewaysScorer.java?rev=1662681&r1=1662680&r2=1662681&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/facet/src/java/org/apache/lucene/facet/DrillSidewaysScorer.java (original)
+++ lucene/dev/trunk/lucene/facet/src/java/org/apache/lucene/facet/DrillSidewaysScorer.java Fri Feb 27 14:02:47 2015
@@ -98,6 +98,24 @@ class DrillSidewaysScorer extends BulkSc
// change up the order of the conjuntions below
assert baseScorer != null;
+ // some scorers, eg ReqExlScorer, can hit NPE if cost is called after nextDoc
+ long baseQueryCost = baseScorer.cost();
+
+ final int numDims = dims.length;
+
+ long drillDownCost = 0;
+ for (int dim=0;dim<numDims;dim++) {
+ DocIdSetIterator disi = dims[dim].disi;
+ if (dims[dim].bits == null && disi != null) {
+ drillDownCost += disi.cost();
+ }
+ }
+
+ long drillDownAdvancedCost = 0;
+ if (numDims > 1 && dims[1].disi == null) {
+ drillDownAdvancedCost = dims[1].disi.cost();
+ }
+
// Position all scorers to their first matching doc:
baseScorer.nextDoc();
int numBits = 0;
@@ -109,14 +127,11 @@ class DrillSidewaysScorer extends BulkSc
}
}
- final int numDims = dims.length;
-
Bits[] bits = new Bits[numBits];
LeafCollector[] bitsSidewaysCollectors = new LeafCollector[numBits];
DocIdSetIterator[] disis = new DocIdSetIterator[numDims-numBits];
LeafCollector[] sidewaysCollectors = new LeafCollector[numDims-numBits];
- long drillDownCost = 0;
int disiUpto = 0;
int bitsUpto = 0;
for (int dim=0;dim<numDims;dim++) {
@@ -125,9 +140,6 @@ class DrillSidewaysScorer extends BulkSc
disis[disiUpto] = disi;
sidewaysCollectors[disiUpto] = dims[dim].sidewaysLeafCollector;
disiUpto++;
- if (disi != null) {
- drillDownCost += disi.cost();
- }
} else {
bits[bitsUpto] = dims[dim].bits;
bitsSidewaysCollectors[bitsUpto] = dims[dim].sidewaysLeafCollector;
@@ -135,8 +147,6 @@ class DrillSidewaysScorer extends BulkSc
}
}
- long baseQueryCost = baseScorer.cost();
-
/*
System.out.println("\nbaseDocID=" + baseScorer.docID() + " est=" + estBaseHitCount);
System.out.println(" maxDoc=" + context.reader().maxDoc());
@@ -150,7 +160,7 @@ class DrillSidewaysScorer extends BulkSc
if (bitsUpto > 0 || scoreSubDocsAtOnce || baseQueryCost < drillDownCost/10) {
//System.out.println("queryFirst: baseScorer=" + baseScorer + " disis.length=" + disis.length + " bits.length=" + bits.length);
doQueryFirstScoring(collector, disis, sidewaysCollectors, bits, bitsSidewaysCollectors);
- } else if (numDims > 1 && (dims[1].disi == null || dims[1].disi.cost() < baseQueryCost/10)) {
+ } else if (numDims > 1 && (dims[1].disi == null || drillDownAdvancedCost < baseQueryCost/10)) {
//System.out.println("drillDownAdvance");
doDrillDownAdvanceScoring(collector, disis, sidewaysCollectors);
} else {
Modified: lucene/dev/trunk/lucene/facet/src/test/org/apache/lucene/facet/TestDrillSideways.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/facet/src/test/org/apache/lucene/facet/TestDrillSideways.java?rev=1662681&r1=1662680&r2=1662681&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/facet/src/test/org/apache/lucene/facet/TestDrillSideways.java (original)
+++ lucene/dev/trunk/lucene/facet/src/test/org/apache/lucene/facet/TestDrillSideways.java Fri Feb 27 14:02:47 2015
@@ -44,6 +44,9 @@ import org.apache.lucene.index.IndexRead
import org.apache.lucene.index.IndexWriterConfig;
import org.apache.lucene.index.RandomIndexWriter;
import org.apache.lucene.index.Term;
+import org.apache.lucene.search.BooleanClause;
+import org.apache.lucene.search.BooleanQuery;
+import org.apache.lucene.search.Collector;
import org.apache.lucene.search.DocIdSet;
import org.apache.lucene.search.Filter;
import org.apache.lucene.search.FilteredQuery;
@@ -1076,5 +1079,46 @@ public class TestDrillSideways extends F
writer.close();
IOUtils.close(taxoWriter, searcher.getIndexReader(), taxoReader, dir, taxoDir);
}
+
+ public void testScorer() throws Exception {
+ // LUCENE-6001 some scorers, eg ReqExlScorer, can hit NPE if cost is called after nextDoc
+ Directory dir = newDirectory();
+ Directory taxoDir = newDirectory();
+
+ // Writes facet ords to a separate directory from the
+ // main index:
+ DirectoryTaxonomyWriter taxoWriter = new DirectoryTaxonomyWriter(taxoDir, IndexWriterConfig.OpenMode.CREATE);
+
+ FacetsConfig config = new FacetsConfig();
+
+ RandomIndexWriter writer = new RandomIndexWriter(random(), dir);
+
+ Document doc = new Document();
+ doc.add(newTextField("field", "foo bar", Field.Store.NO));
+ doc.add(new FacetField("Author", "Bob"));
+ doc.add(new FacetField("dim", "a"));
+ writer.addDocument(config.build(taxoWriter, doc));
+
+ // NRT open
+ IndexSearcher searcher = newSearcher(writer.getReader());
+
+ // NRT open
+ TaxonomyReader taxoReader = new DirectoryTaxonomyReader(taxoWriter);
+
+ DrillSideways ds = new DrillSideways(searcher, config, taxoReader);
+
+ BooleanQuery bq = new BooleanQuery(true);
+ bq.add(new TermQuery(new Term("field", "foo")), BooleanClause.Occur.MUST);
+ bq.add(new TermQuery(new Term("field", "bar")), BooleanClause.Occur.MUST_NOT);
+ DrillDownQuery ddq = new DrillDownQuery(config, bq);
+ ddq.add("field", "foo");
+ ddq.add("author", bq);
+ ddq.add("dim", bq);
+ DrillSidewaysResult r = ds.search(null, ddq, 10);
+ assertEquals(0, r.hits.totalHits);
+
+ writer.close();
+ IOUtils.close(searcher.getIndexReader(), taxoReader, taxoWriter, dir, taxoDir);
+ }
}