Skip to content

Commit 27abe1c

Browse files
authored
Utilize iterator and not approximation in MaxScoreBulkScorer (#15380)
* Utilize iterator and not approximation in MaxScoreBulkScorer * CHANGES * add assert on verifiedMatches * adjust assertion * adding some random approx query wrapping * iter
1 parent c3d8ba0 commit 27abe1c

File tree

5 files changed

+29
-2
lines changed

5 files changed

+29
-2
lines changed

lucene/CHANGES.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -224,6 +224,9 @@ Bug Fixes
224224
* GITHUB#15334: Fix NPE for MemoryIndex when using nearest neighbor search. MemoryIndex does not support
225225
nearest neighbor search, but it should not throw an NPE (Ben Trent)
226226

227+
* GITHUB#15380: Fix potential EOF introduced by optimized filter iterations in MaxScoreBulkScorer. The
228+
approximation and the match verification could get out of sync, resulting in an EOFException. (Ben Trent)
229+
227230
Other
228231
---------------------
229232
* GITHUB#15237: Fix SmartChinese to only deserialize dictionary data from classpath with a native array

lucene/core/src/java/org/apache/lucene/search/DisjunctionScorer.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,9 +101,20 @@ DisiWrapper getSubMatches() throws IOException {
101101
}
102102
}
103103
unverifiedMatches.clear();
104+
assert assertVerifiedMatchesApproximationDocID();
104105
return verifiedMatches;
105106
}
106107

108+
private boolean assertVerifiedMatchesApproximationDocID() {
109+
int docID = docID();
110+
for (DisiWrapper w = verifiedMatches; w != null; w = w.next) {
111+
if (w.doc != docID) {
112+
return false;
113+
}
114+
}
115+
return true;
116+
}
117+
107118
@Override
108119
public boolean matches() throws IOException {
109120
verifiedMatches = null;

lucene/core/src/java/org/apache/lucene/search/MaxScoreBulkScorer.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -171,7 +171,8 @@ private void scoreInnerWindowWithFilter(
171171
DisiWrapper top = essentialQueue.top();
172172
assert top.doc < max;
173173
while (top.doc < filter.doc) {
174-
top.doc = top.approximation.advance(filter.doc);
174+
// Must use the iterator as `top` might be a two-phase iterator
175+
top.doc = top.iterator.advance(filter.doc);
175176
top = essentialQueue.updateTop();
176177
}
177178

lucene/core/src/test/org/apache/lucene/search/TestBooleanRewrites.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
import org.apache.lucene.search.BooleanClause.Occur;
3535
import org.apache.lucene.store.Directory;
3636
import org.apache.lucene.tests.index.RandomIndexWriter;
37+
import org.apache.lucene.tests.search.RandomApproximationQuery;
3738
import org.apache.lucene.tests.util.LuceneTestCase;
3839
import org.apache.lucene.tests.util.TestUtil;
3940

@@ -518,11 +519,13 @@ private Query randomBooleanQuery(Random random) {
518519
}
519520

520521
private Query randomWrapper(Random random, Query query) {
521-
switch (random.nextInt(2)) {
522+
switch (random.nextInt(3)) {
522523
case 0:
523524
return new BoostQuery(query, TestUtil.nextInt(random, 0, 4));
524525
case 1:
525526
return new ConstantScoreQuery(query);
527+
case 2:
528+
return new RandomApproximationQuery(query, random);
526529
default:
527530
throw new AssertionError();
528531
}

lucene/core/src/test/org/apache/lucene/search/TestMaxScoreBulkScorer.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
import org.apache.lucene.index.Term;
3333
import org.apache.lucene.search.BooleanClause.Occur;
3434
import org.apache.lucene.store.Directory;
35+
import org.apache.lucene.tests.search.RandomApproximationQuery;
3536
import org.apache.lucene.tests.util.LuceneTestCase;
3637
import org.apache.lucene.util.Bits;
3738

@@ -146,6 +147,10 @@ public void testFilteredDisjunction() throws Exception {
146147
new BoostQuery(new ConstantScoreQuery(new TermQuery(new Term("foo", "A"))), 2);
147148
Query clause2 = new ConstantScoreQuery(new TermQuery(new Term("foo", "C")));
148149
Query filter = new TermQuery(new Term("foo", "B"));
150+
if (random().nextBoolean()) {
151+
clause1 = new RandomApproximationQuery(clause1, random());
152+
clause2 = new RandomApproximationQuery(clause2, random());
153+
}
149154
LeafReaderContext context = searcher.getIndexReader().leaves().get(0);
150155
Scorer scorer1 =
151156
searcher
@@ -214,6 +219,10 @@ public void testFilteredDisjunctionWithSkipping() throws Exception {
214219
new BoostQuery(new ConstantScoreQuery(new TermQuery(new Term("foo", "A"))), 2);
215220
Query clause2 = new ConstantScoreQuery(new TermQuery(new Term("foo", "C")));
216221
Query filter = new TermQuery(new Term("foo", "B"));
222+
if (random().nextBoolean()) {
223+
clause1 = new RandomApproximationQuery(clause1, random());
224+
clause2 = new RandomApproximationQuery(clause2, random());
225+
}
217226
LeafReaderContext context = searcher.getIndexReader().leaves().get(0);
218227
Scorer scorer1 =
219228
searcher

0 commit comments

Comments
 (0)