diff --git a/core/src/main/java/org/elasticsearch/index/mapper/MapperService.java b/core/src/main/java/org/elasticsearch/index/mapper/MapperService.java index 0423f5520b2..256f12e861b 100755 --- a/core/src/main/java/org/elasticsearch/index/mapper/MapperService.java +++ b/core/src/main/java/org/elasticsearch/index/mapper/MapperService.java @@ -272,8 +272,12 @@ public class MapperService extends AbstractIndexComponent { if (Version.indexCreated(indexSettings).onOrAfter(Version.V_2_0_0_beta1) && mapper.type().equals(mapper.parentFieldMapper().type())) { throw new IllegalArgumentException("The [_parent.type] option can't point to the same type"); } - if (mapper.type().contains(".") && !PercolatorService.TYPE_NAME.equals(mapper.type())) { - logger.warn("Type [{}] contains a '.', it is recommended not to include it within a type name", mapper.type()); + if (typeNameStartsWithIllegalDot(mapper)) { + if (Version.indexCreated(indexSettings).onOrAfter(Version.V_2_0_0_beta1)) { + throw new IllegalArgumentException("mapping type name [" + mapper.type() + "] must not start with a '.'"); + } else { + logger.warn("Type [{}] starts with a '.', it is recommended not to start a type name with a '.'", mapper.type()); + } } // we can add new field/object mappers while the old ones are there // since we get new instances of those, and when we remove, we remove @@ -315,6 +319,10 @@ public class MapperService extends AbstractIndexComponent { } } + private boolean typeNameStartsWithIllegalDot(DocumentMapper mapper) { + return mapper.type().startsWith(".") && !PercolatorService.TYPE_NAME.equals(mapper.type()); + } + private boolean assertSerialization(DocumentMapper mapper) { // capture the source now, it may change due to concurrent parsing final CompressedXContent mappingSource = mapper.mappingSource(); diff --git a/core/src/test/java/org/elasticsearch/index/mapper/MapperServiceTest.java b/core/src/test/java/org/elasticsearch/index/mapper/MapperServiceTest.java new file mode 100644 index 00000000000..18447355d8c --- /dev/null +++ b/core/src/test/java/org/elasticsearch/index/mapper/MapperServiceTest.java @@ -0,0 +1,49 @@ +/* + * Licensed to Elasticsearch under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.elasticsearch.index.mapper; + +import org.elasticsearch.test.ElasticsearchSingleNodeTest; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; + +import static org.hamcrest.CoreMatchers.containsString; +import static org.hamcrest.Matchers.hasToString; + +public class MapperServiceTest extends ElasticsearchSingleNodeTest { + @Rule + public ExpectedException expectedException = ExpectedException.none(); + + @Test + public void testTypeNameStartsWithIllegalDot() { + expectedException.expect(MapperParsingException.class); + expectedException.expect(hasToString(containsString("mapping type name [.test-type] must not start with a '.'"))); + String index = "test-index"; + String type = ".test-type"; + String field = "field"; + client() + .admin() + .indices() + .prepareCreate(index) + .addMapping(type, field, "type=string") + .execute() + .actionGet(); + } +} diff --git a/docs/reference/migration/migrate_2_0.asciidoc b/docs/reference/migration/migrate_2_0.asciidoc index c8aa72dd433..4475e6d5667 100644 --- a/docs/reference/migration/migrate_2_0.asciidoc +++ b/docs/reference/migration/migrate_2_0.asciidoc @@ -192,6 +192,7 @@ A `RoutingMissingException` is now thrown instead. * The setting `index.mapping.allow_type_wrapper` has been removed. Documents should always be sent without the type as the root element. * The delete mappings API has been removed. Mapping types can no longer be deleted. +* Mapping type names can no longer start with dots. * The `ignore_conflicts` option of the put mappings API has been removed. Conflicts can't be ignored anymore. * The `binary` field does not support the `compress` and `compress_threshold` options anymore.