From f7cb1d4d084b81a73b360c669d28576168710d75 Mon Sep 17 00:00:00 2001 From: Julie Tibshirani Date: Fri, 20 Aug 2021 10:28:00 -0700 Subject: [PATCH] [7.x] Make sure copy_to accepts null values (#76770) In #72820 we improved the error message when attempting to `copy_to` with an object value. The change accidentally started throwing errors for null values too, although they're allowed. This PR fixes the regression and adds an explicit test for `copy_to` with null values. --- .../index/mapper/DocumentParser.java | 2 +- .../index/mapper/CopyToMapperTests.java | 26 +++++++++++++++++++ 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/server/src/main/java/org/elasticsearch/index/mapper/DocumentParser.java b/server/src/main/java/org/elasticsearch/index/mapper/DocumentParser.java index 6c9f15c85bb9c..5512f216ac2e7 100644 --- a/server/src/main/java/org/elasticsearch/index/mapper/DocumentParser.java +++ b/server/src/main/java/org/elasticsearch/index/mapper/DocumentParser.java @@ -556,7 +556,7 @@ static void parseObjectOrField(DocumentParserContext context, Mapper mapper) thr List copyToFields = fieldMapper.copyTo().copyToFields(); if (context.isWithinCopyTo() == false && copyToFields.isEmpty() == false) { XContentParser.Token currentToken = context.parser().currentToken(); - if (currentToken.isValue() == false) { + if (currentToken.isValue() == false && currentToken != XContentParser.Token.VALUE_NULL) { // sanity check, we currently support copy-to only for value-type field, not objects throw new MapperParsingException("Cannot copy field [" + mapper.name() + "] to fields " + copyToFields + ". Copy-to currently only works for value-type fields, not objects."); diff --git a/server/src/test/java/org/elasticsearch/index/mapper/CopyToMapperTests.java b/server/src/test/java/org/elasticsearch/index/mapper/CopyToMapperTests.java index 27f7ebf4aeaeb..7ed078c0ca5ff 100644 --- a/server/src/test/java/org/elasticsearch/index/mapper/CopyToMapperTests.java +++ b/server/src/test/java/org/elasticsearch/index/mapper/CopyToMapperTests.java @@ -13,6 +13,7 @@ import org.elasticsearch.common.xcontent.ToXContent; import org.elasticsearch.common.xcontent.XContentBuilder; import org.elasticsearch.common.xcontent.XContentParser; +import org.elasticsearch.common.xcontent.XContentType; import org.elasticsearch.common.xcontent.json.JsonXContent; import org.hamcrest.Matchers; @@ -644,6 +645,31 @@ public void testCopyToDateRangeFailure() throws Exception { ); } + public void testCopyToWithNullValue() throws Exception { + DocumentMapper docMapper = createDocumentMapper(topMapping(b -> + b.startObject("properties") + .startObject("keyword_copy") + .field("type", "keyword") + .field("null_value", "default-value") + .endObject() + .startObject("keyword") + .field("type", "keyword") + .array("copy_to", "keyword_copy") + .endObject() + .endObject())); + + BytesReference json = BytesReference.bytes(jsonBuilder().startObject() + .nullField("keyword") + .endObject()); + + LuceneDocument document = docMapper.parse(new SourceToParse("test", MapperService.SINGLE_MAPPING_NAME, + "1", json, XContentType.JSON)).rootDoc(); + assertEquals(0, document.getFields("keyword").length); + + IndexableField[] fields = document.getFields("keyword_copy"); + assertEquals(2, fields.length); + } + public void testCopyToGeoPoint() throws Exception { DocumentMapper docMapper = createDocumentMapper(topMapping(b -> { b.startObject("properties");