Skip to content

Commit 9aba430

Browse files
authored
Fix npe when using source confirmed text query against missing field (#127414) (#127526)
We should check for the field and statistics actually existing when checking matches and explanation with `match_only_text` fields closes: #125635 (cherry picked from commit 3d67e0e)
1 parent efea30e commit 9aba430

File tree

3 files changed

+37
-2
lines changed

3 files changed

+37
-2
lines changed

docs/changelog/127414.yaml

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
pr: 127414
2+
summary: Fix npe when using source confirmed text query against missing field
3+
area: Search
4+
type: bug
5+
issues: []

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

+11-2
Original file line numberDiff line numberDiff line change
@@ -267,7 +267,11 @@ public boolean isCacheable(LeafReaderContext ctx) {
267267
@Override
268268
public Explanation explain(LeafReaderContext context, int doc) throws IOException {
269269
NumericDocValues norms = context.reader().getNormValues(field);
270-
RuntimePhraseScorer scorer = (RuntimePhraseScorer) scorerSupplier(context).get(0);
270+
ScorerSupplier scorerSupplier = scorerSupplier(context);
271+
if (scorerSupplier == null) {
272+
return Explanation.noMatch("No matching phrase");
273+
}
274+
RuntimePhraseScorer scorer = (RuntimePhraseScorer) scorerSupplier.get(0);
271275
if (scorer == null) {
272276
return Explanation.noMatch("No matching phrase");
273277
}
@@ -277,6 +281,7 @@ public Explanation explain(LeafReaderContext context, int doc) throws IOExceptio
277281
}
278282
float phraseFreq = scorer.freq();
279283
Explanation freqExplanation = Explanation.match(phraseFreq, "phraseFreq=" + phraseFreq);
284+
assert simScorer != null;
280285
Explanation scoreExplanation = simScorer.explain(freqExplanation, getNormValue(norms, doc));
281286
return Explanation.match(
282287
scoreExplanation.getValue(),
@@ -321,7 +326,11 @@ public Matches matches(LeafReaderContext context, int doc) throws IOException {
321326
Weight innerWeight = in.createWeight(searcher, ScoreMode.COMPLETE_NO_SCORES, 1);
322327
return innerWeight.matches(context, doc);
323328
}
324-
RuntimePhraseScorer scorer = (RuntimePhraseScorer) scorerSupplier(context).get(0L);
329+
ScorerSupplier scorerSupplier = scorerSupplier(context);
330+
if (scorerSupplier == null) {
331+
return null;
332+
}
333+
RuntimePhraseScorer scorer = (RuntimePhraseScorer) scorerSupplier.get(0L);
325334
if (scorer == null) {
326335
return null;
327336
}

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

+21
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
import org.apache.lucene.queries.spans.SpanTermQuery;
2525
import org.apache.lucene.search.BooleanClause.Occur;
2626
import org.apache.lucene.search.BooleanQuery;
27+
import org.apache.lucene.search.Explanation;
2728
import org.apache.lucene.search.IndexSearcher;
2829
import org.apache.lucene.search.MatchNoDocsQuery;
2930
import org.apache.lucene.search.Matches;
@@ -101,6 +102,26 @@ public void testTerm() throws Exception {
101102
}
102103
}
103104

105+
public void testMissingPhrase() throws Exception {
106+
try (Directory dir = newDirectory(); IndexWriter w = new IndexWriter(dir, newIndexWriterConfig(Lucene.STANDARD_ANALYZER))) {
107+
108+
Document doc = new Document();
109+
doc.add(new TextField("body", "a b c b a b c", Store.YES));
110+
w.addDocument(doc);
111+
112+
try (IndexReader reader = DirectoryReader.open(w)) {
113+
IndexSearcher searcher = newSearcher(reader);
114+
PhraseQuery query = new PhraseQuery("missing_field", "b", "c");
115+
Query sourceConfirmedPhraseQuery = new SourceConfirmedTextQuery(query, SOURCE_FETCHER_PROVIDER, Lucene.STANDARD_ANALYZER);
116+
Explanation explanation = searcher.explain(sourceConfirmedPhraseQuery, 0);
117+
assertFalse(explanation.isMatch());
118+
119+
Weight weight = searcher.createWeight(query, ScoreMode.COMPLETE, 1);
120+
assertNull(weight.matches(getOnlyLeafReader(reader).getContext(), 0));
121+
}
122+
}
123+
}
124+
104125
public void testPhrase() throws Exception {
105126
try (Directory dir = newDirectory(); IndexWriter w = new IndexWriter(dir, newIndexWriterConfig(Lucene.STANDARD_ANALYZER))) {
106127

0 commit comments

Comments
 (0)