Browse Source

Merge pull request #15715 from jpountz/fix/dyn_mapping_and_template_multi_field

Fix dynamic mapping corner case.
Adrien Grand 9 years ago
parent
commit
cb08c52a2a

+ 3 - 1
core/src/main/java/org/elasticsearch/index/mapper/FieldMapper.java

@@ -362,7 +362,9 @@ public abstract class FieldMapper extends Mapper implements Cloneable {
     public FieldMapper updateFieldType(Map<String, MappedFieldType> fullNameToFieldType) {
         final MappedFieldType newFieldType = fullNameToFieldType.get(fieldType.name());
         if (newFieldType == null) {
-            throw new IllegalStateException();
+            // this field does not exist in the mappings yet
+            // this can happen if this mapper represents a mapping update
+            return this;
         } else if (fieldType.getClass() != newFieldType.getClass()) {
             throw new IllegalStateException("Mixing up field types: " + fieldType.getClass() + " != " + newFieldType.getClass());
         }

+ 48 - 0
core/src/test/java/org/elasticsearch/index/mapper/DynamicMappingTests.java

@@ -461,6 +461,54 @@ public class DynamicMappingTests extends ESSingleNodeTestCase {
         }
     }
 
+    public void testMixTemplateMultiFieldAndMappingReuse() throws Exception {
+        IndexService indexService = createIndex("test");
+        XContentBuilder mappings1 = jsonBuilder().startObject()
+                .startObject("type1")
+                    .startArray("dynamic_templates")
+                        .startObject()
+                            .startObject("template1")
+                                .field("match_mapping_type", "string")
+                                .startObject("mapping")
+                                    .field("type", "string")
+                                    .startObject("fields")
+                                        .startObject("raw")
+                                            .field("type", "string")
+                                            .field("index", "not_analyzed")
+                                        .endObject()
+                                    .endObject()
+                                .endObject()
+                            .endObject()
+                        .endObject()
+                    .endArray()
+                .endObject().endObject();
+        indexService.mapperService().merge("type1", new CompressedXContent(mappings1.bytes()), true, false);
+        XContentBuilder mappings2 = jsonBuilder().startObject()
+                .startObject("type2")
+                    .startObject("properties")
+                        .startObject("field")
+                            .field("type", "string")
+                        .endObject()
+                    .endObject()
+                .endObject().endObject();
+        indexService.mapperService().merge("type2", new CompressedXContent(mappings2.bytes()), true, false);
+
+        XContentBuilder json = XContentFactory.jsonBuilder().startObject()
+                    .field("field", "foo")
+                .endObject();
+        SourceToParse source = SourceToParse.source(json.bytes()).id("1");
+        DocumentMapper mapper = indexService.mapperService().documentMapper("type1");
+        assertNull(mapper.mappers().getMapper("field.raw"));
+        ParsedDocument parsed = mapper.parse(source);
+        assertNotNull(parsed.dynamicMappingsUpdate());
+
+        indexService.mapperService().merge("type1", new CompressedXContent(parsed.dynamicMappingsUpdate().toString()), false, false);
+        mapper = indexService.mapperService().documentMapper("type1");
+        assertNotNull(mapper.mappers().getMapper("field.raw"));
+        parsed = mapper.parse(source);
+        assertNull(parsed.dynamicMappingsUpdate());
+    }
+
     public void testDefaultFloatingPointMappings() throws IOException {
         DocumentMapper mapper = createIndex("test").mapperService().documentMapperWithAutoCreate("type").getDocumentMapper();
         doTestDefaultFloatingPointMappings(mapper, XContentFactory.jsonBuilder());