From fda928114af15de06394f6af986e84b6a9c26339 Mon Sep 17 00:00:00 2001 From: Ryan Ernst Date: Wed, 15 Mar 2017 15:14:32 -0700 Subject: [PATCH] Mapping: Fix NPE with scaled floats stats when field is not indexed (#23528) This fixes an NPE in finding scaled float stats. The type of min/max methods on the wrapped long stats returns a boxed type, but in the case this is null, the unbox done for the FieldStats.Double ctor primitive types will cause the NPE. These methods would have null for min/max when the field exists, but does not actually have points values. fixes #23487 --- .../index/mapper/ScaledFloatFieldMapper.java | 11 ++++++++--- .../index/mapper/ScaledFloatFieldTypeTests.java | 12 +++++++++++- 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/core/src/main/java/org/elasticsearch/index/mapper/ScaledFloatFieldMapper.java b/core/src/main/java/org/elasticsearch/index/mapper/ScaledFloatFieldMapper.java index a8505f33e043f..46f323d1e5dd8 100644 --- a/core/src/main/java/org/elasticsearch/index/mapper/ScaledFloatFieldMapper.java +++ b/core/src/main/java/org/elasticsearch/index/mapper/ScaledFloatFieldMapper.java @@ -265,11 +265,16 @@ public FieldStats stats(IndexReader reader) throws IOException { if (stats == null) { return null; } - return new FieldStats.Double(stats.getMaxDoc(), stats.getDocCount(), + if (stats.hasMinMax()) { + return new FieldStats.Double(stats.getMaxDoc(), stats.getDocCount(), stats.getSumDocFreq(), stats.getSumTotalTermFreq(), stats.isSearchable(), stats.isAggregatable(), - stats.getMinValue() == null ? null : stats.getMinValue() / scalingFactor, - stats.getMaxValue() == null ? null : stats.getMaxValue() / scalingFactor); + stats.getMinValue() / scalingFactor, + stats.getMaxValue() / scalingFactor); + } + return new FieldStats.Double(stats.getMaxDoc(), stats.getDocCount(), + stats.getSumDocFreq(), stats.getSumTotalTermFreq(), + stats.isSearchable(), stats.isAggregatable()); } @Override diff --git a/core/src/test/java/org/elasticsearch/index/mapper/ScaledFloatFieldTypeTests.java b/core/src/test/java/org/elasticsearch/index/mapper/ScaledFloatFieldTypeTests.java index e1fdf10356444..dd66421986779 100644 --- a/core/src/test/java/org/elasticsearch/index/mapper/ScaledFloatFieldTypeTests.java +++ b/core/src/test/java/org/elasticsearch/index/mapper/ScaledFloatFieldTypeTests.java @@ -23,6 +23,7 @@ import org.apache.lucene.document.DoublePoint; import org.apache.lucene.document.LongPoint; import org.apache.lucene.document.SortedNumericDocValuesField; +import org.apache.lucene.document.StoredField; import org.apache.lucene.index.DirectoryReader; import org.apache.lucene.index.IndexWriter; import org.apache.lucene.index.IndexWriterConfig; @@ -143,6 +144,15 @@ public void testStats() throws IOException { assertNull(ft.stats(reader)); } Document doc = new Document(); + doc.add(new StoredField("scaled_float", -1)); + w.addDocument(doc); + try (DirectoryReader reader = DirectoryReader.open(w)) { + // field exists, but has no point values + FieldStats stats = ft.stats(reader); + assertFalse(stats.hasMinMax()); + assertNull(stats.getMinValue()); + assertNull(stats.getMaxValue()); + } LongPoint point = new LongPoint("scaled_float", -1); doc.add(point); w.addDocument(doc); @@ -152,7 +162,7 @@ public void testStats() throws IOException { FieldStats stats = ft.stats(reader); assertEquals(-1/ft.getScalingFactor(), stats.getMinValue()); assertEquals(10/ft.getScalingFactor(), stats.getMaxValue()); - assertEquals(2, stats.getMaxDoc()); + assertEquals(3, stats.getMaxDoc()); } w.deleteAll(); try (DirectoryReader reader = DirectoryReader.open(w)) {