Skip to content

Commit cdde094

Browse files
authored
[7.16] Prevent NullPointerException in SourceConfirmedTextQuery (#80472) (#80476)
* Prevent NullPointerException in SourceConfirmedTextQuery (#80472) Prevents a npe when the field that does not exists in the index * Prevent NullPointerException in SourceConfirmedTextQuery
1 parent 76f09cf commit cdde094

File tree

2 files changed

+38
-20
lines changed

2 files changed

+38
-20
lines changed

modules/mapper-extras/src/main/java/org/elasticsearch/index/query/SourceConfirmedTextQuery.java

Lines changed: 27 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -214,28 +214,35 @@ public Weight createWeight(IndexSearcher searcher, ScoreMode scoreMode, float bo
214214
throw new IllegalStateException("Query " + in + " doesn't have any term");
215215
}
216216
final String field = terms.iterator().next().field();
217-
final Map<Term, TermStates> termStates = new HashMap<>();
218-
final List<TermStatistics> termStats = new ArrayList<>();
219-
for (Term term : terms) {
220-
TermStates ts = termStates.computeIfAbsent(term, t -> {
221-
try {
222-
return TermStates.build(searcher.getTopReaderContext(), t, scoreMode.needsScores());
223-
} catch (IOException e) {
224-
throw new UncheckedIOException(e);
225-
}
226-
});
227-
if (scoreMode.needsScores()) {
228-
if (ts.docFreq() > 0) {
229-
termStats.add(searcher.termStatistics(term, ts.docFreq(), ts.totalTermFreq()));
217+
final CollectionStatistics collectionStatistics = searcher.collectionStatistics(field);
218+
final SimScorer simScorer;
219+
final Weight approximationWeight;
220+
if (collectionStatistics == null) {
221+
// field does not exist in the index
222+
simScorer = null;
223+
approximationWeight = null;
224+
} else {
225+
final Map<Term, TermStates> termStates = new HashMap<>();
226+
final List<TermStatistics> termStats = new ArrayList<>();
227+
for (Term term : terms) {
228+
TermStates ts = termStates.computeIfAbsent(term, t -> {
229+
try {
230+
return TermStates.build(searcher.getTopReaderContext(), t, scoreMode.needsScores());
231+
} catch (IOException e) {
232+
throw new UncheckedIOException(e);
233+
}
234+
});
235+
if (scoreMode.needsScores()) {
236+
if (ts.docFreq() > 0) {
237+
termStats.add(searcher.termStatistics(term, ts.docFreq(), ts.totalTermFreq()));
238+
}
239+
} else {
240+
termStats.add(new TermStatistics(term.bytes(), 1, 1L));
230241
}
231-
} else {
232-
termStats.add(new TermStatistics(term.bytes(), 1, 1L));
233242
}
243+
simScorer = searcher.getSimilarity().scorer(boost, collectionStatistics, termStats.toArray(new TermStatistics[0]));
244+
approximationWeight = searcher.createWeight(approximate(in), ScoreMode.COMPLETE_NO_SCORES, 1f);
234245
}
235-
final SimScorer simScorer = searcher.getSimilarity()
236-
.scorer(boost, searcher.collectionStatistics(field), termStats.toArray(new TermStatistics[0]));
237-
final Weight approximationWeight = searcher.createWeight(approximate(in), ScoreMode.COMPLETE_NO_SCORES, 1f);
238-
239246
return new Weight(this) {
240247

241248
@Override
@@ -272,7 +279,7 @@ public Explanation explain(LeafReaderContext context, int doc) throws IOExceptio
272279

273280
@Override
274281
public RuntimePhraseScorer scorer(LeafReaderContext context) throws IOException {
275-
final Scorer approximationScorer = approximationWeight.scorer(context);
282+
final Scorer approximationScorer = approximationWeight != null ? approximationWeight.scorer(context) : null;
276283
if (approximationScorer == null) {
277284
return null;
278285
}

modules/mapper-extras/src/test/java/org/elasticsearch/index/query/SourceConfirmedTextQueryTests.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -417,4 +417,15 @@ public void testApproximation() {
417417
).build();
418418
assertEquals(approximation, SourceConfirmedTextQuery.approximate(phrasePrefixQuery));
419419
}
420+
421+
public void testEmptyIndex() throws Exception {
422+
try (Directory dir = newDirectory(); IndexWriter w = new IndexWriter(dir, newIndexWriterConfig(Lucene.STANDARD_ANALYZER))) {
423+
try (IndexReader reader = DirectoryReader.open(w)) {
424+
IndexSearcher searcher = new IndexSearcher(reader);
425+
PhraseQuery query = new PhraseQuery("body", "a", "b");
426+
Query sourceConfirmedPhraseQuery = new SourceConfirmedTextQuery(query, SOURCE_FETCHER_PROVIDER, Lucene.STANDARD_ANALYZER);
427+
assertEquals(0, searcher.count(sourceConfirmedPhraseQuery));
428+
}
429+
}
430+
}
420431
}

0 commit comments

Comments
 (0)