Fixed bug that mapper_parsing_exception is thrown for numeric field with ignore_malformed=true when inserting "NaN", "Infinity" or "-Infinity" values (#25967)

This commit is contained in:
honourednihilist 2017-07-31 17:14:30 +03:00 committed by Adrien Grand
parent 2b0f4287b3
commit 0848ffd52e
2 changed files with 28 additions and 13 deletions

View File

@ -399,8 +399,12 @@ public class ScaledFloatFieldMapper extends FieldMapper {
double doubleValue = numericValue.doubleValue(); double doubleValue = numericValue.doubleValue();
if (Double.isFinite(doubleValue) == false) { if (Double.isFinite(doubleValue) == false) {
// since we encode to a long, we have no way to carry NaNs and infinities if (ignoreMalformed.value()) {
throw new IllegalArgumentException("[scaled_float] only supports finite values, but got [" + doubleValue + "]"); return;
} else {
// since we encode to a long, we have no way to carry NaNs and infinities
throw new IllegalArgumentException("[scaled_float] only supports finite values, but got [" + doubleValue + "]");
}
} }
long scaledValue = Math.round(doubleValue * fieldType().getScalingFactor()); long scaledValue = Math.round(doubleValue * fieldType().getScalingFactor());

View File

@ -31,7 +31,9 @@ import org.elasticsearch.test.InternalSettingsPlugin;
import org.junit.Before; import org.junit.Before;
import java.io.IOException; import java.io.IOException;
import java.util.Arrays;
import java.util.Collection; import java.util.Collection;
import java.util.List;
import static org.hamcrest.Matchers.containsString; import static org.hamcrest.Matchers.containsString;
@ -223,10 +225,19 @@ public class ScaledFloatFieldMapperTests extends ESSingleNodeTestCase {
} }
public void testIgnoreMalformed() throws Exception { public void testIgnoreMalformed() throws Exception {
doTestIgnoreMalformed("a", "For input string: \"a\"");
List<String> values = Arrays.asList("NaN", "Infinity", "-Infinity");
for (String value : values) {
doTestIgnoreMalformed(value, "[scaled_float] only supports finite values, but got [" + value + "]");
}
}
private void doTestIgnoreMalformed(String value, String exceptionMessageContains) throws Exception {
String mapping = XContentFactory.jsonBuilder().startObject().startObject("type") String mapping = XContentFactory.jsonBuilder().startObject().startObject("type")
.startObject("properties").startObject("field").field("type", "scaled_float") .startObject("properties").startObject("field").field("type", "scaled_float")
.field("scaling_factor", 10.0).endObject().endObject() .field("scaling_factor", 10.0).endObject().endObject()
.endObject().endObject().string(); .endObject().endObject().string();
DocumentMapper mapper = parser.parse("type", new CompressedXContent(mapping)); DocumentMapper mapper = parser.parse("type", new CompressedXContent(mapping));
@ -234,26 +245,26 @@ public class ScaledFloatFieldMapperTests extends ESSingleNodeTestCase {
ThrowingRunnable runnable = () -> mapper.parse(SourceToParse.source("test", "type", "1", XContentFactory.jsonBuilder() ThrowingRunnable runnable = () -> mapper.parse(SourceToParse.source("test", "type", "1", XContentFactory.jsonBuilder()
.startObject() .startObject()
.field("field", "a") .field("field", value)
.endObject() .endObject()
.bytes(), .bytes(),
XContentType.JSON)); XContentType.JSON));
MapperParsingException e = expectThrows(MapperParsingException.class, runnable); MapperParsingException e = expectThrows(MapperParsingException.class, runnable);
assertThat(e.getCause().getMessage(), containsString("For input string: \"a\"")); assertThat(e.getCause().getMessage(), containsString(exceptionMessageContains));
mapping = XContentFactory.jsonBuilder().startObject().startObject("type") mapping = XContentFactory.jsonBuilder().startObject().startObject("type")
.startObject("properties").startObject("field").field("type", "scaled_float") .startObject("properties").startObject("field").field("type", "scaled_float")
.field("scaling_factor", 10.0).field("ignore_malformed", true).endObject().endObject() .field("scaling_factor", 10.0).field("ignore_malformed", true).endObject().endObject()
.endObject().endObject().string(); .endObject().endObject().string();
DocumentMapper mapper2 = parser.parse("type", new CompressedXContent(mapping)); DocumentMapper mapper2 = parser.parse("type", new CompressedXContent(mapping));
ParsedDocument doc = mapper2.parse(SourceToParse.source("test", "type", "1", XContentFactory.jsonBuilder() ParsedDocument doc = mapper2.parse(SourceToParse.source("test", "type", "1", XContentFactory.jsonBuilder()
.startObject() .startObject()
.field("field", "a") .field("field", value)
.endObject() .endObject()
.bytes(), .bytes(),
XContentType.JSON)); XContentType.JSON));
IndexableField[] fields = doc.rootDoc().getFields("field"); IndexableField[] fields = doc.rootDoc().getFields("field");
assertEquals(0, fields.length); assertEquals(0, fields.length);