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).
This commit is contained in:
parent
5a0b6d1977
commit
6ac799074e
|
@ -473,8 +473,8 @@ public class DateFieldMapper extends FieldMapper {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void doMerge(Mapper mergeWith, boolean updateAllTypes) {
|
protected void doMerge(Mapper mergeWith, boolean updateAllTypes) {
|
||||||
final DateFieldMapper other = (DateFieldMapper) mergeWith;
|
|
||||||
super.doMerge(mergeWith, updateAllTypes);
|
super.doMerge(mergeWith, updateAllTypes);
|
||||||
|
final DateFieldMapper other = (DateFieldMapper) mergeWith;
|
||||||
if (other.ignoreMalformed.explicit()) {
|
if (other.ignoreMalformed.explicit()) {
|
||||||
this.ignoreMalformed = other.ignoreMalformed;
|
this.ignoreMalformed = other.ignoreMalformed;
|
||||||
}
|
}
|
||||||
|
|
|
@ -395,4 +395,20 @@ public class DateFieldMapperTests extends ESSingleNodeTestCase {
|
||||||
MapperService.MergeReason.MAPPING_UPDATE, randomBoolean()));
|
MapperService.MergeReason.MAPPING_UPDATE, randomBoolean()));
|
||||||
assertThat(e.getMessage(), containsString("[mapper [release_date] has different [format] values]"));
|
assertThat(e.getMessage(), containsString("[mapper [release_date] has different [format] values]"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testMergeText() throws Exception {
|
||||||
|
String mapping = XContentFactory.jsonBuilder().startObject().startObject("doc")
|
||||||
|
.startObject("properties").startObject("date").field("type", "date").endObject()
|
||||||
|
.endObject().endObject().endObject().string();
|
||||||
|
DocumentMapper mapper = indexService.mapperService().parse("doc", new CompressedXContent(mapping), false);
|
||||||
|
|
||||||
|
String mappingUpdate = XContentFactory.jsonBuilder().startObject().startObject("doc")
|
||||||
|
.startObject("properties").startObject("date").field("type", "text").endObject()
|
||||||
|
.endObject().endObject().endObject().string();
|
||||||
|
DocumentMapper update = indexService.mapperService().parse("doc", new CompressedXContent(mappingUpdate), false);
|
||||||
|
|
||||||
|
IllegalArgumentException e = expectThrows(IllegalArgumentException.class,
|
||||||
|
() -> mapper.merge(update.mapping(), randomBoolean()));
|
||||||
|
assertEquals("mapper [date] of different type, current_type [date], merged_type [text]", e.getMessage());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue