LUCENE-6001: DrillSideways hits NullPointerException for some BooleanQuery searches

git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1662681 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Michael McCandless 2015-02-27 14:02:47 +00:00
parent 0a169719c7
commit e98b031bda
3 changed files with 67 additions and 9 deletions

View File

@ -61,6 +61,10 @@ Bug Fixes
* LUCENE-6293: Fixed TimSorter bug. (Adrien Grand) * LUCENE-6293: Fixed TimSorter bug. (Adrien Grand)
* LUCENE-6001: DrillSideways hits NullPointerException for certain
BooleanQuery searches. (Dragan Jotannovic, jane chang via Mike
McCandless)
Optimizations Optimizations
* LUCENE-6183, LUCENE-5647: Avoid recompressing stored fields * LUCENE-6183, LUCENE-5647: Avoid recompressing stored fields

View File

@ -98,6 +98,24 @@ class DrillSidewaysScorer extends BulkScorer {
// change up the order of the conjuntions below // change up the order of the conjuntions below
assert baseScorer != null; 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: // Position all scorers to their first matching doc:
baseScorer.nextDoc(); baseScorer.nextDoc();
int numBits = 0; int numBits = 0;
@ -109,14 +127,11 @@ class DrillSidewaysScorer extends BulkScorer {
} }
} }
final int numDims = dims.length;
Bits[] bits = new Bits[numBits]; Bits[] bits = new Bits[numBits];
LeafCollector[] bitsSidewaysCollectors = new LeafCollector[numBits]; LeafCollector[] bitsSidewaysCollectors = new LeafCollector[numBits];
DocIdSetIterator[] disis = new DocIdSetIterator[numDims-numBits]; DocIdSetIterator[] disis = new DocIdSetIterator[numDims-numBits];
LeafCollector[] sidewaysCollectors = new LeafCollector[numDims-numBits]; LeafCollector[] sidewaysCollectors = new LeafCollector[numDims-numBits];
long drillDownCost = 0;
int disiUpto = 0; int disiUpto = 0;
int bitsUpto = 0; int bitsUpto = 0;
for (int dim=0;dim<numDims;dim++) { for (int dim=0;dim<numDims;dim++) {
@ -125,9 +140,6 @@ class DrillSidewaysScorer extends BulkScorer {
disis[disiUpto] = disi; disis[disiUpto] = disi;
sidewaysCollectors[disiUpto] = dims[dim].sidewaysLeafCollector; sidewaysCollectors[disiUpto] = dims[dim].sidewaysLeafCollector;
disiUpto++; disiUpto++;
if (disi != null) {
drillDownCost += disi.cost();
}
} else { } else {
bits[bitsUpto] = dims[dim].bits; bits[bitsUpto] = dims[dim].bits;
bitsSidewaysCollectors[bitsUpto] = dims[dim].sidewaysLeafCollector; bitsSidewaysCollectors[bitsUpto] = dims[dim].sidewaysLeafCollector;
@ -135,8 +147,6 @@ class DrillSidewaysScorer extends BulkScorer {
} }
} }
long baseQueryCost = baseScorer.cost();
/* /*
System.out.println("\nbaseDocID=" + baseScorer.docID() + " est=" + estBaseHitCount); System.out.println("\nbaseDocID=" + baseScorer.docID() + " est=" + estBaseHitCount);
System.out.println(" maxDoc=" + context.reader().maxDoc()); System.out.println(" maxDoc=" + context.reader().maxDoc());
@ -150,7 +160,7 @@ class DrillSidewaysScorer extends BulkScorer {
if (bitsUpto > 0 || scoreSubDocsAtOnce || baseQueryCost < drillDownCost/10) { if (bitsUpto > 0 || scoreSubDocsAtOnce || baseQueryCost < drillDownCost/10) {
//System.out.println("queryFirst: baseScorer=" + baseScorer + " disis.length=" + disis.length + " bits.length=" + bits.length); //System.out.println("queryFirst: baseScorer=" + baseScorer + " disis.length=" + disis.length + " bits.length=" + bits.length);
doQueryFirstScoring(collector, disis, sidewaysCollectors, bits, bitsSidewaysCollectors); 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"); //System.out.println("drillDownAdvance");
doDrillDownAdvanceScoring(collector, disis, sidewaysCollectors); doDrillDownAdvanceScoring(collector, disis, sidewaysCollectors);
} else { } else {

View File

@ -44,6 +44,9 @@ import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.IndexWriterConfig; import org.apache.lucene.index.IndexWriterConfig;
import org.apache.lucene.index.RandomIndexWriter; import org.apache.lucene.index.RandomIndexWriter;
import org.apache.lucene.index.Term; 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.DocIdSet;
import org.apache.lucene.search.Filter; import org.apache.lucene.search.Filter;
import org.apache.lucene.search.FilteredQuery; import org.apache.lucene.search.FilteredQuery;
@ -1076,5 +1079,46 @@ public class TestDrillSideways extends FacetTestCase {
writer.close(); writer.close();
IOUtils.close(taxoWriter, searcher.getIndexReader(), taxoReader, dir, taxoDir); 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);
}
} }