You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by ji...@apache.org on 2017/12/07 13:09:00 UTC

lucene-solr:master: LUCENE-8082: Fix NPE in TopFieldCollectors that don't track total hit count

Repository: lucene-solr
Updated Branches:
  refs/heads/master 4fc5a872d -> 68d16c2a6


LUCENE-8082: Fix NPE in TopFieldCollectors that don't track total hit count


Project: http://git-wip-us.apache.org/repos/asf/lucene-solr/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucene-solr/commit/68d16c2a
Tree: http://git-wip-us.apache.org/repos/asf/lucene-solr/tree/68d16c2a
Diff: http://git-wip-us.apache.org/repos/asf/lucene-solr/diff/68d16c2a

Branch: refs/heads/master
Commit: 68d16c2a65b4acd0ce1ca543ae53a82e2516f1e5
Parents: 4fc5a87
Author: Jim Ferenczi <ji...@apache.org>
Authored: Thu Dec 7 14:08:46 2017 +0100
Committer: Jim Ferenczi <ji...@apache.org>
Committed: Thu Dec 7 14:08:46 2017 +0100

----------------------------------------------------------------------
 .../apache/lucene/search/TopFieldCollector.java | 12 +++++++---
 .../lucene/search/TestTopFieldCollector.java    | 25 ++++++++++++++++++++
 2 files changed, 34 insertions(+), 3 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/68d16c2a/lucene/core/src/java/org/apache/lucene/search/TopFieldCollector.java
----------------------------------------------------------------------
diff --git a/lucene/core/src/java/org/apache/lucene/search/TopFieldCollector.java b/lucene/core/src/java/org/apache/lucene/search/TopFieldCollector.java
index c3597e9..3d85277 100644
--- a/lucene/core/src/java/org/apache/lucene/search/TopFieldCollector.java
+++ b/lucene/core/src/java/org/apache/lucene/search/TopFieldCollector.java
@@ -121,9 +121,11 @@ public abstract class TopFieldCollector extends TopDocsCollector<Entry> {
 
       final LeafFieldComparator[] comparators = queue.getComparators(context);
       final int[] reverseMul = queue.getReverseMul();
+      final Sort indexSort = context.reader().getMetaData().getSort();
       final boolean canEarlyTerminate = trackTotalHits == false &&
           trackMaxScore == false &&
-          canEarlyTerminate(sort, context.reader().getMetaData().getSort());
+          indexSort != null &&
+          canEarlyTerminate(sort, indexSort);
       final int initialTotalHits = totalHits;
 
       return new MultiComparatorLeafCollector(comparators, reverseMul, mayNeedScoresTwice) {
@@ -212,7 +214,9 @@ public abstract class TopFieldCollector extends TopDocsCollector<Entry> {
       this.trackTotalHits = trackTotalHits;
 
       // Must set maxScore to NEG_INF, or otherwise Math.max always returns NaN.
-      maxScore = Float.NEGATIVE_INFINITY;
+      if (trackMaxScore) {
+        maxScore = Float.NEGATIVE_INFINITY;
+      }
 
       FieldComparator<?>[] comparators = queue.comparators;
       // Tell all comparators their top value:
@@ -227,9 +231,11 @@ public abstract class TopFieldCollector extends TopDocsCollector<Entry> {
     public LeafCollector getLeafCollector(LeafReaderContext context) throws IOException {
       docBase = context.docBase;
       final int afterDoc = after.doc - docBase;
+      final Sort indexSort = context.reader().getMetaData().getSort();
       final boolean canEarlyTerminate = trackTotalHits == false &&
           trackMaxScore == false &&
-          canEarlyTerminate(sort, context.reader().getMetaData().getSort());
+          indexSort != null &&
+          canEarlyTerminate(sort, indexSort);
       final int initialTotalHits = totalHits;
       return new MultiComparatorLeafCollector(queue.getComparators(context), queue.getReverseMul(), mayNeedScoresTwice) {
 

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/68d16c2a/lucene/core/src/test/org/apache/lucene/search/TestTopFieldCollector.java
----------------------------------------------------------------------
diff --git a/lucene/core/src/test/org/apache/lucene/search/TestTopFieldCollector.java b/lucene/core/src/test/org/apache/lucene/search/TestTopFieldCollector.java
index 0b7dc5b..d8363f7 100644
--- a/lucene/core/src/test/org/apache/lucene/search/TestTopFieldCollector.java
+++ b/lucene/core/src/test/org/apache/lucene/search/TestTopFieldCollector.java
@@ -102,6 +102,31 @@ public class TestTopFieldCollector extends LuceneTestCase {
       assertTrue(Float.isNaN(td.getMaxScore()));
     }
   }
+
+  public void testSortWithoutTotalHitTracking() throws Exception {
+    Sort sort = new Sort(SortField.FIELD_DOC);
+    for(int i = 0; i < 2; i++) {
+      Query q = new MatchAllDocsQuery();
+      // check that setting trackTotalHits to false does not throw an NPE because
+      // the index is not sorted
+      TopDocsCollector<Entry> tdc;
+      if (i % 2 == 0) {
+        tdc =  TopFieldCollector.create(sort, 10, true, false, false, false);
+      } else {
+        FieldDoc fieldDoc = new FieldDoc(1, Float.NaN, new Object[] { 1 });
+        tdc = TopFieldCollector.create(sort, 10, fieldDoc, true, false, false, false);
+      }
+
+      is.search(q, tdc);
+
+      TopDocs td = tdc.topDocs();
+      ScoreDoc[] sd = td.scoreDocs;
+      for(int j = 0; j < sd.length; j++) {
+        assertTrue(Float.isNaN(sd[j].score));
+      }
+      assertTrue(Float.isNaN(td.getMaxScore()));
+    }
+  }
   
   public void testSortWithScoreNoMaxScoreTracking() throws Exception {