Merge pull request #17864 from rjernst/dynamic_lookup
Mappings: Fix dynamic check to properly handle parents
This commit is contained in:
commit
ef1e1acf3d
|
@ -480,7 +480,7 @@ final class DocumentParser {
|
|||
if (objectMapper != null) {
|
||||
parseObjectOrField(context, objectMapper);
|
||||
} else {
|
||||
ObjectMapper.Dynamic dynamic = dynamicOrDefault(mapper, context.root().dynamic());
|
||||
ObjectMapper.Dynamic dynamic = dynamicOrDefault(mapper, context);
|
||||
if (dynamic == ObjectMapper.Dynamic.STRICT) {
|
||||
throw new StrictDynamicMappingException(mapper.fullPath(), currentFieldName);
|
||||
} else if (dynamic == ObjectMapper.Dynamic.TRUE) {
|
||||
|
@ -519,7 +519,7 @@ final class DocumentParser {
|
|||
}
|
||||
} else {
|
||||
|
||||
ObjectMapper.Dynamic dynamic = dynamicOrDefault(parentMapper, context.root().dynamic());
|
||||
ObjectMapper.Dynamic dynamic = dynamicOrDefault(parentMapper, context);
|
||||
if (dynamic == ObjectMapper.Dynamic.STRICT) {
|
||||
throw new StrictDynamicMappingException(parentMapper.fullPath(), arrayFieldName);
|
||||
} else if (dynamic == ObjectMapper.Dynamic.TRUE) {
|
||||
|
@ -794,7 +794,7 @@ final class DocumentParser {
|
|||
}
|
||||
|
||||
private static void parseDynamicValue(final ParseContext context, ObjectMapper parentMapper, String currentFieldName, XContentParser.Token token) throws IOException {
|
||||
ObjectMapper.Dynamic dynamic = dynamicOrDefault(parentMapper, context.root().dynamic());
|
||||
ObjectMapper.Dynamic dynamic = dynamicOrDefault(parentMapper, context);
|
||||
if (dynamic == ObjectMapper.Dynamic.STRICT) {
|
||||
throw new StrictDynamicMappingException(parentMapper.fullPath(), currentFieldName);
|
||||
}
|
||||
|
@ -867,7 +867,7 @@ final class DocumentParser {
|
|||
mapper = context.docMapper().objectMappers().get(context.path().pathAsText(paths[i]));
|
||||
if (mapper == null) {
|
||||
// One mapping is missing, check if we are allowed to create a dynamic one.
|
||||
ObjectMapper.Dynamic dynamic = dynamicOrDefault(parent, context.root().dynamic());
|
||||
ObjectMapper.Dynamic dynamic = dynamicOrDefault(parent, context);
|
||||
|
||||
switch (dynamic) {
|
||||
case STRICT:
|
||||
|
@ -899,10 +899,26 @@ final class DocumentParser {
|
|||
}
|
||||
}
|
||||
|
||||
private static ObjectMapper.Dynamic dynamicOrDefault(ObjectMapper parentMapper, ObjectMapper.Dynamic dynamicDefault) {
|
||||
// find what the dynamic setting is given the current parse context and parent
|
||||
private static ObjectMapper.Dynamic dynamicOrDefault(ObjectMapper parentMapper, ParseContext context) {
|
||||
ObjectMapper.Dynamic dynamic = parentMapper.dynamic();
|
||||
while (dynamic == null) {
|
||||
int lastDotNdx = parentMapper.name().lastIndexOf('.');
|
||||
if (lastDotNdx == -1) {
|
||||
// no dot means we the parent is the root, so just delegate to the default outside the loop
|
||||
break;
|
||||
}
|
||||
String parentName = parentMapper.name().substring(0, lastDotNdx);
|
||||
parentMapper = context.docMapper().objectMappers().get(parentName);
|
||||
if (parentMapper == null) {
|
||||
// If parentMapper is ever null, it means the parent of the current mapper was dynamically created.
|
||||
// But in order to be created dynamically, the dynamic setting of that parent was necessarily true
|
||||
return ObjectMapper.Dynamic.TRUE;
|
||||
}
|
||||
dynamic = parentMapper.dynamic();
|
||||
}
|
||||
if (dynamic == null) {
|
||||
return dynamicDefault == null ? ObjectMapper.Dynamic.TRUE : dynamicDefault;
|
||||
return context.root().dynamic() == null ? ObjectMapper.Dynamic.TRUE : context.root().dynamic();
|
||||
}
|
||||
return dynamic;
|
||||
}
|
||||
|
|
|
@ -98,6 +98,65 @@ public class DocumentParserTests extends ESSingleNodeTestCase {
|
|||
assertEquals("789", values[2]);
|
||||
}
|
||||
|
||||
public void testPropagateDynamicWithExistingMapper() throws Exception {
|
||||
DocumentMapperParser mapperParser = createIndex("test").mapperService().documentMapperParser();
|
||||
String mapping = XContentFactory.jsonBuilder().startObject().startObject("type")
|
||||
.field("dynamic", false)
|
||||
.startObject("properties")
|
||||
.startObject("foo")
|
||||
.field("type", "object")
|
||||
.field("dynamic", true)
|
||||
.startObject("properties")
|
||||
.endObject().endObject().endObject().endObject().string();
|
||||
DocumentMapper mapper = mapperParser.parse("type", new CompressedXContent(mapping));
|
||||
BytesReference bytes = XContentFactory.jsonBuilder()
|
||||
.startObject().startObject("foo")
|
||||
.field("bar", "something")
|
||||
.endObject().endObject().bytes();
|
||||
ParsedDocument doc = mapper.parse("test", "type", "1", bytes);
|
||||
assertNotNull(doc.dynamicMappingsUpdate());
|
||||
assertNotNull(doc.rootDoc().getField("foo.bar"));
|
||||
}
|
||||
|
||||
public void testPropagateDynamicWithDynamicMapper() throws Exception {
|
||||
DocumentMapperParser mapperParser = createIndex("test").mapperService().documentMapperParser();
|
||||
String mapping = XContentFactory.jsonBuilder().startObject().startObject("type")
|
||||
.field("dynamic", false)
|
||||
.startObject("properties")
|
||||
.startObject("foo")
|
||||
.field("type", "object")
|
||||
.field("dynamic", true)
|
||||
.startObject("properties")
|
||||
.endObject().endObject().endObject().endObject().string();
|
||||
DocumentMapper mapper = mapperParser.parse("type", new CompressedXContent(mapping));
|
||||
BytesReference bytes = XContentFactory.jsonBuilder()
|
||||
.startObject().startObject("foo").startObject("bar")
|
||||
.field("baz", "something")
|
||||
.endObject().endObject().endObject().bytes();
|
||||
ParsedDocument doc = mapper.parse("test", "type", "1", bytes);
|
||||
assertNotNull(doc.dynamicMappingsUpdate());
|
||||
assertNotNull(doc.rootDoc().getField("foo.bar.baz"));
|
||||
}
|
||||
|
||||
public void testDynamicRootFallback() throws Exception {
|
||||
DocumentMapperParser mapperParser = createIndex("test").mapperService().documentMapperParser();
|
||||
String mapping = XContentFactory.jsonBuilder().startObject().startObject("type")
|
||||
.field("dynamic", false)
|
||||
.startObject("properties")
|
||||
.startObject("foo")
|
||||
.field("type", "object")
|
||||
.startObject("properties")
|
||||
.endObject().endObject().endObject().endObject().string();
|
||||
DocumentMapper mapper = mapperParser.parse("type", new CompressedXContent(mapping));
|
||||
BytesReference bytes = XContentFactory.jsonBuilder()
|
||||
.startObject().startObject("foo")
|
||||
.field("bar", "something")
|
||||
.endObject().endObject().bytes();
|
||||
ParsedDocument doc = mapper.parse("test", "type", "1", bytes);
|
||||
assertNull(doc.dynamicMappingsUpdate());
|
||||
assertNull(doc.rootDoc().getField("foo.bar"));
|
||||
}
|
||||
|
||||
DocumentMapper createDummyMapping(MapperService mapperService) throws Exception {
|
||||
String mapping = jsonBuilder().startObject().startObject("type").startObject("properties")
|
||||
.startObject("y").field("type", "object").endObject()
|
||||
|
|
Loading…
Reference in New Issue