From aed1f68e494c65ad50b98a3e0a7a2b6a794b2965 Mon Sep 17 00:00:00 2001 From: Ryan Ernst Date: Mon, 6 Jul 2015 18:22:06 -0700 Subject: [PATCH] Mappings: Enforce field names do not contain dot Field names containing dots can cause problems. For example, @jpountz made this recreation which cause no error, but can result in a serialization exception if the type already exists: https://gist.github.com/jpountz/8c66817e00a322b81f85 But this is not just a potential conflict. It also has larger problems, since only the leaf mapper is created. The intermediate "foo" object field would not exist if only "foo.bar" was in the mappings. This change forbids the use of dots in field names. It also fixes an issue with passing through the update_all_types setting, which was always set to true whenever a type already existed (!). I do not think we should worry about backwards compatibility here. This should be a hard break (and added to the migration plugin). --- .../index/mapper/DocumentMapper.java | 6 +++--- .../index/mapper/object/ObjectMapper.java | 17 ++++++++++------- .../index/mapper/simple/SimpleMapperTests.java | 15 +++++++++++++++ 3 files changed, 28 insertions(+), 10 deletions(-) diff --git a/core/src/main/java/org/elasticsearch/index/mapper/DocumentMapper.java b/core/src/main/java/org/elasticsearch/index/mapper/DocumentMapper.java index de201941ed7f7..1a847997e8429 100644 --- a/core/src/main/java/org/elasticsearch/index/mapper/DocumentMapper.java +++ b/core/src/main/java/org/elasticsearch/index/mapper/DocumentMapper.java @@ -399,10 +399,10 @@ public boolean isParent(String type) { return mapperService.getParentTypes().contains(type); } - private void addMappers(Collection objectMappers, Collection fieldMappers) { + private void addMappers(Collection objectMappers, Collection fieldMappers, boolean updateAllTypes) { assert mappingLock.isWriteLockedByCurrentThread(); // first ensure we don't have any incompatible new fields - mapperService.checkNewMappersCompatibility(objectMappers, fieldMappers, true); + mapperService.checkNewMappersCompatibility(objectMappers, fieldMappers, updateAllTypes); // update mappers for this document type MapBuilder builder = MapBuilder.newMapBuilder(this.objectMappers); @@ -424,7 +424,7 @@ public MergeResult merge(Mapping mapping, boolean simulate, boolean updateAllTyp final MergeResult mergeResult = new MergeResult(simulate, updateAllTypes); this.mapping.merge(mapping, mergeResult); if (simulate == false) { - addMappers(mergeResult.getNewObjectMappers(), mergeResult.getNewFieldMappers()); + addMappers(mergeResult.getNewObjectMappers(), mergeResult.getNewFieldMappers(), updateAllTypes); refreshSource(); } return mergeResult; diff --git a/core/src/main/java/org/elasticsearch/index/mapper/object/ObjectMapper.java b/core/src/main/java/org/elasticsearch/index/mapper/object/ObjectMapper.java index 12f0319f32a57..30592f4e9fe23 100644 --- a/core/src/main/java/org/elasticsearch/index/mapper/object/ObjectMapper.java +++ b/core/src/main/java/org/elasticsearch/index/mapper/object/ObjectMapper.java @@ -278,7 +278,10 @@ protected static void parseProperties(ObjectMapper.Builder objBuilder, Map> iterator = propsNode.entrySet().iterator(); while (iterator.hasNext()) { Map.Entry entry = iterator.next(); - String propName = entry.getKey(); + String fieldName = entry.getKey(); + if (fieldName.contains(".")) { + throw new MapperParsingException("Field name [" + fieldName + "] cannot contain '.'"); + } // Should accept empty arrays, as a work around for when the // user can't provide an empty Map. (PHP for example) boolean isEmptyList = entry.getValue() instanceof List && ((List) entry.getValue()).isEmpty(); @@ -301,23 +304,23 @@ protected static void parseProperties(ObjectMapper.Builder objBuilder, Map