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) {
|
if (objectMapper != null) {
|
||||||
parseObjectOrField(context, objectMapper);
|
parseObjectOrField(context, objectMapper);
|
||||||
} else {
|
} else {
|
||||||
ObjectMapper.Dynamic dynamic = dynamicOrDefault(mapper, context.root().dynamic());
|
ObjectMapper.Dynamic dynamic = dynamicOrDefault(mapper, context);
|
||||||
if (dynamic == ObjectMapper.Dynamic.STRICT) {
|
if (dynamic == ObjectMapper.Dynamic.STRICT) {
|
||||||
throw new StrictDynamicMappingException(mapper.fullPath(), currentFieldName);
|
throw new StrictDynamicMappingException(mapper.fullPath(), currentFieldName);
|
||||||
} else if (dynamic == ObjectMapper.Dynamic.TRUE) {
|
} else if (dynamic == ObjectMapper.Dynamic.TRUE) {
|
||||||
|
@ -519,7 +519,7 @@ final class DocumentParser {
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
ObjectMapper.Dynamic dynamic = dynamicOrDefault(parentMapper, context.root().dynamic());
|
ObjectMapper.Dynamic dynamic = dynamicOrDefault(parentMapper, context);
|
||||||
if (dynamic == ObjectMapper.Dynamic.STRICT) {
|
if (dynamic == ObjectMapper.Dynamic.STRICT) {
|
||||||
throw new StrictDynamicMappingException(parentMapper.fullPath(), arrayFieldName);
|
throw new StrictDynamicMappingException(parentMapper.fullPath(), arrayFieldName);
|
||||||
} else if (dynamic == ObjectMapper.Dynamic.TRUE) {
|
} 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 {
|
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) {
|
if (dynamic == ObjectMapper.Dynamic.STRICT) {
|
||||||
throw new StrictDynamicMappingException(parentMapper.fullPath(), currentFieldName);
|
throw new StrictDynamicMappingException(parentMapper.fullPath(), currentFieldName);
|
||||||
}
|
}
|
||||||
|
@ -867,7 +867,7 @@ final class DocumentParser {
|
||||||
mapper = context.docMapper().objectMappers().get(context.path().pathAsText(paths[i]));
|
mapper = context.docMapper().objectMappers().get(context.path().pathAsText(paths[i]));
|
||||||
if (mapper == null) {
|
if (mapper == null) {
|
||||||
// One mapping is missing, check if we are allowed to create a dynamic one.
|
// 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) {
|
switch (dynamic) {
|
||||||
case STRICT:
|
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();
|
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) {
|
if (dynamic == null) {
|
||||||
return dynamicDefault == null ? ObjectMapper.Dynamic.TRUE : dynamicDefault;
|
return context.root().dynamic() == null ? ObjectMapper.Dynamic.TRUE : context.root().dynamic();
|
||||||
}
|
}
|
||||||
return dynamic;
|
return dynamic;
|
||||||
}
|
}
|
||||||
|
|
|
@ -98,6 +98,65 @@ public class DocumentParserTests extends ESSingleNodeTestCase {
|
||||||
assertEquals("789", values[2]);
|
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 {
|
DocumentMapper createDummyMapping(MapperService mapperService) throws Exception {
|
||||||
String mapping = jsonBuilder().startObject().startObject("type").startObject("properties")
|
String mapping = jsonBuilder().startObject().startObject("type").startObject("properties")
|
||||||
.startObject("y").field("type", "object").endObject()
|
.startObject("y").field("type", "object").endObject()
|
||||||
|
|
Loading…
Reference in New Issue