From 72fc7801e2fb717df2f77d30b68a09aa09c9ec83 Mon Sep 17 00:00:00 2001 From: iverase Date: Mon, 8 Nov 2021 07:44:53 +0100 Subject: [PATCH] Prevent NullPointerException in SourceConfirmedTextQuery --- .../extras/SourceConfirmedTextQuery.java | 47 +++++++++++-------- .../extras/SourceConfirmedTextQueryTests.java | 12 +++++ 2 files changed, 39 insertions(+), 20 deletions(-) diff --git a/modules/mapper-extras/src/main/java/org/elasticsearch/index/mapper/extras/SourceConfirmedTextQuery.java b/modules/mapper-extras/src/main/java/org/elasticsearch/index/mapper/extras/SourceConfirmedTextQuery.java index 51ad57b7f26e4..09a53f4abc9fe 100644 --- a/modules/mapper-extras/src/main/java/org/elasticsearch/index/mapper/extras/SourceConfirmedTextQuery.java +++ b/modules/mapper-extras/src/main/java/org/elasticsearch/index/mapper/extras/SourceConfirmedTextQuery.java @@ -219,28 +219,35 @@ public Weight createWeight(IndexSearcher searcher, ScoreMode scoreMode, float bo throw new IllegalStateException("Query " + in + " doesn't have any term"); } final String field = terms.iterator().next().field(); - final Map termStates = new HashMap<>(); - final List termStats = new ArrayList<>(); - for (Term term : terms) { - TermStates ts = termStates.computeIfAbsent(term, t -> { - try { - return TermStates.build(searcher.getTopReaderContext(), t, scoreMode.needsScores()); - } catch (IOException e) { - throw new UncheckedIOException(e); - } - }); - if (scoreMode.needsScores()) { - if (ts.docFreq() > 0) { - termStats.add(searcher.termStatistics(term, ts.docFreq(), ts.totalTermFreq())); + final CollectionStatistics collectionStatistics = searcher.collectionStatistics(field); + final SimScorer simScorer; + final Weight approximationWeight; + if (collectionStatistics == null) { + // field does not exist in the index + simScorer = null; + approximationWeight = null; + } else { + final Map termStates = new HashMap<>(); + final List termStats = new ArrayList<>(); + for (Term term : terms) { + TermStates ts = termStates.computeIfAbsent(term, t -> { + try { + return TermStates.build(searcher.getTopReaderContext(), t, scoreMode.needsScores()); + } catch (IOException e) { + throw new UncheckedIOException(e); + } + }); + if (scoreMode.needsScores()) { + if (ts.docFreq() > 0) { + termStats.add(searcher.termStatistics(term, ts.docFreq(), ts.totalTermFreq())); + } + } else { + termStats.add(new TermStatistics(term.bytes(), 1, 1L)); } - } else { - termStats.add(new TermStatistics(term.bytes(), 1, 1L)); } + simScorer = searcher.getSimilarity().scorer(boost, collectionStatistics, termStats.toArray(TermStatistics[]::new)); + approximationWeight = searcher.createWeight(approximate(in), ScoreMode.COMPLETE_NO_SCORES, 1f); } - final SimScorer simScorer = searcher.getSimilarity() - .scorer(boost, searcher.collectionStatistics(field), termStats.toArray(TermStatistics[]::new)); - final Weight approximationWeight = searcher.createWeight(approximate(in), ScoreMode.COMPLETE_NO_SCORES, 1f); - return new Weight(this) { @Override @@ -272,7 +279,7 @@ public Explanation explain(LeafReaderContext context, int doc) throws IOExceptio @Override public RuntimePhraseScorer scorer(LeafReaderContext context) throws IOException { - final Scorer approximationScorer = approximationWeight.scorer(context); + final Scorer approximationScorer = approximationWeight != null ? approximationWeight.scorer(context) : null; if (approximationScorer == null) { return null; } diff --git a/modules/mapper-extras/src/test/java/org/elasticsearch/index/mapper/extras/SourceConfirmedTextQueryTests.java b/modules/mapper-extras/src/test/java/org/elasticsearch/index/mapper/extras/SourceConfirmedTextQueryTests.java index c0ce863b06969..71489ebf8eda3 100644 --- a/modules/mapper-extras/src/test/java/org/elasticsearch/index/mapper/extras/SourceConfirmedTextQueryTests.java +++ b/modules/mapper-extras/src/test/java/org/elasticsearch/index/mapper/extras/SourceConfirmedTextQueryTests.java @@ -417,4 +417,16 @@ public void testApproximation() { ).build(); assertEquals(approximation, SourceConfirmedTextQuery.approximate(phrasePrefixQuery)); } + + public void testEmptyIndex() throws Exception { + try (Directory dir = newDirectory(); IndexWriter w = new IndexWriter(dir, newIndexWriterConfig(Lucene.STANDARD_ANALYZER))) { + try (IndexReader reader = DirectoryReader.open(w)) { + IndexSearcher searcher = new IndexSearcher(reader); + PhraseQuery query = new PhraseQuery("body", "a", "b"); + Query sourceConfirmedPhraseQuery = new SourceConfirmedTextQuery(query, SOURCE_FETCHER_PROVIDER, Lucene.STANDARD_ANALYZER); + assertEquals(0, searcher.count(sourceConfirmedPhraseQuery)); + } + } + } + }