Index: lucene/CHANGES.txt =================================================================== --- lucene/CHANGES.txt (revision 1173280) +++ lucene/CHANGES.txt (working copy) @@ -20,6 +20,10 @@ should ignore the maxMergedSegmentMB setting (v.sevel via Mike McCandless) +* LUCENE-3442: TermQuery.TermWeight.scorer() returns null for non-atomic + IndexReaders (optimization bug), preventing QueryWrapperFilter and similar + classes to get a top-level DocIdSet. (Dan C., Uwe Schindler) + New Features Optimizations Index: lucene/src/java/org/apache/lucene/search/TermQuery.java =================================================================== --- lucene/src/java/org/apache/lucene/search/TermQuery.java (revision 1173280) +++ lucene/src/java/org/apache/lucene/search/TermQuery.java (working copy) @@ -94,7 +94,8 @@ @Override public Scorer scorer(IndexReader reader, boolean scoreDocsInOrder, boolean topScorer) throws IOException { - if (hash != null && !hash.contains(reader.hashCode())) { + // only use the early exit condition if we have an atomic reader, because Lucene 3.x still supports non-atomic readers here: + if (hash != null && reader.getSequentialSubReaders() == null && !hash.contains(reader.hashCode())) { return null; } Index: lucene/src/test/org/apache/lucene/search/TestQueryWrapperFilter.java =================================================================== --- lucene/src/test/org/apache/lucene/search/TestQueryWrapperFilter.java (revision 1173280) +++ lucene/src/test/org/apache/lucene/search/TestQueryWrapperFilter.java (working copy) @@ -81,4 +81,37 @@ reader.close(); dir.close(); } + + // this test is for 3.x only, in 4.x we no longer support non-atomic readers passed to getDocIdSet(): + public void test_LUCENE3442() throws Exception { + Directory dir = newDirectory(); + RandomIndexWriter writer = new RandomIndexWriter(random, dir); + Document doc = new Document(); + doc.add(newField("id", "1001", Store.YES, Index.NOT_ANALYZED)); + doc.add(newField("text", "headline one group one", Store.YES, Index.ANALYZED)); + writer.addDocument(doc); + IndexReader rdr = writer.getReader(); + writer.close(); + IndexSearcher searcher = new IndexSearcher(rdr); + TermQuery tq = new TermQuery(new Term("text", "headline")); + TopDocs results = searcher.search(tq, 5); + assertEquals(1, results.totalHits); + + Filter f = new QueryWrapperFilter(tq); + // rdr may not be atomic (it isn't in most cases), TermQuery inside QWF should still work! + DocIdSet dis = f.getDocIdSet(rdr); + assertNotNull(dis); + DocIdSetIterator it = dis.iterator(); + assertNotNull(it); + int docId, count = 0; + while ((docId = it.nextDoc()) != DocIdSetIterator.NO_MORE_DOCS) { + assertEquals("1001", rdr.document(docId).get("id")); + count++; + } + assertEquals(1, count); + searcher.close(); + rdr.close(); + dir.close(); + } + }