You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by jp...@apache.org on 2020/10/16 17:01:01 UTC

[lucene-solr] branch master updated: LUCENE-9524: Fix NPE in SpanWeight#explain when no scoring is require… (#1978)

This is an automated email from the ASF dual-hosted git repository.

jpountz pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/lucene-solr.git


The following commit(s) were added to refs/heads/master by this push:
     new 6990109  LUCENE-9524: Fix NPE in SpanWeight#explain when no scoring is require… (#1978)
6990109 is described below

commit 6990109f9be97c6c32724dd5c001f5d3bc8da5e8
Author: zacharymorn <za...@gmail.com>
AuthorDate: Fri Oct 16 10:00:46 2020 -0700

    LUCENE-9524: Fix NPE in SpanWeight#explain when no scoring is require… (#1978)
---
 lucene/CHANGES.txt                                 |  3 ++
 .../org/apache/lucene/search/spans/SpanWeight.java | 21 ++++++++----
 .../lucene/search/spans/TestSpanExplanations.java  | 38 ++++++++++++++++++++++
 3 files changed, 55 insertions(+), 7 deletions(-)

diff --git a/lucene/CHANGES.txt b/lucene/CHANGES.txt
index 7abc950..4e02d1e 100644
--- a/lucene/CHANGES.txt
+++ b/lucene/CHANGES.txt
@@ -161,6 +161,9 @@ Bug fixes
 * LUCENE-9365: FuzzyQuery was missing matches when prefix length was equal to the term length
   (Mark Harwood, Mike Drob)
 
+* LUCENE-9524: Fix NPE in SpanWeight#explain when no scoring is required and SpanWeight has null Similarity.SimScorer.
+  (Zach Chen)
+
 Other
 
 * LUCENE-9312: Allow gradle builds against arbitrary JVMs. (Tomoko Uchida, Dawid Weiss)
diff --git a/lucene/core/src/java/org/apache/lucene/search/spans/SpanWeight.java b/lucene/core/src/java/org/apache/lucene/search/spans/SpanWeight.java
index d70d277..f9787fd 100644
--- a/lucene/core/src/java/org/apache/lucene/search/spans/SpanWeight.java
+++ b/lucene/core/src/java/org/apache/lucene/search/spans/SpanWeight.java
@@ -20,6 +20,7 @@ package org.apache.lucene.search.spans;
 import java.io.IOException;
 import java.util.Arrays;
 import java.util.Comparator;
+import java.util.Locale;
 import java.util.Map;
 
 import org.apache.lucene.index.LeafReaderContext;
@@ -156,13 +157,19 @@ public abstract class SpanWeight extends Weight {
     if (scorer != null) {
       int newDoc = scorer.iterator().advance(doc);
       if (newDoc == doc) {
-        float freq = scorer.sloppyFreq();
-        LeafSimScorer docScorer = new LeafSimScorer(simScorer, context.reader(), field, true);
-        Explanation freqExplanation = Explanation.match(freq, "phraseFreq=" + freq);
-        Explanation scoreExplanation = docScorer.explain(doc, freqExplanation);
-        return Explanation.match(scoreExplanation.getValue(),
-            "weight("+getQuery()+" in "+doc+") [" + similarity.getClass().getSimpleName() + "], result of:",
-            scoreExplanation);
+        if (simScorer != null) {
+          float freq = scorer.sloppyFreq();
+          LeafSimScorer docScorer = new LeafSimScorer(simScorer, context.reader(), field, true);
+          Explanation freqExplanation = Explanation.match(freq, "phraseFreq=" + freq);
+          Explanation scoreExplanation = docScorer.explain(doc, freqExplanation);
+          return Explanation.match(scoreExplanation.getValue(),
+              "weight("+getQuery()+" in "+doc+") [" + similarity.getClass().getSimpleName() + "], result of:",
+              scoreExplanation);
+        } else {
+          // simScorer won't be set when scoring isn't needed
+          return Explanation.match(0f, String.format(Locale.ROOT,
+              "match %s in %s without score", getQuery(), doc));
+        }
       }
     }
 
diff --git a/lucene/core/src/test/org/apache/lucene/search/spans/TestSpanExplanations.java b/lucene/core/src/test/org/apache/lucene/search/spans/TestSpanExplanations.java
index b986cd4..966cde1 100644
--- a/lucene/core/src/test/org/apache/lucene/search/spans/TestSpanExplanations.java
+++ b/lucene/core/src/test/org/apache/lucene/search/spans/TestSpanExplanations.java
@@ -17,12 +17,22 @@
 package org.apache.lucene.search.spans;
 
 
+import java.io.IOException;
+
+import org.apache.lucene.document.Document;
+import org.apache.lucene.document.Field;
+import org.apache.lucene.index.DirectoryReader;
+import org.apache.lucene.index.IndexWriter;
+import org.apache.lucene.index.LeafReaderContext;
+import org.apache.lucene.index.Term;
 import org.apache.lucene.search.*;
+import org.apache.lucene.store.Directory;
 
 /**
  * TestExplanations subclass focusing on span queries
  */
 public class TestSpanExplanations extends BaseExplanationTestCase {
+  private static final String FIELD_CONTENT = "content";
 
   /* simple SpanTermQueries */
   
@@ -165,4 +175,32 @@ public class TestSpanExplanations extends BaseExplanationTestCase {
     qtest(q, new int[] {0,1,3});
   }
 
+  public void testExplainWithoutScoring() throws IOException {
+    SpanNearQuery query = new SpanNearQuery(new SpanQuery[]{
+        new SpanTermQuery(new Term(FIELD_CONTENT, "dolor")),
+        new SpanTermQuery(new Term(FIELD_CONTENT, "lorem"))},
+        0,
+        true);
+
+    try (Directory rd = newDirectory()) {
+      try (IndexWriter writer = new IndexWriter(rd, newIndexWriterConfig(analyzer))) {
+        Document doc = new Document();
+        doc.add(newTextField(FIELD_CONTENT, "dolor lorem ipsum", Field.Store.YES));
+        writer.addDocument(doc);
+      }
+
+      try (DirectoryReader reader = DirectoryReader.open(rd)) {
+        IndexSearcher indexSearcher = newSearcher(reader);
+        SpanWeight spanWeight = query.createWeight(indexSearcher, ScoreMode.COMPLETE_NO_SCORES, 1f);
+
+        final LeafReaderContext ctx = reader.leaves().get(0);
+        Explanation explanation = spanWeight.explain(ctx, 0);
+
+        assertEquals(0f, explanation.getValue());
+        assertEquals("match spanNear([content:dolor, content:lorem], 0, true) in 0 without score",
+            explanation.getDescription());
+
+      }
+    }
+  }
 }