Skip to content

Commit 000fb9b

Browse files
committed
Fix dynamic mapping update generation. (#27467)
When a field is not mapped, Elasticsearch tries to generate a mapping update from the parsed document. Some documents can introduce corner-cases, for instance in the event of a multi-valued field whose values would be mapped to different field types if they were supplied on their own, see for instance: ``` PUT index/doc/1 { "foo": ["2017-11-10T02:00:01.247Z","bar"] } ``` In that case, dynamic mappings want to map the first value as a `date` field and the second one as a `text` field. This currently throws an exception, which is expected, but the wrong one since it throws a `class_cast_exception` (which triggers a HTTP 5xx code) when it should throw an `illegal_argument_exception` (HTTP 4xx).
1 parent e91182d commit 000fb9b

File tree

2 files changed

+17
-1
lines changed

2 files changed

+17
-1
lines changed

core/src/main/java/org/elasticsearch/index/mapper/DateFieldMapper.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -488,8 +488,8 @@ protected void parseCreateField(ParseContext context, List<IndexableField> field
488488

489489
@Override
490490
protected void doMerge(Mapper mergeWith, boolean updateAllTypes) {
491-
final DateFieldMapper other = (DateFieldMapper) mergeWith;
492491
super.doMerge(mergeWith, updateAllTypes);
492+
final DateFieldMapper other = (DateFieldMapper) mergeWith;
493493
this.includeInAll = other.includeInAll;
494494
if (other.ignoreMalformed.explicit()) {
495495
this.ignoreMalformed = other.ignoreMalformed;

core/src/test/java/org/elasticsearch/index/mapper/DateFieldMapperTests.java

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -410,4 +410,20 @@ public void testMergeDate() throws IOException {
410410
MapperService.MergeReason.MAPPING_UPDATE, randomBoolean()));
411411
assertThat(e.getMessage(), containsString("[mapper [release_date] has different [format] values]"));
412412
}
413+
414+
public void testMergeText() throws Exception {
415+
String mapping = XContentFactory.jsonBuilder().startObject().startObject("doc")
416+
.startObject("properties").startObject("date").field("type", "date").endObject()
417+
.endObject().endObject().endObject().string();
418+
DocumentMapper mapper = indexService.mapperService().parse("doc", new CompressedXContent(mapping), false);
419+
420+
String mappingUpdate = XContentFactory.jsonBuilder().startObject().startObject("doc")
421+
.startObject("properties").startObject("date").field("type", "text").endObject()
422+
.endObject().endObject().endObject().string();
423+
DocumentMapper update = indexService.mapperService().parse("doc", new CompressedXContent(mappingUpdate), false);
424+
425+
IllegalArgumentException e = expectThrows(IllegalArgumentException.class,
426+
() -> mapper.merge(update.mapping(), randomBoolean()));
427+
assertEquals("mapper [date] of different type, current_type [date], merged_type [text]", e.getMessage());
428+
}
413429
}

0 commit comments

Comments
 (0)