From 1d812f3c6a7e7b68d4b0d6e2d304b1a8d7ace35f Mon Sep 17 00:00:00 2001 From: Uwe Schindler Date: Wed, 22 Feb 2012 13:34:48 +0000 Subject: [PATCH] LUCENE-3816: Fixed problem in FilteredDocIdSet, if null was returned from the delegate DocIdSet.iterator(), which is allowed to return null by DocIdSet specification when no documents match. git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1292282 13f79535-47bb-0310-9956-ffa450edef68 --- lucene/CHANGES.txt | 5 +++ .../lucene/search/FilteredDocIdSet.java | 6 ++- .../apache/lucene/search/TestDocIdSet.java | 37 +++++++++++++++++++ 3 files changed, 47 insertions(+), 1 deletion(-) diff --git a/lucene/CHANGES.txt b/lucene/CHANGES.txt index 36f48699afc..dfd029a6fb4 100644 --- a/lucene/CHANGES.txt +++ b/lucene/CHANGES.txt @@ -911,6 +911,11 @@ Bug fixes These checks now use getFilePointer instead to avoid this. (Jamir Shaikh, Mike McCandless, Robert Muir) +* LUCENE-3816: Fixed problem in FilteredDocIdSet, if null was returned + from the delegate DocIdSet.iterator(), which is allowed to return + null by DocIdSet specification when no documents match. + (Shay Banon via Uwe Schindler) + Optimizations * LUCENE-3653: Improve concurrency in VirtualMethod and AttributeSource by diff --git a/lucene/core/src/java/org/apache/lucene/search/FilteredDocIdSet.java b/lucene/core/src/java/org/apache/lucene/search/FilteredDocIdSet.java index e994d1a0391..a9f908a4ab9 100644 --- a/lucene/core/src/java/org/apache/lucene/search/FilteredDocIdSet.java +++ b/lucene/core/src/java/org/apache/lucene/search/FilteredDocIdSet.java @@ -84,7 +84,11 @@ public abstract class FilteredDocIdSet extends DocIdSet { */ @Override public DocIdSetIterator iterator() throws IOException { - return new FilteredDocIdSetIterator(_innerSet.iterator()) { + final DocIdSetIterator iterator = _innerSet.iterator(); + if (iterator == null) { + return null; + } + return new FilteredDocIdSetIterator(iterator) { @Override protected boolean match(int docid) { return FilteredDocIdSet.this.match(docid); diff --git a/lucene/core/src/test/org/apache/lucene/search/TestDocIdSet.java b/lucene/core/src/test/org/apache/lucene/search/TestDocIdSet.java index f2a5553ab4a..43b1c0e46ff 100644 --- a/lucene/core/src/test/org/apache/lucene/search/TestDocIdSet.java +++ b/lucene/core/src/test/org/apache/lucene/search/TestDocIdSet.java @@ -125,4 +125,41 @@ public class TestDocIdSet extends LuceneTestCase { dir.close(); } + public void testNullIteratorFilteredDocIdSet() throws Exception { + Directory dir = newDirectory(); + RandomIndexWriter writer = new RandomIndexWriter(random, dir); + Document doc = new Document(); + doc.add(newField("c", "val", StringField.TYPE_UNSTORED)); + writer.addDocument(doc); + IndexReader reader = writer.getReader(); + writer.close(); + + // First verify the document is searchable. + IndexSearcher searcher = newSearcher(reader); + Assert.assertEquals(1, searcher.search(new MatchAllDocsQuery(), 10).totalHits); + + // Now search w/ a Filter which returns a null DocIdSet + Filter f = new Filter() { + @Override + public DocIdSet getDocIdSet(AtomicReaderContext context, Bits acceptDocs) throws IOException { + final DocIdSet innerNullIteratorSet = new DocIdSet() { + @Override + public DocIdSetIterator iterator() { + return null; + } + }; + return new FilteredDocIdSet(innerNullIteratorSet) { + @Override + protected boolean match(int docid) { + return true; + } + }; + } + }; + + Assert.assertEquals(0, searcher.search(new MatchAllDocsQuery(), f, 10).totalHits); + reader.close(); + dir.close(); + } + }