Index: lucene/CHANGES.txt =================================================================== --- lucene/CHANGES.txt (revision 1292271) +++ lucene/CHANGES.txt (working copy) @@ -911,6 +911,11 @@ 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 Index: lucene/core/src/java/org/apache/lucene/search/FilteredDocIdSet.java =================================================================== --- lucene/core/src/java/org/apache/lucene/search/FilteredDocIdSet.java (revision 1292271) +++ lucene/core/src/java/org/apache/lucene/search/FilteredDocIdSet.java (working copy) @@ -84,7 +84,11 @@ */ @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); Index: lucene/core/src/test/org/apache/lucene/search/TestDocIdSet.java =================================================================== --- lucene/core/src/test/org/apache/lucene/search/TestDocIdSet.java (revision 1292271) +++ lucene/core/src/test/org/apache/lucene/search/TestDocIdSet.java (working copy) @@ -125,4 +125,41 @@ 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(); + } + }