Преглед изворни кода

Fix null_value parsing for data_nanos field mapper (#61994)

The null_value parameter for date fields is always parsed using DateFormatter.parseMillis,
which is incorrect for nanosecond resolution fields. This commit changes the parsing logic
to always use DateFieldType.parse() to parse the null value.
Alan Woodward пре 5 година
родитељ
комит
b0510a36cd

+ 3 - 3
server/src/main/java/org/elasticsearch/index/mapper/DateFieldMapper.java

@@ -225,12 +225,12 @@ public final class DateFieldMapper extends ParametrizedFieldMapper {
             return List.of(index, docValues, store, format, locale, nullValue, ignoreMalformed, boost, meta);
         }
 
-        private Long parseNullValue(DateFormatter formatter) {
+        private Long parseNullValue(DateFieldType fieldType) {
             if (nullValue.getValue() == null) {
                 return null;
             }
             try {
-                return formatter.parseMillis(nullValue.getValue());
+                return fieldType.parse(nullValue.getValue());
             }
             catch (Exception e) {
                 throw new MapperParsingException("Error parsing [null_value] on field [" + name() + "]: " + e.getMessage(), e);
@@ -242,7 +242,7 @@ public final class DateFieldMapper extends ParametrizedFieldMapper {
             DateFieldType ft = new DateFieldType(buildFullName(context), index.getValue(), docValues.getValue(),
                 buildFormatter(), resolution, meta.getValue());
             ft.setBoost(boost.getValue());
-            Long nullTimestamp = parseNullValue(ft.dateTimeFormatter);
+            Long nullTimestamp = parseNullValue(ft);
             return new DateFieldMapper(name, ft, multiFieldsBuilder.build(this, context),
                 copyTo.build(), nullTimestamp, resolution, this);
         }

+ 27 - 0
server/src/test/java/org/elasticsearch/index/mapper/DateFieldMapperTests.java

@@ -192,6 +192,33 @@ public class DateFieldMapperTests extends MapperTestCase {
         assertFalse(dvField.fieldType().stored());
     }
 
+    public void testNanosNullValue() throws IOException {
+        DocumentMapper mapper = createDocumentMapper(fieldMapping(this::minimalMapping));
+
+        ParsedDocument doc = mapper.parse(source(b -> b.nullField("field")));
+        assertArrayEquals(new IndexableField[0], doc.rootDoc().getFields("field"));
+
+        MapperService mapperService = createMapperService(fieldMapping(b -> b
+            .field("type", "date_nanos")
+            .field("null_value", "2016-03-11")));
+
+        DateFieldMapper.DateFieldType ft = (DateFieldMapper.DateFieldType) mapperService.fieldType("field");
+        long expectedNullValue = ft.parse("2016-03-11");
+
+        doc = mapperService.documentMapper().parse(source(b -> b.nullField("field")));
+        IndexableField[] fields = doc.rootDoc().getFields("field");
+        assertEquals(2, fields.length);
+        IndexableField pointField = fields[0];
+        assertEquals(1, pointField.fieldType().pointIndexDimensionCount());
+        assertEquals(8, pointField.fieldType().pointNumBytes());
+        assertFalse(pointField.fieldType().stored());
+        assertEquals(expectedNullValue, pointField.numericValue().longValue());
+        IndexableField dvField = fields[1];
+        assertEquals(DocValuesType.SORTED_NUMERIC, dvField.fieldType().docValuesType());
+        assertEquals(expectedNullValue, dvField.numericValue().longValue());
+        assertFalse(dvField.fieldType().stored());
+    }
+
     public void testBadNullValue() {
 
         MapperParsingException e = expectThrows(MapperParsingException.class,