Fix not Recognizing Disabled Object Mapper (#39862)
* Fixes not finding disabled object mapper when using dotted field name notation * Closes #39456
This commit is contained in:
parent
52b0b9cb55
commit
e2b60c7141
|
@ -83,6 +83,20 @@ final class DocumentParser {
|
|||
return parsedDocument(source, context, createDynamicUpdate(mapping, docMapper, context.getDynamicMappers()));
|
||||
}
|
||||
|
||||
private static boolean containsDisabledObjectMapper(ObjectMapper objectMapper, String[] subfields) {
|
||||
for (int i = 0; i < subfields.length - 1; ++i) {
|
||||
Mapper mapper = objectMapper.getMapper(subfields[i]);
|
||||
if (mapper instanceof ObjectMapper == false) {
|
||||
break;
|
||||
}
|
||||
objectMapper = (ObjectMapper) mapper;
|
||||
if (objectMapper.isEnabled() == false) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private static void internalParseDocument(Mapping mapping, MetadataFieldMapper[] metadataFieldsMappers,
|
||||
ParseContext.InternalParseContext context, XContentParser parser) throws IOException {
|
||||
final boolean emptyDoc = isEmptyDoc(mapping, parser);
|
||||
|
@ -387,24 +401,30 @@ final class DocumentParser {
|
|||
|
||||
private static void innerParseObject(ParseContext context, ObjectMapper mapper, XContentParser parser,
|
||||
String currentFieldName, XContentParser.Token token) throws IOException {
|
||||
assert token == XContentParser.Token.FIELD_NAME || token == XContentParser.Token.END_OBJECT;
|
||||
String[] paths = null;
|
||||
while (token != XContentParser.Token.END_OBJECT) {
|
||||
if (token == XContentParser.Token.START_OBJECT) {
|
||||
parseObject(context, mapper, currentFieldName);
|
||||
} else if (token == XContentParser.Token.START_ARRAY) {
|
||||
parseArray(context, mapper, currentFieldName);
|
||||
} else if (token == XContentParser.Token.FIELD_NAME) {
|
||||
if (token == XContentParser.Token.FIELD_NAME) {
|
||||
currentFieldName = parser.currentName();
|
||||
paths = splitAndValidatePath(currentFieldName);
|
||||
if (MapperService.isMetadataField(context.path().pathAsText(currentFieldName))) {
|
||||
throw new MapperParsingException("Field [" + currentFieldName + "] is a metadata field and cannot be added inside"
|
||||
+ " a document. Use the index API request parameters.");
|
||||
} else if (containsDisabledObjectMapper(mapper, paths)) {
|
||||
parser.nextToken();
|
||||
parser.skipChildren();
|
||||
}
|
||||
} else if (token == XContentParser.Token.START_OBJECT) {
|
||||
parseObject(context, mapper, currentFieldName, paths);
|
||||
} else if (token == XContentParser.Token.START_ARRAY) {
|
||||
parseArray(context, mapper, currentFieldName, paths);
|
||||
} else if (token == XContentParser.Token.VALUE_NULL) {
|
||||
parseNullValue(context, mapper, currentFieldName);
|
||||
parseNullValue(context, mapper, currentFieldName, paths);
|
||||
} else if (token == null) {
|
||||
throw new MapperParsingException("object mapping for [" + mapper.name() + "] tried to parse field [" + currentFieldName
|
||||
+ "] as object, but got EOF, has a concrete value been provided to it?");
|
||||
} else if (token.isValue()) {
|
||||
parseValue(context, mapper, currentFieldName, token);
|
||||
parseValue(context, mapper, currentFieldName, token, paths);
|
||||
}
|
||||
token = parser.nextToken();
|
||||
}
|
||||
|
@ -475,10 +495,10 @@ final class DocumentParser {
|
|||
}
|
||||
}
|
||||
|
||||
private static void parseObject(final ParseContext context, ObjectMapper mapper, String currentFieldName) throws IOException {
|
||||
private static void parseObject(final ParseContext context, ObjectMapper mapper, String currentFieldName,
|
||||
String[] paths) throws IOException {
|
||||
assert currentFieldName != null;
|
||||
|
||||
final String[] paths = splitAndValidatePath(currentFieldName);
|
||||
Mapper objectMapper = getMapper(mapper, currentFieldName, paths);
|
||||
if (objectMapper != null) {
|
||||
context.path().add(currentFieldName);
|
||||
|
@ -512,10 +532,10 @@ final class DocumentParser {
|
|||
}
|
||||
}
|
||||
|
||||
private static void parseArray(ParseContext context, ObjectMapper parentMapper, String lastFieldName) throws IOException {
|
||||
private static void parseArray(ParseContext context, ObjectMapper parentMapper, String lastFieldName,
|
||||
String[] paths) throws IOException {
|
||||
String arrayFieldName = lastFieldName;
|
||||
|
||||
final String[] paths = splitAndValidatePath(arrayFieldName);
|
||||
Mapper mapper = getMapper(parentMapper, lastFieldName, paths);
|
||||
if (mapper != null) {
|
||||
// There is a concrete mapper for this field already. Need to check if the mapper
|
||||
|
@ -562,35 +582,33 @@ final class DocumentParser {
|
|||
}
|
||||
|
||||
private static void parseNonDynamicArray(ParseContext context, ObjectMapper mapper,
|
||||
String lastFieldName, String arrayFieldName) throws IOException {
|
||||
final String lastFieldName, String arrayFieldName) throws IOException {
|
||||
XContentParser parser = context.parser();
|
||||
XContentParser.Token token;
|
||||
final String[] paths = splitAndValidatePath(lastFieldName);
|
||||
while ((token = parser.nextToken()) != XContentParser.Token.END_ARRAY) {
|
||||
if (token == XContentParser.Token.START_OBJECT) {
|
||||
parseObject(context, mapper, lastFieldName);
|
||||
parseObject(context, mapper, lastFieldName, paths);
|
||||
} else if (token == XContentParser.Token.START_ARRAY) {
|
||||
parseArray(context, mapper, lastFieldName);
|
||||
} else if (token == XContentParser.Token.FIELD_NAME) {
|
||||
lastFieldName = parser.currentName();
|
||||
parseArray(context, mapper, lastFieldName, paths);
|
||||
} else if (token == XContentParser.Token.VALUE_NULL) {
|
||||
parseNullValue(context, mapper, lastFieldName);
|
||||
parseNullValue(context, mapper, lastFieldName, paths);
|
||||
} else if (token == null) {
|
||||
throw new MapperParsingException("object mapping for [" + mapper.name() + "] with array for [" + arrayFieldName
|
||||
+ "] tried to parse as array, but got EOF, is there a mismatch in types for the same field?");
|
||||
} else {
|
||||
parseValue(context, mapper, lastFieldName, token);
|
||||
assert token.isValue();
|
||||
parseValue(context, mapper, lastFieldName, token, paths);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void parseValue(final ParseContext context, ObjectMapper parentMapper,
|
||||
String currentFieldName, XContentParser.Token token) throws IOException {
|
||||
String currentFieldName, XContentParser.Token token, String[] paths) throws IOException {
|
||||
if (currentFieldName == null) {
|
||||
throw new MapperParsingException("object mapping [" + parentMapper.name() + "] trying to serialize a value with"
|
||||
+ " no field associated with it, current value [" + context.parser().textOrNull() + "]");
|
||||
}
|
||||
|
||||
final String[] paths = splitAndValidatePath(currentFieldName);
|
||||
Mapper mapper = getMapper(parentMapper, currentFieldName, paths);
|
||||
if (mapper != null) {
|
||||
parseObjectOrField(context, mapper);
|
||||
|
@ -605,9 +623,10 @@ final class DocumentParser {
|
|||
}
|
||||
}
|
||||
|
||||
private static void parseNullValue(ParseContext context, ObjectMapper parentMapper, String lastFieldName) throws IOException {
|
||||
private static void parseNullValue(ParseContext context, ObjectMapper parentMapper, String lastFieldName,
|
||||
String[] paths) throws IOException {
|
||||
// we can only handle null values if we have mappings for them
|
||||
Mapper mapper = getMapper(parentMapper, lastFieldName, splitAndValidatePath(lastFieldName));
|
||||
Mapper mapper = getMapper(parentMapper, lastFieldName, paths);
|
||||
if (mapper != null) {
|
||||
// TODO: passing null to an object seems bogus?
|
||||
parseObjectOrField(context, mapper);
|
||||
|
|
|
@ -79,6 +79,56 @@ public class DocumentParserTests extends ESSingleNodeTestCase {
|
|||
assertNotNull(doc.rootDoc().getField(IdFieldMapper.NAME));
|
||||
}
|
||||
|
||||
public void testDotsWithFieldDisabled() throws IOException {
|
||||
DocumentMapperParser mapperParser = createIndex("test").mapperService().documentMapperParser();
|
||||
String mapping = Strings.toString(jsonBuilder().startObject().startObject("type").startObject("properties")
|
||||
.startObject("foo").field("enabled", false).endObject()
|
||||
.endObject().endObject().endObject());
|
||||
DocumentMapper mapper = mapperParser.parse("type", new CompressedXContent(mapping));
|
||||
{
|
||||
BytesReference bytes = BytesReference.bytes(jsonBuilder()
|
||||
.startObject()
|
||||
.field("foo.bar", 111)
|
||||
.endObject());
|
||||
ParsedDocument doc = mapper.parse(new SourceToParse("test", "type", "1", bytes, XContentType.JSON));
|
||||
assertNull(doc.rootDoc().getField("foo"));
|
||||
assertNull(doc.rootDoc().getField("bar"));
|
||||
assertNull(doc.rootDoc().getField("foo.bar"));
|
||||
}
|
||||
{
|
||||
BytesReference bytes = BytesReference.bytes(jsonBuilder()
|
||||
.startObject()
|
||||
.field("foo.bar", new int[]{1, 2, 3})
|
||||
.endObject());
|
||||
ParsedDocument doc = mapper.parse(new SourceToParse("test", "type", "1", bytes, XContentType.JSON));
|
||||
assertNull(doc.rootDoc().getField("foo"));
|
||||
assertNull(doc.rootDoc().getField("bar"));
|
||||
assertNull(doc.rootDoc().getField("foo.bar"));
|
||||
}
|
||||
{
|
||||
BytesReference bytes = BytesReference.bytes(jsonBuilder()
|
||||
.startObject()
|
||||
.field("foo.bar", Collections.singletonMap("key", "value"))
|
||||
.endObject());
|
||||
ParsedDocument doc = mapper.parse(new SourceToParse("test", "type", "1", bytes, XContentType.JSON));
|
||||
assertNull(doc.rootDoc().getField("foo"));
|
||||
assertNull(doc.rootDoc().getField("bar"));
|
||||
assertNull(doc.rootDoc().getField("foo.bar"));
|
||||
}
|
||||
{
|
||||
BytesReference bytes = BytesReference.bytes(jsonBuilder()
|
||||
.startObject()
|
||||
.field("foo.bar", "string value")
|
||||
.field("blub", 222)
|
||||
.endObject());
|
||||
ParsedDocument doc = mapper.parse(new SourceToParse("test", "type", "1", bytes, XContentType.JSON));
|
||||
assertNull(doc.rootDoc().getField("foo"));
|
||||
assertNull(doc.rootDoc().getField("bar"));
|
||||
assertNull(doc.rootDoc().getField("foo.bar"));
|
||||
assertNotNull(doc.rootDoc().getField("blub"));
|
||||
}
|
||||
}
|
||||
|
||||
public void testDotsWithExistingMapper() throws Exception {
|
||||
DocumentMapperParser mapperParser = createIndex("test").mapperService().documentMapperParser();
|
||||
String mapping = Strings.toString(XContentFactory.jsonBuilder().startObject().startObject("type").startObject("properties")
|
||||
|
|
Loading…
Reference in New Issue