Skip to content

Commit dadfd90

Browse files
committed
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 d526525 commit dadfd90

File tree

5 files changed

+28
-3
lines changed

5 files changed

+28
-3
lines changed

lucene/CHANGES.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@ http://s.apache.org/luceneversions
77

88
Bug Fixes
99
---------------------
10-
(No changes)
10+
* GITHUB#15380: Fix potential EOF introduced by optimized filter iterations in MaxScoreBulkScorer. The
11+
approximation and the match verification could get out of sync, resulting in an EOFException. (Ben Trent)
1112

1213
======================= Lucene 10.3.1 =======================
1314

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

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,9 +105,20 @@ DisiWrapper getSubMatches() throws IOException {
105105
}
106106
}
107107
unverifiedMatches.clear();
108+
assert assertVerifiedMatchesApproximationDocID();
108109
return verifiedMatches;
109110
}
110111

112+
private boolean assertVerifiedMatchesApproximationDocID() {
113+
int docID = docID();
114+
for (DisiWrapper w = verifiedMatches; w != null; w = w.next) {
115+
if (w.doc != docID) {
116+
return false;
117+
}
118+
}
119+
return true;
120+
}
121+
111122
@Override
112123
public boolean matches() throws IOException {
113124
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
@@ -173,7 +173,8 @@ private void scoreInnerWindowWithFilter(
173173
DisiWrapper top = essentialQueue.top();
174174
assert top.doc < max;
175175
while (top.doc < filter.doc) {
176-
top.doc = top.approximation.advance(filter.doc);
176+
// Must use the iterator as `top` might be a two-phase iterator
177+
top.doc = top.iterator.advance(filter.doc);
177178
top = essentialQueue.updateTop();
178179
}
179180

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)